all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: martin rudalics <rudalics@gmx.at>
To: "Clément Pit--Claudel" <clement.pit@gmail.com>, emacs-devel@gnu.org
Subject: Re: Latest master broken on Cocoa/NS
Date: Fri, 15 Jul 2016 18:41:06 +0200	[thread overview]
Message-ID: <57891222.1060900@gmx.at> (raw)
In-Reply-To: <57890B53.4050402@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 347 bytes --]

 > company-mode would benefit tremendously from such a thing.

Attached.  mini-frame.diff is against master from this morning and
contains unrelated stuff which should not bother you.  The entry point
is the function ‘make-mini-frame’.  mini-frame.el has some functions to
show how it can be used.  No NS support, obviously.

martin


[-- Attachment #2: mini-frame.diff --]
[-- Type: text/plain, Size: 49068 bytes --]

diff --git a/lisp/frame.el b/lisp/frame.el
index 09738d1..478cc2b 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -144,6 +144,13 @@ handle-focus-out
 This function runs the hook `focus-out-hook'."
   (interactive "e")
   (run-hooks 'focus-out-hook))
+
+(defun handle-move-frame (event)
+  "Handle a move-frame event.
+This function runs the abnormal hook `move-frame-functions'."
+  (interactive "e")
+  (let ((frame (posn-window (event-start event))))
+    (run-hook-with-args 'move-frame-functions frame)))
 \f
 ;;;; Arrangement of frames at startup

@@ -1483,6 +1490,90 @@ frame-monitor-attributes
 	   for frames = (cdr (assq 'frames attributes))
 	   if (memq frame frames) return attributes))

+(declare-function x-make-mini-frame "xfns.c" (&optional frame parameters))
+(declare-function w32-make-mini-frame "w32fns.c" (&optional frame parameters))
+
+(defun make-mini-frame (&optional frame parameters)
+  "Make a new mini-frame with FRAME as its parent.
+Optional argument FRAME must specify a live frame.  If omitted,
+FRAME defaults to the selected frame.  The mini-frame is made on
+the same display as FRAME.  Return the new mini-frame, nil if its
+creation failed.
+
+PARAMETERS is a list of frame parameters.  The 'child-window'
+parameter is special: If non-nil, the mini-frame becomes a
+\"child window\" of FRAME.  This usually means that the
+mini-frame is clipped at the boundaries of FRAME and is moved,
+raised, and iconified together with FRAME.  Usually, this also
+means that the position of the mini-frame in the Z-order
+\(stacking order) is always right above FRAME.
+
+'child-window' omitted or nil usually means that the application
+has to take full care of how to raise, move and iconify the
+mini-frame and how to maintain its place in the Z-order (stacking
+order) of frames on the display.  On some platforms, such a
+mini-frame invariably appears on top of all other frames so you
+usually would like to hide it whenever its parent frame is not on
+top of the Z-order or does not have focus.  On other platforms,
+such a mini-frame may appear right above FRAME as with a non-nil
+'child-window' parameter.
+
+The stacking order of mini-frames with the same parent is
+undefined regardless of whether a 'child-window' parameter has
+been specified or not.  On many platforms, the stacking order of
+mini-frames with a non-nil 'child-window' parameter may be also
+undefined wrt control elements (like a scroll bar) which may
+appear under or over the mini-frame, depending on which of them
+has been drawn later.
+
+By default, mini-frames are drawn without any external borders, a
+title bar or the buttons to minimize, maximize or delete the
+frame.  The 'border-width' parameter, which is usually not used
+on \"normal\" frames, can be used to draw a border around the
+mini-frame.  On Windows, specifying a positive number as border
+width produces a one pixel wide external border.  That border is
+also reported as \"external\" by `frame-geometry' which, on
+Windows, always returns value of zero for `border-width'.  On
+both, X and Windows, the border drawn due to this parameter's
+setting is not within the native edges of the mini-frame.
+
+Other aspects of mini-frames are platform-dependent as well.  For
+example, on Windows, the 'alpha' parameter may not work correctly
+when used together with a non-nil 'child-window' parameter.  On
+X, mini-frames with a non-nil 'child-window' parameter may have
+to be explicitly redrawn when their parent frame is deiconified.
+
+The hooks `move-frame-functions', `focus-in-hook',
+`focus-out-hook', `window-configuration-change-hook', and
+‘window-size-change-functions' can be used to control size,
+placing and visibilty of a mini-frame when size, position or
+contents of its parent frame change."
+  (let* ((frame (window-normalize-frame frame))
+	 (frame-type (framep-on-display frame)))
+    (cond
+     ((eq frame-type 'x)
+      (x-create-mini-frame frame parameters))
+     ((eq frame-type 'w32)
+      (w32-create-mini-frame frame parameters)))))
+
+(declare-function x-frame-list-z-order "xfns.c" (&optional display))
+(declare-function w32-frame-list-z-order "w32fns.c" (&optional display))
+
+(defun frame-list-z-order (&optional display)
+  "Return list of Emacs' frames, in Z (stacking) order.
+The optional argument DISPLAY specifies which display to poll.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+Frames are listed from bottommost (first) to topmost (last).
+Return nil if DISPLAY contains no Emacs frame.  Child frames are
+not listed by this function."
+  (let ((display (framep-on-display display)))
+    (cond
+     ((eq display 'x)
+      (x-frame-list-z-order display))
+     ((eq display 'w32)
+      (w32-frame-list-z-order display)))))
 \f
 ;;;; Frame/display capabilities.

@@ -1882,14 +1973,14 @@ delete-other-frames
   (interactive)
   (unless frame
     (setq frame (selected-frame)))
-  (let* ((mini-frame (window-frame (minibuffer-window frame)))
-	 (frames (delq mini-frame (delq frame (frame-list)))))
+  (let* ((minibuffer-frame (window-frame (minibuffer-window frame)))
+	 (frames (delq minibuffer-frame (delq frame (frame-list)))))
     ;; Only consider frames on the same terminal.
     (dolist (frame (prog1 frames (setq frames nil)))
       (if (eq (frame-terminal) (frame-terminal frame))
           (push frame frames)))
     ;; Delete mon-minibuffer-only frames first, because `delete-frame'
-    ;; signals an error when trying to delete a mini-frame that's
+    ;; signals an error when trying to delete a minibuffer-frame that's
     ;; still in use by another frame.
     (dolist (frame frames)
       (unless (eq (frame-parameter frame 'minibuffer) 'only)
diff --git a/src/frame.c b/src/frame.c
index 22143ab..9d86b07 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -81,11 +81,6 @@
 {
   f->buffer_predicate = val;
 }
-static void
-fset_minibuffer_window (struct frame *f, Lisp_Object val)
-{
-  f->minibuffer_window = val;
-}

 struct frame *
 decode_live_frame (register Lisp_Object frame)
@@ -418,9 +413,13 @@ struct frame *
      sizes and any "new" settings for scroll bars, dividers, fringes and
      margins (though the latter should have been processed already).  */
   min_windows_width
-    = frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qt : Qnil, Qt);
+    = (f->mini_frame
+       ? unit_width
+       : frame_windows_min_size (frame, Qt, (inhibit == 5) ? Qt : Qnil, Qt));
   min_windows_height
-    = frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt);
+    = (f->mini_frame
+       ? unit_height
+       : frame_windows_min_size (frame, Qnil, (inhibit == 5) ? Qt : Qnil, Qt));

   if (inhibit >= 2 && inhibit <= 4)
     /* When INHIBIT is in [2..4] inhibit if the "old" window sizes stay
@@ -636,6 +635,7 @@ struct frame *
   f->inhibit_vertical_resize = false;
   f->tool_bar_redisplayed = false;
   f->tool_bar_resized = false;
+  f->mini_frame = false;
   f->column_width = 1;  /* !FRAME_WINDOW_P value.  */
   f->line_height = 1;  /* !FRAME_WINDOW_P value.  */
 #ifdef HAVE_WINDOW_SYSTEM
@@ -1381,18 +1381,18 @@ of them (the selected terminal frame) is actually displayed.
 It considers only frames on the same terminal as FRAME.
 By default, skip minibuffer-only frames.
 If omitted, FRAME defaults to the selected frame.
-If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
-If MINIFRAME is a window, include only its own frame
+If optional argument MINIBUF is nil, exclude minibuffer-only frames.
+If MINIBUF is a window, include only its own frame
 and any frame now using that window as the minibuffer.
-If MINIFRAME is `visible', include all visible frames.
-If MINIFRAME is 0, include all visible and iconified frames.
+If MINIBUF is `visible', include all visible frames.
+If MINIBUF is 0, include all visible and iconified frames.
 Otherwise, include all frames.  */)
-  (Lisp_Object frame, Lisp_Object miniframe)
+  (Lisp_Object frame, Lisp_Object minibuf)
 {
   if (NILP (frame))
     frame = selected_frame;
   CHECK_LIVE_FRAME (frame);
-  return next_frame (frame, miniframe);
+  return next_frame (frame, minibuf);
 }

 DEFUN ("previous-frame", Fprevious_frame, Sprevious_frame, 0, 2, 0,
@@ -1400,18 +1400,18 @@ of them (the selected terminal frame) is actually displayed.
 It considers only frames on the same terminal as FRAME.
 By default, skip minibuffer-only frames.
 If omitted, FRAME defaults to the selected frame.
-If optional argument MINIFRAME is nil, exclude minibuffer-only frames.
-If MINIFRAME is a window, include only its own frame
+If optional argument MINIBUF is nil, exclude minibuffer-only frames.
+If MINIBUF is a window, include only its own frame
 and any frame now using that window as the minibuffer.
-If MINIFRAME is `visible', include all visible frames.
-If MINIFRAME is 0, include all visible and iconified frames.
+If MINIBUF is `visible', include all visible frames.
+If MINIBUF is 0, include all visible and iconified frames.
 Otherwise, include all frames.  */)
-  (Lisp_Object frame, Lisp_Object miniframe)
+  (Lisp_Object frame, Lisp_Object minibuf)
 {
   if (NILP (frame))
     frame = selected_frame;
   CHECK_LIVE_FRAME (frame);
-  return prev_frame (frame, miniframe);
+  return prev_frame (frame, minibuf);
 }

 DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
@@ -1515,7 +1515,7 @@ of them (the selected terminal frame) is actually displayed.
   struct frame *sf;
   struct kboard *kb;

-  int minibuffer_selected, is_tooltip_frame;
+  int minibuffer_selected, tip_or_mini_frame;

   if (! FRAME_LIVE_P (f))
     return Qnil;
@@ -1557,13 +1557,14 @@ of them (the selected terminal frame) is actually displayed.
 	}
     }

-  is_tooltip_frame = !NILP (Fframe_parameter (frame, Qtooltip));
+  tip_or_mini_frame
+    = (!NILP (Fframe_parameter (frame, Qtooltip))
+       || !NILP (Fframe_parameter (frame, Qmini_frame)));

-  /* Run `delete-frame-functions' unless FORCE is `noelisp' or
-     frame is a tooltip.  FORCE is set to `noelisp' when handling
-     a disconnect from the terminal, so we don't dare call Lisp
-     code.  */
-  if (NILP (Vrun_hooks) || is_tooltip_frame)
+  /* Run `delete-frame-functions' unless FORCE is `noelisp' or FRAME is
+     a tip or mini-frame.  FORCE is set to `noelisp' when handling a
+     disconnect from the terminal, so we don't dare call Lisp code.  */
+  if (NILP (Vrun_hooks) || tip_or_mini_frame)
     ;
   else if (EQ (force, Qnoelisp))
     pending_funcalls
@@ -1815,7 +1816,7 @@ of them (the selected terminal frame) is actually displayed.
     }

   /* Cause frame titles to update--necessary if we now have just one frame.  */
-  if (!is_tooltip_frame)
+  if (!tip_or_mini_frame)
     update_mode_lines = 15;

   return Qnil;
@@ -4901,6 +4902,7 @@ or a list (- N) meaning -N pixels relative to bottom/right corner.
   DEFSYM (Qicon_left, "icon-left");
   DEFSYM (Qicon_top, "icon-top");
   DEFSYM (Qtooltip, "tooltip");
+  DEFSYM (Qmini_frame, "mini-frame");
   DEFSYM (Quser_position, "user-position");
   DEFSYM (Quser_size, "user-size");
   DEFSYM (Qwindow_id, "window-id");
@@ -5138,6 +5140,11 @@ even if the end of the buffer is shown (i.e. overscrolling).
                doc: /* Normal hook run when a frame loses input focus.  */);
   Vfocus_out_hook = Qnil;

+  DEFVAR_LISP ("move-frame-functions", Vmove_frame_functions,
+               doc: /* Functions run after a frame was moved.
+The functions are run with one arg, the frame that moved.  */);
+  Vmove_frame_functions = Qnil;
+
   DEFVAR_LISP ("delete-frame-functions", Vdelete_frame_functions,
 	       doc: /* Functions run before deleting a frame.
 The functions are run with one arg, the frame to be deleted.
diff --git a/src/frame.h b/src/frame.h
index 5e3ee68..16c5a92 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -342,6 +342,9 @@ struct frame
   /* Non-zero if this frame's faces need to be recomputed.  */
   bool_bf face_change : 1;

+  /* True means this a mini-frame.  */
+  bool_bf mini_frame : 1;
+
   /* Bitfield area ends here.  */

   /* Number of lines (rounded up) of tool bar.  REMOVE THIS  */
@@ -515,6 +518,12 @@ struct frame
 /* Most code should use these functions to set Lisp fields in struct frame.  */

 INLINE void
+fset_minibuffer_window (struct frame *f, Lisp_Object val)
+{
+  f->minibuffer_window = val;
+}
+
+INLINE void
 fset_buffer_list (struct frame *f, Lisp_Object val)
 {
   f->buffer_list = val;
diff --git a/src/keyboard.c b/src/keyboard.c
index 653f527..e4b4fcd 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -4048,6 +4048,14 @@ static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
 	  kbd_fetch_ptr = event + 1;
 	}
 #endif
+#if defined (HAVE_X11) || defined (HAVE_NTGUI)
+      else if (event->kind == MOVE_FRAME_EVENT)
+	{
+	  /* Make an event (move-frame (FRAME)).  */
+	  obj = list2 (Qmove_frame, list1 (event->ie.frame_or_window));
+	  kbd_fetch_ptr = event + 1;
+	}
+#endif
 #ifdef HAVE_XWIDGETS
       else if (event->kind == XWIDGET_EVENT)
 	{
@@ -10936,6 +10944,7 @@ struct event_head

   {SYMBOL_INDEX (Qfocus_in),            SYMBOL_INDEX (Qfocus_in)},
   {SYMBOL_INDEX (Qfocus_out),           SYMBOL_INDEX (Qfocus_out)},
+  {SYMBOL_INDEX (Qmove_frame),          SYMBOL_INDEX (Qmove_frame)},
   {SYMBOL_INDEX (Qdelete_frame),        SYMBOL_INDEX (Qdelete_frame)},
   {SYMBOL_INDEX (Qiconify_frame),       SYMBOL_INDEX (Qiconify_frame)},
   {SYMBOL_INDEX (Qmake_frame_visible),  SYMBOL_INDEX (Qmake_frame_visible)},
@@ -11108,6 +11117,7 @@ struct event_head
   DEFSYM (Qswitch_frame, "switch-frame");
   DEFSYM (Qfocus_in, "focus-in");
   DEFSYM (Qfocus_out, "focus-out");
+  DEFSYM (Qmove_frame, "move-frame");
   DEFSYM (Qdelete_frame, "delete-frame");
   DEFSYM (Qiconify_frame, "iconify-frame");
   DEFSYM (Qmake_frame_visible, "make-frame-visible");
@@ -11846,6 +11856,8 @@ shutdown when Emacs receives a fatal signal (e.g., a crash).
 			    "handle-focus-in");
   initial_define_lispy_key (Vspecial_event_map, "focus-out",
 			    "handle-focus-out");
+  initial_define_lispy_key (Vspecial_event_map, "move-frame",
+			    "handle-move-frame");
 }

 /* Mark the pointers in the kboard objects.
diff --git a/src/termhooks.h b/src/termhooks.h
index ff74d99..9829b50 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -202,6 +202,9 @@ enum event_kind

   FOCUS_OUT_EVENT,

+  /* Generated when a frame is moved.  */
+  MOVE_FRAME_EVENT,
+
   /* Generated when mouse moves over window not currently selected.  */
   SELECT_WINDOW_EVENT,

diff --git a/src/w32fns.c b/src/w32fns.c
index d6b54d1..70e0ab3 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -345,7 +345,7 @@ struct frame *
 static Lisp_Object unwind_create_frame (Lisp_Object);
 static void unwind_create_tip_frame (Lisp_Object);
 static void my_create_window (struct frame *);
-static void my_create_tip_window (struct frame *);
+static void my_create_tip_window (struct frame *, bool, Lisp_Object);

 /* TODO: Native Input Method support; see x_create_im.  */
 void x_set_foreground_color (struct frame *, Lisp_Object, Lisp_Object);
@@ -5065,42 +5065,39 @@ struct frame *
    messages for the tooltip.  Creating tooltips indirectly also creates
    deadlocks when tooltips are created for menu items.  */
 static void
-my_create_tip_window (struct frame *f)
+my_create_tip_window (struct frame *f, bool mini_frame, Lisp_Object owner)
 {
   RECT rect;
+  Window window;

   rect.left = rect.top = 0;
   rect.right = FRAME_PIXEL_WIDTH (f);
   rect.bottom = FRAME_PIXEL_HEIGHT (f);
-
   AdjustWindowRect (&rect, f->output_data.w32->dwStyle, false);

-  tip_window = FRAME_W32_WINDOW (f)
-    = CreateWindow (EMACS_CLASS,
-		    f->namebuf,
-		    f->output_data.w32->dwStyle,
-		    f->left_pos,
-		    f->top_pos,
-		    rect.right - rect.left,
-		    rect.bottom - rect.top,
-		    FRAME_W32_WINDOW (SELECTED_FRAME ()), /* owner */
-		    NULL,
-		    hinst,
-		    NULL);
-
-  if (tip_window)
+  if (window
+      = CreateWindow (EMACS_CLASS, f->namebuf, f->output_data.w32->dwStyle,
+		      f->left_pos, f->top_pos,
+		      rect.right - rect.left, rect.bottom - rect.top,
+		      (FRAME_W32_WINDOW /* owner */
+		       (mini_frame ? XFRAME (owner) : SELECTED_FRAME ())),
+		      NULL, hinst, NULL))
     {
-      SetWindowLong (tip_window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
-      SetWindowLong (tip_window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
-      SetWindowLong (tip_window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
-      SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
+      FRAME_W32_WINDOW (f) = window;
+      if (!mini_frame)
+	tip_window = FRAME_W32_WINDOW (f);
+
+      SetWindowLong (window, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
+      SetWindowLong (window, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
+      SetWindowLong (window, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
+      SetWindowLong (window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));

       /* Tip frames have no scrollbars.  */
-      SetWindowLong (tip_window, WND_VSCROLLBAR_INDEX, 0);
-      SetWindowLong (tip_window, WND_HSCROLLBAR_INDEX, 0);
+      SetWindowLong (window, WND_VSCROLLBAR_INDEX, 0);
+      SetWindowLong (window, WND_HSCROLLBAR_INDEX, 0);

       /* Do this to discard the default setting specified by our parent. */
-      ShowWindow (tip_window, SW_HIDE);
+      ShowWindow (window, SW_HIDE);
     }
 }

@@ -6515,7 +6512,8 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,


 /* Create a frame for a tooltip on the display described by DPYINFO.
-   PARMS is a list of frame parameters.  Value is the frame.
+   PARMS is a list of frame parameters.  MINI_FRAME true means to create
+   a mini-frame.  Value is the frame.

    Note that functions called here, esp. x_default_parameter can
    signal errors, for instance when a specified color name is
@@ -6523,7 +6521,7 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
    when this happens.  */

 static Lisp_Object
-x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
+x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms, bool mini_frame, Lisp_Object owner)
 {
   struct frame *f;
   Lisp_Object frame;
@@ -6558,7 +6556,10 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
   f->wants_modeline = false;
   XSETFRAME (frame, f);

-  record_unwind_protect (unwind_create_tip_frame, frame);
+  if (mini_frame)
+    record_unwind_protect (do_unwind_create_frame, frame);
+  else
+    record_unwind_protect (unwind_create_tip_frame, frame);

   /* By setting the output method, we're essentially saying that
      the frame is live, as per FRAME_LIVE_P.  If we get a signal
@@ -6606,7 +6607,8 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
      that are needed to determine window geometry.  */
   x_default_font_parameter (f, parms);

-  x_default_parameter (f, parms, Qborder_width, make_number (2),
+  x_default_parameter (f, parms, Qborder_width,
+		       make_number (mini_frame ? 0 : 2),
 		       "borderWidth", "BorderWidth", RES_TYPE_NUMBER);
   /* This defaults to 2 in order to match xterm.  We recognize either
      internalBorderWidth or internalBorder (which is what xterm calls
@@ -6622,7 +6624,8 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
 		       parms);
     }

-  x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
+  x_default_parameter (f, parms, Qinternal_border_width,
+		       make_number (mini_frame ? 0 : 1),
 		       "internalBorderWidth", "internalBorderWidth",
 		       RES_TYPE_NUMBER);
   /* Also do the stuff which must be set before the window exists.  */
@@ -6642,7 +6645,29 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
      init_iterator with a null face cache, which should not happen.  */
   init_frame_faces (f);

-  f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
+  /* Handle `child-window' and `border-width' separately for
+     mini-frames.  */
+  if (mini_frame)
+    {
+      Lisp_Object border_width = Fcdr (Fassq (Qborder_width, f->param_alist));
+
+      f->output_data.w32->dwStyle =
+	(!NILP (Fassq (Qchild_window, parms))) ? WS_CHILD : WS_POPUP;
+
+      /* Always disable input.  */
+      f->output_data.w32->dwStyle =
+	f->output_data.w32->dwStyle | WS_DISABLED;
+
+      /* Have Windows draw a "thin-line border".  `border-width' is
+	 usually dismissed on Windows but for mini frames, if it's
+	 non-zero, draw a standard thin border around the frame. */
+      if (NUMBERP (border_width) && (XINT (border_width) > 0))
+	f->output_data.w32->dwStyle =
+	  f->output_data.w32->dwStyle | WS_BORDER;
+    }
+  else
+    f->output_data.w32->dwStyle = WS_DISABLED | WS_BORDER | WS_POPUP;
+
   f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;

   x_figure_window_size (f, parms, true, &x_width, &x_height);
@@ -6656,7 +6681,7 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
   f->bottom_divider_width = 0;

   block_input ();
-  my_create_tip_window (f);
+  my_create_tip_window (f, mini_frame, owner);
   unblock_input ();

   x_make_gc (f);
@@ -6680,8 +6705,10 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
   SET_FRAME_LINES (f, 0);
   adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
 		     height * FRAME_LINE_HEIGHT (f), 0, true, Qtip_frame);
-  /* Add `tooltip' frame parameter's default value. */
-  if (NILP (Fframe_parameter (frame, Qtooltip)))
+  /* Add `mini-frame' or `tooltip' frame parameter's default value. */
+  if (mini_frame && NILP (Fframe_parameter (frame, Qmini_frame)))
+    Fmodify_frame_parameters (frame, Fcons (Fcons (Qmini_frame, Qt), Qnil));
+  if (!mini_frame && NILP (Fframe_parameter (frame, Qtooltip)))
     Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));

   /* Set up faces after all frame parameters are known.  This call
@@ -7060,7 +7087,7 @@ with offset DY added (default is -10).
       /* Create a frame for the tooltip, and record it in the global
 	 variable tip_frame.  */
       struct frame *f;		/* The value is unused.  */
-      if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
+      if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, false, Qnil)))
 	{
 	  /* Creating the tip frame failed.  */
 	  unblock_input ();
@@ -7071,6 +7098,7 @@ with offset DY added (default is -10).
   tip_f = XFRAME (tip_frame);
   window = FRAME_ROOT_WINDOW (tip_f);
   set_window_buffer (window, Fget_buffer_create (tip), false, false);
+
   w = XWINDOW (window);
   w->pseudo_window_p = true;

@@ -7179,6 +7207,89 @@ with offset DY added (default is -10).
 {
   return x_hide_tip (!tooltip_reuse_hidden_frame);
 }
+
+
+DEFUN ("w32-create-mini-frame", Fw32_create_mini_frame, Sw32_create_mini_frame, 1, 2, 0,
+       doc: /* Create a mini-frame.
+FRAME is the frame where to attach this one to.  PARAMETERS is an alist of
+frame paramaters.
+
+The following parameters are special:
+
+- 'child-window" makes the new frame a child window of FRAME.  This has
+  a number of consequences.  On Windows 'alpha' does not necessarily
+  work if this is set.
+
+- 'external-border' enables external border.  */)
+     (Lisp_Object frame, Lisp_Object parameters)
+{
+  struct frame *f = decode_window_system_frame (frame);
+  Lisp_Object tip_frame;
+  ptrdiff_t count = SPECPDL_INDEX ();
+  long window_prompting = 0;
+
+  if (!FRAME_W32_P (f) || NILP (FRAME_MINIBUF_WINDOW(f)))
+    error ("Cannot create tip-like frame for non-GUI or minibuffer-less frame");
+
+  /* Make copy of frame parameters because the original is in pure
+     storage now. */
+  parameters = Fcopy_alist (parameters);
+
+  specbind (Qinhibit_redisplay, Qt);
+  block_input ();
+  if (!NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parameters, true, frame)))
+    {
+      struct frame *tip_f;
+      struct window *w;
+      int old_windows_or_buffers_changed = windows_or_buffers_changed;
+      Lisp_Object window, tem;
+      Lisp_Object visibility;
+      int x_width = 0, x_height = 0;
+
+      tip_f = XFRAME (tip_frame);
+      window = FRAME_ROOT_WINDOW (tip_f);
+      w = XWINDOW (window);
+      w->pseudo_window_p = true;
+
+      fset_minibuffer_window (tip_f, FRAME_MINIBUF_WINDOW (f));
+      FRAME_EXTERNAL_MENU_BAR (tip_f) = false;
+
+      window_prompting
+	= x_figure_window_size (tip_f, parameters, true, &x_width, &x_height);
+
+      tip_f->mini_frame = true;
+      /* Allow x_set_window_size, now.  */
+      tip_f->can_x_set_window_size = true;
+
+      if (x_width > 0)
+	SET_FRAME_WIDTH (tip_f, x_width);
+      if (x_height > 0)
+	SET_FRAME_HEIGHT (tip_f, x_height);
+
+      adjust_frame_size (tip_f, FRAME_TEXT_WIDTH (tip_f), FRAME_TEXT_HEIGHT (tip_f),
+			 0, true, Qx_create_frame_2); /* NEW SYMBOL NEEDED */
+
+      visibility = x_get_arg (FRAME_DISPLAY_INFO (f), parameters,
+			      Qvisibility, 0, 0, RES_TYPE_SYMBOL);
+      if (EQ (visibility, Qunbound) || !NILP (visibility))
+	SET_FRAME_VISIBLE (tip_f, 1);
+
+      ShowWindow (FRAME_W32_WINDOW (tip_f),
+		  (EQ (visibility, Qunbound) || !NILP (visibility))
+		  ? SW_SHOWNOACTIVATE : SW_HIDE);
+
+      w->must_be_updated_p = true;
+      update_single_window (w);
+      windows_or_buffers_changed = old_windows_or_buffers_changed;
+
+      for (tem = parameters; CONSP (tem); tem = XCDR (tem))
+	if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+	  fset_param_alist (tip_f, Fcons (XCAR (tem), tip_f->param_alist));
+    }
+
+  unblock_input ();
+  return unbind_to (count, tip_frame);
+}
 \f
 /***********************************************************************
 			File selection dialog
@@ -8563,6 +8674,58 @@ value is a list of the form (LEFT, TOP, RIGHT, BOTTOM).  All values are
     }
 }

+static Lisp_Object
+w32_frame_list_z_order (struct w32_display_info *dpyinfo, HWND window, Lisp_Object frames)
+{
+  while (window)
+    {
+      HWND child;
+      struct frame *f = x_window_to_frame (dpyinfo, window);
+      Lisp_Object frame;
+
+      /* Process child windows first - they precede their parent in the
+	 z-order.  */
+      block_input ();
+      child = GetWindow (window, GW_CHILD);
+      unblock_input ();
+      if (child)
+	frames = w32_frame_list_z_order (dpyinfo, child, frames);
+
+      if (f)
+	{
+	  XSETFRAME (frame, f);
+	  frames = Fcons (frame, frames);
+	}
+
+      block_input ();
+      window = GetNextWindow (window, GW_HWNDNEXT);
+      unblock_input ();
+    }
+
+  return frames;
+}
+
+DEFUN ("w32-frame-list-z-order", Fw32_frame_list_z_order,
+       Sw32_frame_list_z_order, 0, 1, 0,
+       doc: /* Return list of Emacs' frames, in Z (stacking) order.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+Frames are listed from bottommost (first) to topmost (last).  Return
+nil if DISPLAY contains no Emacs frame.  */)
+  (Lisp_Object display)
+{
+  struct w32_display_info *dpyinfo = check_x_display_info (display);
+  HWND window;
+
+  block_input ();
+  window = GetTopWindow (NULL);
+  unblock_input ();
+
+  return w32_frame_list_z_order (dpyinfo, window, Qnil);
+}
+
 DEFUN ("w32-mouse-absolute-pixel-position", Fw32_mouse_absolute_pixel_position,
        Sw32_mouse_absolute_pixel_position, 0, 0, 0,
        doc: /* Return absolute position of mouse cursor in pixels.
@@ -9709,6 +9872,41 @@ enum NI_Severity {

 #endif	/* WINDOWSNT && !HAVE_DBUS */

+/* XXXXXXXXXXXXXXXXXXXXX */
+#ifdef WINDOWSNT
+DEFUN ("w32-focus", Fw32_focus, Sw32_focus,
+       0, 0, 0,
+       doc: /* Return t if the selected frame has focus.  */)
+     (void)
+{
+  HWND focus_window;
+
+  block_input ();
+  focus_window = GetFocus ();
+  unblock_input ();
+
+  return focus_window == NULL ? Qnil : Qt;
+}
+
+DEFUN ("w32-foreground-window", Fw32_foreground_window, Sw32_foreground_window,
+       0, 0, 0,
+       doc: /* Return frame of current foreground window, if it's ours.  */)
+     (void)
+{
+  Lisp_Object frame;
+  struct frame *f;
+  struct w32_display_info *dpyinfo = &one_w32_display_info;
+
+  block_input ();
+  f = x_window_to_frame (dpyinfo, GetForegroundWindow ());
+  unblock_input ();
+  XSETFRAME (frame, f);
+
+  return frame;
+}
+
+#endif
+/* XXXXXXXXXXXXXXXXXXXXXXXX */
 \f
 /***********************************************************************
 			    Initialization
@@ -9781,6 +9979,7 @@ enum NI_Severity {
   DEFSYM (Qmm_size, "mm-size");
   DEFSYM (Qframes, "frames");
   DEFSYM (Qtip_frame, "tip-frame");
+  DEFSYM (Qchild_window, "child-window");
   DEFSYM (Qassq_delete_all, "assq-delete-all");
   DEFSYM (Qunicode_sip, "unicode-sip");
 #if defined WINDOWSNT && !defined HAVE_DBUS
@@ -10094,6 +10293,15 @@ successive mouse move (or scroll bar drag) events before they are
 This variable has effect only on Windows Vista and later.  */);
   w32_disable_new_uniscribe_apis = 0;

