// Modules to control application life and create native browser window const { BrowserWindow, Menu, MenuItem, ipcMain, app, shell, dialog, autoUpdater } = require('electron/main') const path = require('node:path') const menu = new Menu() menu.append(new MenuItem({ label: 'Hello' })) menu.append(new MenuItem({ type: 'separator' })) menu.append( new MenuItem({ label: 'Electron', type: 'checkbox', checked: true }) ) const template = [ { label: 'Edit', submenu: [ { label: 'Undo', accelerator: 'CmdOrCtrl+Z', role: 'undo' }, { label: 'Redo', accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo' }, { type: 'separator' }, { label: 'Cut', accelerator: 'CmdOrCtrl+X', role: 'cut' }, { label: 'Copy', accelerator: 'CmdOrCtrl+C', role: 'copy' }, { label: 'Paste', accelerator: 'CmdOrCtrl+V', role: 'paste' }, { label: 'Select All', accelerator: 'CmdOrCtrl+A', role: 'selectall' } ] }, { label: 'View', submenu: [ { label: 'Reload', accelerator: 'CmdOrCtrl+R', click: (item, focusedWindow) => { if (focusedWindow) { // on reload, start fresh and close any old // open secondary windows if (focusedWindow.id === 1) { for (const win of BrowserWindow.getAllWindows()) { if (win.id > 1) win.close() } } focusedWindow.reload() } } }, { label: 'Toggle Full Screen', accelerator: (() => { if (process.platform === 'darwin') { return 'Ctrl+Command+F' } else { return 'F11' } })(), click: (item, focusedWindow) => { if (focusedWindow) { focusedWindow.setFullScreen(!focusedWindow.isFullScreen()) } } }, { label: 'Toggle Developer Tools', accelerator: (() => { if (process.platform === 'darwin') { return 'Alt+Command+I' } else { return 'Ctrl+Shift+I' } })(), click: (item, focusedWindow) => { if (focusedWindow) { focusedWindow.webContents.toggleDevTools() } } }, { type: 'separator' }, { label: 'App Menu Demo', click: function (item, focusedWindow) { if (focusedWindow) { const options = { type: 'info', title: 'Application Menu Demo', buttons: ['Ok'], message: 'This demo is for the Menu section, showing how to create a clickable menu item in the application menu.' } dialog.showMessageBox(focusedWindow, options, function () {}) } } } ] }, { label: 'Window', role: 'window', submenu: [ { label: 'Minimize', accelerator: 'CmdOrCtrl+M', role: 'minimize' }, { label: 'Close', accelerator: 'CmdOrCtrl+W', role: 'close' }, { type: 'separator' }, { label: 'Reopen Window', accelerator: 'CmdOrCtrl+Shift+T', enabled: false, key: 'reopenMenuItem', click: () => { app.emit('activate') } } ] }, { label: 'Help', role: 'help', submenu: [ { label: 'Learn More', click: () => { shell.openExternal('https://electronjs.org') } } ] } ] function addUpdateMenuItems (items, position) { if (process.mas) return const version = app.getVersion() const updateItems = [ { label: `Version ${version}`, enabled: false }, { label: 'Checking for Update', enabled: false, key: 'checkingForUpdate' }, { label: 'Check for Update', visible: false, key: 'checkForUpdate', click: () => { autoUpdater.checkForUpdates() } }, { label: 'Restart and Install Update', enabled: true, visible: false, key: 'restartToUpdate', click: () => { autoUpdater.quitAndInstall() } } ] items.splice.apply(items, [position, 0].concat(updateItems)) } function findReopenMenuItem () { const menu = Menu.getApplicationMenu() if (!menu) return let reopenMenuItem for (const item of menu.items) { if (item.submenu) { for (const subitem of item.submenu.items) { if (subitem.key === 'reopenMenuItem') { reopenMenuItem = subitem } } } } return reopenMenuItem } if (process.platform === 'darwin') { const name = app.getName() template.unshift({ label: name, submenu: [ { label: `About ${name}`, role: 'about' }, { type: 'separator' }, { label: 'Services', role: 'services', submenu: [] }, { type: 'separator' }, { label: `Hide ${name}`, accelerator: 'Command+H', role: 'hide' }, { label: 'Hide Others', accelerator: 'Command+Alt+H', role: 'hideothers' }, { label: 'Show All', role: 'unhide' }, { type: 'separator' }, { label: 'Quit', accelerator: 'Command+Q', click: () => { app.quit() } } ] }) // Window menu. template[3].submenu.push( { type: 'separator' }, { label: 'Bring All to Front', role: 'front' } ) addUpdateMenuItems(template[0].submenu, 1) } if (process.platform === 'win32') { const helpMenu = template[template.length - 1].submenu addUpdateMenuItems(helpMenu, 0) } // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow function createWindow () { // Create the browser window. mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js') } }) // and load the index.html of the app. mainWindow.loadFile('index.html') // Open the DevTools. // mainWindow.webContents.openDevTools() // Emitted when the window is closed. mainWindow.on('closed', function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null }) // Open external links in the default browser mainWindow.webContents.on('will-navigate', (event, url) => { event.preventDefault() shell.openExternal(url) }) } // 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() const menu = Menu.buildFromTemplate(template) Menu.setApplicationMenu(menu) }) // Quit when all windows are closed. app.on('window-all-closed', function () { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q const reopenMenuItem = findReopenMenuItem() if (reopenMenuItem) reopenMenuItem.enabled = true if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', function () { // On macOS it is common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (mainWindow === null) { createWindow() } }) app.on('browser-window-created', (event, win) => { const reopenMenuItem = findReopenMenuItem() if (reopenMenuItem) reopenMenuItem.enabled = false win.webContents.on('context-menu', (e, params) => { menu.popup(win, params.x, params.y) }) }) ipcMain.on('show-context-menu', event => { const win = BrowserWindow.fromWebContents(event.sender) menu.popup(win) }) // In this file you can include the rest of your app's specific main process // code. You can also put them in separate files and require them here.