Electron can be a bit of a headache when it comes to communicate between the window and the main process, and for good reason: Security.
However, this problem has two solutions:
- Not recommended: plain ipcRenderer required with
{ nodeIntegration: true }
and window.electron
in index.html, that can cause a lot of trouble, don't do that, you give access to the user to all nodejs functions, like fs, child_process, ...
- Recomended: preload. Preload makes the bridge between the process and the window allowing you to pick what you want to share with the window, in this case, ipcRenderer without the whole electron access.
Read more about Electron secuity here
First, create a preload.js to pass scope isolated ipcRenderer.send function to the window
// preload.js
const { contextBridge, ipcRenderer } = require('electron');
const exposedAPI = {
sendMessage: (message) => {
ipcRenderer.send('my-event', string);
}
};
contextBridge.exposeInMainWorld("electron", exposedAPI);
More about contextBridge here
In the main electron script
// main.js
const { ipcRenderer } = require('electron');
...
const window = new BrowserWindow({
...
preload: 'my/preload/path/preload.js', // Here preload is loaded when the window is created
})
...
ipcRenderer.on('my-event', (string) => {
// do struff with string
});
Great full example here
Finally, the window where you want to capture the event from without changing the behaviour
// index.html or your-script.js
document.addEventListener('keydown', (evt) => { // keyup, keydown or keypress
window.electron.exposedAPI.sendMessage('key was pressed');
});