Skip to content

Commit bdd7c08

Browse files
tdknByronnshcr
authored andcommitted
fix: Prevent focus shift during IME composition
Add composition state tracking to CommitMessageEditor and ReviewCreation components to prevent keyboard shortcuts from interfering with IME input. Track isComposing state and disable Enter/Tab/Escape navigation while users are typing with input methods like Asian keyboards. Co-authored-by: Byron <[email protected]> Co-authored-by: nshcr <[email protected]>
1 parent 72de844 commit bdd7c08

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

apps/desktop/src/components/CommitMessageEditor.svelte

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
6969
let composer = $state<ReturnType<typeof MessageEditor>>();
7070
let titleInput = $state<HTMLTextAreaElement>();
71+
let isComposing = $state(false);
7172
7273
const suggestionsHandler = new CommitSuggestions(aiService, uiState);
7374
const diffInputArgs = $derived<DiffInputContextArgs>(
@@ -165,14 +166,27 @@
165166
onchange={(value) => {
166167
onChange?.({ title: value });
167168
}}
169+
oninput={(e: Event) => {
170+
if (e instanceof InputEvent) {
171+
isComposing = e.isComposing;
172+
}
173+
}}
168174
onkeydown={async (e: KeyboardEvent) => {
175+
if (
176+
['Enter', 'Escape', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(e.key) &&
177+
isComposing
178+
) {
179+
e.preventDefault();
180+
isComposing = false;
181+
return;
182+
}
169183
if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
170184
e.preventDefault();
171185
if (title.trim()) {
172186
emitAction();
173187
}
174188
}
175-
if (e.key === 'Enter' || (e.key === 'Tab' && !e.shiftKey)) {
189+
if ((e.key === 'Enter' || (e.key === 'Tab' && !e.shiftKey)) && !isComposing) {
176190
e.preventDefault();
177191
composer?.focus();
178192
}

apps/desktop/src/components/ReviewCreation.svelte

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
9292
let titleInput = $state<HTMLTextAreaElement | undefined>(undefined);
9393
let messageEditor = $state<MessageEditor>();
94+
let isComposing = $state(false);
9495
9596
// AI things
9697
const aiGenEnabled = projectAiGenEnabled(projectId);
@@ -387,7 +388,15 @@
387388
prTitle.set(value);
388389
}}
389390
onkeydown={(e: KeyboardEvent) => {
390-
if (e.key === 'Enter' || (e.key === 'Tab' && !e.shiftKey)) {
391+
if (
392+
['Enter', 'Escape', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes(e.key) &&
393+
isComposing
394+
) {
395+
e.preventDefault();
396+
isComposing = false;
397+
return;
398+
}
399+
if ((e.key === 'Enter' || (e.key === 'Tab' && !e.shiftKey)) && !isComposing) {
391400
e.preventDefault();
392401
messageEditor?.focus();
393402
}
@@ -398,7 +407,7 @@
398407
return true;
399408
}
400409

401-
if (e.key === 'Escape') {
410+
if (e.key === 'Escape' && !isComposing) {
402411
e.preventDefault();
403412
onClose();
404413
}
@@ -408,6 +417,9 @@
408417
oninput={(e: Event) => {
409418
const target = e.target as HTMLInputElement;
410419
prTitle.set(target.value);
420+
if (e instanceof InputEvent) {
421+
isComposing = e.isComposing;
422+
}
411423
}}
412424
/>
413425
<MessageEditor

0 commit comments

Comments
 (0)