wheel.go RawHistoryFolder

1package webterm
2
3// Wheel quantization converts raw browser wheel deltas into discrete
4// terminal wheel reports. Browsers emit wheel events as a scroll distance,
5// not as physical notches: high-resolution wheels and trackpads produce a
6// burst of micro-events per notch, and forwarding one SGR report per event
7// scrolls dozens of lines per notch. The accumulator below merges fractions
8// until they form whole notches, so one notch yields one report, like an
9// ordinary terminal. The remainder is kept per terminal and bounded.
10const (
11	// wheelPixelsPerNotch matches the Chromium convention of 100 CSS pixels
12	// per wheel notch in pixel (DOM_DELTA_PIXEL) mode.
13	wheelPixelsPerNotch = 100
14	// wheelLinesPerNotch matches the browser convention of 3 lines per wheel
15	// notch in line (DOM_DELTA_LINE) mode.
16	wheelLinesPerNotch = 3
17	// wheelNotchesPerPage converts page (DOM_DELTA_PAGE) mode into notches.
18	wheelNotchesPerPage = 10
19	// wheelMaxNotchesPerEvent caps the reports emitted for a single event.
20	wheelMaxNotchesPerEvent = 10
21	// wheelMaxAccumulated caps the retained remainder in notch units, so a
22	// violent momentum gesture cannot bank phantom scrolling.
23	wheelMaxAccumulated = 10.0
24	// wheelShiftMultiplier is the fast-scroll factor while Shift is held.
25	wheelShiftMultiplier = 10
26)
27
28// consumeWheel converts one wheel delta into whole-notch SGR reports. It
29// returns the report count and the SGR button (64 for up, 65 for down).
30// Sub-notch fractions accumulate on the terminal; a zero count means the
31// delta was banked for later. Shift multiplies the notch count for
32// predictable fast scrolling.
33func (t *Terminal) consumeWheel(deltaY float64, deltaMode int, shift bool) (int, int) {
34	t.mu.Lock()
35	defer t.mu.Unlock()
36	t.wheelAcc += wheelNotches(deltaY, deltaMode)
37	if t.wheelAcc > wheelMaxAccumulated {
38		t.wheelAcc = wheelMaxAccumulated
39	} else if t.wheelAcc < -wheelMaxAccumulated {
40		t.wheelAcc = -wheelMaxAccumulated
41	}
42	notches := int(t.wheelAcc)
43	t.wheelAcc -= float64(notches)
44	if t.wheelAcc < 1e-9 && t.wheelAcc > -1e-9 {
45		t.wheelAcc = 0
46	}
47	if notches == 0 {
48		return 0, 0
49	}
50	magnitude := notches
51	if magnitude < 0 {
52		magnitude = -magnitude
53	}
54	if magnitude > wheelMaxNotchesPerEvent {
55		magnitude = wheelMaxNotchesPerEvent
56		if notches < 0 {
57			notches = -magnitude
58		} else {
59			notches = magnitude
60		}
61	}
62	if shift {
63		magnitude *= wheelShiftMultiplier
64		if magnitude > wheelMaxNotchesPerEvent*wheelShiftMultiplier {
65			magnitude = wheelMaxNotchesPerEvent * wheelShiftMultiplier
66		}
67	}
68	button := 65
69	if notches < 0 {
70		button = 64
71	}
72	return magnitude, button
73}
74
75// resetWheel drops the banked wheel remainder. It runs when wheel input is
76// ignored (mouse tracking off, out-of-bounds cell) so a stale remainder
77// cannot leak into a later, unrelated scroll gesture.
78func (t *Terminal) resetWheel() {
79	t.mu.Lock()
80	defer t.mu.Unlock()
81	t.wheelAcc = 0
82}
83
84// wheelNotches converts a raw wheel delta into notch units. Unknown delta
85// modes contribute nothing rather than guessing a scale.
86func wheelNotches(deltaY float64, deltaMode int) float64 {
87	switch deltaMode {
88	case 0:
89		return deltaY / wheelPixelsPerNotch
90	case 1:
91		return deltaY / wheelLinesPerNotch
92	case 2:
93		return deltaY * wheelNotchesPerPage
94	default:
95		return 0
96	}
97}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close