]> git.eshelyaron.com Git - emacs.git/commitdiff
Resurrect mouse-highlight of close buttons on tab-bar
authorEli Zaretskii <eliz@gnu.org>
Tue, 13 Apr 2021 13:40:42 +0000 (16:40 +0300)
committerEli Zaretskii <eliz@gnu.org>
Tue, 13 Apr 2021 13:40:42 +0000 (16:40 +0300)
* 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.

src/w32term.c
src/xdisp.c

index 0ee805a8526f208624396dc1cae0f954548e4b0c..361cf33c0245d3fed98ee6abdb8838179081bfc7 100644 (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)
index 50d9040057ad33ac6c6b808cd879b4c76c6b4ad7..8f7180381b4390a3efc5f177b7c71a505e01cf4b 100644 (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)