feat(web): mnemonic + legacy keystroke pre-proc unit tests

This commit is contained in:
Joshua A. Horton 2024-01-22 14:08:10 +07:00
parent 3c0adc38e4
commit a404c20ddf
4 changed files with 586 additions and 16 deletions

View file

@ -32,7 +32,9 @@ const Codes = {
"ALT_GR_SIM": (0x0001 | 0x0004),
"CHIRAL":0x001F, // The base bitmask for chiral keyboards. Includes SHIFT, which is non-chiral.
"IS_CHIRAL":0x000F, // Used to test if a bitmask uses a chiral modifier.
"NON_CHIRAL":0x0070 // The default bitmask, for non-chiral keyboards
"NON_CHIRAL":0x0070, // The default bitmask, for non-chiral keyboards,
// Represents all modifier codes not supported by KMW 1.0 legacy keyboards.
"NON_LEGACY": 0x006F // ALL, but without the SHIFT bit
},
stateBitmasks: {

View file

@ -121,6 +121,10 @@ export function preprocessKeyboardEvent(e: KeyboardEvent, keyboardState: Keyboar
// Stage 3 - Set our modifier state tracking variable and perform basic AltGr-related management.
const LmodifierChange = keyboardState.modStateFlags != curModState;
// KeyboardState update: save our known modifier/state analysis bits.
// Note: `keyboardState` is typically the full-fledged KeyboardProcessor instance. As a result,
// changes here persist across calls (as we only ever make the one instance).
keyboardState.modStateFlags = curModState;
// For European keyboards, not all browsers properly send both key-up events for the AltGr combo.

View file

@ -39,7 +39,9 @@ export function processForMnemonicsAndLegacy(s: KeyEvent, activeKeyboard: Keyboa
//
// Third: DO, however, track direct presses of any main modifier key. The OSK should
// reflect the current modifier state even for legacy keyboards.
if(!activeKeyboard.definesPositionalOrMnemonic && !(s.Lmodifiers & 0x60) && !s.isModifier) {
if(!activeKeyboard.definesPositionalOrMnemonic &&
!(s.Lmodifiers & Codes.modifierBitmasks.NON_LEGACY) &&
!s.isModifier) {
// Support version 1.0 KeymanWeb keyboards that do not define positional vs mnemonic
s = new KeyEvent({
Lcode: KeyMapping._USKeyCodeToCharCode(s),

View file

@ -5,24 +5,586 @@ import { preprocessKeyboardEvent } from 'keyman/app/browser';
import { processForMnemonicsAndLegacy } from 'keyman/engine/main';
import { PhysicalInputEventSpec } from '@keymanapp/recorder-core';
import { DeviceSpec } from '@keymanapp/web-utils';
import { Codes, Keyboard, KeyEvent } from '@keymanapp/keyboard-processor';
const ModifierCodes = Codes.modifierCodes;
const KeyCodes = Codes.keyCodes;
const DUMMY_DEVICE = new DeviceSpec('chrome', 'desktop', 'windows', false);
// console.log(JSON.stringify(processedEvent));
describe("app/browser: hardware event processing", () => {
describe('preprocessKeyboardEvent', () => {
it('dummy', () => {
let test = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: 20,
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
location: 1
}) as any as KeyboardEvent, {
// Only needs to be non-null for chiral-keystroke detection and for mnemonic detection.
activeKeyboard: null,
modStateFlags: 0,
baseLayout: 'us'
},
new DeviceSpec('chrome', 'desktop', 'windows', false)
);
describe('positional keyboards', () => {
it("simple shifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
location: 1
}) as any as KeyboardEvent, {
activeKeyboard: new Keyboard({ KM: 0 }),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
console.log(JSON.stringify(test));
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
assert.equal(processedEvent.Lmodifiers, ModifierCodes.SHIFT);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
// Note: Codes.modifierCodes.VIRTUAL_KEY is NOT applied here. It's applied by the
// compiler & filtered out directly within the `keyMatch` keyboard-API func. It's
// never part of the actual processed event object within KMW.
});
it("simple unshifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: 0
}) as any as KeyboardEvent, {
activeKeyboard: new Keyboard({ KM: 0 }),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
assert.equal(processedEvent.Lmodifiers, 0);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("left-alt press", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_ALT,
modifierSet: PhysicalInputEventSpec.modifierCodes.Alt,
location: 1
}) as any as KeyboardEvent, {
// KMBM: Keyman Modifier BitMask
activeKeyboard: new Keyboard({KM: 0}),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
assert.equal(processedEvent.Lmodifiers, ModifierCodes.ALT);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("left-alt release", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_ALT,
modifierSet: 0,
location: 1
}) as any as KeyboardEvent, {
// KMBM: Keyman Modifier BitMask
activeKeyboard: new Keyboard({KM: 0}),
modStateFlags: ModifierCodes.ALT,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
assert.equal(processedEvent.Lmodifiers, 0);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
});
describe('positional+chiral keyboards', () => {
it("simple shifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
location: 1
}) as any as KeyboardEvent, {
// KMBM: Keyman Modifier BitMask
activeKeyboard: new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
assert.equal(processedEvent.Lmodifiers, ModifierCodes.SHIFT);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("simple unshifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: 0
}) as any as KeyboardEvent, {
// KMBM: Keyman Modifier BitMask
activeKeyboard: new Keyboard({KM: 0, KMBM: Codes.modifierBitmasks.CHIRAL}),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
assert.equal(processedEvent.Lmodifiers, 0);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("left-alt press", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_ALT,
modifierSet: PhysicalInputEventSpec.modifierCodes.Alt,
location: 1
}) as any as KeyboardEvent, {
// KMBM: Keyman Modifier BitMask
activeKeyboard: new Keyboard({KM: 0, KMBM: Codes.modifierBitmasks.CHIRAL}),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
assert.equal(processedEvent.Lmodifiers, ModifierCodes.LALT);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("left-alt release", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_ALT,
modifierSet: 0,
location: 1
}) as any as KeyboardEvent, {
// KMBM: Keyman Modifier BitMask
activeKeyboard: new Keyboard({KM: 0, KMBM: Codes.modifierBitmasks.CHIRAL}),
modStateFlags: ModifierCodes.LALT,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_ALT);
assert.equal(processedEvent.Lmodifiers, 0);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
});
describe('mnemonic keyboards', () => {
it("simple shifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
location: 1
}) as any as KeyboardEvent, {
activeKeyboard: new Keyboard({ KM: 1 }),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, 'A'.charCodeAt(0));
assert.equal(processedEvent.Lmodifiers, ModifierCodes.SHIFT);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("simple unshifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: 0
}) as any as KeyboardEvent, {
activeKeyboard: new Keyboard({ KM: 1 }),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, 'a'.charCodeAt(0));
assert.equal(processedEvent.Lmodifiers, 0);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
});
describe('legacy keyboards', () => {
it("simple shifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: PhysicalInputEventSpec.modifierCodes.Shift,
location: 1
}) as any as KeyboardEvent, {
activeKeyboard: new Keyboard({ KM: undefined }),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isFalse(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, 'A'.charCodeAt(0));
assert.equal(processedEvent.Lmodifiers, 0);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("simple unshifted 'a'", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: 0
}) as any as KeyboardEvent, {
activeKeyboard: new Keyboard({ KM: undefined }),
modStateFlags: 0,
baseLayout: 'us'
},
DUMMY_DEVICE
);
assert.isFalse(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, 'a'.charCodeAt(0));
assert.equal(processedEvent.Lmodifiers, 0);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
it("'a' during left-alt", () => {
const processedEvent = preprocessKeyboardEvent(new PhysicalInputEventSpec({
keyCode: KeyCodes.K_A,
modifierSet: PhysicalInputEventSpec.modifierCodes.Alt,
location: 0
}) as any as KeyboardEvent, {
activeKeyboard: new Keyboard({ KM: undefined }),
// Internally assumes that the ALT-press event was previously handled, with this as
// the resulting modifier state at the time of key-press.
modStateFlags: ModifierCodes.LALT,
baseLayout: 'us'
},
DUMMY_DEVICE
);
// ... which is used to disable the key within the rule-processing `keyMatch` function, as
// the keyboard's rules weren't compiled with the Codes.VIRTUAL_KEY bit set.
assert.isTrue(processedEvent.LisVirtualKey);
assert.equal(processedEvent.Lcode, KeyCodes.K_A);
assert.equal(processedEvent.Lmodifiers, ModifierCodes.ALT);
assert.equal(processedEvent.Lstates, ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK);
});
});
});
describe('processForMnemonicsAndLegacy', () => {
describe('positional keyboards', () => {
it("simple shifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: ModifierCodes.SHIFT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM: 0}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
it("simple unshifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: 0,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM: 0}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
it("left-alt press", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_ALT,
Lmodifiers: ModifierCodes.ALT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_ALT"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM: 0}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
it("left-alt release", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_ALT,
Lmodifiers: 0,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM: 0}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
});
describe('positional+chiral keyboards', () => {
it("simple shifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: ModifierCodes.SHIFT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
it("simple unshifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: 0,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
it("left-alt press", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_ALT,
Lmodifiers: ModifierCodes.LALT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_ALT"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
it("left-alt release", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_LALT,
Lmodifiers: 0,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:0, KMBM: Codes.modifierBitmasks.CHIRAL}),
'us'
);
assert.strictEqual(finalKeyEvent, baseKeyEvent);
});
});
describe('mnemonic keyboards', () => {
it("simple shifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: ModifierCodes.SHIFT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:1}),
'us'
);
// May be the same instance, but the instance gets mutated. Compare against literals
// for expected values.
assert.equal(finalKeyEvent.Lcode, 'A'.charCodeAt(0));
assert.equal(finalKeyEvent.Lmodifiers, ModifierCodes.SHIFT);
assert.isTrue(finalKeyEvent.LisVirtualKey);
});
it("simple unshifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: 0,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:1}),
'us'
);
// May be the same instance, but the instance gets mutated. Compare against literals
// for expected values.
assert.equal(finalKeyEvent.Lcode, 'a'.charCodeAt(0));
assert.equal(finalKeyEvent.Lmodifiers, 0);
assert.isTrue(finalKeyEvent.LisVirtualKey);
});
});
describe('legacy keyboards', () => {
it("simple shifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: ModifierCodes.SHIFT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:undefined}),
'us'
);
// The event object gets wholesale-replaced.
assert.notStrictEqual(finalKeyEvent, baseKeyEvent);
assert.isFalse(finalKeyEvent.LisVirtualKey);
assert.equal(finalKeyEvent.Lcode, 'A'.charCodeAt(0));
assert.equal(finalKeyEvent.Lmodifiers, 0);
});
it("simple unshifted 'a'", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: 0,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:undefined}),
'us'
);
// The event object gets wholesale-replaced.
assert.notStrictEqual(finalKeyEvent, baseKeyEvent);
assert.isFalse(finalKeyEvent.LisVirtualKey);
assert.equal(finalKeyEvent.Lcode, 'a'.charCodeAt(0));
assert.equal(finalKeyEvent.Lmodifiers, 0);
});
it("'a' during alt", () => {
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: ModifierCodes.ALT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:undefined}),
'us'
);
// Legacy keyboards expect this to be false; this acts as a filter for legacy keyboards
// to prevent key processing with held CTRL / ALT.
assert.isTrue(finalKeyEvent.LisVirtualKey);
assert.equal(finalKeyEvent.Lcode, KeyCodes.K_A);
assert.equal(finalKeyEvent.Lmodifiers, ModifierCodes.ALT);
});
it("'a' during left-alt (invalid state)", () => {
// Not that such a state should ever occur, but if it did... we can ensure it's
// handled robustly.
const baseKeyEvent = new KeyEvent({
Lcode: KeyCodes.K_A,
Lmodifiers: ModifierCodes.LALT,
Lstates: ModifierCodes.NO_CAPS | ModifierCodes.NO_NUM_LOCK | ModifierCodes.NO_SCROLL_LOCK,
LisVirtualKey: true,
device: DUMMY_DEVICE,
kName: "K_A"
});
const finalKeyEvent = processForMnemonicsAndLegacy(
baseKeyEvent,
new Keyboard({KM:undefined}),
'us'
);
// Legacy keyboards expect this to be false; this acts as a filter for legacy keyboards
// to prevent key processing with held CTRL / ALT.
assert.isTrue(finalKeyEvent.LisVirtualKey);
assert.equal(finalKeyEvent.Lcode, KeyCodes.K_A);
assert.equal(finalKeyEvent.Lmodifiers, ModifierCodes.LALT);
});
});
});
});