mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-14 09:39:42 +00:00
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).
This commit is contained in:
parent
2c980ea613
commit
479f51a63b
@ -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)
|
||||
{
|
||||
|
60
src/xdisp.c
60
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);
|
||||
|
72
src/xfns.c
72
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);
|
||||
|
||||
if (FRAME_LIVE_P (f))
|
||||
{
|
||||
struct frame *f = XFRAME (tip_frame);
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user