You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Although the windowManager.bridge module provides a mechanism to add a listener for an event (e.g. the 'on' method) there is no method to remove the listener. Since an anonymous function is actually used in the underlying EventEmitter.addListener() method (not the callback passed in to 'on') it is impossible to unregister from events once set. This anonymous wrapper function would have to be returned as a "handle" to provide any hope of removing a listener later (a call the current API doesn't support).
There is actually a bigger problem here that involves the scenario where two BrowserWindows (e.g. separate Renderer processes) wish to communicate using the bridge. Assume BrowserWindow A creates (via the 'remote' IPC services) a new BrowserWindow B and wishes to communicate from A to B. BrowserWindow B will register an 'on()' event handler while BrowserWindow A will use the bridge's emit() function to send it messages. This works great. The problem occurs when BrowserWindow B closes. There is no opportunity for BrowserWindow B to remove it's listener for the event emitted by BrowserWindow A. Should BrowserWindow A create a new instance of BrowserWindow B (which adds the same event listener again), internally, the EventEmitter now has TWO handlers registered for the event in question. One listener for a (previously closed) BrowserWindow B and a new one for the recently re-created BrowserWindow B. When BrowserWindow A calls emit() an exception is thrown warning that a message is trying to be sent to a BrowserWindow (B) that is closed and destroyed. Because of this exception the event never gets to the newly re-created BrowserWindow B.
The windowManager.bridge module almost needs to monitor the life-times of each window it manages. It does this to remove windows from it's list of open windows but that is not enough. On 'close' it would likely need to scan the list of listeners looking for handlers on Renderer processes that are no longer available. I don't think the Render process can do this itself because it's likely too late (once it catches the 'close' event) to make a remote IPC call to the windowManager singleton to remove it's handlers.
For now, I've added my own method to windowManager.bridge that simple removes ALL the listeners for a given event. So BrowserWindow A adds a listener for BrowserWindow B closing. When it gets this indication it removes ALL listeners for this event.
This works in my scenario (e.g. I don't get the exception any longer) but it is rather draconian - especially if there were other BrowserWindows that are not closing and are registered to receive the same event. In that case, their event listeners would no longer be called.
I'm hoping you can suggest a different approach to handle this problem, or at a minimum, at least provide the method (above) on the bridge to be able to remove all listeners for a given event. A better solution would be to remove all handlers for a given event on a specific BrowserWindow although it's not clear if this is possible.
I hope you can offer some advice here . . .
The text was updated successfully, but these errors were encountered:
Btw, sorry for bringing old issues to live but this function is a must D:
Maybe internally you can attach a removeEvents function on the BrowserWindow "closed" event as electron guarantees that it will be emitted in any case
Although the windowManager.bridge module provides a mechanism to add a listener for an event (e.g. the 'on' method) there is no method to remove the listener. Since an anonymous function is actually used in the underlying EventEmitter.addListener() method (not the callback passed in to 'on') it is impossible to unregister from events once set. This anonymous wrapper function would have to be returned as a "handle" to provide any hope of removing a listener later (a call the current API doesn't support).
There is actually a bigger problem here that involves the scenario where two BrowserWindows (e.g. separate Renderer processes) wish to communicate using the bridge. Assume BrowserWindow A creates (via the 'remote' IPC services) a new BrowserWindow B and wishes to communicate from A to B. BrowserWindow B will register an 'on()' event handler while BrowserWindow A will use the bridge's emit() function to send it messages. This works great. The problem occurs when BrowserWindow B closes. There is no opportunity for BrowserWindow B to remove it's listener for the event emitted by BrowserWindow A. Should BrowserWindow A create a new instance of BrowserWindow B (which adds the same event listener again), internally, the EventEmitter now has TWO handlers registered for the event in question. One listener for a (previously closed) BrowserWindow B and a new one for the recently re-created BrowserWindow B. When BrowserWindow A calls emit() an exception is thrown warning that a message is trying to be sent to a BrowserWindow (B) that is closed and destroyed. Because of this exception the event never gets to the newly re-created BrowserWindow B.
The windowManager.bridge module almost needs to monitor the life-times of each window it manages. It does this to remove windows from it's list of open windows but that is not enough. On 'close' it would likely need to scan the list of listeners looking for handlers on Renderer processes that are no longer available. I don't think the Render process can do this itself because it's likely too late (once it catches the 'close' event) to make a remote IPC call to the windowManager singleton to remove it's handlers.
For now, I've added my own method to windowManager.bridge that simple removes ALL the listeners for a given event. So BrowserWindow A adds a listener for BrowserWindow B closing. When it gets this indication it removes ALL listeners for this event.
This works in my scenario (e.g. I don't get the exception any longer) but it is rather draconian - especially if there were other BrowserWindows that are not closing and are registered to receive the same event. In that case, their event listeners would no longer be called.
I'm hoping you can suggest a different approach to handle this problem, or at a minimum, at least provide the method (above) on the bridge to be able to remove all listeners for a given event. A better solution would be to remove all handlers for a given event on a specific BrowserWindow although it's not clear if this is possible.
I hope you can offer some advice here . . .
The text was updated successfully, but these errors were encountered: