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.
This commit is contained in:
Marc Durdin 2022-06-26 15:54:05 +10:00
parent 870d1c8598
commit e5293a695c

View file

@ -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();
}
}
};