How to open a modal dialog in electron's main process

In electron (new versions), the dialog API is only available in the main process. So when we want to open a dialog in the render process, we have to communicate with the main process and let the main process open the dialog.

The problem is that, by default the main process opens a normal dialog rather than a modal.

a modal takes priority over the page and prevent the user from interacting with the page until the modal is closed.

Solution

The APIs of the dialog module all have an browserWindow argument which is optional.

If the browserWindow argument is a window, than the dialog becomes a modal of that window.

Code example

The example below shows how to open a modal dialog that opens a directory.

Code for render process

const { ipcRenderer } = require('electron')
const dir = await ipcRenderer.invoke('openDir')

Code for main process

const { BrowserWindow, ipcMain, dialog } = require('electron')


ipcMain.handle('openDir', async (event) => {
    const win = BrowserWindow.fromWebContents(event.sender)
    const result = await dialog.showOpenDialog(win, {
        properties: ['openDirectory']
    })
    if (result.canceled) {
        return null
    } else {
        return result.filePaths[0]
    }
})

Notice:

  • BrowserWindow.fromWebContents(event.sender) shows how to get the requesting window.
  • dialog.showOpenDialog(win, ...) shows how to open a modal dialog.
Posted on 2023-07-04