'How to access the mainWindow from another script in Electron?
My electron app defines the BrowserWindow
mainWindow in the main.js. It loads an html and eventually inside of the html a script runs the function dialog.showMessageBox()
which displays a simple warning:
dialog.showMessageBox({
type: 'warning',
message: "You have been warned.",
buttons: ["OK"]
});
I want this dialog to be a child of the mainWindow b/c that makes it a modal, which disables the mainWindow until it is closed. To implement this you normally would just add mainWindow,
before the type declaration. Unfortunately it doesn't know the variable mainWindow since the dialog.showMessageBox()
is created in a different script (site.js).
How can I create a dialog, that is a child of the mainWindow without creating it in the main.js? Can ipc help somehow?
Solution 1:[1]
Current Electron versions (>= 14.0.0)
Starting with Electron 14.0.0, the below-mentioned remote
module has been deprecated and subsequently removed. In order to still open these dialog boxes from the renderer process, I suggest to send a message to the main process via IPC:
// renderer process
const { ipcRenderer } = require ("electron");
ipcRenderer.send ("show-message");
And the listening part in the main process:
// main process
const { dialog, ipcMain, BrowserWindow } = require ("electron");
ipcMain.on ("show-message", (event, args) => {
dialog.showMessageBox (BrowserWindow.fromWebContents (event.sender), {
type: "warning",
message: "You have been warned.",
buttons: ["OK"]
});
});
This will open the message box as a modal dialog for the BrowserWindow
instance which has sent the IPC message and will thus work as a drop-in replacement for the remote
code.
Electron < 14.0.0
You can use Electron's remote
module to get your current BrowserWindow
from the script included (loaded) in that window:
const remote = require ("electron").remote;
dialog.showMessageBox (remote.getCurrentWindow (), {
type: "warning",
message: "You have been warned.",
buttons: ["OK"]
});
Solution 2:[2]
The accepted answer is still correct, but quite old, and in the meantime the Electron team decided to slowly deprecate the remote
module (more info here and here):
However, I was able to fix it by using BrowserWindow.getFocusedWindow()
, which makes only one tiny assumption that the window which triggers the MsgBox is the one being currently focused (my guess is that in 99% of the cases that's true). Here's the updated code:
const { dialog, BrowserWindow } = require ("electron");
dialog.showMessageBox (BrowserWindow.getFocusedWindow(), {
type: "warning",
message: "You have been warned.",
buttons: ["OK"]
});
Solution 3:[3]
To safely get the mainWindow in electron, I store its ID in a env variable and call BrowserWindow.fromId(ID)
when needed.
BrowserWindow.getFocusedWindow()
will not work in some case, for exemple if you load an URL from a child window to the main window.
I met some weird effect too, with BrowserWindow.getAllWindows()
solution.
// store the ID at init time when you create your main window
process.env.MAIN_WINDOW_ID = mainWindow.id;
// every time you want the main window, call this function.
// don't forget to convert the env variable to type number otherwise this will throw an error.
const getMainWindow = () => {
const ID = process.env.MAIN_WINDOW_ID * 1;
return BrowserWindow.fromId(ID)
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Mihai Paraschivescu |
Solution 3 |