aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2018-01-18 10:36:47 +0100
committerMartin Rudalics2018-01-18 10:36:47 +0100
commite462308f03c9c16c47abc82d6f339ca9d18898f9 (patch)
tree49cc7306cb35a007eb43a2fe122be881f5cfa13f /src
parent6e9f20b3ff49adfc05a7f4b49b1b92daa4fb1ca9 (diff)
downloademacs-e462308f03c9c16c47abc82d6f339ca9d18898f9.tar.gz
emacs-e462308f03c9c16c47abc82d6f339ca9d18898f9.zip
Fix some tooltip related problems
Replace 'tooltip' frame parameter with a 'tooltip' member in the frame structure. For GTK+ builds use 'tip_last_frame' to find the frame for which the currently visible tooltip was made. For modeline help-echoing have tooltips show applicable actions only. * lisp/bindings.el (mode-line-default-help-echo): New function as default value of homonymous option. * src/dispextern.h (tip_frame, tip_window): Remove declarations. * src/frame.c (make_frame): Initialize new frame structure member 'tooltip'. (Fframe_list, other_frames): Rewrite with new macro FRAME_TOOLTIP_P. * src/frame.h (struct frame): New member 'tooltip'. (FRAME_TOOLTIP_P): New macro. * src/gtkutil.c (xg_prepare_tooltip, xg_hide_tooltip): Rewrite using boolean return values. * src/nsfns.m (tip_frame): Remove declaration. * src/w32fns.c (w32_display_monitor_attributes_list) (w32_display_monitor_attributes_list_fallback): Rewrite with new macro FRAME_TOOLTIP_P. (tip_last_string, tip_last_frame, tip_last_parms): New Lisp scalars replacing Lisp vector last_show_tip_args. (x_create_tip_frame): Set new frame's 'tooltip' structure member to true. (x_hide_tip): Additionally test tip_frame for liveness. (Fx_show_tip): Handle last_show_tip_args to tip_last_frame, tip_last_string and tip_last_parms conversion. (syms_of_w32fns): staticpro tip_last_frame, tip_last_string and tip_last_parms instead of last_show_tip_args. * src/w32term.c (w32_read_socket, x_new_font): Rewrite with new macro FRAME_TOOLTIP_P. * src/w32term.h (tip_window): Add external declaration. * src/xdisp.c (x_consider_frame_title, prepare_menu_bars) (should_produce_line_number): Rewrite with new macro FRAME_TOOLTIP_P. (note_mode_line_or_margin_highlight): If `mode-line-default-help-echo' specifies a function, call it to produce help echo string. * src/xfns.c (x_make_monitor_attribute_list) (Fx_display_monitor_attributes_list): Rewrite with new macro FRAME_TOOLTIP_P. (tip_last_string, tip_last_frame, tip_last_parms): New Lisp scalars replacing Lisp vector last_show_tip_args. (x_create_tip_frame): Set new frame's 'tooltip' structure member to true. (x_hide_tip): Rewrite with additional tests of frames for liveness and taking into account that for GTK+ tips the reference frame is now stored in tip_last_frame instead of tip_frame. (Fx_show_tip): Handle last_show_tip_args to tip_last_frame, tip_last_string and tip_last_parms conversion. For GTK+ store FRAME argument in tip_last-frame. (syms_of_xfns): staticpro tip_last_frame, tip_last_string and tip_last_parms instead of last_show_tip_args. * src/xterm.c (x_update_begin, handle_one_xevent, x_new_font) (x_set_window_size): Rewrite with new macro FRAME_TOOLTIP_P. * src/xterm.h (tip_window): Add external declaration. * etc/NEWS: Mention new modeline tooltips behavior.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h9
-rw-r--r--src/frame.c59
-rw-r--r--src/frame.h7
-rw-r--r--src/gtkutil.c14
-rw-r--r--src/nsfns.m4
-rw-r--r--src/w32fns.c110
-rw-r--r--src/w32term.c4
-rw-r--r--src/w32term.h2
-rw-r--r--src/xdisp.c29
-rw-r--r--src/xfns.c257
-rw-r--r--src/xterm.c19
-rw-r--r--src/xterm.h2
12 files changed, 295 insertions, 221 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 25bd6b24f22..441361b4083 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3452,15 +3452,6 @@ void gamma_correct (struct frame *, COLORREF *);
3452void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); 3452void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
3453void x_change_tool_bar_height (struct frame *f, int); 3453void x_change_tool_bar_height (struct frame *f, int);
3454 3454
3455/* The frame used to display a tooltip.
3456
3457 Note: In a GTK build with non-zero x_gtk_use_system_tooltips, this
3458 variable holds the frame that shows the tooltip, not the frame of
3459 the tooltip itself, so checking whether a frame is a tooltip frame
3460 cannot just compare the frame to what this variable holds. */
3461extern Lisp_Object tip_frame;
3462
3463extern Window tip_window;
3464extern frame_parm_handler x_frame_parm_handlers[]; 3455extern frame_parm_handler x_frame_parm_handlers[];
3465 3456
3466extern void start_hourglass (void); 3457extern void start_hourglass (void);
diff --git a/src/frame.c b/src/frame.c
index 1c6289a6b6c..9b560808128 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -832,6 +832,7 @@ make_frame (bool mini_p)
832 f->no_focus_on_map = false; 832 f->no_focus_on_map = false;
833 f->no_accept_focus = false; 833 f->no_accept_focus = false;
834 f->z_group = z_group_none; 834 f->z_group = z_group_none;
835 f->tooltip = false;
835#if ! defined (USE_GTK) && ! defined (HAVE_NS) 836#if ! defined (USE_GTK) && ! defined (HAVE_NS)
836 f->last_tool_bar_item = -1; 837 f->last_tool_bar_item = -1;
837#endif 838#endif
@@ -1467,20 +1468,21 @@ DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
1467 1468
1468DEFUN ("frame-list", Fframe_list, Sframe_list, 1469DEFUN ("frame-list", Fframe_list, Sframe_list,
1469 0, 0, 0, 1470 0, 0, 0,
1470 doc: /* Return a list of all live frames. */) 1471 doc: /* Return a list of all live frames.
1472The return value does not include any tooltip frame. */)
1471 (void) 1473 (void)
1472{ 1474{
1473 Lisp_Object frames;
1474 frames = Fcopy_sequence (Vframe_list);
1475#ifdef HAVE_WINDOW_SYSTEM 1475#ifdef HAVE_WINDOW_SYSTEM
1476 if (FRAMEP (tip_frame) 1476 Lisp_Object list = Qnil, tail, frame;
1477#ifdef USE_GTK 1477
1478 && !NILP (Fframe_parameter (tip_frame, Qtooltip)) 1478 FOR_EACH_FRAME (tail, frame)
1479#endif 1479 if (!FRAME_TOOLTIP_P (XFRAME (frame)))
1480 ) 1480 list = Fcons (frame, list);
1481 frames = Fdelq (tip_frame, frames); 1481 /* Reverse list for consistency with the !HAVE_WINDOW_SYSTEM case. */
1482#endif 1482 return Fnreverse (list);
1483 return frames; 1483#else /* !HAVE_WINDOW_SYSTEM */
1484 return Fcopy_sequence (Vframe_list);
1485#endif /* HAVE_WINDOW_SYSTEM */
1484} 1486}
1485 1487
1486DEFUN ("frame-parent", Fframe_parent, Sframe_parent, 1488DEFUN ("frame-parent", Fframe_parent, Sframe_parent,
@@ -1711,7 +1713,8 @@ DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
1711 * other_frames: 1713 * other_frames:
1712 * 1714 *
1713 * Return true if there exists at least one visible or iconified frame 1715 * Return true if there exists at least one visible or iconified frame
1714 * but F. Return false otherwise. 1716 * but F. Tooltip frames do not qualify as candidates. Return false
1717 * if no such frame exists.
1715 * 1718 *
1716 * INVISIBLE true means we are called from make_frame_invisible where 1719 * INVISIBLE true means we are called from make_frame_invisible where
1717 * such a frame must be visible or iconified. INVISIBLE nil means we 1720 * such a frame must be visible or iconified. INVISIBLE nil means we
@@ -1725,7 +1728,6 @@ static bool
1725other_frames (struct frame *f, bool invisible, bool force) 1728other_frames (struct frame *f, bool invisible, bool force)
1726{ 1729{
1727 Lisp_Object frames, frame, frame1; 1730 Lisp_Object frames, frame, frame1;
1728 struct frame *f1;
1729 Lisp_Object minibuffer_window = FRAME_MINIBUF_WINDOW (f); 1731 Lisp_Object minibuffer_window = FRAME_MINIBUF_WINDOW (f);
1730 1732
1731 XSETFRAME (frame, f); 1733 XSETFRAME (frame, f);
@@ -1735,7 +1737,8 @@ other_frames (struct frame *f, bool invisible, bool force)
1735 1737
1736 FOR_EACH_FRAME (frames, frame1) 1738 FOR_EACH_FRAME (frames, frame1)
1737 { 1739 {
1738 f1 = XFRAME (frame1); 1740 struct frame *f1 = XFRAME (frame1);
1741
1739 if (f != f1) 1742 if (f != f1)
1740 { 1743 {
1741 /* Verify that we can still talk to the frame's X window, and 1744 /* Verify that we can still talk to the frame's X window, and
@@ -1744,7 +1747,7 @@ other_frames (struct frame *f, bool invisible, bool force)
1744 if (FRAME_WINDOW_P (f1)) 1747 if (FRAME_WINDOW_P (f1))
1745 x_sync (f1); 1748 x_sync (f1);
1746#endif 1749#endif
1747 if (NILP (Fframe_parameter (frame1, Qtooltip)) 1750 if (!FRAME_TOOLTIP_P (f1)
1748 /* Tooltips and child frames count neither for 1751 /* Tooltips and child frames count neither for
1749 invisibility nor for deletions. */ 1752 invisibility nor for deletions. */
1750 && !FRAME_PARENT_FRAME (f1) 1753 && !FRAME_PARENT_FRAME (f1)
@@ -1877,7 +1880,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1877 } 1880 }
1878 } 1881 }
1879 1882
1880 is_tooltip_frame = !NILP (Fframe_parameter (frame, Qtooltip)); 1883 is_tooltip_frame = FRAME_TOOLTIP_P (f);
1881 1884
1882 /* Run `delete-frame-functions' unless FORCE is `noelisp' or 1885 /* Run `delete-frame-functions' unless FORCE is `noelisp' or
1883 frame is a tooltip. FORCE is set to `noelisp' when handling 1886 frame is a tooltip. FORCE is set to `noelisp' when handling
@@ -1925,27 +1928,31 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
1925 Do not call next_frame here because it may loop forever. 1928 Do not call next_frame here because it may loop forever.
1926 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */ 1929 See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
1927 FOR_EACH_FRAME (tail, frame1) 1930 FOR_EACH_FRAME (tail, frame1)
1928 if (!EQ (frame, frame1) 1931 {
1929 && NILP (Fframe_parameter (frame1, Qtooltip)) 1932 struct frame *f1 = XFRAME (frame1);
1930 && (FRAME_TERMINAL (XFRAME (frame)) 1933
1931 == FRAME_TERMINAL (XFRAME (frame1))) 1934 if (!EQ (frame, frame1)
1932 && FRAME_VISIBLE_P (XFRAME (frame1))) 1935 && !FRAME_TOOLTIP_P (f1)
1933 break; 1936 && FRAME_TERMINAL (f) == FRAME_TERMINAL (f1)
1937 && FRAME_VISIBLE_P (f1))
1938 break;
1939 }
1934 1940
1935 /* If there is none, find *some* other frame. */ 1941 /* If there is none, find *some* other frame. */
1936 if (NILP (frame1) || EQ (frame1, frame)) 1942 if (NILP (frame1) || EQ (frame1, frame))
1937 { 1943 {
1938 FOR_EACH_FRAME (tail, frame1) 1944 FOR_EACH_FRAME (tail, frame1)
1939 { 1945 {
1946 struct frame *f1 = XFRAME (frame1);
1947
1940 if (!EQ (frame, frame1) 1948 if (!EQ (frame, frame1)
1941 && FRAME_LIVE_P (XFRAME (frame1)) 1949 && FRAME_LIVE_P (f1)
1942 && NILP (Fframe_parameter (frame1, Qtooltip))) 1950 && !FRAME_TOOLTIP_P (f1))
1943 { 1951 {
1944 /* Do not change a text terminal's top-frame. */
1945 struct frame *f1 = XFRAME (frame1);
1946 if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1)) 1952 if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1))
1947 { 1953 {
1948 Lisp_Object top_frame = FRAME_TTY (f1)->top_frame; 1954 Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
1955
1949 if (!EQ (top_frame, frame)) 1956 if (!EQ (top_frame, frame))
1950 frame1 = top_frame; 1957 frame1 = top_frame;
1951 } 1958 }
diff --git a/src/frame.h b/src/frame.h
index 402d6c0a7b2..2c9c4143886 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -342,6 +342,9 @@ struct frame
342 ENUM_BF (output_method) output_method : 3; 342 ENUM_BF (output_method) output_method : 3;
343 343
344#ifdef HAVE_WINDOW_SYSTEM 344#ifdef HAVE_WINDOW_SYSTEM
345 /* True if this frame is a tooltip frame. */
346 bool_bf tooltip : 1;
347
345 /* See FULLSCREEN_ enum on top. */ 348 /* See FULLSCREEN_ enum on top. */
346 ENUM_BF (fullscreen_type) want_fullscreen : 4; 349 ENUM_BF (fullscreen_type) want_fullscreen : 4;
347 350
@@ -351,9 +354,7 @@ struct frame
351 354
352 /* Nonzero if we should actually display horizontal scroll bars on this frame. */ 355 /* Nonzero if we should actually display horizontal scroll bars on this frame. */
353 bool_bf horizontal_scroll_bars : 1; 356 bool_bf horizontal_scroll_bars : 1;
354#endif /* HAVE_WINDOW_SYSTEM */
355 357
356#if defined (HAVE_WINDOW_SYSTEM)
357 /* True if this is an undecorated frame. */ 358 /* True if this is an undecorated frame. */
358 bool_bf undecorated : 1; 359 bool_bf undecorated : 1;
359 360
@@ -967,6 +968,7 @@ default_pixels_per_inch_y (void)
967#define FRAME_Z_GROUP_ABOVE_SUSPENDED(f) \ 968#define FRAME_Z_GROUP_ABOVE_SUSPENDED(f) \
968 ((f)->z_group == z_group_above_suspended) 969 ((f)->z_group == z_group_above_suspended)
969#define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below) 970#define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below)
971#define FRAME_TOOLTIP_P(f) ((f)->tooltip)
970#ifdef NS_IMPL_COCOA 972#ifdef NS_IMPL_COCOA
971#define FRAME_NS_APPEARANCE(f) ((f)->ns_appearance) 973#define FRAME_NS_APPEARANCE(f) ((f)->ns_appearance)
972#define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar) 974#define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar)
@@ -983,6 +985,7 @@ default_pixels_per_inch_y (void)
983#define FRAME_Z_GROUP_NONE(f) ((void) (f), true) 985#define FRAME_Z_GROUP_NONE(f) ((void) (f), true)
984#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false) 986#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false)
985#define FRAME_Z_GROUP_BELOW(f) ((void) (f), false) 987#define FRAME_Z_GROUP_BELOW(f) ((void) (f), false)
988#define FRAME_TOOLTIP_P(f) ((void) f, false)
986#endif /* HAVE_WINDOW_SYSTEM */ 989#endif /* HAVE_WINDOW_SYSTEM */
987 990
988/* Whether horizontal scroll bars are currently enabled for frame F. */ 991/* Whether horizontal scroll bars are currently enabled for frame F. */
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 047417fde84..34c0fcc2650 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -687,6 +687,7 @@ qttip_cb (GtkWidget *widget,
687 g_signal_connect (x->ttip_lbl, "hierarchy-changed", 687 g_signal_connect (x->ttip_lbl, "hierarchy-changed",
688 G_CALLBACK (hierarchy_ch_cb), f); 688 G_CALLBACK (hierarchy_ch_cb), f);
689 } 689 }
690
690 return FALSE; 691 return FALSE;
691} 692}
692 693
@@ -713,7 +714,8 @@ xg_prepare_tooltip (struct frame *f,
713 GtkRequisition req; 714 GtkRequisition req;
714 Lisp_Object encoded_string; 715 Lisp_Object encoded_string;
715 716
716 if (!x->ttip_lbl) return 0; 717 if (!x->ttip_lbl)
718 return FALSE;
717 719
718 block_input (); 720 block_input ();
719 encoded_string = ENCODE_UTF_8 (string); 721 encoded_string = ENCODE_UTF_8 (string);
@@ -745,7 +747,7 @@ xg_prepare_tooltip (struct frame *f,
745 747
746 unblock_input (); 748 unblock_input ();
747 749
748 return 1; 750 return TRUE;
749#endif /* USE_GTK_TOOLTIP */ 751#endif /* USE_GTK_TOOLTIP */
750} 752}
751 753
@@ -768,18 +770,18 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
768#endif 770#endif
769} 771}
770 772
773
771/* Hide tooltip if shown. Do nothing if not shown. 774/* Hide tooltip if shown. Do nothing if not shown.
772 Return true if tip was hidden, false if not (i.e. not using 775 Return true if tip was hidden, false if not (i.e. not using
773 system tooltips). */ 776 system tooltips). */
774
775bool 777bool
776xg_hide_tooltip (struct frame *f) 778xg_hide_tooltip (struct frame *f)
777{ 779{
778 bool ret = 0;
779#ifdef USE_GTK_TOOLTIP 780#ifdef USE_GTK_TOOLTIP
780 if (f->output_data.x->ttip_window) 781 if (f->output_data.x->ttip_window)
781 { 782 {
782 GtkWindow *win = f->output_data.x->ttip_window; 783 GtkWindow *win = f->output_data.x->ttip_window;
784
783 block_input (); 785 block_input ();
784 gtk_widget_hide (GTK_WIDGET (win)); 786 gtk_widget_hide (GTK_WIDGET (win));
785 787
@@ -792,10 +794,10 @@ xg_hide_tooltip (struct frame *f)
792 } 794 }
793 unblock_input (); 795 unblock_input ();
794 796
795 ret = 1; 797 return TRUE;
796 } 798 }
797#endif 799#endif
798 return ret; 800 return FALSE;
799} 801}
800 802
801 803
diff --git a/src/nsfns.m b/src/nsfns.m
index c8b30246268..0f60bb8107f 100644
--- a/src/nsfns.m
+++ b/src/nsfns.m
@@ -2753,10 +2753,6 @@ If omitted or nil, that stands for the selected frame's display. */)
2753 return make_number (1 << min (dpyinfo->n_planes, 24)); 2753 return make_number (1 << min (dpyinfo->n_planes, 24));
2754} 2754}
2755 2755
2756
2757/* Unused dummy def needed for compatibility. */
2758Lisp_Object tip_frame;
2759
2760/* TODO: move to xdisp or similar */ 2756/* TODO: move to xdisp or similar */
2761static void 2757static void
2762compute_tip_xy (struct frame *f, 2758compute_tip_xy (struct frame *f,
diff --git a/src/w32fns.c b/src/w32fns.c
index 6e0b3adf160..27c765ed920 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6423,7 +6423,7 @@ w32_display_monitor_attributes_list (void)
6423 { 6423 {
6424 struct frame *f = XFRAME (frame); 6424 struct frame *f = XFRAME (frame);
6425 6425
6426 if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) 6426 if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
6427 { 6427 {
6428 HMONITOR monitor = 6428 HMONITOR monitor =
6429 monitor_from_window_fn (FRAME_W32_WINDOW (f), 6429 monitor_from_window_fn (FRAME_W32_WINDOW (f),
@@ -6510,7 +6510,7 @@ w32_display_monitor_attributes_list_fallback (struct w32_display_info *dpyinfo)
6510 { 6510 {
6511 struct frame *f = XFRAME (frame); 6511 struct frame *f = XFRAME (frame);
6512 6512
6513 if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) 6513 if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
6514 frames = Fcons (frame, frames); 6514 frames = Fcons (frame, frames);
6515 } 6515 }
6516 attributes = Fcons (Fcons (Qframes, frames), attributes); 6516 attributes = Fcons (Fcons (Qframes, frames), attributes);
@@ -6916,20 +6916,25 @@ no value of TYPE (always string in the MS Windows case). */)
6916static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, 6916static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
6917 Lisp_Object, int, int, int *, int *); 6917 Lisp_Object, int, int, int *, int *);
6918 6918
6919/* The frame of a currently visible tooltip. */ 6919/* The frame of the currently visible tooltip. */
6920
6921Lisp_Object tip_frame; 6920Lisp_Object tip_frame;
6922 6921
6923/* If non-nil, a timer started that hides the last tooltip when it 6922/* The window-system window corresponding to the frame of the
6924 fires. */ 6923 currently visible tooltip. */
6924Window tip_window;
6925 6925
6926/* A timer that hides or deletes the currently visible tooltip when it
6927 fires. */
6926Lisp_Object tip_timer; 6928Lisp_Object tip_timer;
6927Window tip_window;
6928 6929
6929/* If non-nil, a vector of 3 elements containing the last args 6930/* STRING argument of last `x-show-tip' call. */
6930 with which x-show-tip was called. See there. */ 6931Lisp_Object tip_last_string;
6931 6932
6932Lisp_Object last_show_tip_args; 6933/* FRAME argument of last `x-show-tip' call. */
6934Lisp_Object tip_last_frame;
6935
6936/* PARMS argument of last `x-show-tip' call. */
6937Lisp_Object tip_last_parms;
6933 6938
6934 6939
6935static void 6940static void
@@ -7002,6 +7007,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
7002 7007
7003 FRAME_FONTSET (f) = -1; 7008 FRAME_FONTSET (f) = -1;
7004 fset_icon_name (f, Qnil); 7009 fset_icon_name (f, Qnil);
7010 f->tooltip = true;
7005 7011
7006#ifdef GLYPH_DEBUG 7012#ifdef GLYPH_DEBUG
7007 image_cache_refcount = 7013 image_cache_refcount =
@@ -7261,7 +7267,17 @@ compute_tip_xy (struct frame *f,
7261 *root_x = min_x; 7267 *root_x = min_x;
7262} 7268}
7263 7269
7264/* Hide tooltip. Delete its frame if DELETE is true. */ 7270/**
7271 * x_hide_tip:
7272 *
7273 * Hide currently visible tooltip and cancel its timer.
7274 *
7275 * This will try to make tooltip_frame invisible (if DELETE is false)
7276 * or delete tooltip_frame (if DELETE is true).
7277 *
7278 * Return Qt if the tooltip was either deleted or made invisible, Qnil
7279 * otherwise.
7280 */
7265static Lisp_Object 7281static Lisp_Object
7266x_hide_tip (bool delete) 7282x_hide_tip (bool delete)
7267{ 7283{
@@ -7286,15 +7302,20 @@ x_hide_tip (bool delete)
7286 7302
7287 if (FRAMEP (tip_frame)) 7303 if (FRAMEP (tip_frame))
7288 { 7304 {
7289 if (delete) 7305 if (FRAME_LIVE_P (XFRAME (tip_frame)))
7290 { 7306 {
7291 delete_frame (tip_frame, Qnil); 7307 if (delete)
7292 tip_frame = Qnil; 7308 {
7309 delete_frame (tip_frame, Qnil);
7310 tip_frame = Qnil;
7311 }
7312 else
7313 x_make_frame_invisible (XFRAME (tip_frame));
7314
7315 was_open = Qt;
7293 } 7316 }
7294 else 7317 else
7295 x_make_frame_invisible (XFRAME (tip_frame)); 7318 tip_frame = Qnil;
7296
7297 was_open = Qt;
7298 } 7319 }
7299 else 7320 else
7300 tip_frame = Qnil; 7321 tip_frame = Qnil;
@@ -7334,7 +7355,8 @@ with offset DY added (default is -10).
7334 7355
7335A tooltip's maximum size is specified by `x-max-tooltip-size'. 7356A tooltip's maximum size is specified by `x-max-tooltip-size'.
7336Text larger than the specified size is clipped. */) 7357Text larger than the specified size is clipped. */)
7337 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy) 7358 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
7359 Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
7338{ 7360{
7339 struct frame *tip_f; 7361 struct frame *tip_f;
7340 struct window *w; 7362 struct window *w;
@@ -7345,8 +7367,7 @@ Text larger than the specified size is clipped. */)
7345 int old_windows_or_buffers_changed = windows_or_buffers_changed; 7367 int old_windows_or_buffers_changed = windows_or_buffers_changed;
7346 ptrdiff_t count = SPECPDL_INDEX (); 7368 ptrdiff_t count = SPECPDL_INDEX ();
7347 ptrdiff_t count_1; 7369 ptrdiff_t count_1;
7348 Lisp_Object window, size; 7370 Lisp_Object window, size, tip_buf;
7349 Lisp_Object tip_buf;
7350 AUTO_STRING (tip, " *tip*"); 7371 AUTO_STRING (tip, " *tip*");
7351 7372
7352 specbind (Qinhibit_redisplay, Qt); 7373 specbind (Qinhibit_redisplay, Qt);
@@ -7368,19 +7389,12 @@ Text larger than the specified size is clipped. */)
7368 else 7389 else
7369 CHECK_NUMBER (dy); 7390 CHECK_NUMBER (dy);
7370 7391
7371 if (NILP (last_show_tip_args))
7372 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
7373
7374 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame))) 7392 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
7375 { 7393 {
7376 Lisp_Object last_string = AREF (last_show_tip_args, 0);
7377 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
7378 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
7379
7380 if (FRAME_VISIBLE_P (XFRAME (tip_frame)) 7394 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
7381 && EQ (frame, last_frame) 7395 && EQ (frame, tip_last_frame)
7382 && !NILP (Fequal_including_properties (last_string, string)) 7396 && !NILP (Fequal_including_properties (string, tip_last_string))
7383 && !NILP (Fequal (last_parms, parms))) 7397 && !NILP (Fequal (parms, tip_last_parms)))
7384 { 7398 {
7385 /* Only DX and DY have changed. */ 7399 /* Only DX and DY have changed. */
7386 tip_f = XFRAME (tip_frame); 7400 tip_f = XFRAME (tip_frame);
@@ -7414,14 +7428,14 @@ Text larger than the specified size is clipped. */)
7414 7428
7415 goto start_timer; 7429 goto start_timer;
7416 } 7430 }
7417 else if (tooltip_reuse_hidden_frame && EQ (frame, last_frame)) 7431 else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
7418 { 7432 {
7419 bool delete = false; 7433 bool delete = false;
7420 Lisp_Object tail, elt, parm, last; 7434 Lisp_Object tail, elt, parm, last;
7421 7435
7422 /* Check if every parameter in PARMS has the same value in 7436 /* Check if every parameter in PARMS has the same value in
7423 last_parms. This may destruct last_parms which, however, 7437 tip_last_parms. This may destruct tip_last_parms
7424 will be recreated below. */ 7438 which, however, will be recreated below. */
7425 for (tail = parms; CONSP (tail); tail = XCDR (tail)) 7439 for (tail = parms; CONSP (tail); tail = XCDR (tail))
7426 { 7440 {
7427 elt = XCAR (tail); 7441 elt = XCAR (tail);
@@ -7431,7 +7445,7 @@ Text larger than the specified size is clipped. */)
7431 if (!EQ (parm, Qleft) && !EQ (parm, Qtop) 7445 if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
7432 && !EQ (parm, Qright) && !EQ (parm, Qbottom)) 7446 && !EQ (parm, Qright) && !EQ (parm, Qbottom))
7433 { 7447 {
7434 last = Fassq (parm, last_parms); 7448 last = Fassq (parm, tip_last_parms);
7435 if (NILP (Fequal (Fcdr (elt), Fcdr (last)))) 7449 if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
7436 { 7450 {
7437 /* We lost, delete the old tooltip. */ 7451 /* We lost, delete the old tooltip. */
@@ -7439,15 +7453,17 @@ Text larger than the specified size is clipped. */)
7439 break; 7453 break;
7440 } 7454 }
7441 else 7455 else
7442 last_parms = call2 (Qassq_delete_all, parm, last_parms); 7456 tip_last_parms =
7457 call2 (Qassq_delete_all, parm, tip_last_parms);
7443 } 7458 }
7444 else 7459 else
7445 last_parms = call2 (Qassq_delete_all, parm, last_parms); 7460 tip_last_parms =
7461 call2 (Qassq_delete_all, parm, tip_last_parms);
7446 } 7462 }
7447 7463
7448 /* Now check if there's a parameter left in last_parms with a 7464 /* Now check if there's a parameter left in tip_last_parms with a
7449 non-nil value. */ 7465 non-nil value. */
7450 for (tail = last_parms; CONSP (tail); tail = XCDR (tail)) 7466 for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
7451 { 7467 {
7452 elt = XCAR (tail); 7468 elt = XCAR (tail);
7453 parm = Fcar (elt); 7469 parm = Fcar (elt);
@@ -7468,9 +7484,9 @@ Text larger than the specified size is clipped. */)
7468 else 7484 else
7469 x_hide_tip (true); 7485 x_hide_tip (true);
7470 7486
7471 ASET (last_show_tip_args, 0, string); 7487 tip_last_frame = frame;
7472 ASET (last_show_tip_args, 1, frame); 7488 tip_last_string = string;
7473 ASET (last_show_tip_args, 2, parms); 7489 tip_last_parms = parms;
7474 7490
7475 /* Block input until the tip has been fully drawn, to avoid crashes 7491 /* Block input until the tip has been fully drawn, to avoid crashes
7476 when drawing tips in menus. */ 7492 when drawing tips in menus. */
@@ -7486,7 +7502,8 @@ Text larger than the specified size is clipped. */)
7486 if (NILP (Fassq (Qborder_width, parms))) 7502 if (NILP (Fassq (Qborder_width, parms)))
7487 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms); 7503 parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
7488 if (NILP (Fassq (Qborder_color, parms))) 7504 if (NILP (Fassq (Qborder_color, parms)))
7489 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms); 7505 parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")),
7506 parms);
7490 if (NILP (Fassq (Qbackground_color, parms))) 7507 if (NILP (Fassq (Qbackground_color, parms)))
7491 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")), 7508 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
7492 parms); 7509 parms);
@@ -10695,9 +10712,12 @@ tip frame. */);
10695 staticpro (&tip_timer); 10712 staticpro (&tip_timer);
10696 tip_frame = Qnil; 10713 tip_frame = Qnil;
10697 staticpro (&tip_frame); 10714 staticpro (&tip_frame);
10698 10715 tip_last_frame = Qnil;
10699 last_show_tip_args = Qnil; 10716 staticpro (&tip_last_frame);
10700 staticpro (&last_show_tip_args); 10717 tip_last_string = Qnil;
10718 staticpro (&tip_last_string);
10719 tip_last_parms = Qnil;
10720 staticpro (&tip_last_parms);
10701 10721
10702 defsubr (&Sx_file_dialog); 10722 defsubr (&Sx_file_dialog);
10703#ifdef WINDOWSNT 10723#ifdef WINDOWSNT
diff --git a/src/w32term.c b/src/w32term.c
index db4ccf58138..137c798c463 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -5569,7 +5569,7 @@ w32_read_socket (struct terminal *terminal,
5569 struct frame *f = XFRAME (frame); 5569 struct frame *f = XFRAME (frame);
5570 /* The tooltip has been drawn already. Avoid the 5570 /* The tooltip has been drawn already. Avoid the
5571 SET_FRAME_GARBAGED below. */ 5571 SET_FRAME_GARBAGED below. */
5572 if (EQ (frame, tip_frame)) 5572 if (FRAME_TOOLTIP_P (f))
5573 continue; 5573 continue;
5574 5574
5575 /* Check "visible" frames and mark each as obscured or not. 5575 /* Check "visible" frames and mark each as obscured or not.
@@ -6046,7 +6046,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
6046 /* Don't change the size of a tip frame; there's no point in 6046 /* Don't change the size of a tip frame; there's no point in
6047 doing it because it's done in Fx_show_tip, and it leads to 6047 doing it because it's done in Fx_show_tip, and it leads to
6048 problems because the tip frame has no widget. */ 6048 problems because the tip frame has no widget. */
6049 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 6049 if (!FRAME_TOOLTIP_P (f))
6050 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 6050 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
6051 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 6051 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
6052 false, Qfont); 6052 false, Qfont);
diff --git a/src/w32term.h b/src/w32term.h
index e500b730ead..c69bebeebdd 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -817,6 +817,8 @@ extern struct window *w32_system_caret_window;
817extern int w32_system_caret_hdr_height; 817extern int w32_system_caret_hdr_height;
818extern int w32_system_caret_mode_height; 818extern int w32_system_caret_mode_height;
819 819
820extern Window tip_window;
821
820#ifdef _MSC_VER 822#ifdef _MSC_VER
821#ifndef EnumSystemLocales 823#ifndef EnumSystemLocales
822/* MSVC headers define these only for _WIN32_WINNT >= 0x0500. */ 824/* MSVC headers define these only for _WIN32_WINNT >= 0x0500. */
diff --git a/src/xdisp.c b/src/xdisp.c
index 59fa00e1af4..d2bb47fdabd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11866,7 +11866,7 @@ x_consider_frame_title (Lisp_Object frame)
11866 if ((FRAME_WINDOW_P (f) 11866 if ((FRAME_WINDOW_P (f)
11867 || FRAME_MINIBUF_ONLY_P (f) 11867 || FRAME_MINIBUF_ONLY_P (f)
11868 || f->explicit_name) 11868 || f->explicit_name)
11869 && NILP (Fframe_parameter (frame, Qtooltip))) 11869 && !FRAME_TOOLTIP_P (f))
11870 { 11870 {
11871 /* Do we have more than one visible frame on this X display? */ 11871 /* Do we have more than one visible frame on this X display? */
11872 Lisp_Object tail, other_frame, fmt; 11872 Lisp_Object tail, other_frame, fmt;
@@ -11883,8 +11883,8 @@ x_consider_frame_title (Lisp_Object frame)
11883 if (tf != f 11883 if (tf != f
11884 && FRAME_KBOARD (tf) == FRAME_KBOARD (f) 11884 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11885 && !FRAME_MINIBUF_ONLY_P (tf) 11885 && !FRAME_MINIBUF_ONLY_P (tf)
11886 && !EQ (other_frame, tip_frame)
11887 && !FRAME_PARENT_FRAME (tf) 11886 && !FRAME_PARENT_FRAME (tf)
11887 && !FRAME_TOOLTIP_P (tf)
11888 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf))) 11888 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11889 break; 11889 break;
11890 } 11890 }
@@ -11953,13 +11953,6 @@ prepare_menu_bars (void)
11953{ 11953{
11954 bool all_windows = windows_or_buffers_changed || update_mode_lines; 11954 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11955 bool some_windows = REDISPLAY_SOME_P (); 11955 bool some_windows = REDISPLAY_SOME_P ();
11956 Lisp_Object tooltip_frame;
11957
11958#ifdef HAVE_WINDOW_SYSTEM
11959 tooltip_frame = tip_frame;
11960#else
11961 tooltip_frame = Qnil;
11962#endif
11963 11956
11964 if (FUNCTIONP (Vpre_redisplay_function)) 11957 if (FUNCTIONP (Vpre_redisplay_function))
11965 { 11958 {
@@ -12000,7 +11993,7 @@ prepare_menu_bars (void)
12000 && !XBUFFER (w->contents)->text->redisplay) 11993 && !XBUFFER (w->contents)->text->redisplay)
12001 continue; 11994 continue;
12002 11995
12003 if (!EQ (frame, tooltip_frame) 11996 if (!FRAME_TOOLTIP_P (f)
12004 && !FRAME_PARENT_FRAME (f) 11997 && !FRAME_PARENT_FRAME (f)
12005 && (FRAME_ICONIFIED_P (f) 11998 && (FRAME_ICONIFIED_P (f)
12006 || FRAME_VISIBLE_P (f) == 1 11999 || FRAME_VISIBLE_P (f) == 1
@@ -12038,7 +12031,7 @@ prepare_menu_bars (void)
12038 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); 12031 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12039 12032
12040 /* Ignore tooltip frame. */ 12033 /* Ignore tooltip frame. */
12041 if (EQ (frame, tooltip_frame)) 12034 if (FRAME_TOOLTIP_P (f))
12042 continue; 12035 continue;
12043 12036
12044 if (some_windows 12037 if (some_windows
@@ -21160,13 +21153,7 @@ should_produce_line_number (struct it *it)
21160 21153
21161#ifdef HAVE_WINDOW_SYSTEM 21154#ifdef HAVE_WINDOW_SYSTEM
21162 /* Don't display line number in tooltip frames. */ 21155 /* Don't display line number in tooltip frames. */
21163 if (FRAMEP (tip_frame) && EQ (WINDOW_FRAME (it->w), tip_frame) 21156 if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
21164#ifdef USE_GTK
21165 /* GTK builds store in tip_frame the frame that shows the tip,
21166 so we need an additional test. */
21167 && !NILP (Fframe_parameter (tip_frame, Qtooltip))
21168#endif
21169 )
21170 return false; 21157 return false;
21171#endif 21158#endif
21172 21159
@@ -30841,9 +30828,11 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30841 = buffer_local_value (Qmode_line_default_help_echo, 30828 = buffer_local_value (Qmode_line_default_help_echo,
30842 w->contents); 30829 w->contents);
30843 30830
30844 if (STRINGP (default_help)) 30831 if (FUNCTIONP (default_help) || STRINGP (default_help))
30845 { 30832 {
30846 help_echo_string = default_help; 30833 help_echo_string = (FUNCTIONP (default_help)
30834 ? safe_call1 (default_help, window)
30835 : default_help);
30847 XSETWINDOW (help_echo_window, w); 30836 XSETWINDOW (help_echo_window, w);
30848 help_echo_object = Qnil; 30837 help_echo_object = Qnil;
30849 help_echo_pos = -1; 30838 help_echo_pos = -1;
diff --git a/src/xfns.c b/src/xfns.c
index 12b7d83c383..43c55cca643 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -4612,8 +4612,9 @@ x_make_monitor_attribute_list (struct MonitorInfo *monitors,
4612 { 4612 {
4613 struct frame *f = XFRAME (frame); 4613 struct frame *f = XFRAME (frame);
4614 4614
4615 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo 4615 if (FRAME_X_P (f)
4616 && !EQ (frame, tip_frame)) 4616 && FRAME_DISPLAY_INFO (f) == dpyinfo
4617 && !FRAME_TOOLTIP_P (f))
4617 { 4618 {
4618 int i = x_get_monitor_for_frame (f, monitors, n_monitors); 4619 int i = x_get_monitor_for_frame (f, monitors, n_monitors);
4619 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i))); 4620 ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
@@ -4914,12 +4915,9 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
4914 { 4915 {
4915 struct frame *f = XFRAME (frame); 4916 struct frame *f = XFRAME (frame);
4916 4917
4917 if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo 4918 if (FRAME_X_P (f)
4918 && !(EQ (frame, tip_frame) 4919 && FRAME_DISPLAY_INFO (f) == dpyinfo
4919#ifdef USE_GTK 4920 && !FRAME_TOOLTIP_P (f))
4920 && !NILP (Fframe_parameter (tip_frame, Qtooltip))
4921#endif
4922 ))
4923 { 4921 {
4924 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f)); 4922 GdkWindow *gwin = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
4925 4923
@@ -6052,22 +6050,27 @@ Otherwise, the return value is a vector with the following fields:
6052 ***********************************************************************/ 6050 ***********************************************************************/
6053 6051
6054static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, 6052static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
6055 Lisp_Object, int, int, int *, int *); 6053 Lisp_Object, int, int, int *, int *);
6056
6057/* The frame of a currently visible tooltip. */
6058 6054
6055/* The frame of the currently visible tooltip. */
6059Lisp_Object tip_frame; 6056Lisp_Object tip_frame;
6060 6057
6061/* If non-nil, a timer started that hides the last tooltip when it 6058/* The window-system window corresponding to the frame of the
6059 currently visible tooltip. */
6060Window tip_window;
6061
6062/* A timer that hides or deletes the currently visible tooltip when it
6062 fires. */ 6063 fires. */
6064Lisp_Object tip_timer;
6063 6065
6064static Lisp_Object tip_timer; 6066/* STRING argument of last `x-show-tip' call. */
6065Window tip_window; 6067Lisp_Object tip_last_string;
6066 6068
6067/* If non-nil, a vector of 3 elements containing the last args 6069/* FRAME argument of last `x-show-tip' call. */
6068 with which x-show-tip was called. See there. */ 6070Lisp_Object tip_last_frame;
6069 6071
6070static Lisp_Object last_show_tip_args; 6072/* PARMS argument of last `x-show-tip' call. */
6073Lisp_Object tip_last_parms;
6071 6074
6072 6075
6073static void 6076static void
@@ -6141,6 +6144,7 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
6141 f->output_data.x->white_relief.pixel = -1; 6144 f->output_data.x->white_relief.pixel = -1;
6142 f->output_data.x->black_relief.pixel = -1; 6145 f->output_data.x->black_relief.pixel = -1;
6143 6146
6147 f->tooltip = true;
6144 fset_icon_name (f, Qnil); 6148 fset_icon_name (f, Qnil);
6145 FRAME_DISPLAY_INFO (f) = dpyinfo; 6149 FRAME_DISPLAY_INFO (f) = dpyinfo;
6146 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; 6150 f->output_data.x->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
@@ -6405,7 +6409,9 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms)
6405 the display in *ROOT_X, and *ROOT_Y. */ 6409 the display in *ROOT_X, and *ROOT_Y. */
6406 6410
6407static void 6411static void
6408compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object dy, int width, int height, int *root_x, int *root_y) 6412compute_tip_xy (struct frame *f,
6413 Lisp_Object parms, Lisp_Object dx, Lisp_Object dy,
6414 int width, int height, int *root_x, int *root_y)
6409{ 6415{
6410 Lisp_Object left, top, right, bottom; 6416 Lisp_Object left, top, right, bottom;
6411 int win_x, win_y; 6417 int win_x, win_y;
@@ -6502,7 +6508,19 @@ compute_tip_xy (struct frame *f, Lisp_Object parms, Lisp_Object dx, Lisp_Object
6502} 6508}
6503 6509
6504 6510
6505/* Hide tooltip. Delete its frame if DELETE is true. */ 6511/**
6512 * x_hide_tip:
6513 *
6514 * Hide currently visible tooltip and cancel its timer.
6515 *
6516 * If GTK+ system tooltips are used, this will try to hide the tooltip
6517 * referenced by the x_output structure of tooltip_last_frame. For
6518 * Emacs tooltips this will try to make tooltip_frame invisible (if
6519 * DELETE is false) or delete tooltip_frame (if DELETE is true).
6520 *
6521 * Return Qt if the tooltip was either deleted or made invisible, Qnil
6522 * otherwise.
6523 */
6506static Lisp_Object 6524static Lisp_Object
6507x_hide_tip (bool delete) 6525x_hide_tip (bool delete)
6508{ 6526{
@@ -6512,10 +6530,17 @@ x_hide_tip (bool delete)
6512 tip_timer = Qnil; 6530 tip_timer = Qnil;
6513 } 6531 }
6514 6532
6515 6533#ifdef USE_GTK
6516 if (NILP (tip_frame) 6534 /* The GTK+ system tooltip window can be found via the x_output
6517 || (!delete && FRAMEP (tip_frame) 6535 structure of tip_last_frame, if it still exists. */
6518 && !FRAME_VISIBLE_P (XFRAME (tip_frame)))) 6536 if (x_gtk_use_system_tooltips && NILP (tip_last_frame))
6537 return Qnil;
6538 else if (!x_gtk_use_system_tooltips
6539 && (NILP (tip_frame)
6540 || (!delete
6541 && FRAMEP (tip_frame)
6542 && FRAME_LIVE_P (XFRAME (tip_frame))
6543 && !FRAME_VISIBLE_P (XFRAME (tip_frame)))))
6519 return Qnil; 6544 return Qnil;
6520 else 6545 else
6521 { 6546 {
@@ -6526,61 +6551,114 @@ x_hide_tip (bool delete)
6526 specbind (Qinhibit_redisplay, Qt); 6551 specbind (Qinhibit_redisplay, Qt);
6527 specbind (Qinhibit_quit, Qt); 6552 specbind (Qinhibit_quit, Qt);
6528 6553
6529#ifdef USE_GTK 6554 if (x_gtk_use_system_tooltips)
6530 { 6555 {
6531 /* When using system tooltip, tip_frame is the Emacs frame on 6556 /* The GTK+ system tooltip window is stored in the x_output
6532 which the tip is shown. */ 6557 structure of tip_last_frame. */
6533 struct frame *f = XFRAME (tip_frame); 6558 struct frame *f = XFRAME (tip_last_frame);
6534
6535 if (FRAME_LIVE_P (f) && xg_hide_tooltip (f))
6536 {
6537 tip_frame = Qnil;
6538 was_open = Qt;
6539 }
6540 }
6541#endif
6542 6559
6543 if (FRAMEP (tip_frame)) 6560 if (FRAME_LIVE_P (f))
6561 {
6562 if (xg_hide_tooltip (f))
6563 was_open = Qt;
6564 }
6565 else
6566 tip_last_frame = Qnil;
6567 }
6568 else
6544 { 6569 {
6545 if (delete) 6570 if (FRAMEP (tip_frame))
6546 { 6571 {
6547 delete_frame (tip_frame, Qnil); 6572 struct frame *f = XFRAME (tip_frame);
6548 tip_frame = Qnil; 6573
6574 if (FRAME_LIVE_P (f))
6575 {
6576 if (delete)
6577 {
6578 delete_frame (tip_frame, Qnil);
6579 tip_frame = Qnil;
6580 }
6581 else
6582 x_make_frame_invisible (f);
6583
6584 was_open = Qt;
6585 }
6586 else
6587 tip_frame = Qnil;
6549 } 6588 }
6550 else 6589 else
6551 x_make_frame_invisible (XFRAME (tip_frame)); 6590 tip_frame = Qnil;
6591 }
6592
6593 return unbind_to (count, was_open);
6594 }
6595#else /* not USE_GTK */
6596 if (NILP (tip_frame)
6597 || (!delete
6598 && FRAMEP (tip_frame)
6599 && FRAME_LIVE_P (XFRAME (tip_frame))
6600 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
6601 return Qnil;
6602 else
6603 {
6604 ptrdiff_t count;
6605 Lisp_Object was_open = Qnil;
6606
6607 count = SPECPDL_INDEX ();
6608 specbind (Qinhibit_redisplay, Qt);
6609 specbind (Qinhibit_quit, Qt);
6610
6611 if (FRAMEP (tip_frame))
6612 {
6613 struct frame *f = XFRAME (tip_frame);
6552 6614
6553 was_open = Qt; 6615 if (FRAME_LIVE_P (f))
6616 {
6617 if (delete)
6618 {
6619 delete_frame (tip_frame, Qnil);
6620 tip_frame = Qnil;
6621 }
6622 else
6623 x_make_frame_invisible (XFRAME (tip_frame));
6554 6624
6555#ifdef USE_LUCID 6625#ifdef USE_LUCID
6556 /* Bloodcurdling hack alert: The Lucid menu bar widget's 6626 /* Bloodcurdling hack alert: The Lucid menu bar widget's
6557 redisplay procedure is not called when a tip frame over 6627 redisplay procedure is not called when a tip frame over
6558 menu items is unmapped. Redisplay the menu manually... */ 6628 menu items is unmapped. Redisplay the menu manually... */
6559 {
6560 Widget w;
6561 struct frame *f = SELECTED_FRAME ();
6562 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
6563 { 6629 {
6564 w = f->output_data.x->menubar_widget; 6630 Widget w;
6631 struct frame *f = SELECTED_FRAME ();
6565 6632
6566 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen) 6633 if (FRAME_X_P (f) && FRAME_LIVE_P (f))
6567 && w != NULL)
6568 { 6634 {
6569 block_input (); 6635 w = f->output_data.x->menubar_widget;
6570 xlwmenu_redisplay (w); 6636
6571 unblock_input (); 6637 if (!DoesSaveUnders (FRAME_DISPLAY_INFO (f)->screen)
6638 && w != NULL)
6639 {
6640 block_input ();
6641 xlwmenu_redisplay (w);
6642 unblock_input ();
6643 }
6572 } 6644 }
6573 } 6645 }
6574 }
6575#endif /* USE_LUCID */ 6646#endif /* USE_LUCID */
6647
6648 was_open = Qt;
6649 }
6650 else
6651 tip_frame = Qnil;
6576 } 6652 }
6577 else 6653 else
6578 tip_frame = Qnil; 6654 tip_frame = Qnil;
6579 6655
6580 return unbind_to (count, was_open); 6656 return unbind_to (count, was_open);
6581 } 6657 }
6658#endif /* USE_GTK */
6582} 6659}
6583 6660
6661
6584DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0, 6662DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
6585 doc: /* Show STRING in a "tooltip" window on frame FRAME. 6663 doc: /* Show STRING in a "tooltip" window on frame FRAME.
6586A tooltip window is a small X window displaying a string. 6664A tooltip window is a small X window displaying a string.
@@ -6611,7 +6689,8 @@ with offset DY added (default is -10).
6611 6689
6612A tooltip's maximum size is specified by `x-max-tooltip-size'. 6690A tooltip's maximum size is specified by `x-max-tooltip-size'.
6613Text larger than the specified size is clipped. */) 6691Text larger than the specified size is clipped. */)
6614 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy) 6692 (Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
6693 Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
6615{ 6694{
6616 struct frame *f, *tip_f; 6695 struct frame *f, *tip_f;
6617 struct window *w; 6696 struct window *w;
@@ -6622,8 +6701,7 @@ Text larger than the specified size is clipped. */)
6622 int old_windows_or_buffers_changed = windows_or_buffers_changed; 6701 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6623 ptrdiff_t count = SPECPDL_INDEX (); 6702 ptrdiff_t count = SPECPDL_INDEX ();
6624 ptrdiff_t count_1; 6703 ptrdiff_t count_1;
6625 Lisp_Object window, size; 6704 Lisp_Object window, size, tip_buf;
6626 Lisp_Object tip_buf;
6627 AUTO_STRING (tip, " *tip*"); 6705 AUTO_STRING (tip, " *tip*");
6628 6706
6629 specbind (Qinhibit_redisplay, Qt); 6707 specbind (Qinhibit_redisplay, Qt);
@@ -6662,36 +6740,27 @@ Text larger than the specified size is clipped. */)
6662 { 6740 {
6663 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y); 6741 compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
6664 xg_show_tooltip (f, root_x, root_y); 6742 xg_show_tooltip (f, root_x, root_y);
6665 /* This is used in Fx_hide_tip. */ 6743 tip_last_frame = frame;
6666 XSETFRAME (tip_frame, f);
6667 } 6744 }
6745
6668 unblock_input (); 6746 unblock_input ();
6669 if (ok) goto start_timer; 6747 if (ok) goto start_timer;
6670 } 6748 }
6671#endif /* USE_GTK */ 6749#endif /* USE_GTK */
6672 6750
6673 if (NILP (last_show_tip_args))
6674 last_show_tip_args = Fmake_vector (make_number (3), Qnil);
6675
6676 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame))) 6751 if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
6677 { 6752 {
6678 Lisp_Object last_string = AREF (last_show_tip_args, 0);
6679 Lisp_Object last_frame = AREF (last_show_tip_args, 1);
6680 Lisp_Object last_parms = AREF (last_show_tip_args, 2);
6681
6682 if (FRAME_VISIBLE_P (XFRAME (tip_frame)) 6753 if (FRAME_VISIBLE_P (XFRAME (tip_frame))
6683 && EQ (frame, last_frame) 6754 && EQ (frame, tip_last_frame)
6684 && !NILP (Fequal_including_properties (last_string, string)) 6755 && !NILP (Fequal_including_properties (tip_last_string, string))
6685 && !NILP (Fequal (last_parms, parms))) 6756 && !NILP (Fequal (tip_last_parms, parms)))
6686 { 6757 {
6687 /* Only DX and DY have changed. */ 6758 /* Only DX and DY have changed. */
6688 tip_f = XFRAME (tip_frame); 6759 tip_f = XFRAME (tip_frame);
6689 if (!NILP (tip_timer)) 6760 if (!NILP (tip_timer))
6690 { 6761 {
6691 Lisp_Object timer = tip_timer; 6762 call1 (Qcancel_timer, tip_timer);
6692
6693 tip_timer = Qnil; 6763 tip_timer = Qnil;
6694 call1 (Qcancel_timer, timer);
6695 } 6764 }
6696 6765
6697 block_input (); 6766 block_input ();
@@ -6703,15 +6772,14 @@ Text larger than the specified size is clipped. */)
6703 6772
6704 goto start_timer; 6773 goto start_timer;
6705 } 6774 }
6706 else if (tooltip_reuse_hidden_frame && EQ (frame, last_frame)) 6775 else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
6707 { 6776 {
6708 bool delete = false; 6777 bool delete = false;
6709 Lisp_Object tail, elt, parm, last; 6778 Lisp_Object tail, elt, parm, last;
6710 6779
6711 /* Check if every parameter in PARMS has the same value in 6780 /* Check if every parameter in PARMS has the same value in
6712 last_parms unless it should be ignored by means of 6781 tip_last_parms. This may destruct tip_last_parms which,
6713 Vtooltip_reuse_hidden_frame_parameters. This may destruct 6782 however, will be recreated below. */
6714 last_parms which, however, will be recreated below. */
6715 for (tail = parms; CONSP (tail); tail = XCDR (tail)) 6783 for (tail = parms; CONSP (tail); tail = XCDR (tail))
6716 { 6784 {
6717 elt = XCAR (tail); 6785 elt = XCAR (tail);
@@ -6721,7 +6789,7 @@ Text larger than the specified size is clipped. */)
6721 if (!EQ (parm, Qleft) && !EQ (parm, Qtop) 6789 if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
6722 && !EQ (parm, Qright) && !EQ (parm, Qbottom)) 6790 && !EQ (parm, Qright) && !EQ (parm, Qbottom))
6723 { 6791 {
6724 last = Fassq (parm, last_parms); 6792 last = Fassq (parm, tip_last_parms);
6725 if (NILP (Fequal (Fcdr (elt), Fcdr (last)))) 6793 if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
6726 { 6794 {
6727 /* We lost, delete the old tooltip. */ 6795 /* We lost, delete the old tooltip. */
@@ -6729,17 +6797,18 @@ Text larger than the specified size is clipped. */)
6729 break; 6797 break;
6730 } 6798 }
6731 else 6799 else
6732 last_parms = call2 (Qassq_delete_all, parm, last_parms); 6800 tip_last_parms =
6801 call2 (Qassq_delete_all, parm, tip_last_parms);
6733 } 6802 }
6734 else 6803 else
6735 last_parms = call2 (Qassq_delete_all, parm, last_parms); 6804 tip_last_parms =
6805 call2 (Qassq_delete_all, parm, tip_last_parms);
6736 } 6806 }
6737 6807
6738 /* Now check if every parameter in what is left of last_parms 6808 /* Now check if every parameter in what is left of
6739 with a non-nil value has an association in PARMS unless it 6809 tip_last_parms with a non-nil value has an association in
6740 should be ignored by means of 6810 PARMS. */
6741 Vtooltip_reuse_hidden_frame_parameters. */ 6811 for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
6742 for (tail = last_parms; CONSP (tail); tail = XCDR (tail))
6743 { 6812 {
6744 elt = XCAR (tail); 6813 elt = XCAR (tail);
6745 parm = Fcar (elt); 6814 parm = Fcar (elt);
@@ -6760,9 +6829,9 @@ Text larger than the specified size is clipped. */)
6760 else 6829 else
6761 x_hide_tip (true); 6830 x_hide_tip (true);
6762 6831
6763 ASET (last_show_tip_args, 0, string); 6832 tip_last_frame = frame;
6764 ASET (last_show_tip_args, 1, frame); 6833 tip_last_string = string;
6765 ASET (last_show_tip_args, 2, parms); 6834 tip_last_parms = parms;
6766 6835
6767 if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame))) 6836 if (!FRAMEP (tip_frame) || !FRAME_LIVE_P (XFRAME (tip_frame)))
6768 { 6837 {
@@ -7823,7 +7892,6 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
7823 defsubr (&Sx_display_list); 7892 defsubr (&Sx_display_list);
7824 defsubr (&Sx_synchronize); 7893 defsubr (&Sx_synchronize);
7825 defsubr (&Sx_backspace_delete_keys_p); 7894 defsubr (&Sx_backspace_delete_keys_p);
7826
7827 defsubr (&Sx_show_tip); 7895 defsubr (&Sx_show_tip);
7828 defsubr (&Sx_hide_tip); 7896 defsubr (&Sx_hide_tip);
7829 defsubr (&Sx_double_buffered_p); 7897 defsubr (&Sx_double_buffered_p);
@@ -7831,9 +7899,12 @@ When using Gtk+ tooltips, the tooltip face is not used. */);
7831 staticpro (&tip_timer); 7899 staticpro (&tip_timer);
7832 tip_frame = Qnil; 7900 tip_frame = Qnil;
7833 staticpro (&tip_frame); 7901 staticpro (&tip_frame);
7834 7902 tip_last_frame = Qnil;
7835 last_show_tip_args = Qnil; 7903 staticpro (&tip_last_frame);
7836 staticpro (&last_show_tip_args); 7904 tip_last_string = Qnil;
7905 staticpro (&tip_last_string);
7906 tip_last_parms = Qnil;
7907 staticpro (&tip_last_parms);
7837 7908
7838 defsubr (&Sx_uses_old_gtk_dialog); 7909 defsubr (&Sx_uses_old_gtk_dialog);
7839#if defined (USE_MOTIF) || defined (USE_GTK) 7910#if defined (USE_MOTIF) || defined (USE_GTK)
diff --git a/src/xterm.c b/src/xterm.c
index f771631dafa..0a2068d7f30 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -996,12 +996,7 @@ static void
996x_update_begin (struct frame *f) 996x_update_begin (struct frame *f)
997{ 997{
998#ifdef USE_CAIRO 998#ifdef USE_CAIRO
999 if (! NILP (tip_frame) && XFRAME (tip_frame) == f 999 if (FRAME_TOOLTIP_P (f) && !FRAME_VISIBLE_P (f))
1000 && ! FRAME_VISIBLE_P (f)
1001#ifdef USE_GTK
1002 && !NILP (Fframe_parameter (tip_frame, Qtooltip))
1003#endif
1004 )
1005 return; 1000 return;
1006 1001
1007 if (! FRAME_CR_SURFACE (f)) 1002 if (! FRAME_CR_SURFACE (f))
@@ -8091,7 +8086,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8091 /* Redo the mouse-highlight after the tooltip has gone. */ 8086 /* Redo the mouse-highlight after the tooltip has gone. */
8092 if (event->xunmap.window == tip_window) 8087 if (event->xunmap.window == tip_window)
8093 { 8088 {
8094 tip_window = 0; 8089 tip_window = None;
8095 x_redo_mouse_highlight (dpyinfo); 8090 x_redo_mouse_highlight (dpyinfo);
8096 } 8091 }
8097 8092
@@ -8733,7 +8728,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
8733 8728
8734#ifdef USE_X_TOOLKIT 8729#ifdef USE_X_TOOLKIT
8735 /* Tip frames are pure X window, set size for them. */ 8730 /* Tip frames are pure X window, set size for them. */
8736 if (! NILP (tip_frame) && XFRAME (tip_frame) == f) 8731 if (FRAME_TOOLTIP_P (f))
8737 { 8732 {
8738 if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height 8733 if (FRAME_PIXEL_HEIGHT (f) != configureEvent.xconfigure.height
8739 || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width) 8734 || FRAME_PIXEL_WIDTH (f) != configureEvent.xconfigure.width)
@@ -9971,11 +9966,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
9971 /* Don't change the size of a tip frame; there's no point in 9966 /* Don't change the size of a tip frame; there's no point in
9972 doing it because it's done in Fx_show_tip, and it leads to 9967 doing it because it's done in Fx_show_tip, and it leads to
9973 problems because the tip frame has no widget. */ 9968 problems because the tip frame has no widget. */
9974 if (NILP (tip_frame) || XFRAME (tip_frame) != f 9969 if (!FRAME_TOOLTIP_P (f))
9975#ifdef USE_GTK
9976 || NILP (Fframe_parameter (tip_frame, Qtooltip))
9977#endif
9978 )
9979 { 9970 {
9980 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), 9971 adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
9981 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3, 9972 FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
@@ -11204,7 +11195,7 @@ x_set_window_size (struct frame *f, bool change_gravity,
11204 /* The following breaks our calculations. If it's really needed, 11195 /* The following breaks our calculations. If it's really needed,
11205 think of something else. */ 11196 think of something else. */
11206#if false 11197#if false
11207 if (NILP (tip_frame) || XFRAME (tip_frame) != f) 11198 if (!FRAME_TOOLTIP_P (f))
11208 { 11199 {
11209 int text_width, text_height; 11200 int text_width, text_height;
11210 11201
diff --git a/src/xterm.h b/src/xterm.h
index f73dd0e25ab..1849a5c9535 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -503,6 +503,8 @@ extern bool x_display_ok (const char *);
503 503
504extern void select_visual (struct x_display_info *); 504extern void select_visual (struct x_display_info *);
505 505
506extern Window tip_window;
507
506/* Each X frame object points to its own struct x_output object 508/* Each X frame object points to its own struct x_output object
507 in the output_data.x field. The x_output structure contains 509 in the output_data.x field. The x_output structure contains
508 the information that is specific to X windows. */ 510 the information that is specific to X windows. */