Guides
Mouse Support
Rezi enables mouse routing when terminal capabilities report mouse support.
Rezi enables mouse routing when terminal capabilities report mouse support.
Mouse Input
Click model
- On mouse down, Rezi hit-tests and immediately moves focus to the hit widget if it is focusable and enabled.
- Activation uses a press/release model:
- Mouse down captures
pressedIdonly for pressable targets (currently button IDs). - Mouse up emits
action: "press"only if release lands on the same enabled pressable ID. - Releasing elsewhere (or disabling/removing the target) cancels the press.
- Mouse down captures
- Non-pressable focusable widgets still take focus on mouse down but do not emit the generic
"press"action. SplitPaneis intentionally not focusable; divider drag is handled by dedicated mouse logic.
Scroll routing and boundaries
Wheel routing order:
VirtualListunder cursor (hitTestTargetId), else focusedVirtualList.- If no
VirtualListhandled the event: focusedCodeEditor,LogsConsole, thenDiffViewer. - If none match, the wheel event is ignored.
Wheel step size (where implemented):
VirtualList:wheelY * 3linesCodeEditor:wheelY * 3vertical lines,wheelX * 3horizontal columnsLogsConsole:wheelY * 3linesDiffViewer:wheelY * 3lines
Clamping:
VirtualList.scrollTop:[0, max(0, totalHeight - viewportHeight)]CodeEditor.scrollTop:[0, max(0, lineCount - viewportHeight)]CodeEditor.scrollLeft:>= 0LogsConsole.scrollTop/DiffViewer.scrollTop:[0, max(0, contentLines - viewportHeight)]
SplitPane drag lifecycle
- Drag starts on primary-button mouse down in divider hit area (
dividerSizeplus 1-cell expansion on each side). - Runtime captures pointer start position and panel start sizes.
- On move/drag, delta is applied via
handleDividerDrag(...):- Only the two panels adjacent to the dragged divider resize.
- Delta is clamped against both panels'
minSizesandmaxSizes. - The panel-pair total size is preserved.
onResizefires on each drag update (absolute cells or percentages, based onsizeMode).- Mouse up ends drag and clears drag state. If pane metadata disappears mid-drag, drag state is canceled.
- When
collapsibleandonCollapseare set, divider double-click (<= 500ms) toggles collapse for the side clicked.
Mouse + keyboard interaction
- Clicking transfers focus through the same focus state used by Tab/Shift+Tab.
- Focus transfer triggers normal blur behavior for the previously focused input (
onBlur). - Keybinding chord state is managed by key routing rules (key events, timeout, mode switch). Mouse events do not run the chord matcher directly.
Hit-testing priority
Mouse routing priority:
- Top open dropdown (consumes mouse input and blocks lower layers while open).
- Layer hit-test using resolved layer order (higher
zIndexfirst; ties resolved by later registration/order). - Base widget hit-test (
hitTestFocusable) with ancestor clip intersection and deterministic overlap tie-break:- depth-first preorder traversal (children left-to-right)
- later tree-order nodes win overlap ties
Modal/layer blocking invariants:
- The topmost modal blocks input to all lower layers and base widgets, including points outside modal bounds.
- Backdrop visual style (
none/dim/opaque) does not change blocking semantics. - If
closeOnBackdropis enabled andonCloseexists, backdrop mouse down closes the blocking layer.