+  /* XXXXXXXXXXXXXX */
+  DEFVAR_BOOL ("w32-keyboard-hook-active",
+	       w32_keyboard_hook_active,
+	       doc: /* Non-nil means w32 hotkey registration is activated.
+Set this to nil to get the old behavior of hotkey handling; this should
+only be necessary if the default setting causes problems.  */);
+  w32_keyboard_hook_active = true;
+  /* XXXXXXXXXXXXXX */
+
   DEFVAR_LISP ("w32-tooltip-extra-pixels",
 	       Vw32_tooltip_extra_pixels,
 	       doc: /* Number of pixels added after tooltip text.
@@ -10134,6 +10342,7 @@ successive mouse move (or scroll bar drag) events before they are
   defsubr (&Sx_display_list);
   defsubr (&Sw32_frame_geometry);
   defsubr (&Sw32_frame_edges);
+  defsubr (&Sw32_frame_list_z_order);
   defsubr (&Sw32_mouse_absolute_pixel_position);
   defsubr (&Sw32_set_mouse_absolute_pixel_position);
   defsubr (&Sx_synchronize);
@@ -10159,6 +10368,10 @@ successive mouse move (or scroll bar drag) events before they are
 #endif

 #ifdef WINDOWSNT
+  /* XXXXXXXXXXXXXXX */
+  defsubr (&Sw32_focus);
+  defsubr (&Sw32_foreground_window);
+  /* XXXXXXXXXXXXXXX */
   defsubr (&Sfile_system_info);
   defsubr (&Sdefault_printer_name);
 #endif
@@ -10166,6 +10379,7 @@ successive mouse move (or scroll bar drag) events before they are
   defsubr (&Sset_message_beep);
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
+  defsubr (&Sw32_create_mini_frame);
   tip_timer = Qnil;
   staticpro (&tip_timer);
   tip_frame = Qnil;
diff --git a/src/w32term.c b/src/w32term.c
index 5a11e2a..04c6178 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5015,7 +5015,11 @@ static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object
 	  f = x_window_to_frame (dpyinfo, msg.msg.hwnd);

 	  if (f && !FRAME_ICONIFIED_P (f))
-	    x_real_positions (f, &f->left_pos, &f->top_pos);
+	    {
+	      x_real_positions (f, &f->left_pos, &f->top_pos);
+	      inev.kind = MOVE_FRAME_EVENT;
+	      XSETFRAME (inev.frame_or_window, f);
+	    }

 	  check_visibility = 1;
 	  break;
@@ -6444,9 +6448,11 @@ struct xim_inst_t
 	 frames that were truely hidden (using make-frame-invisible), so
 	 we need it to avoid Bug#5482.  It seems that iconified is only
 	 set for minimized windows that are still visible, so use that to
-	 determine the appropriate flag to pass ShowWindow.  */
+	 determine the appropriate flag to pass to ShowWindow.  */
       my_show_window (f, FRAME_W32_WINDOW (f),
-                      FRAME_ICONIFIED_P (f) ? SW_RESTORE : SW_SHOWNORMAL);
+		      f->mini_frame ? SW_SHOWNOACTIVATE
+                      : FRAME_ICONIFIED_P (f) ? SW_RESTORE
+		      : SW_SHOWNORMAL);
     }

   /* Synchronize to ensure Emacs knows the frame is visible
@@ -6531,7 +6537,8 @@ struct xim_inst_t
   x_set_bitmap_icon (f);

   /* Simulate the user minimizing the frame.  */
