mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 18:37:24 +00:00
fix(cloud): WAKE-SCROLLBACK a pane remounted on wake paints its kept output at once (the blank frames were the fresh xterm before the snapshot)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { PaneManager } from '@/lib/pane-manager/pane-manager'
|
||||
import { useAppStore } from '@/store/index'
|
||||
import { wakeScrollbackPreview } from '@/lib/orca-cloud/cloud-wake-scrollback'
|
||||
import { applyExpandedLayoutTo } from './expand/expanded-pane-layout'
|
||||
import { replayTerminalLayout } from './terminal-layout-replay'
|
||||
import { restoreScrollbackBuffers } from '../snapshots/saved-terminal-output-replay'
|
||||
@@ -48,6 +49,14 @@ export function restoreTerminalPaneLayout(args: {
|
||||
refs.restoredViewportBlankingPanesRef,
|
||||
liveAltScreenLeafIds
|
||||
)
|
||||
// WAKE-SCROLLBACK: waking remounts a cloud pane with a fresh, empty xterm; paint its kept pre-sleep
|
||||
// output now (client-side, text + SGR) so it never shows blank before the woken snapshot's restore.
|
||||
for (const pane of manager.getPanes()) {
|
||||
const preview = wakeScrollbackPreview(pane.leafId)
|
||||
if (preview !== null) {
|
||||
pane.terminal.write(preview)
|
||||
}
|
||||
}
|
||||
const hasScrollbackRefs = Boolean(initialLayoutRef.current.scrollbackRefsByLeafId)
|
||||
if (
|
||||
restoredBuffers &&
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
finishWakeScrollbackRestore,
|
||||
forgetWakeScrollback,
|
||||
hasPendingWakeScrollback,
|
||||
wakeScrollbackPreview,
|
||||
resetWakeScrollbackForTests
|
||||
} from './cloud-wake-scrollback'
|
||||
|
||||
@@ -243,6 +244,16 @@ describe('WAKE-SCROLLBACK', () => {
|
||||
expect(beginWakeScrollbackRestore('leaf-1', terminal)?.block).toContain('new')
|
||||
})
|
||||
|
||||
it('a pane remounted on wake (fresh, empty xterm) is painted with its kept output at once', async () => {
|
||||
const before = pane(6)
|
||||
await write(before, '\x1b[32m$ ls\x1b[0m\r\nREADME\r\n$ ')
|
||||
capture(before, 'leaf-1')
|
||||
const remounted = pane(6)
|
||||
await write(remounted, wakeScrollbackPreview('leaf-1')!)
|
||||
expect(text(remounted)).toEqual(['$ ls', 'README', '$'])
|
||||
expect(wakeScrollbackPreview('leaf-none')).toBeNull()
|
||||
})
|
||||
|
||||
it('reports a pending restore only when there is output to put back', async () => {
|
||||
const empty = pane(4)
|
||||
captureWakeScrollback('leaf-e', empty, { sleptAt: SLEPT_AT, agentPane: false, maxRows: 5000 })
|
||||
|
||||
@@ -124,6 +124,15 @@ export function armWakeScrollback(leafIds: Iterable<string>): void {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* What a freshly mounted pane shows until its woken snapshot's restore: the kept output alone
|
||||
* (text + SGR only), or null when there is none.
|
||||
*/
|
||||
export function wakeScrollbackPreview(leafId: string): string | null {
|
||||
const text = pending.get(leafId)?.text ?? null
|
||||
return text === null ? null : `\x1b[0m${sanitizeRestoredText(text)}\x1b[0m`
|
||||
}
|
||||
|
||||
/** The pane has pre-sleep output waiting to be put back after its wake. */
|
||||
export function hasPendingWakeScrollback(leafId: string): boolean {
|
||||
return (pending.get(leafId)?.text ?? null) !== null
|
||||
|
||||
Reference in New Issue
Block a user