Can't pass an IPC message to a browserwindow - javascript

I'm messing around with electron, one of the things i'm trying to do is monitor a directory for file changes, and send the full path of the file that changed to a browser window via IPC to a renderer. I know the file watcher is working since it's logging to the console, but the path never makes it to the browserwindow.
Putting logging lines in the renderer never log, and remote debugging and stepping through the code, i can see it never fires off to the renderer.
Any idea? I'm new to this javascript stuff so it's probably something simple i'm missing. Thanks in advance!
main.js:
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const ipc = electron.ipcMain
const watchfiles = require('./watchfiles')
const windows = []
app.on('ready', _ => {
[1].forEach(_ => {
let win = new BrowserWindow({
height: 400,
width: 400
})
win.loadURL(`file://${__dirname}/watchfiles.html`)
win.on('closed', _ => {
mainWindow = null
})
windows.push(win)
})
})
ipc.on('filewatch-start', _ => {
//Log
console.log('Filewatch started')
watchfiles(fullPath => {
windows.forEach(win => {
win.webContents.send('changedfiles', fullPath)
})
})
})
renderer.js:
const electron = require('electron')
const ipc = electron.ipcRenderer
document.getElementById('start').addEventListener('click', _ =>{
ipc.send('filewatch-start')
})
ipc.on('changedfiles', (event, message) => {
document.getElementById('changedfiles').innerHTML = message
})
watchfiles.js:
module.exports = function watchfiles(watchr) {
// Import the watching library
var watchr = require('watchr')
// Define our watching parameters
var path = process.cwd()
function listener (changeType, fullPath, currentStat, previousStat) {
switch ( changeType ) {
case 'update':
console.log('the file', fullPath, 'was updated', currentStat, previousStat)
break
case 'create':
console.log('the file', fullPath, 'was created', currentStat)
break
}
}
function next (err) {
if ( err ) return console.log('watch failed on', path, 'with error', err)
console.log('watch successful on', path)
}
// Watch the path with the change listener and completion callback
var stalker = watchr.open(path, listener, next)
// Close the stalker of the watcher
//stalker.close()
}
watchfile.html:
<html>
<head>
<link rel="stylesheet" href="watchfiles.css" />
</head>
<body>
<div id="container">
<h1 class="title">Watching files:</h1>
<div class="watchfiles" id="changedfiles"></div>
<button class="btn" id="start">Start</button>
</div>
<script>require('./renderer')</script>
</body>
</html>

Regarding only the IPC communication this simpler version works:
main.js
const { app, ipcMain, BrowserWindow } = require('electron')
const windows = []
app.on('ready', _ => {
/* ... */
})
ipcMain.on('filewatch-start', _ => {
console.log('Filewatch started')
windows.forEach(win => {
win.webContents.send('changedfiles', 'examplePath')
})
})
renderer.js
const { ipcRenderer } = require('electron')
window.onload = () => {
document.getElementById('start').addEventListener('click', _ =>{
ipcRenderer.send('filewatch-start')
})
ipcRenderer.on('changedfiles', (event, message) => {
document.getElementById('changedfiles').innerHTML = message
})
}
watchfile.html
<html>
<head>
<script type="text/javascript" src="./renderer.js"></script>
</head>
<body>
<div id="container">
<h1 class="title">Watching files:</h1>
<div class="watchfiles" id="changedfiles" />
<button class="btn" id="start">Start</button>
</div>
</body>
</html>
Regarding the overall design, you can do the job of watchfiles.js in main.js, no need to separate them:
main.js (compact)
const { app, ipcMain, BrowserWindow } = require('electron')
const watchr = require('watchr')
const path = process.cwd()
let windows = []
let stalker = null
const listener = (changeType, fullPath, currentStat, previousStat) => {
var msg = ''
console.log('change detected: ', changeType, currentStat, previousStat)
switch ( changeType ) {
case 'update':
msg = 'the file' + fullPath + ' was updated'
break
case 'create':
msg = 'the file' + fullPath + ' was created'
break
}
windows.forEach(win => {
win.webContents.send('changedfiles', msg)
})
}
const next = (err) => {
if ( err ) return console.log('watch failed on', path, 'with error', err)
console.log('watch successful on', path)
}
app.on('ready', () => {
[1].forEach(() => {
let win = new BrowserWindow({
height: 400,
width: 400
})
win.loadURL(`file://${__dirname}/watchfile.html`)
win.on('closed', _ => {
mainWindow = null
})
windows.push(win)
})
})
app.on('quit', () => {
if (stalker) stalker.close()
})
ipcMain.on('filewatch-start', _ => {
console.log('Filewatch started')
if (!stalker) {
stalker = watchr.open(path, listener, next)
}
})

