emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] master 54b7eb0: Revert "Cleanup tooltips"


From: John Wiegley
Subject: [Emacs-diffs] master 54b7eb0: Revert "Cleanup tooltips"
Date: Tue, 12 Jul 2016 22:28:13 +0000 (UTC)

branch: master
commit 54b7eb0dee2397f1430e81b7356f8efb19946ba0
Author: John Wiegley <address@hidden>
Commit: John Wiegley <address@hidden>

    Revert "Cleanup tooltips"
    
    This reverts commit 20038f8ab75dd1551412a43cd58520c483c22921.
    
    I am reverting this change because it was applied without prior discussion
    on emacs-devel, and has been found to break the NS port.  It needs more
    testing and review before it should be applied here.
---
 src/dispextern.h |    2 +
 src/frame.c      |   19 ++--
 src/frame.h      |    9 --
 src/gtkutil.c    |   29 +-----
 src/gtkutil.h    |    1 -
 src/menu.c       |    7 +-
 src/nsfns.m      |    4 +
 src/w32fns.c     |  213 ++++++++++++++++++++++-------------------
 src/w32term.c    |   15 ++-
 src/w32term.h    |    3 -
 src/xdisp.c      |   21 ++++-
 src/xfns.c       |  277 +++++++++++++++++++++++++++---------------------------
 src/xterm.c      |   19 ++--
 src/xterm.h      |    4 -
 14 files changed, 304 insertions(+), 319 deletions(-)

diff --git a/src/dispextern.h b/src/dispextern.h
index c2fcca5..1325ff9 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3461,6 +3461,8 @@ 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);
 
+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 80e181f..22143ab 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -642,7 +642,6 @@ make_frame (bool mini_p)
   f->vertical_scroll_bar_type = vertical_scroll_bar_none;
   f->horizontal_scroll_bars = false;
   f->want_fullscreen = FULLSCREEN_NONE;
-  f->tooltip = false;
 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
   f->last_tool_bar_item = -1;
 #endif
@@ -1261,16 +1260,13 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
        doc: /* Return a list of all live frames.  */)
   (void)
 {
+  Lisp_Object frames;
+  frames = Fcopy_sequence (Vframe_list);
 #ifdef HAVE_WINDOW_SYSTEM
-  Lisp_Object list = Qnil, tail, frame;
-
-  FOR_EACH_FRAME (tail, frame)
-    if (!FRAME_TOOLTIP_P (XFRAME (frame)))
-      list = Fcons (frame, list);
-  return list;
-#else /* !HAVE_WINDOW_SYSTEM */
-  return Fcopy_sequence (Vframe_list);
+  if (FRAMEP (tip_frame))
+    frames = Fdelq (tip_frame, frames);
 #endif
+  return frames;
 }
 
 /* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
@@ -1561,7 +1557,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
        }
     }
 
-  is_tooltip_frame = FRAME_TOOLTIP_P (f);
+  is_tooltip_frame = !NILP (Fframe_parameter (frame, Qtooltip));
 
   /* Run `delete-frame-functions' unless FORCE is `noelisp' or
      frame is a tooltip.  FORCE is set to `noelisp' when handling
@@ -4904,6 +4900,7 @@ syms_of_frame (void)
   DEFSYM (Qgeometry, "geometry");
   DEFSYM (Qicon_left, "icon-left");
   DEFSYM (Qicon_top, "icon-top");
+  DEFSYM (Qtooltip, "tooltip");
   DEFSYM (Quser_position, "user-position");
   DEFSYM (Quser_size, "user-size");
   DEFSYM (Qwindow_id, "window-id");
@@ -5025,8 +5022,6 @@ syms_of_frame (void)
   DEFSYM (Qvertical_scroll_bars, "vertical-scroll-bars");
   DEFSYM (Qvisibility, "visibility");
   DEFSYM (Qwait_for_wm, "wait-for-wm");
-  DEFSYM (Qtooltip_timer, "tooltip-timer");
-  DEFSYM (Qtooltip_parameters, "tooltip-parameters");
 
   {
     int i;
diff --git a/src/frame.h b/src/frame.h
index 635a5ed..5e3ee68 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -309,9 +309,6 @@ 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;
 
@@ -864,9 +861,6 @@ default_pixels_per_inch_y (void)
 #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) \
   ((f)->vertical_scroll_bar_type == vertical_scroll_bar_right)
 
-/* Whether F is a tooltip frame.  */
-#define FRAME_TOOLTIP_P(f) ((f)->tooltip)
-
 #else /* not HAVE_WINDOW_SYSTEM */
 
 /* If there is no window system, there are no scroll bars.  */
@@ -875,9 +869,6 @@ default_pixels_per_inch_y (void)
 #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) ((void) f, 0)
 #define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) f, 0)
 
