diff --git a/assets/default-keybindings.json b/assets/default-keybindings.json index fff2891d5..3597e2e43 100644 --- a/assets/default-keybindings.json +++ b/assets/default-keybindings.json @@ -87,39 +87,48 @@ }, { "command": "app:selectTab-1", - "keys": ["Cmd:1"] + "keys": ["Cmd:1"], + "commandStr":"/screen 1" }, { "command": "app:selectTab-2", - "keys": ["Cmd:2"] + "keys": ["Cmd:2"], + "commandStr":"/screen 2" }, { "command": "app:selectTab-3", - "keys": ["Cmd:3"] + "keys": ["Cmd:3"], + "commandStr":"/screen 3" }, { "command": "app:selectTab-4", - "keys": ["Cmd:4"] + "keys": ["Cmd:4"], + "commandStr":"/screen 4" }, { "command": "app:selectTab-5", - "keys": ["Cmd:5"] + "keys": ["Cmd:5"], + "commandStr":"/screen 5" }, { "command": "app:selectTab-6", - "keys": ["Cmd:6"] + "keys": ["Cmd:6"], + "commandStr":"/screen 6" }, { "command": "app:selectTab-7", - "keys": ["Cmd:7"] + "keys": ["Cmd:7"], + "commandStr":"/screen 7" }, { "command": "app:selectTab-8", - "keys": ["Cmd:8"] + "keys": ["Cmd:8"], + "commandStr":"/screen 8" }, { "command": "app:selectTab-9", - "keys": ["Cmd:9"] + "keys": ["Cmd:9"], + "commandStr":"/screen 9" }, { "command": "app:selectTabLeft", diff --git a/src/app/clientsettings/clientsettings.tsx b/src/app/clientsettings/clientsettings.tsx index 764bc993b..9572e7c9c 100644 --- a/src/app/clientsettings/clientsettings.tsx +++ b/src/app/clientsettings/clientsettings.tsx @@ -5,6 +5,7 @@ import * as React from "react"; import * as mobxReact from "mobx-react"; import * as mobx from "mobx"; import { boundMethod } from "autobind-decorator"; +import { If } from "tsx-control-statements/components"; import { GlobalModel, GlobalCommandRunner, RemotesModel, getApi } from "@/models"; import { Toggle, InlineSettingsTextEdit, SettingsError, Dropdown } from "@/common/elements"; import { commandRtnHandler, isBlank } from "@/util/util"; @@ -13,6 +14,25 @@ import * as appconst from "@/app/appconst"; import "./clientsettings.less"; import { MainView } from "../common/elements/mainview"; +class ClientSettingsKeybindings extends React.Component<{}, {}> { + componentDidMount() { + let clientSettingsViewModel = GlobalModel.clientSettingsViewModel; + let keybindManager = GlobalModel.keybindManager; + keybindManager.registerKeybinding("mainview", "clientsettings", "generic:cancel", (waveEvent) => { + clientSettingsViewModel.closeView(); + return true; + }); + } + + componentWillUnmount() { + GlobalModel.keybindManager.unregisterDomain("clientsettings"); + } + + render() { + return null; + } +} + @mobxReact.observer class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> { errorMessage: OV = mobx.observable.box(null, { name: "ClientSettings-errorMessage" }); @@ -168,6 +188,9 @@ class ClientSettingsView extends React.Component<{ model: RemotesModel }, { hove return ( + + +
Term Font Size
diff --git a/src/app/connections/connections.tsx b/src/app/connections/connections.tsx index f440fa6b3..0cdc45c8e 100644 --- a/src/app/connections/connections.tsx +++ b/src/app/connections/connections.tsx @@ -14,6 +14,25 @@ import * as util from "@/util/util"; import "./connections.less"; import { MainView } from "../common/elements/mainview"; +class ConnectionsKeybindings extends React.Component<{}, {}> { + componentDidMount() { + let connectionViewModel = GlobalModel.connectionViewModel; + let keybindManager = GlobalModel.keybindManager; + keybindManager.registerKeybinding("mainview", "connections", "generic:cancel", (waveEvent) => { + connectionViewModel.closeView(); + return true; + }); + } + + componentWillUnmount() { + GlobalModel.keybindManager.unregisterDomain("connections"); + } + + render() { + return null; + } +} + @mobxReact.observer class ConnectionsView extends React.Component<{ model: RemotesModel }, { hoveredItemId: string }> { tableRef: React.RefObject = React.createRef(); @@ -127,6 +146,9 @@ class ConnectionsView extends React.Component<{ model: RemotesModel }, { hovered return ( + + + { + @boundMethod + componentDidMount() { + let historyViewModel = GlobalModel.historyViewModel; + let keybindManager = GlobalModel.keybindManager; + keybindManager.registerKeybinding("mainview", "history", "generic:cancel", (waveEvent) => { + historyViewModel.handleUserClose(); + return true; + }); + } + + @boundMethod + componentWillUnmount() { + GlobalModel.keybindManager.unregisterDomain("history"); + } + + render() { + return null; + } +} + @mobxReact.observer class HistoryView extends React.Component<{}, {}> { tableRef: React.RefObject = React.createRef(); @@ -448,6 +469,9 @@ class HistoryView extends React.Component<{}, {}> { return ( + + +
{ GlobalCommandRunner.connectionsView(); } - @boundMethod - handleWebSharingClick(): void { - if (GlobalModel.activeMainView.get() == "webshare") { - GlobalModel.showSessionView(); - return; - } - GlobalModel.showWebShareView(); - } - @boundMethod handleSettingsClick(): void { if (GlobalModel.activeMainView.get() == "clientsettings") { diff --git a/src/app/workspace/workspaceview.tsx b/src/app/workspace/workspaceview.tsx index 717a91b5d..c73b8eea9 100644 --- a/src/app/workspace/workspaceview.tsx +++ b/src/app/workspace/workspaceview.tsx @@ -7,6 +7,7 @@ import * as mobx from "mobx"; import cn from "classnames"; import dayjs from "dayjs"; import localizedFormat from "dayjs/plugin/localizedFormat"; +import { If } from "tsx-control-statements/components"; import { GlobalModel } from "@/models"; import { CmdInput } from "./cmdinput/cmdinput"; import { ScreenView } from "./screen/screenview"; @@ -17,6 +18,66 @@ import "./workspace.less"; dayjs.extend(localizedFormat); +class SessionKeybindings extends React.Component<{}, {}> { + componentDidMount() { + let keybindManager = GlobalModel.keybindManager; + keybindManager.registerKeybinding("mainview", "session", "app:toggleSidebar", (waveEvent) => { + GlobalModel.handleToggleSidebar(); + return true; + }); + keybindManager.registerKeybinding("mainview", "session", "app:newTab", (waveEvent) => { + GlobalModel.onNewTab(); + return true; + }); + keybindManager.registerKeybinding("mainview", "session", "app:closeCurrentTab", (waveEvent) => { + GlobalModel.onCloseCurrentTab(); + return true; + }); + for (let index = 1; index <= 9; index++) { + keybindManager.registerKeybinding("mainview", "session", "app:selectTab-" + index, null); + } + keybindManager.registerKeybinding("mainview", "session", "app:selectTabLeft", (waveEvent) => { + GlobalModel.onBracketCmd(-1); + return true; + }); + keybindManager.registerKeybinding("mainview", "session", "app:selectTabRight", (waveEvent) => { + GlobalModel.onBracketCmd(1); + return true; + }); + keybindManager.registerKeybinding("pane", "session", "app:selectLineAbove", (waveEvent) => { + GlobalModel.onMetaArrowUp(); + return true; + }); + keybindManager.registerKeybinding("pane", "session", "app:selectLineBelow", (waveEvent) => { + GlobalModel.onMetaArrowDown(); + return true; + }); + keybindManager.registerKeybinding("pane", "session", "app:restartCommand", (waveEvent) => { + GlobalModel.onRestartCommand(); + return true; + }); + keybindManager.registerKeybinding("pane", "session", "app:restartLastCommand", (waveEvent) => { + GlobalModel.onRestartLastCommand(); + return true; + }); + keybindManager.registerKeybinding("pane", "session", "app:focusSelectedLine", (waveEvent) => { + GlobalModel.onFocusSelectedLine(); + return true; + }); + keybindManager.registerKeybinding("pane", "session", "app:deleteActiveLine", (waveEvent) => { + return GlobalModel.handleDeleteActiveLine(); + }); + } + + componentWillUnmount() { + GlobalModel.keybindManager.unregisterDomain("session"); + } + + render() { + return null; + } +} + @mobxReact.observer class WorkspaceView extends React.Component<{}, {}> { render() { @@ -47,6 +108,9 @@ class WorkspaceView extends React.Component<{}, {}> { width: `${window.innerWidth - mainSidebarModel.getWidth()}px`, }} > + + + diff --git a/src/electron/emain.ts b/src/electron/emain.ts index 2b6114775..3e46f3696 100644 --- a/src/electron/emain.ts +++ b/src/electron/emain.ts @@ -359,59 +359,6 @@ function createMainWindow(clientData: ClientDataType | null): Electron.BrowserWi if (input.type != "keyDown") { return; } - const mods = getMods(input); - if (checkKeyPressed(waveEvent, "Cmd:t")) { - win.webContents.send("t-cmd", mods); - e.preventDefault(); - return; - } - if (checkKeyPressed(waveEvent, "Cmd:r")) { - e.preventDefault(); - win.webContents.send("r-cmd", mods); - return; - } - if (checkKeyPressed(waveEvent, "Cmd:l")) { - win.webContents.send("l-cmd", mods); - e.preventDefault(); - return; - } - if (checkKeyPressed(waveEvent, "Cmd:w")) { - e.preventDefault(); - win.webContents.send("w-cmd", mods); - return; - } - if (checkKeyPressed(waveEvent, "Cmd:ArrowUp") || checkKeyPressed(waveEvent, "Cmd:ArrowDown")) { - if (checkKeyPressed(waveEvent, "Cmd:ArrowUp")) { - win.webContents.send("meta-arrowup"); - } else { - win.webContents.send("meta-arrowdown"); - } - e.preventDefault(); - return; - } - if (checkKeyPressed(waveEvent, "Cmd:PageUp") || checkKeyPressed(waveEvent, "Cmd:PageDown")) { - if (checkKeyPressed(waveEvent, "Cmd:PageUp")) { - win.webContents.send("meta-pageup"); - } else { - win.webContents.send("meta-pagedown"); - } - e.preventDefault(); - return; - } - if (input.code.startsWith("Digit") && input.meta && !input.control) { - const digitNum = parseInt(input.code.substring(5)); - if (isNaN(digitNum) || digitNum < 1 || digitNum > 9) { - return; - } - e.preventDefault(); - win.webContents.send("digit-cmd", { digit: digitNum }, mods); - } - if (checkKeyPressed(waveEvent, "Cmd:[") || checkKeyPressed(waveEvent, "Cmd:]")) { - const rel = checkKeyPressed(waveEvent, "Cmd:]") ? 1 : -1; - win.webContents.send("bracket-cmd", { relative: rel }, mods); - e.preventDefault(); - return; - } }); win.webContents.on("will-navigate", shNavHandler); win.webContents.on("will-frame-navigate", shFrameNavHandler); diff --git a/src/electron/preload.js b/src/electron/preload.js index 1b5f1a637..2ef26f7d4 100644 --- a/src/electron/preload.js +++ b/src/electron/preload.js @@ -21,17 +21,7 @@ contextBridge.exposeInMainWorld("api", { installAppUpdate: () => ipcRenderer.send("install-app-update"), getAppUpdateStatus: () => ipcRenderer.sendSync("get-app-update-status"), onAppUpdateStatus: (callback) => ipcRenderer.on("app-update-status", (_, val) => callback(val)), - onTCmd: (callback) => ipcRenderer.on("t-cmd", callback), - onLCmd: (callback) => ipcRenderer.on("l-cmd", callback), - onWCmd: (callback) => ipcRenderer.on("w-cmd", callback), - onRCmd: (callback) => ipcRenderer.on("r-cmd", callback), onZoomChanged: (callback) => ipcRenderer.on("zoom-changed", callback), - onMetaArrowUp: (callback) => ipcRenderer.on("meta-arrowup", callback), - onMetaArrowDown: (callback) => ipcRenderer.on("meta-arrowdown", callback), - onMetaPageUp: (callback) => ipcRenderer.on("meta-pageup", callback), - onMetaPageDown: (callback) => ipcRenderer.on("meta-pagedown", callback), - onBracketCmd: (callback) => ipcRenderer.on("bracket-cmd", callback), - onDigitCmd: (callback) => ipcRenderer.on("digit-cmd", callback), onMenuItemAbout: (callback) => ipcRenderer.on("menu-item-about", callback), contextScreen: (screenOpts, position) => ipcRenderer.send("context-screen", screenOpts, position), contextEditMenu: (position, opts) => ipcRenderer.send("context-editmenu", position, opts), diff --git a/src/models/clientsettingsview.ts b/src/models/clientsettingsview.ts index e74a02a53..7c8c2f1f0 100644 --- a/src/models/clientsettingsview.ts +++ b/src/models/clientsettingsview.ts @@ -22,15 +22,6 @@ class ClientSettingsViewModel { this.globalModel.activeMainView.set("clientsettings"); })(); } - - handleDocKeyDown(e: any): void { - const waveEvent = adaptFromReactOrNativeKeyEvent(e); - if (checkKeyPressed(waveEvent, "Escape")) { - e.preventDefault(); - this.closeView(); - return; - } - } } export { ClientSettingsViewModel }; diff --git a/src/models/connectionsview.ts b/src/models/connectionsview.ts index 297beda1c..b5fef5637 100644 --- a/src/models/connectionsview.ts +++ b/src/models/connectionsview.ts @@ -22,15 +22,6 @@ class ConnectionsViewModel { this.globalModel.activeMainView.set("connections"); })(); } - - handleDocKeyDown(e: any): void { - const waveEvent = adaptFromReactOrNativeKeyEvent(e); - if (checkKeyPressed(waveEvent, "Escape")) { - e.preventDefault(); - this.closeView(); - return; - } - } } export { ConnectionsViewModel }; diff --git a/src/models/historyview.ts b/src/models/historyview.ts index 63b934d20..192b97d09 100644 --- a/src/models/historyview.ts +++ b/src/models/historyview.ts @@ -290,13 +290,8 @@ class HistoryViewModel { GlobalCommandRunner.historyView(this._getSearchParams(0, 0)); } - handleDocKeyDown(e: any): void { - const waveEvent = adaptFromReactOrNativeKeyEvent(e); - if (checkKeyPressed(waveEvent, "Escape")) { - e.preventDefault(); - this.closeView(); - return; - } + handleUserClose() { + this.closeView(); } showHistoryView(data: HistoryViewDataType): void { diff --git a/src/models/model.ts b/src/models/model.ts index 04d7a29f6..eeed5fded 100644 --- a/src/models/model.ts +++ b/src/models/model.ts @@ -177,18 +177,8 @@ class Model { } return fontSize; }); - getApi().onTCmd(this.onTCmd.bind(this)); - getApi().onLCmd(this.onLCmd.bind(this)); - getApi().onWCmd(this.onWCmd.bind(this)); - getApi().onRCmd(this.onRCmd.bind(this)); getApi().onZoomChanged(this.onZoomChanged.bind(this)); getApi().onMenuItemAbout(this.onMenuItemAbout.bind(this)); - getApi().onMetaArrowUp(this.onMetaArrowUp.bind(this)); - getApi().onMetaArrowDown(this.onMetaArrowDown.bind(this)); - getApi().onMetaPageUp(this.onMetaPageUp.bind(this)); - getApi().onMetaPageDown(this.onMetaPageDown.bind(this)); - getApi().onBracketCmd(this.onBracketCmd.bind(this)); - getApi().onDigitCmd(this.onDigitCmd.bind(this)); getApi().onWaveSrvStatusChange(this.onWaveSrvStatusChange.bind(this)); getApi().onAppUpdateStatus(this.onAppUpdateStatus.bind(this)); document.addEventListener("keydown", this.docKeyDownHandler.bind(this)); @@ -383,12 +373,6 @@ class Model { })(); } - showWebShareView(): void { - mobx.action(() => { - this.activeMainView.set("webshare"); - })(); - } - getBaseHostPort(): string { if (this.isDev) { return appconst.DevServerEndpoint; @@ -471,6 +455,22 @@ class Model { // nothing for now } + handleToggleSidebar() { + const activeScreen = this.getActiveScreen(); + if (activeScreen != null) { + const isSidebarOpen = activeScreen.isSidebarOpen(); + if (isSidebarOpen) { + GlobalCommandRunner.screenSidebarClose(); + } else { + GlobalCommandRunner.screenSidebarOpen(); + } + } + } + + handleDeleteActiveLine(): boolean { + return this.deleteActiveLine(); + } + docKeyDownHandler(e: KeyboardEvent) { const waveEvent = adaptFromReactOrNativeKeyEvent(e); if (isModKeyPress(e)) { @@ -493,47 +493,8 @@ class Model { this.modalsModel.popModal(); return; } - this.keybindManager.processKeyEvent(e, waveEvent); - if (this.activeMainView.get() == "history") { - this.historyViewModel.handleDocKeyDown(e); - } - if (this.activeMainView.get() == "connections") { - this.connectionViewModel.handleDocKeyDown(e); - } - if (this.activeMainView.get() == "clientsettings") { - this.clientSettingsViewModel.handleDocKeyDown(e); - } else { - if (checkKeyPressed(waveEvent, "Escape")) { - e.preventDefault(); - if (this.activeMainView.get() == "webshare") { - this.showSessionView(); - return; - } - const inputModel = this.inputModel; - inputModel.toggleInfoMsg(); - if (inputModel.inputMode.get() != null) { - inputModel.resetInputMode(); - } - return; - } - if (this.activeMainView.get() == "session" && checkKeyPressed(waveEvent, "Cmd:Ctrl:s")) { - e.preventDefault(); - const activeScreen = this.getActiveScreen(); - if (activeScreen != null) { - const isSidebarOpen = activeScreen.isSidebarOpen(); - if (isSidebarOpen) { - GlobalCommandRunner.screenSidebarClose(); - } else { - GlobalCommandRunner.screenSidebarOpen(); - } - } - } - if (checkKeyPressed(waveEvent, "Cmd:d")) { - const ranDelete = this.deleteActiveLine(); - if (ranDelete) { - e.preventDefault(); - } - } + if (this.keybindManager.processKeyEvent(e, waveEvent)) { + return; } } @@ -562,7 +523,7 @@ class Model { return true; } - onWCmd(e: any, mods: KeyModsType) { + onCloseCurrentTab() { if (this.activeMainView.get() != "session") { return; } @@ -582,7 +543,7 @@ class Model { }); } - onRCmd(e: any, mods: KeyModsType) { + onRestartLastCommand() { if (this.activeMainView.get() != "session") { return; } @@ -590,17 +551,22 @@ class Model { if (activeScreen == null) { return; } - if (mods.shift) { - // restart last line - GlobalCommandRunner.lineRestart("E", true); - } else { - // restart selected line - const selectedLine = activeScreen.selectedLine.get(); - if (selectedLine == null || selectedLine == 0) { - return; - } - GlobalCommandRunner.lineRestart(String(selectedLine), true); + GlobalCommandRunner.lineRestart("E", true); + } + + onRestartCommand() { + if (this.activeMainView.get() != "session") { + return; } + const activeScreen = this.getActiveScreen(); + if (activeScreen == null) { + return; + } + const selectedLine = activeScreen.selectedLine.get(); + if (selectedLine == null || selectedLine == 0) { + return; + } + GlobalCommandRunner.lineRestart(String(selectedLine), true); } onZoomChanged(): void { @@ -700,7 +666,7 @@ class Model { return rtn; } - onTCmd(e: any, mods: KeyModsType) { + onNewTab() { GlobalCommandRunner.createNewScreen(); } @@ -722,7 +688,7 @@ class Model { } } - onLCmd(e: any, mods: KeyModsType) { + onFocusSelectedLine() { const screen = this.getActiveScreen(); if (screen != null) { GlobalCommandRunner.screenSetFocus("cmd"); @@ -787,26 +753,19 @@ class Model { })(); } - onMetaPageUp(): void { - GlobalCommandRunner.screenSelectLine("-1"); - } - - onMetaPageDown(): void { - GlobalCommandRunner.screenSelectLine("+1"); - } - onMetaArrowUp(): void { GlobalCommandRunner.screenSelectLine("-1"); } onMetaArrowDown(): void { + console.log("meta arrow down?"); GlobalCommandRunner.screenSelectLine("+1"); } - onBracketCmd(e: any, arg: { relative: number }, mods: KeyModsType) { - if (arg.relative == 1) { + onBracketCmd(relative: number) { + if (relative == 1) { GlobalCommandRunner.switchScreen("+"); - } else if (arg.relative == -1) { + } else if (relative == -1) { GlobalCommandRunner.switchScreen("-"); } } @@ -1373,7 +1332,7 @@ class Model { type: "fecmd", metacmd: "eval", args: [cmdStr], - kwargs: null, + kwargs: {}, uicontext: this.getUIContext(), interactive: interactive, rawstr: cmdStr, diff --git a/src/types/custom.d.ts b/src/types/custom.d.ts index 9d3383af9..2cf2d9634 100644 --- a/src/types/custom.d.ts +++ b/src/types/custom.d.ts @@ -901,18 +901,8 @@ declare global { installAppUpdate: () => void; getAppUpdateStatus: () => AppUpdateStatusType; onAppUpdateStatus: (callback: (status: AppUpdateStatusType) => void) => void; - onTCmd: (callback: (mods: KeyModsType) => void) => void; - onLCmd: (callback: (mods: KeyModsType) => void) => void; - onRCmd: (callback: (mods: KeyModsType) => void) => void; - onWCmd: (callback: (mods: KeyModsType) => void) => void; onZoomChanged: (callback: () => void) => void; onMenuItemAbout: (callback: () => void) => void; - onMetaArrowUp: (callback: () => void) => void; - onMetaArrowDown: (callback: () => void) => void; - onMetaPageUp: (callback: () => void) => void; - onMetaPageDown: (callback: () => void) => void; - onBracketCmd: (callback: (event: any, arg: { relative: number }, mods: KeyModsType) => void) => void; - onDigitCmd: (callback: (event: any, arg: { digit: number }, mods: KeyModsType) => void) => void; contextScreen: (screenOpts: { screenId: string }, position: { x: number; y: number }) => void; contextEditMenu: (position: { x: number; y: number }, opts: ContextMenuOpts) => void; onWaveSrvStatusChange: (callback: (status: boolean, pid: number) => void) => void; diff --git a/src/util/keyutil.ts b/src/util/keyutil.ts index f4c50cc4f..e934ace24 100644 --- a/src/util/keyutil.ts +++ b/src/util/keyutil.ts @@ -129,7 +129,6 @@ class KeybindManager { return true; } let curCommand = commandsList.shift(); - console.log("running: ", curCommand); let prtn = this.globalModel.submitRawCommand(curCommand, false, false); prtn.then((rtn) => { if (!rtn.success) { @@ -174,18 +173,17 @@ class KeybindManager { return false; } - processKeyEvent(nativeEvent: any, event: WaveKeyboardEvent) { + processKeyEvent(nativeEvent: any, event: WaveKeyboardEvent): boolean { let modalLevel = this.levelMap.get("modal"); if (modalLevel.length != 0) { // console.log("processing modal"); // special case when modal keybindings are present let shouldReturn = this.processLevel(nativeEvent, event, modalLevel); if (shouldReturn) { - return; + return true; } let systemLevel = this.levelMap.get("system"); - this.processLevel(nativeEvent, event, systemLevel); - return; + return this.processLevel(nativeEvent, event, systemLevel); } for (let index = this.levelArray.length - 1; index >= 0; index--) { let curLevel = this.levelArray[index]; @@ -198,9 +196,10 @@ class KeybindManager { } let shouldReturn = this.processLevel(nativeEvent, event, curKeybindsArray); if (shouldReturn) { - return; + return true; } } + return false; } keybindingAlreadyAdded(level: string, domain: string, keybinding: string) { @@ -358,6 +357,7 @@ function parseKeyDescription(keyDescription: string): KeyPressDecl { for (let key of keys) { if (key == "Cmd") { rtn.mods.Cmd = true; + rtn.mods.Meta = true; } else if (key == "Shift") { rtn.mods.Shift = true; } else if (key == "Ctrl") { @@ -398,24 +398,31 @@ function parseKey(key: string): { key: string; type: string } { return { key: key, type: KeyTypeKey }; } +function notMod(keyPressMod, eventMod) { + if (keyPressMod != true) { + keyPressMod = false; + } + return (keyPressMod && !eventMod) || (eventMod && !keyPressMod); +} + function checkKeyPressed(event: WaveKeyboardEvent, keyDescription: string): boolean { let keyPress = parseKeyDescription(keyDescription); - if (keyPress.mods.Option && !event.option) { + if (notMod(keyPress.mods.Option, event.option)) { return false; } - if (keyPress.mods.Cmd && !event.cmd) { + if (notMod(keyPress.mods.Cmd, event.cmd)) { return false; } - if (keyPress.mods.Shift && !event.shift) { + if (notMod(keyPress.mods.Shift, event.shift)) { return false; } - if (keyPress.mods.Ctrl && !event.control) { + if (notMod(keyPress.mods.Ctrl, event.control)) { return false; } - if (keyPress.mods.Alt && !event.alt) { + if (notMod(keyPress.mods.Alt, event.alt)) { return false; } - if (keyPress.mods.Meta && !event.meta) { + if (notMod(keyPress.mods.Meta, event.meta)) { return false; } let eventKey = "";