I need to build an app that will span across multiple monitor screens, something like this: Electron suports multiple windows but how to comunicate between them?
The main thing to remember is that in Electron, interProcess communication is done by ipcMain (in the main process) and ipcRenderer(in all the created windows). Like below: From what i've seen in the GitHub comments - direct communication between the Renderer instances is not allowed. Everything must pass trough the mainProcess.
the code: mainProcess.js:
function createWindow1 () {
window1 = new BrowserWindow({width: 800,height: 600})
window1.loadURL(`file://${__dirname}/window1.html`)
window1.webContents.openDevTools()
window1.on('closed', function () {
window1 = null
})
return window1
}
function createWindow2 () {
window2 = new BrowserWindow({width: 1000, height: 600})
window2.loadURL(`file://${__dirname}/window2.html`)
window2.webContents.openDevTools()
window2.on('closed', function () {
window2 = null
})
return window2
}
app.on('ready', () => {
window1 = createWindow1();
window2 = createWindow2();
ipcMain.on('nameMsg', (event, arg) => {
console.log("name inside main process is: ", arg); // this comes form within window 1 -> and into the mainProcess
event.sender.send('nameReply', { not_right: false }) // sends back/replies to window 1 - "event" is a reference to this chanel.
window2.webContents.send( 'forWin2', arg ); // sends the stuff from Window1 to Window2.
});
window1.html:
<body>
<input type="text" id="name" value="" placeholder="Enter your name">
<button type="button" id="sendName" >Send the name! </button>
</body>
<script>
// You can also require other files to run in this process
require('./window1.js')
</script>
window1.js:
const ipcRenderer = require('electron').ipcRenderer
let name = document.getElementById('name');
ButtonSendName = document.getElementById('sendName');
ButtonSendName.addEventListener('click', (event) => {
ipcRenderer.send('nameMsg', name.value);
})
ipcRenderer.on('nameReply', (event, arg) => {
console.log(arg) // why/what is not right..
});
window2.html:
<body>
<p id = "showName"></p>
</body>
<script>
require('./window2.js')
</script>
window2.js:
const { ipcRenderer } = require('electron')
showName = document.getElementById('showName')
ipcRenderer.on('forWin2', function (event, arg){
console.log(arg);
showName.innerHTML = arg;
});
console.log("I'm Window2");
A demo would be better, but I don't know how to build an electron CodeBin app. This image gives you an idea:
Enjoy the power of Electron !
Depending on your requirements... it is possible to create SharedWorker that acts as a proxy transferring MessagePorts between windows. Note: SharedWorker requires all windows run from the same origin (might not meet your requirements). So for example, in the main window create a MessageChannel (which has provides two ports), then transfer port1 via the SharedWorker to one window and port2 to the other window. Now the two windows can communicate directly via the ports using postMessage. As a bonus postMessage also supports transferables. I was playing around with the idea but haven't yet fully developed the library but you can get the idea from some work in progress here: https://github.com/lneir/electron-direct-comm
Whenever we talk about communicating from one window to another window inside of an Electron application, you always want to be thinking of the IPC system, Inter Process Communication.
So in one window you will listen for an event, for example, a form submittal.
Once the form is submitted, you can take the text out of that input and emit an event to the Electron app.
Then the Electron app will trigger its own event and send the event on over to the mainWindow
which will receive the text and append it on to its list.
You can start this with just vanilla JavaScript in the secondary window.html file like so:
document.querySelector('form').addEventListener('submit', event => {
event.preventDefault();
});
So the above assumes you are working with a form you are trying to submit.