mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
fix(terminal): keep the page-key fallback out of swipes, pinches, wheel notches and dialogs
Review follow-up for the hollow-pane PageUp/PageDown fallback (_maybePageCliTranscript): - A mostly horizontal wheel swipe (both deltas present, |deltaX| > |deltaY|) is consumed without paging. The touch path already locks its axis. - A pinch (wheel events with ctrlKey, as Chrome reports one) is consumed without paging. - Only a trackpad-sized opening event (under 2 rows) pages at once. A wheel notch (100 px, 4 rows) accumulates toward half a screen as before, so five slow notches send one PageUp again instead of five. A debt from a pre-paid page still dies with its gesture; plain wheel travel carries across notches. - Nothing pages while the active tab's alert is 'action' (a pending permission_prompt or elicitation_dialog), so a page key never reaches an open dialog's selector. Docs: the invariants paragraph now says which Codex versions were seen drawing on the alt screen (0.157.1, 0.160) and that 0.147.0 still draws inline, without claiming a cutoff.
This commit is contained in:
1 parent
2eff6dcbdd
commit
a4926e49f1
3 files changed
+103
-13
No files matched your search
@@ -172,14 +172,15 @@ describe('PageUp/PageDown fallback for a hollow local buffer (issue #205 round 2
|
||||
it('answers the first event of a gesture at once and owes the travel back', () => {
|
||||
const { app, sent } = hollowApp();
|
||||
|
||||
// A trackpad flick is far less than half a screen (18 rows here). It used to
|
||||
// send nothing at all, so a session that always lands here looked dead.
|
||||
expect(app._maybePageCliTranscript({ shiftKey: false }, -10)).toBe(true);
|
||||
// A trackpad flick opens with a small delta and stays far short of half a
|
||||
// screen (18 rows here). It used to send nothing at all, so a session that
|
||||
// always lands here looked dead.
|
||||
expect(app._maybePageCliTranscript({ shiftKey: false }, -1)).toBe(true);
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([{ id: 'sess-1', data: '\x1b[5~' }]);
|
||||
|
||||
// The pre-paid page is owed back: the rest of this page's travel sends nothing…
|
||||
app._maybePageCliTranscript({ shiftKey: false }, -8);
|
||||
app._maybePageCliTranscript({ shiftKey: false }, -17);
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toHaveLength(1);
|
||||
|
||||
@@ -200,15 +201,79 @@ describe('PageUp/PageDown fallback for a hollow local buffer (issue #205 round 2
|
||||
let now = 1_000;
|
||||
clock.now = () => now;
|
||||
|
||||
app._maybePageCliTranscript({ shiftKey: false }, -2); // first event: one PageUp
|
||||
app._maybePageCliTranscript({ shiftKey: false }, 2); // reversal: one PageDown at once
|
||||
app._maybePageCliTranscript({ shiftKey: false }, -1); // first event: one PageUp
|
||||
app._maybePageCliTranscript({ shiftKey: false }, 1); // reversal: one PageDown at once
|
||||
now += 1_000;
|
||||
app._maybePageCliTranscript({ shiftKey: false }, 2); // after a pause: another at once
|
||||
app._maybePageCliTranscript({ shiftKey: false }, 1); // after a pause: another at once
|
||||
app._maybePageCliTranscript({ shiftKey: false }, 0.05); // sub-row jitter in the same gesture: nothing
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([{ id: 'sess-1', data: '\x1b[5~\x1b[6~\x1b[6~' }]);
|
||||
});
|
||||
|
||||
it('lets wheel notches accumulate instead of paging a full screen on each one', () => {
|
||||
// A 100 px notch is 4 rows. Only a trackpad-sized opening event (under 2 rows)
|
||||
// pages at once; a notch adds up toward half a screen as it always did, so
|
||||
// slow notches (each one its own gesture by the 150 ms gap) still page once
|
||||
// per 18 rows here, not once per notch.
|
||||
for (const gapMs of [250, 40]) {
|
||||
const { app, sent, clock } = hollowApp();
|
||||
let now = 1_000;
|
||||
clock.now = () => now;
|
||||
for (let i = 0; i < 5; i++) {
|
||||
expect(app._maybePageCliTranscript({ shiftKey: false, deltaY: -100 }, -4)).toBe(true);
|
||||
now += gapMs;
|
||||
}
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([{ id: 'sess-1', data: '\x1b[5~' }]);
|
||||
}
|
||||
});
|
||||
|
||||
it('consumes a mostly horizontal swipe without paging', () => {
|
||||
const { app, sent } = hollowApp();
|
||||
|
||||
// A sideways trackpad swipe carries a little vertical drift (3 px is 0.12 rows,
|
||||
// above the jitter floor). It must not page the transcript.
|
||||
for (let i = 0; i < 6; i++) {
|
||||
expect(app._maybePageCliTranscript({ shiftKey: false, deltaX: 60, deltaY: 3 }, 0.12)).toBe(true);
|
||||
}
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([]);
|
||||
|
||||
// A mostly vertical swipe with some sideways drift still pages.
|
||||
app._maybePageCliTranscript({ shiftKey: false, deltaX: 3, deltaY: -25 }, -1);
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([{ id: 'sess-1', data: '\x1b[5~' }]);
|
||||
});
|
||||
|
||||
it('consumes a trackpad pinch without paging', () => {
|
||||
const { app, sent } = hollowApp();
|
||||
|
||||
// Chrome reports a pinch as wheel events with ctrlKey set.
|
||||
for (let i = 0; i < 4; i++) {
|
||||
expect(app._maybePageCliTranscript({ shiftKey: false, ctrlKey: true, deltaY: 4 }, 0.16)).toBe(true);
|
||||
}
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([]);
|
||||
});
|
||||
|
||||
it('does not page while the session is showing a dialog', () => {
|
||||
const { app, sent } = hollowApp();
|
||||
// 'action' is set while a permission_prompt or elicitation_dialog is pending
|
||||
// (updateTabAlertFromHooks in app.js). Page keys must not reach that selector.
|
||||
app.tabAlerts = new Map([['sess-1', 'action']]);
|
||||
|
||||
expect(app._maybePageCliTranscript({ shiftKey: false }, -1)).toBe(true);
|
||||
expect(app._maybePageCliTranscript({ shiftKey: false }, -40)).toBe(true);
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([]);
|
||||
|
||||
// Once the dialog is answered (an idle alert, or none) paging resumes.
|
||||
app.tabAlerts.set('sess-1', 'idle');
|
||||
app._maybePageCliTranscript({ shiftKey: false }, 1);
|
||||
app._flushWheelSgrQueue();
|
||||
expect(sent).toEqual([{ id: 'sess-1', data: '\x1b[6~' }]);
|
||||
});
|
||||
|
||||
it('does not page on sub-row jitter that opens a gesture', () => {
|
||||
const { app, sent } = hollowApp();
|
||||
|
||||
|
||||
Reference in new issue
Block a user