emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master e462308: Fix some tooltip related problems


From: Martin Rudalics
Subject: [Emacs-diffs] master e462308: Fix some tooltip related problems
Date: Thu, 18 Jan 2018 04:38:45 -0500 (EST)

branch: master
commit e462308f03c9c16c47abc82d6f339ca9d18898f9
Author: Martin Rudalics <address@hidden>
Commit: Martin Rudalics <address@hidden>

    Fix some tooltip related problems
    
    Replace 'tooltip' frame parameter with a 'tooltip' member in
    the frame structure.  For GTK+ builds use 'tip_last_frame' to
    find the frame for which the currently visible tooltip was
    made.  For modeline help-echoing have tooltips show applicable
    actions only.
    
    * lisp/bindings.el (mode-line-default-help-echo): New function
    as default value of homonymous option.
    * src/dispextern.h (tip_frame, tip_window): Remove
    declarations.
    * src/frame.c (make_frame): Initialize new frame structure
    member 'tooltip'.
    (Fframe_list, other_frames): Rewrite with new macro
    FRAME_TOOLTIP_P.
    * src/frame.h (struct frame): New member 'tooltip'.
    (FRAME_TOOLTIP_P): New macro.
    * src/gtkutil.c (xg_prepare_tooltip, xg_hide_tooltip): Rewrite
    using boolean return values.
    * src/nsfns.m (tip_frame): Remove declaration.
    * src/w32fns.c (w32_display_monitor_attributes_list)
    (w32_display_monitor_attributes_list_fallback): Rewrite with
    new macro FRAME_TOOLTIP_P.
    (tip_last_string, tip_last_frame, tip_last_parms): New Lisp
    scalars replacing Lisp vector last_show_tip_args.
    (x_create_tip_frame): Set new frame's 'tooltip' structure
    member to true.
    (x_hide_tip): Additionally test tip_frame for liveness.
    (Fx_show_tip): Handle last_show_tip_args to tip_last_frame,
    tip_last_string and tip_last_parms conversion.
    (syms_of_w32fns): staticpro tip_last_frame, tip_last_string
    and tip_last_parms instead of last_show_tip_args.
    * src/w32term.c (w32_read_socket, x_new_font): Rewrite with
    new macro FRAME_TOOLTIP_P.
    * src/w32term.h (tip_window): Add external declaration.
    * src/xdisp.c (x_consider_frame_title, prepare_menu_bars)
    (should_produce_line_number): Rewrite with new macro
    FRAME_TOOLTIP_P.
    (note_mode_line_or_margin_highlight): If
    `mode-line-default-help-echo' specifies a function, call it to
    produce help echo string.
    * src/xfns.c (x_make_monitor_attribute_list)
    (Fx_display_monitor_attributes_list): Rewrite with
    new macro FRAME_TOOLTIP_P.
    (tip_last_string, tip_last_frame, tip_last_parms): New Lisp
    scalars replacing Lisp vector last_show_tip_args.
    (x_create_tip_frame): Set new frame's 'tooltip' structure
    member to true.
    (x_hide_tip): Rewrite with additional tests of frames for
    liveness and taking into account that for GTK+ tips the
    reference frame is now stored in tip_last_frame instead of
    tip_frame.
    (Fx_show_tip): Handle last_show_tip_args to tip_last_frame,
    tip_last_string and tip_last_parms conversion.  For GTK+ store
    FRAME argument in tip_last-frame.
    (syms_of_xfns): staticpro tip_last_frame, tip_last_string
    and tip_last_parms instead of last_show_tip_args.
    * src/xterm.c (x_update_begin, handle_one_xevent, x_new_font)
    (x_set_window_size): Rewrite with new macro FRAME_TOOLTIP_P.
    * src/xterm.h (tip_window): Add external declaration.
    * etc/NEWS: Mention new modeline tooltips behavior.
---
 etc/NEWS         |   6 ++
 lisp/bindings.el |  57 ++++++++++--
 src/dispextern.h |   9 --
 src/frame.c      |  59 +++++++------
 src/frame.h      |   7 +-
 src/gtkutil.c    |  14 +--
 src/nsfns.m      |   4 -
 src/w32fns.c     | 110 ++++++++++++++----------
 src/w32term.c    |   4 +-
 src/w32term.h    |   2 +
 src/xdisp.c      |  29 ++-----
 src/xfns.c       | 257 +++++++++++++++++++++++++++++++++++--------------------
 src/xterm.c      |  19 ++--
 src/xterm.h      |   2 +
 14 files changed, 350 insertions(+), 229 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 872bd31..ed07b10 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -58,6 +58,12 @@ on GUI frames when tooltips are displayed in the echo area.  
Instead,
 it resizes the echo area as needed to accommodate the full tool-tip
 text.
 
+---
+** Show modeline tooltips only if the corresponding action applies.
+Customize the option 'mode-line-default-help-echo' to restore the old
+behavior where the tooltip text is also shown when the corresponding
+action does not apply.
+
 +++
 ** New function 'logcount' calculates an integer's Hamming weight.
 
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 8375bb9..9960ba6 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -124,17 +124,58 @@ corresponding to the mode line clicked."
 
 ;;; Mode line contents
 
-(defcustom mode-line-default-help-echo
-  "mouse-1: Select (drag to resize)\n\
-mouse-2: Make current window occupy the whole frame\n\
-mouse-3: Remove current window from display"
+(defun mode-line-default-help-echo (window)
+  "Return default help echo text for WINDOW's mode-line."
+  (let* ((frame (window-frame window))
+         (line-1a
+          ;; Show text to select window only if the window is not
+          ;; selected.
+          (not (eq window (frame-selected-window frame))))
+         (line-1b
+          ;; Show text to drag modeline if and only if it can be done.
+          (or (window-in-direction 'below window)
+              (let ((mini-window (minibuffer-window frame)))
+                (and (eq frame (window-frame mini-window))
+                     (or (minibuffer-window-active-p mini-window)
+                         (not resize-mini-windows))))))
+         (line-2
+          ;; Show text make window occupy the whole frame
+          ;; only if it doesn't already do that.
+          (not (eq window (frame-root-window frame))))
+         (line-3
+          ;; Show text to delete window only if that's possible.
+          (not (eq window (frame-root-window frame)))))
+    (when (or line-1a line-1b line-2 line-3)
+      (concat
+       (when (or line-1a line-1b)
+         (concat
+          "mouse-1: "
+          (when line-1a "Select window")
+          (when line-1b
+            (if line-1a " (drag to resize)" "Drag to resize"))
+          (when (or line-2 line-3) "\n")))
+       (when line-2
+         (concat
+          "mouse-2: Make window occupy whole frame"
+          (when line-3 "\n")))
+       (when line-3
+         "mouse-3: Remove window from frame")))))
+
+(defcustom mode-line-default-help-echo #'mode-line-default-help-echo
   "Default help text for the mode line.
 If the value is a string, it specifies the tooltip or echo area
 message to display when the mouse is moved over the mode line.
-If the text at the mouse position has a `help-echo' text
-property, that overrides this variable."
-  :type '(choice (const :tag "No help" :value nil) string)
-  :version "24.3"
+If the value is a function, call that function with one argument
+- the window whose mode-line to display.  If the text at the
+mouse position has a `help-echo' text property, that overrides
+this variable."
+  :type '(choice
+          (const :tag "No help" :value nil)
+          function
+          (string :value "mouse-1: Select (drag to resize)\n\
+mouse-2: Make current window occupy the whole frame\n\
+mouse-3: Remove current window from display"))
+  :version "27.1"
   :group 'mode-line)
 
 (defvar mode-line-front-space '(:eval (if (display-graphic-p) " " "-"))
diff --git a/src/dispextern.h b/src/dispextern.h
index 25bd6b2..441361b 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3452,15 +3452,6 @@ void gamma_correct (struct frame *, COLORREF *);
 void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
 void x_change_tool_bar_height (struct frame *f, int);
 
-/* The frame used to display a tooltip.
-
-   Note: In a GTK build with non-zero x_gtk_use_system_tooltips, this
-   variable holds the frame that shows the tooltip, not the frame of
-   the tooltip itself, so checking whether a frame is a tooltip frame
-   cannot just compare the frame to what this variable holds.  */
-extern Lisp_Object tip_frame;
-
-extern Window tip_window;
 extern frame_parm_handler x_frame_parm_handlers[];
 
 extern void start_hourglass (void);
diff --git a/src/frame.c b/src/frame.c
index 1c6289a..9b56080 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -832,6 +832,7 @@ make_frame (bool mini_p)
   f->no_focus_on_map = false;
   f->no_accept_focus = false;
   f->z_group = z_group_none;
+  f->tooltip = false;
 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
   f->last_tool_bar_item = -1;
 #endif
@@ -1467,20 +1468,21 @@ DEFUN ("selected-frame", Fselected_frame, 
Sselected_frame, 0, 0, 0,
 
 DEFUN ("frame-list", Fframe_list, Sframe_list,
        0, 0, 0,
-       doc: /* Return a list of all live frames.  */)
+       doc: /* Return a list of all live frames.
+The return value does not include any tooltip frame.  */)
   (void)
 {
-  Lisp_Object frames;
-  frames = Fcopy_sequence (Vframe_list);
 #ifdef HAVE_WINDOW_SYSTEM
-  if (FRAMEP (tip_frame)
-#ifdef USE_GTK
-      && !NILP (Fframe_parameter (tip_frame, Qtooltip))
-#endif
-      )
-    frames = Fdelq (tip_frame, frames);
-#endif
-  return frames;
+  Lisp_Object list = Qnil, tail, frame;
+
+  FOR_EACH_FRAME (tail, frame)
+    if (!FRAME_TOOLTIP_P (XFRAME (frame)))
+      list = Fcons (frame, list);
+  /* Reverse list for consistency with the !HAVE_WINDOW_SYSTEM case.  */
+  return Fnreverse (list);
+#else /* !HAVE_WINDOW_SYSTEM */
+  return Fcopy_sequence (Vframe_list);
+#endif /* HAVE_WINDOW_SYSTEM */
 }
 
 DEFUN ("frame-parent", Fframe_parent, Sframe_parent,
@@ -1711,7 +1713,8 @@ DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
  * other_frames:
  *
  * Return true if there exists at least one visible or iconified frame
- * but F.  Return false otherwise.
+ * but F.  Tooltip frames do not qualify as candidates.  Return false
+ * if no such frame exists.
  *
  * INVISIBLE true means we are called from make_frame_invisible where
  * such a frame must be visible or iconified.  INVISIBLE nil means we
@@ -1725,7 +1728,6 @@ static bool
 other_frames (struct frame *f, bool invisible, bool force)
 {
   Lisp_Object frames, frame, frame1;
-  struct frame *f1;
   Lisp_Object minibuffer_window = FRAME_MINIBUF_WINDOW (f);
 
   XSETFRAME (frame, f);
@@ -1735,7 +1737,8 @@ other_frames (struct frame *f, bool invisible, bool force)
 
   FOR_EACH_FRAME (frames, frame1)
     {
-      f1 = XFRAME (frame1);
+      struct frame *f1 = XFRAME (frame1);
+
       if (f != f1)
        {
          /* Verify that we can still talk to the frame's X window, and
@@ -1744,7 +1747,7 @@ other_frames (struct frame *f, bool invisible, bool force)
          if (FRAME_WINDOW_P (f1))
            x_sync (f1);
 #endif
-         if (NILP (Fframe_parameter (frame1, Qtooltip))
+         if (!FRAME_TOOLTIP_P (f1)
              /* Tooltips and child frames count neither for
                 invisibility nor for deletions.  */
              && !FRAME_PARENT_FRAME (f1)
@@ -1877,7 +1880,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
        }
     }
 
-  is_tooltip_frame = !NILP (Fframe_parameter (frame, Qtooltip));
+  is_tooltip_frame = FRAME_TOOLTIP_P (f);
 
   /* Run `delete-frame-functions' unless FORCE is `noelisp' or
      frame is a tooltip.  FORCE is set to `noelisp' when handling
@@ -1925,27 +1928,31 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
         Do not call next_frame here because it may loop forever.
         See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025.  */
       FOR_EACH_FRAME (tail, frame1)
-       if (!EQ (frame, frame1)
-           && NILP (Fframe_parameter (frame1, Qtooltip))
-           && (FRAME_TERMINAL (XFRAME (frame))
-               == FRAME_TERMINAL (XFRAME (frame1)))
-           && FRAME_VISIBLE_P (XFRAME (frame1)))
-         break;
+       {
+         struct frame *f1 = XFRAME (frame1);
+
+         if (!EQ (frame, frame1)
+             && !FRAME_TOOLTIP_P (f1)
+             && FRAME_TERMINAL (f) == FRAME_TERMINAL (f1)
+             && FRAME_VISIBLE_P (f1))
+           break;
+       }
 
       /* If there is none, find *some* other frame.  */
       if (NILP (frame1) || EQ (frame1, frame))
        {
          FOR_EACH_FRAME (tail, frame1)
            {
+             struct frame *f1 = XFRAME (frame1);
+
              if (!EQ (frame, frame1)
-                 && FRAME_LIVE_P (XFRAME (frame1))
-                 && NILP (Fframe_parameter (frame1, Qtooltip)))
+                 && FRAME_LIVE_P (f1)
+                 && !FRAME_TOOLTIP_P (f1))
                {
-                 /* Do not change a text terminal's top-frame.  */
-                 struct frame *f1 = XFRAME (frame1);
                  if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1))
                    {
                      Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
+
                      if (!EQ (top_frame, frame))
                        frame1 = top_frame;
                    }
diff --git a/src/frame.h b/src/frame.h
index 402d6c0..2c9c414 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -342,6 +342,9 @@ struct frame
   ENUM_BF (output_method) output_method : 3;
 
 #ifdef HAVE_WINDOW_SYSTEM
+  /* True if this frame is a tooltip frame.  */
+  bool_bf tooltip : 1;
+
   /* See FULLSCREEN_ enum on top.  */
   ENUM_BF (fullscreen_type) want_fullscreen : 4;
 
@@ -351,9 +354,7 @@ struct frame
 
   /* Nonzero if we should actually display horizontal scroll bars on this 
frame.  */
   bool_bf horizontal_scroll_bars : 1;
-#endif /* HAVE_WINDOW_SYSTEM */
 
-#if defined (HAVE_WINDOW_SYSTEM)
   /* True if this is an undecorated frame.  */
   bool_bf undecorated : 1;
 
@@ -967,6 +968,7 @@ default_pixels_per_inch_y (void)
 #define FRAME_Z_GROUP_ABOVE_SUSPENDED(f)       \
   ((f)->z_group == z_group_above_suspended)
 #define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below)
+#define FRAME_TOOLTIP_P(f) ((f)->tooltip)
 #ifdef NS_IMPL_COCOA
 #define FRAME_NS_APPEARANCE(f) ((f)->ns_appearance)
 #define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar)
@@ -983,6 +985,7 @@ default_pixels_per_inch_y (void)
 #define FRAME_Z_GROUP_NONE(f) ((void) (f), true)
 #define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false)
 #define FRAME_Z_GROUP_BELOW(f) ((void) (f), false)
+#define FRAME_TOOLTIP_P(f) ((void) f, false)
 #endif /* HAVE_WINDOW_SYSTEM */
 
 /* Whether horizontal scroll bars are currently enabled for frame F.  */
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 047417f..34c0fcc 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -687,6 +687,7 @@ qttip_cb (GtkWidget  *widget,
       g_signal_connect (x->ttip_lbl, "hierarchy-changed",
                         G_CALLBACK (hierarchy_ch_cb), f);
     }
+
   return FALSE;
 }
 
@@ -713,7 +714,8 @@ xg_prepare_tooltip (struct frame *f,
   GtkRequisition req;
   Lisp_Object encoded_string;
 
-  if (!x->ttip_lbl) return 0;
+  if (!x->ttip_lbl)
+    return FALSE;
 
   block_input ();
   encoded_string = ENCODE_UTF_8 (string);
@@ -745,7 +747,7 @@ xg_prepare_tooltip (struct frame *f,
 
   unblock_input ();
 
-  return 1;
+  return TRUE;
 #endif /* USE_GTK_TOOLTIP */
 }
 
@@ -768,18 +770,18 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
 #endif
 }
 
+
 /* Hide tooltip if shown.  Do nothing if not shown.
    Return true if tip was hidden, false if not (i.e. not using
    system tooltips).  */
-
 bool
 xg_hide_tooltip (struct frame *f)
 {
-  bool ret = 0;
 #ifdef USE_GTK_TOOLTIP
   if (f->output_data.x->ttip_window)
     {
       GtkWindow *win = f->output_data.x->ttip_window;
+
       block_input ();
       gtk_widget_hide (GTK_WIDGET (win));
 
@@ -792,10 +794,10 @@ xg_hide_tooltip (struct frame *f)
         }
       unblock_input ();
 
-      ret = 1;
+      return TRUE;
     }
 #endif
-  return ret;
+  return FALSE;
 }
 
 
diff --git a/src/nsfns.m b/src/nsfns.m
index c8b3024..0f60bb8 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2753,10 +2753,6 @@ If omitted or nil, that stands for the selected frame's 
display.  */)
   return make_number (1 << min (dpyinfo->n_planes, 24));
 }
 
-
-/* Unused dummy def needed for compatibility. */
-Lisp_Object tip_frame;
-
 /* TODO: move to xdisp or similar */
 static void
 compute_tip_xy (struct frame *f,
diff --git a/src/w32fns.c b/src/w32fns.c
index 6e0b3ad..27c765e 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6423,7 +6423,7 @@ w32_display_monitor_attributes_list (void)
     {
       struct frame *f = XFRAME (frame);
 
-      if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
+      if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
        {
          HMONITOR monitor =
            monitor_from_window_fn (FRAME_W32_WINDOW (f),
@@ -6510,7 +6510,7 @@ w32_display_monitor_attributes_list_fallback (struct 
w32_display_info *dpyinfo)
     {
       struct frame *f = XFRAME (frame);
 
-      if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
+      if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
        frames = Fcons (frame, frames);
     }
   attributes = Fcons (Fcons (Qframes, frames), attributes);
@@ -6916,20 +6916,25 @@ no value of TYPE (always string in the MS Windows 
case).  */)
 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
                            Lisp_Object, int, int, int *, int *);
 
-/* The frame of a currently visible tooltip.  */
-
+/* The frame of the currently visible tooltip.  */
 Lisp_Object tip_frame;
 
-/* If non-nil, a timer started that hides the last tooltip when it
-   fires.  */
+/* The window-system window corresponding to the frame of the
+   currently visible tooltip.  */
+Window tip_window;
 
+/* A timer that hides or deletes the currently visible tooltip when it
+   fires.  */
 Lisp_Object tip_timer;
-Window tip_window;
 
-/* If non-nil, a vector of 3 elements containing the last args
-   with which x-show-tip was called.  See there.  */
+/* STRING argument of last `x-show-tip' call.  */
+Lisp_Object tip_last_string;
 