-/* If there is no window system, there are no tooltips.  */
-#define FRAME_TOOLTIP_P(f) ((void) f, 0)
-
 #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 e08a4b5..88e6d30 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -731,23 +731,14 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
 bool
 xg_hide_tooltip (struct frame *f)
 {
+  bool ret = 0;
 #ifdef USE_GTK_TOOLTIP
-  struct x_output *x = FRAME_X_OUTPUT (f);
-
-  if (x->ttip_window)
+  if (f->output_data.x->ttip_window)
     {
       GtkWindow *win = f->output_data.x->ttip_window;
-
       block_input ();
       gtk_widget_hide (GTK_WIDGET (win));
 
-      /* Cancel call to xg_hide_tip.  */
-      if (x->ttip_timeout != 0)
-       {
-         g_source_remove (x->ttip_timeout);
-         x->ttip_timeout = 0;
-       }
-
       if (g_object_get_data (G_OBJECT (win), "restore-tt"))
         {
           GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET (win));
@@ -756,21 +747,11 @@ xg_hide_tooltip (struct frame *f)
           g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL);
         }
       unblock_input ();
-      return 1;
-    }
-#endif
-  return 0;
-}
 
-/* One-shot timeout handler attached to GTK event loop in Fx_show_tip.  */
-
-gboolean
-xg_hide_tip (gpointer data)
-{
-#ifdef USE_GTK_TOOLTIP
-  xg_hide_tooltip ((struct frame *) data);
+      ret = 1;
+    }
 #endif
-  return FALSE;
+  return ret;
 }
 
 
diff --git a/src/gtkutil.h b/src/gtkutil.h
index d4dc295..8840fe7 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -178,7 +178,6 @@ extern bool xg_prepare_tooltip (struct frame *f,
                                int *height);
 extern void xg_show_tooltip (struct frame *f, int root_x, int root_y);
 extern bool xg_hide_tooltip (struct frame *f);
-extern gboolean xg_hide_tip (gpointer data);
 
 #ifdef USE_CAIRO
 extern void xg_page_setup_dialog (void);