-  SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
+/**   SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0); **/
+  my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWMINNOACTIVE);

   SET_FRAME_VISIBLE (f, 0);
   SET_FRAME_ICONIFIED (f, true);
diff --git a/src/window.c b/src/window.c
index e123b89..2ff0dc5 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1896,6 +1896,115 @@ of the (first) text line, YPOS is negative.
   return list4i (row->height + min (0, row->y) - crop, i, row->y, crop);
 }

+DEFUN ("window-lines-pixel-dimensions", Fwindow_lines_pixel_dimensions, Swindow_lines_pixel_dimensions, 0, 6, 0,
+       doc: /* Return pixel dimensions of WINDOW's lines.
+The return value is a list of the x- and y-coordinates of the lower
+right corner of the last character of each line.  Return nil if the
+current glyph matrix of WINDOW is not up-to-date.
+
+Optional argument WINDOW specifies the window whose lines' dimensions
+shall be returned.  Nil or omitted means to return the dimensions for
+the selected window.
+
+FIRST, if non-nil, specifies the first line whose dimensions shall be
+returned.  If FIRST is nil and BODY is non-nil, start with the first
+text line of WINDOW.  Otherwise, start with the first line of WINDOW.
+
+LAST, if non-nil, specifies the last line whose dimensions shall be
+returned.  If LAST is nil and BODY is non-nil, the last line is the last
+line of the body (text area) of WINDOW.  Otherwise, last is the last
+line of WINDOW.
+
+INVERSE, if non-nil, means that the y-pixel value returned should
+specify the number of pixels from the left corner of the last glyph of
+each line to the right edge (body edge if BODY is non-nil) of WINDOW.
+INVERSE nil means to count from the left edge (body edge if BODY is
+non-nil) of WINDOW.
+
+LEFT non-nil means to return the x- and y-coordinates of the lower left
+corner of the leftmost character on each line.  This is the value that
+should be used for buffers that mostly display text from right to
+left.  */)
+  (Lisp_Object window, Lisp_Object first, Lisp_Object last, Lisp_Object body, Lisp_Object inverse, Lisp_Object left)
+{
+  struct window *w = decode_live_window (window);
+  struct buffer *b;
+  struct glyph_row *row, *end_row;
+  int max_y = NILP (body) ? WINDOW_PIXEL_HEIGHT (w) : window_text_bottom_y (w);
+  Lisp_Object rows = Qnil;
+  int window_width = NILP (body) ? w->pixel_width : window_body_width (w, true);
+  int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+  int subtract = NILP (body) ? 0 : header_line_height;
+  bool invert = !NILP (inverse);
+  bool left_flag = !NILP (left);
+
+  if (noninteractive || w->pseudo_window_p)
+    return Qnil;
+
+  CHECK_BUFFER (w->contents);
+  b = XBUFFER (w->contents);
+
+  /* Fail if current matrix is not up-to-date.  */
+  if (!w->window_end_valid
+      || windows_or_buffers_changed
+      || b->clip_changed
+      || b->prevent_redisplay_optimizations_p
+      || window_outdated (w))
+    return Qnil;
+
+  if (NILP (first))
+    row = MATRIX_ROW (w->current_matrix, 0);
+  else if (NUMBERP (first))
+    {
+      CHECK_RANGED_INTEGER (first, 0, w->current_matrix->nrows);
+      row = MATRIX_ROW (w->current_matrix, XINT (first));
+    }
+  else if (!NILP (body))
+    row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
+  else
+    error ("Invalid specification of first line");
+
+  if (NILP (last))
+    end_row = MATRIX_ROW (w->current_matrix, w->current_matrix->nrows);
+  else if (NUMBERP (first))
+    {
+      CHECK_RANGED_INTEGER (first, 0, w->current_matrix->nrows);
+      end_row = MATRIX_ROW (w->current_matrix, XINT (last));
+    }
+  else if (!NILP (body))
+    end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
+  else
+    error ("Invalid specification of last line");
+
+  while (row <= end_row && row->enabled_p
+	 && row->y + row->height < max_y)
+    {
+
+      if (left_flag)
+	{
+	  struct glyph *glyph = row->glyphs[TEXT_AREA];
+
+	  rows = Fcons (Fcons (make_number
+			       (invert
+				? glyph->pixel_width
+				: window_width - glyph->pixel_width),
+			       make_number (row->y + row->height - subtract)),
+			rows);
+	}
+      else
+	rows = Fcons (Fcons (make_number
+			     (invert
+			      ? window_width - row->pixel_width
+			      : row->pixel_width), /* maybe add left
+						      margin here */
+			     make_number (row->y + row->height - subtract)),
+		      rows);
+      row++;
+    }
+
+  return Fnreverse (rows);
+}
+
 DEFUN ("window-dedicated-p", Fwindow_dedicated_p, Swindow_dedicated_p,
        0, 1, 0,
        doc: /* Return non-nil when WINDOW is dedicated to its buffer.
@@ -7571,6 +7680,7 @@ this value for parameters without read syntax (like windows or frames).
   defsubr (&Sset_window_point);
   defsubr (&Sset_window_start);
   defsubr (&Swindow_dedicated_p);
+  defsubr (&Swindow_lines_pixel_dimensions);
   defsubr (&Sset_window_dedicated_p);
   defsubr (&Swindow_display_table);
   defsubr (&Sset_window_display_table);
diff --git a/src/xdisp.c b/src/xdisp.c
index 14d6f8f..b31e77d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11367,10 +11367,15 @@ static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
   struct frame *sf = SELECTED_FRAME ();

   mini_window = FRAME_MINIBUF_WINDOW (sf);
+
+  /* Don't redisplay if the selected frame has no mini_window.  This may
+     be the case for tooltip frames.  */
+  if (NILP (mini_window))
+    return;
   w = XWINDOW (mini_window);
   f = XFRAME (WINDOW_FRAME (w));

-  /* Don't display if frame is invisible or not yet initialized.  */
+  /* Don't redisplay if frame is invisible or not yet initialized.  */
   if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
     return;

@@ -11713,7 +11718,8 @@ static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
   if ((FRAME_WINDOW_P (f)
        || FRAME_MINIBUF_ONLY_P (f)
        || f->explicit_name)
-      && NILP (Fframe_parameter (frame, Qtooltip)))
+      && NILP (Fframe_parameter (frame, Qtooltip))
+      && NILP (Fframe_parameter (frame, Qmini_frame)))
     {
       /* Do we have more than one visible frame on this X display?  */
       Lisp_Object tail, other_frame, fmt;
diff --git a/src/xfns.c b/src/xfns.c
index 798dc49..2643f11 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4738,6 +4738,60 @@ value is a list of the form (LEFT, TOP, RIGHT, BOTTOM).  All values are
 				 : Qnative_edges));
 }