-Lisp_Object last_show_tip_args;
+/* FRAME argument of last `x-show-tip' call.  */
+Lisp_Object tip_last_frame;
+
+/* PARMS argument of last `x-show-tip' call.  */
+Lisp_Object tip_last_parms;
 
 
 static void
@@ -7002,6 +7007,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, 
Lisp_Object parms)
 
   FRAME_FONTSET (f)  = -1;
   fset_icon_name (f, Qnil);
+  f->tooltip = true;
 
 #ifdef GLYPH_DEBUG
   image_cache_refcount =
@@ -7261,7 +7267,17 @@ compute_tip_xy (struct frame *f,
     *root_x = min_x;
 }
 
-/* Hide tooltip.  Delete its frame if DELETE is true.  */
+/**
+ * x_hide_tip:
+ *
+ * Hide currently visible tooltip and cancel its timer.
+ *
+ * This will try to make tooltip_frame invisible (if DELETE is false)
+ * or delete tooltip_frame (if DELETE is true).
+ *
+ * Return Qt if the tooltip was either deleted or made invisible, Qnil
+ * otherwise.
+ */
 static Lisp_Object
 x_hide_tip (bool delete)
 {
@@ -7286,15 +7302,20 @@ x_hide_tip (bool delete)
 
       if (FRAMEP (tip_frame))
        {
-         if (delete)
+         if (FRAME_LIVE_P (XFRAME (tip_frame)))
            {
-             delete_frame (tip_frame, Qnil);
-             tip_frame = Qnil;
+             if (delete)
+               {
+                 delete_frame (tip_frame, Qnil);
+                 tip_frame = Qnil;
+               }
+             else
+               x_make_frame_invisible (XFRAME (tip_frame));
+
+             was_open = Qt;
            }
          else
-           x_make_frame_invisible (XFRAME (tip_frame));
-
-         was_open = Qt;
+           tip_frame = Qnil;
        }
       else
        tip_frame = Qnil;
@@ -7334,7 +7355,8 @@ with offset DY added (default is -10).
 
 A tooltip's maximum size is specified by `x-max-tooltip-size'.
 Text larger than the specified size is clipped.  */)