diff --git a/src/menu.c b/src/menu.c
index 675caff..90bb19a 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1400,12 +1400,7 @@ no quit occurs and `x-popup-menu' returns nil.  */)
 #ifdef HAVE_WINDOW_SYSTEM
   /* Hide a previous tip, if any.  */
   if (!FRAME_TERMCAP_P (f))
-    {
-      Lisp_Object frame;
-
-      XSETFRAME (frame, f);
-      Fx_hide_tip (frame);
-    }
+    Fx_hide_tip ();
 #endif
 
 #ifdef HAVE_NTGUI     /* FIXME: Is it really w32-specific?  --Stef  */
diff --git a/src/nsfns.m b/src/nsfns.m
index a017be5..051e509 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2658,6 +2658,10 @@ 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 f5e5b33..d6b54d1 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -343,6 +343,7 @@ x_window_to_frame (struct w32_display_info *dpyinfo, HWND 
wdesc)
 
 
 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 *);
 
@@ -5067,7 +5068,6 @@ static void
 my_create_tip_window (struct frame *f)
 {
   RECT rect;
-  Window tip_window;
 
   rect.left = rect.top = 0;
   rect.right = FRAME_PIXEL_WIDTH (f);
@@ -5215,8 +5215,9 @@ x_make_gc (struct frame *f)
 }
 
 
-/* Handler for signals raised during x_create_frame.
-   FRAME is the frame which is partially constructed.  */
+/* Handler for signals raised during x_create_frame and
+   x_create_tip_frame.  FRAME is the frame which is partially
+   constructed.  */
 
 static Lisp_Object
 unwind_create_frame (Lisp_Object frame)
@@ -5990,7 +5991,7 @@ w32_display_monitor_attributes_list (void)
     {
       struct frame *f = XFRAME (frame);
 
-      if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
+      if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
        {
          HMONITOR monitor =
            monitor_from_window_fn (FRAME_W32_WINDOW (f),
@@ -6077,7 +6078,7 @@ w32_display_monitor_attributes_list_fallback (struct 
w32_display_info *dpyinfo)
     {
       struct frame *f = XFRAME (frame);
 
-      if (FRAME_W32_P (f) && FRAME_TOOLTIP_P (f))
+      if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
        frames = Fcons (frame, frames);
     }
   attributes = Fcons (Fcons (Qframes, frames), attributes);
@@ -6480,6 +6481,39 @@ no value of TYPE (always string in the MS Windows case). 
 */)
                                Tool tips
  ***********************************************************************/
 
+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 tip_frame;
+
+/* If non-nil, a timer started that hides the last 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.  */
+
+Lisp_Object last_show_tip_args;
+
+
+static void
+unwind_create_tip_frame (Lisp_Object frame)
+{
+  Lisp_Object deleted;
+
+  deleted = unwind_create_frame (frame);
+  if (EQ (deleted, Qt))
+    {
+      tip_window = NULL;
+      tip_frame = Qnil;
+    }
+}
+
+
 /* Create a frame for a tooltip on the display described by DPYINFO.
    PARMS is a list of frame parameters.  Value is the frame.
 
@@ -6524,7 +6558,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, 
Lisp_Object parms)
   f->wants_modeline = false;
   XSETFRAME (frame, f);
 
-  record_unwind_protect (do_unwind_create_frame, frame);
+  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
@@ -6536,7 +6570,6 @@ 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 =
@@ -6645,7 +6678,11 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, 
Lisp_Object parms)
   height = FRAME_LINES (f);
   SET_FRAME_COLS (f, 0);
   SET_FRAME_LINES (f, 0);
-  change_frame_size (f, width, height, true, false, false, false);
+  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)))
+    Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
 
   /* Set up faces after all frame parameters are known.  This call
      also merges in face attributes specified for new frames.
@@ -6673,9 +6710,6 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, 
Lisp_Object parms)
 
   f->no_split = true;
 
-  /* Now this is an official tooltip frame on this display.  */
-  dpyinfo->w32_tooltip_frame = f;
-
   /* Now that the frame is official, it counts as a reference to
      its display.  */
   FRAME_DISPLAY_INFO (f)->reference_count++;
@@ -6794,39 +6828,46 @@ compute_tip_xy (struct frame *f,
     *root_x = min_x;
 }
 
-/* Hide tooltip frame F and delete it if DELETE is true.  */
-
+/* Hide tooltip.  Delete its frame if DELETE is true.  */
 static Lisp_Object
-x_hide_tip (struct frame *f, bool delete)
+x_hide_tip (bool delete)
 {
-  if (f)
+  if (!NILP (tip_timer))
     {
-      Lisp_Object frame, timer;
+      call1 (Qcancel_timer, tip_timer);
+      tip_timer = Qnil;
+    }
 
-      XSETFRAME (frame, f);
-      timer = Fframe_parameter (frame, Qtooltip_timer);
+  if (NILP (tip_frame)
+      || (!delete && FRAMEP (tip_frame)
+         && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+    return Qnil;
+  else
+    {
+      ptrdiff_t count;
+      Lisp_Object was_open = Qnil;
 
-      if (!NILP (timer))
-       call1 (Qcancel_timer, timer);
+      count = SPECPDL_INDEX ();
+      specbind (Qinhibit_redisplay, Qt);
+      specbind (Qinhibit_quit, Qt);
 
-      if (!delete && !FRAME_VISIBLE_P (f))
-       return Qnil;
-      else
+      if (FRAMEP (tip_frame))
        {
-         ptrdiff_t count = SPECPDL_INDEX ();
-
-         specbind (Qinhibit_redisplay, Qt);
-         specbind (Qinhibit_quit, Qt);
-
          if (delete)
-           delete_frame (frame, Qnil);
+           {
+             delete_frame (tip_frame, Qnil);
+             tip_frame = Qnil;
+           }
          else
-           x_make_frame_invisible (f);
+           x_make_frame_invisible (XFRAME (tip_frame));
 
-         return unbind_to (count, Qt);
+         was_open = Qt;
        }
+      else
+       tip_frame = Qnil;
+
+      return unbind_to (count, was_open);
     }
-  return Qnil;
 }
 
 
@@ -6860,8 +6901,7 @@ 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;
@@ -6872,7 +6912,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, tip_frame, parameters;
+  Lisp_Object window, size;
   AUTO_STRING (tip, " *tip*");
 
   specbind (Qinhibit_redisplay, Qt);
@@ -6894,22 +6934,14 @@ Text larger than the specified size is clipped.  */)
   else
     CHECK_NUMBER (dy);
 
-  parameters = Fframe_parameter (frame, Qtooltip_parameters);
-  if (NILP (parameters))
-    parameters = Fmake_vector (make_number (3), Qnil);
+  if (NILP (last_show_tip_args))
+    last_show_tip_args = Fmake_vector (make_number (3), Qnil);
 
-  /* Look at current tooltip frame, if any.  */
-  tip_f = FRAME_DISPLAY_INFO (XFRAME (frame))->w32_tooltip_frame;
-  if (tip_f)
-    XSETFRAME (tip_frame, tip_f);
-  else
-    tip_frame = Qnil;
-
-  if (tip_f && FRAME_LIVE_P (tip_f))
+  if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
     {
-      Lisp_Object last_string = AREF (parameters, 0);
-      Lisp_Object last_frame = AREF (parameters, 1);
-      Lisp_Object last_parms = AREF (parameters, 2);
+      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)
@@ -6917,10 +6949,14 @@ Text larger than the specified size is clipped.  */)
          && !NILP (Fequal (last_parms, parms)))
        {
          /* Only DX and DY have changed.  */
-         Lisp_Object timer = Fframe_parameter (tip_frame, Qtooltip_timer);
+         tip_f = XFRAME (tip_frame);
+         if (!NILP (tip_timer))
+           {
+             Lisp_Object timer = tip_timer;
 
-         if (!NILP (timer))
-           call1 (Qcancel_timer, timer);
+             tip_timer = Qnil;
+             call1 (Qcancel_timer, timer);
+           }
 
          block_input ();
          compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
@@ -6990,22 +7026,17 @@ Text larger than the specified size is clipped.  */)
                }
            }
 
-         x_hide_tip (tip_f, delete);
+         x_hide_tip (delete);
        }
       else
-       x_hide_tip (tip_f, true);
+       x_hide_tip (true);
     }
   else
-    x_hide_tip (tip_f, true);
+    x_hide_tip (true);
 
-  /* Update tooltip parameters.  */
-  {
-    AUTO_FRAME_ARG (arg, Qtooltip_parameters, parameters);
-    ASET (parameters, 0, string);
-    ASET (parameters, 1, frame);
-    ASET (parameters, 2, parms);
-    Fmodify_frame_parameters (frame, arg);
-  }
+  ASET (last_show_tip_args, 0, string);
+  ASET (last_show_tip_args, 1, frame);
+  ASET (last_show_tip_args, 2, parms);
 
   /* Block input until the tip has been fully drawn, to avoid crashes
      when drawing tips in menus.  */
@@ -7025,8 +7056,11 @@ Text larger than the specified size is clipped.  */)
       if (NILP (Fassq (Qbackground_color, parms)))
        parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
                       parms);
-      if (NILP (tip_frame
-               = x_create_tip_frame (FRAME_DISPLAY_INFO (XFRAME (frame)), 
parms)))
+
+      /* 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)))
        {
          /* Creating the tip frame failed.  */
          unblock_input ();
@@ -7130,47 +7164,20 @@ Text larger than the specified size is clipped.  */)
   windows_or_buffers_changed = old_windows_or_buffers_changed;
 
  start_timer:
-  {
-    /* Let the tip disappear after timeout seconds.  */
-    AUTO_FRAME_ARG (arg, Qtooltip_timer,
-                   call3 (intern ("run-at-time"), timeout,
-                          Qnil, intern ("x-hide-tip")));
-    Fmodify_frame_parameters (tip_frame, arg);
-  }
+  /* Let the tip disappear after timeout seconds.  */
+  tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
+                    intern ("x-hide-tip"));
+
   return unbind_to (count, Qnil);
 }
 
 
-DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 1, 0,
+DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
        doc: /* Hide the current tooltip window, if there is any.
-Optional FRAME is the frame to hide tooltip on.
 Value is t if tooltip was open, nil otherwise.  */)
-  (Lisp_Object frame)
+  (void)
 {
-  Lisp_Object obj = Qnil;
-
-  if (NILP (frame))
-    {
-      struct w32_display_info *dpyinfo;
-
-      for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
-       if (dpyinfo->w32_tooltip_frame)
-         if (!NILP (x_hide_tip (dpyinfo->w32_tooltip_frame,
-                                !tooltip_reuse_hidden_frame)))
-           obj = Qt;
-    }
-  else
-    {
-      struct frame *f;
-
-      CHECK_FRAME (frame);
-      f = XFRAME (frame);
-      if (FRAME_DISPLAY_INFO (f)
-         && FRAME_DISPLAY_INFO (f)->w32_tooltip_frame)
-       obj = x_hide_tip (FRAME_DISPLAY_INFO (f)->w32_tooltip_frame,
-                         !tooltip_reuse_hidden_frame);
-    }
-  return obj;
+  return x_hide_tip (!tooltip_reuse_hidden_frame);
 }
 
 /***********************************************************************
@@ -9773,6 +9780,7 @@ syms_of_w32fns (void)
   DEFSYM (Qworkarea, "workarea");
   DEFSYM (Qmm_size, "mm-size");
   DEFSYM (Qframes, "frames");
+  DEFSYM (Qtip_frame, "tip-frame");
   DEFSYM (Qassq_delete_all, "assq-delete-all");
   DEFSYM (Qunicode_sip, "unicode-sip");
 #if defined WINDOWSNT && !defined HAVE_DBUS
@@ -10158,6 +10166,13 @@ tip frame.  */);
   defsubr (&Sset_message_beep);
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
+  tip_timer = Qnil;
+  staticpro (&tip_timer);
+  tip_frame = Qnil;
+  staticpro (&tip_frame);
+
+  last_show_tip_args = Qnil;
+  staticpro (&last_show_tip_args);
 
   defsubr (&Sx_file_dialog);
 #ifdef WINDOWSNT
diff --git a/src/w32term.c b/src/w32term.c
index 8c2fdaf..5a11e2a 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5024,10 +5024,11 @@ w32_read_socket (struct terminal *terminal,
          /* wParam non-zero means Window is about to be shown, 0 means
             about to be hidden.  */
          /* Redo the mouse-highlight after the tooltip has gone.  */
-         if (!msg.msg.wParam
-             && dpyinfo->w32_tooltip_frame
-             && FRAME_W32_WINDOW (dpyinfo->w32_tooltip_frame) == msg.msg.hwnd)
-           x_redo_mouse_highlight (dpyinfo);
+         if (!msg.msg.wParam && msg.msg.hwnd == tip_window)
+           {
+             tip_window = NULL;
+             x_redo_mouse_highlight (dpyinfo);
+           }
 
          /* If window has been obscured or exposed by another window
             being maximized or minimized/restored, then recheck
@@ -5393,7 +5394,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 (FRAME_TOOLTIP_P (f))
+       if (EQ (frame, tip_frame))
          continue;
 
        /* Check "visible" frames and mark each as obscured or not.
@@ -5870,7 +5871,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 (!FRAME_TOOLTIP_P (f))
+      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
        adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
                           FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
                           false, Qfont);
@@ -6568,8 +6569,6 @@ x_free_frame_resources (struct frame *f)
     dpyinfo->w32_focus_event_frame = 0;
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
-  if (f == dpyinfo->w32_tooltip_frame)
-    dpyinfo->w32_tooltip_frame = 0;
   if (f == hlinfo->mouse_face_mouse_frame)
     reset_mouse_highlight (hlinfo);
 
diff --git a/src/w32term.h b/src/w32term.h
index 3934e85..3204770 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -186,9 +186,6 @@ struct w32_display_info
   /* The frame waiting to be auto-raised in w32_read_socket.  */
   struct frame *w32_pending_autoraise_frame;
 
-  /* Tooltip frame on this display.  */
-  struct frame *w32_tooltip_frame;
-
   /* The frame where the mouse was last time we reported a mouse event.  */
   struct frame *last_mouse_frame;
 
diff --git a/src/xdisp.c b/src/xdisp.c
index b8dcdce..14d6f8f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2841,7 +2841,11 @@ init_iterator (struct it *it, struct window *w,
      frames when the fringes are turned off.  But leave the dimensions
      zero for tooltip frames, as these glyphs look ugly there and also
      sabotage calculations of tooltip dimensions in x-show-tip.  */
-  if (!FRAME_TOOLTIP_P (it->f))
+#ifdef HAVE_WINDOW_SYSTEM
+  if (!(FRAME_WINDOW_P (it->f)
+       && FRAMEP (tip_frame)
+       && it->f == XFRAME (tip_frame)))
+#endif
     {
       if (it->line_wrap == TRUNCATE)
        {
@@ -11709,7 +11713,7 @@ x_consider_frame_title (Lisp_Object frame)
   if ((FRAME_WINDOW_P (f)
        || FRAME_MINIBUF_ONLY_P (f)
        || f->explicit_name)
-      && !FRAME_TOOLTIP_P (f))
+      && NILP (Fframe_parameter (frame, Qtooltip)))
     {
       /* Do we have more than one visible frame on this X display?  */
       Lisp_Object tail, other_frame, fmt;
@@ -11726,7 +11730,7 @@ x_consider_frame_title (Lisp_Object frame)
          if (tf != f
              && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
              && !FRAME_MINIBUF_ONLY_P (tf)
-             && !FRAME_TOOLTIP_P (tf)
+             && !EQ (other_frame, tip_frame)
              && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
            break;
        }
@@ -11789,6 +11793,13 @@ 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))
     {
@@ -11829,7 +11840,7 @@ prepare_menu_bars (void)
              && !XBUFFER (w->contents)->text->redisplay)
            continue;
 
-         if (!FRAME_TOOLTIP_P (f)
+         if (!EQ (frame, tooltip_frame)
              && (FRAME_ICONIFIED_P (f)
                  || FRAME_VISIBLE_P (f) == 1
                  /* Exclude TTY frames that are obscured because they
@@ -11866,7 +11877,7 @@ prepare_menu_bars (void)
          struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
 
          /* Ignore tooltip frame.  */
-         if (FRAME_TOOLTIP_P (f))
+         if (EQ (frame, tooltip_frame))
            continue;
 
          if (some_windows
diff --git a/src/xfns.c b/src/xfns.c
index 16dbcfd..798dc49 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4151,7 +4151,7 @@ x_make_monitor_attribute_list (struct MonitorInfo 
*monitors,
       struct frame *f = XFRAME (frame);
 
       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
-         && !FRAME_TOOLTIP_P (f))
+         && !EQ (frame, tip_frame))
        {
          int i = x_get_monitor_for_frame (f, monitors, n_monitors);
          ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
@@ -4447,7 +4447,7 @@ Internal use only, use `display-monitor-attributes-list' 
instead.  */)
       struct frame *f = XFRAME (frame);
 
       if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
