マルチなウィンドウのElectronアプリで、メニュー制御する話
Electronのアプリで、ウィンドウ毎に、メニューを切り替えたいとか、
有効無効を切り替えたいことってあると思うんです。
今回はフォーカスが当たっている時だけ、メニューを有効にする方法の話。
メニューアイテムのenabledを切り替える
メニューの有効無効を切り替えるには、
メニューのアイテムのenabled属性を切り替えれば良し。
メニューを作るときに、id属性を設定しておいて。
import {Menu} from 'electron'; const menuList = [ { ... (略) ... }, { label: '辞書', submenu: [ { id: 'dict-close', // ←←← idを設定 enabled: false, label: '辞書を閉じる (⌘W)', click() { if (myApp.dictWindow) { myApp.dictWindow.close(); } }, }, { id: 'dict-tutorial', // ←←← idを設定 enabled: false, label: '辞書チュートリアル', click() { if (myApp.dictWindow) { myApp.dictWindow.webContents.send('menu', 'tutorial'); } }, }, {type: 'separator'}, { id: 'dict-add', // ←←← idを設定 enabled: false, label: '定義データ追加 (⌘N)', click() { if (myApp.dictWindow) { myApp.dictWindow.webContents.send('menu', 'add'); } }, }, ] }, { ... (略) ... }, ]; const menuTemplate = Menu.buildFromTemplate(menuList); Menu.setApplicationMenu(menuTemplate);
そのidでメニューを取り出して、enabled属性を切り替える。
import {Menu} from 'electron'; const dictMenuItems = [ 'dict-close', 'dict-tutorial', 'dict-add', 'dict-delete', 'dict-save', 'dict-cancel', 'dict-export', 'dict-reset', ]; const menu = Menu.getApplicationMenu(); for (let m of dictMenuItems) { const item = menu.getMenuItemById(m); item.enabled = true; // ←←← enabledを切り替え }
フォーカスされたらメニューを有効に、フォーカスが外れたらメニューを無効に
BrowserWindowがフォーカスされている時だけメニューを有効にするには、
focus、blur、それとcloseのイベントを拾う。
closeも拾って置かないと、フォーカスされた状態でウィンドウ閉じられると、
ウィンドウ閉じてるのにメニューが有効なままになる。
this.dictWindow.on('close', () => { disableDictMenu(); // ←←← イベントを拾って、メニューのenabledを切り替える }); this.dictWindow.on('focus', () => { enableDictMenu(); // ←←← イベントを拾って、メニューのenabledを切り替える }); this.dictWindow.on('blur', () => { disableDictMenu(); // ←←← イベントを拾って、メニューのenabledを切り替える });
ウィンドウまわりのコードも含めると。
... (略) ... function showDictWindow(): void { const acceptFirstMouse = this.appCfg.acceptFirstMouse; this.dictWindow = new BrowserWindow({ width: width, height: height, show: false, // show at did-finish-load event }); this.dictWindow.loadURL(`file://${__dirname}/contents-dict.html`); // window event this.dictWindow.webContents.on('did-finish-load', () => { myApp.dictWindow.show(); myApp.dictWindow.focus(); }); this.dictWindow.on('close', () => { disableDictMenu(); }); this.dictWindow.on('focus', () => { enableDictMenu(); }); this.dictWindow.on('blur', () => { disableDictMenu(); }); }
メニューのacceleratorが邪魔な話
メニューアイテムにacceleratorを設定していると、
そのショートカットキーは、全てのウィンドウで効いてしまう。
import {Menu} from 'electron'; const menuList = [ { ... (略) ... }, { label: '辞書', submenu: [ { role: 'quit', accelerator: 'Command+Q', // ←←← acceleratorってこれ }, ] }, { ... (略) ... }, ]; const menuTemplate = Menu.buildFromTemplate(menuList); Menu.setApplicationMenu(menuTemplate);
これが邪魔なら、なんらかの対処をいれましょう。
acceleratorを無効にするか、
有効にしたい時以外はacceleratorを切る。
終わり
オワリダヨ