Skip to content

Commit 49d4fed

Browse files
Merge pull request #32 from SharpMUSH/feat/tab-chip-colours
fix(tabs): a background pane says which tab it is showing
2 parents 94967fd + d522c7b commit 49d4fed

13 files changed

Lines changed: 863 additions & 1148 deletions

File tree

CLAUDE.md

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,11 @@ python3 tools/ansi_frame_to_image.py frame.ansi frame.html # or .svg
539539
wording, and this is the one that happens many times an hour), `prefix-panel` (the ⌃B which-key
540540
panel — the state `prefix` becomes a few hundred milliseconds later, if no key has arrived),
541541
`focus`/`focus-moved` (a split *and* a second command line — the one geometry showing a focused pane
542-
beside an unfocused one and an armed bar above an idle one, before and after a real ⌃→), plus the
542+
beside an unfocused one and an armed bar above an idle one, before and after a real ⌃→),
543+
`tabs` (**two tabs in the pane that does *not* hold the focus** — the one geometry that can show a
544+
strip saying which tab is in front, since every other view has at most one tab in an unfocused pane.
545+
It opens a third window for itself alone, and re-activates the main window before splitting, because
546+
opening brings a window to the front and a split carries the tabs that are not), plus the
543547
default workspace
544548
(no `--view`). Any settings screen also takes a `-edit` suffix, which opens it and drives real
545549
keys in so the frame shows a field mid-edit. State toggles: `collapsed`, `prefix`, `timestamps`,
@@ -854,10 +858,25 @@ markup (`[bold #rrggbb on #rrggbb]…[/]`, `[[`/`]]` escaping, `[link=url]…[/]
854858
`TabTitles` claimed the opposite for as long as it existed, and the claim had two costs: the unread
855859
count went out untinted, and a window title was never escaped — a window called `[Chat]`, or a web view
856860
titled from the page it loaded, had that eaten as a tag by the parser *and* by the hit test. Titles are
857-
`MarkupText.Escape`d now. The tint covers the name and the count only; the `` stays outside it, because
858-
focus and activity are independent facts and a marker that changed colour on an incoming line would be
859-
reporting the wrong one. **The two cues are different channels on purpose** — focus is said entirely in
860-
*backgrounds* from the theme's chrome family, activity in a *foreground* no plane is painted in.
861+
`MarkupText.Escape`d now. The tint and the selection **bold** cover the name and the count only; the ``
862+
stays outside them, because focus, selection and activity are independent facts and a marker that
863+
changed colour on an incoming line would be reporting the wrong one. **The cues are different channels
864+
on purpose** — focus in *background luminance*, activity in a *foreground* no plane is painted in,
865+
selection in *weight* and in a within-strip step. A selected tab can be unread, so the two are one tag
866+
(`[bold #rrggbb]`) rather than two nested ones.
867+
- **A tab chip says which tab you are viewing, relative to its own strip — and pane focus is not a term in
868+
it.** The selected chip is painted `PaneSurfaceTone` exactly, the plane its own page is painted on, and
869+
its siblings are `WorkspacePalette.Recessed` one step below it (`BackdropScale`, the backdrop's own
870+
step). Focus arrives already folded into that plane — tinted for the character, lifted for focus — so
871+
one ratio inside every strip reads whether or not the pane holds the keyboard, and hue is untouched.
872+
Deriving the selected chip *from* focus is what made this unreadable: `PaintTabChips` computed an
873+
unfocused pane's selected chip and its siblings from the same expression, background **and** ink, so
874+
every chip in a background pane was byte-identical to the pane's surface and the `` was no help
875+
because `TabTitles` only emits it on the focused pane. `TabSelectionTests`, and the `tabs` view is the
876+
frame — no other view has two tabs in an unfocused pane, which is why nothing caught it.
877+
**Not fixed here**: the `` between chips and the `` filling the rest of the strip are hardcoded
878+
`Color.Grey` in `TabControl.Rendering.cs`, unthemeable in all three header styles. That is an upstream
879+
change.
861880
- **One unread count, one spelling: `UnreadBadge`.** The sidebar and the tab strip are two views of
862881
`WorkspaceWindow.Unread`, and they had two formatters — the rail capped at `99+`, the tab printed the
863882
raw integer, so a busy channel read `99+` in one place and `(4127)` in the other. Cap, field width and
@@ -889,7 +908,7 @@ markup (`[bold #rrggbb on #rrggbb]…[/]`, `[[`/`]]` escaping, `[link=url]…[/]
889908
is derived from the pane rectangle (`PaneOutputRects`), so a border, gutter or marker column that only
890909
the focused pane has would re-announce a different terminal size to every connected server on every
891910
focus change and reflow the game's own output. The cues are the pane's own plane
892-
(`WorkspacePalette.Focus`), the active tab's chip colour (`TabControl.Active*BackgroundColor`), and a
911+
(`WorkspacePalette.Focus`), the tab chips it carries that plane into, and a
893912
`` in the tab *title* — all zero-cost. `FocusIndicationTests.MovingFocusDoesNotMoveAnyPaneRectangle`
894913
is the test that stops this being "improved" into a border. Colours live in `WorkspacePalette`, whose
895914
constants are all derived from a `ScreenPalette` pair so the workspace and the settings screens share

0 commit comments

Comments
 (0)