+static Lisp_Object
+x_frame_list_z_order (Display* dpy, struct x_display_info *dpyinfo,  Window window, Lisp_Object frames)
+{
+  Window root, parent, *children;
+  unsigned int nchildren;
+  int i;
+
+  block_input ();
+  if (XQueryTree (dpy, window, &root, &parent, &children, &nchildren))
+    {
+      unblock_input ();
+      for (i = nchildren - 1; i >= 0; i--)
+	{
+	  struct frame *f = x_window_to_frame (dpyinfo, children[i]);
+
+	  /* Process child windows first - they precede their paarent
+	     in the z-order.  */
+	  frames = x_frame_list_z_order (dpy, dpyinfo, children[i], frames);
+
+	  if (f)
+	    {
+	      Lisp_Object frame;
+
+	      XSETFRAME (frame, f);
+	      frames = Fcons (frame, frames);
+	    }
+	}
+
+      if (children) XFree ((char *)children);
+    }
+  else
+    unblock_input ();
+
+  return frames;
+}
+
+
+DEFUN ("x-frame-list-z-order", Fx_frame_list_z_order,
+       Sx_frame_list_z_order, 0, 1, 0,
+       doc: /* Return list of Emacs' frames, in Z (stacking) order.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display.
+
+Frames are listed from bottommost (first) to topmost (last).  Return
+nil if DISPLAY contains no Emacs frame.  */)
+  (Lisp_Object display)
+{
+  struct x_display_info *dpyinfo = check_x_display_info (display);
+  Display *dpy = dpyinfo->display;
+
+  return x_frame_list_z_order (dpy, dpyinfo, dpyinfo->root_window, Qnil);
+}
+
 DEFUN ("x-mouse-absolute-pixel-position", Fx_mouse_absolute_pixel_position,
        Sx_mouse_absolute_pixel_position, 0, 0, 0,
        doc: /* Return absolute position of mouse cursor in pixels.
@@ -5355,7 +5409,7 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
    when this happens.  */

 static Lisp_Object
-x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
+x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms,  bool mini_frame, Lisp_Object owner)
 {
   struct frame *f;
   Lisp_Object frame;
@@ -5381,7 +5435,10 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
   f = make_frame (false);
   f->wants_modeline = false;
   XSETFRAME (frame, f);
-  record_unwind_protect (unwind_create_tip_frame, frame);
+  if (mini_frame)
+    record_unwind_protect (do_unwind_create_frame, frame);
+  else
+    record_unwind_protect (unwind_create_tip_frame, frame);

   f->terminal = dpyinfo->terminal;

@@ -5495,7 +5552,8 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
 		       parms);
     }

