feat: Auto-scroll to bottom via Events

feat: Auto-scroll to bottom on exiting mouse mode
This commit is contained in:
jacob314
2026-04-01 12:29:54 -07:00
parent fd8355472a
commit ff0902e608
5 changed files with 31 additions and 1 deletions
+7 -1
View File
@@ -1755,7 +1755,13 @@ Logging in with Google... Restarting Gemini CLI to continue.
}
if (keyMatchers[Command.TOGGLE_MOUSE_MODE](key)) {
setMouseMode((prev) => !prev);
setMouseMode((prev) => {
const next = !prev;
if (!next && !isAlternateBuffer) {
appEvents.emit(AppEvent.ScrollToBottom);
}
return next;
});
return true;
}
@@ -26,6 +26,7 @@ import { OverflowProvider } from '../contexts/OverflowContext.js';
import { ConfigInitDisplay } from './ConfigInitDisplay.js';
import { TodoTray } from './messages/Todo.js';
import { useComposerStatus } from '../hooks/useComposerStatus.js';
import { appEvents, AppEvent } from '../../utils/events.js';
export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
const uiState = useUIState();
@@ -55,6 +56,12 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
const { setShortcutsHelpVisible } = uiActions;
useEffect(() => {
if (hasPendingActionRequired) {
appEvents.emit(AppEvent.ScrollToBottom);
}
}, [hasPendingActionRequired]);
useEffect(() => {
if (uiState.shortcutsHelpVisible && !isPassiveShortcutsHelpState) {
setShortcutsHelpVisible(false);
@@ -338,6 +338,10 @@ export const InputPrompt: React.FC<InputPromptProps> = ({
const showCursor =
focus && isShellFocused && !isEmbeddedShellFocused && !copyModeEnabled;
useEffect(() => {
appEvents.emit(AppEvent.ScrollToBottom);
}, [buffer.text, buffer.cursor]);
// Notify parent component about escape prompt state changes
useEffect(() => {
if (onEscapePromptChange) {
@@ -23,6 +23,7 @@ import { MAX_GEMINI_MESSAGE_LINES } from '../constants.js';
import { useConfirmingTool } from '../hooks/useConfirmingTool.js';
import { ToolConfirmationQueue } from './ToolConfirmationQueue.js';
import { isTopicTool } from './messages/TopicMessage.js';
import { appEvents, AppEvent } from '../../utils/events.js';
const MemoizedHistoryItemDisplay = memo(HistoryItemDisplay);
const MemoizedAppHeader = memo(AppHeader);
@@ -53,6 +54,16 @@ export const MainContent = () => {
}
}, [showConfirmationQueue, confirmingToolCallId]);
useEffect(() => {
const handleScroll = () => {
scrollableListRef.current?.scrollToEnd();
};
appEvents.on(AppEvent.ScrollToBottom, handleScroll);
return () => {
appEvents.off(AppEvent.ScrollToBottom, handleScroll);
};
}, []);
const {
pendingHistoryItems,
mainAreaWidth,
+2
View File
@@ -23,6 +23,7 @@ export enum AppEvent {
PasteTimeout = 'paste-timeout',
TerminalBackground = 'terminal-background',
TransientMessage = 'transient-message',
ScrollToBottom = 'scroll-to-bottom',
}
export interface AppEvents {
@@ -32,6 +33,7 @@ export interface AppEvents {
[AppEvent.PasteTimeout]: never[];
[AppEvent.TerminalBackground]: [string];
[AppEvent.TransientMessage]: [TransientMessagePayload];
[AppEvent.ScrollToBottom]: never[];
}
export const appEvents = new EventEmitter<AppEvents>();