Reputation: 65
I have one main window listing all available servers with a status button which has the id of the server. An info window is opened after pressing the related status button - passing the id to the copy of info window, making the status button disabled. If the info window is closed, the info window passes back the id to the main window so it makes the status button enabled again. To do that, I'm using main.js
as a proxy, listening to the renderer processes and exchange information between main window and info window.
The thing that I'm trying to do is to list servers. If they are online, get some information from multiple servers at once on different renderer processes (instance of info window).
The problem is I want all info windows to be closed if the main window is closed.
// App ready
app.on('ready', ()=>{
mainWindow = new BrowserWindow({x : 0, y : 0 , width : 500, height: 600});
mainWindow.loadURL(url.format({
pathname : path.join(__dirname, 'windows', 'mainWindow.html'),
protocol : 'file',
slashes : true
}));
// Close the app if main window closed
mainWindow.on('close', (e) => {
let openedOnes = BrowserWindow.getAllWindows();
openedOnes.forEach(wind => {
if(wind.hasOwnProperty('custom')){
wind.close();
};
});
app.quit();
});
});
While creating info window, I add a custom field to the BrowserWindow
object:
BrowserWindow {
_events:
{ blur: [Function],
focus: [Function],
show: [Function: visibilityChanged],
hide: [Function: visibilityChanged],
minimize: [Function: visibilityChanged],
maximize: [Function: visibilityChanged],
restore: [Function: visibilityChanged],
close: [Function: callIntoRenderer] },
_eventsCount: 8,
devToolsWebContents: [Getter],
custom: { server_id: '3' } }
So with the help of the custom field, I can get all opened server info instances.
But when I click close, the following part is failing at main.js
;
ipcMain.on('window_closed', (e, item)=>{
mainWindow.webContents.send('button_enable', item);
});
It raises the following error.
main.js:53
is the line ipcMain.on('window_closed'...
. By the way, if I omit this line everything works perfectly.
Upvotes: 0
Views: 1937
Reputation: 10199
It looks like what's happening is your mainWindow
close
handler gets triggered which tells other windows to close, which then fires off the window_closed
event (I guess that's a custom event that you added?), and by the timemainWindow.webContents.send
is called, the mainWindow
's close handler finished and the window closed.
Simply add an isDestroyed
check before sending the message like so:
ipcMain.on('window_closed', (e, item)=>{
if (mainWindow && !mainWindow.isDestroyed())
mainWindow.webContents.send('button_enable', item);
});
Your other options (though arguably less optimal) are:
window_closed
handler return out if it sees the flag (surely there's no reason to send a button_enable
message if we're about to shut everything down):
let mainWindowIsClosing = false;
mainWindow.on('close', (e)=>{
mainWindowIsClosing = true;
...
wind.close();
...
});
ipcMain.on('window_closed', (e, item)=>{
if (mainWindowIsClosing) return;
mainWindow.webContents.send('button_enable', item);
});
destroy
method instead of close
to avoid firing the close
event for child windows. (though window_closed
isn't an Electron event I believe, so it depends on how you've hooked everything up):
mainWindow.on('close', (e)=>{
...
wind.destroy();
});
Upvotes: 1
Reputation: 51
You should use Child/Parent BrowserWindows like here: https://electronjs.org/docs/api/browser-window#parent-and-child-windows
You will get more easier all child windows with:
win.getChildWindows()
https://electronjs.org/docs/api/browser-window#wingetchildwindows
Upvotes: 0
Reputation: 65
Found a solution as follows;
mainWindow.on('close', (e)=>{
mainWindow = null;
try{
let openedOnes = BrowserWindow.getAllWindows();
openedOnes.forEach(wind=>{
if(wind.hasOwnProperty('custom')){
wind.close();
};
});
app.quit();
}catch(e){
console.log(e);
}
});
Before closing the main window, i set the mainwindow to null. When an info window is closed, check if its not set to null, send the mainwindow an info window is closed and its status button should be enabled;
ipcMain.on('window_closed', (e, item)=>{
try {
if(mainWindow !== null){
mainWindow.webContents.send('button_enable', item);
}
} catch (error) {
console.log(error);
}
});
Upvotes: 0