From: Eli Zaretskii Date: Tue, 13 Apr 2021 13:40:42 +0000 (+0300) Subject: Resurrect mouse-highlight of close buttons on tab-bar X-Git-Tag: emacs-28.0.90~2868 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=1667253fec963e2ffb2bb36db67564533cf92787;p=emacs.git 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. --- diff --git a/src/w32term.c b/src/w32term.c index 0ee805a8526..361cf33c024 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -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) diff --git a/src/xdisp.c b/src/xdisp.c index 50d9040057a..8f7180381b4 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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)