-         && !FRAME_TOOLTIP_P (f))
+         && !EQ (frame, tip_frame))
        {
          GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
 
@@ -5312,6 +5312,39 @@ no value of TYPE (always string in the MS Windows case). 
 */)
                                Tool tips
  ***********************************************************************/
 
+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 tip_frame;
+
+/* If non-nil, a timer started that hides the last tooltip when it
+   fires.  */
+
+static 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.  */
+
+static Lisp_Object last_show_tip_args;
+
+
+static void
+unwind_create_tip_frame (Lisp_Object frame)
+{
+  Lisp_Object deleted;
+
+  deleted = unwind_create_frame (frame);
+  if (EQ (deleted, Qt))
+    {
+      tip_window = None;
+      tip_frame = Qnil;
+    }
+}
+
+
 /* Create a frame for a tooltip on the display described by DPYINFO.
    PARMS is a list of frame parameters.  TEXT is the string to
    display in the tip frame.  Value is the frame.
@@ -5348,7 +5381,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
   f = make_frame (false);
   f->wants_modeline = false;
   XSETFRAME (frame, f);
-  record_unwind_protect (do_unwind_create_frame, frame);
+  record_unwind_protect (unwind_create_tip_frame, frame);
 
   f->terminal = dpyinfo->terminal;
 
@@ -5369,7 +5402,6 @@ 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;
@@ -5513,7 +5545,8 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
       = f->output_data.x->text_cursor;
     /* Arrange for getting MapNotify and UnmapNotify events.  */
     attrs.event_mask = StructureNotifyMask;
-    FRAME_X_WINDOW (f)
+    tip_window
+      = FRAME_X_WINDOW (f)
       = XCreateWindow (FRAME_X_DISPLAY (f),
                       FRAME_DISPLAY_INFO (f)->root_window,
                       /* x, y, width, height */
@@ -5522,7 +5555,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
                       f->border_width,
                       CopyFromParent, InputOutput, CopyFromParent,
                       mask, &attrs);
-    XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+    XChangeProperty (FRAME_X_DISPLAY (f), tip_window,
                      FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
                      XA_ATOM, 32, PropModeReplace,
                      (unsigned char *)&type, 1);
@@ -5549,6 +5582,13 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
   SET_FRAME_LINES (f, 0);
   change_frame_size (f, width, height, true, false, false, false);
 
+  /* Add `tooltip' frame parameter's default value. */
+  if (NILP (Fframe_parameter (frame, Qtooltip)))
+    {
+      AUTO_FRAME_ARG (arg, Qtooltip, Qt);
+      Fmodify_frame_parameters (frame, arg);
+    }
+
   /* FIXME - can this be done in a similar way to normal frames?
      http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
 
@@ -5593,9 +5633,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo, 
Lisp_Object parms)
 
   f->no_split = true;
 
-  /* Now this is an official tooltip frame on this display.  */
-  dpyinfo->x_tooltip_frame = f;
-
   /* Now that the frame will be official, it counts as a reference to
      its display and terminal.  */
   FRAME_DISPLAY_INFO (f)->reference_count++;
