mouse-face properties on tab-bar tab captions (bug#76394)
* etc/NEWS: Announce 'tab-bar' 'mouse-face' support. * src/xdisp.c (note_tab_bar_highlight): Handle mouse-face property. * lisp/tab-bar.el (tab-bar-tab-highlight): New face. (tab-bar-tab-name-format-mouse-face): New function adds the 'mouse-face' 'tab-bar-tab-highlight' to the tab name. (tab-bar-tab-name-format-functions): Add 'tab-bar-tab-name-format-mouse-face'.
This commit is contained in:
parent
63cc542b94
commit
efd483cf0e
3 changed files with 137 additions and 18 deletions
6
etc/NEWS
6
etc/NEWS
|
@ -289,6 +289,12 @@ specified by external means.
|
|||
*** New abnormal hook 'tab-bar-auto-width-functions'.
|
||||
This hook allows you to control which tab-bar tabs are auto-resized.
|
||||
|
||||
---
|
||||
*** 'mouse-face' properties are now supported on the 'tab-bar'.
|
||||
'tab-bar' tab "buttons" are now highlighted when the mouse pointer
|
||||
hovers over them. You can customize the new face
|
||||
'tab-bar-tab-highlight'.
|
||||
|
||||
---
|
||||
*** New abnormal hook 'tab-bar-post-undo-close-tab-functions'.
|
||||
This hook allows you to operate on a reopened tab.
|
||||
|
|
|
@ -85,6 +85,16 @@
|
|||
:version "28.1"
|
||||
:group 'tab-bar-faces)
|
||||
|
||||
(defface tab-bar-tab-highlight
|
||||
'((((class color) (min-colors 88))
|
||||
:box (:line-width 1 :style released-button)
|
||||
:background "grey85"
|
||||
:foreground "black")
|
||||
(t :inverse-video nil))
|
||||
"Tab bar face for highlighting."
|
||||
:version "31.1"
|
||||
:group 'tab-bar-faces)
|
||||
|
||||
|
||||
|
||||
(defvar tab-bar-mode-map (make-sparse-keymap)
|
||||
|
@ -886,10 +896,15 @@ It uses the function `tab-bar-tab-face-function'."
|
|||
0 (length name) (funcall tab-bar-tab-face-function tab) t name)
|
||||
name)
|
||||
|
||||
(defun tab-bar-tab-name-format-mouse-face (name _tab _i)
|
||||
"Apply the `mouse-face' `tab-bar-tab-highlight' to the tab name."
|
||||
(propertize name 'mouse-face 'tab-bar-tab-highlight))
|
||||
|
||||
(defcustom tab-bar-tab-name-format-functions
|
||||
'(tab-bar-tab-name-format-hints
|
||||
tab-bar-tab-name-format-close-button
|
||||
tab-bar-tab-name-format-face)
|
||||
tab-bar-tab-name-format-face
|
||||
tab-bar-tab-name-format-mouse-face)
|
||||
"Functions called to modify the tab name.
|
||||
Each function is called with three arguments: the name returned
|
||||
by the previously called modifier, the tab and its number.
|
||||
|
@ -899,6 +914,7 @@ It should return the formatted tab name to display in the tab bar."
|
|||
(function-item tab-bar-tab-name-format-hints)
|
||||
(function-item tab-bar-tab-name-format-close-button)
|
||||
(function-item tab-bar-tab-name-format-face)
|
||||
(function-item tab-bar-tab-name-format-mouse-face)
|
||||
(function :tag "Custom function")))
|
||||
:group 'tab-bar
|
||||
:version "30.1")
|
||||
|
|
131
src/xdisp.c
131
src/xdisp.c
|
@ -15084,7 +15084,6 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
|
|||
return Fcons (Qtab_bar, Fcons (caption, make_fixnum (0)));
|
||||
}
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
@ -15096,8 +15095,7 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
|
|||
struct window *w = XWINDOW (window);
|
||||
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
|
||||
int hpos, vpos;
|
||||
struct glyph *glyph;
|
||||
struct glyph_row *row;
|
||||
struct glyph *glyph = NULL;
|
||||
int i;
|
||||
Lisp_Object enabled_p;
|
||||
int prop_idx;
|
||||
|
@ -15143,25 +15141,124 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
|
|||
|
||||
/* 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. */
|
||||
struct glyph_row *row = NULL;
|
||||
struct glyph *row_start_glyph = NULL;
|
||||
struct glyph *tmp_glyph;
|
||||
int total_pixel_width;
|
||||
Lisp_Object string;
|
||||
Lisp_Object mouse_face;
|
||||
int mouse_face_id = -1;
|
||||
int hpos0, hpos_caption;
|
||||
|
||||
row = MATRIX_ROW (w->current_matrix, vpos);
|
||||
for (i = x = 0; i < hpos; ++i)
|
||||
x += row->glyphs[TEXT_AREA][i].pixel_width;
|
||||
/* display_tab_bar does not yet support R2L. */
|
||||
eassert (!row->reversed_p);
|
||||
row_start_glyph = row->glyphs[TEXT_AREA];
|
||||
|
||||
/* 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;
|
||||
string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_CAPTION);
|
||||
if (STRINGP (string))
|
||||
{
|
||||
/* Compute starting column of the tab-bar-item to adjust col
|
||||
of the mouse face relative to row_start_glyph.
|
||||
|
||||
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;
|
||||
tab_bar_item_info does not contain the absolute starting
|
||||
offset of the item. We compute it by looking backwards
|
||||
until we find a glyph that belongs to a previous tab bar
|
||||
item, or if this is the first item. */
|
||||
hpos0 = hpos + 1;
|
||||
int tmp_prop_idx;
|
||||
bool tmp_bool;
|
||||
for (tmp_glyph = glyph;
|
||||
tmp_glyph >= row_start_glyph;
|
||||
tmp_glyph--)
|
||||
{
|
||||
if (!tab_bar_item_info (f, tmp_glyph, &tmp_prop_idx, &tmp_bool)
|
||||
|| tmp_prop_idx != prop_idx)
|
||||
break; /* Just before the beginning of this item. */
|
||||
else
|
||||
--hpos0;
|
||||
}
|
||||
|
||||
/* Offset into the caption vs. the row. */
|
||||
hpos_caption = hpos - hpos0;
|
||||
|
||||
mouse_face = Fget_text_property (make_fixnum (hpos_caption),
|
||||
Qmouse_face, string);
|
||||
if (!NILP (mouse_face))
|
||||
{
|
||||
mouse_face_id = lookup_named_face (w, f, mouse_face, false);
|
||||
if (mouse_face_id < 0)
|
||||
mouse_face_id = compute_char_face (f, ' ', mouse_face);
|
||||
draw = DRAW_MOUSE_FACE;
|
||||
}
|
||||
}
|
||||
|
||||
if (draw == DRAW_MOUSE_FACE)
|
||||
{
|
||||
Lisp_Object b, e;
|
||||
ptrdiff_t begpos, endpos;
|
||||
int beg_x, end_x;
|
||||
|
||||
/* Search for mouse-face boundaries. */
|
||||
b = Fprevious_single_property_change (make_fixnum (hpos_caption + 1),
|
||||
Qmouse_face, string, Qnil);
|
||||
if (NILP (b))
|
||||
begpos = 0;
|
||||
else
|
||||
begpos = XFIXNUM (b);
|
||||
e = Fnext_single_property_change (make_fixnum (begpos), Qmouse_face, string, Qnil);
|
||||
if (NILP (e))
|
||||
endpos = SCHARS (string);
|
||||
else
|
||||
endpos = XFIXNUM (e);
|
||||
|
||||
/* Compute the starting and ending pixel coordinates */
|
||||
for (i = beg_x = 0;
|
||||
i < hpos0 + begpos; ++i)
|
||||
beg_x += row->glyphs[TEXT_AREA][i].pixel_width;
|
||||
for (end_x = 0,
|
||||
i = hpos0 + begpos;
|
||||
i < hpos0 + endpos; ++i)
|
||||
end_x += row->glyphs[TEXT_AREA][i].pixel_width;
|
||||
|
||||
if ( EQ (window, hlinfo->mouse_face_window)
|
||||
&& (hlinfo->mouse_face_beg_col <= hpos
|
||||
&& hpos < hlinfo->mouse_face_end_col)
|
||||
&& hlinfo->mouse_face_beg_row == vpos )
|
||||
return;
|
||||
|
||||
hlinfo->mouse_face_window = window;
|
||||
hlinfo->mouse_face_face_id = mouse_face_id;
|
||||
hlinfo->mouse_face_beg_row = vpos;
|
||||
hlinfo->mouse_face_end_row = vpos;
|
||||
hlinfo->mouse_face_past_end = false;
|
||||
hlinfo->mouse_face_beg_col = hpos0 + begpos;
|
||||
hlinfo->mouse_face_end_col = hpos0 + endpos;
|
||||
hlinfo->mouse_face_beg_x = beg_x;
|
||||
hlinfo->mouse_face_end_x = end_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Compute the x-position of the glyph. In front and past the
|
||||
image is a space. We include this in the highlighted area. */
|
||||
for (i = x = 0; i < hpos; ++i)
|
||||
x += row->glyphs[TEXT_AREA][i].pixel_width;
|
||||
total_pixel_width = glyph->pixel_width;
|
||||
|
||||
hlinfo->mouse_face_face_id = TAB_BAR_FACE_ID;
|
||||
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 + total_pixel_width;
|
||||
hlinfo->mouse_face_window = window;
|
||||
}
|
||||
|
||||
/* Display it as active. */
|
||||
show_mouse_face (hlinfo, draw, true);
|
||||
|
|
Loading…
Add table
Reference in a new issue