From a4014c058b547d4f9c8c61c6737c85c2636fdb34 Mon Sep 17 00:00:00 2001 From: Trevor Murphy Date: Thu, 17 Oct 2024 15:51:14 -0700 Subject: [PATCH] Add new `header-line-active' and `header-line-inactive' faces This is all intended to parallel the 'mode-line-active' and 'mode-line-inactive' distinction. * doc/emacs/display.texi (Standard Faces): Document the new faces. * lisp/faces.el (header-line-active, header-line-inactive): New faces. * src/dispextern.h (CURRENT_HEADER_LINE_ACTIVE_FACE_ID_3) (CURRENT_HEADER_LINE_ACTIVE_FACE_ID): New macros based on mode line equivalents. (face_id): New face IDs. * src/xdisp.c (window_box_height, pos_visible_p, init_iterator) (window_text_pixel_size, display_mode_lines, display_mode_line) (format-mode-line): Replace all uses of HEADER_LINE_FACE_ID with either a new macro or the new face IDs. * src/xfaces.c (syms_of_xfaces): New lisp symbols. (lookup_basic_face, realize_basic_faces): Map new face IDs to their lisp symbols. (Bug#73862) --- doc/emacs/display.texi | 16 +++++++++++++++ etc/NEWS | 5 +++++ lisp/faces.el | 15 ++++++++++++++ src/dispextern.h | 33 +++++++++++++++++++++++++++++-- src/xdisp.c | 45 ++++++++++++++++++++++++------------------ src/xfaces.c | 8 ++++++-- 6 files changed, 99 insertions(+), 23 deletions(-) diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 88520874c8e..22cd316f836 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -782,6 +782,22 @@ at the top of a window just as the mode line appears at the bottom. Most windows do not have a header line---only some special modes, such Info mode, create one. +The @code{header-line-active} and @code{header-line-inactive} faces (which +are the ones used on the header lines) inherit from this face. + +@item header-line-active +@cindex faces for header lines +Like @code{header-line}, but used for the header line of the currently +selected window. This face inherits from @code{header-line}, so changes +in that face affect header lines in all windows. + +@item header-line-inactive +@cindex @code{header-line-inactive} face +Like @code{header-line}, but used for header lines of the windows other +than the selected one (if those windows have a header line). This face +inherits from @code{header-line}, so changes in that face affect header +lines in all windows. + @item header-line-highlight @cindex @code{header-line-highlight} face Similar to @code{highlight} and @code{mode-line-highlight}, but used diff --git a/etc/NEWS b/etc/NEWS index fae573ed9de..cb2ba2a78ff 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -162,6 +162,11 @@ The version bundled with Emacs is out-of-date, and is now marked as obsolete. Use 'M-x list-packages' to install the 'idlwave' package from GNU ELPA instead. ++++ +** New face 'header-line-active'. +This inherits from the 'header-line' face, but is the face actually used +on the header lines (along with 'header-line-inactive'). + * Editing Changes in Emacs 31.1 diff --git a/lisp/faces.el b/lisp/faces.el index de4f3a9f92b..af06c943efd 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -2821,6 +2821,21 @@ Use the face `mode-line-highlight' for features that can be selected." :version "28.1" :group 'basic-faces) +(defface header-line-active + '((t :inherit header-line)) + "Face for the selected header line. +This inherits from the `header-line' face." + :version "29.5" + :group 'mode-line-faces + :group 'basic-faces) + +(defface header-line-inactive + '((t :inherit header-line)) + "Basic header line face for non-selected windows." + :version "29.5" + :group 'mode-line-faces + :group 'basic-faces) + (defface vertical-border '((((type tty)) :inherit mode-line-inactive)) "Face used for vertical window dividers on ttys." diff --git a/src/dispextern.h b/src/dispextern.h index 004eb82d87a..9df6eaf623a 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1561,6 +1561,34 @@ struct glyph_string : estimate_mode_line_height \ (XFRAME ((W)->frame), CURRENT_MODE_LINE_ACTIVE_FACE_ID (W))))) +/* Return the desired face id for the header line of a window, depending + on whether the window is selected or not, or if the window is the + scrolling window for the currently active minibuffer window. + + Due to the way display_mode_lines manipulates with the contents of + selected_window, this macro needs three arguments: SELW which is + compared against the current value of selected_window, MBW which is + compared against minibuf_window (if SELW doesn't match), and SCRW + which is compared against minibuf_selected_window (if MBW matches). */ + +#define CURRENT_HEADER_LINE_ACTIVE_FACE_ID_3(SELW, MBW, SCRW) \ + ((!mode_line_in_non_selected_windows \ + || (SELW) == XWINDOW (selected_window) \ + || (minibuf_level > 0 \ + && !NILP (minibuf_selected_window) \ + && (MBW) == XWINDOW (minibuf_window) \ + && (SCRW) == XWINDOW (minibuf_selected_window))) \ + ? HEADER_LINE_ACTIVE_FACE_ID \ + : HEADER_LINE_INACTIVE_FACE_ID) + + +/* Return the desired face id for the header line of window W. */ + +#define CURRENT_HEADER_LINE_ACTIVE_FACE_ID(W) \ + CURRENT_HEADER_LINE_ACTIVE_FACE_ID_3(W, \ + XWINDOW (selected_window), \ + W) + /* Return the current height of the header line of window W. If not known from W->header_line_height, look at W's current glyph matrix, or return an estimation based on the height of the font of the face `header-line'. */ @@ -1572,7 +1600,7 @@ struct glyph_string = (MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \ ? MATRIX_HEADER_LINE_HEIGHT ((W)->current_matrix) \ : estimate_mode_line_height \ - (XFRAME ((W)->frame), HEADER_LINE_FACE_ID)))) + (XFRAME ((W)->frame), CURRENT_HEADER_LINE_ACTIVE_FACE_ID (W))))) /* Return the current height of the tab line of window W. If not known from W->tab_line_height, look at W's current glyph matrix, or return @@ -1893,7 +1921,8 @@ enum face_id MODE_LINE_INACTIVE_FACE_ID, TOOL_BAR_FACE_ID, FRINGE_FACE_ID, - HEADER_LINE_FACE_ID, + HEADER_LINE_ACTIVE_FACE_ID, + HEADER_LINE_INACTIVE_FACE_ID, SCROLL_BAR_FACE_ID, BORDER_FACE_ID, CURSOR_FACE_ID, diff --git a/src/xdisp.c b/src/xdisp.c index 1f28ac43d8b..0fa3c34c314 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1358,7 +1358,7 @@ window_box_height (struct window *w) if (hl_row && hl_row->mode_line_p) height -= hl_row->height; else - height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID); + height -= estimate_mode_line_height (f, CURRENT_HEADER_LINE_ACTIVE_FACE_ID (w)); } } @@ -1753,7 +1753,7 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, = window_parameter (w, Qheader_line_format); w->header_line_height - = display_mode_line (w, HEADER_LINE_FACE_ID, + = display_mode_line (w, CURRENT_HEADER_LINE_ACTIVE_FACE_ID (w), NILP (window_header_line_format) ? BVAR (current_buffer, header_line_format) : window_header_line_format); @@ -3197,13 +3197,14 @@ CHECK_WINDOW_END (struct window *w) BASE_FACE_ID is the id of a base face to use. It must be one of DEFAULT_FACE_ID for normal text, MODE_LINE_ACTIVE_FACE_ID, - MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying - mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar. + MODE_LINE_INACTIVE_FACE_ID, HEADER_LINE_ACTIVE_FACE_ID, or + HEADER_LINE_INACTIVE_FACE_ID for displaying mode lines, or + TOOL_BAR_FACE_ID for displaying the tool-bar. If ROW is null and BASE_FACE_ID is equal to MODE_LINE_ACTIVE_FACE_ID, - MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator - will be initialized to use the corresponding mode line glyph row of - the desired matrix of W. */ + MODE_LINE_INACTIVE_FACE_ID, HEADER_LINE_ACTIVE_FACE_ID, or + HEADER_LINE_INACTIVE_FACE_ID the iterator will be initialized to use + the corresponding mode line glyph row of the desired matrix of W. */ void init_iterator (struct it *it, struct window *w, @@ -3251,7 +3252,8 @@ init_iterator (struct it *it, struct window *w, row = MATRIX_MODE_LINE_ROW (w->desired_matrix); else if (base_face_id == TAB_LINE_FACE_ID) row = MATRIX_TAB_LINE_ROW (w->desired_matrix); - else if (base_face_id == HEADER_LINE_FACE_ID) + else if (base_face_id == HEADER_LINE_ACTIVE_FACE_ID + || base_face_id == HEADER_LINE_INACTIVE_FACE_ID) { /* Header line row depends on whether tab line is enabled. */ w->desired_matrix->tab_line_p = window_wants_tab_line (w); @@ -11854,7 +11856,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object window_header_line_format = window_parameter (w, Qheader_line_format); - y = y + display_mode_line (w, HEADER_LINE_FACE_ID, + y = y + display_mode_line (w, CURRENT_HEADER_LINE_ACTIVE_FACE_ID (w), NILP (window_header_line_format) ? BVAR (current_buffer, header_line_format) : window_header_line_format); @@ -27453,11 +27455,11 @@ display_mode_lines (struct window *w) line_number_displayed = false; w->column_number_displayed = -1; + struct window *sel_w = XWINDOW (old_selected_window); if (window_wants_mode_line (w)) { Lisp_Object window_mode_line_format = window_parameter (w, Qmode_line_format); - struct window *sel_w = XWINDOW (old_selected_window); /* Select mode line face based on the real selected window. */ display_mode_line (w, @@ -27485,7 +27487,7 @@ display_mode_lines (struct window *w) Lisp_Object window_header_line_format = window_parameter (w, Qheader_line_format); - display_mode_line (w, HEADER_LINE_FACE_ID, + display_mode_line (w, CURRENT_HEADER_LINE_ACTIVE_FACE_ID_3 (sel_w, sel_w, w), NILP (window_header_line_format) ? BVAR (current_buffer, header_line_format) : window_header_line_format); @@ -27500,11 +27502,12 @@ display_mode_lines (struct window *w) } -/* Display mode or header/tab line of window W. FACE_ID specifies - which line to display; it is either MODE_LINE_ACTIVE_FACE_ID, - HEADER_LINE_FACE_ID or TAB_LINE_FACE_ID. FORMAT is the - mode/header/tab line format to display. Value is the pixel height - of the mode/header/tab line displayed. */ +/* Display mode or header/tab line of window W. FACE_ID specifies which + line to display; it is either MODE_LINE_ACTIVE_FACE_ID, + HEADER_LINE_ACTIVE_FACE_ID, HEADER_LINE_INACTIVE_FACE_ID, or + TAB_LINE_FACE_ID. FORMAT is the mode/header/tab line format to + display. Value is the pixel height of the mode/header/tab line + displayed. */ static int display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) @@ -27525,7 +27528,8 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) it.glyph_row->tab_line_p = true; w->desired_matrix->tab_line_p = true; } - else if (face_id == HEADER_LINE_FACE_ID) + else if (face_id == HEADER_LINE_ACTIVE_FACE_ID + || face_id == HEADER_LINE_INACTIVE_FACE_ID) w->desired_matrix->header_line_p = true; /* FIXME: This should be controlled by a user option. But @@ -27544,7 +27548,9 @@ display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format) record_unwind_save_match_data (); if (NILP (Vmode_line_compact) - || face_id == HEADER_LINE_FACE_ID || face_id == TAB_LINE_FACE_ID) + || face_id == HEADER_LINE_ACTIVE_FACE_ID + || face_id == HEADER_LINE_INACTIVE_FACE_ID + || face_id == TAB_LINE_FACE_ID) { mode_line_target = MODE_LINE_DISPLAY; display_mode_element (&it, 0, 0, 0, format, Qnil, false); @@ -28313,7 +28319,8 @@ are the selected window and the WINDOW's buffer). */) ? MODE_LINE_ACTIVE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID) : EQ (face, Qmode_line_active) ? MODE_LINE_ACTIVE_FACE_ID : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID - : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID + : EQ (face, Qheader_line_active) ? HEADER_LINE_ACTIVE_FACE_ID + : EQ (face, Qheader_line_inactive) ? HEADER_LINE_INACTIVE_FACE_ID : EQ (face, Qtab_line) ? TAB_LINE_FACE_ID : EQ (face, Qtab_bar) ? TAB_BAR_FACE_ID : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID diff --git a/src/xfaces.c b/src/xfaces.c index e248279e9b7..f6264802fa4 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -5117,7 +5117,8 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id) case DEFAULT_FACE_ID: name = Qdefault; break; case MODE_LINE_ACTIVE_FACE_ID: name = Qmode_line_active; break; case MODE_LINE_INACTIVE_FACE_ID: name = Qmode_line_inactive; break; - case HEADER_LINE_FACE_ID: name = Qheader_line; break; + case HEADER_LINE_ACTIVE_FACE_ID: name = Qheader_line_active; break; + case HEADER_LINE_INACTIVE_FACE_ID: name = Qheader_line_inactive; break; case TAB_LINE_FACE_ID: name = Qtab_line; break; case TAB_BAR_FACE_ID: name = Qtab_bar; break; case TOOL_BAR_FACE_ID: name = Qtool_bar; break; @@ -5867,7 +5868,8 @@ realize_basic_faces (struct frame *f) realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID); realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID); realize_named_face (f, Qfringe, FRINGE_FACE_ID); - realize_named_face (f, Qheader_line, HEADER_LINE_FACE_ID); + realize_named_face (f, Qheader_line_active, HEADER_LINE_ACTIVE_FACE_ID); + realize_named_face (f, Qheader_line_inactive, HEADER_LINE_INACTIVE_FACE_ID); realize_named_face (f, Qscroll_bar, SCROLL_BAR_FACE_ID); realize_named_face (f, Qborder, BORDER_FACE_ID); realize_named_face (f, Qcursor, CURSOR_FACE_ID); @@ -7438,6 +7440,8 @@ syms_of_xfaces (void) DEFSYM (Qfringe, "fringe"); DEFSYM (Qtab_line, "tab-line"); DEFSYM (Qheader_line, "header-line"); + DEFSYM (Qheader_line_inactive, "header-line-inactive"); + DEFSYM (Qheader_line_active, "header-line-active"); DEFSYM (Qscroll_bar, "scroll-bar"); DEFSYM (Qmenu, "menu"); DEFSYM (Qcursor, "cursor");