Close event for window being fired after window has been closed


#1

I have a renderer process (RP), that spawns a browser window (BW)
When close is clicked on BW, I want the RP to catch this event and hide it instead.
However, the RP close event is fired after the BW window has been closed, and I get an exception because the BW does not exist anymore.

The documentation states that close should be in due time and can prevent the window from closing:

Emitted when the window is going to be closed. It’s emitted before the beforeunload and unload event of the DOM. Calling event.preventDefault() will cancel the close.

Here is the RP code:

bw.on("close", (e: Electron.Event) => hideWindow(e));
let hideWindow = (e: Electron.Event) => {
    e.preventDefault();
    bw.hide();
    return false;
  }

What am I missing or doing wrong?


#2

It specifically states in the documentation:

Usually you would want to use the beforeunload handler to decide whether the window should be closed,

And there is an example in the documentation that shows how to use beforeunload to do what you’re asking.


#3

That exists on window, not on BrowserWindow. Therefore it cannot be used.
The quote you printes just states the usual handler, which I am not interested in using, unless it is the only way.
For example, changing “close” to “beforeunload” does not invoke the callback at all.
The following never invokes hideWindow()

bw.on("beforeunload", (e: Electron.Event) => hideWindow(e));
let hideWindow = (e: Electron.Event) => {
    e.preventDefault();
    bw.hide();
    return false;
  }

#4

I just tried your example code, slightly modified, in my own toy Electron application and it worked. I’m using Electron v1.4.4. Here’s the code I used:

mainWindow.on('close', (e) => {
  e.preventDefault()
  mainWindow.hide()
  console.log('Window hiddnen')
  return false
})

You can see the code and try it for yourself at https://github.com/lee-dohm/hero-database/tree/test-close. script/start should launch things for you (unless you’re on Windows, then you’ll have to do some things manually).


#5

I am on windows unfortunately, but i’ll try to set it up on windows.


#6

So I couldn’t exactly figure out how to test your example, but it is not what I am asking for.

I am spawning a browserwindow in a renderer process, whereas you spawn it in the main process.
I think that is why it works in your example.

Check this one and close the window with the text: CLOSE ME

It will throw the exception below and not print Window hiddnen

Uncaught Error: Could not call remote function 'hide'. Check that the function signature is correct. Underlying error: Object has been destroyed
Error: Could not call remote function 'hide'. Check that the function signature is correct. Underlying error: Object has been destroyed
    at callFunction (C:\source\cthule\electron-quick-start\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:235:11)
    at EventEmitter.<anonymous> (C:\source\cthule\electron-quick-start\node_modules\electron\dist\resources\electron.asar\browser\rpc-server.js:342:5)
    at emitMany (events.js:127:13)
    at EventEmitter.emit (events.js:201:7)
    at WebContents.<anonymous> (C:\source\cthule\electron-quick-start\node_modules\electron\dist\resources\electron.asar\browser\api\web-contents.js:231:13)
    at emitTwo (events.js:106:13)
    at WebContents.emit (events.js:191:7)

#7

run npm install and then npm start


#8

Ah, ok. I wouldn’t expect the scenario you’re attempting to work because callbacks passed to the main process via a remote object are called asynchronously. Because your close callback is called asynchronously, it probably isn’t getting the chance to e.preventDefault() before the window closes.


#9

Okay, so it is simply not possible to use the close event in this case.
I will pursue a different approach then.


#10

Thank you for your assistance