From 5e8b2bdb50168496e530d41b2ad947b542173e2f Mon Sep 17 00:00:00 2001 From: MacRimi Date: Sat, 31 Jan 2026 16:48:22 +0100 Subject: [PATCH] Update terminal panel --- AppImage/components/lxc-terminal-modal.tsx | 75 ++++++++++++++----- AppImage/components/script-terminal-modal.tsx | 7 +- AppImage/components/terminal-panel.tsx | 6 +- 3 files changed, 65 insertions(+), 23 deletions(-) diff --git a/AppImage/components/lxc-terminal-modal.tsx b/AppImage/components/lxc-terminal-modal.tsx index 4ff93bee..d31a1a92 100644 --- a/AppImage/components/lxc-terminal-modal.tsx +++ b/AppImage/components/lxc-terminal-modal.tsx @@ -169,7 +169,7 @@ export function LxcTerminalModal({ } }, 25000) - // Sync terminal size + // Sync terminal size first fitAddon.fit() ws.send(JSON.stringify({ type: "resize", @@ -177,12 +177,14 @@ export function LxcTerminalModal({ rows: term.rows, })) - // Auto-execute pct enter command after a brief delay + // Auto-execute pct enter command after terminal is ready + // Wait for shell prompt to appear before sending command setTimeout(() => { if (ws.readyState === WebSocket.OPEN) { - ws.send(`pct enter ${vmid}\n`) + // Send the command as plain text like user would type + ws.send(`pct enter ${vmid}\r`) } - }, 500) + }, 800) } ws.onmessage = (event) => { @@ -287,13 +289,41 @@ export function LxcTerminalModal({ } }, []) - const sendCtrlC = useCallback(() => sendKey("\x03"), [sendKey]) + const sendEsc = useCallback(() => sendKey("\x1b"), [sendKey]) + const sendTab = useCallback(() => sendKey("\t"), [sendKey]) const sendArrowUp = useCallback(() => sendKey("\x1b[A"), [sendKey]) const sendArrowDown = useCallback(() => sendKey("\x1b[B"), [sendKey]) const sendArrowLeft = useCallback(() => sendKey("\x1b[D"), [sendKey]) const sendArrowRight = useCallback(() => sendKey("\x1b[C"), [sendKey]) const sendEnter = useCallback(() => sendKey("\r"), [sendKey]) - const sendTab = useCallback(() => sendKey("\t"), [sendKey]) + const sendCtrlC = useCallback(() => sendKey("\x03"), [sendKey]) // Ctrl+C + + // Ctrl key state - user presses Ctrl button, then types a letter + const [ctrlPressed, setCtrlPressed] = useState(false) + + const handleCtrlPress = useCallback(() => { + setCtrlPressed(true) + setTimeout(() => setCtrlPressed(false), 3000) + }, []) + + // Handle keyboard input when Ctrl is pressed + useEffect(() => { + if (!ctrlPressed || !isOpen) return + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key.length === 1) { + e.preventDefault() + const code = e.key.toLowerCase().charCodeAt(0) - 96 + if (code >= 1 && code <= 26) { + sendKey(String.fromCharCode(code)) + } + setCtrlPressed(false) + } + } + + window.addEventListener("keydown", handleKeyDown) + return () => window.removeEventListener("keydown", handleKeyDown) + }, [ctrlPressed, isOpen, sendKey]) const showMobileControls = isMobile || isTablet @@ -302,6 +332,7 @@ export function LxcTerminalModal({ {/* Resize bar */}
- Ctrl+C + ESC + + - +
)} diff --git a/AppImage/components/script-terminal-modal.tsx b/AppImage/components/script-terminal-modal.tsx index f0b2f77b..3d799010 100644 --- a/AppImage/components/script-terminal-modal.tsx +++ b/AppImage/components/script-terminal-modal.tsx @@ -736,9 +736,10 @@ export function ScriptTerminalModal({ }} variant="outline" size="sm" - className="h-8 px-2.5 text-xs bg-zinc-800 hover:bg-zinc-700 border-zinc-700 text-white" + className="h-8 px-2.5 text-xs bg-blue-600/20 hover:bg-blue-600/30 border-blue-600/50 text-blue-400" > - + + Enter )} diff --git a/AppImage/components/terminal-panel.tsx b/AppImage/components/terminal-panel.tsx index 5eca562d..92a7024f 100644 --- a/AppImage/components/terminal-panel.tsx +++ b/AppImage/components/terminal-panel.tsx @@ -963,9 +963,9 @@ const handleClose = () => { }} variant="outline" size="sm" - className="h-8 px-3 text-xs" + className="h-8 px-3 text-xs bg-blue-600/20 hover:bg-blue-600/30 border-blue-600/50 text-blue-400" > - ↵ + ↵ Enter )}