aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2018-02-10 10:18:38 +0100
committerMartin Rudalics2018-02-10 10:18:38 +0100
commit479f51a63bb0de72453881d72a1b3ff5f30b4658 (patch)
tree2dfd86cd245bc11954b933f2e99670aa3b42b4ee /src
parent2c980ea613115f5c2858e172f3bf9be103439a46 (diff)
downloademacs-479f51a63bb0de72453881d72a1b3ff5f30b4658.tar.gz
emacs-479f51a63bb0de72453881d72a1b3ff5f30b4658.zip
Make tooltip code handle scenarios from Bug#30182 and Bug#30399
Move calculation of the mode line default help echo from note_mode_line_or_margin_highlight to display_mode_lines (Bug#30182). Fix cursor type for dragging the mode line. Normalize FRAME argument of Fx_show_tip before assigning it to tip_last_frame and handle the transition from GTK+ to Emacs tooltips and vice-versa in x_hide_tip (Bug#30399). * src/window.h (struct window): New Lisp member mode_line_help_echo. (wset_mode_line_help_echo): New function. * src/w32fns.c (Fx_show_tip): Normalize the FRAME argument bevore storing it in tip_last_frame (Bug#30399). * src/xdisp.c (display_mode_lines): Calculate mode line default help echo string here and store it in the window's mode_line_help_echo slot (Bug#30182). (note_mode_line_or_margin_highlight): Use value in window's mode_line_help_echo slot as mode line default help echo. When the window is resizable show a vertical drag cursor instead of the vertical scroll bar cursor. * src/xfns.c (x_hide_tip): Rewrite the GTK+ part to correctly handle the transition from GTK+ system to Emacs tooltips and vice-versa (Bug#30399). (Fx_show_tip): Normalize the FRAME argument bevore storing it in tip_last_frame (Bug#30399).
Diffstat (limited to 'src')
-rw-r--r--src/w32fns.c8
-rw-r--r--src/window.h9
-rw-r--r--src/xdisp.c60
-rw-r--r--src/xfns.c72
4 files changed, 90 insertions, 59 deletions
diff --git a/src/w32fns.c b/src/w32fns.c
index 27c765ed920..2b8c34a5ab5 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -6930,7 +6930,7 @@ Lisp_Object tip_timer;
6930/* STRING argument of last `x-show-tip' call. */ 6930/* STRING argument of last `x-show-tip' call. */
6931Lisp_Object tip_last_string; 6931Lisp_Object tip_last_string;
6932 6932
6933/* FRAME argument of last `x-show-tip' call. */ 6933/* Normalized FRAME argument of last `x-show-tip' call. */
6934Lisp_Object tip_last_frame; 6934Lisp_Object tip_last_frame;
6935 6935
6936/* PARMS argument of last `x-show-tip' call. */ 6936/* PARMS argument of last `x-show-tip' call. */
@@ -7373,7 +7373,11 @@ Text larger than the specified size is clipped. */)
7373 specbind (Qinhibit_redisplay, Qt); 7373 specbind (Qinhibit_redisplay, Qt);
7374 7374
7375 CHECK_STRING (string); 7375 CHECK_STRING (string);
7376
7377 if (NILP (frame))
7378 frame = selected_frame;
7376 decode_window_system_frame (frame); 7379 decode_window_system_frame (frame);
7380
7377 if (NILP (timeout)) 7381 if (NILP (timeout))
7378 timeout = make_number (5); 7382 timeout = make_number (5);
7379 else 7383 else
@@ -7508,7 +7512,7 @@ Text larger than the specified size is clipped. */)
7508 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")), 7512 parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
7509 parms); 7513 parms);
7510 7514
7511 /* Create a frame for the tooltip, and record it in the global 7515 /* Create a frame for the tooltip and record it in the global
7512 variable tip_frame. */ 7516 variable tip_frame. */
7513 struct frame *f; /* The value is unused. */ 7517 struct frame *f; /* The value is unused. */
7514 if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms))) 7518 if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
diff --git a/src/window.h b/src/window.h
index 629283ac40c..91ef7d90272 100644
--- a/src/window.h
+++ b/src/window.h
@@ -178,6 +178,9 @@ struct window
178 /* An alist with parameters. */ 178 /* An alist with parameters. */
179 Lisp_Object window_parameters; 179 Lisp_Object window_parameters;
180 180
181 /* The help echo text for this window. Qnil if there's none. */
182 Lisp_Object mode_line_help_echo;
183
181 /* No Lisp data may follow below this point without changing 184 /* No Lisp data may follow below this point without changing
182 mark_object in alloc.c. The member current_matrix must be the 185 mark_object in alloc.c. The member current_matrix must be the
183 first non-Lisp member. */ 186 first non-Lisp member. */
@@ -445,6 +448,12 @@ wset_redisplay_end_trigger (struct window *w, Lisp_Object val)
445} 448}
446 449
447INLINE void 450INLINE void
451wset_mode_line_help_echo (struct window *w, Lisp_Object val)
452{
453 w->mode_line_help_echo = val;
454}
455
456INLINE void
448wset_new_pixel (struct window *w, Lisp_Object val) 457wset_new_pixel (struct window *w, Lisp_Object val)
449{ 458{
450 w->new_pixel = val; 459 w->new_pixel = val;
diff --git a/src/xdisp.c b/src/xdisp.c
index 55f3151b4f2..9a5bd2eb96c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -23209,6 +23209,23 @@ display_mode_lines (struct window *w)
23209 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window; 23209 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
23210 int n = 0; 23210 int n = 0;
23211 23211
23212 if (window_wants_mode_line (w))
23213 {
23214 Lisp_Object window;
23215 Lisp_Object default_help
23216 = buffer_local_value (Qmode_line_default_help_echo, w->contents);
23217
23218 /* Set up mode line help echo. Do this before selecting w so it
23219 can reasonably tell whether a mouse click will select w. */
23220 XSETWINDOW (window, w);
23221 if (FUNCTIONP (default_help))
23222 wset_mode_line_help_echo (w, safe_call1 (default_help, window));
23223 else if (STRINGP (default_help))
23224 wset_mode_line_help_echo (w, default_help);
23225 else
23226 wset_mode_line_help_echo (w, Qnil);
23227 }
23228
23212 selected_frame = new_frame; 23229 selected_frame = new_frame;
23213 /* FIXME: If we were to allow the mode-line's computation changing the buffer 23230 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23214 or window's point, then we'd need select_window_1 here as well. */ 23231 or window's point, then we'd need select_window_1 here as well. */
@@ -23223,7 +23240,6 @@ display_mode_lines (struct window *w)
23223 { 23240 {
23224 Lisp_Object window_mode_line_format 23241 Lisp_Object window_mode_line_format
23225 = window_parameter (w, Qmode_line_format); 23242 = window_parameter (w, Qmode_line_format);
23226
23227 struct window *sel_w = XWINDOW (old_selected_window); 23243 struct window *sel_w = XWINDOW (old_selected_window);
23228 23244
23229 /* Select mode line face based on the real selected window. */ 23245 /* Select mode line face based on the real selected window. */
@@ -30733,9 +30749,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30733 struct window *w = XWINDOW (window); 30749 struct window *w = XWINDOW (window);
30734 struct frame *f = XFRAME (w->frame); 30750 struct frame *f = XFRAME (w->frame);
30735 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); 30751 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30736#ifdef HAVE_WINDOW_SYSTEM
30737 Display_Info *dpyinfo;
30738#endif
30739 Cursor cursor = No_Cursor; 30752 Cursor cursor = No_Cursor;
30740 Lisp_Object pointer = Qnil; 30753 Lisp_Object pointer = Qnil;
30741 int dx, dy, width, height; 30754 int dx, dy, width, height;
@@ -30829,7 +30842,8 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30829 30842
30830 /* Set the help text and mouse pointer. If the mouse is on a part 30843 /* Set the help text and mouse pointer. If the mouse is on a part
30831 of the mode line without any text (e.g. past the right edge of 30844 of the mode line without any text (e.g. past the right edge of
30832 the mode line text), use the default help text and pointer. */ 30845 the mode line text), use that windows's mode line help echo if it
30846 has been set. */
30833 if (STRINGP (string) || area == ON_MODE_LINE) 30847 if (STRINGP (string) || area == ON_MODE_LINE)
30834 { 30848 {
30835 /* Arrange to display the help by setting the global variables 30849 /* Arrange to display the help by setting the global variables
@@ -30846,21 +30860,13 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30846 help_echo_object = string; 30860 help_echo_object = string;
30847 help_echo_pos = charpos; 30861 help_echo_pos = charpos;
30848 } 30862 }
30849 else if (area == ON_MODE_LINE) 30863 else if (area == ON_MODE_LINE
30864 && !NILP (w->mode_line_help_echo))
30850 { 30865 {
30851 Lisp_Object default_help 30866 help_echo_string = w->mode_line_help_echo;
30852 = buffer_local_value (Qmode_line_default_help_echo, 30867 XSETWINDOW (help_echo_window, w);
30853 w->contents); 30868 help_echo_object = Qnil;
30854 30869 help_echo_pos = -1;
30855 if (FUNCTIONP (default_help) || STRINGP (default_help))
30856 {
30857 help_echo_string = (FUNCTIONP (default_help)
30858 ? safe_call1 (default_help, window)
30859 : default_help);
30860 XSETWINDOW (help_echo_window, w);
30861 help_echo_object = Qnil;
30862 help_echo_pos = -1;
30863 }
30864 } 30870 }
30865 } 30871 }
30866 30872
@@ -30872,7 +30878,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30872 || minibuf_level 30878 || minibuf_level
30873 || NILP (Vresize_mini_windows)); 30879 || NILP (Vresize_mini_windows));
30874 30880
30875 dpyinfo = FRAME_DISPLAY_INFO (f);
30876 if (STRINGP (string)) 30881 if (STRINGP (string))
30877 { 30882 {
30878 cursor = FRAME_X_OUTPUT (f)->nontext_cursor; 30883 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -30882,25 +30887,28 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30882 30887
30883 /* Change the mouse pointer according to what is under X/Y. */ 30888 /* Change the mouse pointer according to what is under X/Y. */
30884 if (NILP (pointer) 30889 if (NILP (pointer)
30885 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))) 30890 && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
30886 { 30891 {
30887 Lisp_Object map; 30892 Lisp_Object map;
30893
30888 map = Fget_text_property (pos, Qlocal_map, string); 30894 map = Fget_text_property (pos, Qlocal_map, string);
30889 if (!KEYMAPP (map)) 30895 if (!KEYMAPP (map))
30890 map = Fget_text_property (pos, Qkeymap, string); 30896 map = Fget_text_property (pos, Qkeymap, string);
30891 if (!KEYMAPP (map) && draggable) 30897 if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
30892 cursor = dpyinfo->vertical_scroll_bar_cursor; 30898 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30893 } 30899 }
30894 } 30900 }
30895 else if (draggable) 30901 else if (draggable && area == ON_MODE_LINE)
30896 /* Default mode-line pointer. */ 30902 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30897 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; 30903 else
30904 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30898 } 30905 }
30899#endif 30906#endif
30900 } 30907 }
30901 30908
30902 /* Change the mouse face according to what is under X/Y. */ 30909 /* Change the mouse face according to what is under X/Y. */
30903 bool mouse_face_shown = false; 30910 bool mouse_face_shown = false;
30911
30904 if (STRINGP (string)) 30912 if (STRINGP (string))
30905 { 30913 {
30906 mouse_face = Fget_text_property (pos, Qmouse_face, string); 30914 mouse_face = Fget_text_property (pos, Qmouse_face, string);
diff --git a/src/xfns.c b/src/xfns.c
index db1ce311021..9f0d9468c14 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6077,7 +6077,7 @@ static Lisp_Object tip_timer;
6077/* STRING argument of last `x-show-tip' call. */ 6077/* STRING argument of last `x-show-tip' call. */
6078static Lisp_Object tip_last_string; 6078static Lisp_Object tip_last_string;
6079 6079
6080/* FRAME argument of last `x-show-tip' call. */ 6080/* Normalized FRAME argument of last `x-show-tip' call. */
6081static Lisp_Object tip_last_frame; 6081static Lisp_Object tip_last_frame;
6082 6082
6083/* PARMS argument of last `x-show-tip' call. */ 6083/* PARMS argument of last `x-show-tip' call. */
@@ -6542,16 +6542,20 @@ x_hide_tip (bool delete)
6542 } 6542 }
6543 6543
6544#ifdef USE_GTK 6544#ifdef USE_GTK
6545 /* The GTK+ system tooltip window can be found via the x_output 6545 /* Any GTK+ system tooltip can be found via the x_output structure of
6546 structure of tip_last_frame, if it still exists. */ 6546 tip_last_frame, provided that frame is still live. Any Emacs
6547 if (x_gtk_use_system_tooltips && NILP (tip_last_frame)) 6547 tooltip is found via the tip_frame variable. Note that the current
6548 return Qnil; 6548 value of x_gtk_use_system_tooltips might not be the same as used
6549 else if (!x_gtk_use_system_tooltips 6549 for the tooltip we have to hide, see Bug#30399. */
6550 && (NILP (tip_frame) 6550 if ((NILP (tip_last_frame) && NILP (tip_frame))
6551 || (!delete 6551 || (!x_gtk_use_system_tooltips
6552 && FRAMEP (tip_frame) 6552 && !delete
6553 && FRAME_LIVE_P (XFRAME (tip_frame)) 6553 && FRAMEP (tip_frame)
6554 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))) 6554 && FRAME_LIVE_P (XFRAME (tip_frame))
6555 && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
6556 /* Either there's no tooltip to hide or it's an already invisible
6557 Emacs tooltip and we don't want to change its type. Return
6558 quickly. */
6555 return Qnil; 6559 return Qnil;
6556 else 6560 else
6557 { 6561 {
@@ -6562,10 +6566,9 @@ x_hide_tip (bool delete)
6562 specbind (Qinhibit_redisplay, Qt); 6566 specbind (Qinhibit_redisplay, Qt);
6563 specbind (Qinhibit_quit, Qt); 6567 specbind (Qinhibit_quit, Qt);
6564 6568
6565 if (x_gtk_use_system_tooltips) 6569 /* Try to hide the GTK+ system tip first. */
6570 if (FRAMEP (tip_last_frame))
6566 { 6571 {
6567 /* The GTK+ system tooltip window is stored in the x_output
6568 structure of tip_last_frame. */
6569 struct frame *f = XFRAME (tip_last_frame); 6572 struct frame *f = XFRAME (tip_last_frame);
6570 6573
6571 if (FRAME_LIVE_P (f)) 6574 if (FRAME_LIVE_P (f))
@@ -6573,33 +6576,37 @@ x_hide_tip (bool delete)
6573 if (xg_hide_tooltip (f)) 6576 if (xg_hide_tooltip (f))
6574 was_open = Qt; 6577 was_open = Qt;
6575 } 6578 }
6576 else
6577 tip_last_frame = Qnil;
6578 } 6579 }
6579 else 6580
6581 /* Reset tip_last_frame, it will be reassigned when showing the
6582 next GTK+ system tooltip. */
6583 tip_last_frame = Qnil;
6584
6585 /* Now look whether there's an Emacs tip around. */
6586 if (FRAMEP (tip_frame))
6580 { 6587 {
6581 if (FRAMEP (tip_frame)) 6588 struct frame *f = XFRAME (tip_frame);
6582 {
6583 struct frame *f = XFRAME (tip_frame);
6584 6589
6585 if (FRAME_LIVE_P (f)) 6590 if (FRAME_LIVE_P (f))
6591 {
6592 if (delete || x_gtk_use_system_tooltips)
6586 { 6593 {
6587 if (delete) 6594 /* Delete the Emacs tooltip frame when DELETE is true
6588 { 6595 or we change the tooltip type from an Emacs one to
6589 delete_frame (tip_frame, Qnil); 6596 a GTK+ system one. */
6590 tip_frame = Qnil; 6597 delete_frame (tip_frame, Qnil);
6591 } 6598 tip_frame = Qnil;
6592 else
6593 x_make_frame_invisible (f);
6594
6595 was_open = Qt;
6596 } 6599 }
6597 else 6600 else
6598 tip_frame = Qnil; 6601 x_make_frame_invisible (f);
6602
6603 was_open = Qt;
6599 } 6604 }
6600 else 6605 else
6601 tip_frame = Qnil; 6606 tip_frame = Qnil;
6602 } 6607 }
6608 else
6609 tip_frame = Qnil;
6603 6610
6604 return unbind_to (count, was_open); 6611 return unbind_to (count, was_open);
6605 } 6612 }
@@ -6721,7 +6728,10 @@ Text larger than the specified size is clipped. */)
6721 if (SCHARS (string) == 0) 6728 if (SCHARS (string) == 0)
6722 string = make_unibyte_string (" ", 1); 6729 string = make_unibyte_string (" ", 1);
6723 6730
6731 if (NILP (frame))
6732 frame = selected_frame;
6724 f = decode_window_system_frame (frame); 6733 f = decode_window_system_frame (frame);
6734
6725 if (NILP (timeout)) 6735 if (NILP (timeout))
6726 timeout = make_number (5); 6736 timeout = make_number (5);
6727 else 6737 else