-  x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
+  x_default_parameter (f, parms, Qinternal_border_width,
+		       make_number (mini_frame ? 0 : 1),
 		       "internalBorderWidth", "internalBorderWidth",
 		       RES_TYPE_NUMBER);
   x_default_parameter (f, parms, Qright_divider_width, make_number (0),
@@ -5545,17 +5603,30 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
       = f->output_data.x->text_cursor;
     /* Arrange for getting MapNotify and UnmapNotify events.  */
     attrs.event_mask = StructureNotifyMask;
-    tip_window
-      = FRAME_X_WINDOW (f)
-      = XCreateWindow (FRAME_X_DISPLAY (f),
-		       FRAME_DISPLAY_INFO (f)->root_window,
-		       /* x, y, width, height */
-		       0, 0, 1, 1,
-		       /* Border.  */
-		       f->border_width,
-		       CopyFromParent, InputOutput, CopyFromParent,
-		       mask, &attrs);
-    XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
+    if (mini_frame && !NILP (Fassq (Qchild_window, parms)))
+      FRAME_X_WINDOW (f)
+	= (XCreateSimpleWindow
+	   (FRAME_X_DISPLAY (f),
+	    FRAME_X_WINDOW (XFRAME (owner)),
+	    /* x, y, width, height */
+	    f->left_pos, f->top_pos, 1, 1,
+	    f->border_width,
+	    CopyFromParent, CopyFromParent));
+    else
+      FRAME_X_WINDOW (f)
+	= (XCreateWindow
+	   (FRAME_X_DISPLAY (f),
+	    FRAME_DISPLAY_INFO (f)->root_window,
+	    /* x, y, width, height */
+	    f->left_pos, f->top_pos, 1, 1,
+	    /* Border.  */
+	    f->border_width,
+	    CopyFromParent, InputOutput, CopyFromParent,
+	    mask, &attrs));
+
+    if (!mini_frame) tip_window = FRAME_X_WINDOW (f);
+
+    XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
                      FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
                      XA_ATOM, 32, PropModeReplace,
                      (unsigned char *)&type, 1);
