Dedicated header band painted above the messages area.
Three-region layout:
[LEFT] [CENTER] [RIGHT]
✓ Copied! Session title d8d6a0a1
(notification/status) (or fallback placeholder) (id target)
com.blockether.vis.core/notify!),
otherwise live channel status. The session title does NOT live here.:title). When the
session has no title yet, falls back to a placeholder so
the row never looks broken on a fresh run.Pure draw: reads :title and :session from app-db, the
active notifications list from vis.core/notifications, writes
cells, registers ONE click region for the copy affordance.
Repaint: the banner updates as notifications come and go.
screen.clj registers a watcher on screen mount that bumps the
render version for any change, so a (notify! ...) from anywhere
nudges this band to repaint immediately.
Dedicated header band painted above the messages area.
Three-region layout:
[LEFT] [CENTER] [RIGHT]
✓ Copied! Session title d8d6a0a1
(notification/status) (or fallback placeholder) (id target)
- LEFT: latest active host notification (`com.blockether.vis.core/notify!`),
otherwise live channel status. The session title does NOT live here.
- CENTER: session title from app-db (`:title`). When the
session has no title yet, falls back to a placeholder so
the row never looks broken on a fresh run.
- RIGHT: short session id (first 8 chars of the UUID) as the clickable
affordance that drops the FULL UUID onto the system clipboard. No
notifications or channel statuses render here.
Pure draw: reads `:title` and `:session` from app-db, the
active notifications list from `vis.core/notifications`, writes
cells, registers ONE click region for the copy affordance.
Repaint: the banner updates as notifications come and go.
`screen.clj` registers a watcher on screen mount that bumps the
render version for any change, so a `(notify! ...)` from anywhere
nudges this band to repaint immediately.Bind false for header-only hover repaints. Geometry did not change, so the previous full frame's published click regions remain valid and the repaint must not mutate the staged click-region buffer.
Bind false for header-only hover repaints. Geometry did not change, so the previous full frame's published click regions remain valid and the repaint must not mutate the staged click-region buffer.
(draw-header! g db header-top cols)Paint the header band starting at header-top, full width cols.
Main content row is a fixed-width 3-slot flex (see vh/slot-layout):
vh/left-slot-cols): latest notification, otherwise live channel status.vh/slot-gap-cols gap each side): workspace title or switcher. With one workspace,
paint inert title text. With multiple workspaces, paint switchable
workspace entries. When app-db has not yet materialised a workspace list,
tab-entries synthesises one placeholder workspace so a fresh
session reads as Untitled session in the centre.vh/right-slot-cols): stable session-id copy affordance only.Workspaces are part of the header row (no separate band). Overflow shows clickable left/right arrows that cycle through workspaces.
Paint the header band starting at `header-top`, full width `cols`. Main content row is a fixed-width 3-slot flex (see `vh/slot-layout`): - LEFT (static `vh/left-slot-cols`): latest notification, otherwise live channel status. - CENTER (rest, minus a `vh/slot-gap-cols` gap each side): workspace title or switcher. With one workspace, paint inert title text. With multiple workspaces, paint switchable workspace entries. When app-db has not yet materialised a workspace list, `tab-entries` synthesises one placeholder workspace so a fresh session reads as `Untitled session` in the centre. - RIGHT (static `vh/right-slot-cols`): stable session-id copy affordance only. Workspaces are part of the header row (no separate band). Overflow shows clickable left/right arrows that cycle through workspaces.
(header-rows db)(header-rows db cols)Rows needed by the header for this app-db. Workspace switcher lives inside
the base content row; each enabled extension that declares a
:tui.slot/header-row channel contribution adds its fn's reported height.
Note: contribution fns are invoked here AND in draw-header! (the
render path needs both the total height and the draw-fn).
Extensions should keep their fn cheap or memoise
per-frame internally — the goal extension uses a 100ms TTL atom
for its SQLite lookup.
Rows needed by the header for this app-db. Workspace switcher lives inside the base content row; each enabled extension that declares a `:tui.slot/header-row` channel contribution adds its fn's reported height. Note: contribution fns are invoked here AND in `draw-header!` (the render path needs both the total height and the draw-fn). Extensions should keep their fn cheap or memoise per-frame internally — the goal extension uses a 100ms TTL atom for its SQLite lookup.
Minimum rows reserved by the header band: top rule + content row +
bottom rule. header-rows adds the height contributed by registered
:tui.slot/header-row extensions on top of this base.
Minimum rows reserved by the header band: top rule + content row + bottom rule. `header-rows` adds the height contributed by registered `:tui.slot/header-row` extensions on top of this base.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |