Hide terminal keyboard when opening sidebars

This commit is contained in:
Mohamed Boudra
2026-05-25 19:26:38 +07:00
parent 2252046f56
commit 5dd2afaac9
6 changed files with 34 additions and 2 deletions
@@ -8,7 +8,7 @@ import {
type ComponentProps, type ComponentProps,
type Ref, type Ref,
} from "react"; } from "react";
import { StyleSheet, View, type StyleProp, type ViewStyle } from "react-native"; import { Keyboard, StyleSheet, View, type StyleProp, type ViewStyle } from "react-native";
import { WebView, type WebViewMessageEvent } from "react-native-webview"; import { WebView, type WebViewMessageEvent } from "react-native-webview";
import type { ITheme } from "@xterm/xterm"; import type { ITheme } from "@xterm/xterm";
import type { TerminalState } from "@server/shared/messages"; import type { TerminalState } from "@server/shared/messages";
@@ -28,6 +28,7 @@ export interface TerminalEmulatorHandle {
restoreOutput: (data: TerminalOutputData) => void; restoreOutput: (data: TerminalOutputData) => void;
renderSnapshot: (state: TerminalState | null) => void; renderSnapshot: (state: TerminalState | null) => void;
clear: () => void; clear: () => void;
blur: () => void;
} }
interface TerminalEmulatorProps { interface TerminalEmulatorProps {
@@ -334,6 +335,12 @@ export default function TerminalEmulator({
outputDecoderRef.current.decode(); outputDecoderRef.current.decode();
sendToWebView({ type: "clear", streamKey }); sendToWebView({ type: "clear", streamKey });
}, },
blur: () => {
webViewRef.current?.injectJavaScript(
"window.__PASEO_TERMINAL_WEBVIEW_BLUR__ && window.__PASEO_TERMINAL_WEBVIEW_BLUR__(); true;",
);
Keyboard.dismiss();
},
}), }),
[sendToWebView, streamKey], [sendToWebView, streamKey],
); );
@@ -47,6 +47,7 @@ export interface TerminalEmulatorHandle {
restoreOutput: (data: TerminalOutputData) => void; restoreOutput: (data: TerminalOutputData) => void;
renderSnapshot: (state: TerminalState | null) => void; renderSnapshot: (state: TerminalState | null) => void;
clear: () => void; clear: () => void;
blur: () => void;
} }
const SCROLLBAR_HANDLE_WIDTH_IDLE = 6; const SCROLLBAR_HANDLE_WIDTH_IDLE = 6;
@@ -302,6 +303,9 @@ export default function TerminalEmulator({
clear: () => { clear: () => {
runtimeRef.current?.clear(); runtimeRef.current?.clear();
}, },
blur: () => {
runtimeRef.current?.blur();
},
}), }),
[], [],
); );
@@ -320,6 +324,9 @@ export default function TerminalEmulator({
clear: () => { clear: () => {
runtimeRef.current?.clear(); runtimeRef.current?.clear();
}, },
blur: () => {
runtimeRef.current?.blur();
},
}), }),
[], [],
); );
@@ -231,6 +231,12 @@ export function TerminalPane({
const requestTerminalReflow = useCallback(() => { const requestTerminalReflow = useCallback(() => {
setResizeRequestToken((current) => current + 1); setResizeRequestToken((current) => current + 1);
}, []); }, []);
useEffect(() => {
if (!isMobile || !isWorkspaceFocused || mobileView === "agent") {
return;
}
emulatorRef.current?.blur();
}, [isMobile, isWorkspaceFocused, mobileView]);
const handleRendererReadyChange = useCallback( const handleRendererReadyChange = useCallback(
(change: TerminalRendererReadyChange) => { (change: TerminalRendererReadyChange) => {
setRendererReadyStreamKey((current) => applyTerminalRendererReadyChange(current, change)); setRendererReadyStreamKey((current) => applyTerminalRendererReadyChange(current, change));
@@ -716,11 +722,13 @@ export function TerminalPane({
const handleSwipeRight = useCallback(() => { const handleSwipeRight = useCallback(() => {
if (!swipeGesturesEnabled) return; if (!swipeGesturesEnabled) return;
emulatorRef.current?.blur();
showMobileAgentList(); showMobileAgentList();
}, [swipeGesturesEnabled, showMobileAgentList]); }, [swipeGesturesEnabled, showMobileAgentList]);
const handleSwipeLeft = useCallback(() => { const handleSwipeLeft = useCallback(() => {
if (!swipeGesturesEnabled) return; if (!swipeGesturesEnabled) return;
emulatorRef.current?.blur();
onOpenFileExplorer(); onOpenFileExplorer();
}, [swipeGesturesEnabled, onOpenFileExplorer]); }, [swipeGesturesEnabled, onOpenFileExplorer]);
const showLoadingOverlay = shouldShowTerminalLoadingOverlay({ const showLoadingOverlay = shouldShowTerminalLoadingOverlay({
@@ -680,6 +680,10 @@ export class TerminalEmulatorRuntime {
terminal.focus(); terminal.focus();
} }
blur(): void {
this.terminal?.blur();
}
private refreshVisibleRows(): void { private refreshVisibleRows(): void {
const terminal = this.terminal; const terminal = this.terminal;
if (!terminal || terminal.rows <= 0) { if (!terminal || terminal.rows <= 0) {
@@ -81,6 +81,7 @@ declare global {
postMessage?: (data: string) => void; postMessage?: (data: string) => void;
}; };
__PASEO_TERMINAL_WEBVIEW_RECEIVE__?: (message: InboundMessage) => void; __PASEO_TERMINAL_WEBVIEW_RECEIVE__?: (message: InboundMessage) => void;
__PASEO_TERMINAL_WEBVIEW_BLUR__?: () => void;
} }
} }
@@ -303,6 +304,10 @@ class TerminalWebViewBridge {
this.host.style.backgroundColor = background; this.host.style.backgroundColor = background;
} }
blur = (): void => {
this.runtime?.blur();
};
private unmount(streamKey: string | null): void { private unmount(streamKey: string | null): void {
if (!this.runtime) { if (!this.runtime) {
return; return;
@@ -435,4 +440,5 @@ document.body.appendChild(root);
const bridge = new TerminalWebViewBridge(root, host); const bridge = new TerminalWebViewBridge(root, host);
window.__PASEO_TERMINAL_WEBVIEW_RECEIVE__ = bridge.receive; window.__PASEO_TERMINAL_WEBVIEW_RECEIVE__ = bridge.receive;
window.__PASEO_TERMINAL_WEBVIEW_BLUR__ = bridge.blur;
sendToNative({ type: "bridgeReady" }); sendToNative({ type: "bridgeReady" });
File diff suppressed because one or more lines are too long