-  (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object 
timeout, Lisp_Object dx, Lisp_Object dy)
+  (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
+   Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
 {
   struct frame *tip_f;
   struct window *w;
@@ -7345,8 +7367,7 @@ Text larger than the specified size is clipped.  */)
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
   ptrdiff_t count = SPECPDL_INDEX ();
   ptrdiff_t count_1;
-  Lisp_Object window, size;
-  Lisp_Object tip_buf;
+  Lisp_Object window, size, tip_buf;
   AUTO_STRING (tip, " *tip*");
 
   specbind (Qinhibit_redisplay, Qt);
@@ -7368,19 +7389,12 @@ Text larger than the specified size is clipped.  */)
   else
     CHECK_NUMBER (dy);
 
-  if (NILP (last_show_tip_args))
-    last_show_tip_args = Fmake_vector (make_number (3), Qnil);
-
   if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
     {
-      Lisp_Object last_string = AREF (last_show_tip_args, 0);
-      Lisp_Object last_frame = AREF (last_show_tip_args, 1);
-      Lisp_Object last_parms = AREF (last_show_tip_args, 2);
-
       if (FRAME_VISIBLE_P (XFRAME (tip_frame))
-         && EQ (frame, last_frame)
-         && !NILP (Fequal_including_properties (last_string, string))
-         && !NILP (Fequal (last_parms, parms)))
+         && EQ (frame, tip_last_frame)
+         && !NILP (Fequal_including_properties (string, tip_last_string))
+         && !NILP (Fequal (parms, tip_last_parms)))
        {
          /* Only DX and DY have changed.  */
          tip_f = XFRAME (tip_frame);
@@ -7414,14 +7428,14 @@ Text larger than the specified size is clipped.  */)
 
          goto start_timer;
        }
