Open UtterDonkey opened 2 years ago
IMO, this issue can go two ways:
nw.Window.open()
callback (and the array returned by nw.Window.getAll()
) should not have access to child window
objects when new_instance === true
. "fixing" this would make newWin.window
undefined, preventing the ability add weird event listeners to some phantom window
object that's not actually attached to that window.window
object through nw.Window.getAll()
or the nw.Window.open()
callback parameter. Adding this would allow postMessage()
to work between windows, even when new_instance
is true.Either way, the "phantom" window
added to the nw.Window.open()
callback parameter should either be fixed or removed.
I am hoping for the second option.
nw.Window.getAll()
returns the actual window object when not using new_instance
It pains me to see a bug report with code in a screenshot, especially when those screenshots and comments were a copy/paste from what I said on Discord. So, I'm adding code explaining @UtterDonkey's last comment, as well as the original code...
NWJS Version : 0.62.0 Operating System : Windows 10
There should be consistent behavior, in regards to how the win.window
object is populated when new_instance
is true
.
Currently, this object is sometimes undefined
and sometimes points to a window
object that's a partial clone of the main window's window
object (not the new window).
package.json
{
"name": "test",
"main": "index.html"
}
index.html
<script>
window.addEventListener('message', (event) => {
console.log(`Message sent to main window: ${event.data}`);
});
nw.Window.get().showDevTools();
</script>
Run the above app with the NW.js SDK.
Enter the following in the DevTools console:
nw.Window.open('index.html', {}, (newWin) => {
newWin.window.opener.postMessage('test via newWin.window.opener', '*');
});
In the new DevTools console that just opened, enter:
window.opener.postMessage('test via window.opener', '*');
nw.Window.getAll(windowList => windowList[0].window.postMessage('test via getAll()', '*'));
Note that all three of these messages are successfully received in the first/main window (shown in the first DevTools console).
Close the secondary window and enter the following in the first DevTools console:
nw.Window.open('index.html', { new_instance: true }, (newWin) => {
newWin.window.opener.postMessage('test via newWin.window.opener', '*');
});
In the new DevTools console that just opened, enter:
window.opener.postMessage('test via window.opener', '*');
nw.Window.getAll(windowList => windowList[0].window.postMessage('test via getAll()', '*'));
Note that all three messages fail:
window.opener
is null
.nw.Window.getAll(windowList => windowList[0].window)
is undefined
.Now here's where it starts to get fun. Close the secondary window again and enter the following in the first DevTools console:
nw.Window.open('index.html', { new_instance: true }, (newWin) => {
newWin.window.addEventListener('message', (event) => {
console.log(`Message sent to 2nd window: ${event.data}`);
});
});
Still in the first/main DevTools console, enter:
nw.Window.getAll(winList => winList[0].window.postMessage('0', '*'));
nw.Window.getAll(winList => winList[1].window.postMessage('1', '*'));
The console for the main window will show both messages, but the secondary window will not have received either.
If the window
object shouldn't be defined when new_instance
is true, we shouldn't be able to add event listeners to the newWin.window
object in the nw.Window.open()
callback (it should be undefined
). That said, it would be very handy to be able to get a handle to that window!
behaviour doesn't make a whole lot of sense. you get the
newWin
object which is the NW.js wrapper around the new window you just made. however, the window inside it isn't actually the window for that window... it's some new window, which allows you to add event listeners but isn't actually attached to the window. and when you add an event listener to it, the main window handles those events.Expected behaviour:
nw.Window.getAll(allWindows => {return allWindows[0].window})
returns the true window object.Actual Behaviour:
nw.Window.getAll(allWindows => {return allWindows[0].window})
returns a completely separate window object that somehow still acts like a window object.Reproduce using the steps above⬆️
OS: Windows 10