Skip to content

Commit 02b1069

Browse files
trop[bot]ckerr
authored andcommitted
fix: Invalidate weak ptrs before window Javascript object is destroyed (backport: 3-0-x) (electron#14591)
* fix: Invalidate weak ptrs before window Javascript object is destroyed * chore: add regression test for electron#14513 This test is similar to the original gist at https://gist.github.com/bpasero/a02a645e11f4946dcca1331d0299149d -- the key is to open multiple windows and add an `app.on('browser-window-focus') listener that accesses window.id. * fix: last commit didn't test the right thing. The test needs to run in the main process to reproduce the conditions reported in electron#14513
1 parent 3348e51 commit 02b1069

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

atom/browser/api/atom_api_top_level_window.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,11 @@ void TopLevelWindow::WillCloseWindow(bool* prevent_default) {
142142
}
143143

144144
void TopLevelWindow::OnWindowClosed() {
145+
// Invalidate weak ptrs before the Javascript object is destroyed,
146+
// there might be some delayed emit events which shouldn't be
147+
// triggered after this.
148+
weak_factory_.InvalidateWeakPtrs();
149+
145150
RemoveFromWeakMap();
146151
window_->RemoveObserver(this);
147152

spec/api-browser-window-spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ describe('BrowserWindow module', () => {
210210
contents.getId()
211211
}, /Object has been destroyed/)
212212
})
213+
it('should not crash when destroying windows with pending events', (done) => {
214+
const responseEvent = 'destroy-test-completed'
215+
ipcRenderer.on(responseEvent, () => done())
216+
ipcRenderer.send('test-browserwindow-destroy', { responseEvent })
217+
})
213218
})
214219

215220
describe('BrowserWindow.loadURL(url)', () => {

spec/static/main.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,26 @@ ipcMain.on('test-webcontents-navigation-observer', (event, options) => {
379379
contents.loadURL(options.url)
380380
})
381381

382+
ipcMain.on('test-browserwindow-destroy', (event, testOptions) => {
383+
let focusListener = (event, win) => win.id
384+
app.on('browser-window-focus', focusListener)
385+
const windowCount = 3
386+
const windowOptions = {
387+
show: false,
388+
width: 400,
389+
height: 400,
390+
webPreferences: {
391+
backgroundThrottling: false
392+
}
393+
}
394+
const windows = Array.from(Array(windowCount)).map(x => new BrowserWindow(windowOptions))
395+
windows.forEach(win => win.show())
396+
windows.forEach(win => win.focus())
397+
windows.forEach(win => win.destroy())
398+
app.removeListener('browser-window-focus', focusListener)
399+
event.sender.send(testOptions.responseEvent)
400+
})
401+
382402
// Suspend listeners until the next event and then restore them
383403
const suspendListeners = (emitter, eventName, callback) => {
384404
const listeners = emitter.listeners(eventName)

0 commit comments

Comments
 (0)