aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2016-07-12 09:16:26 +0300
committerDmitry Antipov2016-07-12 09:16:26 +0300
commit20038f8ab75dd1551412a43cd58520c483c22921 (patch)
treeb42949b761e9642ae6dabc2cfb399f2000207e46 /src
parent8ea599254784e3e6da37ec7ea73f1f6ec6a92ff1 (diff)
downloademacs-20038f8ab75dd1551412a43cd58520c483c22921.tar.gz
emacs-20038f8ab75dd1551412a43cd58520c483c22921.zip
Cleanup tooltips
* src/dispextern.h (toplevel): Remove 'tip_frame' and 'tip_window' decls. * src/frame.h (struct frame): New bitfield to indicate tooltip frame. (FRAME_TOOLTIP_P): New macro. * src/frame.c (make_frame): Mark new frame as regular frame by default. (Fframe_list, delete_frame): Redesign to use FRAME_TOOLTIP_P. (syms_of_frame): Don't DEFSYM 'Qtooltip' but use 'Qtooltip_timer' and 'Qtooltip_parameters' instead. * src/gtkutil.h (toplevel): Add 'xg_hide_tip' decl. * src/gtkutil.c (xg_hide_tip): New function. (xg_hide_tooltip): Adjust to cancel GTK event loop timeout if needed. * src/menu.c (Fx_popup_menu): Adjust call to Fx_hide_tip. * src/nsfns.c (toplevel): Remove 'tip_frame' leftover. * src/w32fns.c (unwind_create_tip_frame): Remove. (w32_display_monitor_attributes_list) (w32_display_monitor_attributes_list_fallback): Use FRAME_TOOLTIP_P. (toplevel): Remove 'tip_frame', 'tip_window' and 'last_show_tip_args'. (x_create_tip_frame): Use do_unwind_create_frame. Mark new frame as a tooltip frame and record it using appropriate display info. (x_hide_tooltip): Add frame arg. (Fx_show_tip): Adjust to avoid globals, store tooltip parameters among base frame parameters, store tooltip hide timer among tooltip frame parameters. (Fx_hide_tip): Add frame arg, hide tooltips on all displays by default. (syms_of_w32fns): Don't DEFSYM 'Qtip_frame', don't initialize and GC-protect 'tip_timer', 'tip_frame' and 'last_show_tip_args'. * src/w32term.c (w32_read_socket): Extract tooltip window id from per-display data. Use FRAME_TOOLTIP_P where appropriate. (x_new_font): Use FRAME_TOOLTIP_P. (x_free_frame_resources): Reset pointer to tooltip frame. * src/w32term.h (struct w32_display_info): New member 'w32_tooltip_frame'. * src/xdisp.c (init_iterator, x_consider_frame_title, prepare_menu_bars): Use FRAME_TOOLTIP_P. * src/xfns.c (x_make_monitor_attribute_list) (Fx_display_monitor_attributes_list): Likewise. (unwind_create_tip_frame): Remove. (toplevel): Remove 'tip_frame', 'tip_window' and 'last_show_tip_args'. (x_create_tip_frame): Use do_unwind_create_frame. Mark new frame as a tooltip frame and record it using appropriate display info. (x_hide_tooltip): Add frame arg. (Fx_show_tip): Adjust to avoid globals, store tooltip parameters among base frame parameters, store tooltip hide timer among tooltip frame parameters. To hide GTK system tooltip, use timeout hooked into GTK event loop. (Fx_hide_tip): Add frame arg, hide tooltips on all displays by default. (syms_of_xfns): Don't DEFSYM 'Qtip_frame', don't initialize and GC-protect 'tip_timer', 'tip_frame' and 'last_show_tip_args'. * src/xterm.c (handle_one_xevent): Extract tooltip window id from per-display data. Use FRAME_TOOLTIP_P where appropriate. (x_new_font, x_set_window_size): Use FRAME_TOOLTIP_P. (x_free_frame_resources): Reset pointer to tooltip frame. * src/xterm.h (struct x_display_info): New member 'x_tooltip_frame'. (struct x_output) [USE_GTK_TOOLTIP]: New member 'ttip_timeout'.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h2
-rw-r--r--src/frame.c19
-rw-r--r--src/frame.h9
-rw-r--r--src/gtkutil.c29
-rw-r--r--src/gtkutil.h1
-rw-r--r--src/menu.c7
-rw-r--r--src/nsfns.m4
-rw-r--r--src/w32fns.c213
-rw-r--r--src/w32term.c15
-rw-r--r--src/w32term.h3
-rw-r--r--src/xdisp.c21
-rw-r--r--src/xfns.c277
-rw-r--r--src/xterm.c19
-rw-r--r--src/xterm.h4
14 files changed, 319 insertions, 304 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 1325ff9da28..c2fcca5591a 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3461,8 +3461,6 @@ void gamma_correct (struct frame *, COLORREF *);
3461void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); 3461void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
3462void x_change_tool_bar_height (struct frame *f, int); 3462void x_change_tool_bar_height (struct frame *f, int);
3463 3463
3464extern Lisp_Object tip_frame;
3465extern Window tip_window;
3466extern frame_parm_handler x_frame_parm_handlers[]; 3464extern frame_parm_handler x_frame_parm_handlers[];
3467 3465
3468extern void start_hourglass (void); 3466extern void start_hourglass (void);
diff --git a/src/frame.c b/src/frame.c
index 22143ab26bf..80e181f89ef 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -642,6 +642,7 @@ make_frame (bool mini_p)
642 f->vertical_scroll_bar_type = vertical_scroll_bar_none; 642 f->vertical_scroll_bar_type = vertical_scroll_bar_none;
643 f->horizontal_scroll_bars = false; 643 f->horizontal_scroll_bars = false;
644 f->want_fullscreen = FULLSCREEN_NONE; 644 f->want_fullscreen = FULLSCREEN_NONE;
645 f->tooltip = false;
645#if ! defined (USE_GTK) && ! defined (HAVE_NS) 646#if ! defined (USE_GTK) && ! defined (HAVE_NS)
646 f->last_tool_bar_item = -1; 647 f->last_tool_bar_item = -1;
647#endif 648#endif
@@ -1260,13 +1261,16 @@ DEFUN ("frame-list", Fframe_list, Sframe_list,
1260 doc: /* Return a list of all live frames. */) 1261 doc: /* Return a list of all live frames. */)
1261 (void) 1262 (void)
1262{ 1263{
1263 Lisp_Object frames;
1264 frames = Fcopy_sequence (Vframe_list);
1265#ifdef HAVE_WINDOW_SYSTEM 1264#ifdef HAVE_WINDOW_SYSTEM
1266 if (FRAMEP (tip_frame)) 1265 Lisp_Object list = Qnil, tail, frame;
1267 frames = Fdelq (tip_frame, frames); 1266
1267 FOR_EACH_FRAME (tail, frame)
1268 if (!FRAME_TOOLTIP_P (XFRAME (frame)))
1269 list = Fcons (frame, list);
1270 return list;
1271#else /* !HAVE_WINDOW_SYSTEM */
1272 return Fcopy_sequence (Vframe_list);
1268#endif 1273#endif
1269 return frames;
1270} 1274}
1271 1275
1272/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the 1276/* Return CANDIDATE if it can be used as 'other-than-FRAME' frame on the
@@ -1557,7 +1561,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1557 } 1561 }
1558 } 1562 }
1559 1563
1560 is_tooltip_frame = !NILP (Fframe_parameter (frame, Qtooltip)); 1564 is_tooltip_frame = FRAME_TOOLTIP_P (f);
1561 1565
1562 /* Run `delete-frame-functions' unless FORCE is `noelisp' or 1566 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1563 frame is a tooltip. FORCE is set to `noelisp' when handling 1567 frame is a tooltip. FORCE is set to `noelisp' when handling
@@ -4900,7 +4904,6 @@ syms_of_frame (void)
4900 DEFSYM (Qgeometry, "geometry"); 4904 DEFSYM (Qgeometry, "geometry");
4901 DEFSYM (Qicon_left, "icon-left"); 4905 DEFSYM (Qicon_left, "icon-left");
4902 DEFSYM (Qicon_top, "icon-top"); 4906 DEFSYM (Qicon_top, "icon-top");
4903 DEFSYM (Qtooltip, "tooltip");
4904 DEFSYM (Quser_position, "user-position"); 4907 DEFSYM (Quser_position, "user-position");
4905 DEFSYM (Quser_size, "user-size"); 4908 DEFSYM (Quser_size, "user-size");
4906 DEFSYM (Qwindow_id, "window-id"); 4909 DEFSYM (Qwindow_id, "window-id");
@@ -5022,6 +5025,8 @@ syms_of_frame (void)
5022 DEFSYM (Qvertical_scroll_bars, "vertical-scroll-bars"); 5025 DEFSYM (Qvertical_scroll_bars, "vertical-scroll-bars");
5023 DEFSYM (Qvisibility, "visibility"); 5026 DEFSYM (Qvisibility, "visibility");
5024 DEFSYM (Qwait_for_wm, "wait-for-wm"); 5027 DEFSYM (Qwait_for_wm, "wait-for-wm");
5028 DEFSYM (Qtooltip_timer, "tooltip-timer");
5029 DEFSYM (Qtooltip_parameters, "tooltip-parameters");
5025 5030
5026 { 5031 {
5027 int i; 5032 int i;
diff --git a/src/frame.h b/src/frame.h
index 5e3ee68942a..635a5ed7be4 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -309,6 +309,9 @@ struct frame
309 ENUM_BF (output_method) output_method : 3; 309 ENUM_BF (output_method) output_method : 3;
310 310
311#ifdef HAVE_WINDOW_SYSTEM 311#ifdef HAVE_WINDOW_SYSTEM
312 /* True if this frame is a tooltip frame. */
313 bool_bf tooltip : 1;
314
312 /* See FULLSCREEN_ enum on top. */ 315 /* See FULLSCREEN_ enum on top. */
313 ENUM_BF (fullscreen_type) want_fullscreen : 4; 316 ENUM_BF (fullscreen_type) want_fullscreen : 4;
314 317
@@ -861,6 +864,9 @@ default_pixels_per_inch_y (void)
861#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) \ 864#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) \
862 ((f)->vertical_scroll_bar_type == vertical_scroll_bar_right) 865 ((f)->vertical_scroll_bar_type == vertical_scroll_bar_right)
863 866
867/* Whether F is a tooltip frame. */
868#define FRAME_TOOLTIP_P(f) ((f)->tooltip)
869
864#else /* not HAVE_WINDOW_SYSTEM */ 870#else /* not HAVE_WINDOW_SYSTEM */
865 871
866/* If there is no window system, there are no scroll bars. */ 872/* If there is no window system, there are no scroll bars. */
@@ -869,6 +875,9 @@ default_pixels_per_inch_y (void)
869#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) ((void) f, 0) 875#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT(f) ((void) f, 0)
870#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) f, 0) 876#define FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT(f) ((void) f, 0)
871 877
878/* If there is no window system, there are no tooltips. */
879#define FRAME_TOOLTIP_P(f) ((void) f, 0)
880
872#endif /* HAVE_WINDOW_SYSTEM */ 881#endif /* HAVE_WINDOW_SYSTEM */
873 882
874/* Whether horizontal scroll bars are currently enabled for frame F. */ 883/* Whether horizontal scroll bars are currently enabled for frame F. */
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 88e6d30bd9a..e08a4b53489 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -731,14 +731,23 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
731bool 731bool
732xg_hide_tooltip (struct frame *f) 732xg_hide_tooltip (struct frame *f)
733{ 733{
734 bool ret = 0;
735#ifdef USE_GTK_TOOLTIP 734#ifdef USE_GTK_TOOLTIP
736 if (f->output_data.x->ttip_window) 735 struct x_output *x = FRAME_X_OUTPUT (f);
736
737 if (x->ttip_window)
737 { 738 {
738 GtkWindow *win = f->output_data.x->ttip_window; 739 GtkWindow *win = f->output_data.x->ttip_window;
740
739 block_input (); 741 block_input ();
740 gtk_widget_hide (GTK_WIDGET (win)); 742 gtk_widget_hide (GTK_WIDGET (win));
741 743
744 /* Cancel call to xg_hide_tip. */
745 if (x->ttip_timeout != 0)
746 {
747 g_source_remove (x->ttip_timeout);
748 x->ttip_timeout = 0;
749 }
750
742 if (g_object_get_data (G_OBJECT (win), "restore-tt")) 751 if (g_object_get_data (G_OBJECT (win), "restore-tt"))
743 { 752 {
744 GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET (win)); 753 GdkWindow *gwin = gtk_widget_get_window (GTK_WIDGET (win));
@@ -747,11 +756,21 @@ xg_hide_tooltip (struct frame *f)
747 g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL); 756 g_object_set (settings, "gtk-enable-tooltips", TRUE, NULL);
748 } 757 }
749 unblock_input (); 758 unblock_input ();
750 759 return 1;
751 ret = 1;
752 } 760 }
753#endif 761#endif
754 return ret; 762 return 0;
763}
764
765/* One-shot timeout handler attached to GTK event loop in Fx_show_tip. */
766
767gboolean
768xg_hide_tip (gpointer data)
769{
770#ifdef USE_GTK_TOOLTIP
771 xg_hide_tooltip ((struct frame *) data);
772#endif
773 return FALSE;
755} 774}
756 775
757 776
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 8840fe76a85..d4dc295c512 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -178,6 +178,7 @@ extern bool xg_prepare_tooltip (struct frame *f,
178 int *height); 178 int *height);
179extern void xg_show_tooltip (struct frame *f, int root_x, int root_y); 179extern void xg_show_tooltip (struct frame *f, int root_x, int root_y);
180extern bool xg_hide_tooltip (struct frame *f); 180extern bool xg_hide_tooltip (struct frame *f);
181extern gboolean xg_hide_tip (gpointer data);
181 182
182#ifdef USE_CAIRO 183#ifdef USE_CAIRO
183extern void xg_page_setup_dialog (void); 184extern void xg_page_setup_dialog (void);
diff --git a/src/menu.c b/src/menu.c
index 90bb19a2e94..675caff6b88 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1400,7 +1400,12 @@ no quit occurs and `x-popup-menu' returns nil. */)
1400#ifdef HAVE_WINDOW_SYSTEM 1400#ifdef HAVE_WINDOW_SYSTEM
1401 /* Hide a previous tip, if any. */ 1401 /* Hide a previous tip, if any. */
1402 if (!FRAME_TERMCAP_P (f)) 1402 if (!FRAME_TERMCAP_P (f))
1403 Fx_hide_tip (); 1403 {
1404 Lisp_Object frame;
1405
1406 XSETFRAME (frame, f);
1407 Fx_hide_tip (frame);
1408 }
1404#endif 1409#endif
1405 1410
1406#ifdef HAVE_NTGUI /* FIXME: Is it really w32-specific? --Stef */ 1411#ifdef HAVE_NTGUI /* FIXME: Is it really w32-specific? --Stef */
diff --git a/src/nsfns.m b/src/nsfns.m
index 051e5091919..a017be5c1c5 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2658,10 +2658,6 @@ If omitted or nil, that stands for the selected frame's display. */)
2658 return make_number (1 << min (dpyinfo->n_planes, 24)); 2658 return make_number (1 << min (dpyinfo->n_planes, 24));
2659} 2659}
2660 2660
2661
2662/* Unused dummy def needed for compatibility. */
2663Lisp_Object tip_frame;
2664
2665/* TODO: move to xdisp or similar */ 2661/* TODO: move to xdisp or similar */
2666static void 2662static void
2667compute_tip_xy (struct frame *f, 2663compute_tip_xy (struct frame *f,
diff --git a/src/w32fns.c b/src/w32fns.c
index 20e09d8a463..0eb720e1cbe 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -341,7 +341,6 @@ x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
341 341
342 342
343static Lisp_Object unwind_create_frame (Lisp_Object); 343static Lisp_Object unwind_create_frame (Lisp_Object);
344static void unwind_create_tip_frame (Lisp_Object);
345static void my_create_window (struct frame *); 344static void my_create_window (struct frame *);
346static void my_create_tip_window (struct frame *); 345static void my_create_tip_window (struct frame *);
347 346
@@ -5053,6 +5052,7 @@ static void
5053my_create_tip_window (struct frame *f) 5052my_create_tip_window (struct frame *f)
5054{ 5053{
5055 RECT rect; 5054 RECT rect;
5055 Window tip_window;
5056 5056
5057 rect.left = rect.top = 0; 5057 rect.left = rect.top = 0;
5058 rect.right = FRAME_PIXEL_WIDTH (f); 5058 rect.right = FRAME_PIXEL_WIDTH (f);
@@ -5200,9 +5200,8 @@ x_make_gc (struct frame *f)
5200} 5200}
5201 5201
5202 5202
5203/* Handler for signals raised during x_create_frame and 5203/* Handler for signals raised during x_create_frame.
5204 x_create_tip_frame. FRAME is the frame which is partially 5204 FRAME is the frame which is partially constructed. */
5205 constructed. */
5206 5205
5207static Lisp_Object 5206static Lisp_Object
5208unwind_create_frame (Lisp_Object frame) 5207unwind_create_frame (Lisp_Object frame)
@@ -5976,7 +5975,7 @@ w32_display_monitor_attributes_list (void)
5976 { 5975 {
5977 struct frame *f = XFRAME (frame); 5976 struct frame *f = XFRAME (frame);
5978 5977
5979 if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) 5978 if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
5980 { 5979 {
5981 HMONITOR monitor = 5980 HMONITOR monitor =
5982 monitor_from_window_fn (FRAME_W32_WINDOW (f), 5981 monitor_from_window_fn (FRAME_W32_WINDOW (f),
@@ -6063,7 +6062,7 @@ w32_display_monitor_attributes_list_fallback (struct w32_display_info *dpyinfo)
6063 { 6062 {
6064 struct frame *f = XFRAME (frame); 6063 struct frame *f = XFRAME (frame);
6065 6064
6066 if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) 6065 if (FRAME_W32_P (f) && FRAME_TOOLTIP_P (f))
6067 frames = Fcons (frame, frames); 6066 frames = Fcons (frame, frames);
6068 } 6067 }
6069 attributes = Fcons (Fcons (Qframes, frames), attributes); 6068 attributes = Fcons (Fcons (Qframes, frames), attributes);
@@ -6466,39 +6465,6 @@ no value of TYPE (always string in the MS Windows case). */)
6466 Tool tips 6465 Tool tips
6467 ***********************************************************************/ 6466 ***********************************************************************/
6468 6467
6469static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
6470 Lisp_Object, int, int, int *, int *);
6471
6472/* The frame of a currently visible tooltip. */
6473
6474Lisp_Object tip_frame;
6475
6476/* If non-nil, a timer started that hides the last tooltip when it
6477 fires. */
6478
6479Lisp_Object tip_timer;
6480Window tip_window;
6481
6482/* If non-nil, a vector of 3 elements containing the last args
6483 with which x-show-tip was called. See there. */
6484
6485Lisp_Object last_show_tip_args;
6486
6487
6488static void
6489unwind_create_tip_frame (Lisp_Object frame)
6490{
6491 Lisp_Object deleted;
6492
6493 deleted = unwind_create_frame (frame);
6494 if (EQ (deleted, Qt))
6495 {
6496 tip_window = NULL;
6497 tip_frame = Qnil;
6498 }
6499}
6500
6501
6502/* Create a frame for a tooltip on the display described by DPYINFO. 6468/* Create a frame for a tooltip on the display described by DPYINFO.
6503 PARMS is a list of frame parameters. Value is the frame. 6469 PARMS is a list of frame parameters. Value is the frame.
6504 6470
@@ -6543,7 +6509,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
6543 f->wants_modeline = false; 6509 f->wants_modeline = false;
6544 XSETFRAME (frame, f); 6510 XSETFRAME (frame, f);
6545 6511
6546 record_unwind_protect (unwind_create_tip_frame, frame); 6512 record_unwind_protect (do_unwind_create_frame, frame);
6547 6513
6548 /* By setting the output method, we're essentially saying that 6514 /* By setting the output method, we're essentially saying that
6549 the frame is live, as per FRAME_LIVE_P. If we get a signal 6515 the frame is live, as per FRAME_LIVE_P. If we get a signal
@@ -6555,6 +6521,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
6555 6521
6556 FRAME_FONTSET (f) = -1; 6522 FRAME_FONTSET (f) = -1;
6557 fset_icon_name (f, Qnil); 6523 fset_icon_name (f, Qnil);
6524 f->tooltip = true;
6558 6525
6559#ifdef GLYPH_DEBUG 6526#ifdef GLYPH_DEBUG
6560 image_cache_refcount = 6527 image_cache_refcount =
@@ -6663,11 +6630,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
6663 height = FRAME_LINES (f); 6630 height = FRAME_LINES (f);
6664 SET_FRAME_COLS (f, 0); 6631 SET_FRAME_COLS (f, 0);
6665 SET_FRAME_LINES (f, 0); 6632 SET_FRAME_LINES (f, 0);
6666 adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f), 6633 change_frame_size (f, width, height, true, false, false, false);
6667 height * FRAME_LINE_HEIGHT (f), 0, true, Qtip_frame);
6668 /* Add `tooltip' frame parameter's default value. */
6669 if (NILP (Fframe_parameter (frame, Qtooltip)))
6670 Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
6671 6634
6672 /* Set up faces after all frame parameters are known. This call 6635 /* Set up faces after all frame parameters are known. This call
6673 also merges in face attributes specified for new frames. 6636 also merges in face attributes specified for new frames.
@@ -6695,6 +6658,9 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
6695 6658
6696 f->no_split = true; 6659 f->no_split = true;
6697 6660
6661 /* Now this is an official tooltip frame on this display. */
6662 dpyinfo->w32_tooltip_frame = f;
6663
6698 /* Now that the frame is official, it counts as a reference to 6664 /* Now that the frame is official, it counts as a reference to
6699 its display. */ 6665 its display. */
6700 FRAME_DISPLAY_INFO (f)->reference_count++; 6666 FRAME_DISPLAY_INFO (f)->reference_count++;
@@ -6813,46 +6779,39 @@ compute_tip_xy (struct frame *f,
6813 *root_x = min_x; 6779 *root_x = min_x;
6814} 6780}
6815 6781
6816/* Hide tooltip. Delete its frame if DELETE is true. */ 6782/* Hide tooltip frame F and delete it if DELETE is true. */
6783
6817static Lisp_Object 6784static Lisp_Object
6818x_hide_tip (bool delete) 6785x_hide_tip (struct frame *f, bool delete)
6819{ 6786{
6820 if (!NILP (tip_timer)) 6787 if (f)
6821 { 6788 {
6822 call1 (Qcancel_timer, tip_timer); 6789 Lisp_Object frame, timer;
6823 tip_timer = Qnil;
6824 }
6825 6790
6826 if (NILP (tip_frame) 6791 XSETFRAME (frame, f);
6827 || (!delete && FRAMEP (tip_frame) 6792 timer = Fframe_parameter (frame, Qtooltip_timer);
6828 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
6829 return Qnil;
6830 else
6831 {
6832 ptrdiff_t count;
6833 Lisp_Object was_open = Qnil;
6834 6793
6835 count = SPECPDL_INDEX (); 6794 if (!NILP (timer))
6836 specbind (Qinhibit_redisplay, Qt); 6795 call1 (Qcancel_timer, timer);
6837 specbind (Qinhibit_quit, Qt);
6838 6796
6839 if (FRAMEP (tip_frame)) 6797 if (!delete && !FRAME_VISIBLE_P (f))
6798 return Qnil;
6799 else
6840 { 6800 {
6801 ptrdiff_t count = SPECPDL_INDEX ();
6802
6803 specbind (Qinhibit_redisplay, Qt);
6804 specbind (Qinhibit_quit, Qt);
6805
6841 if (delete) 6806 if (delete)
6842 { 6807 delete_frame (frame, Qnil);
6843 delete_frame (tip_frame, Qnil);
6844 tip_frame = Qnil;
6845 }
6846 else 6808 else
6847 x_make_frame_invisible (XFRAME (tip_frame)); 6809 x_make_frame_invisible (f);
6848 6810
6849 was_open = Qt; 6811 return unbind_to (count, Qt);
6850 } 6812 }
6851 else
6852 tip_frame = Qnil;
6853
6854 return unbind_to (count, was_open);
6855 } 6813 }
6814 return Qnil;
6856} 6815}
6857 6816
6858 6817
@@ -6886,7 +6845,8 @@ with offset DY added (default is -10).
6886 6845
6887A tooltip's maximum size is specified by `x-max-tooltip-size'. 6846A tooltip's maximum size is specified by `x-max-tooltip-size'.
6888Text larger than the specified size is clipped. */) 6847Text larger than the specified size is clipped. */)
6889 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy) 6848 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
6849 Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
6890{ 6850{
6891 struct frame *tip_f; 6851 struct frame *tip_f;
6892 struct window *w; 6852 struct window *w;
@@ -6897,7 +6857,7 @@ Text larger than the specified size is clipped. */)
6897 int old_windows_or_buffers_changed = windows_or_buffers_changed; 6857 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6898 ptrdiff_t count = SPECPDL_INDEX (); 6858 ptrdiff_t count = SPECPDL_INDEX ();
6899 ptrdiff_t count_1; 6859 ptrdiff_t count_1;
6900 Lisp_Object window, size; 6860 Lisp_Object window, size, tip_frame, parameters;
6901 AUTO_STRING (tip, " *tip*"); 6861 AUTO_STRING (tip, " *tip*");
6902 6862
6903 specbind (Qinhibit_redisplay, Qt); 6863 specbind (Qinhibit_redisplay, Qt);
@@ -6919,14 +6879,22 @@ Text larger than the specified size is clipped. */)
6919 else 6879 else
6920 CHECK_NUMBER (dy); 6880 CHECK_NUMBER (dy);
6921 6881
6922 if (NILP (last_show_tip_args)) 6882 parameters = Fframe_parameter (frame, Qtooltip_parameters);
6923 last_show_tip_args = Fmake_vector (make_number (3), Qnil); 6883 if (NILP (parameters))
6884 parameters = Fmake_vector (make_number (3), Qnil);
6924 6885
6925 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame))) 6886 /* Look at current tooltip frame, if any. */
6887 tip_f = FRAME_DISPLAY_INFO (XFRAME (frame))->w32_tooltip_frame;
6888 if (tip_f)
6889 XSETFRAME (tip_frame, tip_f);
6890 else
6891 tip_frame = Qnil;
6892
6893 if (tip_f && FRAME_LIVE_P (tip_f))
6926 { 6894 {
6927 Lisp_Object last_string = AREF (last_show_tip_args, 0); 6895 Lisp_Object last_string = AREF (parameters, 0);
6928 Lisp_Object last_frame = AREF (last_show_tip_args, 1); 6896 Lisp_Object last_frame = AREF (parameters, 1);
6929 Lisp_Object last_parms = AREF (last_show_tip_args, 2); 6897 Lisp_Object last_parms = AREF (parameters, 2);
6930 6898
6931 if (FRAME_VISIBLE_P (XFRAME (tip_frame)) 6899 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
6932 && EQ (frame, last_frame) 6900 && EQ (frame, last_frame)
@@ -6934,14 +6902,10 @@ Text larger than the specified size is clipped. */)
6934 && !NILP (Fequal (last_parms, parms))) 6902 && !NILP (Fequal (last_parms, parms)))
6935 { 6903 {
6936 /* Only DX and DY have changed. */ 6904 /* Only DX and DY have changed. */
6937 tip_f = XFRAME (tip_frame); 6905 Lisp_Object timer = Fframe_parameter (tip_frame, Qtooltip_timer);
6938 if (!NILP (tip_timer))
6939 {
6940 Lisp_Object timer = tip_timer;
6941 6906
6942 tip_timer = Qnil; 6907 if (!NILP (timer))
6943 call1 (Qcancel_timer, timer); 6908 call1 (Qcancel_timer, timer);
6944 }
6945 6909
6946 block_input (); 6910 block_input ();
6947 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f), 6911 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
@@ -7011,17 +6975,22 @@ Text larger than the specified size is clipped. */)
7011 } 6975 }
7012 } 6976 }
7013 6977
7014 x_hide_tip (delete); 6978 x_hide_tip (tip_f, delete);
7015 } 6979 }
7016 else 6980 else
7017 x_hide_tip (true); 6981 x_hide_tip (tip_f, true);
7018 } 6982 }
7019 else 6983 else
7020 x_hide_tip (true); 6984 x_hide_tip (tip_f, true);
7021 6985
7022 ASET (last_show_tip_args, 0, string); 6986 /* Update tooltip parameters. */
7023 ASET (last_show_tip_args, 1, frame); 6987 {
7024 ASET (last_show_tip_args, 2, parms); 6988 AUTO_FRAME_ARG (arg, Qtooltip_parameters, parameters);
6989 ASET (parameters, 0, string);
6990 ASET (parameters, 1, frame);
6991 ASET (parameters, 2, parms);
6992 Fmodify_frame_parameters (frame, arg);
6993 }
7025 6994
7026 /* Block input until the tip has been fully drawn, to avoid crashes 6995 /* Block input until the tip has been fully drawn, to avoid crashes
7027 when drawing tips in menus. */ 6996 when drawing tips in menus. */
@@ -7041,11 +7010,8 @@ Text larger than the specified size is clipped. */)
7041 if (NILP (Fassq (Qbackground_color, parms))) 7010 if (NILP (Fassq (Qbackground_color, parms)))
7042 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")), 7011 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
7043 parms); 7012 parms);
7044 7013 if (NILP (tip_frame
7045 /* Create a frame for the tooltip, and record it in the global 7014 = x_create_tip_frame (FRAME_DISPLAY_INFO (XFRAME (frame)), parms)))
7046 variable tip_frame. */
7047 struct frame *f; /* The value is unused. */
7048 if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
7049 { 7015 {
7050 /* Creating the tip frame failed. */ 7016 /* Creating the tip frame failed. */
7051 unblock_input (); 7017 unblock_input ();
@@ -7149,20 +7115,47 @@ Text larger than the specified size is clipped. */)
7149 windows_or_buffers_changed = old_windows_or_buffers_changed; 7115 windows_or_buffers_changed = old_windows_or_buffers_changed;
7150 7116
7151 start_timer: 7117 start_timer:
7152 /* Let the tip disappear after timeout seconds. */ 7118 {
7153 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil, 7119 /* Let the tip disappear after timeout seconds. */
7154 intern ("x-hide-tip")); 7120 AUTO_FRAME_ARG (arg, Qtooltip_timer,
7155 7121 call3 (intern ("run-at-time"), timeout,
7122 Qnil, intern ("x-hide-tip")));
7123 Fmodify_frame_parameters (tip_frame, arg);
7124 }
7156 return unbind_to (count, Qnil); 7125 return unbind_to (count, Qnil);
7157} 7126}
7158 7127
7159 7128
7160DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0, 7129DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 1, 0,
7161 doc: /* Hide the current tooltip window, if there is any. 7130 doc: /* Hide the current tooltip window, if there is any.
7131Optional FRAME is the frame to hide tooltip on.
7162Value is t if tooltip was open, nil otherwise. */) 7132Value is t if tooltip was open, nil otherwise. */)
7163 (void) 7133 (Lisp_Object frame)
7164{ 7134{
7165 return x_hide_tip (!tooltip_reuse_hidden_frame); 7135 Lisp_Object obj = Qnil;
7136
7137 if (NILP (frame))
7138 {
7139 struct w32_display_info *dpyinfo;
7140
7141 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
7142 if (dpyinfo->w32_tooltip_frame)
7143 if (!NILP (x_hide_tip (dpyinfo->w32_tooltip_frame,
7144 !tooltip_reuse_hidden_frame)))
7145 obj = Qt;
7146 }
7147 else
7148 {
7149 struct frame *f;
7150
7151 CHECK_FRAME (frame);
7152 f = XFRAME (frame);
7153 if (FRAME_DISPLAY_INFO (f)
7154 && FRAME_DISPLAY_INFO (f)->w32_tooltip_frame)
7155 obj = x_hide_tip (FRAME_DISPLAY_INFO (f)->w32_tooltip_frame,
7156 !tooltip_reuse_hidden_frame);
7157 }
7158 return obj;
7166} 7159}
7167 7160
7168/*********************************************************************** 7161/***********************************************************************
@@ -9765,7 +9758,6 @@ syms_of_w32fns (void)
9765 DEFSYM (Qworkarea, "workarea"); 9758 DEFSYM (Qworkarea, "workarea");
9766 DEFSYM (Qmm_size, "mm-size"); 9759 DEFSYM (Qmm_size, "mm-size");
9767 DEFSYM (Qframes, "frames"); 9760 DEFSYM (Qframes, "frames");
9768 DEFSYM (Qtip_frame, "tip-frame");
9769 DEFSYM (Qassq_delete_all, "assq-delete-all"); 9761 DEFSYM (Qassq_delete_all, "assq-delete-all");
9770 DEFSYM (Qunicode_sip, "unicode-sip"); 9762 DEFSYM (Qunicode_sip, "unicode-sip");
9771#if defined WINDOWSNT && !defined HAVE_DBUS 9763#if defined WINDOWSNT && !defined HAVE_DBUS
@@ -10151,13 +10143,6 @@ tip frame. */);
10151 defsubr (&Sset_message_beep); 10143 defsubr (&Sset_message_beep);
10152 defsubr (&Sx_show_tip); 10144 defsubr (&Sx_show_tip);
10153 defsubr (&Sx_hide_tip); 10145 defsubr (&Sx_hide_tip);
10154 tip_timer = Qnil;
10155 staticpro (&tip_timer);
10156 tip_frame = Qnil;
10157 staticpro (&tip_frame);
10158
10159 last_show_tip_args = Qnil;
10160 staticpro (&last_show_tip_args);
10161 10146
10162 defsubr (&Sx_file_dialog); 10147 defsubr (&Sx_file_dialog);
10163#ifdef WINDOWSNT 10148#ifdef WINDOWSNT
diff --git a/src/w32term.c b/src/w32term.c
index 5a11e2a871a..8c2fdaf0f59 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5024,11 +5024,10 @@ w32_read_socket (struct terminal *terminal,
5024 /* wParam non-zero means Window is about to be shown, 0 means 5024 /* wParam non-zero means Window is about to be shown, 0 means
5025 about to be hidden. */ 5025 about to be hidden. */
5026 /* Redo the mouse-highlight after the tooltip has gone. */ 5026 /* Redo the mouse-highlight after the tooltip has gone. */
5027 if (!msg.msg.wParam && msg.msg.hwnd == tip_window) 5027 if (!msg.msg.wParam
5028 { 5028 && dpyinfo->w32_tooltip_frame
5029 tip_window = NULL; 5029 && FRAME_W32_WINDOW (dpyinfo->w32_tooltip_frame) == msg.msg.hwnd)
5030 x_redo_mouse_highlight (dpyinfo); 5030 x_redo_mouse_highlight (dpyinfo);
5031 }
5032 5031
5033 /* If window has been obscured or exposed by another window 5032 /* If window has been obscured or exposed by another window
5034 being maximized or minimized/restored, then recheck 5033 being maximized or minimized/restored, then recheck
@@ -5394,7 +5393,7 @@ w32_read_socket (struct terminal *terminal,
5394 struct frame *f = XFRAME (frame); 5393 struct frame *f = XFRAME (frame);
5395 /* The tooltip has been drawn already. Avoid the 5394 /* The tooltip has been drawn already. Avoid the
5396 SET_FRAME_GARBAGED below. */ 5395 SET_FRAME_GARBAGED below. */
5397 if (EQ (frame, tip_frame)) 5396 if (FRAME_TOOLTIP_P (f))
5398 continue; 5397 continue;
5399 5398
5400 /* Check "visible" frames and mark each as obscured or not. 5399 /* Check "visible" frames and mark each as obscured or not.
@@ -5871,7 +5870,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
5871 /* Don't change the size of a tip frame; there's no point in 5870 /* Don't change the size of a tip frame; there's no point in
5872 doing it because it's done in Fx_show_tip, and it leads to 5871 doing it because it's done in Fx_show_tip, and it leads to
5873 problems because the tip frame has no widget. */ 5872 problems because the tip frame has no widget. */
5874 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 5873 if (!FRAME_TOOLTIP_P (f))
5875 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 5874 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
5876 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 5875 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
5877 false, Qfont); 5876 false, Qfont);
@@ -6569,6 +6568,8 @@ x_free_frame_resources (struct frame *f)
6569 dpyinfo->w32_focus_event_frame = 0; 6568 dpyinfo->w32_focus_event_frame = 0;
6570 if (f == dpyinfo->x_highlight_frame) 6569 if (f == dpyinfo->x_highlight_frame)
6571 dpyinfo->x_highlight_frame = 0; 6570 dpyinfo->x_highlight_frame = 0;
6571 if (f == dpyinfo->w32_tooltip_frame)
6572 dpyinfo->w32_tooltip_frame = 0;
6572 if (f == hlinfo->mouse_face_mouse_frame) 6573 if (f == hlinfo->mouse_face_mouse_frame)
6573 reset_mouse_highlight (hlinfo); 6574 reset_mouse_highlight (hlinfo);
6574 6575
diff --git a/src/w32term.h b/src/w32term.h
index 320477073a5..3934e8500a3 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -186,6 +186,9 @@ struct w32_display_info
186 /* The frame waiting to be auto-raised in w32_read_socket. */ 186 /* The frame waiting to be auto-raised in w32_read_socket. */
187 struct frame *w32_pending_autoraise_frame; 187 struct frame *w32_pending_autoraise_frame;
188 188
189 /* Tooltip frame on this display. */
190 struct frame *w32_tooltip_frame;
191
189 /* The frame where the mouse was last time we reported a mouse event. */ 192 /* The frame where the mouse was last time we reported a mouse event. */
190 struct frame *last_mouse_frame; 193 struct frame *last_mouse_frame;
191 194
diff --git a/src/xdisp.c b/src/xdisp.c
index 14d6f8fcf93..b8dcdcec41f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2841,11 +2841,7 @@ init_iterator (struct it *it, struct window *w,
2841 frames when the fringes are turned off. But leave the dimensions 2841 frames when the fringes are turned off. But leave the dimensions
2842 zero for tooltip frames, as these glyphs look ugly there and also 2842 zero for tooltip frames, as these glyphs look ugly there and also
2843 sabotage calculations of tooltip dimensions in x-show-tip. */ 2843 sabotage calculations of tooltip dimensions in x-show-tip. */
2844#ifdef HAVE_WINDOW_SYSTEM 2844 if (!FRAME_TOOLTIP_P (it->f))
2845 if (!(FRAME_WINDOW_P (it->f)
2846 && FRAMEP (tip_frame)
2847 && it->f == XFRAME (tip_frame)))
2848#endif
2849 { 2845 {
2850 if (it->line_wrap == TRUNCATE) 2846 if (it->line_wrap == TRUNCATE)
2851 { 2847 {
@@ -11713,7 +11709,7 @@ x_consider_frame_title (Lisp_Object frame)
11713 if ((FRAME_WINDOW_P (f) 11709 if ((FRAME_WINDOW_P (f)
11714 || FRAME_MINIBUF_ONLY_P (f) 11710 || FRAME_MINIBUF_ONLY_P (f)
11715 || f->explicit_name) 11711 || f->explicit_name)
11716 && NILP (Fframe_parameter (frame, Qtooltip))) 11712 && !FRAME_TOOLTIP_P (f))
11717 { 11713 {
11718 /* Do we have more than one visible frame on this X display? */ 11714 /* Do we have more than one visible frame on this X display? */
11719 Lisp_Object tail, other_frame, fmt; 11715 Lisp_Object tail, other_frame, fmt;
@@ -11730,7 +11726,7 @@ x_consider_frame_title (Lisp_Object frame)
11730 if (tf != f 11726 if (tf != f
11731 && FRAME_KBOARD (tf) == FRAME_KBOARD (f) 11727 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11732 && !FRAME_MINIBUF_ONLY_P (tf) 11728 && !FRAME_MINIBUF_ONLY_P (tf)
11733 && !EQ (other_frame, tip_frame) 11729 && !FRAME_TOOLTIP_P (tf)
11734 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf))) 11730 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11735 break; 11731 break;
11736 } 11732 }
@@ -11793,13 +11789,6 @@ prepare_menu_bars (void)
11793{ 11789{
11794 bool all_windows = windows_or_buffers_changed || update_mode_lines; 11790 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11795 bool some_windows = REDISPLAY_SOME_P (); 11791 bool some_windows = REDISPLAY_SOME_P ();
11796 Lisp_Object tooltip_frame;
11797
11798#ifdef HAVE_WINDOW_SYSTEM
11799 tooltip_frame = tip_frame;
11800#else
11801 tooltip_frame = Qnil;
11802#endif
11803 11792
11804 if (FUNCTIONP (Vpre_redisplay_function)) 11793 if (FUNCTIONP (Vpre_redisplay_function))
11805 { 11794 {
@@ -11840,7 +11829,7 @@ prepare_menu_bars (void)
11840 && !XBUFFER (w->contents)->text->redisplay) 11829 && !XBUFFER (w->contents)->text->redisplay)
11841 continue; 11830 continue;
11842 11831
11843 if (!EQ (frame, tooltip_frame) 11832 if (!FRAME_TOOLTIP_P (f)
11844 && (FRAME_ICONIFIED_P (f) 11833 && (FRAME_ICONIFIED_P (f)
11845 || FRAME_VISIBLE_P (f) == 1 11834 || FRAME_VISIBLE_P (f) == 1
11846 /* Exclude TTY frames that are obscured because they 11835 /* Exclude TTY frames that are obscured because they
@@ -11877,7 +11866,7 @@ prepare_menu_bars (void)
11877 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); 11866 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
11878 11867
11879 /* Ignore tooltip frame. */ 11868 /* Ignore tooltip frame. */
11880 if (EQ (frame, tooltip_frame)) 11869 if (FRAME_TOOLTIP_P (f))
11881 continue; 11870 continue;
11882 11871
11883 if (some_windows 11872 if (some_windows
diff --git a/src/xfns.c b/src/xfns.c
index 798dc49bef5..16dbcfd5f84 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4151,7 +4151,7 @@ x_make_monitor_attribute_list (struct MonitorInfo *monitors,
4151 struct frame *f = XFRAME (frame); 4151 struct frame *f = XFRAME (frame);
4152 4152
4153 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo 4153 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
4154 && !EQ (frame, tip_frame)) 4154 && !FRAME_TOOLTIP_P (f))
4155 { 4155 {
4156 int i = x_get_monitor_for_frame (f, monitors, n_monitors); 4156 int i = x_get_monitor_for_frame (f, monitors, n_monitors);
4157 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i))); 4157 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
@@ -4447,7 +4447,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4447 struct frame *f = XFRAME (frame); 4447 struct frame *f = XFRAME (frame);
4448 4448
4449 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo 4449 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
4450 && !EQ (frame, tip_frame)) 4450 && !FRAME_TOOLTIP_P (f))
4451 { 4451 {
4452 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f)); 4452 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4453 4453
@@ -5312,39 +5312,6 @@ no value of TYPE (always string in the MS Windows case). */)
5312 Tool tips 5312 Tool tips
5313 ***********************************************************************/ 5313 ***********************************************************************/
5314 5314
5315static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
5316 Lisp_Object, int, int, int *, int *);
5317
5318/* The frame of a currently visible tooltip. */
5319
5320Lisp_Object tip_frame;
5321
5322/* If non-nil, a timer started that hides the last tooltip when it
5323 fires. */
5324
5325static Lisp_Object tip_timer;
5326Window tip_window;
5327
5328/* If non-nil, a vector of 3 elements containing the last args
5329 with which x-show-tip was called. See there. */
5330
5331static Lisp_Object last_show_tip_args;
5332
5333
5334static void
5335unwind_create_tip_frame (Lisp_Object frame)
5336{
5337 Lisp_Object deleted;
5338
5339 deleted = unwind_create_frame (frame);
5340 if (EQ (deleted, Qt))
5341 {
5342 tip_window = None;
5343 tip_frame = Qnil;
5344 }
5345}
5346
5347
5348/* Create a frame for a tooltip on the display described by DPYINFO. 5315/* Create a frame for a tooltip on the display described by DPYINFO.
5349 PARMS is a list of frame parameters. TEXT is the string to 5316 PARMS is a list of frame parameters. TEXT is the string to
5350 display in the tip frame. Value is the frame. 5317 display in the tip frame. Value is the frame.
@@ -5381,7 +5348,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
5381 f = make_frame (false); 5348 f = make_frame (false);
5382 f->wants_modeline = false; 5349 f->wants_modeline = false;
5383 XSETFRAME (frame, f); 5350 XSETFRAME (frame, f);
5384 record_unwind_protect (unwind_create_tip_frame, frame); 5351 record_unwind_protect (do_unwind_create_frame, frame);
5385 5352
5386 f->terminal = dpyinfo->terminal; 5353 f->terminal = dpyinfo->terminal;
5387 5354
@@ -5402,6 +5369,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
5402 f->output_data.x->white_relief.pixel = -1; 5369 f->output_data.x->white_relief.pixel = -1;
5403 f->output_data.x->black_relief.pixel = -1; 5370 f->output_data.x->black_relief.pixel = -1;
5404 5371
5372 f->tooltip = true;
5405 fset_icon_name (f, Qnil); 5373 fset_icon_name (f, Qnil);
5406 FRAME_DISPLAY_INFO (f) = dpyinfo; 5374 FRAME_DISPLAY_INFO (f) = dpyinfo;
5407 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 5375 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
@@ -5545,8 +5513,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
5545 = f->output_data.x->text_cursor; 5513 = f->output_data.x->text_cursor;
5546 /* Arrange for getting MapNotify and UnmapNotify events. */ 5514 /* Arrange for getting MapNotify and UnmapNotify events. */
5547 attrs.event_mask = StructureNotifyMask; 5515 attrs.event_mask = StructureNotifyMask;
5548 tip_window 5516 FRAME_X_WINDOW (f)
5549 = FRAME_X_WINDOW (f)
5550 = XCreateWindow (FRAME_X_DISPLAY (f), 5517 = XCreateWindow (FRAME_X_DISPLAY (f),
5551 FRAME_DISPLAY_INFO (f)->root_window, 5518 FRAME_DISPLAY_INFO (f)->root_window,
5552 /* x, y, width, height */ 5519 /* x, y, width, height */
@@ -5555,7 +5522,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
5555 f->border_width, 5522 f->border_width,
5556 CopyFromParent, InputOutput, CopyFromParent, 5523 CopyFromParent, InputOutput, CopyFromParent,
5557 mask, &attrs); 5524 mask, &attrs);
5558 XChangeProperty (FRAME_X_DISPLAY (f), tip_window, 5525 XChangeProperty (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
5559 FRAME_DISPLAY_INFO (f)->Xatom_net_window_type, 5526 FRAME_DISPLAY_INFO (f)->Xatom_net_window_type,
5560 XA_ATOM, 32, PropModeReplace, 5527 XA_ATOM, 32, PropModeReplace,
5561 (unsigned char *)&type, 1); 5528 (unsigned char *)&type, 1);
@@ -5582,13 +5549,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
5582 SET_FRAME_LINES (f, 0); 5549 SET_FRAME_LINES (f, 0);
5583 change_frame_size (f, width, height, true, false, false, false); 5550 change_frame_size (f, width, height, true, false, false, false);
5584 5551
5585 /* Add `tooltip' frame parameter's default value. */
5586 if (NILP (Fframe_parameter (frame, Qtooltip)))
5587 {
5588 AUTO_FRAME_ARG (arg, Qtooltip, Qt);
5589 Fmodify_frame_parameters (frame, arg);
5590 }
5591
5592 /* FIXME - can this be done in a similar way to normal frames? 5552 /* FIXME - can this be done in a similar way to normal frames?
5593 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */ 5553 http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
5594 5554
@@ -5633,6 +5593,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
5633 5593
5634 f->no_split = true; 5594 f->no_split = true;
5635 5595
5596 /* Now this is an official tooltip frame on this display. */
5597 dpyinfo->x_tooltip_frame = f;
5598
5636 /* Now that the frame will be official, it counts as a reference to 5599 /* Now that the frame will be official, it counts as a reference to
5637 its display and terminal. */ 5600 its display and terminal. */
5638 FRAME_DISPLAY_INFO (f)->reference_count++; 5601 FRAME_DISPLAY_INFO (f)->reference_count++;
@@ -5663,7 +5626,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
5663 the display in *ROOT_X, and *ROOT_Y. */ 5626 the display in *ROOT_X, and *ROOT_Y. */
5664 5627
5665static void 5628static void
5666compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object dy, int width, int height, int *root_x, int *root_y) 5629compute_tip_xy (struct frame *f,
5630 Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
5631 int width, int height, int *root_x, int *root_y)
5667{ 5632{
5668 Lisp_Object left, top, right, bottom; 5633 Lisp_Object left, top, right, bottom;
5669 int win_x, win_y; 5634 int win_x, win_y;
@@ -5759,56 +5724,39 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object
5759 *root_x = min_x; 5724 *root_x = min_x;
5760} 5725}
5761 5726
5727/* Hide tooltip frame F and delete it if DELETE is true. */
5762 5728
5763/* Hide tooltip. Delete its frame if DELETE is true. */
5764static Lisp_Object 5729static Lisp_Object
5765x_hide_tip (bool delete) 5730x_hide_tip (struct frame *f, bool delete)
5766{ 5731{
5767 if (!NILP (tip_timer)) 5732 if (f)
5768 { 5733 {
5769 call1 (Qcancel_timer, tip_timer); 5734 Lisp_Object frame, timer;
5770 tip_timer = Qnil;
5771 }
5772 5735
5736 XSETFRAME (frame, f);
5737 timer = Fframe_parameter (frame, Qtooltip_timer);
5773 5738
5774 if (NILP (tip_frame) 5739 if (!NILP (timer))
5775 || (!delete && FRAMEP (tip_frame) 5740 call1 (Qcancel_timer, timer);
5776 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
5777 return Qnil;
5778 else
5779 {
5780 ptrdiff_t count;
5781 Lisp_Object was_open = Qnil;
5782 5741
5783 count = SPECPDL_INDEX (); 5742 if (!delete && !FRAME_VISIBLE_P (f))
5784 specbind (Qinhibit_redisplay, Qt); 5743 return Qnil;
5785 specbind (Qinhibit_quit, Qt); 5744 else
5745 {
5746 ptrdiff_t count = SPECPDL_INDEX ();
5786 5747
5787#ifdef USE_GTK 5748 specbind (Qinhibit_redisplay, Qt);
5788 { 5749 specbind (Qinhibit_quit, Qt);
5789 /* When using system tooltip, tip_frame is the Emacs frame on
5790 which the tip is shown. */
5791 struct frame *f = XFRAME (tip_frame);
5792 5750
5793 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f)) 5751#ifdef USE_GTK
5794 { 5752 if (x_gtk_use_system_tooltips)
5795 tip_frame = Qnil; 5753 /* Should be handled by xg_hide_tooltip. */
5796 was_open = Qt; 5754 emacs_abort ();
5797 }
5798 }
5799#endif 5755#endif
5800
5801 if (FRAMEP (tip_frame))
5802 {
5803 if (delete) 5756 if (delete)
5804 { 5757 delete_frame (frame, Qnil);
5805 delete_frame (tip_frame, Qnil);
5806 tip_frame = Qnil;
5807 }
5808 else 5758 else
5809 x_make_frame_invisible (XFRAME (tip_frame)); 5759 x_make_frame_invisible (f);
5810
5811 was_open = Qt;
5812 5760
5813#ifdef USE_LUCID 5761#ifdef USE_LUCID
5814 /* Bloodcurdling hack alert: The Lucid menu bar widget's 5762 /* Bloodcurdling hack alert: The Lucid menu bar widget's
@@ -5816,12 +5764,12 @@ x_hide_tip (bool delete)
5816 menu items is unmapped. Redisplay the menu manually... */ 5764 menu items is unmapped. Redisplay the menu manually... */
5817 { 5765 {
5818 Widget w; 5766 Widget w;
5819 struct frame *f = SELECTED_FRAME (); 5767 struct frame *sf = SELECTED_FRAME ();
5820 if (FRAME_X_P (f) && FRAME_LIVE_P (f)) 5768 if (FRAME_X_P (sf) && FRAME_LIVE_P (sf))
5821 { 5769 {
5822 w = f->output_data.x->menubar_widget; 5770 w = sf->output_data.x->menubar_widget;
5823 5771
5824 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen) 5772 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (sf)->screen)
5825 && w != NULL) 5773 && w != NULL)
5826 { 5774 {
5827 block_input (); 5775 block_input ();
@@ -5831,12 +5779,10 @@ x_hide_tip (bool delete)
5831 } 5779 }
5832 } 5780 }
5833#endif /* USE_LUCID */ 5781#endif /* USE_LUCID */
5782 return unbind_to (count, Qt);
5834 } 5783 }
5835 else
5836 tip_frame = Qnil;
5837
5838 return unbind_to (count, was_open);
5839 } 5784 }
5785 return Qnil;
5840} 5786}
5841 5787
5842DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, 5788DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
@@ -5869,7 +5815,8 @@ with offset DY added (default is -10).
5869 5815
5870A tooltip's maximum size is specified by `x-max-tooltip-size'. 5816A tooltip's maximum size is specified by `x-max-tooltip-size'.
5871Text larger than the specified size is clipped. */) 5817Text larger than the specified size is clipped. */)
5872 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy) 5818 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
5819 Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
5873{ 5820{
5874 struct frame *f, *tip_f; 5821 struct frame *f, *tip_f;
5875 struct window *w; 5822 struct window *w;
@@ -5880,7 +5827,7 @@ Text larger than the specified size is clipped. */)
5880 int old_windows_or_buffers_changed = windows_or_buffers_changed; 5827 int old_windows_or_buffers_changed = windows_or_buffers_changed;
5881 ptrdiff_t count = SPECPDL_INDEX (); 5828 ptrdiff_t count = SPECPDL_INDEX ();
5882 ptrdiff_t count_1; 5829 ptrdiff_t count_1;
5883 Lisp_Object window, size; 5830 Lisp_Object window, size, tip_frame, parameters;
5884 AUTO_STRING (tip, " *tip*"); 5831 AUTO_STRING (tip, " *tip*");
5885 5832
5886 specbind (Qinhibit_redisplay, Qt); 5833 specbind (Qinhibit_redisplay, Qt);
@@ -5910,8 +5857,8 @@ Text larger than the specified size is clipped. */)
5910 { 5857 {
5911 bool ok; 5858 bool ok;
5912 5859
5913 /* Hide a previous tip, if any. */ 5860 /* Hide a previous tip on this frame, if any. */
5914 Fx_hide_tip (); 5861 xg_hide_tooltip (f);
5915 5862
5916 block_input (); 5863 block_input ();
5917 ok = xg_prepare_tooltip (f, string, &width, &height); 5864 ok = xg_prepare_tooltip (f, string, &width, &height);
@@ -5919,37 +5866,47 @@ Text larger than the specified size is clipped. */)
5919 { 5866 {
5920 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); 5867 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
5921 xg_show_tooltip (f, root_x, root_y); 5868 xg_show_tooltip (f, root_x, root_y);
5922 /* This is used in Fx_hide_tip. */
5923 XSETFRAME (tip_frame, f);
5924 } 5869 }
5925 unblock_input (); 5870 unblock_input ();
5926 if (ok) goto start_timer; 5871 if (ok)
5872 /* Schedule call to xg_hide_tip from GTK event loop
5873 to allow the tip disappear after timeout seconds. */
5874 FRAME_X_OUTPUT (f)->ttip_timeout
5875 = g_timeout_add_seconds (XINT (timeout), xg_hide_tip, (gpointer) f);
5876 else
5877 /* FIXME: what if not ok? */
5878 FRAME_X_OUTPUT (f)->ttip_timeout = 0;
5879 return unbind_to (count, Qnil);
5927 } 5880 }
5928#endif /* USE_GTK */ 5881#endif /* USE_GTK */
5929 5882
5930 if (NILP (last_show_tip_args)) 5883 parameters = Fframe_parameter (frame, Qtooltip_parameters);
5931 last_show_tip_args = Fmake_vector (make_number (3), Qnil); 5884 if (NILP (parameters))
5885 parameters = Fmake_vector (make_number (3), Qnil);
5932 5886
5933 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame))) 5887 /* Look at current tooltip frame, if any. */
5888 tip_f = FRAME_DISPLAY_INFO (f)->x_tooltip_frame;
5889 if (tip_f)
5890 XSETFRAME (tip_frame, tip_f);
5891 else
5892 tip_frame = Qnil;
5893
5894 if (tip_f && FRAME_LIVE_P (tip_f))
5934 { 5895 {
5935 Lisp_Object last_string = AREF (last_show_tip_args, 0); 5896 Lisp_Object last_string = AREF (parameters, 0);
5936 Lisp_Object last_frame = AREF (last_show_tip_args, 1); 5897 Lisp_Object last_frame = AREF (parameters, 1);
5937 Lisp_Object last_parms = AREF (last_show_tip_args, 2); 5898 Lisp_Object last_parms = AREF (parameters, 2);
5938 5899
5939 if (FRAME_VISIBLE_P (XFRAME (tip_frame)) 5900 if (FRAME_VISIBLE_P (tip_f)
5940 && EQ (frame, last_frame) 5901 && EQ (frame, last_frame)
5941 && !NILP (Fequal_including_properties (last_string, string)) 5902 && !NILP (Fequal_including_properties (last_string, string))
5942 && !NILP (Fequal (last_parms, parms))) 5903 && !NILP (Fequal (last_parms, parms)))
5943 { 5904 {
5944 /* Only DX and DY have changed. */ 5905 /* Only DX and DY have changed. */
5945 tip_f = XFRAME (tip_frame); 5906 Lisp_Object timer = Fframe_parameter (tip_frame, Qtooltip_timer);
5946 if (!NILP (tip_timer))
5947 {
5948 Lisp_Object timer = tip_timer;
5949 5907
5950 tip_timer = Qnil; 5908 if (!NILP (timer))
5951 call1 (Qcancel_timer, timer); 5909 call1 (Qcancel_timer, timer);
5952 }
5953 5910
5954 block_input (); 5911 block_input ();
5955 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f), 5912 compute_tip_xy (tip_f, parms, dx, dy, FRAME_PIXEL_WIDTH (tip_f),
@@ -6009,17 +5966,22 @@ Text larger than the specified size is clipped. */)
6009 } 5966 }
6010 } 5967 }
6011 5968
6012 x_hide_tip (delete); 5969 x_hide_tip (tip_f, delete);
6013 } 5970 }
6014 else 5971 else
6015 x_hide_tip (true); 5972 x_hide_tip (tip_f, true);
6016 } 5973 }
6017 else 5974 else
6018 x_hide_tip (true); 5975 x_hide_tip (tip_f, true);
6019 5976
6020 ASET (last_show_tip_args, 0, string); 5977 /* Update tooltip parameters. */
6021 ASET (last_show_tip_args, 1, frame); 5978 {
6022 ASET (last_show_tip_args, 2, parms); 5979 AUTO_FRAME_ARG (arg, Qtooltip_parameters, parameters);
5980 ASET (parameters, 0, string);
5981 ASET (parameters, 1, frame);
5982 ASET (parameters, 2, parms);
5983 Fmodify_frame_parameters (frame, arg);
5984 }
6023 5985
6024 if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame))) 5986 if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
6025 { 5987 {
@@ -6035,9 +5997,6 @@ Text larger than the specified size is clipped. */)
6035 if (NILP (Fassq (Qbackground_color, parms))) 5997 if (NILP (Fassq (Qbackground_color, parms)))
6036 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")), 5998 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
6037 parms); 5999 parms);
6038
6039 /* Create a frame for the tooltip, and record it in the global
6040 variable tip_frame. */
6041 if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms))) 6000 if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
6042 /* Creating the tip frame failed. */ 6001 /* Creating the tip frame failed. */
6043 return unbind_to (count, Qnil); 6002 return unbind_to (count, Qnil);
@@ -6115,20 +6074,69 @@ Text larger than the specified size is clipped. */)
6115 windows_or_buffers_changed = old_windows_or_buffers_changed; 6074 windows_or_buffers_changed = old_windows_or_buffers_changed;
6116 6075
6117 start_timer: 6076 start_timer:
6118 /* Let the tip disappear after timeout seconds. */ 6077 {
6119 tip_timer = call3 (intern ("run-at-time"), timeout, Qnil, 6078 /* Let the tip disappear after timeout seconds. */
6120 intern ("x-hide-tip")); 6079 AUTO_FRAME_ARG (arg, Qtooltip_timer,
6121 6080 call3 (intern ("run-at-time"), timeout,
6081 Qnil, intern ("x-hide-tip")));
6082 Fmodify_frame_parameters (tip_frame, arg);
6083 }
6122 return unbind_to (count, Qnil); 6084 return unbind_to (count, Qnil);
6123} 6085}
6124 6086
6125 6087DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 1, 0,
6126DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
6127 doc: /* Hide the current tooltip window, if there is any. 6088 doc: /* Hide the current tooltip window, if there is any.
6089Optional FRAME is the frame to hide tooltip on.
6128Value is t if tooltip was open, nil otherwise. */) 6090Value is t if tooltip was open, nil otherwise. */)
6129 (void) 6091 (Lisp_Object frame)
6130{ 6092{
6131 return x_hide_tip (!tooltip_reuse_hidden_frame); 6093 Lisp_Object obj = Qnil;
6094
6095#ifdef USE_GTK
6096 if (x_gtk_use_system_tooltips)
6097 {
6098 if (NILP (frame))
6099 {
6100 Lisp_Object tail, frame;
6101
6102 FOR_EACH_FRAME (tail, frame)
6103 if (FRAME_X_P (XFRAME (frame)))
6104 if (xg_hide_tooltip (XFRAME (frame)))
6105 obj = Qt;
6106 }
6107 else
6108 {
6109 CHECK_FRAME (frame);
6110 if (FRAME_X_P (XFRAME (frame)))
6111 if (xg_hide_tooltip (XFRAME (frame)))
6112 obj = Qt;
6113 }
6114 return obj;
6115 }
6116#endif /* USE_GTK */
6117
6118 if (NILP (frame))
6119 {
6120 struct x_display_info *dpyinfo;
6121
6122 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
6123 if (dpyinfo->x_tooltip_frame)
6124 if (!NILP (x_hide_tip (dpyinfo->x_tooltip_frame,
6125 !tooltip_reuse_hidden_frame)))
6126 obj = Qt;
6127 }
6128 else
6129 {
6130 struct frame *f;
6131
6132 CHECK_FRAME (frame);
6133 f = XFRAME (frame);
6134 if (FRAME_DISPLAY_INFO (f)
6135 && FRAME_DISPLAY_INFO (f)->x_tooltip_frame)
6136 obj = x_hide_tip (FRAME_DISPLAY_INFO (f)->x_tooltip_frame,
6137 !tooltip_reuse_hidden_frame);
6138 }
6139 return obj;
6132} 6140}
6133 6141
6134 6142
@@ -6997,13 +7005,6 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
6997 7005
6998 defsubr (&Sx_show_tip); 7006 defsubr (&Sx_show_tip);
6999 defsubr (&Sx_hide_tip); 7007 defsubr (&Sx_hide_tip);
7000 tip_timer = Qnil;
7001 staticpro (&tip_timer);
7002 tip_frame = Qnil;
7003 staticpro (&tip_frame);
7004
7005 last_show_tip_args = Qnil;
7006 staticpro (&last_show_tip_args);
7007 7008
7008 defsubr (&Sx_uses_old_gtk_dialog); 7009 defsubr (&Sx_uses_old_gtk_dialog);
7009#if defined (USE_MOTIF) || defined (USE_GTK) 7010#if defined (USE_MOTIF) || defined (USE_GTK)
diff --git a/src/xterm.c b/src/xterm.c
index cd1d712f39a..ada1160ec90 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -987,8 +987,7 @@ static void
987x_update_begin (struct frame *f) 987x_update_begin (struct frame *f)
988{ 988{
989#ifdef USE_CAIRO 989#ifdef USE_CAIRO
990 if (! NILP (tip_frame) && XFRAME (tip_frame) == f 990 if (FRAME_TOOLTIP_P (f) && ! FRAME_VISIBLE_P (f))
991 && ! FRAME_VISIBLE_P (f))
992 return; 991 return;
993 992
994 if (! FRAME_CR_SURFACE (f)) 993 if (! FRAME_CR_SURFACE (f))
@@ -7839,11 +7838,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
7839 7838
7840 case UnmapNotify: 7839 case UnmapNotify:
7841 /* Redo the mouse-highlight after the tooltip has gone. */ 7840 /* Redo the mouse-highlight after the tooltip has gone. */
7842 if (event->xunmap.window == tip_window) 7841 if (dpyinfo->x_tooltip_frame
7843 { 7842 && FRAME_X_WINDOW (dpyinfo->x_tooltip_frame) == event->xunmap.window)
7844 tip_window = 0; 7843 x_redo_mouse_highlight (dpyinfo);
7845 x_redo_mouse_highlight (dpyinfo);
7846 }
7847 7844
7848 f = x_top_window_to_frame (dpyinfo, event->xunmap.window); 7845 f = x_top_window_to_frame (dpyinfo, event->xunmap.window);
7849 if (f) /* F may no longer exist if 7846 if (f) /* F may no longer exist if
@@ -8433,7 +8430,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8433 8430
8434#ifdef USE_X_TOOLKIT 8431#ifdef USE_X_TOOLKIT
8435 /* Tip frames are pure X window, set size for them. */ 8432 /* Tip frames are pure X window, set size for them. */
8436 if (! NILP (tip_frame) && XFRAME (tip_frame) == f) 8433 if (FRAME_TOOLTIP_P (f))
8437 { 8434 {
8438 if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height 8435 if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
8439 || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width) 8436 || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
@@ -9614,7 +9611,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
9614 /* Don't change the size of a tip frame; there's no point in 9611 /* Don't change the size of a tip frame; there's no point in
9615 doing it because it's done in Fx_show_tip, and it leads to 9612 doing it because it's done in Fx_show_tip, and it leads to
9616 problems because the tip frame has no widget. */ 9613 problems because the tip frame has no widget. */
9617 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 9614 if (!FRAME_TOOLTIP_P (f))
9618 { 9615 {
9619 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 9616 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
9620 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 9617 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
@@ -10689,7 +10686,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
10689 /* The following breaks our calculations. If it's really needed, 10686 /* The following breaks our calculations. If it's really needed,
10690 think of something else. */ 10687 think of something else. */
10691#if false 10688#if false
10692 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 10689 if (!FRAME_TOOLTIP_P (f))
10693 { 10690 {
10694 int text_width, text_height; 10691 int text_width, text_height;
10695 10692
@@ -11340,6 +11337,8 @@ x_free_frame_resources (struct frame *f)
11340 dpyinfo->x_focus_event_frame = 0; 11337 dpyinfo->x_focus_event_frame = 0;
11341 if (f == dpyinfo->x_highlight_frame) 11338 if (f == dpyinfo->x_highlight_frame)
11342 dpyinfo->x_highlight_frame = 0; 11339 dpyinfo->x_highlight_frame = 0;
11340 if (f == dpyinfo->x_tooltip_frame)
11341 dpyinfo->x_tooltip_frame = 0;
11343 if (f == hlinfo->mouse_face_mouse_frame) 11342 if (f == hlinfo->mouse_face_mouse_frame)
11344 reset_mouse_highlight (hlinfo); 11343 reset_mouse_highlight (hlinfo);
11345 11344
diff --git a/src/xterm.h b/src/xterm.h
index 675a48443dc..1eb3e304f84 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -362,6 +362,9 @@ struct x_display_info
362 /* The frame waiting to be auto-raised in XTread_socket. */ 362 /* The frame waiting to be auto-raised in XTread_socket. */
363 struct frame *x_pending_autoraise_frame; 363 struct frame *x_pending_autoraise_frame;
364 364
365 /* Tooltip frame on this display. */
366 struct frame *x_tooltip_frame;
367
365 /* The frame where the mouse was last time we reported a ButtonPress event. */ 368 /* The frame where the mouse was last time we reported a ButtonPress event. */
366 struct frame *last_mouse_frame; 369 struct frame *last_mouse_frame;
367 370
@@ -575,6 +578,7 @@ struct x_output
575 GtkTooltip *ttip_widget; 578 GtkTooltip *ttip_widget;
576 GtkWidget *ttip_lbl; 579 GtkWidget *ttip_lbl;
577 GtkWindow *ttip_window; 580 GtkWindow *ttip_window;
581 guint ttip_timeout;
578#endif /* USE_GTK_TOOLTIP */ 582#endif /* USE_GTK_TOOLTIP */
579 583
580#endif /* USE_GTK */ 584#endif /* USE_GTK */