mirror of
https://github.com/stablyai/orca.git
synced 2026-10-27 08:02:51 +00:00
Preserve terminal scrollback when restoring a hidden alternate-screen pane
On Windows, an alternate-screen TUI pane (Claude Code) could lose scroll-up after being hidden (tab/worktree switch or app backgrounded) and shown again. Root cause: on hidden->visible restore, applyMainBufferSnapshot unconditionally wrote a destructive clear (\x1b[2J\x1b[3J\x1b[H) before replaying the snapshot, wiping xterm's scrollback. The attach/reattach path already guards this same clear behind !isAlternateScreen (pty-transport.ts); the snapshot path did not. Thread an alternateScreen flag from the backend headless serialization through the pty:getMainBufferSnapshot IPC + preload types into applyMainBufferSnapshot, and skip the destructive clear when restoring an alternate-screen buffer. Add a regression test asserting the clear is NOT emitted for an alt-screen restore (and the existing normal-buffer test still asserts it IS). Fixes #5723
This commit is contained in:
@@ -5262,6 +5262,7 @@ export class OrcaRuntimeService {
|
||||
seq?: number
|
||||
source?: 'headless' | 'renderer'
|
||||
oscLinks?: TerminalOscLinkRange[]
|
||||
alternateScreen?: boolean
|
||||
} | null> {
|
||||
return this.serializeTerminalBufferFromAvailableState(ptyId, opts)
|
||||
}
|
||||
@@ -5278,6 +5279,7 @@ export class OrcaRuntimeService {
|
||||
seq?: number
|
||||
source?: 'headless' | 'renderer'
|
||||
oscLinks?: TerminalOscLinkRange[]
|
||||
alternateScreen?: boolean
|
||||
} | null> {
|
||||
return this.serializeHeadlessTerminalBuffer(ptyId, { ...opts, includeEmpty: true })
|
||||
}
|
||||
@@ -5294,6 +5296,7 @@ export class OrcaRuntimeService {
|
||||
seq?: number
|
||||
source?: 'headless' | 'renderer'
|
||||
oscLinks?: TerminalOscLinkRange[]
|
||||
alternateScreen?: boolean
|
||||
} | null> {
|
||||
const headlessSnapshot = await this.serializeHeadlessTerminalBuffer(ptyId, {
|
||||
...opts,
|
||||
@@ -5540,6 +5543,7 @@ export class OrcaRuntimeService {
|
||||
seq?: number
|
||||
source?: 'headless' | 'renderer'
|
||||
oscLinks?: TerminalOscLinkRange[]
|
||||
alternateScreen?: boolean
|
||||
} | null> {
|
||||
const headlessSnapshot = await this.serializeHeadlessTerminalBuffer(ptyId, opts)
|
||||
if (headlessSnapshot) {
|
||||
@@ -5650,6 +5654,7 @@ export class OrcaRuntimeService {
|
||||
seq?: number
|
||||
source?: 'headless'
|
||||
oscLinks?: TerminalOscLinkRange[]
|
||||
alternateScreen?: boolean
|
||||
} | null> {
|
||||
const state = this.headlessTerminals.get(ptyId)
|
||||
if (!state) {
|
||||
@@ -5664,7 +5669,8 @@ export class OrcaRuntimeService {
|
||||
// caller can request scrollback so the user can scroll up to see prior
|
||||
// agent output.
|
||||
const requested = opts.scrollbackRows ?? 0
|
||||
const scrollbackRows = state.emulator.isAlternateScreen ? 0 : requested
|
||||
const isAlternateScreen = state.emulator.isAlternateScreen
|
||||
const scrollbackRows = isAlternateScreen ? 0 : requested
|
||||
const snapshot = state.emulator.getSnapshot({ scrollbackRows })
|
||||
const data = snapshot.rehydrateSequences + snapshot.snapshotAnsi
|
||||
return data.length > 0 || opts.includeEmpty === true
|
||||
@@ -5676,7 +5682,11 @@ export class OrcaRuntimeService {
|
||||
lastTitle: snapshot.lastTitle,
|
||||
seq: state.outputSequence,
|
||||
source: 'headless',
|
||||
oscLinks: snapshot.oscLinks
|
||||
oscLinks: snapshot.oscLinks,
|
||||
// Why: lets the renderer skip the destructive scrollback clear when
|
||||
// restoring an alt-screen snapshot — clearing wipes xterm's own
|
||||
// history that the TUI relies on for scroll-up after a tab return.
|
||||
alternateScreen: isAlternateScreen
|
||||
}
|
||||
: null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user