Commit 479f51a6 authored by Martin Rudalics's avatar Martin Rudalics
Browse files

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).
parent 2c980ea6
......@@ -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)))
......
......@@ -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. */
......@@ -444,6 +447,12 @@ wset_redisplay_end_trigger (struct window *w, Lisp_Object val)
w->redisplay_end_trigger = 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)
{
......
......@@ -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);
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment