qwen-code/packages/cli/src/ui/components/ShellInputPrompt.tsx
tanzhenxin f831586d96 fix(cli): prevent Ctrl+F from leaking to PTY as ^F artifact
When toggling shell focus mode with Ctrl+F, the raw control character
was being forwarded to the PTY, causing a ^F artifact to appear in the
shell. This fix intercepts the Ctrl+F keypress before it reaches the
PTY when it's used for focus mode toggling.

Fixes #2236

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-03-13 16:34:55 +08:00

63 lines
1.7 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { useCallback } from 'react';
import type React from 'react';
import { useKeypress } from '../hooks/useKeypress.js';
import { ShellExecutionService } from '@qwen-code/qwen-code-core';
import { keyToAnsi, type Key } from '../hooks/keyToAnsi.js';
import { keyMatchers, Command } from '../keyMatchers.js';
export interface ShellInputPromptProps {
activeShellPtyId: number | null;
focus?: boolean;
}
export const ShellInputPrompt: React.FC<ShellInputPromptProps> = ({
activeShellPtyId,
focus = true,
}) => {
const handleShellInputSubmit = useCallback(
(input: string) => {
if (activeShellPtyId) {
ShellExecutionService.writeToPty(activeShellPtyId, input);
}
},
[activeShellPtyId],
);
const handleInput = useCallback(
(key: Key) => {
if (!focus || !activeShellPtyId) {
return;
}
// Don't forward Ctrl+F to the PTY — it's used to toggle shell focus.
// Without this, the raw ^F control character gets written to the shell.
if (keyMatchers[Command.TOGGLE_SHELL_INPUT_FOCUS](key)) {
return;
}
if (key.ctrl && key.shift && key.name === 'up') {
ShellExecutionService.scrollPty(activeShellPtyId, -1);
return;
}
if (key.ctrl && key.shift && key.name === 'down') {
ShellExecutionService.scrollPty(activeShellPtyId, 1);
return;
}
const ansiSequence = keyToAnsi(key);
if (ansiSequence) {
handleShellInputSubmit(ansiSequence);
}
},
[focus, handleShellInputSubmit, activeShellPtyId],
);
useKeypress(handleInput, { isActive: focus });
return null;
};