Related

Why electron defaultPath is not opening the provided directory path

Hi i'm not able to open the provided directory path(/home/userxyz/Releases/alpha) with electron
What i'm trying
i have a path like this on ubuntu /home/userxyz/Releases/alpha
when i try to open this path with below code
const files = await dialog.showOpenDialog({
title:'Browse mapped drive',
defaultPath: "/home/userxyz/Releases/alpha",
properties: ['openFile', 'multiSelections']
});
it is opening some junk directory
Note: i will be having variable let openDirectory = "/home/userxyz/Releases/alpha" which will change based on config value.
Question: i want to open a directory with the provided path let say the path will be /home/userxyz/Releases/alpha
Regarding successfully opening a defaultPath, I have noticed that if the passed-in path does not exist, then either
the last opened path or the valid part of the defaultPath (starting from the left) is opened. Therefore, you would want to confirm that
the defaultPath exists prior to opening a dialog.
I have included a full but minimised example on how to implement your desired action. Note the use of the preload.js
script (via whitelisted channel names only) and
the ipcRenderer.invoke(channel, ...args)
method in the render process and
the ipcMain.handle(channel, listener)
method in the main process.
I have used the channel name openFileDialog.
preload.js (main process)
// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// White-listed channels.
const ipc = {
'render': {
// From render to main.
'send': [],
// From main to render.
'receive': [],
// From render to main and back again.
'sendReceive': [
'openFileDialog' // Channel name
]
}
};
// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods.
'ipcRender', {
// From render to main.
send: (channel, args) => {
let validChannels = ipc.render.send;
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, args);
}
},
// From main to render.
receive: (channel, listener) => {
let validChannels = ipc.render.receive;
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`.
ipcRenderer.on(channel, (event, ...args) => listener(...args));
}
},
// From render to main and back again.
invoke: (channel, args) => {
let validChannels = ipc.render.sendReceive;
if (validChannels.includes(channel)) {
return ipcRenderer.invoke(channel, args);
}
}
}
);
See below for further use of the preload.js script.
/**
* Render --> Main
* ---------------
* Render: window.ipcRender.send('channel', data); // Data is optional.
* Main: electronIpcMain.on('channel', (event, data) => { methodName(data); })
*
* Main --> Render
* ---------------
* Main: windowName.webContents.send('channel', data); // Data is optional.
* Render: window.ipcRender.receive('channel', (data) => { methodName(data); });
*
* Render --> Main (Value) --> Render
* ----------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', (event, data) => { return someMethod(data); });
*
* Render --> Main (Promise) --> Render
* ------------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', async (event, data) => {
* return await promiseName(data)
* .then(() => { return result; })
* });
*/
In this main.js file, one would want to check that the defaultPath exists first, else when the dialog
opens it may be unreliable / appear as a random path.
main.js (main process)
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronDialog = require('electron').dialog;
const electronIpcMain = require('electron').ipcMain;
const nodePath = require("path");
// Prevent garbage collection
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
// Only pass in a valid defaultPath
let defaultPath = '/home/user/Releases/alpha'; // Ubuntu
// let defaultPath = 'C:\\Users\\user\\invalid\\path'; // Windows
electronIpcMain.handle('openFileDialog', () => {
// Dialog options
let options = {
title: 'Browse mapped drive',
defaultPath: defaultPath,
properties: ['openFile', 'multiSelections']
};
// Open dialog
return electronDialog.showOpenDialog(window, options)
.then((result) => {
// Bail early if user cancelled dialog
if (result.canceled) { return }
return result.filePaths;
})
})
Detect button click, send an IPC message to the main thread which opens the dialog. Upon the dialog returning a value,
it is returned to the render process and displayed as <li> items.
index.html (render process)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Electron Test</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
</head>
<body>
<input type="button" id="button" value="Open File Dialog">
<ul id="paths"></ul>
</body>
<script>
document.getElementById('button').addEventListener('click', () => {
window.ipcRender.invoke('openFileDialog')
.then((paths) => {
if (paths === undefined) { return } // Dialog was cancelled
let result = '';
for (let path of paths) {
result += '<li>' + path + '</li>';
}
document.getElementById('paths').innerHTML = result;
})
})
</script>
</html>

electron app json data to renderer using ipc

i am new to electron so im sorry if my question is childish
but i have sent some user inout data as object from renderer to main to store in json file (electron-db)
but i want to show all data in a table
i tired this by event.reply but it giving my desired result in preload's log only
i dont know how to take it from preload to html table
here i have attached my code from main
// catch obj This is Main.js
ipcMain.on("message", (event, obj) => {
db.createTable("medicine", (succ, msg) => {
// succ - boolean, tells if the call is successful
if (succ) {
console.log(msg);
} else {
console.log("An error has occured. " + msg);
}
});
console.warn(obj);
if ((db.valid("medicine"), location)) {
db.insertTableContent("medicine", obj, (succ, msg) => {
// succ - boolean, tells if the call is successful
console.log("Success: " + succ);
console.log("Message: " + msg);
});
}
let row;
const app = electron.app || electron.remote.app;
db.getAll("medicine", (succ, data) => {
// succ - boolean, tells if the call is successful
// data - array of objects that represents the rows.
// console.warn(data);
row = data;
});
console.warn(row)
event.reply("message", row)
});
and this is my preload
const {contextBridge, ipcMain, ipcRenderer} = require('electron');
const API = {
sendmsg: (obj) => ipcRenderer.send("message", obj)
}
// const getAllData = function fetchData(){
// ipcRenderer.send("req", "this is requirment for All data")
// }
ipcRenderer.on("message", (_event, row) => {
console.log(row)
})
contextBridge.exposeInMainWorld("api", API);
consol.log(row) giving my an array of all data in my db
but i dont know how to make it availabe in html files script or in renderer
The wiring of your IPC is a bit mixed up and confusing. To simplify your scripts, try separating them into their own functionality. IE: Use your preload.js script to allow communication between the main process and render process(es) only.
Not knowing what database you are using, I will assume your database code is correct and functional.
Below is an example of how I would set-up my preload.js script and use it to communicate between processes.
This preload.js script uses whitelisted channel names to identify which IPC lines of communication can be used, similar to Node.js eventName.
preload.js (main process)
// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// White-listed channels.
const ipc = {
'render': {
// From render to main.
'send': [],
// From main to render.
'receive': [],
// From render to main and back again.
'sendReceive': [
'message' // Channel name
]
}
};
// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods.
'ipcRender', {
// From render to main.
send: (channel, args) => {
let validChannels = ipc.render.send;
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, args);
}
},
// From main to render.
receive: (channel, listener) => {
let validChannels = ipc.render.receive;
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`.
ipcRenderer.on(channel, (event, ...args) => listener(...args));
}
},
// From render to main and back again.
invoke: (channel, args) => {
let validChannels = ipc.render.sendReceive;
if (validChannels.includes(channel)) {
return ipcRenderer.invoke(channel, args);
}
}
}
);
For brevity, I have included your database code within the below main.js file.
main.js (main process)
'use strict';
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;
const nodePath = require("path");
// db = require('db'); // Your (connected) database
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
// From render to main and back again
electronIpcMain.handle('message', (event, obj) => {
// Create the table
db.createTable("medicine", (succ, msg) => {
if (succ) {
console.log(msg);
} else {
console.log('An error has occurred. ' + msg);
}
});
console.warn(obj);
// Insert your data object
if ((db.valid("medicine"), location)) {
db.insertTableContent("medicine", obj, (succ, msg) => {
console.log('Success: ' + succ);
console.log('Message: ' + msg);
});
}
let rows;
// Retrieve all rows
db.getAll("medicine", (succ, data) => {
// succ - boolean, tells if the call is successful
// data - array of objects that represents the rows.
// console.warn(data);
rows = data;
});
console.warn(rows);
return rows; // Simple return the result via IPC
// Testing purposes.
// let rows = [
// {"name": "Amoxicillin", "weight": "250mg"},
// {"name": "Codeine", "weight": "50mg"},
// {"name": "Penicillin", "weight": "25mg"}
// ];
//
// rows.push(obj);
//
// console.log(rows);
//
// return rows;
})
Lastly, I have tried to implement what the basic functionality of your index.html file may be like.
index.html (render process)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Medicine</title>
</head>
<body>
<h1>Add Medicine</h1>
<label for="name">Name: </label>
<input id="name" type="text">
<label for="weight">Weight: </label>
<input id="weight" type="text">
<input id="button" type="button" value="Add">
</body>
<script>
let name = document.getElementById('name');
let weight = document.getElementById('weight');
document.getElementById('button').addEventListener('click', () => {
// From render to main and (.then) back again
window.ipcRender.invoke('message', {"name": name.value, "weight": weight.value})
.then((rows) => {
console.log(rows);
})
})
</script>
</html>

