TUI: make the focused panel unmistakable #123
Closed
opened 2026-08-25 12:18:01 +01:00 by naps62-yolo
·
0 comments
No Branch/Tag Specified
main
chorale
upbeat
tritone-2
fermata-4
android-app/271-theme-apk
blitz/android-app
android-app/270-command-bar
android-app/268-app-shell
android-app/267-structured
android-app/266-terminal
android-app/269-spawn-form
android-app/265-sidebar
android-app/264-daemon-connection
android-app/263-api-client
android-app/262-project-scaffold
rhapsody
dominant-2
animato-2
glockenspiel
septet
mandolin
chord
timbre-2
aeolian
cello-2
allegro
lento
lyre
maestoso
cadence-3
modulation-2
modulation
xylophone-2
tuba-2
piccolo-2
grazioso-2
grazioso
hymn
xylophone
blitz/react-tailwind-migration
254-design-kit-react
253-delete-vanilla-wire-react
issue/252-tests-rtl
issue/242-daemon-link-react
issue/240-types-api-router
issue/251-preview-mode-react
issue/250-dialogs-drawer-react
issue/249-layout-system-react
247-command-bar-react
issue/248-spawn-dialog-react
246-structured-pane-react
issue/245-terminal-pane-react
244-sidebar-react
issue/243-theme-tokens-tailwind
issue/241-catalog-connection-zustand
issue/239-scaffold-react-tailwind
timpani
staccato-2
trombone-2
grave-2
harpsichord-2
recorder-4
vivace
sotto
tuba
chaconne
etude
arpeggio
harpsichord
cadence-2
brillante
clarinet
snare-2
staccato
recorder-2
tritone
balalaika
timbre
violin
fix/web-nix-build
blitz/codex-structured-sessions
codex-structured-sessions/203-tui-spawn
codex-structured-sessions/202-web-spawn
codex-structured-sessions/201-codex-lifecycle
codex-structured-sessions/200-select-acp-adapter
blitz/structured-view
vivo
structured-view/199-command-resolution
structured-view/198-viewport
structured-view/197-lock-order
structured-view/196-concurrent-handshakes
structured-view/195-autoscroll
structured-view/194-plan-row
structured-view/193-expanded-reconnect
structured-view/192-pty-gate
structured-view/143-spawn-structured
structured-view/191-accurate-diffs
structured-view/190-web-tool-state
structured-view/189-tui-approval-failure
structured-view/188-web-submit
structured-view/187-tui-spawn-race
structured-view/141-tui-structured
structured-view/140-web-structured
structured-view/186-unknown-update-doc
structured-view/185-lock-order
structured-view/184-approval-persist
structured-view/142-structured-activity
structured-view/137-structured-docs
fix/codex-attach-scroll
structured-view/139-permission-requests
structured-view/138-structured-api
structured-view/136-transcript-projection
structured-view/183-dismissal-race
structured-view/182-natural-exit-race
structured-view/181-recovery-provenance
structured-view/180-shutdown-create
structured-view/179-shutdown-drain
structured-view/177-restart-worktree
structured-view/178-pid-safe
structured-view/135-event-log
structured-view/134-acp-subprocess
10-umbrella-feature-gate-tests
structured-view/133-session-view
contrabass
fermata
interlude
crescendo
reboot/173-timing-assert
reboot/169-tui-dormant
blitz/reboot-resilience
reboot/171-scrollback
reboot/176-session-id-refresh
reboot/175-resume-races
reboot/168-web-dormant
reboot/174-bootid-strand
reboot/167-resume-policy
reboot/166-resume-route
reboot/172-worktree-field
reboot/164-boot-id
reboot/165-resume-command
reboot/163-prune-sidecars
tuplet
reboot/162-dormant
reboot/161-agent-session-id
sarabande
glissando
blitz/command-bar
legato
command-bar/159-web-leader-config
command-bar/157-touch-entry
command-bar/158-literal-leader
command-bar/156-tui-literal-ctrlk
command-bar/155-tui-drillin
command-bar/151-web-drillin
command-bar/154-tui-sigils
command-bar/152-web-pane-ctrlk
command-bar/150-web-sigils
command-bar/153-tui-bar
aubade
command-bar/147-rust-matcher
dominant
command-bar/149-web-bar
command-bar/145-daemon-focus
command-bar/146-ts-matcher
command-bar/148-web-registry
harmony
command-bar/144-contract
coda
oboe
accordion
snare
feroce
cantabile
fix/tui-daemon-url-resolution
haiky
activity
shortcuts
dorian
symphony
colors
flugelhorn
andante
trombone
organ
scherzo
duduk
sostenuto
lullaby
moderato-motif
largo-piano
moderato-bassoon
lento-sonata
animato-trumpet
largo-lute
feroce-violin
grazioso-viola
sostenuto-bassoon
crescendo-rondo
refresh
marcato-nocturne
brillante-fugue
forte-lyre
rename
themes
blitz/tui-shell
issue/124-project-groups
issue/122-theme-presets
issue/123-focused-panels
issue/121-tui-line2
issue/120-web-line2
issue/119-bare-maestro-tui
issue/118-palette-roles
issue/117-path-helpers
issue/116-sidebar-contract
blitz/sidebar-cards
sidebar-cards/115-fourth-flake
sidebar-cards/114-hook-error
sidebar-cards/113-more-flakes
sidebar-cards/106-hooks-install
sidebar-cards/112-detail-render
sidebar-cards/111-flaky-retention
sidebar-cards/105-activity-endpoint
sidebar-cards/110-lenient-activity
sidebar-cards/108-tui-cards
sidebar-cards/107-web-cards
sidebar-cards/104-activity-clock
sidebar-cards/103-session-env
sidebar-cards/102-activity-wire
sidebar-cards/101-sidebar-contract
blitz/spawn-v2
spawn-v2/97-enter-submits
spawn-v2/94-labels
spawn-v2/96-tui-picker
spawn-v2/93-collapse-worktree
spawn-v2/98-flake-ci
spawn-v2/95-project-picker
spawn-v2/74-gitroot-debounce
spawn-v2/76-preset-reset
spawn-v2/73-draft-pane-swap
spawn-v2/91-wt-toggle-default
spawn-v2/92-form-width
spawn-v2/70-fastforward-key
spawn-v2/72-opendraft-reuse
spawn-v2/75-projects-ttl
blitz/worktree-lifecycle
wl/83-blocked-work
wl/88-e2e-lifecycle
wl/87-drop-cleanup-flag
wl/82-natural-exit
wl/84-web-worktrees
wl/81-force-retains
wl/85-tui-worktrees
wl/86-cli-worktrees
wl/79-kill-guard
wl/80-worktrees-api
wl/77-worktree-collisions
wl/78-retained-store
spawn-v2/67-fastforward
spawn-v2/66-e2e
spawn-v2/65-tui-worktree
spawn-v2/68-draft-teardown
spawn-v2/62-drop-modal
spawn-v2/64-tui-fields
spawn-v2/61-wt-defaults
spawn-v2/53-names
spawn-v2/55-branches
spawn-v2/59-projectlist
spawn-v2/54-projects
spawn-v2/60-autocomplete
spawn-v2/63-tui-draft-pane
spawn-v2/56-worktree-place
spawn-v2/58-tui-textinput
spawn-v2/57-draft-pane
nix
refactor
dev-environment
linear/nap-228-daemon-recover-leaves-stale-tmux-pipe-pane-attach-shows-no
No results found.
Projects
Clear projects
No projects
No Assignees
No due date set.
Blocks
Depends on
#124 TUI: group sidebar cards by project, collapsible
naps62/maestro
#118 TUI: move every colour behind a named-role palette
naps62/maestro
#121 TUI: render line 2 on every session card
naps62/maestro
Reference: naps62/maestro#123
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Focus in the TUI is nearly invisible.
render.rstints the sidebar's right-edge rule and the pane's top rule cyan when that side has focus, and that is the entire cue — a single line changing colour at the edge of the screen. Worse, the sidebar's highlighted card keeps its filled selection background whether or not the sidebar has focus, so the sidebar always looks like the active panel.Two changes, and both are wanted:
The selection goes hollow when the sidebar is unfocused. The highlighted card keeps its filled background only while focus is on the sidebar. Unfocused, it drops to an outline or an edge marker that still says "this is where the cursor is" without claiming the keys. The thing that looks selected should only look selected when your keystrokes go there.
The active panel gets a coloured border. Use the palette's focused and unfocused border roles.
The border costs screen space, and the layout must not move when focus changes — a border that appears on focus would reflow the screen under the cursor. So both panels carry a border at all times and only its colour changes. That is 2 of the sidebar's 28 columns, and 2 rows plus 2 columns off the pane.
render.rs:110records that the current 1-row-rule layout deliberately replacedLength(3) + Borders::ALLto reclaim exactly those rows; this issue knowingly spends some of them back, and the sidebar's usable width drops accordingly. Check that the card truncation logic insidebar.rsstill behaves at the narrower width.The pane renders a live terminal's own output, which sets its own colours. Do not dim or restyle the pane's contents to signal focus — the border is the cue there.
Tests: the highlighted card renders filled when the sidebar is focused and hollow when it is not, the border style follows
AppState::focus, and the layout's pane and sidebar rectangles are identical in both focus states.Depends on: #118, #121