diff options
| author | Martin Rudalics | 2018-02-10 10:18:38 +0100 |
|---|---|---|
| committer | Martin Rudalics | 2018-02-10 10:18:38 +0100 |
| commit | 479f51a63bb0de72453881d72a1b3ff5f30b4658 (patch) | |
| tree | 2dfd86cd245bc11954b933f2e99670aa3b42b4ee /src | |
| parent | 2c980ea613115f5c2858e172f3bf9be103439a46 (diff) | |
| download | emacs-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.c | 8 | ||||
| -rw-r--r-- | src/window.h | 9 | ||||
| -rw-r--r-- | src/xdisp.c | 60 | ||||
| -rw-r--r-- | src/xfns.c | 72 |
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. */ |
| 6931 | Lisp_Object tip_last_string; | 6931 | Lisp_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. */ |
| 6934 | Lisp_Object tip_last_frame; | 6934 | Lisp_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 | ||
| 447 | INLINE void | 450 | INLINE void |
| 451 | wset_mode_line_help_echo (struct window *w, Lisp_Object val) | ||
| 452 | { | ||
| 453 | w->mode_line_help_echo = val; | ||
| 454 | } | ||
| 455 | |||
| 456 | INLINE void | ||
| 448 | wset_new_pixel (struct window *w, Lisp_Object val) | 457 | wset_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. */ |
| 6078 | static Lisp_Object tip_last_string; | 6078 | static 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. */ |
| 6081 | static Lisp_Object tip_last_frame; | 6081 | static 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 |