Subject: Re: bug#73862: [PATCH] Add `header-line-active` and `header-line-inactive` faces.

From: Eli Zaretskii <[email-masked]>
Date: Sun, 22 Dec 2024 17:52:25 +0200

> From: Eshel Yaron <[email-masked]>
> Cc: Eli Zaretskii <[email-masked]>,  [email-masked],
>   [email-masked],  [email-masked],  [email-masked],
>  Ihor Radchenko <[email-masked]>
> Date: Sat, 14 Dec 2024 10:45:45 +0100
> 
> Eshel Yaron writes:
> 
> >>> Aaron shared a recipe to reproduce this behavior, copied here:
> >>> 
> >>> --8<---------------cut here---------------start------------->8---
> >>> (setq header-line-format "Some header")
> >>> (face-remap-set-base 'header-line 'highlight)
> >>> (switch-to-buffer-other-window "new")
> >>> ;; In new buffer/window:
> >>> (setq header-line-format "Some header")
> >>> (other-window 1)
> >>> ;; In original buffer/window:
> >>> (set-face-attribute 'default nil :height (+ (face-attribute 'default :height) 10))
> >>> --8<---------------cut here---------------end--------------->8---
> >>
> >> Are you also change the attributes of the default face to cause the
> >> "spreading"?  If not, please show a recipe.  Because I was unable to
> >> see this without something like the last line of the recipe, and also
> >> that line _must_ be in the buffer where header-line is remapped,
> >> otherwise the effect is not seen.
> >
> > Yes, I used C-x C-M-= in the buffer in which I remapped header-line.
> 
> Note that this issue also affects Org: org-columns remaps header-line in
> org-columns--display-here.  (CC'ing Ihor.)

Please try the patch below.  If it gives good results, please run with
it for awhile, and tell if you see anything unusual or unexpected.

diff --git a/src/xfaces.c b/src/xfaces.c
index 5f60f38..9591a5c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5143,10 +5143,19 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id)
      for the very common no-remapping case.  */
   mapping = assq_no_quit (name, Vface_remapping_alist);
   if (NILP (mapping))
-    return face_id;		/* Give up.  */
+    {
+      Lisp_Object face_attrs[LFACE_VECTOR_SIZE];
+
+      /* If the face inherits from another, we need to realize it,
+         because the parent face could be remapped.  */
+      if (!get_lface_attributes (w, f, name, face_attrs, false, 0)
+	  || NILP (face_attrs[LFACE_INHERIT_INDEX])
+	  || UNSPECIFIEDP (face_attrs[LFACE_INHERIT_INDEX]))
+	return face_id;		/* Give up.  */
+    }
 
-  /* If there is a remapping entry, lookup the face using NAME, which will
-     handle the remapping too.  */
+  /* If there is a remapping entry, or the face inherits from another,
+     lookup the face using NAME, which will handle the remapping too.  */
   remapped_face_id = lookup_named_face (w, f, name, false);
   if (remapped_face_id < 0)
     return face_id;		/* Give up. */
@@ -5863,6 +5872,11 @@ realize_basic_faces (struct frame *f)
 
   if (realize_default_face (f))
     {
+      /* Basic faces must be realized disregarding face-remapping-alist,
+         since otherwise face-remapping might affect the basiic faces in
+         the face cache.  */
+      specpdl_ref count = SPECPDL_INDEX ();
+      specbind (Qface_remapping_alist, Qnil);
       realize_named_face (f, Qmode_line_active, MODE_LINE_ACTIVE_FACE_ID);
       realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID);
       realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID);
@@ -5884,6 +5898,7 @@ realize_basic_faces (struct frame *f)
       realize_named_face (f, Qchild_frame_border, CHILD_FRAME_BORDER_FACE_ID);
       realize_named_face (f, Qtab_bar, TAB_BAR_FACE_ID);
       realize_named_face (f, Qtab_line, TAB_LINE_FACE_ID);
+      unbind_to (count, Qnil);
 
       /* Reflect changes in the `menu' face in menu bars.  */
       if (FRAME_FACE_CACHE (f)->menu_face_changed_p)