NWJS: Manipulate multiple windows

323 views
Skip to first unread message

Abdelhamid Abouhassane

unread,
May 9, 2022, 4:08:33 PM5/9/22
to nw.js
Hello to you all,

I'm currently using nwjs v0.64.0, and i'm trying to ma,ipluate many windows however i seem to be able to manage only the main window for example i made a function that is suposed to return a new window instance :

const instantiator = () => {
    gui.Window.open('index.html', {}, function (window) {
        // Get the current window
        if(process.env.NODE_ENV === 'local') {
            window.showDevTools();
        }

        return window;
    });

    return gui.Window.get();
}

const runner1 = instantiator();
const runner2 = instantiator();

setTimeout(() => {
        runner1.instance.close();
}, 5000);

setTimeout(() => {
        runner2.instance.close();
}, 10000);

The behavior of this code above is that after 5s the program closes the first window but the other does not close and i get this error on the console "Unchecked runtime.lastError: cannot find browser window" after 10s.

I understood that "gui.Window.get()" returns the same main window instance and when runner2 tries to close it, it finds that it was already close and thus runner2 points to nothing.
I also tried to return directly "return gui.Window.open" but the result is undefined :/

My question would be is to how to return each time a pointer to the newly created window so in order to manage each window separately?

Thanks in advance,
A.A

Abdelhamid Abouhassane

unread,
May 9, 2022, 4:11:09 PM5/9/22
to nw.js
Correction of the code, it's :

setTimeout(() => {
        runner1.close();
}, 5000);

setTimeout(() => {
        runner2.close();
}, 10000);

I had it return an object at first, my bad !

Brian Bothwell

unread,
May 10, 2022, 9:43:29 AM5/10/22
to Abdelhamid Abouhassane, nw.js
You should not be returning `nw.Window.get()` and expecting it to be a handle for the new window. The handle for the new window is the `window` parameter in the `nw.Window.open()` callback. You need to be adding these (inside the callback) to a "global list", then looping through that list and closing each one.

- Brian


--
You received this message because you are subscribed to the Google Groups "nw.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nwjs-general...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nwjs-general/e4d0d235-a408-4869-81e2-ca19c4d65d8dn%40googlegroups.com.

Abdelhamid Abouhassane

unread,
May 10, 2022, 10:57:14 AM5/10/22
to nw.js
But then the "global list" will be populated with windows until a certain time, a time that we have no control over, right?

Brian Bothwell

unread,
May 10, 2022, 11:53:46 AM5/10/22
to Abdelhamid Abouhassane, nw.js
You have full control over the list. They remain in the list until you remove them (presumably after they're closed). Many people build a "window manager", consisting of something similar to the following:
  • Wrapper function around `nw.Window.open()` which:
    • Automatically adds the new window handle to the "global list". Optionally checks if the window is already open; if open, focus that window instead of re-opening.
    • Automatically adds an event handler to the new window's `close` event. This event handler removes the window from the "global list".
  • Event handler for the application closing, which gracefully closes all windows before exiting.

- Brian


Abdelhamid Abouhassane

unread,
May 10, 2022, 5:02:08 PM5/10/22
to nw.js
Can i do better than this, i don't like using timeout :/ but i found no other way

const gui = require('nw.gui');

gui.Window.open('index.html');

const setupExecutors = (window) => {
       return new Promise((resolve, reject) => {
                      const executors = [];
                      window.getAll((pages) => {
                            // this is juste to add other data that will be pushed to executors
                            pages.forEach((page) => {
                                   executors.push(page);
                            });
                      });

                      setTimeout(() => {
                          if(executors.length === poolExecutor) {
                                   resolve(executors);
                          } else {
                                   reject('Failed to setup executors !');
                         }
                     }, 200);
       })
}

setupExecutors(gui.Window).then((executors) => {
       console.log('executors.length: ', executors.length);
})
       
Reply all
Reply to author
Forward
0 new messages