Skip to content

Commit 9861330

Browse files
committed
fix: clear terminal viewport when switching sessions
1 parent 3dbe1b7 commit 9861330

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

apps/web/src/App.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,24 @@ export default function App() {
703703
term.clear();
704704
}, []);
705705

706+
const prepareSessionSwitch = useCallback(() => {
707+
const term = termRef.current;
708+
if (term) {
709+
term.clear();
710+
}
711+
712+
outboxRef.current.chunks.length = 0;
713+
outboxRef.current.bytes = 0;
714+
outboxRef.current.droppedBytes = 0;
715+
pendingResizeRef.current = null;
716+
717+
setOutputBytes(0);
718+
setQueuedInputBytes(0);
719+
setDroppedInputBytes(0);
720+
}, []);
721+
706722
const startFreshSession = useCallback(() => {
723+
prepareSessionSwitch();
707724
setSessionMode("control");
708725
sessionIdRef.current = undefined;
709726
setSessionId("");
@@ -733,14 +750,15 @@ export default function App() {
733750
}
734751

735752
connect();
736-
}, [connect, setSessionMode]);
753+
}, [connect, prepareSessionSwitch, setSessionMode]);
737754

738755
const resumeSession = useCallback(
739756
(targetSessionId: string, mode: AttachMode = "control") => {
740757
if (!targetSessionId) {
741758
return;
742759
}
743760

761+
prepareSessionSwitch();
744762
setSessionMode(mode);
745763
sessionIdRef.current = targetSessionId;
746764
setSessionId(targetSessionId);
@@ -753,7 +771,7 @@ export default function App() {
753771

754772
reconnectNow();
755773
},
756-
[reconnectNow, setSessionMode],
774+
[prepareSessionSwitch, reconnectNow, setSessionMode],
757775
);
758776

759777
const resumePreviousSession = useCallback(() => {

apps/web/test/app.integration.test.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const runtime = vi.hoisted(() => {
2929
cols = 80;
3030
rows = 24;
3131
options: { fontSize: number };
32+
clearCalls = 0;
3233

3334
private dataHandlers = new Set<(data: string) => void>();
3435

@@ -55,7 +56,7 @@ const runtime = vi.hoisted(() => {
5556
}
5657

5758
clear(): void {
58-
// no-op for tests
59+
this.clearCalls += 1;
5960
}
6061

6162
dispose(): void {
@@ -337,8 +338,15 @@ describe("App integration", () => {
337338
await act(async () => {
338339
ws1.triggerOpen();
339340
ws1.triggerMessage({ type: "ready", sessionId: "session-old" });
341+
ws1.triggerMessage({ type: "output", data: "hello\n" });
340342
});
341343

344+
expect(screen.getByTestId("output-value").getAttribute("data-bytes")).toBe(
345+
"6",
346+
);
347+
const terminal = runtime.FakeTerminal.instances[0];
348+
expect(terminal.clearCalls).toBe(0);
349+
342350
const attachFirst = sentMessages(ws1).find(
343351
(message) => message.type === "attach",
344352
);
@@ -352,6 +360,11 @@ describe("App integration", () => {
352360
fireEvent.click(screen.getByTestId("session-menu-new"));
353361
});
354362

363+
expect(screen.getByTestId("output-value").getAttribute("data-bytes")).toBe(
364+
"0",
365+
);
366+
expect(terminal.clearCalls).toBe(1);
367+
355368
await waitFor(
356369
() => {
357370
expect(MockWebSocket.instances.length).toBe(2);
@@ -416,6 +429,9 @@ describe("App integration", () => {
416429
fireEvent.click(screen.getByTestId("session-menu-resume-last"));
417430
});
418431

432+
const terminal = runtime.FakeTerminal.instances[0];
433+
expect(terminal.clearCalls).toBe(1);
434+
419435
await waitFor(
420436
() => {
421437
expect(MockWebSocket.instances.length).toBe(2);

0 commit comments

Comments
 (0)