Fix mouse pointer inside mouse-face on text with 'pointer' property

* src/dispnew.c (gui_update_window_end): Don't consider mouse face
overwritten.
* src/xdisp.c (show_mouse_face): Accept an additional argument;
redefine the mouse cursor only if that argument is 'true'.  All
callers changed.  (Bug#75931)
This commit is contained in:
Eli Zaretskii 2025-02-02 08:23:02 +02:00
parent 42f1318e65
commit 354b2907fc
2 changed files with 18 additions and 20 deletions

View file

@ -4597,9 +4597,6 @@ gui_update_window_end (struct window *w, bool cursor_on_p,
w->output_cursor.hpos, w->output_cursor.vpos,
w->output_cursor.x, w->output_cursor.y);
if (cursor_in_mouse_face_p (w) && cursor_on_p)
mouse_face_overwritten_p = 1;
if (draw_window_fringes (w, true))
{
if (WINDOW_RIGHT_DIVIDER_WIDTH (w))

View file

@ -1229,7 +1229,7 @@ static void get_cursor_offset_for_mouse_face (struct window *w,
static void produce_special_glyphs (struct it *, enum display_element_type);
static void pad_mode_line (struct it *, bool);
static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face, bool);
static bool coords_in_mouse_face_p (struct window *, int, int);
static void reset_box_start_end_flags (struct it *);
@ -15052,14 +15052,14 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
{
/* Show the clicked button in pressed state. */
if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN, true);
f->last_tab_bar_item = prop_idx; /* record the pressed tab */
}
else
{
/* Show item in released state. */
if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
show_mouse_face (hlinfo, DRAW_IMAGE_RAISED, true);
f->last_tab_bar_item = -1;
}
@ -15157,7 +15157,7 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
hlinfo->mouse_face_face_id = TAB_BAR_FACE_ID;
/* Display it as active. */
show_mouse_face (hlinfo, draw);
show_mouse_face (hlinfo, draw, true);
}
set_help_echo:
@ -16074,7 +16074,7 @@ handle_tool_bar_click_with_device (struct frame *f, int x, int y, bool down_p,
{
/* Show item in pressed state. */
if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN, true);
f->last_tool_bar_item = prop_idx;
}
else
@ -16085,7 +16085,7 @@ handle_tool_bar_click_with_device (struct frame *f, int x, int y, bool down_p,
/* Show item in released state. */
if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
show_mouse_face (hlinfo, DRAW_IMAGE_RAISED, true);
key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
@ -16181,7 +16181,7 @@ note_tool_bar_highlight (struct frame *f, int x, int y)
hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
/* Display it as active. */
show_mouse_face (hlinfo, draw);
show_mouse_face (hlinfo, draw, true);
}
set_help_echo:
@ -34196,12 +34196,13 @@ erase_phys_cursor (struct window *w)
/* Since erasing the phys cursor will probably lead to corruption of
the mouse face display if the glyph's pixel_width is not kept up
to date with the :box property of the mouse face, just redraw the
mouse face. */
mouse face, but leave the mouse cursor as it was. */
if (FRAME_WINDOW_P (WINDOW_XFRAME (w)) && mouse_face_here_p)
{
w->phys_cursor_on_p = false;
w->phys_cursor_type = NO_CURSOR;
show_mouse_face (MOUSE_HL_INFO (WINDOW_XFRAME (w)), DRAW_MOUSE_FACE);
show_mouse_face (MOUSE_HL_INFO (WINDOW_XFRAME (w)), DRAW_MOUSE_FACE,
false);
return;
}
#endif
@ -34462,7 +34463,8 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
/* Display the active region described by mouse_face_* according to DRAW. */
static void
show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw,
bool define_mouse_cursor)
{
/* Don't bother doing anything if the mouse-face window is not set
up. */
@ -34604,7 +34606,7 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
#ifdef HAVE_WINDOW_SYSTEM
/* Change the mouse cursor. */
if (FRAME_WINDOW_P (f) && NILP (track_mouse))
if (FRAME_WINDOW_P (f) && NILP (track_mouse) && define_mouse_cursor)
{
if (draw == DRAW_NORMAL_TEXT
#ifndef HAVE_EXT_TOOL_BAR
@ -34612,8 +34614,7 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
#endif
&& !EQ (hlinfo->mouse_face_window, f->tab_bar_window))
FRAME_RIF (f)->define_frame_cursor (f, FRAME_OUTPUT_DATA (f)->text_cursor);
else
if (draw == DRAW_MOUSE_FACE)
else if (draw == DRAW_MOUSE_FACE)
FRAME_RIF (f)->define_frame_cursor (f, FRAME_OUTPUT_DATA (f)->hand_cursor);
else
FRAME_RIF (f)->define_frame_cursor (f, FRAME_OUTPUT_DATA (f)->nontext_cursor);
@ -34632,7 +34633,7 @@ clear_mouse_face (Mouse_HLInfo *hlinfo)
bool cleared
= !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
if (cleared)
show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
show_mouse_face (hlinfo, DRAW_NORMAL_TEXT, true);
hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
hlinfo->mouse_face_window = Qnil;
@ -35199,7 +35200,7 @@ mouse_face_from_buffer_pos (Lisp_Object window,
= face_at_buffer_position (w, mouse_charpos, &ignore,
mouse_charpos + 1,
!hlinfo->mouse_face_hidden, -1, 0);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE, true);
}
/* The following function is not used anymore (replaced with
@ -35909,7 +35910,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
face_at_string_position (w, string, charpos, 0, &ignore,
glyph->face_id, true, 0);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE, true);
mouse_face_shown = true;
if (NILP (pointer))
@ -36448,7 +36449,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
hlinfo->mouse_face_face_id
= face_at_string_position (w, object, pos, 0, &ignore,
glyph->face_id, true, 0);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
show_mouse_face (hlinfo, DRAW_MOUSE_FACE, true);
cursor = No_Cursor;
}
else