summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Rudalics <rudalics@gmx.at>2018-02-10 10:18:38 +0100
committerMartin Rudalics <rudalics@gmx.at>2018-02-10 10:18:38 +0100
commit479f51a63bb0de72453881d72a1b3ff5f30b4658 (patch)
tree2dfd86cd245bc11954b933f2e99670aa3b42b4ee
parent2c980ea613115f5c2858e172f3bf9be103439a46 (diff)
downloademacs-479f51a63bb0de72453881d72a1b3ff5f30b4658.tar.gz
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).
-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;
/* STRING argument of last `x-show-tip' call. */
Lisp_Object tip_last_string;
-/* FRAME argument of last `x-show-tip' call. */
+/* Normalized FRAME argument of last `x-show-tip' call. */
Lisp_Object tip_last_frame;
/* PARMS argument of last `x-show-tip' call. */
@@ -7373,7 +7373,11 @@ Text larger than the specified size is clipped. */)
specbind (Qinhibit_redisplay, Qt);
CHECK_STRING (string);
+
+ if (NILP (frame))
+ frame = selected_frame;
decode_window_system_frame (frame);
+
if (NILP (timeout))
timeout = make_number (5);
else
@@ -7508,7 +7512,7 @@ Text larger than the specified size is clipped. */)
parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
parms);
- /* Create a frame for the tooltip, and record it in the global
+ /* Create a frame for the tooltip and record it in the global
variable tip_frame. */
struct frame *f; /* The value is unused. */
if (NILP (tip_frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms)))
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
/* An alist with parameters. */
Lisp_Object window_parameters;
+ /* The help echo text for this window. Qnil if there's none. */
+ Lisp_Object mode_line_help_echo;
+
/* No Lisp data may follow below this point without changing
mark_object in alloc.c. The member current_matrix must be the
first non-Lisp member. */
@@ -445,6 +448,12 @@ wset_redisplay_end_trigger (struct window *w, Lisp_Object val)
}
INLINE void
+wset_mode_line_help_echo (struct window *w, Lisp_Object val)
+{
+ w->mode_line_help_echo = val;
+}
+
+INLINE void
wset_new_pixel (struct window *w, Lisp_Object val)
{
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)
Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
int n = 0;
+ if (window_wants_mode_line (w))
+ {
+ Lisp_Object window;
+ Lisp_Object default_help
+ = buffer_local_value (Qmode_line_default_help_echo, w->contents);
+
+ /* Set up mode line help echo. Do this before selecting w so it
+ can reasonably tell whether a mouse click will select w. */
+ XSETWINDOW (window, w);
+ if (FUNCTIONP (default_help))
+ wset_mode_line_help_echo (w, safe_call1 (default_help, window));
+ else if (STRINGP (default_help))
+ wset_mode_line_help_echo (w, default_help);
+ else
+ wset_mode_line_help_echo (w, Qnil);
+ }
+
selected_frame = new_frame;
/* FIXME: If we were to allow the mode-line's computation changing the buffer
or window's point, then we'd need select_window_1 here as well. */
@@ -23223,7 +23240,6 @@ display_mode_lines (struct window *w)
{
Lisp_Object window_mode_line_format
= window_parameter (w, Qmode_line_format);
-
struct window *sel_w = XWINDOW (old_selected_window);
/* 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,
struct window *w = XWINDOW (window);
struct frame *f = XFRAME (w->frame);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-#ifdef HAVE_WINDOW_SYSTEM
- Display_Info *dpyinfo;
-#endif
Cursor cursor = No_Cursor;
Lisp_Object pointer = Qnil;
int dx, dy, width, height;
@@ -30829,7 +30842,8 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
/* Set the help text and mouse pointer. If the mouse is on a part
of the mode line without any text (e.g. past the right edge of
- the mode line text), use the default help text and pointer. */
+ the mode line text), use that windows's mode line help echo if it
+ has been set. */
if (STRINGP (string) || area == ON_MODE_LINE)
{
/* 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,
help_echo_object = string;
help_echo_pos = charpos;
}
- else if (area == ON_MODE_LINE)
+ else if (area == ON_MODE_LINE
+ && !NILP (w->mode_line_help_echo))
{
- Lisp_Object default_help
- = buffer_local_value (Qmode_line_default_help_echo,
- w->contents);
-
- if (FUNCTIONP (default_help) || STRINGP (default_help))
- {
- help_echo_string = (FUNCTIONP (default_help)
- ? safe_call1 (default_help, window)
- : default_help);
- XSETWINDOW (help_echo_window, w);
- help_echo_object = Qnil;
- help_echo_pos = -1;
- }
+ help_echo_string = w->mode_line_help_echo;
+ XSETWINDOW (help_echo_window, w);
+ help_echo_object = Qnil;
+ help_echo_pos = -1;
}
}
@@ -30872,7 +30878,6 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
|| minibuf_level
|| NILP (Vresize_mini_windows));
- dpyinfo = FRAME_DISPLAY_INFO (f);
if (STRINGP (string))
{
cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
@@ -30882,25 +30887,28 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
/* Change the mouse pointer according to what is under X/Y. */
if (NILP (pointer)
- && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
+ && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
{
Lisp_Object map;
+
map = Fget_text_property (pos, Qlocal_map, string);
if (!KEYMAPP (map))
map = Fget_text_property (pos, Qkeymap, string);
- if (!KEYMAPP (map) && draggable)
- cursor = dpyinfo->vertical_scroll_bar_cursor;
+ if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
+ cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
}
}
- else if (draggable)
- /* Default mode-line pointer. */
- cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
+ else if (draggable && area == ON_MODE_LINE)
+ cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
+ else
+ cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
}
#endif
}
/* Change the mouse face according to what is under X/Y. */
bool mouse_face_shown = false;
+
if (STRINGP (string))
{
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;
/* STRING argument of last `x-show-tip' call. */
static Lisp_Object tip_last_string;
-/* FRAME argument of last `x-show-tip' call. */
+/* Normalized FRAME argument of last `x-show-tip' call. */
static Lisp_Object tip_last_frame;
/* PARMS argument of last `x-show-tip' call. */
@@ -6542,16 +6542,20 @@ x_hide_tip (bool delete)
}
#ifdef USE_GTK
- /* The GTK+ system tooltip window can be found via the x_output
- structure of tip_last_frame, if it still exists. */
- if (x_gtk_use_system_tooltips && NILP (tip_last_frame))
- return Qnil;
- else if (!x_gtk_use_system_tooltips
- && (NILP (tip_frame)
- || (!delete
- && FRAMEP (tip_frame)
- && FRAME_LIVE_P (XFRAME (tip_frame))
- && !FRAME_VISIBLE_P (XFRAME (tip_frame)))))
+ /* Any GTK+ system tooltip can be found via the x_output structure of
+ tip_last_frame, provided that frame is still live. Any Emacs
+ tooltip is found via the tip_frame variable. Note that the current
+ value of x_gtk_use_system_tooltips might not be the same as used
+ for the tooltip we have to hide, see Bug#30399. */
+ if ((NILP (tip_last_frame) && NILP (tip_frame))
+ || (!x_gtk_use_system_tooltips
+ && !delete
+ && FRAMEP (tip_frame)
+ && FRAME_LIVE_P (XFRAME (tip_frame))
+ && !FRAME_VISIBLE_P (XFRAME (tip_frame))))
+ /* Either there's no tooltip to hide or it's an already invisible
+ Emacs tooltip and we don't want to change its type. Return
+ quickly. */
return Qnil;
else
{
@@ -6562,10 +6566,9 @@ x_hide_tip (bool delete)
specbind (Qinhibit_redisplay, Qt);
specbind (Qinhibit_quit, Qt);
- if (x_gtk_use_system_tooltips)
+ /* Try to hide the GTK+ system tip first. */
+ if (FRAMEP (tip_last_frame))
{
- /* The GTK+ system tooltip window is stored in the x_output
- structure of tip_last_frame. */
struct frame *f = XFRAME (tip_last_frame);
if (FRAME_LIVE_P (f))
@@ -6573,33 +6576,37 @@ x_hide_tip (bool delete)
if (xg_hide_tooltip (f))
was_open = Qt;
}
- else
- tip_last_frame = Qnil;
}
- else
+
+ /* Reset tip_last_frame, it will be reassigned when showing the
+ next GTK+ system tooltip. */
+ tip_last_frame = Qnil;
+
+ /* Now look whether there's an Emacs tip around. */
+ if (FRAMEP (tip_frame))
{
- if (FRAMEP (tip_frame))
- {
- struct frame *f = XFRAME (tip_frame);
+ struct frame *f = XFRAME (tip_frame);
- if (FRAME_LIVE_P (f))
+ if (FRAME_LIVE_P (f))
+ {
+ if (delete || x_gtk_use_system_tooltips)
{
- if (delete)
- {
- delete_frame (tip_frame, Qnil);
- tip_frame = Qnil;
- }
- else
- x_make_frame_invisible (f);
-
- was_open = Qt;
+ /* Delete the Emacs tooltip frame when DELETE is true
+ or we change the tooltip type from an Emacs one to
+ a GTK+ system one. */
+ delete_frame (tip_frame, Qnil);
+ tip_frame = Qnil;
}
else
- tip_frame = Qnil;
+ x_make_frame_invisible (f);
+
+ was_open = Qt;
}
else
tip_frame = Qnil;
}
+ else
+ tip_frame = Qnil;
return unbind_to (count, was_open);
}
@@ -6721,7 +6728,10 @@ Text larger than the specified size is clipped. */)
if (SCHARS (string) == 0)
string = make_unibyte_string (" ", 1);
+ if (NILP (frame))
+ frame = selected_frame;
f = decode_window_system_frame (frame);
+
if (NILP (timeout))
timeout = make_number (5);
else