Having trouble adding a callback function from the main.js to the renderer.js after button click in another window

Hi at the moment i have used the ipcRenderer in one of my JS files to execute a function in the main.js. This code executes without a problem. What I'm trying to do straight after is send a callback function to the main renderer.js file so that i can execute another function which manipulates the appearance of some icons in the main window.
main.js code:
ipcMain.on('ReadyBtn', (event) => {
console.log('request received')
ToggleReady();
event.returnValue = "toggle ready test";
})
sidebar.js code - this file is where I'm using the ipc renderer:
const ReadyBtn = document.getElementById('btnReady')
ReadyBtn.addEventListener('click', function(){
ipcRenderer.sendSync("ReadyBtn")
});
The code above works fine, when the button is clicked the toggleReady() function within the main.js file is triggered.
What i would now like to do is set up a call back function in the renderer.js file so that i can execute another function "stateReady()", after the button is clicked. Below is what i have so far:
(async () =>{
await ipcRenderer.invoke('ReadyBtn')
stateReady();
})();
Noting that you have not included your preload.js script in your question, I have added the below preload.js script
which has no concrete implementations in it (apart from the IPC methods), only configuration of whitelisted channel names.
preload.js (main process)
// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;
// White-listed channels.
const ipc = {
'render': {
// From render to main.
'send': [],
// From main to render.
'receive': [],
// From render to main and back again.
'sendReceive': [
'ReadyBtn' // Channel name
]
}
};
// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
// Allowed 'ipcRenderer' methods.
'ipcRender', {
// From render to main.
send: (channel, args) => {
let validChannels = ipc.render.send;
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, args);
}
},
// From main to render.
receive: (channel, listener) => {
let validChannels = ipc.render.receive;
if (validChannels.includes(channel)) {
// Deliberately strip event as it includes `sender`.
ipcRenderer.on(channel, (event, ...args) => listener(...args));
}
},
// From render to main and back again.
invoke: (channel, args) => {
let validChannels = ipc.render.sendReceive;
if (validChannels.includes(channel)) {
return ipcRenderer.invoke(channel, args);
}
}
}
);
This preload.js script is used like so.
/**
* Render --> Main
* ---------------
* Render: window.ipcRender.send('channel', data); // Data is optional.
* Main: electronIpcMain.on('channel', (event, data) => { methodName(data); })
*
* Main --> Render
* ---------------
* Main: windowName.webContents.send('channel', data); // Data is optional.
* Render: window.ipcRender.receive('channel', (data) => { methodName(data); });
*
* Render --> Main (Value) --> Render
* ----------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', (event, data) => { return someMethod(data); });
*
* Render --> Main (Promise) --> Render
* ------------------------------------
* Render: window.ipcRender.invoke('channel', data).then((result) => { methodName(result); });
* Main: electronIpcMain.handle('channel', async (event, data) => {
* return await promiseName(data)
* .then(() => { return result; })
* });
*/
In your main.js file you will use the handle method to listen for a message on the ReadyBtn channel, process the request and then return a response.
main.js (main process)
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;
const nodePath = require("path");
let window;
function createWindow() {
const window = new electronBrowserWindow({
x: 0,
y: 0,
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: nodePath.join(__dirname, 'preload.js')
}
});
window.loadFile('index.html')
.then(() => { window.show(); });
return window;
}
electronApp.on('ready', () => {
window = createWindow();
});
electronApp.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electronApp.quit();
}
});
electronApp.on('activate', () => {
if (electronBrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// ---
electronIpcMain.handle('ReadyBtn', (event, message) => {
console.log('Request received'); // Testing
// toggleReady();
return 'Toggle ready test';
})
In your index.html file, you will use the invoke method to send a message on the ReadyBtn channel to the main process and then wait for a response.
index.html (render process)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Electron Test</title>
</head>
<body>
<input id="button" type="button" value="Button">
</body>
<script>
document.getElementById('button').addEventListener('click', () => {
window.ipcRender.invoke('ReadyBtn')
.then((result) => {
console.log(result); // Testing
console.log('Request received'); // Testing
// stateReady();
})
})
</script>
</html>

Electron JS - Get path of chosen directory

Im fairly new in the programming world. I'm making an app where it should be possible to choose a directory, where to save some generated files.
I'm working with the ipc, and it seems like some of the code works, but it looks like i can't get the mainIpc to send the path back to the renderer.
I hope the hive can help, thanks in advance!
Renderer:
const electron = require("electron");
const ipc = require("electron").ipcRenderer;
createBtn.addEventListener("click", (event) => {
ipc.send("path:get");
});
ipc.on("path:selected", function (path) {
console.log("Full path: ", path);
});
Main
const ipc = require("electron").ipcMain;
const os = require("os");
const { dialog } = require("electron");
ipc.on("path:get", function (event) {
if (os.platform() === "linux" || os.platform() === "win32") {
dialog.showOpenDialog(
{
properties: ["openFile"],
},
function (files) {
if (files) win.webContents.send("path:selected", files[0]);
console.log("SENT");
}
);
} else {
dialog.showOpenDialog(
{
properties: ["openFile", "openDirectory"],
},
function (files) {
if (files) win.webContents.send("path:selected", files[0]);
console.log("SENT");
}
);
}
});
Edit: Adding the setup
Setup
const { app, BrowserWindow } = require("electron");
const ipc = require("electron").ipcMain;
const os = require("os");
const { dialog } = require("electron");
try {
require("electron-reloader")(module);
} catch (_) {}
let win;
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
},
});
win.loadFile("./src/index.html");
}
app.whenReady().then(createWindow);
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
I figured it out with some kind help.
So if anyone needs the same procedure i'll try to explain what i got to.
So, in the main, i had to add a then, because the showDialog returns a promise
if (os.platform() === "linux" || os.platform() === "win32") {
dialog
.showOpenDialog({
properties: ["openFile", "openDirectory"],
})
.then((result) => {
if (result) win.webContents.send("path:selected", result.filePaths);
})
.catch((err) => {
console.log(err);
});
} else {
dialog
.showOpenDialog({
properties: ["openFile", "openDirectory"],
})
.then((result) => {
console.log(result.filePaths);
if (result) win.webContents.send("path:selected", result.filePaths);
})
.catch((err) => {
console.log(err);
});
}
});
This sends back an array with the path at [0]
in the renderer i forgot to add the event as an parameter.
ipc.on("path:selected", (event, path) => {
chosenPath = path;
console.log("Full path: ", chosenPath[0]);
});

