Resurrect mouse-highlight of close buttons on tab-bar

* src/w32term.c (w32_draw_image_relief): Support tab-bar drawing
with relief as xterm.c does.

* src/xdisp.c (handle_tab_bar_click): Access the mouse-highlight
info.  Call show_mouse_face to show the button in the pressed or
the released state, according to value of DOWN_P.
(note_tab_bar_highlight): Function added back.
(note_mouse_highlight): Call note_tab_bar_highlight when the mouse
pointer is in the tab-bar window.
(show_mouse_face): Return immediately if mouse_face_window is not
set up in HLINFO.  This avoids rare assertion violations.
This commit is contained in:
Eli Zaretskii 2021-04-13 16:40:42 +03:00
parent 6de79542e4
commit 1667253fec
2 changed files with 131 additions and 5 deletions

View file

@ -2031,8 +2031,11 @@ w32_draw_image_relief (struct glyph_string *s)
if (s->hl == DRAW_IMAGE_SUNKEN
|| s->hl == DRAW_IMAGE_RAISED)
{
thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF;
thick = (tab_bar_button_relief < 0
? DEFAULT_TAB_BAR_BUTTON_RELIEF
: (tool_bar_button_relief < 0
? DEFAULT_TOOL_BAR_BUTTON_RELIEF
: min (tool_bar_button_relief, 1000000)));
raised_p = s->hl == DRAW_IMAGE_RAISED;
}
else
@ -2045,6 +2048,19 @@ w32_draw_image_relief (struct glyph_string *s)
y1 = y + s->slice.height - 1;
extra_x = extra_y = 0;
if (s->face->id == TAB_BAR_FACE_ID)
{
if (CONSP (Vtab_bar_button_margin)
&& FIXNUMP (XCAR (Vtab_bar_button_margin))
&& FIXNUMP (XCDR (Vtab_bar_button_margin)))
{
extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin));
extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin));
}
else if (FIXNUMP (Vtab_bar_button_margin))
extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin);
}
if (s->face->id == TOOL_BAR_FACE_ID)
{
if (CONSP (Vtool_bar_button_margin)

View file

@ -13682,6 +13682,7 @@ void
handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
int modifiers)
{
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
struct window *w = XWINDOW (f->tab_bar_window);
int hpos, vpos, prop_idx;
bool close_p;
@ -13703,13 +13704,22 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
return;
if (down_p)
f->last_tab_bar_item = prop_idx; /* record the pressed tab */
{
/* Show the clicked button in pressed state. */
if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
f->last_tab_bar_item = prop_idx; /* record the pressed tab */
}
else
{
Lisp_Object key, frame;
struct input_event event;
EVENT_INIT (event);
/* Show item in released state. */
if (!NILP (Vmouse_highlight))
show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
key = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY);
XSETFRAME (frame, f);
@ -13722,6 +13732,97 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
}
}
/* Possibly highlight a tab-bar item on frame F when mouse moves to
tab-bar window-relative coordinates X/Y. Called from
note_mouse_highlight. */
static void
note_tab_bar_highlight (struct frame *f, int x, int y)
{
Lisp_Object window = f->tab_bar_window;
struct window *w = XWINDOW (window);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
int hpos, vpos;
struct glyph *glyph;
struct glyph_row *row;
int i;
Lisp_Object enabled_p;
int prop_idx;
bool close_p;
enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
int rc;
/* Function note_mouse_highlight is called with negative X/Y
values when mouse moves outside of the frame. */
if (x <= 0 || y <= 0)
{
clear_mouse_face (hlinfo);
return;
}
rc = get_tab_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx, &close_p);
if (rc < 0)
{
/* Not on tab-bar item. */
clear_mouse_face (hlinfo);
return;
}
else if (rc == 0)
/* On same tab-bar item as before. */
goto set_help_echo;
clear_mouse_face (hlinfo);
bool mouse_down_p = false;
#ifndef HAVE_NS
/* Mouse is down, but on different tab-bar item? */
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
mouse_down_p = (gui_mouse_grabbed (dpyinfo)
&& f == dpyinfo->last_mouse_frame);
if (mouse_down_p && f->last_tab_bar_item != prop_idx)
return;
#endif
draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
/* If tab-bar item is not enabled, don't highlight it. */
enabled_p = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_ENABLED_P);
if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
{
/* Compute the x-position of the glyph. In front and past the
image is a space. We include this in the highlighted area. */
row = MATRIX_ROW (w->current_matrix, vpos);
for (i = x = 0; i < hpos; ++i)
x += row->glyphs[TEXT_AREA][i].pixel_width;
/* Record this as the current active region. */
hlinfo->mouse_face_beg_col = hpos;
hlinfo->mouse_face_beg_row = vpos;
hlinfo->mouse_face_beg_x = x;
hlinfo->mouse_face_past_end = false;
hlinfo->mouse_face_end_col = hpos + 1;
hlinfo->mouse_face_end_row = vpos;
hlinfo->mouse_face_end_x = x + glyph->pixel_width;
hlinfo->mouse_face_window = window;
hlinfo->mouse_face_face_id = TAB_BAR_FACE_ID;
/* Display it as active. */
show_mouse_face (hlinfo, draw);
}
set_help_echo:
/* Set help_echo_string to a help string to display for this tab-bar item.
XTread_socket does the rest. */
help_echo_object = help_echo_window = Qnil;
help_echo_pos = -1;
help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_HELP);
if (NILP (help_echo_string))
help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_CAPTION);
}
#endif /* HAVE_WINDOW_SYSTEM */
/* Find the tab-bar item at X coordinate and return its information. */
@ -31860,6 +31961,11 @@ draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
static void
show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
{
/* Don't bother doing anything if the mouse-face window is not set
up. */
if (!WINDOWP (hlinfo->mouse_face_window))
return;
struct window *w = XWINDOW (hlinfo->mouse_face_window);
struct frame *f = XFRAME (WINDOW_FRAME (w));
@ -33414,9 +33520,13 @@ note_mouse_highlight (struct frame *f, int x, int y)
frame_to_window_pixel_xy (w, &x, &y);
#if defined (HAVE_WINDOW_SYSTEM)
/* We don't highlight tab-bar buttons. */
/* Handle tab-bar window differently since it doesn't display a
buffer. */
if (EQ (window, f->tab_bar_window))
return;
{
note_tab_bar_highlight (f, x, y);
return;
}
#endif
#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_TOOL_BAR)