Module: Tuile::Mouse
- Defined in:
- lib/tuile/mouse.rb,
lib/tuile/mouse/router.rb,
sig/tuile.rbs
Overview
The mouse: the events, their parser, and the tracking levels Screen#run_event_loop asks the terminal for. Who gets one is Router's story.
Four of the five classes are what Mouse.parse reads off the wire; DragEvent is
the router's own, a move while something holds the grab. Each is a
Data.define including the Event marker — no inheritance, so a case
matches either one class or Mouse::Event for all of them. Enter and exit
have no class at all: nothing is parsed, they are the difference between two
hovered chains.
Coordinates are screen-absolute and 0-based everywhere.
Defined Under Namespace
Modules: Event Classes: DownEvent, DragEvent, MoveEvent, Router, ScrollEvent, UpEvent
Constant Summary collapse
- LEVELS =
The
capture_mouse:levels, each a strict superset of the one before, and each unlocking one tier of events::clicks(mode 1000) gives down, up and scroll;:drag(1002) adds drag;:hover(1003) adds move, enter and exit (R_mouse_reporting). %i[clicks drag hover].freeze
- MODES =
Returns the DEC private mode each level sets.
{ clicks: 1000, drag: 1002, hover: 1003 }.freeze
- MODIFIER_BITS =
X10 button code layout:
button | 4 shift | 8 meta | 16 ctrl | 32 motion | 64 wheel, button 3 meaning "released" (R_mouse_reporting). 4 | 8 | 16
Class Method Summary collapse
-
.level(capture_mouse) ⇒ Symbol?
Normalizes a
capture_mouse:argument to a level. -
.parse(key) ⇒ Event?
Parses an X10 mouse report (
\e[M+ 3 bytes: button, x, y) into one of DownEvent, UpEvent, ScrollEvent or MoveEvent. Modifier bits are ignored. -
.report?(key) ⇒ Boolean
Whether
keyis a mouse report. -
.start_tracking(level) ⇒ String
@param
level— one of LEVELS. -
.stop_tracking(level) ⇒ String
@param
level— one of LEVELS.
Class Method Details
.level(capture_mouse) ⇒ Symbol?
Normalizes a capture_mouse: argument to a level.
@param capture_mouse — false, true (== :clicks), or one of LEVELS.
@return — the level; nil when tracking is off.
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/tuile/mouse.rb', line 103 def level(capture_mouse) case capture_mouse when false, nil then nil when true then :clicks when *LEVELS then capture_mouse else raise ArgumentError, "capture_mouse: expected true, false or one of #{LEVELS}, got #{capture_mouse.inspect}" end end |
.parse(key) ⇒ Event?
Parses an X10 mouse report (\e[M + 3 bytes: button, x, y) into one of
DownEvent, UpEvent, ScrollEvent or MoveEvent. Modifier bits are
ignored.
Raises Error when key starts with the mouse prefix but is
not exactly 6 bytes long. Both shorter and longer inputs are bugs in
the upstream key-reader: a shorter prefix means the tail was lost on
the way in, and a longer one means we over-consumed into the next
escape sequence. We refuse to silently truncate either case because
the trailing \e of an over-read corrupts the next getkey, and the
corruption then surfaces as garbled keystrokes in focused inputs
rather than as a parser failure pointing at the actual cause.
@param key — key read via Keys.getkey
@return — nil if key is not a mouse report, or reports
a wheel button beyond the four directions.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/tuile/mouse.rb', line 145 def parse(key) return nil unless report?(key) unless key.bytesize == 6 raise Tuile::Error, "malformed mouse event: expected 6 bytes after \\e[M prefix, got #{key.bytesize}: #{key.inspect}" end code = (key[3].ord - 32) & ~MODIFIER_BITS # XTerm reports coordinates 1-based (column N is encoded as N + 32); # subtract 33 so that `x` and `y` are 0-based. x = key[4].ord - 33 y = key[5].ord - 33 low = code & 3 if code.anybits?(64) direction = %i[up down left right][low] direction && ScrollEvent.new(direction, x, y) elsif code.anybits?(32) MoveEvent.new((low), x, y) elsif low == 3 UpEvent.new(x, y) else DownEvent.new((low), x, y) end end |
.report?(key) ⇒ Boolean
Whether key is a mouse report. True on the X10 \e[M prefix
regardless of length — parse is the place that validates the full
6-byte shape and raises on malformed input.
@param key — key read via Keys.getkey
127 |
# File 'lib/tuile/mouse.rb', line 127 def report?(key) = key.start_with?("\e[M") |