@@ -6038,7 +6109,7 @@ with offset DY added (default is -10).

       /* Create a frame for the tooltip, and record it in the global
 	 variable tip_frame.  */
-      if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
+      if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, false, Qnil)))
 	/* Creating the tip frame failed.  */
 	return unbind_to (count, Qnil);
     }
@@ -6131,6 +6202,90 @@ with offset DY added (default is -10).
   return x_hide_tip (!tooltip_reuse_hidden_frame);
 }

+DEFUN ("x-create-mini-frame", Fx_create_mini_frame, Sx_create_mini_frame, 1, 2, 0,
+       doc:  /* Create a mini-frame.
+FRAME is the frame where to attach this one to.  PARAMETERS is an alist of
+frame paramaters.
+
+The following parameters are special:
+
+- 'child-window" makes the new frame a child window of FRAME.  This has
+  a number of consequences.  On Windows 'alpha' does not necessarily
+  work if this is set.
+
+- 'external-border' enables external border.  */)
+     (Lisp_Object frame, Lisp_Object parameters)
+{
+  struct frame *f = decode_window_system_frame (frame);
+  struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
+  Lisp_Object tip_frame;
+  ptrdiff_t count = SPECPDL_INDEX ();
+
+  if (!dpyinfo->terminal->name)
+    error ("Terminal is not live, can't create new frames on it");
+
+  if (NILP (FRAME_MINIBUF_WINDOW(f)))
+    error ("Cannot create tip-like frame for minibuffer-less frame");
+
+  /* Make copy of frame parameters because the original is in pure
+     storage now. */
+  parameters = Fcopy_alist (parameters);
+
+  specbind (Qinhibit_redisplay, Qt);
+  block_input ();
+  if (!NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parameters, true, frame)))
+    {
+      struct frame *tip_f;
+      struct window *w;
+      int old_windows_or_buffers_changed = windows_or_buffers_changed;
+      Lisp_Object window, tem;
+      Lisp_Object visibility;
+      int x_width = 0, x_height = 0;
+
+      tip_f = XFRAME (tip_frame);
+      window = FRAME_ROOT_WINDOW (tip_f);
+      w = XWINDOW (window);
+      w->pseudo_window_p = true;
+
+      fset_minibuffer_window (tip_f, FRAME_MINIBUF_WINDOW (f));
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+      FRAME_EXTERNAL_MENU_BAR (tip_f) = false;
+#endif /* not USE_X_TOOLKIT && not USE_GTK */
+
+      x_figure_window_size (tip_f, parameters, true, &x_width, &x_height);
+
+      tip_f->mini_frame = true;
+      /* Allow x_set_window_size, now.  */
+      tip_f->can_x_set_window_size = true;
+
+      if (x_width > 0)
+	SET_FRAME_WIDTH (tip_f, x_width);
+      if (x_height > 0)
+	SET_FRAME_HEIGHT (tip_f, x_height);
+
+      adjust_frame_size (tip_f, FRAME_TEXT_WIDTH (tip_f), FRAME_TEXT_HEIGHT (tip_f),
+			 0, true, Qx_create_frame_2); /* NEW SYMBOL NEEDED */
+
+      visibility = x_get_arg (FRAME_DISPLAY_INFO (f), parameters,
+			      Qvisibility, 0, 0, RES_TYPE_SYMBOL);
+      if (EQ (visibility, Qunbound) || !NILP (visibility))
+	SET_FRAME_VISIBLE (tip_f, 1);
+
+      /* Map tip-like frame.  */
+      XMapRaised (FRAME_X_DISPLAY (tip_f), FRAME_X_WINDOW (tip_f));
+
+      w->must_be_updated_p = true;
+      update_single_window (w);
+      windows_or_buffers_changed = old_windows_or_buffers_changed;
+
+      for (tem = parameters; CONSP (tem); tem = XCDR (tem))
+	if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem))))
+	  fset_param_alist (tip_f, Fcons (XCAR (tem), tip_f->param_alist));
+    }
+
+  unblock_input ();
+  return unbind_to (count, tip_frame);
+}
 \f
 /***********************************************************************
 			File selection dialog
@@ -6792,6 +6947,7 @@ FRAMES should be nil (the selected frame), a frame, or a list of
   DEFSYM (Qcancel_timer, "cancel-timer");
   DEFSYM (Qfont_parameter, "font-parameter");
   DEFSYM (Qmono, "mono");
+  DEFSYM (Qchild_window, "child-window");
   DEFSYM (Qassq_delete_all, "assq-delete-all");

 #ifdef USE_CAIRO
@@ -6985,6 +7141,7 @@ FRAMES should be nil (the selected frame), a frame, or a list of
   defsubr (&Sx_display_monitor_attributes_list);
   defsubr (&Sx_frame_geometry);
   defsubr (&Sx_frame_edges);
+  defsubr (&Sx_frame_list_z_order);
   defsubr (&Sx_mouse_absolute_pixel_position);
   defsubr (&Sx_set_mouse_absolute_pixel_position);
   defsubr (&Sx_wm_set_size_hint);
@@ -6997,6 +7154,7 @@ FRAMES should be nil (the selected frame), a frame, or a list of

   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
+  defsubr (&Sx_create_mini_frame);
   tip_timer = Qnil;
   staticpro (&tip_timer);
   tip_frame = Qnil;
diff --git a/src/xterm.c b/src/xterm.c
index cd1d712..03d53c6 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -4252,7 +4252,7 @@ Status x_parse_color (struct frame *f, const char *color_name,
 /* Return the Emacs frame-object corresponding to an X window.
    It could be the frame's main window or an icon window.  */

