Repository navigation
Conversation
The `header-line` face in themes such as tsdh-dark carries `:inverse-video t`. GNU merges every face source (the row's base face, text-property faces, and overlays) into one lface vector and swaps foreground and background exactly once, at realization: `face_at_string_position` (src/xfaces.c:7105) copies the base face's lface, and `load_face_colors` (src/xfaces.c:1389-1400) performs the swap. A foreground-only face on a header-line string therefore paints its colour as the background. neomacs realized the base face's swap before the string's text-property faces were merged, so a face such as `pi-coding-agent-model-name` (inheriting `font-lock-type-face`) stayed a purple foreground on the light header line instead of becoming the purple pill GNU Emacs draws. Record GNU's merged `:inverse-video` attribute on `ResolvedFace` and let `apply_specified_face_over` undo the base face's realized swap, merge the new source against the pre-inverse colours, and swap once at the end. The flag also participates in `same_resolved_face`, because it decides how later sources merge over a face. Add a resolver test for an inverse-video base merged with a foreground-only text face. Two layout tests that asserted the pre-fix colours for an inverse base now pin their base face flat, since their subject is remapping and glyphless rendering rather than inverse video.
`merge_named_active_face` skipped installing a merged escape-glyph, glyphless-char, nobreak-space, or nobreak-hyphen face when the foreground was unchanged. GNU swaps a merged foreground into the background when the base face is `:inverse-video` (`load_face_colors`, src/xfaces.c:1389-1400), and `nobreak-space` can set `:background` outright (its `min-colors 8` branch), so a foreground-only comparison discarded real color changes: an escape glyph over an inverse-video base kept the base face instead of painting its color in the background. Compare both slots, including the terminal-default sentinels, before treating the merge as a no-op. Add a layout test that puts an `(:inverse-video t)` text property on a control char and asserts the escape-glyph color lands in the caret's background.
`realize_face` and `apply_specified_face_over` always wrote `:distant-foreground` into the foreground when the realized foreground and background were too close. GNU replaces the *background* instead when the face is `:inverse-video`, because the swap has already moved the colors (`load_face_colors`, src/xfaces.c:1417-1425). Write the distant color into whichever slot `:inverse-video` moved the foreground to. Add a resolver test covering both the plain (foreground) and inverse-video (background) cases.
eval-exec
approved these changes
Sep 9, 2026
eval-exec
left a comment
Owner
There was a problem hiding this comment.
Approved for integration per maintainer direction. Local nextest review confirms the targeted improvements; a remaining face-merge regression involving lossy distant-foreground realization will be fixed on main with a regression test. This approval does not imply that remaining case is resolved.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Inverse-video faces were realized before later string and semantic faces were merged. This could put merged colors in the wrong slot, discard escape/nobreak color changes, and apply distant-foreground to the wrong side.
Preserve the pending inverse-video attribute through face resolution, merge later sources against the unswapped colors, and realize the swap once after merging. The escape/nobreak no-op check now compares both color slots, and distant-foreground follows the inverse-video slot.