From 1413da8899737fbd64ab2e24aea78a020b7ec3f8 Mon Sep 17 00:00:00 2001 From: victorwon2001 <192616110+victorwon2001@users.noreply.github.com> Date: Thu, 3 Sep 2026 22:26:14 +0900 Subject: [PATCH] =?UTF-8?q?fix(terminal):=20=E7=AA=97=E5=8F=A3=E9=87=8D?= =?UTF-8?q?=E6=96=B0=E8=81=9A=E7=84=A6=E6=97=B6=E5=BC=BA=E5=88=B6=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E7=BB=88=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../useTerminalRefreshEffects.test.ts | 43 ++++++++++++++++++- .../terminal/useTerminalRefreshEffects.ts | 2 +- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/components/terminal/useTerminalRefreshEffects.test.ts b/src/components/terminal/useTerminalRefreshEffects.test.ts index 095a098d..1e65ac97 100644 --- a/src/components/terminal/useTerminalRefreshEffects.test.ts +++ b/src/components/terminal/useTerminalRefreshEffects.test.ts @@ -5,6 +5,7 @@ import type { TerminalFitScheduler } from "./terminalFitScheduler"; import { useTerminalRefreshEffects } from "./useTerminalRefreshEffects"; const windowMocks = vi.hoisted(() => ({ + focusChanged: undefined as ((event: { payload: boolean }) => void) | undefined, scaleChanged: undefined as | ((event: { payload: { scaleFactor: number } }) => void) | undefined, @@ -14,7 +15,10 @@ vi.mock("@tauri-apps/api/window", () => ({ getCurrentWindow: () => ({ onResized: async () => vi.fn(), onMoved: async () => vi.fn(), - onFocusChanged: async () => vi.fn(), + onFocusChanged: async (callback: (event: { payload: boolean }) => void) => { + windowMocks.focusChanged = callback; + return vi.fn(); + }, onScaleChanged: async ( callback: (event: { payload: { scaleFactor: number } }) => void, ) => { @@ -26,6 +30,7 @@ vi.mock("@tauri-apps/api/window", () => ({ describe("useTerminalRefreshEffects", () => { beforeEach(() => { + windowMocks.focusChanged = undefined; windowMocks.scaleChanged = undefined; }); @@ -56,6 +61,42 @@ describe("useTerminalRefreshEffects", () => { expect(activeRefresh).not.toHaveProperty("clearTextureAtlas"); }); + it("forces fit and repaint when the native window regains focus", async () => { + const schedule = vi.fn(); + renderHook(() => + useTerminalRefreshEffects({ + terminalRef: { current: {} as Terminal }, + fitSchedulerRef: { + current: { schedule } as unknown as TerminalFitScheduler, + }, + active: true, + visible: true, + terminalReady: true, + performanceMode: "normal", + sessionId: "session-1", + showGutter: false, + showContentPadding: false, + }), + ); + await waitFor(() => expect(windowMocks.focusChanged).toBeTypeOf("function")); + schedule.mockClear(); + + windowMocks.focusChanged?.({ payload: false }); + expect(schedule).not.toHaveBeenCalled(); + + windowMocks.focusChanged?.({ payload: true }); + expect(schedule).toHaveBeenCalledTimes(1); + expect(schedule).toHaveBeenCalledWith( + expect.objectContaining({ + reason: "window-focus", + force: true, + refresh: true, + clearTextureAtlas: false, + focus: true, + }), + ); + }); + it("still invalidates textures after a DPI scale change", async () => { const schedule = vi.fn(); renderHook(() => diff --git a/src/components/terminal/useTerminalRefreshEffects.ts b/src/components/terminal/useTerminalRefreshEffects.ts index fb3a6181..e2c205af 100644 --- a/src/components/terminal/useTerminalRefreshEffects.ts +++ b/src/components/terminal/useTerminalRefreshEffects.ts @@ -202,7 +202,7 @@ export function useTerminalRefreshEffects({ .catch(() => {}); appWindow .onFocusChanged(({ payload }) => { - if (!disposed && payload) scheduleWindowFit("window-focus"); + if (!disposed && payload) scheduleWindowFit("window-focus", true); }) .then((unlisten) => { unlistenFocused = unlisten;