mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 00:02:31 +00:00
fix(terminal): make selection guard test-safe
This commit is contained in:
@@ -23,6 +23,7 @@ import { TERMINAL_FOCUS_IN_SEQUENCE, TERMINAL_FOCUS_OUT_SEQUENCE } from './foreg
|
||||
import { isRemoteRuntimePtyId } from './paired-parked-terminal-restore'
|
||||
import { isCodexPaneStale } from './codex-pane-stale'
|
||||
import { installTerminalSelectionFitGuard } from '../terminal-selection-fit-guard'
|
||||
import { initializePaneGeometry, readPaneSize } from './read-pane-size'
|
||||
|
||||
import type { ConnectPanePtySession } from './connect-pane-pty-session'
|
||||
|
||||
@@ -308,12 +309,9 @@ export function installPtyInputForward(session: ConnectPanePtySession): void {
|
||||
if (reattachCols > 0 && reattachRows > 0) {
|
||||
session.transport.resize(reattachCols, reattachRows)
|
||||
}
|
||||
// Why: POSIX only sends SIGWINCH on an actual dimension change; signal explicitly so restored TUIs repaint at the correct cursor after replay.
|
||||
if (!isRemoteRuntimePtyId(reattachPtyId)) {
|
||||
window.api.pty.signal(reattachPtyId, 'SIGWINCH')
|
||||
}
|
||||
// Why here: a deferred reveal resolves the fit handle as incomplete, so an awaited
|
||||
// reassertion at the call site would never run for that path.
|
||||
if (session.deps.isVisibleRef.current) {
|
||||
session.ptySizeReassertion.request({ fit: false })
|
||||
}
|
||||
@@ -341,8 +339,6 @@ export function installPtyInputForward(session: ConnectPanePtySession): void {
|
||||
)
|
||||
}
|
||||
session.scheduleForegroundGridDriftCheck = (force = false): void => {
|
||||
// Why: mobile-owned PTYs intentionally keep a non-desktop grid; drift
|
||||
// healing would refit xterm even if resize forwarding is later suppressed.
|
||||
if (
|
||||
session.disposed ||
|
||||
!session.deps.isVisibleRef.current ||
|
||||
@@ -371,27 +367,12 @@ export function installPtyInputForward(session: ConnectPanePtySession): void {
|
||||
) {
|
||||
return
|
||||
}
|
||||
// Why: xterm cell metrics can settle after the DOM box stops resizing, so
|
||||
// ResizeObserver never fires even though FitAddon now proposes more cols.
|
||||
requestStablePaneFit(session.pane as ManagedPaneInternal, () =>
|
||||
session.ptySizeReassertion.request({ fit: false })
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// Why: observe the outer pane as the layout signal for both desktop drift
|
||||
// healing and mobile take-back. Normal desktop panes compare xterm against
|
||||
// the PTY's applied size; mobile-fit panes only report desktop geometry so
|
||||
// the parked phone-sized PTY is not resized. See docs/mobile-fit-hold.md.
|
||||
session.pendingGeometryReportRaf = null
|
||||
session.lastObservedDesktopGrid = null
|
||||
session.readPaneSize = (): { width: number; height: number } | null => {
|
||||
if (typeof session.pane.container.getBoundingClientRect !== 'function') {
|
||||
return null
|
||||
}
|
||||
const rect = session.pane.container.getBoundingClientRect()
|
||||
return { width: rect.width, height: rect.height }
|
||||
}
|
||||
session.lastObservedPaneSize = session.readPaneSize()
|
||||
session.pendingPaneGeometryChanged = false
|
||||
session.readPaneSize = () => readPaneSize(session)
|
||||
initializePaneGeometry(session)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import type { ConnectPanePtySession } from './connect-pane-pty-session'
|
||||
|
||||
export function readPaneSize(
|
||||
session: ConnectPanePtySession
|
||||
): { width: number; height: number } | null {
|
||||
if (typeof session.pane.container.getBoundingClientRect !== 'function') {
|
||||
return null
|
||||
}
|
||||
const rect = session.pane.container.getBoundingClientRect()
|
||||
return { width: rect.width, height: rect.height }
|
||||
}
|
||||
|
||||
export function initializePaneGeometry(session: ConnectPanePtySession): void {
|
||||
session.pendingGeometryReportRaf = null
|
||||
session.lastObservedDesktopGrid = null
|
||||
session.lastObservedPaneSize = readPaneSize(session)
|
||||
session.pendingPaneGeometryChanged = false
|
||||
}
|
||||
@@ -37,17 +37,23 @@ export function installTerminalSelectionFitGuard(
|
||||
active = false
|
||||
}
|
||||
|
||||
terminalElement?.addEventListener('mousedown', handleMouseDown, true)
|
||||
ownerDocument?.addEventListener('mouseup', handleMouseUp, true)
|
||||
ownerWindow?.addEventListener('blur', clear)
|
||||
if (terminalElement && typeof terminalElement.addEventListener === 'function') {
|
||||
terminalElement.addEventListener('mousedown', handleMouseDown, true)
|
||||
}
|
||||
if (ownerDocument && typeof ownerDocument.addEventListener === 'function') {
|
||||
ownerDocument.addEventListener('mouseup', handleMouseUp, true)
|
||||
}
|
||||
if (ownerWindow && typeof ownerWindow.addEventListener === 'function') {
|
||||
ownerWindow.addEventListener('blur', clear)
|
||||
}
|
||||
|
||||
return {
|
||||
isActive: () => active,
|
||||
dispose: () => {
|
||||
clear()
|
||||
terminalElement?.removeEventListener('mousedown', handleMouseDown, true)
|
||||
ownerDocument?.removeEventListener('mouseup', handleMouseUp, true)
|
||||
ownerWindow?.removeEventListener('blur', clear)
|
||||
terminalElement?.removeEventListener?.('mousedown', handleMouseDown, true)
|
||||
ownerDocument?.removeEventListener?.('mouseup', handleMouseUp, true)
|
||||
ownerWindow?.removeEventListener?.('blur', clear)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user