Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

windowManger.bridge: No mechanism available to remove a listener #12

Open
gschmottlach-xse opened this issue Aug 21, 2016 · 3 comments
Open

Comments

@gschmottlach-xse
Copy link

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.

'removeAllListeners': function(event) {
                windowManager.eventEmitter.removeAllListeners(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 . . .

@tamkeen-tms
Copy link
Owner

Hi there,

Great point. I will try to figure out a way to handle this issue. Thanks

@refeele
Copy link

refeele commented Sep 26, 2020

Use electron-unhandled to get rid of those problems in runtime.
It doesn't removes the listeners but works as a quick (and nasty) fix atm :(

@refeele
Copy link

refeele commented Sep 26, 2020

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 :octocat:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants