Commit e462308f authored by Martin Rudalics's avatar Martin Rudalics

Fix some tooltip related problems

Replace 'tooltip' frame parameter with a 'tooltip' member in
the frame structure.  For GTK+ builds use 'tip_last_frame' to
find the frame for which the currently visible tooltip was
made.  For modeline help-echoing have tooltips show applicable
actions only.

* lisp/bindings.el (mode-line-default-help-echo): New function
as default value of homonymous option.
* src/dispextern.h (tip_frame, tip_window): Remove
declarations.
* src/frame.c (make_frame): Initialize new frame structure
member 'tooltip'.
(Fframe_list, other_frames): Rewrite with new macro
FRAME_TOOLTIP_P.
* src/frame.h (struct frame): New member 'tooltip'.
(FRAME_TOOLTIP_P): New macro.
* src/gtkutil.c (xg_prepare_tooltip, xg_hide_tooltip): Rewrite
using boolean return values.
* src/nsfns.m (tip_frame): Remove declaration.
* src/w32fns.c (w32_display_monitor_attributes_list)
(w32_display_monitor_attributes_list_fallback): Rewrite with
new macro FRAME_TOOLTIP_P.
(tip_last_string, tip_last_frame, tip_last_parms): New Lisp
scalars replacing Lisp vector last_show_tip_args.
(x_create_tip_frame): Set new frame's 'tooltip' structure
member to true.
(x_hide_tip): Additionally test tip_frame for liveness.
(Fx_show_tip): Handle last_show_tip_args to tip_last_frame,
tip_last_string and tip_last_parms conversion.
(syms_of_w32fns): staticpro tip_last_frame, tip_last_string
and tip_last_parms instead of last_show_tip_args.
* src/w32term.c (w32_read_socket, x_new_font): Rewrite with
new macro FRAME_TOOLTIP_P.
* src/w32term.h (tip_window): Add external declaration.
* src/xdisp.c (x_consider_frame_title, prepare_menu_bars)
(should_produce_line_number): Rewrite with new macro
FRAME_TOOLTIP_P.
(note_mode_line_or_margin_highlight): If
`mode-line-default-help-echo' specifies a function, call it to
produce help echo string.
* src/xfns.c (x_make_monitor_attribute_list)
(Fx_display_monitor_attributes_list): Rewrite with
new macro FRAME_TOOLTIP_P.
(tip_last_string, tip_last_frame, tip_last_parms): New Lisp
scalars replacing Lisp vector last_show_tip_args.
(x_create_tip_frame): Set new frame's 'tooltip' structure
member to true.
(x_hide_tip): Rewrite with additional tests of frames for
liveness and taking into account that for GTK+ tips the
reference frame is now stored in tip_last_frame instead of
tip_frame.
(Fx_show_tip): Handle last_show_tip_args to tip_last_frame,
tip_last_string and tip_last_parms conversion.  For GTK+ store
FRAME argument in tip_last-frame.
(syms_of_xfns): staticpro tip_last_frame, tip_last_string
and tip_last_parms instead of last_show_tip_args.
* src/xterm.c (x_update_begin, handle_one_xevent, x_new_font)
(x_set_window_size): Rewrite with new macro FRAME_TOOLTIP_P.
* src/xterm.h (tip_window): Add external declaration.
* etc/NEWS: Mention new modeline tooltips behavior.
parent 6e9f20b3
......@@ -58,6 +58,12 @@ on GUI frames when tooltips are displayed in the echo area. Instead,
it resizes the echo area as needed to accommodate the full tool-tip
text.
---
** Show modeline tooltips only if the corresponding action applies.
Customize the option 'mode-line-default-help-echo' to restore the old
behavior where the tooltip text is also shown when the corresponding
action does not apply.
+++
** New function 'logcount' calculates an integer's Hamming weight.
......
......@@ -124,17 +124,58 @@ corresponding to the mode line clicked."
;;; Mode line contents
(defcustom mode-line-default-help-echo
"mouse-1: Select (drag to resize)\n\
mouse-2: Make current window occupy the whole frame\n\
mouse-3: Remove current window from display"
(defun mode-line-default-help-echo (window)
"Return default help echo text for WINDOW's mode-line."
(let* ((frame (window-frame window))
(line-1a
;; Show text to select window only if the window is not
;; selected.
(not (eq window (frame-selected-window frame))))
(line-1b
;; Show text to drag modeline if and only if it can be done.
(or (window-in-direction 'below window)
(let ((mini-window (minibuffer-window frame)))
(and (eq frame (window-frame mini-window))
(or (minibuffer-window-active-p mini-window)
(not resize-mini-windows))))))
(line-2
;; Show text make window occupy the whole frame
;; only if it doesn't already do that.
(not (eq window (frame-root-window frame))))
(line-3
;; Show text to delete window only if that's possible.
(not (eq window (frame-root-window frame)))))
(when (or line-1a line-1b line-2 line-3)
(concat
(when (or line-1a line-1b)
(concat
"mouse-1: "
(when line-1a "Select window")
(when line-1b
(if line-1a " (drag to resize)" "Drag to resize"))
(when (or line-2 line-3) "\n")))
(when line-2
(concat
"mouse-2: Make window occupy whole frame"
(when line-3 "\n")))
(when line-3
"mouse-3: Remove window from frame")))))
(defcustom mode-line-default-help-echo #'mode-line-default-help-echo
"Default help text for the mode line.
If the value is a string, it specifies the tooltip or echo area
message to display when the mouse is moved over the mode line.
If the text at the mouse position has a `help-echo' text
property, that overrides this variable."
:type '(choice (const :tag "No help" :value nil) string)
:version "24.3"
If the value is a function, call that function with one argument
- the window whose mode-line to display. If the text at the
mouse position has a `help-echo' text property, that overrides
this variable."
:type '(choice
(const :tag "No help" :value nil)
function
(string :value "mouse-1: Select (drag to resize)\n\
mouse-2: Make current window occupy the whole frame\n\
mouse-3: Remove current window from display"))
:version "27.1"
:group 'mode-line)
(defvar mode-line-front-space '(:eval (if (display-graphic-p) " " "-"))
......
......@@ -3452,15 +3452,6 @@ void gamma_correct (struct frame *, COLORREF *);
void x_implicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
void x_change_tool_bar_height (struct frame *f, int);
/* The frame used to display a tooltip.
Note: In a GTK build with non-zero x_gtk_use_system_tooltips, this
variable holds the frame that shows the tooltip, not the frame of
the tooltip itself, so checking whether a frame is a tooltip frame
cannot just compare the frame to what this variable holds. */
extern Lisp_Object tip_frame;
extern Window tip_window;
extern frame_parm_handler x_frame_parm_handlers[];
extern void start_hourglass (void);
......
......@@ -832,6 +832,7 @@ make_frame (bool mini_p)
f->no_focus_on_map = false;
f->no_accept_focus = false;
f->z_group = z_group_none;
f->tooltip = false;
#if ! defined (USE_GTK) && ! defined (HAVE_NS)
f->last_tool_bar_item = -1;
#endif
......@@ -1467,20 +1468,21 @@ DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
DEFUN ("frame-list", Fframe_list, Sframe_list,
0, 0, 0,
doc: /* Return a list of all live frames. */)
doc: /* Return a list of all live frames.
The return value does not include any tooltip frame. */)
(void)
{
Lisp_Object frames;
frames = Fcopy_sequence (Vframe_list);
#ifdef HAVE_WINDOW_SYSTEM
if (FRAMEP (tip_frame)
#ifdef USE_GTK
&& !NILP (Fframe_parameter (tip_frame, Qtooltip))
#endif
)
frames = Fdelq (tip_frame, frames);
#endif
return frames;
Lisp_Object list = Qnil, tail, frame;
FOR_EACH_FRAME (tail, frame)
if (!FRAME_TOOLTIP_P (XFRAME (frame)))
list = Fcons (frame, list);
/* Reverse list for consistency with the !HAVE_WINDOW_SYSTEM case. */
return Fnreverse (list);
#else /* !HAVE_WINDOW_SYSTEM */
return Fcopy_sequence (Vframe_list);
#endif /* HAVE_WINDOW_SYSTEM */
}
DEFUN ("frame-parent", Fframe_parent, Sframe_parent,
......@@ -1711,7 +1713,8 @@ DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
* other_frames:
*
* Return true if there exists at least one visible or iconified frame
* but F. Return false otherwise.
* but F. Tooltip frames do not qualify as candidates. Return false
* if no such frame exists.
*
* INVISIBLE true means we are called from make_frame_invisible where
* such a frame must be visible or iconified. INVISIBLE nil means we
......@@ -1725,7 +1728,6 @@ static bool
other_frames (struct frame *f, bool invisible, bool force)
{
Lisp_Object frames, frame, frame1;
struct frame *f1;
Lisp_Object minibuffer_window = FRAME_MINIBUF_WINDOW (f);
XSETFRAME (frame, f);
......@@ -1735,7 +1737,8 @@ other_frames (struct frame *f, bool invisible, bool force)
FOR_EACH_FRAME (frames, frame1)
{
f1 = XFRAME (frame1);
struct frame *f1 = XFRAME (frame1);
if (f != f1)
{
/* Verify that we can still talk to the frame's X window, and
......@@ -1744,7 +1747,7 @@ other_frames (struct frame *f, bool invisible, bool force)
if (FRAME_WINDOW_P (f1))
x_sync (f1);
#endif
if (NILP (Fframe_parameter (frame1, Qtooltip))
if (!FRAME_TOOLTIP_P (f1)
/* Tooltips and child frames count neither for
invisibility nor for deletions. */
&& !FRAME_PARENT_FRAME (f1)
......@@ -1877,7 +1880,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
}
}
is_tooltip_frame = !NILP (Fframe_parameter (frame, Qtooltip));
is_tooltip_frame = FRAME_TOOLTIP_P (f);
/* Run `delete-frame-functions' unless FORCE is `noelisp' or
frame is a tooltip. FORCE is set to `noelisp' when handling
......@@ -1925,27 +1928,31 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
Do not call next_frame here because it may loop forever.
See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=15025. */
FOR_EACH_FRAME (tail, frame1)
if (!EQ (frame, frame1)
&& NILP (Fframe_parameter (frame1, Qtooltip))
&& (FRAME_TERMINAL (XFRAME (frame))
== FRAME_TERMINAL (XFRAME (frame1)))
&& FRAME_VISIBLE_P (XFRAME (frame1)))
break;
{
struct frame *f1 = XFRAME (frame1);
if (!EQ (frame, frame1)
&& !FRAME_TOOLTIP_P (f1)
&& FRAME_TERMINAL (f) == FRAME_TERMINAL (f1)
&& FRAME_VISIBLE_P (f1))
break;
}
/* If there is none, find *some* other frame. */
if (NILP (frame1) || EQ (frame1, frame))
{
FOR_EACH_FRAME (tail, frame1)
{
struct frame *f1 = XFRAME (frame1);
if (!EQ (frame, frame1)
&& FRAME_LIVE_P (XFRAME (frame1))
&& NILP (Fframe_parameter (frame1, Qtooltip)))
&& FRAME_LIVE_P (f1)
&& !FRAME_TOOLTIP_P (f1))
{
/* Do not change a text terminal's top-frame. */
struct frame *f1 = XFRAME (frame1);
if (FRAME_TERMCAP_P (f1) || FRAME_MSDOS_P (f1))
{
Lisp_Object top_frame = FRAME_TTY (f1)->top_frame;
if (!EQ (top_frame, frame))
frame1 = top_frame;
}
......
......@@ -342,6 +342,9 @@ struct frame
ENUM_BF (output_method) output_method : 3;
#ifdef HAVE_WINDOW_SYSTEM
/* True if this frame is a tooltip frame. */
bool_bf tooltip : 1;
/* See FULLSCREEN_ enum on top. */
ENUM_BF (fullscreen_type) want_fullscreen : 4;
......@@ -351,9 +354,7 @@ struct frame
/* Nonzero if we should actually display horizontal scroll bars on this frame. */
bool_bf horizontal_scroll_bars : 1;
#endif /* HAVE_WINDOW_SYSTEM */
#if defined (HAVE_WINDOW_SYSTEM)
/* True if this is an undecorated frame. */
bool_bf undecorated : 1;
......@@ -967,6 +968,7 @@ default_pixels_per_inch_y (void)
#define FRAME_Z_GROUP_ABOVE_SUSPENDED(f) \
((f)->z_group == z_group_above_suspended)
#define FRAME_Z_GROUP_BELOW(f) ((f)->z_group == z_group_below)
#define FRAME_TOOLTIP_P(f) ((f)->tooltip)
#ifdef NS_IMPL_COCOA
#define FRAME_NS_APPEARANCE(f) ((f)->ns_appearance)
#define FRAME_NS_TRANSPARENT_TITLEBAR(f) ((f)->ns_transparent_titlebar)
......@@ -983,6 +985,7 @@ default_pixels_per_inch_y (void)
#define FRAME_Z_GROUP_NONE(f) ((void) (f), true)
#define FRAME_Z_GROUP_ABOVE(f) ((void) (f), false)
#define FRAME_Z_GROUP_BELOW(f) ((void) (f), false)
#define FRAME_TOOLTIP_P(f) ((void) f, false)
#endif /* HAVE_WINDOW_SYSTEM */
/* Whether horizontal scroll bars are currently enabled for frame F. */
......
......@@ -687,6 +687,7 @@ qttip_cb (GtkWidget *widget,
g_signal_connect (x->ttip_lbl, "hierarchy-changed",
G_CALLBACK (hierarchy_ch_cb), f);
}
return FALSE;
}
......@@ -713,7 +714,8 @@ xg_prepare_tooltip (struct frame *f,
GtkRequisition req;
Lisp_Object encoded_string;
if (!x->ttip_lbl) return 0;
if (!x->ttip_lbl)
return FALSE;
block_input ();
encoded_string = ENCODE_UTF_8 (string);
......@@ -745,7 +747,7 @@ xg_prepare_tooltip (struct frame *f,
unblock_input ();
return 1;
return TRUE;
#endif /* USE_GTK_TOOLTIP */
}
......@@ -768,18 +770,18 @@ xg_show_tooltip (struct frame *f, int root_x, int root_y)
#endif
}
/* Hide tooltip if shown. Do nothing if not shown.
Return true if tip was hidden, false if not (i.e. not using
system tooltips). */
bool
xg_hide_tooltip (struct frame *f)
{
bool ret = 0;
#ifdef USE_GTK_TOOLTIP
if (f->output_data.x->ttip_window)
{
GtkWindow *win = f->output_data.x->ttip_window;
block_input ();
gtk_widget_hide (GTK_WIDGET (win));
......@@ -792,10 +794,10 @@ xg_hide_tooltip (struct frame *f)
}
unblock_input ();
ret = 1;
return TRUE;
}
#endif
return ret;
return FALSE;
}
......
......@@ -2753,10 +2753,6 @@ and GNUstep implementations ("distributor-specific release
return make_number (1 << min (dpyinfo->n_planes, 24));
}
/* Unused dummy def needed for compatibility. */
Lisp_Object tip_frame;
/* TODO: move to xdisp or similar */
static void
compute_tip_xy (struct frame *f,
......
......@@ -6423,7 +6423,7 @@ w32_display_monitor_attributes_list (void)
{
struct frame *f = XFRAME (frame);
if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
{
HMONITOR monitor =
monitor_from_window_fn (FRAME_W32_WINDOW (f),
......@@ -6510,7 +6510,7 @@ w32_display_monitor_attributes_list_fallback (struct w32_display_info *dpyinfo)
{
struct frame *f = XFRAME (frame);
if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
if (FRAME_W32_P (f) && !FRAME_TOOLTIP_P (f))
frames = Fcons (frame, frames);
}
attributes = Fcons (Fcons (Qframes, frames), attributes);
......@@ -6916,20 +6916,25 @@ no value of TYPE (always string in the MS Windows case). */)
static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
Lisp_Object, int, int, int *, int *);
/* The frame of a currently visible tooltip. */
/* The frame of the currently visible tooltip. */
Lisp_Object tip_frame;
/* If non-nil, a timer started that hides the last tooltip when it
fires. */
/* The window-system window corresponding to the frame of the
currently visible tooltip. */
Window tip_window;
/* A timer that hides or deletes the currently visible tooltip when it
fires. */
Lisp_Object tip_timer;
Window tip_window;
/* If non-nil, a vector of 3 elements containing the last args
with which x-show-tip was called. See there. */
/* STRING argument of last `x-show-tip' call. */
Lisp_Object tip_last_string;
Lisp_Object last_show_tip_args;
/* FRAME argument of last `x-show-tip' call. */
Lisp_Object tip_last_frame;
/* PARMS argument of last `x-show-tip' call. */
Lisp_Object tip_last_parms;
static void
......@@ -7002,6 +7007,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms)
FRAME_FONTSET (f) = -1;
fset_icon_name (f, Qnil);
f->tooltip = true;
#ifdef GLYPH_DEBUG
image_cache_refcount =
......@@ -7261,7 +7267,17 @@ compute_tip_xy (struct frame *f,
*root_x = min_x;
}
/* Hide tooltip. Delete its frame if DELETE is true. */
/**
* x_hide_tip:
*
* Hide currently visible tooltip and cancel its timer.
*
* This will try to make tooltip_frame invisible (if DELETE is false)
* or delete tooltip_frame (if DELETE is true).
*
* Return Qt if the tooltip was either deleted or made invisible, Qnil
* otherwise.
*/
static Lisp_Object
x_hide_tip (bool delete)
{
......@@ -7286,15 +7302,20 @@ x_hide_tip (bool delete)
if (FRAMEP (tip_frame))
{
if (delete)
if (FRAME_LIVE_P (XFRAME (tip_frame)))
{
delete_frame (tip_frame, Qnil);
tip_frame = Qnil;
if (delete)
{
delete_frame (tip_frame, Qnil);
tip_frame = Qnil;
}
else
x_make_frame_invisible (XFRAME (tip_frame));
was_open = Qt;
}
else
x_make_frame_invisible (XFRAME (tip_frame));
was_open = Qt;
tip_frame = Qnil;
}
else
tip_frame = Qnil;
......@@ -7334,7 +7355,8 @@ with offset DY added (default is -10).
A tooltip's maximum size is specified by `x-max-tooltip-size'.
Text larger than the specified size is clipped. */)
(Lisp_Object string, Lisp_Object frame, Lisp_Object parms, Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
(Lisp_Object string, Lisp_Object frame, Lisp_Object parms,
Lisp_Object timeout, Lisp_Object dx, Lisp_Object dy)
{
struct frame *tip_f;
struct window *w;
......@@ -7345,8 +7367,7 @@ Text larger than the specified size is clipped. */)
int old_windows_or_buffers_changed = windows_or_buffers_changed;
ptrdiff_t count = SPECPDL_INDEX ();
ptrdiff_t count_1;
Lisp_Object window, size;
Lisp_Object tip_buf;
Lisp_Object window, size, tip_buf;
AUTO_STRING (tip, " *tip*");
specbind (Qinhibit_redisplay, Qt);
......@@ -7368,19 +7389,12 @@ Text larger than the specified size is clipped. */)
else
CHECK_NUMBER (dy);
if (NILP (last_show_tip_args))
last_show_tip_args = Fmake_vector (make_number (3), Qnil);
if (FRAMEP (tip_frame) && FRAME_LIVE_P (XFRAME (tip_frame)))
{
Lisp_Object last_string = AREF (last_show_tip_args, 0);
Lisp_Object last_frame = AREF (last_show_tip_args, 1);
Lisp_Object last_parms = AREF (last_show_tip_args, 2);
if (FRAME_VISIBLE_P (XFRAME (tip_frame))
&& EQ (frame, last_frame)
&& !NILP (Fequal_including_properties (last_string, string))
&& !NILP (Fequal (last_parms, parms)))
&& EQ (frame, tip_last_frame)
&& !NILP (Fequal_including_properties (string, tip_last_string))
&& !NILP (Fequal (parms, tip_last_parms)))
{
/* Only DX and DY have changed. */
tip_f = XFRAME (tip_frame);
......@@ -7414,14 +7428,14 @@ Text larger than the specified size is clipped. */)
goto start_timer;
}
else if (tooltip_reuse_hidden_frame && EQ (frame, last_frame))
else if (tooltip_reuse_hidden_frame && EQ (frame, tip_last_frame))
{
bool delete = false;
Lisp_Object tail, elt, parm, last;
/* Check if every parameter in PARMS has the same value in
last_parms. This may destruct last_parms which, however,
will be recreated below. */
tip_last_parms. This may destruct tip_last_parms
which, however, will be recreated below. */
for (tail = parms; CONSP (tail); tail = XCDR (tail))
{
elt = XCAR (tail);
......@@ -7431,7 +7445,7 @@ Text larger than the specified size is clipped. */)
if (!EQ (parm, Qleft) && !EQ (parm, Qtop)
&& !EQ (parm, Qright) && !EQ (parm, Qbottom))
{
last = Fassq (parm, last_parms);
last = Fassq (parm, tip_last_parms);
if (NILP (Fequal (Fcdr (elt), Fcdr (last))))
{
/* We lost, delete the old tooltip. */
......@@ -7439,15 +7453,17 @@ Text larger than the specified size is clipped. */)
break;
}
else
last_parms = call2 (Qassq_delete_all, parm, last_parms);
tip_last_parms =
call2 (Qassq_delete_all, parm, tip_last_parms);
}
else
last_parms = call2 (Qassq_delete_all, parm, last_parms);
tip_last_parms =
call2 (Qassq_delete_all, parm, tip_last_parms);
}
/* Now check if there's a parameter left in last_parms with a
/* Now check if there's a parameter left in tip_last_parms with a
non-nil value. */
for (tail = last_parms; CONSP (tail); tail = XCDR (tail))
for (tail = tip_last_parms; CONSP (tail); tail = XCDR (tail))
{
elt = XCAR (tail);
parm = Fcar (elt);
......@@ -7468,9 +7484,9 @@ Text larger than the specified size is clipped. */)
else
x_hide_tip (true);
ASET (last_show_tip_args, 0, string);
ASET (last_show_tip_args, 1, frame);
ASET (last_show_tip_args, 2, parms);
tip_last_frame = frame;
tip_last_string = string;
tip_last_parms = parms;
/* Block input until the tip has been fully drawn, to avoid crashes
when drawing tips in menus. */
......@@ -7486,7 +7502,8 @@ Text larger than the specified size is clipped. */)
if (NILP (Fassq (Qborder_width, parms)))
parms = Fcons (Fcons (Qborder_width, make_number (1)), parms);
if (NILP (Fassq (Qborder_color, parms)))
parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")), parms);
parms = Fcons (Fcons (Qborder_color, build_string ("lightyellow")),
parms);
if (NILP (Fassq (Qbackground_color, parms)))
parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
parms);
......@@ -10695,9 +10712,12 @@ tip frame. */);
staticpro (&tip_timer);
tip_frame = Qnil;
staticpro (&tip_frame);
last_show_tip_args = Qnil;
staticpro (&last_show_tip_args);
tip_last_frame = Qnil;
staticpro (&tip_last_frame);
tip_last_string = Qnil;
staticpro (&tip_last_string);
tip_last_parms = Qnil;
staticpro (&tip_last_parms);
defsubr (&Sx_file_dialog);
#ifdef WINDOWSNT
......
......@@ -5569,7 +5569,7 @@ w32_read_socket (struct terminal *terminal,
struct frame *f = XFRAME (frame);
/* The tooltip has been drawn already. Avoid the
SET_FRAME_GARBAGED below. */
if (EQ (frame, tip_frame))
if (FRAME_TOOLTIP_P (f))
continue;
/* Check "visible" frames and mark each as obscured or not.
......@@ -6046,7 +6046,7 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
/* Don't change the size of a tip frame; there's no point in
doing it because it's done in Fx_show_tip, and it leads to
problems because the tip frame has no widget. */
if (NILP (tip_frame) || XFRAME (tip_frame) != f)
if (!FRAME_TOOLTIP_P (f))
adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 3,
false, Qfont);
......
......@@ -817,6 +817,8 @@ extern struct window *w32_system_caret_window;
extern int w32_system_caret_hdr_height;
extern int w32_system_caret_mode_height;
extern Window tip_window;
#ifdef _MSC_VER
#ifndef EnumSystemLocales
/* MSVC headers define these only for _WIN32_WINNT >= 0x0500. */
......
......@@ -11866,7 +11866,7 @@ x_consider_frame_title (Lisp_Object frame)
if ((FRAME_WINDOW_P (f)
|| FRAME_MINIBUF_ONLY_P (f)
|| f->explicit_name)
&& NILP (Fframe_parameter (frame, Qtooltip)))
&& !FRAME_TOOLTIP_P (f))
{
/* Do we have more than one visible frame on this X display? */
Lisp_Object tail, other_frame, fmt;
......@@ -11883,8 +11883,8 @@ x_consider_frame_title (Lisp_Object frame)
if (tf != f
&& FRAME_KBOARD (tf) == FRAME_KBOARD (f)
&& !FRAME_MINIBUF_ONLY_P (tf)
&& !EQ (other_frame, tip_frame)
&& !FRAME_PARENT_FRAME (tf)
&& !FRAME_TOOLTIP_P (tf)
&& (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
break;
}
......@@ -11953,13 +11953,6 @@ prepare_menu_bars (void)
{
bool all_windows = windows_or_buffers_changed || update_mode_lines;
bool some_windows = REDISPLAY_SOME_P ();
Lisp_Object tooltip_frame;
#ifdef HAVE_WINDOW_SYSTEM
tooltip_frame = tip_frame;
#else
tooltip_frame = Qnil;
#endif
if (FUNCTIONP (Vpre_redisplay_function))
{
......@@ -12000,7 +11993,7 @@ prepare_menu_bars (void)
&& !XBUFFER (w->contents)->text->redisplay)
continue;
if (!EQ (frame, tooltip_frame)
if (!FRAME_TOOLTIP_P (f)
&& !FRAME_PARENT_FRAME (f)
&& (FRAME_ICONIFIED_P (f)
|| FRAME_VISIBLE_P (f) == 1
......@@ -12038,7 +12031,7 @@ prepare_menu_bars (void)
struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
/* Ignore tooltip frame. */
if (EQ (frame, tooltip_frame))
if (FRAME_TOOLTIP_P (f))
continue;
if (some_windows
......@@ -21160,13 +21153,7 @@ should_produce_line_number (struct it *it)
#ifdef HAVE_WINDOW_SYSTEM
/* Don't display line number in tooltip frames. */
if (FRAMEP (tip_frame) && EQ (WINDOW_FRAME (it->w), tip_frame)
#ifdef USE_GTK
/* GTK builds store in tip_frame the frame that shows the tip,
so we need an additional test. */
&& !NILP (Fframe_parameter (tip_frame, Qtooltip))
#endif
)
if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
return false;
#endif
......@@ -30841,9 +30828,11 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
= buffer_local_value (Qmode_line_default_help_echo,
w->contents);
if (STRINGP (default_help))
if (FUNCTIONP (default_help) || STRINGP (default_help))
{
help_echo_string = 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;
......@@ -4612,8 +4612,9 @@ x_make_monitor_attribute_list (struct MonitorInfo *monitors,
{
struct frame *f = XFRAME (frame);
if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
&& !EQ (frame, tip_frame))
if (FRAME_X_P (f)
&& FRAME_DISPLAY_INFO (f) == dpyinfo
&& !FRAME_TOOLTIP_P (f))
{
int i = x_get_monitor_for_frame (f, monitors, n_monitors);
ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
......@@ -4914,12 +4915,9 @@ Internal use only, use `display-monitor-attributes-list' instead. */)
{
struct frame *f = XFRAME (frame);
if (FRAME_X_P (f) && FRAME_DISPLAY_INFO (f) == dpyinfo
&& !(EQ (frame, tip_frame)
#ifdef USE_GTK
&& !NILP (Fframe_parameter (tip_frame, Qtooltip))
#endif
))
if (FRAME_X_P (f)
&& FRAME_DISPLAY_INFO (f) == dpyinfo