Mouse interaction state: drag tracking, anchor position, separator resize, multi-click detection, and hover tracking.
Multi-click detection
The TUI always sends click_count: 1 because libvaxis doesn't track
multi-clicks. The BEAM detects double/triple-clicks by comparing press
timestamps and positions. GUI frontends send the native click count
directly, so BEAM detection is skipped when click_count > 1.
Two presses within @double_click_ms milliseconds at the same position
(within @click_distance cells) increment the click count. The count
resets on motion, timeout, or a click at a different position.
Summary
Functions
Records a timer reference created by the mouse workflow.
Clears hover state and returns any timer for the owning workflow to cancel.
Returns the double-click timing window in milliseconds (for testing).
Returns the hover debounce delay in milliseconds (for testing).
Prepares hover clearing without touching the process timer API.
Prepares hover state without touching the process timer API.
Records a mouse press and computes the effective click count.
Records a mouse press using a timestamp supplied by the input workflow.
Returns true if a separator resize drag is active.
Records hover position and returns timer work for the owning workflow.
Begins a content drag from the given buffer position.
Begins a content drag from the given buffer position and originating window.
Begins a separator resize drag in the given direction at the given position.
Ends an active drag, clearing the anchor.
Ends a separator resize drag.
Updates the separator position during an active resize drag.
Types
@type t() :: %MingaEditor.State.Mouse{ anchor: {non_neg_integer(), non_neg_integer()} | nil, click_count: non_neg_integer(), drag_click_count: pos_integer(), drag_origin_window: MingaEditor.Window.id() | nil, dragging: boolean(), hover_pos: {integer(), integer()} | nil, hover_timer: reference() | nil, last_press_pos: {integer(), integer()} | nil, last_press_time: integer() | nil, resize_dragging: {MingaEditor.WindowTree.direction() | :agent_separator, non_neg_integer()} | nil }
Functions
Records a timer reference created by the mouse workflow.
Clears hover state and returns any timer for the owning workflow to cancel.
@spec double_click_ms() :: pos_integer()
Returns the double-click timing window in milliseconds (for testing).
@spec hover_delay_ms() :: pos_integer()
Returns the hover debounce delay in milliseconds (for testing).
Prepares hover clearing without touching the process timer API.
Prepares hover state without touching the process timer API.
@spec record_press(t(), integer(), integer(), pos_integer()) :: t()
Records a mouse press and computes the effective click count.
If native_click_count > 1, uses that directly (GUI frontend).
Otherwise, detects multi-clicks by timing and position (TUI fallback).
Returns the updated mouse state with click_count set.
Records a mouse press using a timestamp supplied by the input workflow.
Returns true if a separator resize drag is active.
Records hover position and returns timer work for the owning workflow.
@spec start_drag( t(), {non_neg_integer(), non_neg_integer()} ) :: t()
Begins a content drag from the given buffer position.
@spec start_drag( t(), {non_neg_integer(), non_neg_integer()}, MingaEditor.Window.id() | nil ) :: t()
Begins a content drag from the given buffer position and originating window.
@spec start_resize( t(), MingaEditor.WindowTree.direction() | :agent_separator, non_neg_integer() ) :: t()
Begins a separator resize drag in the given direction at the given position.
Ends an active drag, clearing the anchor.
Ends a separator resize drag.
@spec update_resize( t(), MingaEditor.WindowTree.direction() | :agent_separator, non_neg_integer() ) :: t()
Updates the separator position during an active resize drag.