-      else if (tooltip_reuse_hidden_frame && EQ (frame, last_frame))
+      else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
        {
          bool delete = false;
          Lisp_Object tail, elt, parm, last;
 
          /* Check if every parameter in PARMS has the same value in
-            last_parms.  This may destruct last_parms which, however,
-            will be recreated below.  */
+            tip_last_parms.  This may destruct tip_last_parms
+            which, however, will be recreated below.  */
          for (tail = parms; CONSP (tail); tail = XCDR (tail))
            {
              elt = XCAR (tail);
@@ -7431,7 +7445,7 @@ Text larger than the specified size is clipped.  */)
              if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
                  && !EQ (parm, Qright) && !EQ (parm, Qbottom))
                {
-                 last = Fassq (parm, last_parms);
+                 last = Fassq (parm, tip_last_parms);
                  if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
                    {
                      /* We lost, delete the old tooltip.  */
@@ -7439,15 +7453,17 @@ Text larger than the specified size is clipped.  */)
                      break;
                    }
                  else
-                   last_parms = call2 (Qassq_delete_all, parm, last_parms);
+                   tip_last_parms =
+                     call2 (Qassq_delete_all, parm, tip_last_parms);
                }
              else
-               last_parms = call2 (Qassq_delete_all, parm, last_parms);
+               tip_last_parms =
+                 call2 (Qassq_delete_all, parm, tip_last_parms);
            }
 
-         /* Now check if there's a parameter left in last_parms with a
+         /* Now check if there's a parameter left in tip_last_parms with a
             non-nil value.  */
-         for (tail = last_parms; CONSP (tail); tail = XCDR (tail))
+         for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
            {
              elt = XCAR (tail);
              parm = Fcar (elt);
@@ -7468,9 +7484,9 @@ Text larger than the specified size is clipped.  */)
   else
     x_hide_tip (true);
 
-  ASET (last_show_tip_args, 0, string);
-  ASET (last_show_tip_args, 1, frame);
-  ASET (last_show_tip_args, 2, parms);
+  tip_last_frame = frame;
+  tip_last_string = string;
+  tip_last_parms = parms;
 
   /* Block input until the tip has been fully drawn, to avoid crashes
      when drawing tips in menus.  */
@@ -7486,7 +7502,8 @@ Text larger than the specified size is clipped.  */)
       if (NILP (Fassq (Qborder_width, parms)))
        parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
       if (NILP (Fassq (Qborder_color, parms)))
-       parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), 
parms);
+       parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")),
+                      parms);
       if (NILP (Fassq (Qbackground_color, parms)))
        parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
                       parms);
@@ -10695,9 +10712,12 @@ tip frame.  */);
   staticpro (&tip_timer);
   tip_frame = Qnil;
   staticpro (&tip_frame);
-
-  last_show_tip_args = Qnil;
-  staticpro (&last_show_tip_args);
+  tip_last_frame = Qnil;
+  staticpro (&tip_last_frame);
+  tip_last_string = Qnil;
+  staticpro (&tip_last_string);
+  tip_last_parms = Qnil;
+  staticpro (&tip_last_parms);
 
   defsubr (&Sx_file_dialog);
 #ifdef WINDOWSNT
diff --git a/src/w32term.c b/src/w32term.c
index db4ccf5..137c798 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5569,7 +5569,7 @@ w32_read_socket (struct terminal *terminal,
        struct frame *f = XFRAME (frame);
        /* The tooltip has been drawn already.  Avoid the
           SET_FRAME_GARBAGED below.  */
-       if (EQ (frame, tip_frame))
+       if (FRAME_TOOLTIP_P (f))
          continue;
 
        /* Check "visible" frames and mark each as obscured or not.
@@ -6046,7 +6046,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int 
fontset)
       /* Don't change the size of a tip frame; there's no point in
         doing it because it's done in Fx_show_tip, and it leads to
         problems because the tip frame has no widget.  */
-      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
+      if (!FRAME_TOOLTIP_P (f))
        adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
                           FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
                           false, Qfont);
diff --git a/src/w32term.h b/src/w32term.h
index e500b73..c69bebe 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -817,6 +817,8 @@ extern struct window *w32_system_caret_window;
 extern int w32_system_caret_hdr_height;
 extern int w32_system_caret_mode_height;
 
+extern Window tip_window;
+
 #ifdef _MSC_VER
 #ifndef EnumSystemLocales
 /* MSVC headers define these only for _WIN32_WINNT >= 0x0500.  */
diff --git a/src/xdisp.c b/src/xdisp.c
index 59fa00e..d2bb47f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11866,7 +11866,7 @@ x_consider_frame_title (Lisp_Object frame)
   if ((FRAME_WINDOW_P (f)
        || FRAME_MINIBUF_ONLY_P (f)
        || f->explicit_name)
-      && NILP (Fframe_parameter (frame, Qtooltip)))
+      && !FRAME_TOOLTIP_P (f))
     {
       /* Do we have more than one visible frame on this X display?  */
       Lisp_Object tail, other_frame, fmt;
@@ -11883,8 +11883,8 @@ x_consider_frame_title (Lisp_Object frame)
          if (tf != f
              && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
              && !FRAME_MINIBUF_ONLY_P (tf)
-             && !EQ (other_frame, tip_frame)
              && !FRAME_PARENT_FRAME (tf)
+             && !FRAME_TOOLTIP_P (tf)
              && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
            break;
        }
@@ -11953,13 +11953,6 @@ prepare_menu_bars (void)
 {
   bool all_windows = windows_or_buffers_changed || update_mode_lines;
   bool some_windows = REDISPLAY_SOME_P ();
-  Lisp_Object tooltip_frame;
-
-#ifdef HAVE_WINDOW_SYSTEM
-  tooltip_frame = tip_frame;
-#else
-  tooltip_frame = Qnil;
-#endif
 
   if (FUNCTIONP (Vpre_redisplay_function))
     {
@@ -12000,7 +11993,7 @@ prepare_menu_bars (void)
              && !XBUFFER (w->contents)->text->redisplay)
            continue;
 
-         if (!EQ (frame, tooltip_frame)
+         if (!FRAME_TOOLTIP_P (f)
              && !FRAME_PARENT_FRAME (f)
              && (FRAME_ICONIFIED_P (f)
                  || FRAME_VISIBLE_P (f) == 1
@@ -12038,7 +12031,7 @@ prepare_menu_bars (void)
          struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
 
          /* Ignore tooltip frame.  */
-         if (EQ (frame, tooltip_frame))
+         if (FRAME_TOOLTIP_P (f))
            continue;
 
          if (some_windows
@@ -21160,13 +21153,7 @@ should_produce_line_number (struct it *it)
 
 #ifdef HAVE_WINDOW_SYSTEM
   /* Don't display line number in tooltip frames.  */
-  if (FRAMEP (tip_frame) && EQ (WINDOW_FRAME (it->w), tip_frame)
-#ifdef USE_GTK
-      /* GTK builds store in tip_frame the frame that shows the tip,
-        so we need an additional test.  */
-      && !NILP (Fframe_parameter (tip_frame, Qtooltip))
-#endif
-      )
+  if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
     return false;
 #endif
 
@@ -30841,9 +30828,11 @@ note_mode_line_or_margin_highlight (Lisp_Object 
window, int x, int y,
                = buffer_local_value (Qmode_line_default_help_echo,
                                      w->contents);
 
-             if (STRINGP (default_help))
+             if (FUNCTIONP (default_help) || STRINGP (default_help))
                {
-                 help_echo_string = default_help;
+                 help_echo_string = (FUNCTIONP (default_help)
+                                     ? safe_call1 (default_help, window)
+                                     : default_help);
                  XSETWINDOW (help_echo_window, w);
                  help_echo_object = Qnil;
                  help_echo_pos = -1;
diff --git a/src/xfns.c b/src/xfns.c
index 12b7d83..43c55cc 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4612,8 +4612,9 @@ x_make_monitor_attribute_list (struct MonitorInfo 
*monitors,
     {
       struct frame *f = XFRAME (frame);
 
-      if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
-         && !EQ (frame, tip_frame))
+      if (FRAME_X_P (f)
+         && FRAME_DISPLAY_INFO (f) == dpyinfo
+         && !FRAME_TOOLTIP_P (f))
        {
          int i = x_get_monitor_for_frame (f, monitors, n_monitors);
          ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
@@ -4914,12 +4915,9 @@ Internal use only, use `display-monitor-attributes-list' 
instead.  */)
     {
       struct frame *f = XFRAME (frame);
 
-      if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
-         && !(EQ (frame, tip_frame)
-#ifdef USE_GTK
-              && !NILP (Fframe_parameter (tip_frame, Qtooltip))
-#endif
-              ))
+      if (FRAME_X_P (f)
+         && FRAME_DISPLAY_INFO (f) == dpyinfo
+         && !FRAME_TOOLTIP_P (f))
        {
          GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
 
@@ -6052,22 +6050,27 @@ Otherwise, the return value is a vector with the 
following fields:
  ***********************************************************************/
 
 static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
-                            Lisp_Object, int, int, int *, int *);
-
-/* The frame of a currently visible tooltip.  */
+                           Lisp_Object, int, int, int *, int *);
 
+/* The frame of the currently visible tooltip.  */
 Lisp_Object tip_frame;
 
-/* If non-nil, a timer started that hides the last tooltip when it
+/* The window-system window corresponding to the frame of the
+   currently visible tooltip.  */
+Window tip_window;
+
+/* A timer that hides or deletes the currently visible tooltip when it
    fires.  */
+Lisp_Object tip_timer;
 
-static Lisp_Object tip_timer;
-Window tip_window;
+/* STRING argument of last `x-show-tip' call.  */
+Lisp_Object tip_last_string;
 
-/* If non-nil, a vector of 3 elements containing the last args
-   with which x-show-tip was called.  See there.  */
+/* FRAME argument of last `x-show-tip' call.  */
+Lisp_Object tip_last_frame;
 
-static Lisp_Object last_show_tip_args;
+/* PARMS argument of last `x-show-tip' call.  */
+Lisp_Object tip_last_parms;
 
 
 static void
@@ -6141,6 +6144,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
   f->output_data.x->white_relief.pixel = -1;
   f->output_data.x->black_relief.pixel = -1;
 
+  f->tooltip = true;
   fset_icon_name (f, Qnil);
   FRAME_DISPLAY_INFO (f) = dpyinfo;
   f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
@@ -6405,7 +6409,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
    the display in *ROOT_X, and *ROOT_Y.  */
 
 static void
-compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, 
Lisp_Object dy, int width, int height, int *root_x, int *root_y)
+compute_tip_xy (struct frame *f,
+               Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
+               int width, int height, int *root_x, int *root_y)
 {
   Lisp_Object left, top, right, bottom;
   int win_x, win_y;
@@ -6502,7 +6508,19 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, 
Lisp_Object dx, Lisp_Object
 }
 
 
-/* Hide tooltip.  Delete its frame if DELETE is true.  */
+/**
+ * x_hide_tip:
+ *
+ * Hide currently visible tooltip and cancel its timer.
+ *
+ * If GTK+ system tooltips are used, this will try to hide the tooltip
+ * referenced by the x_output structure of tooltip_last_frame.  For
+ * Emacs tooltips this will try to make tooltip_frame invisible (if
+ * DELETE is false) or delete tooltip_frame (if DELETE is true).
+ *
+ * Return Qt if the tooltip was either deleted or made invisible, Qnil
+ * otherwise.
+ */
 static Lisp_Object
 x_hide_tip (bool delete)
 {
@@ -6512,10 +6530,17 @@ x_hide_tip (bool delete)
       tip_timer = Qnil;
     }
 
-
-  if (NILP (tip_frame)
-      || (!delete && FRAMEP (tip_frame)
-         && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+#ifdef USE_GTK
+  /* The GTK+ system tooltip window can be found via the x_output
+     structure of tip_last_frame, if it still exists.  */
+  if (x_gtk_use_system_tooltips && NILP (tip_last_frame))
+    return Qnil;
+  else if (!x_gtk_use_system_tooltips
+          && (NILP (tip_frame)
+              || (!delete
+                  && FRAMEP (tip_frame)
+                  && FRAME_LIVE_P (XFRAME (tip_frame))
+                  && !FRAME_VISIBLE_P (XFRAME (tip_frame)))))
     return Qnil;
   else
     {
@@ -6526,61 +6551,114 @@ x_hide_tip (bool delete)
       specbind (Qinhibit_redisplay, Qt);
       specbind (Qinhibit_quit, Qt);
 
-#ifdef USE_GTK
-      {
-       /* When using system tooltip, tip_frame is the Emacs frame on
-          which the tip is shown.  */
-       struct frame *f = XFRAME (tip_frame);
-
-       if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
-         {
-           tip_frame = Qnil;
-           was_open = Qt;
-         }
-      }
-#endif
+      if (x_gtk_use_system_tooltips)
+       {
+         /* The GTK+ system tooltip window is stored in the x_output
+            structure of tip_last_frame.  */
+         struct frame *f = XFRAME (tip_last_frame);
 
-      if (FRAMEP (tip_frame))
+         if (FRAME_LIVE_P (f))
+           {
+             if (xg_hide_tooltip (f))
+               was_open = Qt;
+           }
+         else
+           tip_last_frame = Qnil;
+       }
+      else
        {
-         if (delete)
+         if (FRAMEP (tip_frame))
            {
-             delete_frame (tip_frame, Qnil);
-             tip_frame = Qnil;
+             struct frame *f = XFRAME (tip_frame);
+
+             if (FRAME_LIVE_P (f))
+               {
+                 if (delete)
+                   {
+                     delete_frame (tip_frame, Qnil);
+                     tip_frame = Qnil;
+                   }
+                 else
+                   x_make_frame_invisible (f);
+
+                 was_open = Qt;
+               }
+             else
+               tip_frame = Qnil;
            }
          else
-           x_make_frame_invisible (XFRAME (tip_frame));
+           tip_frame = Qnil;
+       }
+
+      return unbind_to (count, was_open);
+    }
+#else /* not USE_GTK */
+  if (NILP (tip_frame)
+      || (!delete
+         && FRAMEP (tip_frame)
+         && FRAME_LIVE_P (XFRAME (tip_frame))
+         && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+    return Qnil;
+  else
+    {
+      ptrdiff_t count;
+      Lisp_Object was_open = Qnil;
+
+      count = SPECPDL_INDEX ();
+      specbind (Qinhibit_redisplay, Qt);
+      specbind (Qinhibit_quit, Qt);
+
+      if (FRAMEP (tip_frame))
+       {
+         struct frame *f = XFRAME (tip_frame);
 
-         was_open = Qt;
+         if (FRAME_LIVE_P (f))
+           {
+             if (delete)
+               {
+                 delete_frame (tip_frame, Qnil);
+                 tip_frame = Qnil;
+               }
+             else
+               x_make_frame_invisible (XFRAME (tip_frame));
 
 #ifdef USE_LUCID
-         /* Bloodcurdling hack alert: The Lucid menu bar widget's
-            redisplay procedure is not called when a tip frame over
-            menu items is unmapped.  Redisplay the menu manually...  */
-         {
-           Widget w;
-           struct frame *f = SELECTED_FRAME ();
-           if (FRAME_X_P (f) && FRAME_LIVE_P (f))
+             /* Bloodcurdling hack alert: The Lucid menu bar widget's
+                redisplay procedure is not called when a tip frame over
+                menu items is unmapped.  Redisplay the menu manually...  */
              {
-               w = f->output_data.x->menubar_widget;
+               Widget w;
+               struct frame *f = SELECTED_FRAME ();
 
-               if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
-                   && w != NULL)
+               if (FRAME_X_P (f) && FRAME_LIVE_P (f))
                  {
-                   block_input ();
-                   xlwmenu_redisplay (w);
-                   unblock_input ();
+                   w = f->output_data.x->menubar_widget;
+
+                   if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
+                       && w != NULL)
+                     {
+                       block_input ();
+                       xlwmenu_redisplay (w);
+                       unblock_input ();
+                     }
                  }
              }
-         }
 #endif /* USE_LUCID */
+
+             was_open = Qt;
+           }
+         else
+           tip_frame = Qnil;
        }
       else
        tip_frame = Qnil;
 
       return unbind_to (count, was_open);
     }
+#endif /* USE_GTK */
 }
 
+
 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
        doc: /* Show STRING in a "tooltip" window on frame FRAME.
 A tooltip window is a small X window displaying a string.
@@ -6611,7 +6689,8 @@ with offset DY added (default is -10).
 
 A tooltip's maximum size is specified by `x-max-tooltip-size'.
 Text larger than the specified size is clipped.  */)
-  (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object 
timeout, Lisp_Object dx, Lisp_Object dy)
+  (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
+   Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
 {
   struct frame *f, *tip_f;
   struct window *w;
@@ -6622,8 +6701,7 @@ Text larger than the specified size is clipped.  */)
   int old_windows_or_buffers_changed = windows_or_buffers_changed;
   ptrdiff_t count = SPECPDL_INDEX ();
   ptrdiff_t count_1;
-  Lisp_Object window, size;
-  Lisp_Object tip_buf;
+  Lisp_Object window, size, tip_buf;
   AUTO_STRING (tip, " *tip*");
 
   specbind (Qinhibit_redisplay, Qt);
@@ -6662,36 +6740,27 @@ Text larger than the specified size is clipped.  */)
         {
          compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
           xg_show_tooltip (f, root_x, root_y);
-          /* This is used in Fx_hide_tip.  */
-          XSETFRAME (tip_frame, f);
+         tip_last_frame = frame;
         }
+
       unblock_input ();
       if (ok) goto start_timer;
     }
 #endif /* USE_GTK */
 
-  if (NILP (last_show_tip_args))
-    last_show_tip_args = Fmake_vector (make_number (3), Qnil);
-
   if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
     {
-      Lisp_Object last_string = AREF (last_show_tip_args, 0);
-      Lisp_Object last_frame = AREF (last_show_tip_args, 1);
-      Lisp_Object last_parms = AREF (last_show_tip_args, 2);
-
       if (FRAME_VISIBLE_P (XFRAME (tip_frame))
-         && EQ (frame, last_frame)
-         && !NILP (Fequal_including_properties (last_string, string))
-         && !NILP (Fequal (last_parms, parms)))
+         && EQ (frame, tip_last_frame)
+         && !NILP (Fequal_including_properties (tip_last_string, string))
+         && !NILP (Fequal (tip_last_parms, parms)))
        {
          /* Only DX and DY have changed.  */
          tip_f = XFRAME (tip_frame);
          if (!NILP (tip_timer))
            {
-             Lisp_Object timer = tip_timer;
-
+             call1 (Qcancel_timer, tip_timer);
              tip_timer = Qnil;
-             call1 (Qcancel_timer, timer);
            }
 
          block_input ();
@@ -6703,15 +6772,14 @@ Text larger than the specified size is clipped.  */)
 
          goto start_timer;
        }
-      else if (tooltip_reuse_hidden_frame && EQ (frame, last_frame))
+      else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
        {
          bool delete = false;
          Lisp_Object tail, elt, parm, last;
 
          /* Check if every parameter in PARMS has the same value in
-            last_parms unless it should be ignored by means of
-            Vtooltip_reuse_hidden_frame_parameters.  This may destruct
-            last_parms which, however, will be recreated below.  */
+            tip_last_parms.  This may destruct tip_last_parms which,
+            however, will be recreated below.  */
          for (tail = parms; CONSP (tail); tail = XCDR (tail))
            {
              elt = XCAR (tail);
@@ -6721,7 +6789,7 @@ Text larger than the specified size is clipped.  */)
              if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
                  && !EQ (parm, Qright) && !EQ (parm, Qbottom))
                {
-                 last = Fassq (parm, last_parms);
+                 last = Fassq (parm, tip_last_parms);
                  if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
                    {
                      /* We lost, delete the old tooltip.  */
@@ -6729,17 +6797,18 @@ Text larger than the specified size is clipped.  */)
                      break;
                    }
                  else
-                   last_parms = call2 (Qassq_delete_all, parm, last_parms);
+                   tip_last_parms =
+                     call2 (Qassq_delete_all, parm, tip_last_parms);
                }
              else
-               last_parms = call2 (Qassq_delete_all, parm, last_parms);
+               tip_last_parms =
+                 call2 (Qassq_delete_all, parm, tip_last_parms);
            }
 
-         /* Now check if every parameter in what is left of last_parms
-            with a non-nil value has an association in PARMS unless it
-            should be ignored by means of
-            Vtooltip_reuse_hidden_frame_parameters.  */
-         for (tail = last_parms; CONSP (tail); tail = XCDR (tail))
+         /* Now check if every parameter in what is left of
+            tip_last_parms with a non-nil value has an association in
+            PARMS.  */
+         for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
            {
              elt = XCAR (tail);
              parm = Fcar (elt);
@@ -6760,9 +6829,9 @@ Text larger than the specified size is clipped.  */)
   else
     x_hide_tip (true);
 
-  ASET (last_show_tip_args, 0, string);
-  ASET (last_show_tip_args, 1, frame);
-  ASET (last_show_tip_args, 2, parms);
+  tip_last_frame = frame;
+  tip_last_string = string;
+  tip_last_parms = parms;
 
   if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
     {
@@ -7823,7 +7892,6 @@ When using Gtk+ tooltips, the tooltip face is not used.  
*/);
   defsubr (&Sx_display_list);
   defsubr (&Sx_synchronize);
   defsubr (&Sx_backspace_delete_keys_p);
-
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
   defsubr (&Sx_double_buffered_p);
@@ -7831,9 +7899,12 @@ When using Gtk+ tooltips, the tooltip face is not used.  
*/);
   staticpro (&tip_timer);
   tip_frame = Qnil;
   staticpro (&tip_frame);
-
-  last_show_tip_args = Qnil;
-  staticpro (&last_show_tip_args);
+  tip_last_frame = Qnil;
+  staticpro (&tip_last_frame);
+  tip_last_string = Qnil;
+  staticpro (&tip_last_string);
+  tip_last_parms = Qnil;
+  staticpro (&tip_last_parms);
 
   defsubr (&Sx_uses_old_gtk_dialog);
 #if defined (USE_MOTIF) || defined (USE_GTK)
diff --git a/src/xterm.c b/src/xterm.c
index f771631..0a2068d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -996,12 +996,7 @@ static void
 x_update_begin (struct frame *f)
 {
 #ifdef USE_CAIRO
-  if (! NILP (tip_frame) && XFRAME (tip_frame) == f
-      && ! FRAME_VISIBLE_P (f)
-#ifdef USE_GTK
-      && !NILP (Fframe_parameter (tip_frame, Qtooltip))
-#endif
-      )
+  if (FRAME_TOOLTIP_P (f) && !FRAME_VISIBLE_P (f))
     return;
 
   if (! FRAME_CR_SURFACE (f))
@@ -8091,7 +8086,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       /* Redo the mouse-highlight after the tooltip has gone.  */
       if (event->xunmap.window == tip_window)
         {
-          tip_window = 0;
+          tip_window = None;
           x_redo_mouse_highlight (dpyinfo);
         }
 
@@ -8733,7 +8728,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
 #ifdef USE_X_TOOLKIT
           /* Tip frames are pure X window, set size for them.  */
-          if (! NILP (tip_frame) && XFRAME (tip_frame) == f)
+          if (FRAME_TOOLTIP_P (f))
             {
               if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
                   || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
@@ -9971,11 +9966,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, 
int fontset)
       /* Don't change the size of a tip frame; there's no point in
         doing it because it's done in Fx_show_tip, and it leads to
         problems because the tip frame has no widget.  */
-      if (NILP (tip_frame) || XFRAME (tip_frame) != f
-#ifdef USE_GTK
-         || NILP (Fframe_parameter (tip_frame, Qtooltip))
-#endif
-         )
+      if (!FRAME_TOOLTIP_P (f))
        {
          adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
                             FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
@@ -11204,7 +11195,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
   /* The following breaks our calculations.  If it's really needed,
      think of something else.  */
 #if false
-  if (NILP (tip_frame) || XFRAME (tip_frame) != f)
+  if (!FRAME_TOOLTIP_P (f))
     {
       int text_width, text_height;
 
diff --git a/src/xterm.h b/src/xterm.h
index f73dd0e..1849a5c 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -503,6 +503,8 @@ extern bool x_display_ok (const char *);
 
 extern void select_visual (struct x_display_info *);
 
+extern Window tip_window;
+
 /* Each X frame object points to its own struct x_output object
    in the output_data.x field.  The x_output structure contains
    the information that is specific to X windows.  */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]