Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating invisible window from main process to compute function in Electron

I am trying to write an Electron program in which the main process creates an invisible window, sends a number to that window, the window computes the factorial and then sends it back.

This is in the main process:

function invisibleWindow() {
  const invisPath = 'file://' + path.join(__dirname, 'files/html/inv.html')

  let win = new BrowserWindow({ width: 400, height: 400, show: false })
  win.loadURL(invisPath)

  win.webContents.on('did-finish-load', function () {
    const input = 100;
    win.webContents.send('compute-factorial', input);
  })



  ipcMain.on('factorial-computed', function (event, input, output) {
    const message = `The factorial of ${input} is ${output}`
    console.log(message);
  })
}

The function gets called in the main process by:

app.on('ready', () => {
  // creates different window here

  invisibleWindow();
});

This is the inv.html file:

<html>
  <script type="text/javascript">
    const ipc = require('electron').ipcRenderer
    const BrowserWindow = require('electron').remote.BrowserWindow

    ipc.on('compute-factorial', function (event, number) {
      const result = factorial(number)

      ipcRenderer.send('factorial-computed', number, result)
      window.close()
    })

    function factorial (num) {
      if (num === 0) return 1
      return num * factorial(num - 1)
    }
  </script>
</html>

Now after I have added this to my program, every time when I start it through the terminal, it does not terminate by itself even when all other (visible) windows are closed. I guess this is because the invisible window is still opened because it did not receive the compute-factorial event.

What am I doing wrong?

like image 320
niklassc Avatar asked Dec 08 '25 18:12

niklassc


1 Answers

This is because of an race condition. Electron docs:

Event: 'did-finish-load'

Emitted when the navigation is done, i.e. the spinner of the tab has stopped spinning, and the onload event was dispatched.

You can try it with setTimeout:

win.webContents.on('did-finish-load', function () {
  setTimeout(() => {
    const input = 100;
    win.webContents.send('compute-factorial', input);
  }, 3000);
});

The main process does not know when the DOM is ready. You can do something like this.

Send your main process an "dom-is-ready" event.

inv.html

ipc.send('dom-is-ready');

Paste your 'did-finish-load' code into 'dom-is-ready'.

main.js

function invisibleWindow() {
  const invisPath = 'file://' + path.join(__dirname, 'files/html/inv.html');

  const win = new BrowserWindow({ 
    width: 400, 
    height: 400, 
    show: false 
  });

  win.loadURL(invisPath);

  win.webContents.on('did-finish-load', function () {
    win.show();
  });

  ipcMain.on('dom-is-ready', function (event) {
    const input = 100;
    win.webContents.send('compute-factorial', input);
  });

  ipcMain.on('factorial-computed', function (event, input, output) {
    const message = `The factorial of ${input} is ${output}`
    console.log(message);
  });
}
like image 180
Phil Avatar answered Dec 11 '25 08:12

Phil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!