@@ -5626,9 +5663,7 @@ 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;
@@ -5724,39 +5759,56 @@ compute_tip_xy (struct frame *f,
     *root_x = min_x;
 }
 
-/* Hide tooltip frame F and delete it if DELETE is true.  */
 
+/* Hide tooltip.  Delete its frame if DELETE is true.  */
 static Lisp_Object
-x_hide_tip (struct frame *f, bool delete)
+x_hide_tip (bool delete)
 {
-  if (f)
+  if (!NILP (tip_timer))
     {
-      Lisp_Object frame, timer;
-
-      XSETFRAME (frame, f);
-      timer = Fframe_parameter (frame, Qtooltip_timer);
+      call1 (Qcancel_timer, tip_timer);
+      tip_timer = Qnil;
+    }
 
-      if (!NILP (timer))
-       call1 (Qcancel_timer, timer);
 
-      if (!delete && !FRAME_VISIBLE_P (f))
-       return Qnil;
-      else
-       {
-         ptrdiff_t count = SPECPDL_INDEX ();
+  if (NILP (tip_frame)
+      || (!delete && FRAMEP (tip_frame)
+         && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+    return Qnil;
+  else
+    {
+      ptrdiff_t count;
+      Lisp_Object was_open = Qnil;
 
-         specbind (Qinhibit_redisplay, Qt);
-         specbind (Qinhibit_quit, Qt);
+      count = SPECPDL_INDEX ();
+      specbind (Qinhibit_redisplay, Qt);
+      specbind (Qinhibit_quit, Qt);
 
 #ifdef USE_GTK
-         if (x_gtk_use_system_tooltips)
-           /* Should be handled by xg_hide_tooltip.  */
-           emacs_abort ();
+      {
+       /* 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 (FRAMEP (tip_frame))
+       {
          if (delete)
-           delete_frame (frame, Qnil);
+           {
+             delete_frame (tip_frame, Qnil);
+             tip_frame = Qnil;
+           }
          else
-           x_make_frame_invisible (f);
+           x_make_frame_invisible (XFRAME (tip_frame));
+
+         was_open = Qt;
 
 #ifdef USE_LUCID
          /* Bloodcurdling hack alert: The Lucid menu bar widget's
@@ -5764,12 +5816,12 @@ x_hide_tip (struct frame *f, bool delete)
             menu items is unmapped.  Redisplay the menu manually...  */
          {
            Widget w;
-           struct frame *sf = SELECTED_FRAME ();
-           if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
+           struct frame *f = SELECTED_FRAME ();
+           if (FRAME_X_P (f) && FRAME_LIVE_P (f))
              {
-               w = sf->output_data.x->menubar_widget;
+               w = f->output_data.x->menubar_widget;
 
-               if (!DoesSaveUnders (FRAME_DISPLAY_INFO (sf)->screen)
+               if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
                    && w != NULL)
                  {
                    block_input ();
@@ -5779,10 +5831,12 @@ x_hide_tip (struct frame *f, bool delete)
              }
          }
 #endif /* USE_LUCID */
-         return unbind_to (count, Qt);
        }
+      else
+       tip_frame = Qnil;
+
+      return unbind_to (count, was_open);
     }
-  return Qnil;
 }
 
 DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
@@ -5815,8 +5869,7 @@ 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;
@@ -5827,7 +5880,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, tip_frame, parameters;
+  Lisp_Object window, size;
   AUTO_STRING (tip, " *tip*");
 
   specbind (Qinhibit_redisplay, Qt);
@@ -5857,8 +5910,8 @@ Text larger than the specified size is clipped.  */)
     {
       bool ok;
 
-      /* Hide a previous tip on this frame, if any.  */
-      xg_hide_tooltip (f);
+      /* Hide a previous tip, if any.  */
+      Fx_hide_tip ();
 
       block_input ();
       ok = xg_prepare_tooltip (f, string, &width, &height);
@@ -5866,47 +5919,37 @@ 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);
         }
       unblock_input ();
-      if (ok)
-       /* Schedule call to xg_hide_tip from GTK event loop
-          to allow the tip disappear after timeout seconds.  */
-       FRAME_X_OUTPUT (f)->ttip_timeout
-         = g_timeout_add_seconds (XINT (timeout), xg_hide_tip, (gpointer) f);
-      else
-       /* FIXME: what if not ok?  */
-       FRAME_X_OUTPUT (f)->ttip_timeout = 0;
-      return unbind_to (count, Qnil);
+      if (ok) goto start_timer;
     }
 #endif /* USE_GTK */
 
-  parameters = Fframe_parameter (frame, Qtooltip_parameters);
-  if (NILP (parameters))
-    parameters = Fmake_vector (make_number (3), Qnil);
+  if (NILP (last_show_tip_args))
+    last_show_tip_args = Fmake_vector (make_number (3), Qnil);
 
-  /* Look at current tooltip frame, if any.  */
-  tip_f = FRAME_DISPLAY_INFO (f)->x_tooltip_frame;
-  if (tip_f)
-    XSETFRAME (tip_frame, tip_f);
-  else
-    tip_frame = Qnil;
-
-  if (tip_f && FRAME_LIVE_P (tip_f))
+  if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
     {
-      Lisp_Object last_string = AREF (parameters, 0);
-      Lisp_Object last_frame = AREF (parameters, 1);
-      Lisp_Object last_parms = AREF (parameters, 2);
+      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 (tip_f)
+      if (FRAME_VISIBLE_P (XFRAME (tip_frame))
          && EQ (frame, last_frame)
          && !NILP (Fequal_including_properties (last_string, string))
          && !NILP (Fequal (last_parms, parms)))
        {
          /* Only DX and DY have changed.  */
-         Lisp_Object timer = Fframe_parameter (tip_frame, Qtooltip_timer);
+         tip_f = XFRAME (tip_frame);
+         if (!NILP (tip_timer))
+           {
+             Lisp_Object timer = tip_timer;
 
-         if (!NILP (timer))
-           call1 (Qcancel_timer, timer);
+             tip_timer = Qnil;
+             call1 (Qcancel_timer, timer);
+           }
 
          block_input ();
          compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
@@ -5966,22 +6009,17 @@ Text larger than the specified size is clipped.  */)
                }
            }
 