-static struct frame *
+struct frame *
 x_window_to_frame (struct x_display_info *dpyinfo, int wdesc)
 {
   Lisp_Object tail, frame;
@@ -8476,7 +8476,20 @@ static void xembed_send_message (struct frame *f, Time,
           if (FRAME_GTK_OUTER_WIDGET (f)
               && gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
 #endif
-	    x_real_positions (f, &f->left_pos, &f->top_pos);
+
+
+	    {
+	      int old_left = f->left_pos;
+	      int old_top = f->top_pos;
+
+	      x_real_positions (f, &f->left_pos, &f->top_pos);
+
+	      if (old_left != f->left_pos || old_top != f->top_pos)
+		{
+		  inev.ie.kind = MOVE_FRAME_EVENT;
+		  XSETFRAME (inev.ie.frame_or_window, f);
+		}
+	    }

 #ifdef HAVE_X_I18N
           if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
diff --git a/src/xterm.h b/src/xterm.h
index 675a484..c61a339 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1086,6 +1086,7 @@ extern bool x_alloc_lighter_color_for_widget (Widget, Display *, Colormap,
 extern void x_cr_draw_frame (cairo_t *, struct frame *);
 extern Lisp_Object x_cr_export_frames (Lisp_Object, cairo_surface_type_t);
 #endif
+extern struct frame *x_window_to_frame (struct x_display_info *, int);

 INLINE int
 x_display_pixel_height (struct x_display_info *dpyinfo)


[-- Attachment #3: mini-frame.el --]
[-- Type: application/emacs-lisp, Size: 13768 bytes --]

      reply	other threads:[~2016-07-15 16:41 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-12 21:47 Latest master broken on Cocoa/NS João Távora
2016-07-12 22:05 ` John Wiegley
2016-07-12 22:06 ` João Távora
2016-07-12 22:26   ` John Wiegley
2016-07-14  5:41     ` Dmitry Antipov
2016-07-14  6:26       ` John Wiegley
2016-07-15  6:41         ` Dmitry Antipov
2016-07-15  6:46           ` John Wiegley
2016-07-15  7:25           ` Eli Zaretskii
2016-07-15  7:28           ` martin rudalics
2016-07-15  8:02             ` Eli Zaretskii
2016-07-15  9:10               ` martin rudalics
2016-07-15 13:35           ` Stefan Monnier
2016-07-15 13:51             ` Clément Pit--Claudel
2016-07-15 14:09               ` Eli Zaretskii
2016-07-15 14:21                 ` Clément Pit--Claudel
2016-07-15 14:25                   ` Eli Zaretskii
2016-07-15 15:14                     ` Clément Pit--Claudel
2016-07-15 16:04                       ` Eli Zaretskii
2016-07-15 16:16                         ` Clément Pit--Claudel
2016-07-15 17:37                           ` Eli Zaretskii
2016-07-15 14:08             ` Dmitry Gutov
2016-07-15 15:20               ` martin rudalics
2016-07-15 16:12                 ` Clément Pit--Claudel
2016-07-15 16:41                   ` martin rudalics [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=57891222.1060900@gmx.at \
    --to=rudalics@gmx.at \
    --cc=clement.pit@gmail.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.