-
Notifications
You must be signed in to change notification settings - Fork 1
Advanced examples
Samuel Leroy edited this page Feb 4, 2022
·
15 revisions
This setup will allow you to use this library without @electron/remote
. Thanks to jjeff for proposing this solution.
const { app, ipcMain, BrowserWindow, Menu} = require('electron');
const path = require('path');
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
frame: false,
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js'),
},
});
win.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
});
ipcMain.on('request-application-menu', (event) => sendApplicationMenu(event.sender));
ipcMain.on('menu-event', (event, commandId) => {
getMenuItemByCommandId(commandId)?.click(undefined, BrowserWindow.fromWebContents(event.sender), event.sender);
});
ipcMain.on('window-event', (event, arg) => {
const window = BrowserWindow.fromWebContents(event.sender);
switch (arg) {
case 'minimize':
window.minimize();
break;
case 'maximize':
window.isMaximized() ? window.unmaximize() : window.maximize();
break;
case 'close':
window.close();
break;
}
});
ipcMain.on('window-state', (event) => {
event.returnValue = BrowserWindow.fromWebContents(event.sender).isMaximized();
});
const sendApplicationMenu = (webContents) => {
const appMenu = Menu.getApplicationMenu();
setDefaultRoleAccelerators(appMenu);
// Strip functions, maps and circular references (for IPC)
const menu = JSON.parse(JSON.stringify(appMenu, getCircularReplacer()));
// Send menu structure to renderer
webContents.send('application-menu', menu);
};
const getCircularReplacer = () => {
const seen = new WeakSet();
return (key, value) => {
if (key === 'commandsMap') return;
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
};
const getMenuItemByCommandId = (commandId, menu = Menu.getApplicationMenu()) => {
for (let i = 0; i < menu.items.length; i++) {
const item = menu.items[i];
if (item.commandId === commandId) {
return item;
} else if (item.submenu) {
const result = getMenuItemByCommandId(commandId, item.submenu);
if (result) {
return result;
}
}
}
};
const setDefaultRoleAccelerators = (menu) => {
for (let i = 0; i < menu.items.length; i++) {
const item = menu.items[i];
if (item.role && item.getDefaultRoleAccelerator) {
item.defaultRoleAccelerator = item.getDefaultRoleAccelerator();
}
if (item.submenu) {
setDefaultRoleAccelerators(item.submenu);
}
}
};
const { ipcRenderer } = require('electron');
const Titlebar = require('@6c65726f79/custom-titlebar');
let titlebar;
window.addEventListener('DOMContentLoaded', () => {
titlebar = new Titlebar({
onMinimize: () => ipcRenderer.send('window-event', 'minimize'),
onMaximize: () => ipcRenderer.send('window-event', 'maximize'),
onClose: () => ipcRenderer.send('window-event', 'close'),
isMaximized: () => ipcRenderer.sendSync('window-state'),
menuItemClickHandler: (commandId) => ipcRenderer.send('menu-event', commandId)
});
ipcRenderer.send('request-application-menu');
});
ipcRenderer.on('application-menu', (event, appMenu) => {
titlebar.updateOptions({menu: appMenu});
});
const { initialize, enable } = require('@electron/remote/main');
const { app, BrowserWindow } = require('electron');
const path = require('path');
initialize();
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
frame: false,
webPreferences: {
nativeWindowOpen: true,
preload: path.join(__dirname, 'preload.js'),
},
});
enable(win.webContents);
setWindowOpenHandler(win);
win.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
});
const setWindowOpenHandler = (window) => {
window.webContents.setWindowOpenHandler(({ url }) => {
return {
action: 'allow',
overrideBrowserWindowOptions: {
frame: false,
webPreferences: {
nativeWindowOpen: true,
preload: path.join(__dirname, 'preload.js'),
},
},
};
});
window.webContents.on('did-create-window', (childWindow) => {
enable(childWindow.webContents);
setWindowOpenHandler(childWindow);
});
};
const { Menu, BrowserWindow, webContents, getCurrentWindow } = require('@electron/remote');
const Titlebar = require('@6c65726f79/custom-titlebar');
const currentWindow = getCurrentWindow();
let titlebar;
currentWindow.webContents.once('dom-ready', () => {
titlebar = new Titlebar({
menu: Menu.getApplicationMenu(),
browserWindow: currentWindow,
onMinimize: () => currentWindow.minimize(),
onMaximize: () => (currentWindow.isMaximized() ? currentWindow.unmaximize() : currentWindow.maximize()),
onClose: () => currentWindow.close(),
isMaximized: () => currentWindow.isMaximized()
});
});
This setup will allow you to use Window Controls Overlay in Electron 16+. The system's default window controls will be used on all platforms.
const { initialize, enable } = require('@electron/remote/main');
const { app, BrowserWindow } = require('electron');
const path = require('path');
initialize();
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
titleBarStyle: "hidden",
titleBarOverlay: {
color: 'black',
symbolColor: 'white',
},
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
})
enable(win.webContents);
win.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
})
const { Menu, getCurrentWindow } = require('@electron/remote');
const Titlebar = require('@6c65726f79/custom-titlebar');
const { platform } = require('process');
const currentWindow = getCurrentWindow();
let titlebar;
currentWindow.webContents.once('dom-ready', () => {
titlebar = new Titlebar({
menu: Menu.getApplicationMenu(),
backgroundColor: 'black',
unfocusEffect: false,
platform: platform,
browserWindow: currentWindow,
windowControlsOverlay: true
});
});
This setup will allow you to use the system's default window controls on macOS. This has no effect on Windows.
const { initialize, enable } = require('@electron/remote/main');
const { app, BrowserWindow } = require('electron');
const path = require('path');
initialize();
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
titleBarStyle: 'hidden',
webPreferences: {
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
})
enable(win.webContents);
win.loadFile('index.html');
}
app.whenReady().then(() => {
createWindow();
})
const { Menu, getCurrentWindow } = require('@electron/remote');
const Titlebar = require('@6c65726f79/custom-titlebar');
const { platform } = require('process');
const currentWindow = getCurrentWindow();
let titlebar;
currentWindow.webContents.once('dom-ready', () => {
titlebar = new Titlebar({
hideControlsOnDarwin: true,
platform: platform,
height: platform == 'darwin' ? 22 : 30,
onMinimize: () => currentWindow.minimize(),
onMaximize: () => currentWindow.isMaximized() ? currentWindow.unmaximize() : currentWindow.maximize(),
onClose: () => currentWindow.close(),
isMaximized: () => currentWindow.isMaximized()
});
});