diff --git a/src/editor-mathfield/keyboard-input.ts b/src/editor-mathfield/keyboard-input.ts index 5a0cfc9df..801c77d4f 100644 --- a/src/editor-mathfield/keyboard-input.ts +++ b/src/editor-mathfield/keyboard-input.ts @@ -534,9 +534,8 @@ export function onInput( // David Bowie emoji: 👨🏻‍🎤 let graphemes = splitGraphemes(text); - // Check if virtual keyboard is visible and the shift key is pressed const keyboard = window.mathVirtualKeyboard; - if (keyboard?.visible && keyboard.isShifted) { + if (keyboard?.isShifted) { graphemes = typeof graphemes === 'string' ? graphemes.toUpperCase() diff --git a/src/virtual-keyboard/utils.ts b/src/virtual-keyboard/utils.ts index 7342815b0..a2e421d88 100644 --- a/src/virtual-keyboard/utils.ts +++ b/src/virtual-keyboard/utils.ts @@ -1064,7 +1064,7 @@ function handlePointerDown(ev: PointerEvent) { // Is it the Shift key? if (isShiftKey(keycap)) { target.classList.add('is-active'); - keyboard.incrementShiftPress(); + keyboard.shiftPressCount++; } if (keycap.variants) { @@ -1107,7 +1107,7 @@ function handleVirtualKeyboardEvent(controller) { if (ev.type === 'pointercancel') { target.classList.remove('is-pressed'); if (isShiftKey(keycap)) { - keyboard.decrementShiftPress(); + keyboard.shiftPressCount--; // Because of capslock, we may not have changed status target.classList.toggle('is-active', keyboard.isShifted); } @@ -1118,7 +1118,7 @@ function handleVirtualKeyboardEvent(controller) { if (ev.type === 'pointerleave' && ev.target === target) { target.classList.remove('is-pressed'); if (isShiftKey(keycap)) { - keyboard.decrementShiftPress(); + keyboard.shiftPressCount--; // Because of capslock, we may not have changed status target.classList.toggle('is-active', keyboard.isShifted); } @@ -1150,7 +1150,8 @@ function handleVirtualKeyboardEvent(controller) { } else executeKeycapCommand(keycap.shift); } else executeKeycapCommand(keycap); - if (keyboard.shiftPressCount === 1) keyboard.resetShiftPress(); + if (keyboard.shiftPressCount === 1 && !(ev as MouseEvent).shiftKey) + keyboard.shiftPressCount = 0; } controller.abort(); ev.preventDefault(); diff --git a/src/virtual-keyboard/virtual-keyboard.ts b/src/virtual-keyboard/virtual-keyboard.ts index d741aa466..666b0dece 100644 --- a/src/virtual-keyboard/virtual-keyboard.ts +++ b/src/virtual-keyboard/virtual-keyboard.ts @@ -72,64 +72,29 @@ export class VirtualKeyboard implements VirtualKeyboardInterface, EventTarget { newActive.classList.add('is-visible'); } - if (this.isShifted) this.render(); - } - - private _isCapslock = false; - get isCapslock(): boolean { - return this._isCapslock; - } - set isCapslock(val: boolean) { - this._element?.classList.toggle('is-caps-lock', this.shiftPressCount === 2); - - if (val === this._isCapslock) return; - - this._isCapslock = val; - this.isShifted = val; + this.render(); } - /** `0`: not pressed - * + /** + * `0`: not pressed * `1`: Shift is locked for next char only - * * `2`: Shift is locked for all characters */ private _shiftPressCount: 0 | 1 | 2 = 0; - get shiftPressCount(): 0 | 1 | 2 { + get shiftPressCount(): typeof this._shiftPressCount { return this._shiftPressCount; } - /** Increments `_shiftPressCount` by `1`, and handle the appropriate related behavior for each val */ - incrementShiftPress(): void { - if (++this._shiftPressCount > 2) this.resetShiftPress(); - else this.isCapslock = true; - } - - /** Decrements `_shiftPressCount` by `1`, and sets `isCapslock` to `false` if reaches `0` */ - decrementShiftPress(): void { - this._shiftPressCount = Math.max(--this._shiftPressCount, 0) as 0 | 1 | 2; - if (this._shiftPressCount === 0) this.isCapslock = false; - } + set shiftPressCount(count: typeof this._shiftPressCount) { + this._shiftPressCount = count > 2 || count < 0 ? 0 : count; + this._element?.classList.toggle('is-caps-lock', this.shiftPressCount === 2); - /** Resets `_shiftPressCount` to `0`, and sets `isCapslock` to `false` */ - resetShiftPress(): void { - this._shiftPressCount = 0; - this.isCapslock = false; + this.render(); } - private _isShifted = false; get isShifted(): boolean { - return this._isShifted; - } - - set isShifted(shifted: boolean) { - if (this._isCapslock) shifted = true; - if (this._isShifted === shifted) return; - - this._isShifted = shifted; - - this.render(); + return this._shiftPressCount > 0; } resetKeycapRegistry(): void { @@ -363,7 +328,6 @@ export class VirtualKeyboard implements VirtualKeyboardInterface, EventTarget { if (typeof x === 'function') x(event); else x?.handleEvent(event); }); - return !event.defaultPrevented; } @@ -505,14 +469,12 @@ export class VirtualKeyboard implements VirtualKeyboardInterface, EventTarget { window.addEventListener('keydown', this, { capture: true }); window.addEventListener('keyup', this, { capture: true }); - this.currentLayer = this.latentLayer; - - this.render(); - this._element?.classList.toggle( 'is-caps-lock', this.shiftPressCount === 2 ); + + this.currentLayer = this.latentLayer; } this._visible = true; @@ -600,7 +562,13 @@ export class VirtualKeyboard implements VirtualKeyboardInterface, EventTarget { this.container?.appendChild(this.element); } - handleEvent(evt: Event): void { + handleEvent( + evt: + | (MessageEvent & { type: 'message' }) + | (PointerEvent & { type: 'contextmenu' | 'mouseup' }) + | (KeyboardEvent & { type: 'keydown' | 'keyup' }) + | (FocusEvent & { type: 'blur' }) + ): void { if (isVirtualKeyboardMessage(evt)) { if (!validateOrigin(evt.origin, this.originValidator)) { throw new DOMException( @@ -631,24 +599,24 @@ export class VirtualKeyboard implements VirtualKeyboardInterface, EventTarget { // press. Restore the userSelect on mouse up document.body.style.userSelect = ''; - this.isShifted = false; + this.shiftPressCount = 0; break; case 'contextmenu': - if ((evt as PointerEvent).button !== 2) evt.preventDefault(); + if (evt.button !== 2) evt.preventDefault(); break; case 'keydown': { - const kev = evt as KeyboardEvent; - if (kev.key === 'Shift') this.incrementShiftPress(); + if (evt.key === 'Shift' && !evt.repeat) this.shiftPressCount = 1; break; } + case 'keyup': { - const kev = evt as KeyboardEvent; - if (kev.key !== 'Shift' && this._shiftPressCount === 1) { - this.isCapslock = false; - this._shiftPressCount = 0; - } + if ( + evt.key === 'Shift' || + (!evt.getModifierState('Shift') && this.shiftPressCount !== 2) + ) + this.shiftPressCount = 0; break; } }