From e8fe0f8d3ee21d0a5a531a8f9800ab01d0e3b579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Monda?= Date: Sun, 11 Mar 2018 22:56:12 +0100 Subject: [PATCH] Fix menu scancode. (#586) * Fix menu scancode. * Change the old menu key scancode 118 to 101. * validate scancodes --- package-lock.json | 192 ++++++++++++++++++ package.json | 1 + packages/uhk-common/package.json | 5 +- .../config-serializer/config-items/index.ts | 3 + .../config-items/key-action/helper.ts | 24 ++- .../config-items/scancode-checker.ts | 26 +++ .../config-items}/scancodes.json | 2 +- .../config-items}/secondaryRole.json | 0 .../tab/keypress/keypress-tab.component.ts | 6 +- .../src/app/services/capture.service.ts | 2 +- .../src/app/services/mapper.service.ts | 4 +- .../uhk-web/src/app/services/user-config.json | 14 +- 12 files changed, 261 insertions(+), 18 deletions(-) create mode 100644 packages/uhk-common/src/config-serializer/config-items/scancode-checker.ts rename packages/{uhk-web/src/app/components/popover/tab/keypress => uhk-common/src/config-serializer/config-items}/scancodes.json (99%) rename packages/{uhk-web/src/app/components/popover/tab/keypress => uhk-common/src/config-serializer/config-items}/secondaryRole.json (100%) diff --git a/package-lock.json b/package-lock.json index 035402cf..6b215830 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2301,6 +2301,174 @@ } } }, + "copyfiles": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.0.0.tgz", + "integrity": "sha512-NSSJdwCH27/hEiBlhkXYWh3AaPo8IATxLX5XtJQgknOvOehrREtETsGd/BNr2vuj0URgKBC/50PNRM3yShQGJQ==", + "dev": true, + "requires": { + "glob": "7.1.2", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "noms": "0.0.0", + "through2": "2.0.3", + "yargs": "11.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "cliui": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", + "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", + "dev": true, + "requires": { + "string-width": "2.1.1", + "strip-ansi": "4.0.0", + "wrap-ansi": "2.1.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "2.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", + "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "5.1.1" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "3.0.0" + } + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "2.3.5", + "xtend": "4.0.1" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yargs": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "dev": true, + "requires": { + "cliui": "4.0.0", + "decamelize": "1.2.0", + "find-up": "2.1.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "dev": true, + "requires": { + "camelcase": "4.1.0" + } + } + } + }, "core-js": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", @@ -7755,6 +7923,30 @@ } } }, + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "readable-stream": "1.0.34" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + } + } + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", diff --git a/package.json b/package.json index 0c4042e2..4d7deb27 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@types/usb": "1.1.3", "autoprefixer": "6.5.3", "buffer": "5.0.6", + "copyfiles": "^2.0.0", "copy-webpack-plugin": "4.0.1", "core-js": "2.4.1", "cross-env": "5.0.5", diff --git a/packages/uhk-common/package.json b/packages/uhk-common/package.json index 871786bc..98d47cdb 100644 --- a/packages/uhk-common/package.json +++ b/packages/uhk-common/package.json @@ -10,7 +10,10 @@ "url": "git@github.com:UltimateHackingKeyboard/agent.git" }, "scripts": { - "build": "tsc", + "build": "run-s tsc copy:*", + "tsc": "tsc", + "copy:scancodes": "copyfiles ./src/config-serializer/config-items/scancodes.json dist", + "copy:secondary-roles": "copyfiles ./src/config-serializer/config-items/secondaryRole.json dist", "test": "jasmine-ts --config=jasmine.json", "coverage": "nyc jasmine-ts --config=jasmine.json" }, diff --git a/packages/uhk-common/src/config-serializer/config-items/index.ts b/packages/uhk-common/src/config-serializer/config-items/index.ts index 009ed593..62e04aed 100644 --- a/packages/uhk-common/src/config-serializer/config-items/index.ts +++ b/packages/uhk-common/src/config-serializer/config-items/index.ts @@ -9,3 +9,6 @@ export * from './macro'; export * from './module'; export * from './module-configuration'; export * from './user-configuration'; + +export const SCANCODES = require('./scancodes.json'); +export const SECONDARY_ROLES = require('./secondaryRole.json'); diff --git a/packages/uhk-common/src/config-serializer/config-items/key-action/helper.ts b/packages/uhk-common/src/config-serializer/config-items/key-action/helper.ts index 4469e489..cea65712 100644 --- a/packages/uhk-common/src/config-serializer/config-items/key-action/helper.ts +++ b/packages/uhk-common/src/config-serializer/config-items/key-action/helper.ts @@ -8,6 +8,7 @@ import { SwitchKeymapAction, UnresolvedSwitchKeymapAction } from './switch-keyma import { MouseAction } from './mouse-action'; import { PlayMacroAction } from './play-macro-action'; import { NoneAction } from './none-action'; +import { isScancodeExists } from '../scancode-checker'; export class Helper { @@ -26,7 +27,12 @@ export class Helper { buffer.backtrack(); if (keyActionFirstByte >= KeyActionId.KeystrokeAction && keyActionFirstByte < KeyActionId.LastKeystrokeAction) { - return new KeystrokeAction().fromBinary(buffer); + const keystrokeAction = new KeystrokeAction().fromBinary(buffer); + if (isValidKeystrokeAction(keystrokeAction)) { + return keystrokeAction; + } + + return new NoneAction(); } switch (keyActionFirstByte) { @@ -68,8 +74,14 @@ export class Helper { } switch (keyAction.keyActionType) { - case keyActionType.KeystrokeAction: - return new KeystrokeAction().fromJsonObject(keyAction); + case keyActionType.KeystrokeAction: { + const keystrokeAction = new KeystrokeAction().fromJsonObject(keyAction); + if (isValidKeystrokeAction(keystrokeAction)) { + return keystrokeAction; + } + + return new NoneAction(); + } case keyActionType.SwitchLayerAction: return new SwitchLayerAction().fromJsonObject(keyAction); case keyActionType.SwitchKeymapAction: @@ -85,3 +97,9 @@ export class Helper { } } } + +function isValidKeystrokeAction(keystrokeAction: KeystrokeAction): boolean { + return keystrokeAction.hasSecondaryRoleAction() || + keystrokeAction.hasActiveModifier() || + keystrokeAction.hasScancode() && isScancodeExists(keystrokeAction.scancode); +} diff --git a/packages/uhk-common/src/config-serializer/config-items/scancode-checker.ts b/packages/uhk-common/src/config-serializer/config-items/scancode-checker.ts new file mode 100644 index 00000000..15929298 --- /dev/null +++ b/packages/uhk-common/src/config-serializer/config-items/scancode-checker.ts @@ -0,0 +1,26 @@ +import { SCANCODES } from './'; + +let scancodeMap: Map; + +export function isScancodeExists(scancode: number): boolean { + if (!scancodeMap) { + fillScancodeMap(); + } + + return scancodeMap.has(scancode); +} + +function fillScancodeMap(): void { + scancodeMap = new Map(); + + for (const scanGroup of SCANCODES) { + for (const child of scanGroup.children) { + if (child.additional && child.additional.scancode) { + scancodeMap.set(child.additional.scancode, child); + } + else { + scancodeMap.set(Number.parseInt(child.id), child); + } + } + } +} diff --git a/packages/uhk-web/src/app/components/popover/tab/keypress/scancodes.json b/packages/uhk-common/src/config-serializer/config-items/scancodes.json similarity index 99% rename from packages/uhk-web/src/app/components/popover/tab/keypress/scancodes.json rename to packages/uhk-common/src/config-serializer/config-items/scancodes.json index b67fc2a5..84148b79 100644 --- a/packages/uhk-web/src/app/components/popover/tab/keypress/scancodes.json +++ b/packages/uhk-common/src/config-serializer/config-items/scancodes.json @@ -242,7 +242,7 @@ "text": "Delete" }, { - "id": "118", + "id": "101", "text": "Menu" }, { diff --git a/packages/uhk-web/src/app/components/popover/tab/keypress/secondaryRole.json b/packages/uhk-common/src/config-serializer/config-items/secondaryRole.json similarity index 100% rename from packages/uhk-web/src/app/components/popover/tab/keypress/secondaryRole.json rename to packages/uhk-common/src/config-serializer/config-items/secondaryRole.json diff --git a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts index 17dabf73..2b1eb8ea 100644 --- a/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts +++ b/packages/uhk-web/src/app/components/popover/tab/keypress/keypress-tab.component.ts @@ -1,6 +1,6 @@ import { Component, Input, OnChanges } from '@angular/core'; import { Select2OptionData, Select2TemplateFunction } from 'ng2-select2'; -import { KeyAction, KeystrokeAction, KeystrokeType } from 'uhk-common'; +import { KeyAction, KeystrokeAction, KeystrokeType, SCANCODES, SECONDARY_ROLES } from 'uhk-common'; import { Tab } from '../tab'; import { MapperService } from '../../../../services/mapper.service'; @@ -35,8 +35,8 @@ export class KeypressTabComponent extends Tab implements OnChanges { id: '0', text: 'None' }]; - this.scanCodeGroups = this.scanCodeGroups.concat(require('./scancodes.json')); - this.secondaryRoleGroups = require('./secondaryRole.json'); + this.scanCodeGroups = this.scanCodeGroups.concat(SCANCODES); + this.secondaryRoleGroups = SECONDARY_ROLES; this.leftModifierSelects = Array(this.leftModifiers.length).fill(false); this.rightModifierSelects = Array(this.rightModifiers.length).fill(false); this.selectedScancodeOption = this.scanCodeGroups[0]; diff --git a/packages/uhk-web/src/app/services/capture.service.ts b/packages/uhk-web/src/app/services/capture.service.ts index ff141905..1362820c 100644 --- a/packages/uhk-web/src/app/services/capture.service.ts +++ b/packages/uhk-web/src/app/services/capture.service.ts @@ -94,7 +94,7 @@ export class CaptureService { this.mapping.set(88, 27); // X this.mapping.set(89, 28); // Y this.mapping.set(90, 29); // Z - this.mapping.set(93, 118); // Menu + this.mapping.set(93, 101); // Menu this.mapping.set(96, 98); // Num pad 0 this.mapping.set(97, 89); // Num pad 1 this.mapping.set(98, 90); // Num pad 2 diff --git a/packages/uhk-web/src/app/services/mapper.service.ts b/packages/uhk-web/src/app/services/mapper.service.ts index f0eb0d19..a93882f5 100644 --- a/packages/uhk-web/src/app/services/mapper.service.ts +++ b/packages/uhk-web/src/app/services/mapper.service.ts @@ -190,6 +190,7 @@ export class MapperService { this.basicScanCodeTextMap.set(98, ['Insert', '0']); this.basicScanCodeTextMap.set(99, ['Del', '.']); this.basicScanCodeTextMap.set(100, ['ISO key', '|']); + this.basicScanCodeTextMap.set(101, ['Menu']); this.basicScanCodeTextMap.set(104, ['F13']); this.basicScanCodeTextMap.set(105, ['F14']); this.basicScanCodeTextMap.set(106, ['F15']); @@ -202,7 +203,6 @@ export class MapperService { this.basicScanCodeTextMap.set(113, ['F22']); this.basicScanCodeTextMap.set(114, ['F23']); this.basicScanCodeTextMap.set(115, ['F24']); - this.basicScanCodeTextMap.set(118, ['Menu']); this.basicScanCodeTextMap.set(176, ['00']); this.basicScanCodeTextMap.set(177, ['000']); @@ -236,7 +236,7 @@ export class MapperService { this.basicScancodeIcons.set(80, 'icon-kbd__mod--arrow-left'); this.basicScancodeIcons.set(81, 'icon-kbd__mod--arrow-down'); this.basicScancodeIcons.set(82, 'icon-kbd__mod--arrow-up'); - this.basicScancodeIcons.set(118, 'icon-kbd__mod--menu'); + this.basicScancodeIcons.set(101, 'icon-kbd__mod--menu'); this.mediaScancodeIcons = new Map(); this.mediaScancodeIcons.set(138, 'icon-kbd__fn--browser'); diff --git a/packages/uhk-web/src/app/services/user-config.json b/packages/uhk-web/src/app/services/user-config.json index 67abb069..886ce6c6 100644 --- a/packages/uhk-web/src/app/services/user-config.json +++ b/packages/uhk-web/src/app/services/user-config.json @@ -495,7 +495,7 @@ { "keyActionType": "keystroke", "type": "basic", - "scancode": 118 + "scancode": 101 }, { "keyActionType": "keystroke", @@ -1501,7 +1501,7 @@ { "keyActionType": "keystroke", "type": "basic", - "scancode": 118 + "scancode": 101 }, { "keyActionType": "keystroke", @@ -2517,7 +2517,7 @@ { "keyActionType": "keystroke", "type": "basic", - "scancode": 118 + "scancode": 101 }, { "keyActionType": "keystroke", @@ -3520,7 +3520,7 @@ { "keyActionType": "keystroke", "type": "basic", - "scancode": 118 + "scancode": 101 }, { "keyActionType": "keystroke", @@ -4533,7 +4533,7 @@ { "keyActionType": "keystroke", "type": "basic", - "scancode": 118 + "scancode": 101 }, { "keyActionType": "keystroke", @@ -5534,7 +5534,7 @@ { "keyActionType": "keystroke", "type": "basic", - "scancode": 118 + "scancode": 101 }, { "keyActionType": "keystroke", @@ -6547,7 +6547,7 @@ { "keyActionType": "keystroke", "type": "basic", - "scancode": 118 + "scancode": 101 }, { "keyActionType": "keystroke",