Skip to content

Commit 4d9e082

Browse files
committed
Add mouse wheel handling for ScrollBar/Scrollable
"Works" in both dimensions but: * Left/write wheel events aren't getting sent by gnome-terminal * Up/down wheel events are sent REALLY quickly by Ghostty * Current implementation doesn't do direction inversing
1 parent eaa7b8d commit 4d9e082

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

lib/Terminal/Widgets/ScrollBar.rakumod

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,27 @@ class Terminal::Widgets::HScrollBar
162162
}
163163
}
164164

165-
#| Handle mouse events
165+
#| Handle mouse wheel events
166+
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
167+
$event where { .mouse.pressed &&
168+
.mouse.button == 6|7 }, AtTarget) {
169+
# Take focus even if wheeled over framing instead of content area
170+
self.toplevel.focus-on(self);
171+
172+
# If enabled, process wheel left/right
173+
if $.enabled {
174+
given $event.mouse.button {
175+
when 6 { self.arrow-left-scroll }
176+
when 7 { self.arrow-right-scroll }
177+
}
178+
}
179+
else {
180+
# Refresh even not enabled because of focus state change
181+
self.full-refresh;
182+
}
183+
}
184+
185+
#| Handle mouse click events
166186
# XXXX: Handle drag events
167187
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
168188
$event where !*.mouse.pressed, AtTarget) {
@@ -309,7 +329,27 @@ class Terminal::Widgets::VScrollBar
309329
}
310330
}
311331

312-
#| Handle mouse events
332+
#| Handle mouse wheel events
333+
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
334+
$event where { .mouse.pressed &&
335+
.mouse.button == 4|5 }, AtTarget) {
336+
# Take focus even if wheeled over framing instead of content area
337+
self.toplevel.focus-on(self);
338+
339+
# If enabled, process wheel up/down
340+
if $.enabled {
341+
given $event.mouse.button {
342+
when 4 { self.arrow-up-scroll }
343+
when 5 { self.arrow-down-scroll }
344+
}
345+
}
346+
else {
347+
# Refresh even not enabled because of focus state change
348+
self.full-refresh;
349+
}
350+
}
351+
352+
#| Handle mouse click events
313353
# XXXX: Handle drag events
314354
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
315355
$event where !*.mouse.pressed, AtTarget) {

lib/Terminal/Widgets/Scrollable.rakumod

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# ABSTRACT: Common role for scrollable widgets
22

3+
use Terminal::Widgets::Events;
4+
5+
36
#| Common role for scrollable widgets
47
role Terminal::Widgets::Scrollable {
58
has UInt:D $.x-scroll = 0;
@@ -86,4 +89,22 @@ role Terminal::Widgets::Scrollable {
8689
self.ensure-x-span-visible($x, $x + (0 max $w - 1));
8790
self.ensure-y-span-visible($y, $y + (0 max $h - 1));
8891
}
92+
93+
#| Handle mouse wheel events
94+
multi method handle-event(Terminal::Widgets::Events::MouseEvent:D
95+
$event where { .mouse.pressed &&
96+
.mouse.button == 4|5|6|7 }, AtTarget) {
97+
# Take focus even if wheeled over framing instead of content area
98+
self.toplevel.focus-on(self);
99+
100+
# Process wheel up/down/left/right
101+
given $event.mouse.button {
102+
when 4 { self.change-y-scroll: -4 }
103+
when 5 { self.change-y-scroll: +4 }
104+
when 6 { self.change-x-scroll: -8 }
105+
when 7 { self.change-x-scroll: +8 }
106+
}
107+
108+
self.refresh-for-scroll;
109+
}
89110
}

0 commit comments

Comments
 (0)