Skip to content

Commit 88daab3

Browse files
authored
🤖 Fix Ctrl+A and Ctrl+C interception in text inputs (#355)
## Problem Ctrl+A (select all) and Ctrl+C (copy) were broken in text inputs because the keybinds were being intercepted globally, even when the user was typing. ## Solution Only intercept these keybinds when actively needed: - **Ctrl+A (ACCEPT_EARLY_COMPACTION)**: Only intercept during active compaction, otherwise allow browser's select-all behavior - **Ctrl+C (INTERRUPT_STREAM)**: Only intercept during compaction or when not in an editable element, otherwise allow browser's copy behavior ## Testing 1. Open cmux in browser (server mode) 2. Type text in the chat input 3. Press Ctrl+A - should select all text 4. Press Ctrl+C - should copy selected text 5. During active compaction, both keybinds should still trigger their compaction-related actions _Generated with `cmux`_
1 parent 91d4804 commit 88daab3

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/hooks/useAIViewKeybinds.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ export function useAIViewKeybinds({
5353
const handleKeyDown = (e: KeyboardEvent) => {
5454
// Ctrl+C during compaction: cancel and restore command to input
5555
// (different from Ctrl+A which accepts early with [truncated])
56+
// Only intercept if actively compacting (otherwise allow browser default for copy)
5657
if (matchesKeybind(e, KEYBINDS.INTERRUPT_STREAM)) {
57-
e.preventDefault();
58-
5958
if (canInterrupt && isCompactingStream(aggregator)) {
6059
// Ctrl+C during compaction: restore original state and enter edit mode
6160
// Stores cancellation marker in localStorage (persists across reloads)
61+
e.preventDefault();
6262
void cancelCompaction(workspaceId, aggregator, (messageId, command) => {
6363
setEditingMessage({ id: messageId, content: command });
6464
});
@@ -67,24 +67,30 @@ export function useAIViewKeybinds({
6767
}
6868

6969
// Normal stream interrupt (non-compaction)
70-
if (canInterrupt || showRetryBarrier) {
70+
// Don't intercept if user is typing in an input field
71+
if (!isEditableElement(e.target) && (canInterrupt || showRetryBarrier)) {
72+
e.preventDefault();
7173
setAutoRetry(false); // User explicitly stopped - don't auto-retry
7274
void window.api.workspace.interruptStream(workspaceId);
75+
return;
7376
}
77+
78+
// Let browser handle Ctrl+C (copy) in editable elements
7479
return;
7580
}
7681

7782
// Ctrl+A during compaction: accept early with [truncated] sentinel
7883
// (different from Ctrl+C which cancels and restores original state)
84+
// Only intercept if actively compacting (otherwise allow browser default for select all)
7985
if (matchesKeybind(e, KEYBINDS.ACCEPT_EARLY_COMPACTION)) {
80-
e.preventDefault();
81-
8286
if (canInterrupt && isCompactingStream(aggregator)) {
8387
// Ctrl+A during compaction: perform compaction with partial summary
8488
// No flag set - handleCompactionAbort will perform compaction with [truncated]
89+
e.preventDefault();
8590
setAutoRetry(false);
8691
void window.api.workspace.interruptStream(workspaceId);
8792
}
93+
// Let browser handle Ctrl+A (select all) when not compacting
8894
return;
8995
}
9096

0 commit comments

Comments
 (0)