methods in contextBridge not working in child window

38 Views Asked by At

I use quasar framework for development. In child windows, I cannot call the code of my myWindowAPI, do you know why?

In electron-preload.ts I have this

function createWindow() {
  let x, y;
  const currentWindow = BrowserWindow.getFocusedWindow();
  if (currentWindow) {
    const [currentWindowX, currentWindowY] = currentWindow.getPosition();
    x = currentWindowX + 24;
    y = currentWindowY + 24;
  }
  let newWindow: Electron.CrossProcessExports.BrowserWindow | undefined;
  newWindow = new BrowserWindow({
    show: false,
    width: 1000,
    height: 600,
    x,
    y,
    frame: false,
    webPreferences: {
      //nodeIntegration: true,
      contextIsolation: true,
    }
  });
  //newWindow.loadURL(`file://${__dirname}/app.html`);
  newWindow.loadURL(process.env.APP_URL);
  newWindow.webContents.openDevTools();
  newWindow.webContents.on('did-finish-load', () => {
    if (!newWindow) {
      throw new Error('"newWindow" is not defined');
    }
    if (process.env.START_MINIMIZED) {
      newWindow.minimize();
    } else {
      newWindow.show();
      newWindow.focus();
    }
  });
  newWindow.on('closed', () => {
    //windows.delete(newWindow);
    newWindow = undefined;
  });
  /*newWindow.on('focus', () => {
    const menuBuilder = new MenuBuilder(newWindow);
    menuBuilder.buildMenu();
  });*/
  //windows.add(newWindow);
  return newWindow;
}

contextBridge.exposeInMainWorld('myWindowAPI', {

  
  ajouterFenetre () {
    createWindow()
  },

  envoi (data: unknown) {
    //BrowserWindow.getFocusedWindow()?.webContents.send('ping', data)
    console.log('envoi', data)
    ipcRenderer.send('ping', data)
  },

  on: () => {
        // Deliberately strip event as it includes `sender`
        ipcRenderer.on('ping2', (event, data) => {
            console.log('recoi 1', data)
        })
  },

  recoi: (func:(data: unknown) => void) => {
    //if (validChannels.includes(channel)) {
    // Deliberately strip event as it includes `sender`
    return ipcRenderer.on('ping2', (event, data) => {
        console.log('recoi 1', data)
    })
    //ipcRenderer.on('ping', (event, data) => func(data))
    //}
  },

  /*recoi: () => new Promise((res) => {
    ipcRenderer.on('ping', (ev, data) => {
        console.log('recoi 1', data)
      res(data);
    });
  }),*/

  minimize () {
    console.log('minimize2')
    //BrowserWindow.getFocusedWindow()?.minimize()
  },

  toggleMaximize () {
    const win = BrowserWindow.getFocusedWindow()

    if (win?.isMaximized()) {
      win.unmaximize()
    } else {
      win?.maximize()
    }
  },

  close () {
    BrowserWindow.getFocusedWindow()?.close()
  }
})

In the main window, the methods myWindowAPI working but not in another window created by method createWindow. I call in my vue component the method

window.myWindowAPI?.ajouterFenetre()

Why is working only in main window ?

1

There are 1 best solutions below

8
Arkellys On

A preload script has to be attached to a window to be accessible:

new BrowserWindow({
  ...
  webPreferences: {
    preload: path.join(__dirname, 'preload.js')
  }
});

Additionaly, if you want to use the same preload for both window, it means you need to move your window creation code on the main process, outside of the preload file, because you can't link a file if you're within it. It simply means adding an extra IPC handler, as per the official example in the docs:

renderer

window.myWindowAPI?.createWindow();

electron-preload.ts

contextBridge.exposeInMainWorld('myWindowAPI', {
  createWindow: () => ipcRenderer.send('create-window'),
  ...
}

electron-main.ts

const createWindow = () => {
  ...
};

ipcMain.on('create-window', createWindow);