Liking cljdoc? Tell your friends :D

com.blockether.vis.ext.channel-tui.click-regions

Live registry of clickable rectangles painted by the chat renderer. The render thread calls begin-frame! at the start of every full repaint, register!s one entry per painted chrome row, then commit-frame!s the staged set as the new live registry. The input thread lookups the entry under the mouse cursor on MOVE (hover) and CLICK_DOWN.

Why double-buffered (staging + published) instead of one atom:

  • register! runs many times during a paint. Reads from the input thread can land BETWEEN the per-row registrations of a single frame. With a single-buffer design the input thread would see a partially-filled vec and miss clicks on chrome rows that hadn't been painted yet - the very bug that made the header copy-id button feel "sometimes broken". The staged buffer is private to the render thread; commit-frame! publishes the WHOLE frame's regions in a single atomic swap, so lookup always sees a complete frame (the previous one until commit, the new one after).

  • The renderer paints into a Lanterna TextGraphics object that has no place to attach "and also - here are the clickable bits I just drew." We'd otherwise need a parallel return channel through every paint helper.

  • The set is small (tens of entries at most - the visible scrollback's worth of links); a linear scan on lookup is fine and removes the need for any spatial-index dance.

Coordinate convention: every region is stored in ABSOLUTE screen coordinates so the input handler can compare directly against MouseAction.getPosition().

Live registry of clickable rectangles painted by the chat
renderer. The render thread calls `begin-frame!` at the start of
every full repaint, `register!`s one entry per painted chrome
row, then `commit-frame!`s the staged set as the new live
registry. The input thread `lookup`s the entry under the mouse
cursor on `MOVE` (hover) and `CLICK_DOWN`.

Why double-buffered (staging + published) instead of one atom:

- `register!` runs many times during a paint. Reads from the
  input thread can land BETWEEN the per-row registrations of
  a single frame. With a single-buffer design the input thread
  would see a partially-filled vec and miss clicks on chrome
  rows that hadn't been painted yet - the very bug that made
  the header copy-id button feel "sometimes broken". The
  staged buffer is private to the render thread; `commit-frame!`
  publishes the WHOLE frame's regions in a single atomic swap,
  so `lookup` always sees a complete frame (the previous one
  until commit, the new one after).

- The renderer paints into a Lanterna `TextGraphics` object that
  has no place to attach "and also - here are the clickable
  bits I just drew." We'd otherwise need a parallel return
  channel through every paint helper.

- The set is small (tens of entries at most - the visible
  scrollback's worth of links); a linear scan on lookup is
  fine and removes the need for any spatial-index dance.

Coordinate convention: every region is stored in ABSOLUTE screen
coordinates so the input handler can compare directly against
`MouseAction.getPosition()`.
raw docstring

assign-labelsclj

(assign-labels regions)

Assign jump labels to the visible :toggle-details regions in regions (pass (current)), in paint order. Returns an ordered vec of [label region] pairs. Dedupes by [session-id node-id] (one fold can register more than one glyph row) keeping the first occurrence, and caps at label-alphabet length. Deterministic: the renderer (painting the badges) and the input handler (resolving a keypress) derive the SAME assignment from the same frame, so neither needs to share mutable state with the other.

Assign jump labels to the visible `:toggle-details` regions in `regions`
(pass `(current)`), in paint order. Returns an ordered vec of `[label
region]` pairs. Dedupes by `[session-id node-id]` (one fold can register
more than one glyph row) keeping the first occurrence, and caps at
`label-alphabet` length. Deterministic: the renderer (painting the badges)
and the input handler (resolving a keypress) derive the SAME assignment from
the same frame, so neither needs to share mutable state with the other.
sourceraw docstring

begin-frame!clj

(begin-frame!)

Open a new paint pass: drop every staged region. Call once at the top of every full chat repaint, BEFORE any register!. Does not touch the published registry - lookup keeps returning the previous frame's regions until commit-frame! runs.

Open a new paint pass: drop every staged region. Call once at the
top of every full chat repaint, BEFORE any `register!`. Does not
touch the published registry - `lookup` keeps returning the
previous frame's regions until `commit-frame!` runs.
sourceraw docstring

commit-frame!clj

(commit-frame!)

Atomically publish the staged regions as the new live set. Call once at the END of every full chat repaint, after every painter (messages area, header, footer, ...) has registered its regions. lookup then sees the freshly-painted frame in a single step, never a partial buffer.

Atomically publish the staged regions as the new live set. Call
once at the END of every full chat repaint, after every painter
(messages area, header, footer, ...) has registered its regions.
`lookup` then sees the freshly-painted frame in a single step,
never a partial buffer.
sourceraw docstring

currentclj

(current)

Snapshot of every currently-registered region, in paint order. The renderer reads this on every paint to decide which row - if any - to highlight.

Snapshot of every currently-registered region, in paint order.
The renderer reads this on every paint to decide which row -
if any - to highlight.
sourceraw docstring

hoveredclj

(hovered)

Return the currently-hovered region or nil. Read by the renderer to paint a highlight on the matching row.

Return the currently-hovered region or nil. Read by the renderer
to paint a highlight on the matching row.
sourceraw docstring

label-alphabetclj

Single-character jump labels for the vim-style disclosure overlay, home row first so the common case is a no-reach keypress. Caps how many folds one screen can label; any beyond the alphabet stay mouse-clickable.

Single-character jump labels for the vim-style disclosure overlay, home row
first so the common case is a no-reach keypress. Caps how many folds one
screen can label; any beyond the alphabet stay mouse-clickable.
sourceraw docstring

lookupclj

(lookup col row)

Return the topmost (last-registered) region containing (col, row), or nil. O(n) linear scan from the END of the regions vec so a newer overlay wins over an older one underneath.

Return the topmost (last-registered) region containing (col, row),
or nil. O(n) linear scan from the END of the regions vec so a
newer overlay wins over an older one underneath.
sourceraw docstring

register!clj

(register! {:keys [bounds] :as region})

Append region to the staging buffer. The renderer calls this once per painted chrome row; the order matches paint order so a later region painted on top of an earlier one wins on lookup (matches what the user actually sees on screen). Regions become visible to lookup only after commit-frame!.

Validates the bounds shape - silently dropping a bad entry would mask renderer bugs.

Append `region` to the staging buffer. The renderer calls this
once per painted chrome row; the order matches paint order so a
later region painted on top of an earlier one wins on lookup
(matches what the user actually sees on screen). Regions become
visible to `lookup` only after `commit-frame!`.

Validates the bounds shape - silently dropping a bad entry
would mask renderer bugs.
sourceraw docstring

reset!clj

(reset!)

Drop every published AND staged region; clear hover. Used by tests and by the screen teardown path; not part of the per-frame paint pipeline.

Drop every published AND staged region; clear hover. Used by
tests and by the screen teardown path; not part of the
per-frame paint pipeline.
sourceraw docstring

set-hovered!clj

(set-hovered! region)

Update the hover pointer. Returns true when the value actually changed; the input handler uses that to decide whether to bump the render version (avoids repaint storms on every mouse twitch inside the same row).

Update the hover pointer. Returns true when the value actually
changed; the input handler uses that to decide whether to bump
the render version (avoids repaint storms on every mouse twitch
inside the same row).
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close