1

In my Electron setup I display a web-based login screen once the app loads. It's housed within a BrowserView that fills the app's screen space. With this approach I can disable nodeIntegration for the login page (as it requires jQuery which is unavailable when nodeIntegration is true) while keeping it enabled for my main app.

But I noticed a delay from when I closed the login view and when the main app would load. e.g. It could take 2 - 5 seconds.

To remove this delay I've started to pre-load the main app using the 'did-finish-load' event. This means that when the login screen is presented I can load the main app in the "background".

However I've hit an issue where the BrowserView loses focus. This means a user needs to manually click on the login input. This started to occur after I added the call to win.loadFile('index.html').

So far I've been able to mitigate this by passing the focus back to the BrowserView once the main app loads. But this is not perfect as there's a brief dead time during which keyboard input is ignored.

Is there a better workaround? My code is below.

const win = new BrowserWindow({
    width: 605, height: 550,
    minWidth: 605, minHeight: 550,
    useContentSize: true,
    maximizable: false,
    title: "My Window"
})

const view = new BrowserView({
    webPreferences: {
      // Enables support for jQuery and others by disabling nodeIntegration in this BrowserView
      nodeIntegration: false,
    }
})

win.setBrowserView(view)
view.setAutoResize({ width: true, height: true})
view.setBounds({ x: 0, y: 0, width: win.getContentBounds().width, height: win.getContentBounds().height })

view.webContents.loadURL('my login url')

view.webContents.once('did-finish-load', () => {
    // Load the main view in the background. This means it'll be available immediately when the login view closes.
    // But it also steals focus from the view so...
    win.loadFile('index.html')

    // Best fix so far but not perfect
    win.webContents.on('did-finish-load', () => view.webContents.focus())
})

view.webContents.on('login-complete-made-up-event', async (event) => {
    // Close the login page to show the main view
    view.destroy()
    // Set the focus onto the main view
    win.webContents.focus()
})
Shane Gannon
  • 6,770
  • 7
  • 41
  • 64
  • "as it requires jQuery which is unavailable when nodeIntegration is true" – I think it is the opposite, at least in my experience. – spring Jul 04 '19 at 20:02
  • Believe I'm correct - have a read of https://electronjs.org/docs/faq#i-can-not-use-jqueryrequirejsmeteorangularjs-in-electron > Due to the Node.js integration of Electron, there are some extra symbols inserted into the DOM like module, exports, require. This causes problems for some libraries since they want to insert the symbols with the same names. – Shane Gannon Jul 04 '19 at 20:26

1 Answers1

1

The fix was rather simple. Stumbled onto it within 5 minutes this morning.

view.webContents.once('did-finish-load', () => {
    // Load the main view in the background. This means it'll be available immediately when the login view closes.
    win.loadFile('index.html')

    // Place focus on the view for keyboard input. i.e. Otherwise the user needs to click.
    // Do this after loading index.html as the loadFile(..) steals focus
    view.webContents.focus()
})
Shane Gannon
  • 6,770
  • 7
  • 41
  • 64
  • Hi Shane! May I ask you to clarify me how to exchange messages between BrowserView and the main process? I haven't found any working example yet. Thanks in advance – Raphael10 Feb 23 '22 at 10:22
  • In short you can use IPC. See https://www.electronjs.org/docs/latest/api/ipc-renderer#ipcrenderersendchannel-args and https://www.electronjs.org/docs/latest/api/web-contents#contentssendchannel-args – Shane Gannon Feb 23 '22 at 18:42
  • Thank you Shane. Actually I've been trying to use, as already did between `main` and `renderer`, between `main` and `browserview`. But I do not see the messages. I guess it has to be something really silly I'm missing, so I've created this StackOverFlow question: https://stackoverflow.com/questions/71243812/messages-between-browserview-and-the-renderer-react-page-in-electron . Please have a look at it. Thank you in advance – Raphael10 Feb 23 '22 at 20:48