キーボード ショート カット
概要
この機能により、Electron アプリケーションのローカルとグローバルの キーボードショートカットを設定できます。
サンプル
ローカルショートカット
ローカルキーボードショートカットは、アプリケーションにフォーカスしているときのみトリガーされます。 ローカルキーボードショートカットを設定するには、Menu モジュール内の MenuItem 作成時に accelerator
プロパティを指定する必要があります。
クイックスタートガイド の作業用アプリケーションから始めることにして、main.js
ファイルを以下のように更新します。
- main.js
- index.html
const { app, BrowserWindow, Menu, MenuItem } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
const menu = new Menu()
menu.append(new MenuItem({
label: 'Electron',
submenu: [{
role: 'help',
accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
click: () => { console.log('Electron rocks!') }
}]
}))
Menu.setApplicationMenu(menu)
app.whenReady().then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>Hit Alt+Shift+I on Windows, or Opt+Cmd+I on mac to see a message printed to the console.</p>
</body>
</html>
注意: 上記のコードでは、ユーザーのオペレーティングシステムによってアクセラレーターを変えていることがわかります。 macOS では
Alt+Cmd+I
で、Linux と Windows ではAlt+Shift+I
です。
Electron アプリケーションを起動すると、アプリケーションメニューが先ほど定義したローカルショートカットとともに表示されます。
ヘルプ
をクリックする又は定義したアクセラレータを押してから、Electron アプリケーションを実行したターミナルを開くと、click
イベントがトリガーされたことで生成されたメッセージ "Electron rocks!" が表示されます。
グローバルショートカット
グローバルキーボードショートカットを設定するには、globalShortcut モジュールを使用して、アプリケーションにキーボードフォーカスがない場合のキーボードイベントを検出する必要があります。
クイックスタートガイド の作業用アプリケーションから始めることにして、main.js
ファイルを以下のように更新します。
- main.js
- index.html
const { app, BrowserWindow, globalShortcut } = require('electron/main')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
globalShortcut.register('Alt+CommandOrControl+I', () => {
console.log('Electron loves global shortcuts!')
})
}).then(createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>Hit Alt+Ctrl+I on Windows or Opt+Cmd+I on Mac to see a message printed to the console.</p>
</body>
</html>
注意: 上記コードの
CommandOrControl
の組み合わせは、macOS ではCommand
を、Windows/Linux ではControl
を使用します。
Electron アプリケーションを起動した後、定義されたキーの組み合わせを押して、Electron アプリケーションを起動したターミナルを開くと、Electron はグローバルショートカット大好きだとわかりますね!
BrowserWindow 内のショートカット
ウェブ API を使用する
BrowserWindow 内でキーボードショートカットを扱いたい場合は、addEventListener() API を使用して keyup
と keydown
の DOM イベント をレンダラープロセス内でリッスンすることでできます。
- main.js
- index.html
- renderer.js
// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron/main')
function createWindow () {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 800,
height: 600
})
// and load the index.html of the app.
mainWindow.loadFile('index.html')
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
<p>Hit any key with this window focused to see it captured here.</p>
<div><span>Last Key Pressed: </span><span id="last-keypress"></span></div>
<script src="./renderer.js"></script>
</body>
</html>
function handleKeyPress (event) {
// You can put code here to handle the keypress.
document.getElementById('last-keypress').innerText = event.key
console.log(`You pressed ${event.key}`)
}
window.addEventListener('keyup', handleKeyPress, true)
注意: 第 3 引数の
true
は、このリスナーが他のリスナーよりも必ず優先してキー押下を受け取ることを示しています。そのため、このリスナー内でstopPropagation()
を呼び出さないでください。
メインプロセス内でのイベントの受け取り
before-input-event
イベントは keydown
イベントと keyup
イベントをディスパッチするより前に発生します。 メニューに表示されないカスタムショートカットをキャッチして処理するため使用することができます。
クイックスタートガイド の作業用アプリケーションから始めることにして、 main.js
ファイルを以下のコードの通りに更新します。
- main.js
- index.html
const { app, BrowserWindow } = require('electron/main')
app.whenReady().then(() => {
const win = new BrowserWindow({ width: 800, height: 600 })
win.loadFile('index.html')
win.webContents.on('before-input-event', (event, input) => {
if (input.control && input.key.toLowerCase() === 'i') {
console.log('Pressed Control+I')
event.preventDefault()
}
})
})
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>Hit Ctrl+I to see a message printed to the console.</p>
</body>
</html>
Electron アプリケーションを起動した後、Electron アプリケーションを実行したターミナルを開き、Ctrl+I
キーの組み合わせを押すと、このキーの組み合わせが正常に受け取られたとわかります。
サードパ ーティライブラリを使用する
ショートカットの解析を手動で行いたくない場合は、mousetrap のような高度なキー検出を行うライブラリがあります。 レンダラープロセスで mousetrap
を実行する使用例を以下に示します。
Mousetrap.bind('4', () => { console.log('4') })
Mousetrap.bind('?', () => { console.log('show shortcuts!') })
Mousetrap.bind('esc', () => { console.log('escape') }, 'keyup')
// 組み合わせ
Mousetrap.bind('command+shift+k', () => { console.log('command shift k') })
// 複数の組み合わせを同じコールバックに割り当て
Mousetrap.bind(['command+k', 'ctrl+k'], () => {
console.log('command k or control k')
// false を返すと規定の動作を抑制してイベントの伝播を止める
return false
})
// Gmail 式シーケンス
Mousetrap.bind('g i', () => { console.log('go to inbox') })
Mousetrap.bind('* a', () => { console.log('select all') })
// コナミコマンド!
Mousetrap.bind('up up down down left right left right b a enter', () => {
console.log('コナミコマンド')
})