fix(terminal): 窗口重新聚焦时强制刷新终端

This commit is contained in:
victorwon2001 committed 2026-09-03 22:26:14 +09:00
1 parent f9e52a3e54
commit 1413da8899
2 files changed
+43 -2

No files matched your search

@@ -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(() =>
@@ -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;