While most of our desktop software is operated with the mouse, some software provides menus and keyboard shortcuts, which are more common on MAC systems. If there is a corresponding shortcut key operation or menu when using the software, it will make the user’s use experience more smooth and convenient. This chapter mainly describes several ways of registering shortcut keys and the differentiated treatment of the menu system.
The Menu Menu
Menu this thing, generally seen in MAC system, win is relatively rare in China, it is a convention. In fact, the shortcut and menu aspects can be said to be one, we can register the corresponding keyboard key on the menu, so the MAC system can use this way to handle the shortcut together. Advantages: the most concise shortcut key processing, simple and convenient. Cons: Can only be triggered when the application is focused (focus on the application, not just the display). Since Win does not use menus in general, it can only be used on the MAC.
import { app, dialog, Menu } from 'electron' import config from './index' import global from './global' const os = require('os') const isMac = Process. platform === 'Darwin' const menuConfig = [{label: app.name, submenu: [{label: 'about ', accelerator: 'Alt+Cmd+I' : 'Alt+Shift+I', click: function () {info()}}]}, {label: 'set ', submenu: [{label: 'quick restart ', accelerator: 'CmdOrCtrl+F5', role: 'reload'}, {label:' exit ', accelerator: 'CmdOrCtrl+Q', role: 'quit'}]}, {label: 'developer Settings ', submenu: [{label:' switch to developer mode ', Accelerator: 'CmdOrCtrl+I', role: Function info() {dialog.showMessageBox({title: 'about ', type: 'info', message: 'vue-cli-electron', // detail: ` version information: \ nelectron version: ${process. Versions. Electron} \ n current system: ${OS. The type ()} ${OS. The arch ()} ${OS. Release ()} \ n the current version: The ${process. The env. VUE_APP_ENV}, ${process. The env. VUE_APP_VERSION} `, the detail: ` version information: \ nelectron version: ${process. Versions. Electron} \ n current system: ${OS. The type ()} ${OS. The arch ()} ${OS. Release ()} \ n the current version: ${globally.envconfig.vue_app_env}, ${globally.envconfig.vue_app_version} ', noLink: true, buttons: [' ok ']})}Copy the code
The menu shortcut registration is added by accelerator. Of course, you can also make different processing according to different systems. Role is the built-in behavior of electron, such as copy-copy, paste, etc., please refer to the official documents
On Windows we hide the menu, and on MAC we display it normally:
function setMenu(win) {
let menu
if (config.devToolsShow) {
menu = Menu.buildFromTemplate(menuConfig)
Menu.setApplicationMenu(menu)
win.webContents.openDevTools({ mode: 'detach' })
} else {
if (isMac) {
menu = Menu.buildFromTemplate(menuConfig)
Menu.setApplicationMenu(menu)
} else {
Menu.setApplicationMenu(null)
}
win.webContents.openDevTools({ mode: 'detach' })
// win.webContents.closeDevTools()
}
}
Copy the code
The main process listens for shortcuts
globalShortcut
The globalShortcut module can register/unregister global shortcuts in the operating system, but it is not recommended to register shortcuts in this way. Advantages: Highest response level, responds whenever the software is running, regardless of what state it is in (unfocused or even hidden). Disadvantages: If the shortcut is already registered by another application, the registration will fail. After successful registration, it has the highest response level, so it will affect the use of shortcut keys of other software. After starting the software, if the shortcut keys of other software are the same, the shortcut keys of other software cannot take effect.
// The main process, rendering process can use remote to register: const { app, globalShortcut } = require('electron') app.whenReady().then(() => { const ret = globalShortcut.register('CommandOrControl+X', () => { console.log('CommandOrControl+X is pressed') }) if (! Ret) {console.log('registration failed')} // Check whether the shortcut key is successfully registered console.log(globalShortcut.isRegistered('CommandOrControl+X')) }) app.on('will-quit', () = > {/ / logout shortcuts globalShortcut unregister (' CommandOrControl + X) / / cancellation of all shortcuts globalShortcut unregisterAll ()})Copy the code
electron-localshortcut
The third party NPM package, API is similar to globalShortcut and is relatively less aggressive. It is targeted at window registrations, so the incoming window is registered. If the window is not focused, it does not respond. Advantages: For window listening, the response needs to be in the focused state, which can be used in most scenarios. Disadvantages: Third-party packages need to be introduced, the page has a WebView, and the focus on the WebView cannot be triggered.
npm install --save electron-localshortcut const electronLocalshortcut = require('electron-localshortcut') const win = new BrowserWindow() win.loadUrl('https://github.com') win.show() electronLocalshortcut.register(win, 'Ctrl+A', () = > {the console. The log (' You pressed CTRL & A ')}) / / check if the shortcut to register the console log (electronLocalshortcut. IsRegistered (win, 'Ctrl + A) / / logout shortcuts electronLocalshortcut unregister (win,' Ctrl + A) electronLocalshortcut. UnregisterAll (win)Copy the code
The rendering process listens for shortcuts
Own page listening
In fact, it is the listener of the keyup of the web page, which can use the communication to transmit the information of the keyboard keys to the main process. Of course, you can also use before-input-event in the main process. Before-input-event is emitted in the rendering process before the keyDown and KeyUp events are scheduled on the page. The key information is captured in the main process. Advantage: for the page listening, often used for a particular page key listening. Disadvantages: If the page has an iframe or webView and the focus is on the iframe or WebView, it cannot be triggered (iframe can trigger before-input-event).
Rendering process: window.addEventListener('keyup', handleKeyPress, Function handleKeyPress(event) {$message. Success (' keyup listener ${event.key} ') console.log(' You pressed ${event.key} ') } window. RemoveEventListener (' keyup handleKeyPress, true) main process: win.webContents.on('before-input-event', (event, input) => { if (input.control && input.key.toLowerCase() === 'i') { console.log('Pressed Control+I') event.preventDefault() } })Copy the code
Combination of keys: of course, generally speaking, shortcut keys are combination of keys, we can use a third-party key library to deal with.
NPM I mouseTrap render process Mousetrap.bind('ctrl+k', function() { $message.success(`Mousetrap ctrl+k`) }) Mousetrap.unbind('ctrl+k')Copy the code
Webview or iframe embedded web page listener
If we have a WebView or iframe in our page, and the focus is on the WebView or iframe, it will cause our shortcut keys to fail.
- The Menu Menu and globalShortcut do not fail.
- Electron localshortcut: Invalid webView, valid iframe
- Keyup: invalid webView, invalid iframe, before-input-event: valid iframe.
This is going to be a bit hard to handle when applying webView, only the Menu Menu and globalShortcut work for it, so what else? We can listen for keyboard keys by injecting preload.js into the WebView and then send the keyboard information back to our rendering process
In vue. Config. Js electronBuilder is amended as: preload: {preload: 'the renderer/SRC/preload/ipcRenderer. Js', webviewPreload: 'SRC/renderer/preload/webview. Js'} webviewPreload injections into the webview is our js, of course, you have to build corresponding files, notice how we build file is webview. Js. It will compile to WebViewPreload.js, so we will inject webViewPreload.js. Note: WebView startup and Node Integration enablement must be configured in webPreferences in the main process window. Webview. Js: const { ipcRenderer } = require('electron') window.addEventListener('keyup', handleKeyPress, true) function handleKeyPress(event) { console.log(event.key) ipcRenderer.sendToHost('ipc-message', { data: Event.key})} Render process: <webview ref="webviewRef" class="webview" src="https://www.baidu.com" :preload="state.preload" ></webview> const { remote } = require('electron') const path = require('path') const webview = webviewRef.value state.preload = path.resolve(remote.app.getAppPath(), './webviewPreload.js') webview.addEventListener('ipc-message', webMessage) webview.addEventListener('dom-ready', () => {webView.openDevTools ()}) function webMessage(event) {console.log(' receive events in this listener that respond to webView nested pages ', $message. Success (' webView: ${event.args[0].data} ')}Copy the code
To summarize briefly, we inject WebViewPreload. js into WebView, use this JS to perform keyup listening of the keyboard, and then send the information back to the rendering process through sendToHost, and the rendering process gets the returned information. The rendering process does not see the printout of our injected JS and WebView. You can use webView.OpenDevTools () to open the WebView console. This example does not cover key combinations, so you need to inject mouseTrap yourself.
This series of updates can only be arranged on weekends and after work, the update of more content will be slow, hope to help you, please more star or like collection support
This article address: xuxin123.com/electron/me… This post is on Github