-         x_hide_tip (tip_f, delete);
+         x_hide_tip (delete);
        }
       else
-       x_hide_tip (tip_f, true);
+       x_hide_tip (true);
     }
   else
-    x_hide_tip (tip_f, true);
+    x_hide_tip (true);
 
-  /* Update tooltip parameters.  */
-  {
-    AUTO_FRAME_ARG (arg, Qtooltip_parameters, parameters);
-    ASET (parameters, 0, string);
-    ASET (parameters, 1, frame);
-    ASET (parameters, 2, parms);
-    Fmodify_frame_parameters (frame, arg);
-  }
+  ASET (last_show_tip_args, 0, string);
+  ASET (last_show_tip_args, 1, frame);
+  ASET (last_show_tip_args, 2, parms);
 
   if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
     {
@@ -5997,6 +6035,9 @@ Text larger than the specified size is clipped.  */)
       if (NILP (Fassq (Qbackground_color, parms)))
        parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
                       parms);
+
+      /* 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)))
        /* Creating the tip frame failed.  */
        return unbind_to (count, Qnil);
@@ -6074,69 +6115,20 @@ Text larger than the specified size is clipped.  */)
   windows_or_buffers_changed = old_windows_or_buffers_changed;
 
  start_timer:
-  {
-    /* Let the tip disappear after timeout seconds.  */
-    AUTO_FRAME_ARG (arg, Qtooltip_timer,
-                   call3 (intern ("run-at-time"), timeout,
-                          Qnil, intern ("x-hide-tip")));
-    Fmodify_frame_parameters (tip_frame, arg);
-  }
+  /* Let the tip disappear after timeout seconds.  */
+  tip_timer = call3 (intern ("run-at-time"), timeout, Qnil,
+                    intern ("x-hide-tip"));
+
   return unbind_to (count, Qnil);
 }
 
-DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 1, 0,
+
+DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
        doc: /* Hide the current tooltip window, if there is any.
-Optional FRAME is the frame to hide tooltip on.
 Value is t if tooltip was open, nil otherwise.  */)
