fix(app): keep retained terminal streams attached
A hidden tab in the focused workspace must keep consuming output, but only the presented pane may claim focus or terminal geometry.
This commit is contained in:
@@ -232,7 +232,7 @@ export function TerminalPane({
|
||||
|
||||
const client = useHostRuntimeClient(serverId);
|
||||
const isConnected = useHostRuntimeIsConnected(serverId);
|
||||
const isTerminalActive = retainedPanelActive && isWorkspaceFocused;
|
||||
const isTerminalPresented = retainedPanelActive && isWorkspaceFocused;
|
||||
const supportsTerminalRestoreModes = useSessionStore(
|
||||
(state) => state.sessions[serverId]?.serverInfo?.features?.["terminal-restore-modes"] === true,
|
||||
);
|
||||
@@ -268,8 +268,8 @@ export function TerminalPane({
|
||||
useBlockMobilePanelOpenGestures(isMobile && isWorkspaceFocused && isPaneFocused && hasSelection);
|
||||
const emulatorRef = useRef<TerminalEmulatorHandle>(null);
|
||||
const terminalIdRef = useRef<string>(terminalId);
|
||||
const terminalActiveRef = useRef(isTerminalActive);
|
||||
terminalActiveRef.current = isTerminalActive;
|
||||
const terminalPresentedRef = useRef(isTerminalPresented);
|
||||
terminalPresentedRef.current = isTerminalPresented;
|
||||
const inputModeRef = useRef<TerminalInputModeState>(DEFAULT_TERMINAL_INPUT_MODE_STATE);
|
||||
const pendingTerminalInputRef = useRef<PendingTerminalInput[]>([]);
|
||||
const keyboardRefitTimeoutsRef = useRef<Array<ReturnType<typeof setTimeout>>>([]);
|
||||
@@ -356,7 +356,7 @@ export function TerminalPane({
|
||||
|
||||
useEffect(() => {
|
||||
const canRequest = canRequestFocusClaim({
|
||||
isWorkspaceFocused: isTerminalActive,
|
||||
isWorkspaceFocused: isTerminalPresented,
|
||||
isPaneFocused,
|
||||
isAppActivelyVisible,
|
||||
isClientReady: client !== null,
|
||||
@@ -378,7 +378,7 @@ export function TerminalPane({
|
||||
isAppActivelyVisible,
|
||||
isConnected,
|
||||
isPaneFocused,
|
||||
isTerminalActive,
|
||||
isTerminalPresented,
|
||||
rendererReadyStreamKey,
|
||||
requestTerminalReflow,
|
||||
scopeKey,
|
||||
@@ -450,7 +450,7 @@ export function TerminalPane({
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!client || !isConnected || !isTerminalActive) {
|
||||
if (!client || !isConnected || !isWorkspaceFocused) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ export function TerminalPane({
|
||||
});
|
||||
setModifiers({ ...EMPTY_MODIFIERS });
|
||||
});
|
||||
}, [client, isConnected, isTerminalActive, workspaceTerminalSession.snapshots]);
|
||||
}, [client, isConnected, isWorkspaceFocused, workspaceTerminalSession.snapshots]);
|
||||
|
||||
useEffect(() => {
|
||||
measuredTerminalSizeRef.current = null;
|
||||
@@ -488,7 +488,7 @@ export function TerminalPane({
|
||||
const getPreferredStreamSize = useStableEvent(() => {
|
||||
if (
|
||||
!canRequestFocusClaim({
|
||||
isWorkspaceFocused: terminalActiveRef.current,
|
||||
isWorkspaceFocused: terminalPresentedRef.current,
|
||||
isPaneFocused,
|
||||
isAppActivelyVisible,
|
||||
isClientReady: client !== null,
|
||||
@@ -503,7 +503,7 @@ export function TerminalPane({
|
||||
|
||||
const handleStreamOutput = useStableEvent(
|
||||
({ terminalId: outputTerminalId, data }: { terminalId: string; data: Uint8Array }) => {
|
||||
if (!terminalActiveRef.current || terminalIdRef.current !== outputTerminalId) {
|
||||
if (terminalIdRef.current !== outputTerminalId) {
|
||||
return;
|
||||
}
|
||||
emulatorRef.current?.writeOutput(data);
|
||||
@@ -513,7 +513,7 @@ export function TerminalPane({
|
||||
const handleStreamRestore = useStableEvent(
|
||||
({ terminalId: restoreTerminalId, data }: { terminalId: string; data: Uint8Array }) => {
|
||||
workspaceTerminalSession.snapshots.clear({ terminalId: restoreTerminalId });
|
||||
if (!terminalActiveRef.current || terminalIdRef.current !== restoreTerminalId) {
|
||||
if (terminalIdRef.current !== restoreTerminalId) {
|
||||
return;
|
||||
}
|
||||
emulatorRef.current?.restoreOutput(data);
|
||||
@@ -523,7 +523,7 @@ export function TerminalPane({
|
||||
const handleStreamSnapshot = useStableEvent(
|
||||
({ terminalId: snapshotTerminalId, state }: { terminalId: string; state: TerminalState }) => {
|
||||
workspaceTerminalSession.snapshots.set({ terminalId: snapshotTerminalId, state });
|
||||
if (!terminalActiveRef.current || terminalIdRef.current !== snapshotTerminalId) {
|
||||
if (terminalIdRef.current !== snapshotTerminalId) {
|
||||
return;
|
||||
}
|
||||
emulatorRef.current?.renderSnapshot(state);
|
||||
@@ -534,7 +534,7 @@ export function TerminalPane({
|
||||
resolveTerminalRestoreOptions({
|
||||
supportsTerminalRestoreModes,
|
||||
canClaimSize: canRequestFocusClaim({
|
||||
isWorkspaceFocused: terminalActiveRef.current,
|
||||
isWorkspaceFocused: terminalPresentedRef.current,
|
||||
isPaneFocused,
|
||||
isAppActivelyVisible,
|
||||
isClientReady: client !== null,
|
||||
@@ -590,7 +590,7 @@ export function TerminalPane({
|
||||
terminalId,
|
||||
terminalStreamKey,
|
||||
rendererReadyStreamKey,
|
||||
isWorkspaceFocused: isTerminalActive,
|
||||
isWorkspaceFocused,
|
||||
});
|
||||
streamControllerRef.current?.setTerminal({
|
||||
terminalId: nextTerminalId,
|
||||
@@ -598,7 +598,7 @@ export function TerminalPane({
|
||||
}, [
|
||||
client,
|
||||
isConnected,
|
||||
isTerminalActive,
|
||||
isWorkspaceFocused,
|
||||
rendererReadyStreamKey,
|
||||
terminalId,
|
||||
terminalStreamKey,
|
||||
@@ -789,7 +789,7 @@ export function TerminalPane({
|
||||
forceClaim: input.forceClaim ?? false,
|
||||
supportsTerminalSizeOwnership,
|
||||
readiness: {
|
||||
isWorkspaceFocused: isTerminalActive,
|
||||
isWorkspaceFocused: isTerminalPresented,
|
||||
isPaneFocused,
|
||||
isAppActivelyVisible,
|
||||
isClientReady: client !== null,
|
||||
@@ -1024,7 +1024,7 @@ export function TerminalPane({
|
||||
}
|
||||
};
|
||||
const showLoadingOverlay = shouldShowTerminalLoadingOverlay({
|
||||
isWorkspaceFocused: isTerminalActive,
|
||||
isWorkspaceFocused: isTerminalPresented,
|
||||
hasStreamError: Boolean(streamError),
|
||||
isAttaching,
|
||||
rendererReadyStreamKey,
|
||||
|
||||
Reference in New Issue
Block a user