mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-12 20:05:34 +00:00
Merge pull request #12072 from keymanapp/change/web/8146_moveCodes2
refactor(web): refactor and harmonize constants 🏗️
This commit is contained in:
commit
ebd2bf423a
17 changed files with 187 additions and 179 deletions
|
|
@ -4,7 +4,7 @@
|
|||
***/
|
||||
|
||||
import { Version, deepCopy } from "@keymanapp/web-utils";
|
||||
import { TouchLayout } from "@keymanapp/common-types";
|
||||
import { ModifierKeyConstants, TouchLayout } from "@keymanapp/common-types";
|
||||
|
||||
import LayoutFormFactorSpec = TouchLayout.TouchLayoutPlatform;
|
||||
import LayoutLayerBase = TouchLayout.TouchLayoutLayer;
|
||||
|
|
@ -349,31 +349,29 @@ export class Layouts {
|
|||
* Description Get name of layer from code, where the modifer order is determined by ascending bit-flag value.
|
||||
*/
|
||||
static getLayerId(m: number): string {
|
||||
let modifierCodes = Codes.modifierCodes;
|
||||
|
||||
var s='';
|
||||
if(m == 0) {
|
||||
return 'default';
|
||||
} else {
|
||||
if(m & modifierCodes['LCTRL']) {
|
||||
if(m & ModifierKeyConstants.LCTRLFLAG) {
|
||||
s = (s.length > 0 ? s + '-' : '') + 'leftctrl';
|
||||
}
|
||||
if(m & modifierCodes['RCTRL']) {
|
||||
if(m & ModifierKeyConstants.RCTRLFLAG) {
|
||||
s = (s.length > 0 ? s + '-' : '') + 'rightctrl';
|
||||
}
|
||||
if(m & modifierCodes['LALT']) {
|
||||
if(m & ModifierKeyConstants.LALTFLAG) {
|
||||
s = (s.length > 0 ? s + '-' : '') + 'leftalt';
|
||||
}
|
||||
if(m & modifierCodes['RALT']) {
|
||||
if(m & ModifierKeyConstants.RALTFLAG) {
|
||||
s = (s.length > 0 ? s + '-' : '') + 'rightalt';
|
||||
}
|
||||
if(m & modifierCodes['SHIFT']) {
|
||||
if(m & ModifierKeyConstants.K_SHIFTFLAG) {
|
||||
s = (s.length > 0 ? s + '-' : '') + 'shift';
|
||||
}
|
||||
if(m & modifierCodes['CTRL']) {
|
||||
if(m & ModifierKeyConstants.K_CTRLFLAG) {
|
||||
s = (s.length > 0 ? s + '-' : '') + 'ctrl';
|
||||
}
|
||||
if(m & modifierCodes['ALT']) {
|
||||
if(m & ModifierKeyConstants.K_ALTFLAG) {
|
||||
s = (s.length > 0 ? s + '-' : '') + 'alt';
|
||||
}
|
||||
return s;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { EncodedVisualKeyboard, LayoutSpec, Layouts } from "./defaultLayouts.js"
|
|||
import { ActiveKey, ActiveLayout, ActiveSubKey } from "./activeLayout.js";
|
||||
import KeyEvent from "../text/keyEvent.js";
|
||||
import type OutputTarget from "../text/outputTarget.js";
|
||||
import { TouchLayout } from "@keymanapp/common-types";
|
||||
import { ModifierKeyConstants, TouchLayout } from "@keymanapp/common-types";
|
||||
type TouchLayoutSpec = TouchLayout.TouchLayoutPlatform & { isDefault?: boolean};
|
||||
|
||||
import type { ComplexKeyboardStore } from "../text/kbdInterface.js";
|
||||
|
|
@ -108,7 +108,7 @@ export type KeyboardObject = {
|
|||
KRTL?: boolean;
|
||||
/**
|
||||
* Keyboard Modifier BitMask: a set of bitflags indicating which modifiers
|
||||
* the keyboard's rules utilize. See also: `Codes.modifierCodes`.
|
||||
* the keyboard's rules utilize. See also: `ModifierKeyConstants`.
|
||||
*/
|
||||
KMBM?: number;
|
||||
/**
|
||||
|
|
@ -420,8 +420,6 @@ export default class Keyboard {
|
|||
* @return {boolean}
|
||||
*/
|
||||
get emulatesAltGr(): boolean {
|
||||
let modifierCodes = Codes.modifierCodes;
|
||||
|
||||
// If we're not chiral, we're not emulating.
|
||||
if(!this.isChiral) {
|
||||
return false;
|
||||
|
|
@ -437,9 +435,9 @@ export default class Keyboard {
|
|||
return false;
|
||||
}
|
||||
|
||||
var emulationMask = modifierCodes['LCTRL'] | modifierCodes['LALT'];
|
||||
var emulationMask = ModifierKeyConstants.LCTRLFLAG | ModifierKeyConstants.LALTFLAG;
|
||||
var unshiftedEmulationLayer = layers[Layouts.getLayerId(emulationMask)];
|
||||
var shiftedEmulationLayer = layers[Layouts.getLayerId(modifierCodes['SHIFT'] | emulationMask)];
|
||||
var shiftedEmulationLayer = layers[Layouts.getLayerId(ModifierKeyConstants.K_SHIFTFLAG | emulationMask)];
|
||||
|
||||
// buildDefaultLayout ensures that these are aliased to the original modifier set being emulated.
|
||||
// As a result, we can directly test for reference equality.
|
||||
|
|
@ -447,12 +445,12 @@ export default class Keyboard {
|
|||
// This allows us to still return `true` after creating the layers for emulation; during keyboard
|
||||
// construction, the two layers should be null for AltGr emulation to succeed.
|
||||
if(unshiftedEmulationLayer != null &&
|
||||
unshiftedEmulationLayer != layers[Layouts.getLayerId(modifierCodes['RALT'])]) {
|
||||
unshiftedEmulationLayer != layers[Layouts.getLayerId(ModifierKeyConstants.RALTFLAG)]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(shiftedEmulationLayer != null &&
|
||||
shiftedEmulationLayer != layers[Layouts.getLayerId(modifierCodes['RALT'] | modifierCodes['SHIFT'])]) {
|
||||
shiftedEmulationLayer != layers[Layouts.getLayerId(ModifierKeyConstants.RALTFLAG | ModifierKeyConstants.K_SHIFTFLAG)]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -665,9 +663,9 @@ export default class Keyboard {
|
|||
* same for the other modifiers.
|
||||
*/
|
||||
Lkc.Lstates = 0;
|
||||
Lkc.Lstates |= stateKeys['K_CAPS'] ? Codes.modifierCodes['CAPS'] : Codes.modifierCodes['NO_CAPS'];
|
||||
Lkc.Lstates |= stateKeys['K_NUMLOCK'] ? Codes.modifierCodes['NUM_LOCK'] : Codes.modifierCodes['NO_NUM_LOCK'];
|
||||
Lkc.Lstates |= stateKeys['K_SCROLL'] ? Codes.modifierCodes['SCROLL_LOCK'] : Codes.modifierCodes['NO_SCROLL_LOCK'];
|
||||
Lkc.Lstates |= stateKeys['K_CAPS'] ? ModifierKeyConstants.CAPITALFLAG : ModifierKeyConstants.NOTCAPITALFLAG;
|
||||
Lkc.Lstates |= stateKeys['K_NUMLOCK'] ? ModifierKeyConstants.NUMLOCKFLAG : ModifierKeyConstants.NOTNUMLOCKFLAG;
|
||||
Lkc.Lstates |= stateKeys['K_SCROLL'] ? ModifierKeyConstants.SCROLLFLAG : ModifierKeyConstants.NOTSCROLLFLAG;
|
||||
}
|
||||
|
||||
// Set LisVirtualKey to false to ensure that nomatch rule does fire for U_xxxx keys
|
||||
|
|
@ -689,7 +687,7 @@ export default class Keyboard {
|
|||
// Handles modifier states when the OSK is emulating rightalt through the leftctrl-leftalt layer.
|
||||
if((Lkc.Lmodifiers & Codes.modifierBitmasks['ALT_GR_SIM']) == Codes.modifierBitmasks['ALT_GR_SIM'] && this.emulatesAltGr) {
|
||||
Lkc.Lmodifiers &= ~Codes.modifierBitmasks['ALT_GR_SIM'];
|
||||
Lkc.Lmodifiers |= Codes.modifierCodes['RALT'];
|
||||
Lkc.Lmodifiers |= ModifierKeyConstants.RALTFLAG;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -729,4 +727,4 @@ export default class Keyboard {
|
|||
const res=dict[keyName.toUpperCase()];
|
||||
return res ? res : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ export interface KeyboardKeymanGlobal {
|
|||
* Defines any public API points used by debug-compiled keyboards for human-readable
|
||||
* nomenclature in rules within a Keyman keyboard's script for keyboard rules.
|
||||
*
|
||||
* Refer to C:\keymanapp\keyman\developer\src\tike\compile\CompileKeymanWeb.pas,
|
||||
* TCompileKeymanWeb.JavaScript_SetupDebug.
|
||||
* Refer to TCompileKeymanWeb.JavaScript_SetupDebug.
|
||||
*/
|
||||
export interface MinimalCodesInterface {
|
||||
readonly modifierCodes: typeof Codes.modifierCodes;
|
||||
|
|
|
|||
|
|
@ -1,31 +1,34 @@
|
|||
// TODO: Move to separate folder: 'codes'
|
||||
// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.
|
||||
/*
|
||||
* Keyman is copyright (C) SIL International. MIT License.
|
||||
*
|
||||
* Keyboard key codes and modifier bitmasks.
|
||||
*/
|
||||
|
||||
// see also: common/web/types/src/kmx/kmx.ts
|
||||
import { ModifierKeyConstants, USVirtualKeyCodes } from '@keymanapp/common-types';
|
||||
|
||||
const Codes = {
|
||||
// Define Keyman Developer modifier bit-flags (exposed for use by other modules)
|
||||
// Compare against /common/include/kmx_file.h. CTRL+F "#define LCTRLFLAG" to find the secton.
|
||||
modifierCodes: {
|
||||
"LCTRL":0x0001, // LCTRLFLAG
|
||||
"RCTRL":0x0002, // RCTRLFLAG
|
||||
"LALT":0x0004, // LALTFLAG
|
||||
"RALT":0x0008, // RALTFLAG
|
||||
"SHIFT":0x0010, // K_SHIFTFLAG
|
||||
"CTRL":0x0020, // K_CTRLFLAG
|
||||
"ALT":0x0040, // K_ALTFLAG
|
||||
// Debug-mode keyboards compiled before Keyman 18.0 referenced the `ModifierKeyConstants`
|
||||
// constants via the names established below. We must continue to support them, as they're
|
||||
// essentially part of the keyboard API now.
|
||||
"LCTRL": ModifierKeyConstants.LCTRLFLAG,
|
||||
"RCTRL": ModifierKeyConstants.RCTRLFLAG,
|
||||
"LALT": ModifierKeyConstants.LALTFLAG,
|
||||
"RALT": ModifierKeyConstants.RALTFLAG,
|
||||
"SHIFT": ModifierKeyConstants.K_SHIFTFLAG,
|
||||
"CTRL": ModifierKeyConstants.K_CTRLFLAG,
|
||||
"ALT": ModifierKeyConstants.K_ALTFLAG,
|
||||
// TENTATIVE: Represents command keys, which some OSes use for shortcuts we don't
|
||||
// want to block. No rule will ever target a modifier set with this bit set to 1.
|
||||
"META":0x0080, // K_METAFLAG
|
||||
"CAPS":0x0100, // CAPITALFLAG
|
||||
"NO_CAPS":0x0200, // NOTCAPITALFLAG
|
||||
"NUM_LOCK":0x0400, // NUMLOCKFLAG
|
||||
"NO_NUM_LOCK":0x0800, // NOTNUMLOCKFLAG
|
||||
"SCROLL_LOCK":0x1000, // SCROLLFLAG
|
||||
"NO_SCROLL_LOCK":0x2000, // NOTSCROLLFLAG
|
||||
"VIRTUAL_KEY":0x4000, // ISVIRTUALKEY
|
||||
"VIRTUAL_CHAR_KEY":0x8000 // VIRTUALCHARKEY // Unused by KMW, but reserved for use by other Keyman engines.
|
||||
|
||||
"META": ModifierKeyConstants.K_METAFLAG,
|
||||
"CAPS": ModifierKeyConstants.CAPITALFLAG,
|
||||
"NO_CAPS": ModifierKeyConstants.NOTCAPITALFLAG,
|
||||
"NUM_LOCK": ModifierKeyConstants.NUMLOCKFLAG,
|
||||
"NO_NUM_LOCK": ModifierKeyConstants.NOTNUMLOCKFLAG,
|
||||
"SCROLL_LOCK": ModifierKeyConstants.SCROLLFLAG,
|
||||
"NO_SCROLL_LOCK": ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
"VIRTUAL_KEY": ModifierKeyConstants.ISVIRTUALKEY,
|
||||
"VIRTUAL_CHAR_KEY": ModifierKeyConstants.VIRTUALCHARKEY // Unused by KMW, but reserved for use by other Keyman engines.
|
||||
// Note: keys_mod_other = 0x10000, used by KMX+ for the
|
||||
// other modifier flag in layers, > 16 bit so not available here.
|
||||
// See keys_mod_other in keyman_core_ldml.ts
|
||||
|
|
@ -50,35 +53,7 @@ const Codes = {
|
|||
|
||||
// Define standard keycode numbers (exposed for use by other modules)
|
||||
keyCodes: {
|
||||
"K_BKSP":8,"K_TAB":9,"K_ENTER":13,
|
||||
"K_SHIFT":16,"K_CONTROL":17,"K_ALT":18,"K_PAUSE":19,"K_CAPS":20,
|
||||
"K_ESC":27,"K_SPACE":32,"K_PGUP":33,
|
||||
"K_PGDN":34,"K_END":35,"K_HOME":36,"K_LEFT":37,"K_UP":38,
|
||||
"K_RIGHT":39,"K_DOWN":40,"K_SEL":41,"K_PRINT":42,"K_EXEC":43,
|
||||
"K_INS":45,"K_DEL":46,"K_HELP":47,"K_0":48,
|
||||
"K_1":49,"K_2":50,"K_3":51,"K_4":52,"K_5":53,"K_6":54,"K_7":55,
|
||||
"K_8":56,"K_9":57,"K_A":65,"K_B":66,"K_C":67,"K_D":68,"K_E":69,
|
||||
"K_F":70,"K_G":71,"K_H":72,"K_I":73,"K_J":74,"K_K":75,"K_L":76,
|
||||
"K_M":77,"K_N":78,"K_O":79,"K_P":80,"K_Q":81,"K_R":82,"K_S":83,
|
||||
"K_T":84,"K_U":85,"K_V":86,"K_W":87,"K_X":88,"K_Y":89,"K_Z":90,
|
||||
"K_NP0":96,"K_NP1":97,"K_NP2":98,
|
||||
"K_NP3":99,"K_NP4":100,"K_NP5":101,"K_NP6":102,
|
||||
"K_NP7":103,"K_NP8":104,"K_NP9":105,"K_NPSTAR":106,
|
||||
"K_NPPLUS":107,"K_SEPARATOR":108,"K_NPMINUS":109,"K_NPDOT":110,
|
||||
"K_NPSLASH":111,"K_F1":112,"K_F2":113,"K_F3":114,"K_F4":115,
|
||||
"K_F5":116,"K_F6":117,"K_F7":118,"K_F8":119,"K_F9":120,
|
||||
"K_F10":121,"K_F11":122,"K_F12":123,"K_NUMLOCK":144,"K_SCROLL":145,
|
||||
"K_LSHIFT":160,"K_RSHIFT":161,"K_LCONTROL":162,"K_RCONTROL":163,
|
||||
"K_LALT":164,"K_RALT":165,
|
||||
"K_COLON":186,"K_EQUAL":187,"K_COMMA":188,"K_HYPHEN":189,
|
||||
"K_PERIOD":190,"K_SLASH":191,"K_BKQUOTE":192,
|
||||
"K_LBRKT":219,"K_BKSLASH":220,"K_RBRKT":221,
|
||||
"K_QUOTE":222,"K_oE2":226,"K_OE2":226,
|
||||
"K_LOPT":50001,"K_ROPT":50002,
|
||||
"K_NUMERALS":50003,"K_SYMBOLS":50004,"K_CURRENCIES":50005,
|
||||
"K_UPPER":50006,"K_LOWER":50007,"K_ALPHA":50008,
|
||||
"K_SHIFTED":50009,"K_ALTGR":50010,
|
||||
"K_TABBACK":50011,"K_TABFWD":50012
|
||||
...USVirtualKeyCodes,
|
||||
} as {[name: string]: number},
|
||||
|
||||
codesUS: [
|
||||
|
|
@ -117,34 +92,34 @@ const Codes = {
|
|||
getModifierState(layerId: string): number {
|
||||
var modifier=0;
|
||||
if(layerId.indexOf('shift') >= 0) {
|
||||
modifier |= Codes.modifierCodes['SHIFT'];
|
||||
modifier |= ModifierKeyConstants.K_SHIFTFLAG;
|
||||
}
|
||||
|
||||
// The chiral checks must not be directly exclusive due each other to visual OSK feedback.
|
||||
var ctrlMatched=false;
|
||||
if(layerId.indexOf('leftctrl') >= 0) {
|
||||
modifier |= Codes.modifierCodes['LCTRL'];
|
||||
modifier |= ModifierKeyConstants.LCTRLFLAG;
|
||||
ctrlMatched=true;
|
||||
}
|
||||
if(layerId.indexOf('rightctrl') >= 0) {
|
||||
modifier |= Codes.modifierCodes['RCTRL'];
|
||||
modifier |= ModifierKeyConstants.RCTRLFLAG;
|
||||
ctrlMatched=true;
|
||||
}
|
||||
if(layerId.indexOf('ctrl') >= 0 && !ctrlMatched) {
|
||||
modifier |= Codes.modifierCodes['CTRL'];
|
||||
modifier |= ModifierKeyConstants.K_CTRLFLAG;
|
||||
}
|
||||
|
||||
var altMatched=false;
|
||||
if(layerId.indexOf('leftalt') >= 0) {
|
||||
modifier |= Codes.modifierCodes['LALT'];
|
||||
modifier |= ModifierKeyConstants.LALTFLAG;
|
||||
altMatched=true;
|
||||
}
|
||||
if(layerId.indexOf('rightalt') >= 0) {
|
||||
modifier |= Codes.modifierCodes['RALT'];
|
||||
modifier |= ModifierKeyConstants.RALTFLAG;
|
||||
altMatched=true;
|
||||
}
|
||||
if(layerId.indexOf('alt') >= 0 && !altMatched) {
|
||||
modifier |= Codes.modifierCodes['ALT'];
|
||||
modifier |= ModifierKeyConstants.K_ALTFLAG;
|
||||
}
|
||||
|
||||
return modifier;
|
||||
|
|
@ -160,9 +135,9 @@ const Codes = {
|
|||
var modifier=0;
|
||||
|
||||
if(layerId.indexOf('caps') >= 0) {
|
||||
modifier |= Codes.modifierCodes['CAPS'];
|
||||
modifier |= ModifierKeyConstants.CAPITALFLAG;
|
||||
} else {
|
||||
modifier |= Codes.modifierCodes['NO_CAPS'];
|
||||
modifier |= ModifierKeyConstants.NOTCAPITALFLAG;
|
||||
}
|
||||
|
||||
return modifier;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// We should start splitting off code needed by keyboards even without a KeyboardProcessor active.
|
||||
// There's an upcoming `/common/web/types` package that 'codes' and 'keyboards' may fit well within.
|
||||
|
||||
import { ModifierKeyConstants} from '@keymanapp/common-types';
|
||||
import Codes from "./codes.js";
|
||||
import type KeyEvent from "./keyEvent.js";
|
||||
import type OutputTarget from "./outputTarget.js";
|
||||
|
|
@ -190,7 +191,7 @@ export default class DefaultRules {
|
|||
|
||||
// check if exact match to SHIFT's code. Only the 'default' and 'shift' layers should have default key outputs.
|
||||
// TODO: Extend to allow AltGr as well - better mnemonic support.
|
||||
if(keyShiftState == Codes.modifierCodes['SHIFT']) {
|
||||
if(keyShiftState == ModifierKeyConstants.K_SHIFTFLAG) {
|
||||
keyShiftState = 1;
|
||||
} else if(keyShiftState != 0) {
|
||||
if(ruleBehavior) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
//#region Imports
|
||||
|
||||
import { type DeviceSpec } from "@keymanapp/web-utils";
|
||||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
|
||||
import Codes from "./codes.js";
|
||||
import type KeyEvent from "./keyEvent.js";
|
||||
|
|
@ -552,8 +553,8 @@ export default class KeyboardInterface extends KeyboardHarness {
|
|||
* @returns
|
||||
*/
|
||||
private static matchModifiersToRuleChirality(eventModifiers: number, targetModifierMask: number): number {
|
||||
const CHIRAL_ALT = Codes.modifierCodes["LALT"] | Codes.modifierCodes["RALT"];
|
||||
const CHIRAL_CTRL = Codes.modifierCodes["LCTRL"] | Codes.modifierCodes["RCTRL"];
|
||||
const CHIRAL_ALT = ModifierKeyConstants.LALTFLAG | ModifierKeyConstants.RALTFLAG;
|
||||
const CHIRAL_CTRL = ModifierKeyConstants.LCTRLFLAG | ModifierKeyConstants.RCTRLFLAG;
|
||||
|
||||
let modifiers = eventModifiers;
|
||||
|
||||
|
|
@ -563,7 +564,7 @@ export default class KeyboardInterface extends KeyboardHarness {
|
|||
|
||||
if(altIntersection) {
|
||||
// Undo the chiral part and replace with non-chiral.
|
||||
modifiers ^= altIntersection | Codes.modifierCodes["ALT"];
|
||||
modifiers ^= altIntersection | ModifierKeyConstants.K_ALTFLAG;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -573,7 +574,7 @@ export default class KeyboardInterface extends KeyboardHarness {
|
|||
|
||||
if(ctrlIntersection) {
|
||||
// Undo the chiral part and replace with non-chiral.
|
||||
modifiers ^= ctrlIntersection | Codes.modifierCodes["CTRL"];
|
||||
modifiers ^= ctrlIntersection | ModifierKeyConstants.K_CTRLFLAG;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -939,7 +940,7 @@ export default class KeyboardInterface extends KeyboardHarness {
|
|||
// Denote the changed store as part of the matched rule's behavior.
|
||||
this.ruleBehavior.setStore[systemId] = strValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1178,4 +1179,4 @@ export default class KeyboardInterface extends KeyboardHarness {
|
|||
(function() {
|
||||
// This will be the only call within the keyboard-processor module.
|
||||
KeyboardInterface.__publishShorthandAPI();
|
||||
}());
|
||||
}());
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import KeyboardInterface, { SystemStoreIDs, VariableStore } from "./kbdInterface
|
|||
import RuleBehavior from "./ruleBehavior.js";
|
||||
|
||||
import { DeviceSpec, globalObject } from "@keymanapp/web-utils";
|
||||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
|
||||
// #endregion
|
||||
|
||||
|
|
@ -275,7 +276,8 @@ export default class KeyboardProcessor extends EventEmitter<EventMap> {
|
|||
let keyShiftState=0;
|
||||
|
||||
const lockNames = ['CAPS', 'NUM_LOCK', 'SCROLL_LOCK'] as const;
|
||||
const lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'] as const;
|
||||
const lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'] as const;
|
||||
const lockModifiers = [ ModifierKeyConstants.CAPITALFLAG, ModifierKeyConstants.NUMLOCKFLAG, ModifierKeyConstants.SCROLLFLAG] as const;
|
||||
|
||||
if(!this.activeKeyboard) {
|
||||
return true;
|
||||
|
|
@ -289,14 +291,14 @@ export default class KeyboardProcessor extends EventEmitter<EventMap> {
|
|||
if(this.activeKeyboard.isChiral && (this.activeKeyboard.emulatesAltGr) &&
|
||||
(this.modStateFlags & Codes.modifierBitmasks['ALT_GR_SIM']) == Codes.modifierBitmasks['ALT_GR_SIM']) {
|
||||
keyShiftState |= Codes.modifierBitmasks['ALT_GR_SIM'];
|
||||
keyShiftState &= ~Codes.modifierCodes['RALT'];
|
||||
keyShiftState &= ~ModifierKeyConstants.RALTFLAG;
|
||||
}
|
||||
|
||||
// Set stateKeys where corresponding value is passed in e.Lstates
|
||||
let stateMutation = false;
|
||||
for(let i=0; i < lockNames.length; i++) {
|
||||
if(e.Lstates & Codes.stateBitmasks[lockNames[i]]) {
|
||||
this.stateKeys[lockKeys[i]] = !!(e.Lstates & Codes.modifierCodes[lockNames[i]]);
|
||||
this.stateKeys[lockKeys[i]] = !!(e.Lstates & lockModifiers[i]);
|
||||
stateMutation = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -314,7 +316,7 @@ export default class KeyboardProcessor extends EventEmitter<EventMap> {
|
|||
if(!e || !e.isModifier) {
|
||||
// Mnemonic keystrokes manipulate the SHIFT property based on CAPS state.
|
||||
// We need to unflip them when tracking the OSK layer.
|
||||
keyShiftState ^= Codes.modifierCodes['SHIFT'];
|
||||
keyShiftState ^= ModifierKeyConstants.K_SHIFTFLAG;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -323,23 +325,22 @@ export default class KeyboardProcessor extends EventEmitter<EventMap> {
|
|||
}
|
||||
|
||||
private updateStates(): void {
|
||||
var lockNames = ['CAPS', 'NUM_LOCK', 'SCROLL_LOCK'] as const;
|
||||
var lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'] as const;
|
||||
const lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'] as const;
|
||||
const lockModifiers = [ModifierKeyConstants.CAPITALFLAG, ModifierKeyConstants.NUMLOCKFLAG, ModifierKeyConstants.SCROLLFLAG] as const;
|
||||
const noLockModifers = [ModifierKeyConstants.NOTCAPITALFLAG, ModifierKeyConstants.NOTNUMLOCKFLAG, ModifierKeyConstants.NOTSCROLLFLAG] as const;
|
||||
|
||||
for(let i=0; i < lockKeys.length; i++) {
|
||||
const key = lockKeys[i];
|
||||
const flag = this.stateKeys[key];
|
||||
const onBit = lockNames[i];
|
||||
const offBit = 'NO_' + lockNames[i];
|
||||
|
||||
// Ensures that the current mod-state info properly matches the currently-simulated
|
||||
// state key states.
|
||||
if(flag) {
|
||||
this.modStateFlags |= Codes.modifierCodes[onBit];
|
||||
this.modStateFlags &= ~Codes.modifierCodes[offBit];
|
||||
this.modStateFlags |= lockModifiers[i];
|
||||
this.modStateFlags &= ~noLockModifers[i];
|
||||
} else {
|
||||
this.modStateFlags &= ~Codes.modifierCodes[onBit];
|
||||
this.modStateFlags |= Codes.modifierCodes[offBit];
|
||||
this.modStateFlags &= ~lockModifiers[i];
|
||||
this.modStateFlags |= noLockModifers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -484,25 +485,25 @@ export default class KeyboardProcessor extends EventEmitter<EventMap> {
|
|||
// Toggle the modifier represented by our input argument.
|
||||
switch(id) {
|
||||
case 'shift':
|
||||
modifier ^= Codes.modifierCodes['SHIFT'];
|
||||
modifier ^= ModifierKeyConstants.K_SHIFTFLAG;
|
||||
break;
|
||||
case 'leftctrl':
|
||||
modifier ^= Codes.modifierCodes['LCTRL'];
|
||||
modifier ^= ModifierKeyConstants.LCTRLFLAG;
|
||||
break;
|
||||
case 'rightctrl':
|
||||
modifier ^= Codes.modifierCodes['RCTRL'];
|
||||
modifier ^= ModifierKeyConstants.RCTRLFLAG;
|
||||
break;
|
||||
case 'ctrl':
|
||||
modifier ^= Codes.modifierCodes['CTRL'];
|
||||
modifier ^= ModifierKeyConstants.K_CTRLFLAG;
|
||||
break;
|
||||
case 'leftalt':
|
||||
modifier ^= Codes.modifierCodes['LALT'];
|
||||
modifier ^= ModifierKeyConstants.LALTFLAG;
|
||||
break;
|
||||
case 'rightalt':
|
||||
modifier ^= Codes.modifierCodes['RALT'];
|
||||
modifier ^= ModifierKeyConstants.RALTFLAG;
|
||||
break;
|
||||
case 'alt':
|
||||
modifier ^= Codes.modifierCodes['ALT'];
|
||||
modifier ^= ModifierKeyConstants.K_ALTFLAG;
|
||||
break;
|
||||
default:
|
||||
s = id;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import fs from 'fs';
|
|||
import { createRequire } from 'module';
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
import { Codes, KeyboardInterface, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor';
|
||||
import { KeyboardInterface, MinimalKeymanGlobal } from '@keymanapp/keyboard-processor';
|
||||
import { NodeKeyboardLoader } from '@keymanapp/keyboard-processor/node-keyboard-loader';
|
||||
import { KeyboardTest, NodeProctor } from '@keymanapp/recorder-core';
|
||||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
|
||||
describe('Engine - Chirality', function() {
|
||||
let testJSONtext = fs.readFileSync(require.resolve('@keymanapp/common-test-resources/json/engine_tests/chirality.json'));
|
||||
|
|
@ -53,14 +54,14 @@ describe('Engine - Chirality', function() {
|
|||
}
|
||||
|
||||
describe("Chiral modifier mapping", function() {
|
||||
let VIRTUAL_KEY_CODE = Codes.modifierCodes["VIRTUAL_KEY"];
|
||||
let CTRL_CODE = Codes.modifierCodes["CTRL"];
|
||||
let LCTRL_CODE = Codes.modifierCodes["LCTRL"];
|
||||
let RCTRL_CODE = Codes.modifierCodes["RCTRL"];
|
||||
let ALT_CODE = Codes.modifierCodes["ALT"];
|
||||
let LALT_CODE = Codes.modifierCodes["LALT"];
|
||||
let RALT_CODE = Codes.modifierCodes["RALT"];
|
||||
let SHIFT_CODE = Codes.modifierCodes["SHIFT"];
|
||||
let VIRTUAL_KEY_CODE = ModifierKeyConstants.VIRTUAL_KEYFLAG;
|
||||
let CTRL_CODE = ModifierKeyConstants.K_CTRLFLAG;
|
||||
let LCTRL_CODE = ModifierKeyConstants.LCTRLFLAG;
|
||||
let RCTRL_CODE = ModifierKeyConstants.RCTRLFLAG;
|
||||
let ALT_CODE = ModifierKeyConstants.K_ALTFLAG;
|
||||
let LALT_CODE = ModifierKeyConstants.LALTFLAG;
|
||||
let RALT_CODE = ModifierKeyConstants.RALTFLAG;
|
||||
let SHIFT_CODE = ModifierKeyConstants.K_SHIFTFLAG;
|
||||
|
||||
it("does not affect non-chiral KeyEvents - CTRL only", function() {
|
||||
let initialModifiers = VIRTUAL_KEY_CODE | CTRL_CODE;
|
||||
|
|
@ -249,4 +250,4 @@ describe('Engine - Chirality', function() {
|
|||
assert.equal(modifierTarget, mappedModifiers);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { assert } from 'chai';
|
||||
import fs from 'fs';
|
||||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
|
||||
import { createRequire } from 'module';
|
||||
const require = createRequire(import.meta.url);
|
||||
|
|
@ -44,8 +44,8 @@ describe('Engine - rule processing', function() {
|
|||
let mnemonicEvent = new KeyEvent({
|
||||
// sil_ipa is a mnenomic keyboard: it expects codes based on the key's standard character output.
|
||||
Lcode: '>'.charCodeAt(0), // 62
|
||||
Lmodifiers: Codes.modifierCodes.SHIFT, // '>' is shift-layer.
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lmodifiers: ModifierKeyConstants.K_SHIFTFLAG, // '>' is shift-layer.
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_N,
|
||||
|
|
@ -66,7 +66,7 @@ describe('Engine - rule processing', function() {
|
|||
// sil_ipa is a mnenomic keyboard: it expects codes based on the key's standard character output.
|
||||
Lcode: '>'.charCodeAt(0), // 62
|
||||
Lmodifiers: 0, // '>' is shift-layer, not default - and this matters for context matching.
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_N,
|
||||
|
|
@ -84,8 +84,8 @@ describe('Engine - rule processing', function() {
|
|||
let positionalEvent = new KeyEvent({
|
||||
// If it were positional, we'd use this instead:
|
||||
Lcode: Codes.keyCodes.K_COMMA, // 188
|
||||
Lmodifiers: Codes.modifierCodes.SHIFT, // '>' is shift-layer.
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lmodifiers: ModifierKeyConstants.K_SHIFTFLAG, // '>' is shift-layer.
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_N,
|
||||
|
|
@ -123,7 +123,7 @@ describe('Engine - rule processing', function() {
|
|||
// armenian is a KMW 1.0 keyboard: it expects codes based on the key's standard character output.
|
||||
Lcode: 'a'.charCodeAt(0),
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NO_CAPSFLAG | ModifierKeyConstants.NO_NUM_LOCKFLAG | ModifierKeyConstants.NO_SCROLL_LOCKFLAG,
|
||||
LisVirtualKey: false,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_N,
|
||||
|
|
@ -143,7 +143,7 @@ describe('Engine - rule processing', function() {
|
|||
// armenian is a KMW 1.0 keyboard: it expects codes based on the key's standard character output.
|
||||
Lcode: 'a'.charCodeAt(0),
|
||||
Lmodifiers: 27,
|
||||
Lstates: Codes.modifierCodes.CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.SCROLL_LOCK | 0x5C00,
|
||||
Lstates: ModifierKeyConstants.CAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.SCROLLFLAG | 0x5C00,
|
||||
LisVirtualKey: false,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_N,
|
||||
|
|
@ -163,7 +163,7 @@ describe('Engine - rule processing', function() {
|
|||
// armenian is a KMW 1.0 keyboard: it expects codes based on the key's standard character output.
|
||||
Lcode: 'a'.charCodeAt(0),
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_N,
|
||||
|
|
@ -182,7 +182,7 @@ describe('Engine - rule processing', function() {
|
|||
// If it were positional, we'd use this instead:
|
||||
Lcode: Codes.keyCodes.K_A,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_N,
|
||||
|
|
@ -195,4 +195,4 @@ describe('Engine - rule processing', function() {
|
|||
assert.isTrue(positionalResult.triggerKeyDefault);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const require = createRequire(import.meta.url);
|
|||
|
||||
import { Codes, KeyboardInterface, KeyboardProcessor, KeyEvent, MinimalKeymanGlobal, Mock } from '@keymanapp/keyboard-processor';
|
||||
import { NodeKeyboardLoader } from '@keymanapp/keyboard-processor/node-keyboard-loader';
|
||||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
|
||||
|
||||
const TEST_DEVICE = {
|
||||
|
|
@ -17,8 +18,6 @@ const TEST_DEVICE = {
|
|||
|
||||
// Basic scaffolding necessary to use special, locally-defined test keyboards.
|
||||
const COMMON_KBD_SCRIPT_PROPS = new (function (){
|
||||
var modCodes = Codes.modifierCodes;
|
||||
|
||||
this.KMINVER="10.0";
|
||||
// this.KV left empty - we aren't doing layout stuff for this test, so it's "fine".
|
||||
// - also this.KV.KLS
|
||||
|
|
@ -26,7 +25,7 @@ const COMMON_KBD_SCRIPT_PROPS = new (function (){
|
|||
this.KH='';
|
||||
this.KM=0;
|
||||
this.KBVER="0.0.1";
|
||||
this.KMBM=modCodes.SHIFT /* 0x0010 */;
|
||||
this.KMBM=ModifierKeyConstants.K_SHIFTFLAG /* 0x0010 */;
|
||||
this.gs=function(t,e) {
|
||||
return this.g_main(t,e);
|
||||
};
|
||||
|
|
@ -131,7 +130,7 @@ describe('Engine - specialized backspace handling', function() {
|
|||
let event = new KeyEvent({
|
||||
Lcode: Codes.keyCodes.K_BKSP,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_BKSP,
|
||||
|
|
@ -159,7 +158,7 @@ describe('Engine - specialized backspace handling', function() {
|
|||
let event = new KeyEvent({
|
||||
Lcode: Codes.keyCodes.K_A,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_A,
|
||||
|
|
@ -194,7 +193,7 @@ describe('Engine - specialized backspace handling', function() {
|
|||
let event = new KeyEvent({
|
||||
Lcode: Codes.keyCodes.K_BKSP,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_BKSP,
|
||||
|
|
@ -229,7 +228,7 @@ describe('Engine - specialized backspace handling', function() {
|
|||
let event = new KeyEvent({
|
||||
Lcode: Codes.keyCodes.K_BKSP,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_BKSP,
|
||||
|
|
@ -257,7 +256,7 @@ describe('Engine - specialized backspace handling', function() {
|
|||
let event = new KeyEvent({
|
||||
Lcode: Codes.keyCodes.K_BKSP,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_BKSP,
|
||||
|
|
@ -285,7 +284,7 @@ describe('Engine - specialized backspace handling', function() {
|
|||
let event = new KeyEvent({
|
||||
Lcode: Codes.keyCodes.K_BKSP,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_BKSP,
|
||||
|
|
@ -320,7 +319,7 @@ describe('Engine - specialized backspace handling', function() {
|
|||
let event = new KeyEvent({
|
||||
Lcode: Codes.keyCodes.K_BKSP,
|
||||
Lmodifiers: 0,
|
||||
Lstates: Codes.modifierCodes.NO_CAPS | Codes.modifierCodes.NO_NUM_LOCK | Codes.modifierCodes.NO_SCROLL_LOCK,
|
||||
Lstates: ModifierKeyConstants.NOTCAPITALFLAG | ModifierKeyConstants.NOTNUMLOCKFLAG | ModifierKeyConstants.NOTSCROLLFLAG,
|
||||
LisVirtualKey: true,
|
||||
kName: '',
|
||||
vkCode: Codes.keyCodes.K_BKSP,
|
||||
|
|
@ -346,4 +345,4 @@ describe('Engine - specialized backspace handling', function() {
|
|||
assert.equal(transform.deleteLeft, 0);
|
||||
assert.isNotOk(transform.deleteRight);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
33
common/web/types/src/consts/modifier-key-constants.ts
Normal file
33
common/web/types/src/consts/modifier-key-constants.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Keyman is copyright (C) SIL International. MIT License.
|
||||
*
|
||||
* Modifier key bit-flags
|
||||
*/
|
||||
|
||||
export const ModifierKeyConstants = {
|
||||
// Define Keyman Developer modifier bit-flags (exposed for use by other modules)
|
||||
// Compare against /common/include/kmx_file.h. CTRL+F "#define LCTRLFLAG" to find the secton.
|
||||
LCTRLFLAG: 0x0001, // Left Control flag
|
||||
RCTRLFLAG: 0x0002, // Right Control flag
|
||||
LALTFLAG: 0x0004, // Left Alt flag
|
||||
RALTFLAG: 0x0008, // Right Alt flag
|
||||
K_SHIFTFLAG: 0x0010, // Either shift flag
|
||||
K_CTRLFLAG: 0x0020, // Either ctrl flag
|
||||
K_ALTFLAG: 0x0040, // Either alt flag
|
||||
K_METAFLAG: 0x0080, // Either Meta-key flag (tentative). Not usable in keyboard rules;
|
||||
// Used internally (currently, only by KMW) to ensure Meta-key
|
||||
// shortcuts safely bypass rules
|
||||
// Meta key = Command key on macOS, Windows key on Windows/Linux
|
||||
CAPITALFLAG: 0x0100, // Caps lock on
|
||||
NOTCAPITALFLAG: 0x0200, // Caps lock NOT on
|
||||
NUMLOCKFLAG: 0x0400, // Num lock on
|
||||
NOTNUMLOCKFLAG: 0x0800, // Num lock NOT on
|
||||
SCROLLFLAG: 0x1000, // Scroll lock on
|
||||
NOTSCROLLFLAG: 0x2000, // Scroll lock NOT on
|
||||
ISVIRTUALKEY: 0x4000, // It is a Virtual Key Sequence
|
||||
VIRTUALCHARKEY: 0x8000, // Keyman 6.0: Virtual Key Cap Sequence NOT YET
|
||||
|
||||
// Note: OTHER_MODIFIER = 0x10000, used by KMX+ for the
|
||||
// other modifier flag in layers, > 16 bit so not available here.
|
||||
// See keys_mod_other in keyman_core_ldml.ts
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
// Define standard keycode numbers (exposed for use by other modules)
|
||||
// TODO-LDML: merge with common\web\keyboard-processor\src\text\codes.ts
|
||||
|
||||
/**
|
||||
* May include non-US virtual key codes
|
||||
|
|
@ -128,7 +127,7 @@ export const USVirtualKeyCodes = {
|
|||
'k_?C1':193,
|
||||
K_oDF:0xDF,
|
||||
K_ODF:0xDF,
|
||||
/*K_LOPT:50001,
|
||||
K_LOPT:50001,
|
||||
K_ROPT:50002,
|
||||
K_NUMERALS:50003,
|
||||
K_SYMBOLS:50004,
|
||||
|
|
@ -139,7 +138,7 @@ export const USVirtualKeyCodes = {
|
|||
K_SHIFTED:50009,
|
||||
K_ALTGR:50010,
|
||||
K_TABBACK:50011,
|
||||
K_TABFWD:50012*/
|
||||
K_TABFWD:50012
|
||||
};
|
||||
|
||||
const k = USVirtualKeyCodes;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import * as r from 'restructure';
|
||||
import { ModifierKeyConstants } from '../consts/modifier-key-constants.js';
|
||||
|
||||
/* Definitions from kmx_file.h. Must be kept in sync */
|
||||
|
||||
|
|
@ -343,25 +344,25 @@ export class KMXFile {
|
|||
public static readonly HK_CTRL = 0x00020000;
|
||||
public static readonly HK_SHIFT = 0x00040000;
|
||||
|
||||
public static readonly LCTRLFLAG = 0x0001; // Left Control flag
|
||||
public static readonly RCTRLFLAG = 0x0002; // Right Control flag
|
||||
public static readonly LALTFLAG = 0x0004; // Left Alt flag
|
||||
public static readonly RALTFLAG = 0x0008; // Right Alt flag
|
||||
public static readonly K_SHIFTFLAG = 0x0010; // Either shift flag
|
||||
public static readonly K_CTRLFLAG = 0x0020; // Either ctrl flag
|
||||
public static readonly K_ALTFLAG = 0x0040; // Either alt flag
|
||||
public static readonly LCTRLFLAG = ModifierKeyConstants.LCTRLFLAG; // Left Control flag
|
||||
public static readonly RCTRLFLAG = ModifierKeyConstants.RCTRLFLAG; // Right Control flag
|
||||
public static readonly LALTFLAG = ModifierKeyConstants.LALTFLAG; // Left Alt flag
|
||||
public static readonly RALTFLAG = ModifierKeyConstants.RALTFLAG; // Right Alt flag
|
||||
public static readonly K_SHIFTFLAG = ModifierKeyConstants.K_SHIFTFLAG; // Either shift flag
|
||||
public static readonly K_CTRLFLAG = ModifierKeyConstants.K_CTRLFLAG; // Either ctrl flag
|
||||
public static readonly K_ALTFLAG = ModifierKeyConstants.K_ALTFLAG; // Either alt flag
|
||||
//public static readonly K_METAFLAG = 0x0080; // Either Meta-key flag (tentative). Not usable in keyboard rules;
|
||||
// Used internally (currently, only by KMW) to ensure Meta-key
|
||||
// shortcuts safely bypass rules
|
||||
// Meta key = Command key on macOS, Windows key on Windows
|
||||
public static readonly CAPITALFLAG = 0x0100; // Caps lock on
|
||||
public static readonly NOTCAPITALFLAG = 0x0200; // Caps lock NOT on
|
||||
public static readonly NUMLOCKFLAG = 0x0400; // Num lock on
|
||||
public static readonly NOTNUMLOCKFLAG = 0x0800; // Num lock NOT on
|
||||
public static readonly SCROLLFLAG = 0x1000; // Scroll lock on
|
||||
public static readonly NOTSCROLLFLAG = 0x2000; // Scroll lock NOT on
|
||||
public static readonly ISVIRTUALKEY = 0x4000; // It is a Virtual Key Sequence
|
||||
public static readonly VIRTUALCHARKEY = 0x8000; // Keyman 6.0: Virtual Key Cap Sequence NOT YET
|
||||
public static readonly CAPITALFLAG = ModifierKeyConstants.CAPITALFLAG; // Caps lock on
|
||||
public static readonly NOTCAPITALFLAG = ModifierKeyConstants.NOTCAPITALFLAG; // Caps lock NOT on
|
||||
public static readonly NUMLOCKFLAG = ModifierKeyConstants.NUMLOCKFLAG; // Num lock on
|
||||
public static readonly NOTNUMLOCKFLAG = ModifierKeyConstants.NOTNUMLOCKFLAG; // Num lock NOT on
|
||||
public static readonly SCROLLFLAG = ModifierKeyConstants.SCROLLFLAG; // Scroll lock on
|
||||
public static readonly NOTSCROLLFLAG = ModifierKeyConstants.NOTSCROLLFLAG; // Scroll lock NOT on
|
||||
public static readonly ISVIRTUALKEY = ModifierKeyConstants.ISVIRTUALKEY; // It is a Virtual Key Sequence
|
||||
public static readonly VIRTUALCHARKEY = ModifierKeyConstants.VIRTUALCHARKEY; // Keyman 6.0: Virtual Key Cap Sequence NOT YET
|
||||
|
||||
// Note: OTHER_MODIFIER = 0x10000, used by KMX+ for the
|
||||
// other modifier flag in layers, > 16 bit so not available here.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ export { UnicodeSetParser, UnicodeSet } from './ldml-keyboard/unicodeset-parser-
|
|||
export { VariableParser, MarkerParser } from './ldml-keyboard/pattern-parser.js';
|
||||
export { LDMLKeyboardXMLSourceFileReader, LDMLKeyboardXMLSourceFileReaderOptions } from './ldml-keyboard/ldml-keyboard-xml-reader.js';
|
||||
|
||||
export { USVirtualKeyCodes } from './consts/virtual-key-constants.js';
|
||||
export * as Constants from './consts/virtual-key-constants.js';
|
||||
export { ModifierKeyConstants } from './consts/modifier-key-constants.js';
|
||||
|
||||
export { defaultCompilerOptions, CompilerBaseOptions, CompilerCallbacks, CompilerOptions, CompilerEvent, CompilerErrorNamespace,
|
||||
CompilerErrorSeverity, CompilerPathCallbacks, CompilerFileSystemCallbacks, CompilerCallbackOptions,
|
||||
|
|
@ -58,4 +60,4 @@ export * as KeymanFileTypes from './util/file-types.js';
|
|||
export * as Schemas from './schemas.js';
|
||||
export * as SchemaValidators from './schema-validators.js';
|
||||
|
||||
export * as xml2js from './deps/xml2js/xml2js.js';
|
||||
export * as xml2js from './deps/xml2js/xml2js.js';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
import {
|
||||
Codes,
|
||||
DefaultRules,
|
||||
|
|
@ -45,7 +46,7 @@ export default class DefaultBrowserRules extends DefaultRules {
|
|||
// This method will be handled between `ContextManager` and PageContextAttachment:
|
||||
// pageContextAttachment.findNeighboringInput(contextManager.activeTarget.getElement(), <same flag>)
|
||||
case Codes.keyCodes['K_TAB']:
|
||||
moveToNext((Lkc.Lmodifiers & Codes.modifierCodes['SHIFT']) != 0);
|
||||
moveToNext((Lkc.Lmodifiers & ModifierKeyConstants.K_SHIFTFLAG) != 0);
|
||||
break;
|
||||
case Codes.keyCodes['K_TABBACK']:
|
||||
moveToNext(true);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { Codes, DeviceSpec, KeyEvent, KeyMapping, Keyboard, KeyboardProcessor } from '@keymanapp/keyboard-processor';
|
||||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
|
||||
import { HardKeyboard, processForMnemonicsAndLegacy } from 'keyman/engine/main';
|
||||
import { DomEventTracker } from 'keyman/engine/events';
|
||||
|
|
@ -96,25 +97,24 @@ export function preprocessKeyboardEvent(e: KeyboardEvent, keyboardState: Keyboar
|
|||
|
||||
curModState |= (e.getModifierState("Shift") ? 0x10 : 0);
|
||||
|
||||
let modifierCodes = Codes.modifierCodes;
|
||||
if(e.getModifierState("Control")) {
|
||||
curModState |= ((e.location != 0 && ctrlEvent) ?
|
||||
(e.location == 1 ? modifierCodes['LCTRL'] : modifierCodes['RCTRL']) : // Condition 1
|
||||
(e.location == 1 ? ModifierKeyConstants.LCTRLFLAG : ModifierKeyConstants.RCTRLFLAG) : // Condition 1
|
||||
prevModState & 0x0003); // Condition 2
|
||||
}
|
||||
if(e.getModifierState("Alt")) {
|
||||
curModState |= ((e.location != 0 && altEvent) ?
|
||||
(e.location == 1 ? modifierCodes['LALT'] : modifierCodes['RALT']) : // Condition 1
|
||||
(e.location == 1 ? ModifierKeyConstants.LALTFLAG : ModifierKeyConstants.RALTFLAG) : // Condition 1
|
||||
prevModState & 0x000C); // Condition 2
|
||||
}
|
||||
|
||||
// Stage 2 - detect state key information. It can be looked up per keypress with no issue.
|
||||
let Lstates = 0;
|
||||
|
||||
Lstates |= e.getModifierState('CapsLock') ? modifierCodes['CAPS'] : modifierCodes['NO_CAPS'];
|
||||
Lstates |= e.getModifierState('NumLock') ? modifierCodes['NUM_LOCK'] : modifierCodes['NO_NUM_LOCK'];
|
||||
Lstates |= e.getModifierState('CapsLock') ? ModifierKeyConstants.CAPITALFLAG : ModifierKeyConstants.NOTCAPITALFLAG;
|
||||
Lstates |= e.getModifierState('NumLock') ? ModifierKeyConstants.NUMLOCKFLAG : ModifierKeyConstants.NOTNUMLOCKFLAG;
|
||||
Lstates |= (e.getModifierState('ScrollLock'))
|
||||
? modifierCodes['SCROLL_LOCK'] : modifierCodes['NO_SCROLL_LOCK'];
|
||||
? ModifierKeyConstants.SCROLLFLAG : ModifierKeyConstants.NOTSCROLLFLAG;
|
||||
|
||||
// We need these states to be tracked as well for proper OSK updates.
|
||||
curModState |= Lstates;
|
||||
|
|
@ -128,14 +128,14 @@ export function preprocessKeyboardEvent(e: KeyboardEvent, keyboardState: Keyboar
|
|||
keyboardState.modStateFlags = curModState;
|
||||
|
||||
// For European keyboards, not all browsers properly send both key-up events for the AltGr combo.
|
||||
let altGrMask = modifierCodes['RALT'] | modifierCodes['LCTRL'];
|
||||
let altGrMask = ModifierKeyConstants.RALTFLAG | ModifierKeyConstants.LCTRLFLAG;
|
||||
if((prevModState & altGrMask) == altGrMask && (curModState & altGrMask) != altGrMask) {
|
||||
// We just released AltGr - make sure it's all released.
|
||||
curModState &= ~ altGrMask;
|
||||
}
|
||||
// Perform basic filtering for Windows-based ALT_GR emulation on European keyboards.
|
||||
if(curModState & modifierCodes['RALT']) {
|
||||
curModState &= ~modifierCodes['LCTRL'];
|
||||
if(curModState & ModifierKeyConstants.RALTFLAG) {
|
||||
curModState &= ~ModifierKeyConstants.LCTRLFLAG;
|
||||
}
|
||||
|
||||
let modifierBitmasks = Codes.modifierBitmasks;
|
||||
|
|
@ -148,14 +148,14 @@ export function preprocessKeyboardEvent(e: KeyboardEvent, keyboardState: Keyboar
|
|||
// Note for future - embedding a kill switch here would facilitate disabling AltGr / Right-alt simulation.
|
||||
if(activeKeyboard.emulatesAltGr && (Lmodifiers & modifierBitmasks['ALT_GR_SIM']) == modifierBitmasks['ALT_GR_SIM']) {
|
||||
Lmodifiers ^= modifierBitmasks['ALT_GR_SIM'];
|
||||
Lmodifiers |= modifierCodes['RALT'];
|
||||
Lmodifiers |= ModifierKeyConstants.RALTFLAG;
|
||||
}
|
||||
} else {
|
||||
// No need to sim AltGr here; we don't need chiral ALTs.
|
||||
Lmodifiers =
|
||||
(curModState & 0x10) | // SHIFT
|
||||
((curModState & (modifierCodes['LCTRL'] | modifierCodes['RCTRL'])) ? 0x20 : 0) |
|
||||
((curModState & (modifierCodes['LALT'] | modifierCodes['RALT'])) ? 0x40 : 0);
|
||||
((curModState & (ModifierKeyConstants.LCTRLFLAG | ModifierKeyConstants.RCTRLFLAG)) ? 0x20 : 0) |
|
||||
((curModState & (ModifierKeyConstants.LALTFLAG | ModifierKeyConstants.RALTFLAG)) ? 0x40 : 0);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ export function preprocessKeyboardEvent(e: KeyboardEvent, keyboardState: Keyboar
|
|||
* because some keyboards specify their own modifierBitmask, which won't include it.
|
||||
* We don't currently use that reference in this method, but that may change in the future.
|
||||
*/
|
||||
Lmodifiers |= (e.metaKey ? modifierCodes['META']: 0);
|
||||
Lmodifiers |= (e.metaKey ? ModifierKeyConstants.K_METAFLAG: 0);
|
||||
|
||||
// Physically-typed keys require use of a 'desktop' form factor and thus are based on a virtual "physical" Device.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { EventEmitter } from "eventemitter3";
|
||||
import { Keyboard, KeyMapping, KeyEvent, type RuleBehavior, Codes } from "@keymanapp/keyboard-processor";
|
||||
import { KeyEventSourceInterface } from 'keyman/engine/events';
|
||||
import { ModifierKeyConstants } from '@keymanapp/common-types';
|
||||
|
||||
interface EventMap {
|
||||
/**
|
||||
|
|
@ -12,14 +13,12 @@ interface EventMap {
|
|||
export default class HardKeyboard extends EventEmitter<EventMap> implements KeyEventSourceInterface<EventMap> { }
|
||||
|
||||
export function processForMnemonicsAndLegacy(s: KeyEvent, activeKeyboard: Keyboard, baseLayout: string): KeyEvent {
|
||||
const modCodes = Codes.modifierCodes;
|
||||
|
||||
// Mnemonic handling.
|
||||
if(activeKeyboard && activeKeyboard.isMnemonic) {
|
||||
// The following will never set a code corresponding to a modifier key, so it's fine to do this,
|
||||
// which may change the value of Lcode, here.
|
||||
|
||||
s.setMnemonicCode(!!(s.Lmodifiers & modCodes.SHIFT), !!(s.Lmodifiers & modCodes.CAPS));
|
||||
s.setMnemonicCode(!!(s.Lmodifiers & ModifierKeyConstants.K_SHIFTFLAG), !!(s.Lmodifiers & ModifierKeyConstants.CAPITALFLAG));
|
||||
}
|
||||
|
||||
// Other minor physical-keyboard adjustments
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue