Restore terminal toolbar focus handling

This commit is contained in:
Mohamed Boudra
2026-06-19 11:54:12 +07:00
parent ad30f65549
commit 9376de1ef1
5 changed files with 36 additions and 8 deletions

View File

@@ -24,6 +24,7 @@ import {
TerminalEmulatorRuntime,
type TerminalOutputData,
} from "../terminal/runtime/terminal-emulator-runtime";
import { encodeTerminalPaste } from "../terminal/runtime/terminal-paste";
import type {
TerminalLocalFileLinkSource,
TerminalLocalFileLinkTarget,
@@ -303,6 +304,18 @@ export default function TerminalEmulator({
const dropActiveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const domBridgeRef = useRef<DOMImperativeFactory | null>(null);
const pasteText = useCallback((text: string) => {
if (text.length === 0) {
return;
}
mountCallbacksRef.current.onInput?.(
encodeTerminalPaste({
text,
bracketedPaste: runtimeRef.current?.getInputModeState().bracketedPaste ?? false,
}),
);
}, []);
useDOMImperativeHandle(
domBridgeRef,
(): DOMImperativeFactory => ({
@@ -325,7 +338,7 @@ export default function TerminalEmulator({
paste: (...args) => {
const text = args[0];
if (typeof text === "string" && text.length > 0) {
mountCallbacksRef.current.onInput?.(text);
pasteText(text);
}
},
copySelection: async () => "",
@@ -340,7 +353,7 @@ export default function TerminalEmulator({
runtimeRef.current?.blur();
},
}),
[],
[pasteText],
);
useImperativeHandle(
ref,
@@ -355,9 +368,7 @@ export default function TerminalEmulator({
runtimeRef.current?.renderSnapshot({ state });
},
paste: (text: string) => {
if (text.length > 0) {
mountCallbacksRef.current.onInput?.(text);
}
pasteText(text);
},
copySelection: async () => "",
clear: () => {
@@ -371,7 +382,7 @@ export default function TerminalEmulator({
runtimeRef.current?.blur();
},
}),
[],
[pasteText],
);
useEffect(() => {

View File

@@ -810,9 +810,10 @@ export function TerminalPane({
const toggleModifier = useCallback(
(modifier: keyof ModifierState) => {
setModifiers((current) => ({ ...current, [modifier]: !current[modifier] }));
requestTerminalFocus();
requestTerminalReflow();
},
[requestTerminalReflow],
[requestTerminalFocus, requestTerminalReflow],
);
const sendVirtualKey = useCallback(
@@ -825,6 +826,7 @@ export function TerminalPane({
meta: false,
});
clearPendingModifiers();
requestTerminalFocus();
requestTerminalReflow();
},
[
@@ -832,6 +834,7 @@ export function TerminalPane({
modifiers.alt,
modifiers.ctrl,
modifiers.shift,
requestTerminalFocus,
requestTerminalReflow,
sendTerminalKey,
],

View File

@@ -308,6 +308,16 @@ describe("terminal-emulator-runtime", () => {
]);
});
it("exposes the tracked input mode state", () => {
const { runtime } = createRuntimeWithTerminal();
runtime.write({ data: terminalOutput("\x1b[?2004h") });
expect(runtime.getInputModeState()).toMatchObject({
bracketedPaste: true,
});
});
it("commits each drained plain write through its own xterm callback", () => {
const { runtime, writeTexts, writeCallbacks } = createRuntimeWithTerminal();
const committed: string[] = [];

View File

@@ -210,6 +210,10 @@ export class TerminalEmulatorRuntime {
this.pendingModifiers = input.pendingModifiers;
}
getInputModeState(): TerminalInputModeState {
return this.inputModeTracker.getState();
}
mount(input: TerminalEmulatorRuntimeMountInput): void {
this.unmount();

File diff suppressed because one or more lines are too long