-  (Lisp_Object frame)
+  (void)
 {
-  Lisp_Object obj = Qnil;
-
-#ifdef USE_GTK
-  if (x_gtk_use_system_tooltips)
-    {
-      if (NILP (frame))
-       {
-         Lisp_Object tail, frame;
-
-         FOR_EACH_FRAME (tail, frame)
-           if (FRAME_X_P (XFRAME (frame)))
-             if (xg_hide_tooltip (XFRAME (frame)))
-               obj = Qt;
-       }
-      else
-       {
-         CHECK_FRAME (frame);
-         if (FRAME_X_P (XFRAME (frame)))
-           if (xg_hide_tooltip (XFRAME (frame)))
-             obj = Qt;
-       }
-      return obj;
-    }
-#endif /* USE_GTK */
-
-  if (NILP (frame))
-    {
-      struct x_display_info *dpyinfo;
-
-      for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
-       if (dpyinfo->x_tooltip_frame)
-         if (!NILP (x_hide_tip (dpyinfo->x_tooltip_frame,
-                                !tooltip_reuse_hidden_frame)))
-           obj = Qt;
-    }
-  else
-    {
-      struct frame *f;
-
-      CHECK_FRAME (frame);
-      f = XFRAME (frame);
-      if (FRAME_DISPLAY_INFO (f)
-         && FRAME_DISPLAY_INFO (f)->x_tooltip_frame)
-       obj = x_hide_tip (FRAME_DISPLAY_INFO (f)->x_tooltip_frame,
-                         !tooltip_reuse_hidden_frame);
-    }
-  return obj;
+  return x_hide_tip (!tooltip_reuse_hidden_frame);
 }
 
 
@@ -7005,6 +6997,13 @@ When using Gtk+ tooltips, the tooltip face is not used.  
*/);
 
   defsubr (&Sx_show_tip);
   defsubr (&Sx_hide_tip);
+  tip_timer = Qnil;
+  staticpro (&tip_timer);
+  tip_frame = Qnil;
+  staticpro (&tip_frame);
+
+  last_show_tip_args = Qnil;
+  staticpro (&last_show_tip_args);
 
   defsubr (&Sx_uses_old_gtk_dialog);
 #if defined (USE_MOTIF) || defined (USE_GTK)
diff --git a/src/xterm.c b/src/xterm.c
index ada1160..cd1d712 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -987,7 +987,8 @@ static void
 x_update_begin (struct frame *f)
 {
 #ifdef USE_CAIRO
-  if (FRAME_TOOLTIP_P (f) && ! FRAME_VISIBLE_P (f))
+  if (! NILP (tip_frame) && XFRAME (tip_frame) == f
+      && ! FRAME_VISIBLE_P (f))
     return;
 
   if (! FRAME_CR_SURFACE (f))
@@ -7838,9 +7839,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
     case UnmapNotify:
       /* Redo the mouse-highlight after the tooltip has gone.  */
-      if (dpyinfo->x_tooltip_frame
-         && FRAME_X_WINDOW (dpyinfo->x_tooltip_frame) == event->xunmap.window)
-       x_redo_mouse_highlight (dpyinfo);
+      if (event->xunmap.window == tip_window)
+        {
+          tip_window = 0;
+          x_redo_mouse_highlight (dpyinfo);
+        }
 
       f = x_top_window_to_frame (dpyinfo, event->xunmap.window);
       if (f)           /* F may no longer exist if
@@ -8430,7 +8433,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
 
 #ifdef USE_X_TOOLKIT
           /* Tip frames are pure X window, set size for them.  */
-          if (FRAME_TOOLTIP_P (f))
+          if (! NILP (tip_frame) && XFRAME (tip_frame) == f)
             {
               if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
                   || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
@@ -9611,7 +9614,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 (!FRAME_TOOLTIP_P (f))
+      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
        {
          adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
                             FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
@@ -10686,7 +10689,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 (!FRAME_TOOLTIP_P (f))
+  if (NILP (tip_frame) || XFRAME (tip_frame) != f)
     {
       int text_width, text_height;
 
@@ -11337,8 +11340,6 @@ x_free_frame_resources (struct frame *f)
     dpyinfo->x_focus_event_frame = 0;
   if (f == dpyinfo->x_highlight_frame)
     dpyinfo->x_highlight_frame = 0;
-  if (f == dpyinfo->x_tooltip_frame)
-    dpyinfo->x_tooltip_frame = 0;
   if (f == hlinfo->mouse_face_mouse_frame)
     reset_mouse_highlight (hlinfo);
 
diff --git a/src/xterm.h b/src/xterm.h
index 1eb3e30..675a484 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -362,9 +362,6 @@ struct x_display_info
   /* The frame waiting to be auto-raised in XTread_socket.  */
   struct frame *x_pending_autoraise_frame;
 
-  /* Tooltip frame on this display.  */
-  struct frame *x_tooltip_frame;
-
   /* The frame where the mouse was last time we reported a ButtonPress event.  
*/
   struct frame *last_mouse_frame;
 
@@ -578,7 +575,6 @@ struct x_output
   GtkTooltip *ttip_widget;
   GtkWidget *ttip_lbl;
   GtkWindow *ttip_window;
-  guint ttip_timeout;
 #endif /* USE_GTK_TOOLTIP */
 
 #endif /* USE_GTK */



reply via email to

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