How do I access DOM using keyboard shortcuts in Electron

I have a 50x50 px div element and I want to change its background color when I hit Ctrl+K. How do I do it?
UPDATE : After searching around for a bit, I tried this code and it still isn't working
index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
</head>
<body>
<div id="d" style="background-color: red; height: 50px; width: 50px;"></div>
<script>
const {ipcRenderer} = require('electron')
ipcRenderer.on('changeCol', (event,color) => {
document.getElementById('d').style.backgroundColor = color;
})
</script>
</body>
</html>
Here's the main.js
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const globalShortcut = electron.globalShortcut;
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadURL(`file://${__dirname}/index.html`)
mainWindow.webContents.openDevTools()
mainWindow.on('closed', function () {
mainWindow = null
})
}
app.on('ready', function() {
createWindow();
// registered a shortcut for Ctrl+K
globalShortcut.register('Control+K', () => {
mainWindow.webContents.on('did-fininsh-load', () => {
mainWindow.webContents.send('changeCol','green');
})
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
if (mainWindow === null) {
createWindow()
}
})
Alright, so I figured out I can't modify DOM directly from the main.js file. We have to use webContents.send() and ipcRenderer to send and recieve asynchronous messages via channels. Here's some simple code which lets you modify a div's background color.
main.js
app.on('ready', function() {
globalShortcut.register('A', () => {
mainWindow.webContents.send('changeColor','green');
});
});
index.html
<script>
const {ipcRenderer} = require('electron')
ipcRenderer.on('changeColor', (event,col) => {
var element = document.getElementById('element');
element.style.color = col;
})
</script>
Probably by using the Accelerator Api
const {app, globalShortcut} = require('electron')
app.on('ready', () => {
// Register a 'Control+K' shortcut listener.
globalShortcut.register('Control+K', () => {
// Do stuff when K and Command is pressed.
})
})
Then just some simple javascript where it says // Do stuff when K and Command is pressed. This is going to depend how your HTML/CSS is set up and the exact results you're looking for.

Categories

Resources