Skip to content

Commit e5af3bc

Browse files
committed
fix: fixed #2685
1 parent 7a80f66 commit e5af3bc

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,13 @@
186186
options like color changes. The context menu event is now prevented before
187187
showing the menu, ensuring focus is maintained regardless of where the
188188
right-click occurs.
189+
- **#2685** Fixed physical keyboard not working after programmatic focus with
190+
manual virtual keyboard policy. When calling `mf.focus()` programmatically at
191+
page load with `mathVirtualKeyboardPolicy: "manual"`, the physical keyboard
192+
would stop working. This was caused by a double `onFocus()` invocation that
193+
set up event capture listeners at the wrong time. The fix prevents the second
194+
`onFocus()` call when focus is initiated programmatically, ensuring keyboard
195+
events are properly routed.
189196
- **#2686** When deleting a range that includes special mathematical atoms like
190197
`\sqrt`, `\frac`, or `\enclose`, the special atom structure is now properly
191198
removed or cleaned up. Previously, deleting content would leave behind empty

src/editor-mathfield/mathfield-private.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ export class _Mathfield implements Mathfield, KeyboardDelegateInterface {
202202
// the `change` event is dispatched
203203
private valueOnFocus: string;
204204
private focusBlurInProgress = false;
205+
private programmaticFocusInProgress = false;
205206

206207
private geometryChangeTimer: ReturnType<typeof requestAnimationFrame>;
207208

@@ -818,7 +819,10 @@ If you are using Vue, this may be because you are using the runtime-only build o
818819

819820
switch (evt.type) {
820821
case 'focus':
821-
this.onFocus({ suppressEvents: true });
822+
// Skip handling DOM focus events that result from programmatic focus()
823+
// calls to prevent double onFocus() invocation (fixes #2685)
824+
if (!this.programmaticFocusInProgress)
825+
this.onFocus({ suppressEvents: true });
822826
break;
823827

824828
case 'blur':
@@ -1349,6 +1353,7 @@ If you are using Vue, this may be because you are using the runtime-only build o
13491353
focus(options?: FocusOptions): void {
13501354
if (this.disabled || this.focusBlurInProgress) return;
13511355
if (!this.hasFocus()) {
1356+
this.programmaticFocusInProgress = true;
13521357
this.onFocus();
13531358
this.model.announce('line');
13541359
}
@@ -1754,6 +1759,11 @@ If you are using Vue, this may be because you are using the runtime-only build o
17541759
this.focusBlurInProgress = false;
17551760
this.keyboardDelegate.focus();
17561761
this.connectToVirtualKeyboard();
1762+
1763+
// Clear the flag after the DOM focus event has been processed
1764+
setTimeout(() => {
1765+
this.programmaticFocusInProgress = false;
1766+
}, 0);
17571767
}
17581768
}, 60);
17591769
}

0 commit comments

Comments
 (0)