mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
feat(tui,coding-agent): configurable fullscreen wheel scrolling with auto acceleration
Adds fullscreenWheelScrollLines ("auto" or 1-100). Auto keeps one line
per event in local macOS terminals and scales with wheel velocity
elsewhere, capped at six lines per event.
closes #9758
This commit is contained in:
parent
8562bcf66a
commit
f1927c2d56
16 changed files with 275 additions and 20 deletions
|
|
@ -504,6 +504,31 @@ describe("TuiAltScreen", () => {
|
|||
tui.stop();
|
||||
});
|
||||
|
||||
// #9758: wheel line counts can change at runtime; Alt keeps its multiplier.
|
||||
it("applies runtime wheel line count updates", async () => {
|
||||
const terminal = new VirtualTerminal(20, 4);
|
||||
const tui = new TuiAltScreen(terminal, undefined, undefined, { wheelScrollLines: 3 });
|
||||
const deltas: Array<number | undefined> = [];
|
||||
tui.addChild(
|
||||
new MouseRegion(new Text("wheel target", 0, 0), (event) => {
|
||||
if (event.type !== "wheel") return undefined;
|
||||
deltas.push(event.wheelDelta);
|
||||
return { handled: true };
|
||||
}),
|
||||
);
|
||||
tui.start();
|
||||
try {
|
||||
await terminal.waitForRender();
|
||||
terminal.sendInput("\x1b[<64;1;1M");
|
||||
tui.setWheelScrollLines(2);
|
||||
terminal.sendInput("\x1b[<65;1;1M");
|
||||
terminal.sendInput("\x1b[<72;1;1M");
|
||||
assert.deepStrictEqual(deltas, [-3, 2, -10]);
|
||||
} finally {
|
||||
tui.stop();
|
||||
}
|
||||
});
|
||||
|
||||
it("chains unused wheel delta to an outer scroll view", async () => {
|
||||
const terminal = new VirtualTerminal(20, 4);
|
||||
const tui = new TuiAltScreen(terminal, undefined, undefined, { wheelScrollLines: 3 });
|
||||
|
|
|
|||
47
packages/tui/test/wheel-scroll.test.ts
Normal file
47
packages/tui/test/wheel-scroll.test.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import assert from "node:assert";
|
||||
import { describe, it } from "node:test";
|
||||
import { WheelScrollAccelerator } from "../src/wheel-scroll.ts";
|
||||
|
||||
function scroll(accelerator: WheelScrollAccelerator, times: number[], direction: -1 | 1 = 1): number[] {
|
||||
return times.map((time) => accelerator.next(direction, time));
|
||||
}
|
||||
|
||||
// #9758: fullscreen wheel scrolling was one line per notch on terminals that do not accelerate wheels.
|
||||
describe("WheelScrollAccelerator", () => {
|
||||
it("uses fixed line counts regardless of timing", () => {
|
||||
const accelerator = new WheelScrollAccelerator(3, true);
|
||||
assert.deepStrictEqual(scroll(accelerator, [0, 10, 20, 1000]), [3, 3, 3, 3]);
|
||||
accelerator.setLines(0.5);
|
||||
assert.strictEqual(accelerator.next(1, 2000), 1);
|
||||
});
|
||||
|
||||
it("keeps one line per event in auto mode when the terminal already accelerates", () => {
|
||||
const accelerator = new WheelScrollAccelerator("auto", false);
|
||||
assert.deepStrictEqual(scroll(accelerator, [0, 10, 20, 30]), [1, 1, 1, 1]);
|
||||
});
|
||||
|
||||
it("scales auto mode with wheel velocity", () => {
|
||||
const accelerator = new WheelScrollAccelerator("auto", true);
|
||||
assert.deepStrictEqual(scroll(accelerator, [0, 150, 300, 450]), [1, 1, 1, 1]);
|
||||
assert.deepStrictEqual(scroll(accelerator, [1000, 1050, 1100, 1150]), [1, 2, 2, 2]);
|
||||
assert.deepStrictEqual(scroll(accelerator, [2000, 2020, 2040, 2060]), [1, 5, 5, 5]);
|
||||
assert.deepStrictEqual(scroll(accelerator, [3000, 3010, 3020, 3030]), [1, 6, 6, 6]);
|
||||
});
|
||||
|
||||
it("does not accelerate bursts of events for a single notch", () => {
|
||||
const accelerator = new WheelScrollAccelerator("auto", true);
|
||||
assert.deepStrictEqual(scroll(accelerator, [0, 3, 6, 9]), [1, 1, 1, 1]);
|
||||
});
|
||||
|
||||
it("resets acceleration on direction changes and pauses", () => {
|
||||
const accelerator = new WheelScrollAccelerator("auto", true);
|
||||
assert.deepStrictEqual(scroll(accelerator, [0, 20, 40]), [1, 5, 5]);
|
||||
assert.strictEqual(accelerator.next(-1, 60), 1);
|
||||
assert.deepStrictEqual(scroll(accelerator, [500, 520]), [1, 5]);
|
||||
});
|
||||
|
||||
it("carries fractional lines between events", () => {
|
||||
const accelerator = new WheelScrollAccelerator("auto", true);
|
||||
assert.deepStrictEqual(scroll(accelerator, [0, 40, 80, 120, 160]), [1, 2, 3, 2, 3]);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue