diff --git a/src/xfns.c b/src/xfns.c index db1ce31..9f0d946 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -6077,7 +6077,7 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, /* 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 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, } #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 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, 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 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, 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 @@ with offset DY added (default is -10). 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