mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-28 14:04:41 -07:00
feat(ui): enable "TerminalBuffer" mode to solve flicker (#24512)
This commit is contained in:
@@ -28,6 +28,7 @@ describe('useAlternateBuffer', () => {
|
||||
it('should return false when config.getUseAlternateBuffer returns false', async () => {
|
||||
mockUseConfig.mockReturnValue({
|
||||
getUseAlternateBuffer: () => false,
|
||||
getUseTerminalBuffer: () => false,
|
||||
} as unknown as ReturnType<typeof mockUseConfig>);
|
||||
|
||||
const { result } = await renderHook(() => useAlternateBuffer());
|
||||
@@ -37,6 +38,7 @@ describe('useAlternateBuffer', () => {
|
||||
it('should return true when config.getUseAlternateBuffer returns true', async () => {
|
||||
mockUseConfig.mockReturnValue({
|
||||
getUseAlternateBuffer: () => true,
|
||||
getUseTerminalBuffer: () => false,
|
||||
} as unknown as ReturnType<typeof mockUseConfig>);
|
||||
|
||||
const { result } = await renderHook(() => useAlternateBuffer());
|
||||
@@ -46,6 +48,7 @@ describe('useAlternateBuffer', () => {
|
||||
it('should return the immutable config value, not react to settings changes', async () => {
|
||||
const mockConfig = {
|
||||
getUseAlternateBuffer: () => true,
|
||||
getUseTerminalBuffer: () => false,
|
||||
} as unknown as ReturnType<typeof mockUseConfig>;
|
||||
|
||||
mockUseConfig.mockReturnValue(mockConfig);
|
||||
@@ -65,6 +68,7 @@ describe('isAlternateBufferEnabled', () => {
|
||||
it('should return true when config.getUseAlternateBuffer returns true', () => {
|
||||
const config = {
|
||||
getUseAlternateBuffer: () => true,
|
||||
getUseTerminalBuffer: () => false,
|
||||
} as unknown as Config;
|
||||
|
||||
expect(isAlternateBufferEnabled(config)).toBe(true);
|
||||
@@ -73,6 +77,7 @@ describe('isAlternateBufferEnabled', () => {
|
||||
it('should return false when config.getUseAlternateBuffer returns false', () => {
|
||||
const config = {
|
||||
getUseAlternateBuffer: () => false,
|
||||
getUseTerminalBuffer: () => false,
|
||||
} as unknown as Config;
|
||||
|
||||
expect(isAlternateBufferEnabled(config)).toBe(false);
|
||||
|
||||
@@ -7,8 +7,13 @@
|
||||
import { useConfig } from '../contexts/ConfigContext.js';
|
||||
import type { Config } from '@google/gemini-cli-core';
|
||||
|
||||
// This method is intentionally misleading while we migrate.
|
||||
// Once getUseTerminalBuffer() is always enabled we will refactor to remove
|
||||
// all instances of this method making it the only path.
|
||||
// Right now this is convenient as it allows us to special case terminalBuffer
|
||||
// rendering like we special case alternateBuffer rendering.
|
||||
export const isAlternateBufferEnabled = (config: Config): boolean =>
|
||||
config.getUseAlternateBuffer();
|
||||
config.getUseAlternateBuffer() || config.getUseTerminalBuffer();
|
||||
|
||||
// This is read from Config so that the UI reads the same value per application session
|
||||
export const useAlternateBuffer = (): boolean => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { useState, useLayoutEffect, useRef, useCallback } from 'react';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import { interpolateColor } from '../themes/color-utils.js';
|
||||
import { debugState } from '../debug.js';
|
||||
@@ -107,7 +107,7 @@ export function useAnimatedScrollbar(
|
||||
}, [cleanup]);
|
||||
|
||||
const wasFocused = useRef(isFocused);
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
if (isFocused && !wasFocused.current) {
|
||||
flashScrollbar();
|
||||
} else if (!isFocused && wasFocused.current) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { useRef, useEffect, useCallback } from 'react';
|
||||
import { useRef, useLayoutEffect, useCallback } from 'react';
|
||||
|
||||
/**
|
||||
* A hook to manage batched scroll state updates.
|
||||
@@ -17,7 +17,7 @@ export function useBatchedScroll(currentScrollTop: number) {
|
||||
// and not depend on the currentScrollTop value directly in its dependency array.
|
||||
const currentScrollTopRef = useRef(currentScrollTop);
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
currentScrollTopRef.current = currentScrollTop;
|
||||
pendingScrollTopRef.current = null;
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ import * as trustedFolders from '../../config/trustedFolders.js';
|
||||
import { coreEvents, ExitCodes, isHeadlessMode } from '@google/gemini-cli-core';
|
||||
import { MessageType } from '../types.js';
|
||||
|
||||
const mockedCwd = vi.hoisted(() => vi.fn());
|
||||
const mockedCwd = vi.hoisted(() => vi.fn().mockReturnValue('/mock/cwd'));
|
||||
const mockedExit = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock('@google/gemini-cli-core', async () => {
|
||||
|
||||
@@ -24,7 +24,7 @@ import type { LoadedSettings } from '../../config/settings.js';
|
||||
import { coreEvents } from '@google/gemini-cli-core';
|
||||
|
||||
// Hoist mocks
|
||||
const mockedCwd = vi.hoisted(() => vi.fn());
|
||||
const mockedCwd = vi.hoisted(() => vi.fn().mockReturnValue('/mock/cwd'));
|
||||
const mockedLoadTrustedFolders = vi.hoisted(() => vi.fn());
|
||||
const mockedIsWorkspaceTrusted = vi.hoisted(() => vi.fn());
|
||||
const mockedUseSettings = vi.hoisted(() => vi.fn());
|
||||
|
||||
Reference in New Issue
Block a user