From e5293a695c278f26e8920072760e1f2fdcab1daa Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Sun, 26 Jun 2022 15:54:05 +1000 Subject: [PATCH] fix(web): Maintain separate Caps Lock states for touch and physical Fixes #6799. Caps Lock state management for touch layouts was not quite right -- it touched the base Caps state variables rather than just the event Lstates property. This meant that it was impossible to track the physical Caps Lock key separately to the touch layout layer, and that the two states would interfere with each other. --- .../src/text/keyboardProcessor.ts | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts b/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts index cfbc3da8b8..e42020747b 100644 --- a/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts +++ b/common/core/web/keyboard-processor/src/text/keyboardProcessor.ts @@ -190,10 +190,14 @@ namespace com.keyman.text { } setSyntheticEventDefaults(Lkc: text.KeyEvent) { - // Set the flags for the state keys. - Lkc.Lstates |= this.stateKeys['K_CAPS'] ? Codes.modifierCodes['CAPS'] : Codes.modifierCodes['NO_CAPS']; - Lkc.Lstates |= this.stateKeys['K_NUMLOCK'] ? Codes.modifierCodes['NUM_LOCK'] : Codes.modifierCodes['NO_NUM_LOCK']; - Lkc.Lstates |= this.stateKeys['K_SCROLL'] ? Codes.modifierCodes['SCROLL_LOCK'] : Codes.modifierCodes['NO_SCROLL_LOCK']; + // Set the flags for the state keys - for desktop devices. For touch + // devices, the only state key in use currently is Caps Lock, which is set + // when the 'caps' layer is active in ActiveKey::constructBaseKeyEvent. + if(!Lkc.device.touchable) { + Lkc.Lstates |= this.stateKeys['K_CAPS'] ? Codes.modifierCodes['CAPS'] : Codes.modifierCodes['NO_CAPS']; + Lkc.Lstates |= this.stateKeys['K_NUMLOCK'] ? Codes.modifierCodes['NUM_LOCK'] : Codes.modifierCodes['NO_NUM_LOCK']; + Lkc.Lstates |= this.stateKeys['K_SCROLL'] ? Codes.modifierCodes['SCROLL_LOCK'] : Codes.modifierCodes['NO_SCROLL_LOCK']; + } // Set LisVirtualKey to false to ensure that nomatch rule does fire for U_xxxx keys if(Lkc.kName && Lkc.kName.substr(0,2) == 'U_') { @@ -272,7 +276,7 @@ namespace com.keyman.text { matchBehavior.mergeInDefaults(defaultBehavior); } matchBehavior.triggerKeyDefault = false; // We've triggered it successfully. - } // If null, we must rely on something else (like the browser, in DOM-aware code) to fulfill the default. + } // If null, we must rely on something else (like the browser, in DOM-aware code) to fulfill the default. this.keyboardInterface.activeTargetOutput = null; } @@ -688,21 +692,10 @@ namespace com.keyman.text { this.layerId = 'default'; } - this.updateStateKeysFromLayer(); - let baseModifierState = text.KeyboardProcessor.getModifierState(this.layerId); this.modStateFlags = baseModifierState | keyEvent.Lstates; } - public updateStateKeysFromLayer() { - if(this.device.formFactor != utils.FormFactor.Desktop) { - // The caps layer works slightly differently on touch than on desktop. - // It's a single layer with no ability to mix with other modifiers - // We need to make sure that the state is kept in sync with the layer. - this.stateKeys['K_CAPS'] = this.layerId == 'caps'; - } - } - static isModifier(Levent: KeyEvent): boolean { switch(Levent.Lcode) { case 16: //"K_SHIFT":16,"K_CONTROL":17,"K_ALT":18 @@ -748,7 +741,6 @@ namespace com.keyman.text { resetContext() { this.layerId = 'default'; - this.updateStateKeysFromLayer(); this.keyboardInterface.resetContextCache(); this._UpdateVKShift(null); }; @@ -758,7 +750,6 @@ namespace com.keyman.text { let layout = this.activeKeyboard.layout(device.formFactor); if(layout.getLayer('numeric')) { this.layerId = 'numeric'; - this.updateStateKeysFromLayer(); } } };