History

fix(web): bypass xterm for global terminal shortcuts (#1580)

Ariaj committed 7 months ago

Commit 39ca3ee1 parent 52a60673 files · +36 −0Browse files

Unified · Split

3 files
  1. apps/web/src/components/ChatView.tsx +5 −0
  2. apps/web/src/components/ThreadTerminalDrawer.browser.tsx +2 −0
  3. apps/web/src/components/ThreadTerminalDrawer.tsx +29 −0
apps/web/src/components/ChatView.tsx+5−0
@@ -10,6 +10,7 @@ import { · 9 unmodified lines
1010 type ProjectId,
1111 type ProviderApprovalDecision,
1212 type ServerProvider,
13+ type ResolvedKeybindingsConfig,
1314 type ScopedThreadRef,
1415 type ThreadId,
1516 type TurnId,
@@ -415,6 +416,7 @@ interface PersistentThreadTerminalDrawerProps { · 399 unmodified lines
415416 splitShortcutLabel: string | undefined;
416417 newShortcutLabel: string | undefined;
417418 closeShortcutLabel: string | undefined;
419+ keybindings: ResolvedKeybindingsConfig;
418420 onAddTerminalContext: (selection: TerminalContextSelection) => void;
419421 }
420422
@@ -427,6 +429,7 @@ const PersistentThreadTerminalDrawer = memo(function PersistentThreadTerminalDra · 6 unmodified lines
427429 splitShortcutLabel,
428430 newShortcutLabel,
429431 closeShortcutLabel,
432+ keybindings,
430433 onAddTerminalContext,
431434 }: PersistentThreadTerminalDrawerProps) {
432435 const serverThread = useStore(useMemo(() => createThreadSelectorByRef(threadRef), [threadRef]));
@@ -570,6 +573,7 @@ const PersistentThreadTerminalDrawer = memo(function PersistentThreadTerminalDra · 137 unmodified lines
570573 splitShortcutLabel={visible ? splitShortcutLabel : undefined}
571574 newShortcutLabel={visible ? newShortcutLabel : undefined}
572575 closeShortcutLabel={visible ? closeShortcutLabel : undefined}
576+ keybindings={keybindings}
573577 onActiveTerminalChange={activateTerminal}
574578 onCloseTerminal={closeTerminal}
575579 onHeightChange={setTerminalHeight}
@@ -3443,6 +3447,7 @@ export default function ChatView(props: ChatViewProps) { · 2867 unmodified lines
34433447 splitShortcutLabel={splitTerminalShortcutLabel ?? undefined}
34443448 newShortcutLabel={newTerminalShortcutLabel ?? undefined}
34453449 closeShortcutLabel={closeTerminalShortcutLabel ?? undefined}
3450+ keybindings={keybindings}
34463451 onAddTerminalContext={addTerminalContextToDraft}
34473452 />
34483453 ))}
apps/web/src/components/ThreadTerminalDrawer.browser.tsx+2−0
@@ -177,6 +177,7 @@ async function mountTerminalViewport(props: { · 176 unmodified lines
177177 autoFocus={false}
178178 resizeEpoch={0}
179179 drawerHeight={320}
180+ keybindings={[]}
180181 />,
181182 { container: host },
182183 );
@@ -196,6 +197,7 @@ async function mountTerminalViewport(props: { · 13 unmodified lines
196197 autoFocus={false}
197198 resizeEpoch={0}
198199 drawerHeight={320}
200+ keybindings={[]}
199201 />,
200202 );
201203 },
apps/web/src/components/ThreadTerminalDrawer.tsx+29−0
@@ -1,6 +1,7 @@
11 import { FitAddon } from "@xterm/addon-fit";
22 import { Plus, SquareSplitHorizontal, TerminalSquare, Trash2, XIcon } from "lucide-react";
33 import {
4+ type ResolvedKeybindingsConfig,
45 type ScopedThreadRef,
56 type TerminalEvent,
67 type TerminalSessionSnapshot,
@@ -29,7 +30,12 @@ import { · 22 unmodified lines
2930 wrappedTerminalLinkRangeIntersectsBufferLine,
3031 } from "../terminal-links";
3132 import {
33+ isDiffToggleShortcut,
3234 isTerminalClearShortcut,
35+ isTerminalCloseShortcut,
36+ isTerminalNewShortcut,
37+ isTerminalSplitShortcut,
38+ isTerminalToggleShortcut,
3339 terminalDeleteShortcutData,
3440 terminalNavigationShortcutData,
3541 } from "../keybindings";
@@ -255,6 +261,7 @@ interface TerminalViewportProps { · 219 unmodified lines
255261 autoFocus: boolean;
256262 resizeEpoch: number;
257263 drawerHeight: number;
264+ keybindings: ResolvedKeybindingsConfig;
258265 }
259266
260267 export function TerminalViewport({
@@ -271,6 +278,7 @@ export function TerminalViewport({ · 10 unmodified lines
271278 autoFocus,
272279 resizeEpoch,
273280 drawerHeight,
281+ keybindings,
274282 }: TerminalViewportProps) {
275283 const containerRef = useRef<HTMLDivElement>(null);
276284 const terminalRef = useRef<Terminal | null>(null);
@@ -282,6 +290,7 @@ export function TerminalViewport({ · 5 unmodified lines
282290 const selectionActionRequestIdRef = useRef(0);
283291 const selectionActionOpenRef = useRef(false);
284292 const selectionActionTimerRef = useRef<number | null>(null);
293+ const keybindingsRef = useRef(keybindings);
285294 const lastAppliedTerminalEventIdRef = useRef(0);
286295 const terminalHydratedRef = useRef(false);
287296 const handleSessionExited = useEffectEvent(() => {
@@ -292,6 +301,10 @@ export function TerminalViewport({ · 4 unmodified lines
292301 });
293302 const readTerminalLabel = useEffectEvent(() => terminalLabel);
294303
304+ useEffect(() => {
305+ keybindingsRef.current = keybindings;
306+ }, [keybindings]);
307+
295308 useEffect(() => {
296309 const mount = containerRef.current;
297310 if (!mount) return;
@@ -403,6 +416,18 @@ export function TerminalViewport({ · 105 unmodified lines
403416 };
404417
405418 terminal.attachCustomKeyEventHandler((event) => {
419+ const currentKeybindings = keybindingsRef.current;
420+ const options = { context: { terminalFocus: true, terminalOpen: true } };
421+ if (
422+ isTerminalToggleShortcut(event, currentKeybindings, options) ||
423+ isTerminalSplitShortcut(event, currentKeybindings, options) ||
424+ isTerminalNewShortcut(event, currentKeybindings, options) ||
425+ isTerminalCloseShortcut(event, currentKeybindings, options) ||
426+ isDiffToggleShortcut(event, currentKeybindings, options)
427+ ) {
428+ return false;
429+ }
430+
406431 const navigationData = terminalNavigationShortcutData(event);
407432 if (navigationData !== null) {
408433 event.preventDefault();
@@ -795,6 +820,7 @@ interface ThreadTerminalDrawerProps { · 386 unmodified lines
795820 onCloseTerminal: (terminalId: string) => void;
796821 onHeightChange: (height: number) => void;
797822 onAddTerminalContext: (selection: TerminalContextSelection) => void;
823+ keybindings: ResolvedKeybindingsConfig;
798824 }
799825
800826 interface TerminalActionButtonProps {
@@ -848,6 +874,7 @@ export default function ThreadTerminalDrawer({ · 47 unmodified lines
848874 onCloseTerminal,
849875 onHeightChange,
850876 onAddTerminalContext,
877+ keybindings,
851878 }: ThreadTerminalDrawerProps) {
852879 const [drawerHeight, setDrawerHeight] = useState(() => clampDrawerHeight(height));
853880 const [resizeEpoch, setResizeEpoch] = useState(0);
@@ -1166,6 +1193,7 @@ export default function ThreadTerminalDrawer({ · 312 unmodified lines
11661193 autoFocus={terminalId === resolvedActiveTerminalId}
11671194 resizeEpoch={resizeEpoch}
11681195 drawerHeight={drawerHeight}
1196+ keybindings={keybindings}
11691197 />
11701198 </div>
11711199 </div>
@@ -1188,6 +1216,7 @@ export default function ThreadTerminalDrawer({ · 16 unmodified lines
11881216 autoFocus
11891217 resizeEpoch={resizeEpoch}
11901218 drawerHeight={drawerHeight}
1219+ keybindings={keybindings}
11911220 />
11921221 </div>
11931222 )}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t