Having Electron manage the minimising, maximising, restoring and closing of your window in the main process is
recommended.
See the
below Browser Window - Instance Methods
for more information.
To implement this functionality, use of a simple preload.js
script configured to transmit data via the use of channel
names between the main process and render process(es) can be used.
Note the use of the channel names window:minimize
, window:maximize
, window:restore
and window:close
. You can
use
any channel name you like.
preload.js
(main process)
// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// White-listed channels.
const ipc = {
'render': {
// From render to main.
'send': [
'window:minimize', // Channel names
'window:maximize',
'window:restore',
'window:close'
],
// From main to render.
'receive': [],
// From render to main and back again.
'sendReceive': []
}
};
// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods.
'ipcRender', {
// From render to main.
send: (channel, args) => {
let validChannels = ipc.render.send;
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, args);
}
},
// From main to render.
receive: (channel, listener) => {
let validChannels = ipc.render.receive;
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`.
ipcRenderer.on(channel, (event, ...args) => listener(...args));
}
},
// From render to main and back again.
invoke: (channel, args) => {
let validChannels = ipc.render.sendReceive;
if (validChannels.includes(channel)) {
return ipcRenderer.invoke(channel, args);
}
}
}
);
Further, use of the above preload.js
script can be used as shown below.
/**
* Render --> Main
* ---------------
* Render: window.ipcRender.send('channel', data); // Data is optional.
* Main: electronIpcMain.on('channel', (event, data) => { methodName(data); })
*
* Main --> Render
* ---------------
* Main: windowName.webContents.send('channel', data); // Data is optional.
* Render: window.ipcRender.receive('channel', (data) => { methodName(data); });
*
* Render --> Main (Value) --> Render
* ----------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', (event, data) => { return someMethod(data); });
*
* Render --> Main (Promise) --> Render
* ------------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', async (event, data) => {
* return await promiseName(data)
* .then(() => { return result; })
* });
*/
In the main.js
script, let's listen for use of the channel name(s) and when detected, modify the window
via the
corresponding instance method(s).
main.js
(main process)
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;
const nodePath = require('path');
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
electronIpcMain.on('window:minimize', () => {
window.minimize();
})
electronIpcMain.on('window:maximize', () => {
window.maximize();
})
electronIpcMain.on('window:restore', () => {
window.restore();
})
electronIpcMain.on('window:close', () => {
window.close();
})
And finally, using event listeners, lets listed for click
events of buttons to send
a message along the correct
channel (name).
index.html
(render process)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Electron Test</title>
</head>
<body>
<input type="button" id="minimize" value="minimise">
<input type="button" id="maximize" value="maximise">
<input type="button" id="restore" value="restore">
<input type="button" id="close" value="close">
</body>
<script>
document.getElementById('minimize').addEventListener('click', () => {
window.ipcRender.send('window:minimize');
});
document.getElementById('maximize').addEventListener('click', () => {
window.ipcRender.send('window:maximize');
});
document.getElementById('restore').addEventListener('click', () => {
window.ipcRender.send('window:restore');
});
document.getElementById('close').addEventListener('click', () => {
window.ipcRender.send('window:close');
});
</script>
</html>