Electron の終了イベントまわりの整理


Electron は終了イベントがいくつかあり、さらに終了の仕方によって発火するイベントの種類や順序が微妙に変わるのが非常にややこしいのでまとめてみることにした。

検証方法

以下の検証スクリプトで Electron アプリを起動して、様々な終了方法を試みたときにどのような出力が出るかを見る。

環境は macOS v10.14.6, Node.js v12.9.1, Electron v6.0.5 で行った。

検証スクリプト
const electron = require('electron');

electron.app.on('ready', () => {
  const window = new electron.BrowserWindow();
  window.on('close', () => console.log('BrowserWindow.close'));
  window.on('closed', () => console.log('BrowserWindow.closed'));
});

electron.app.on('window-all-closed', () => {
  console.log('app.window-all-closed');
  electron.app.quit();
});
electron.app.on('before-quit', () => console.log('app.before-quit'));
electron.app.on('will-quit', () => console.log('app.will-quit'));
electron.app.on('quit', () => console.log('app.quit'));

window-all-closed のイベントハンドラで app.quit() を呼んでいるのは、 window-all-closed イベントを subscribe してない場合はそのまま quit が実行されるが subscribe している場合は quit が実行されないという仕様になっているため。

検証結果

終了方法をいくつか試したが、結果は2パターンに分かれた。

パターン 1

  • Cmd + Q で終了した場合
  • SIGTERM を送った場合
  • SIGINT を送った場合
app.before-quit
BrowserWindow.close
app.will-quit
app.quit
BrowserWindow.closed

「アプリが終了するからウィンドウを閉じますね」という流れ。

パターン 2

  • Cmd + W で終了した場合
  • ウィンドウの閉じるボタンを押した場合
BrowserWindow.close
app.window-all-closed
app.before-quit
app.will-quit
app.quit
BrowserWindow.closed

「ウィンドウがすべて閉じたからアプリを終了しますね」という流れ。

パターン 1 と比べると、app.window-all-closed が発火している点と app.before-quit が発火するタイミングが遅い点が異なっている。

参考

各イベントの詳細は公式ドキュメントを参照されたい。

app.will-quitevent.preventDefault() でキャンセルできるけど app.quit はできないとか、そういう違いなどが書かれている。