diff --git a/packages/cli/src/ui/AppContainer.test.tsx b/packages/cli/src/ui/AppContainer.test.tsx
index 355195d90d..13550d3f42 100644
--- a/packages/cli/src/ui/AppContainer.test.tsx
+++ b/packages/cli/src/ui/AppContainer.test.tsx
@@ -2770,7 +2770,7 @@ describe('AppContainer State Management', () => {
unmount();
});
- it('should exit copy mode on any key press', async () => {
+ it('should exit copy mode on non-scroll key press', async () => {
await setupCopyModeTest(isAlternateMode);
// Enter copy mode
@@ -2792,6 +2792,61 @@ describe('AppContainer State Management', () => {
unmount();
});
+ it('should not exit copy mode on PageDown and should pass it through', async () => {
+ const childHandler = vi.fn().mockReturnValue(false);
+ await setupCopyModeTest(true, childHandler);
+
+ // Enter copy mode
+ act(() => {
+ stdin.write('\x13'); // Ctrl+S
+ });
+ rerender();
+ expect(disableMouseEvents).toHaveBeenCalled();
+
+ childHandler.mockClear();
+ (enableMouseEvents as Mock).mockClear();
+
+ // PageDown should be passed through to lower-priority handlers.
+ act(() => {
+ stdin.write('\x1b[6~');
+ });
+ rerender();
+
+ expect(enableMouseEvents).not.toHaveBeenCalled();
+ expect(childHandler).toHaveBeenCalled();
+ expect(childHandler).toHaveBeenCalledWith(
+ expect.objectContaining({ name: 'pagedown' }),
+ );
+ unmount();
+ });
+
+ it('should not exit copy mode on Shift+Down and should pass it through', async () => {
+ const childHandler = vi.fn().mockReturnValue(false);
+ await setupCopyModeTest(true, childHandler);
+
+ // Enter copy mode
+ act(() => {
+ stdin.write('\x13'); // Ctrl+S
+ });
+ rerender();
+ expect(disableMouseEvents).toHaveBeenCalled();
+
+ childHandler.mockClear();
+ (enableMouseEvents as Mock).mockClear();
+
+ act(() => {
+ stdin.write('\x1b[1;2B'); // Shift+Down
+ });
+ rerender();
+
+ expect(enableMouseEvents).not.toHaveBeenCalled();
+ expect(childHandler).toHaveBeenCalled();
+ expect(childHandler).toHaveBeenCalledWith(
+ expect.objectContaining({ name: 'down', shift: true }),
+ );
+ unmount();
+ });
+
it('should have higher priority than other priority listeners when enabled', async () => {
// 1. Initial state with a child component's priority listener (already subscribed)
// It should NOT handle Ctrl+S so we can enter copy mode.
diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx
index 2e5e4554dd..03e001546b 100644
--- a/packages/cli/src/ui/AppContainer.tsx
+++ b/packages/cli/src/ui/AppContainer.tsx
@@ -1864,7 +1864,18 @@ Logging in with Google... Restarting Gemini CLI to continue.
useKeypress(handleGlobalKeypress, { isActive: true, priority: true });
useKeypress(
- () => {
+ (key: Key) => {
+ if (
+ keyMatchers[Command.SCROLL_UP](key) ||
+ keyMatchers[Command.SCROLL_DOWN](key) ||
+ keyMatchers[Command.PAGE_UP](key) ||
+ keyMatchers[Command.PAGE_DOWN](key) ||
+ keyMatchers[Command.SCROLL_HOME](key) ||
+ keyMatchers[Command.SCROLL_END](key)
+ ) {
+ return false;
+ }
+
setCopyModeEnabled(false);
enableMouseEvents();
return true;
diff --git a/packages/cli/src/ui/components/CopyModeWarning.test.tsx b/packages/cli/src/ui/components/CopyModeWarning.test.tsx
index de7cb3a888..6f202ced4a 100644
--- a/packages/cli/src/ui/components/CopyModeWarning.test.tsx
+++ b/packages/cli/src/ui/components/CopyModeWarning.test.tsx
@@ -35,7 +35,8 @@ describe('CopyModeWarning', () => {
const { lastFrame, waitUntilReady, unmount } = render();
await waitUntilReady();
expect(lastFrame()).toContain('In Copy Mode');
- expect(lastFrame()).toContain('Press any key to exit');
+ expect(lastFrame()).toContain('Use Page Up/Down to scroll');
+ expect(lastFrame()).toContain('Press Ctrl+S or any other key to exit');
unmount();
});
});
diff --git a/packages/cli/src/ui/components/CopyModeWarning.tsx b/packages/cli/src/ui/components/CopyModeWarning.tsx
index 8d5423bb89..4b6328274b 100644
--- a/packages/cli/src/ui/components/CopyModeWarning.tsx
+++ b/packages/cli/src/ui/components/CopyModeWarning.tsx
@@ -19,7 +19,8 @@ export const CopyModeWarning: React.FC = () => {
return (
- In Copy Mode. Press any key to exit.
+ In Copy Mode. Use Page Up/Down to scroll. Press Ctrl+S or any other key
+ to exit.
);