Chrome Dev tools in electron app? - node.js

I have found that, while running some Electron app, I can access Chrome Dev Tools by pressing Cmd-Alt-I, while on some others I can't. I am wondering which is the setting to avoid/enable this behaviour.

There are a couple of options. You can initialize your BrowserWindow without devtools:
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
devTools: false
}
});
Or you can catch the opened event on the webContents and close it:
mainWindow.webContents.on("devtools-opened", () => {
mainWindow.webContents.closeDevTools();
});

Related

Electron starts unfocused (responds to double clicks only)

I'm developing a test application using Electron 18.
I noticed that sometimes on mac the app starts without the focus.
If I click on the window nothing change, I noticed that performing a double click the html buttons are pressed but the window remain unfocused.
My code if very very easy:
Html:
<button>Test</button>
<hr>
Also the main.js is basic:
const { app, BrowserWindow, ipcMain, screen, globalShortcut } = require('electron');
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})
Nothing more..
I start the app with elecrtron ./ and sometime, I get the windows unfocus as the following image (as you can see the app name is gray, unfocused):
It happen more ofter when I press ctrl+R to refresh the page

Jest check if setting is true or false

I want to make a simple jest test to check if devTools was left on for an Electron app. I have this function in main.js:
function createWindow () {
win = new BrowserWindow({
width: 1024,
height: 728,
backgroundColor: '#000000',
webPreferences: {
nodeIntegration: true,
devTools: false
},
frame: false
});
I just want to make a test to see if devTools is false. Can jest just read that specific variable?
Yes, you can access the options that were passed to the BrowserWindow constructor like such:
win = new BrowserWindow( {
webPreferences: {
nodeIntegration: true,
devTools: true
},
});
console.log( win.webContents.browserWindowOptions.webPreferences.devTools );
// will print true
Note that you can only retrieve the value if it actually appears in the constructor call options, otherwise it is undefined.
Further note that this is undocumented: the Electron docs do not mention webContents.browserWindowOptions. I have tried this using Electron 10.1.0.
I've recently found out about Spectron and it allows you to test Electron apps. Their documentation shows them using Mocha, but I'm pretty sure you can get it working with Jest. I don't need to check if devTools is on in my Electron app anymore, but I'm posting here for anyone that wants to do something similar.

Get path of associated file when opened on double click Electron builder

Information:
OS: windows 10
Electron Version: Latest
Electron Builder Version: Latest
I am trying to make an app that edits .txt files. I want to get the path of the text file when it is opened with the application (i.e. the user chooses to open the .txt with my app). I have included the following in the build of my package.json:
"fileAssociations": [
{
"name": "Text Files",
"description": "Plain Text File",
"ext": [
"txt"
]
}
],
This makes the application open with the file however how do I get the path of the file that was used to open the app. I know I have to do something with a process.argv however I have no idea how to use this. I have tried the below with no success:
ipcMain.on('get-file-data', function(event) {
var data = null;
if (process.platform == 'win32' && process.argv.length >= 2) {
var openFilePath = process.argv[1];
console.log(data)
win.webContents.send('openFile', openFilePath)
}
});
How can I get the path of the file?
This is the log of the whole process. As we can see here, the second argv is the path of the input file path. So process.argv[1] will be enough to the file path. Not sure why you can't get a path.
Maybe this comes from your ipc event listener. Which means the get-file-data is not fired correctly.
As you can see in this below image,I'm showing this process variable in this browser console. Here is how I exposed process variable to the renderer. But this is just for debug! Recommend not doing this in your production.
preload.js
process.once("loaded", () => {
window.process = process;
});
main.js
mainWindow = new BrowserWindow({
width: 1024,
height: 728,
minWidth: 800,
minHeight: 750,
webPreferences: {
enableRemoteModule: true,
preload: path.join(__dirname, "preload.js"),
}
});
And you can use window.process or process on your renderer
I managed to get the path with the following:
const { remote } = require('electron');
console.log(remote.process.argv[1])
This returns the path of the file used to open the app!

Cordova Electron app, openFileDialog event

In my app I open a new window with an external web pagte. This page let users to choose a file. I need to intercept the openFileDialog opened.
Is there a way to do this?
Alternatively ss there a way to execute a script from the external page that runs some function on my electron app?
Thank you
Example:
// open an external page
const { remote } = require('electron');
const { BrowserWindow } = remote;
win = remote.getCurrentWindow();
newWin = new BrowserWindow(
{
parent: win,
modal: false,
show: false,
width: 1280,
height: 1024,
webPreferences: {
nodeIntegration: false,
plugins: true
}
}
);
newWin.loadURL(url);
//Page into newWin will open a file choose dialog and i need to know this is happened...
Did you tried electron dialog, below code snippet uses a same electron thread
const { dialog } = require('electron')
console.log(dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] }))
To exchange information between process you may look into
ipc-main AND webContents

Electron - How to load a html file into the current window?

I was looking all around: docs, google, etc., on how to load a html file in the main window of an electron app, but I can't find a way.
Is it really this complicated or dead simple?
With what I have came up is ajax, thus works:
$("#main").load("./views/details.html");
Another method I have found is via remote:
const {BrowserWindow} = require('electron').remote
let win = new BrowserWindow({width: 800, height: 600})
win.loadURL('https://github.com')
But this opens always a new window, and I need to replace the existing page
If you want to load a new URL in an existing window you can do this in the renderer process:
const { remote } = require('electron')
remote.getCurrentWindow().loadURL('https://github.com')
Note that Electron restarts the renderer process when a new URL is loaded, so you'll probably see a flash when that happens. This is why it's usually best to use a single page application (SPA) architecture when building Electron apps.
I know this post is quite old but it's the most popular one on Google in terms of the question of loading new layouts for windows.
I had the same white flash issue because I'm not using any single page framework like React or Vue.js (I'm planning to in the future). So if you are not using too, you can create a function on the main process that hides or shows which window you want to show to make it look like one-page app.
You can get and set each windows' size and position to make the transition better:
function loadPage(page) {
if (page == "landing") {
landingWindow.setSize(uiWindow.getSize()[0],uiWindow.getSize()[1])
landingWindow.setPosition(uiWindow.getPosition()[0],uiWindow.getPosition()[1])
landingWindow.show()
uiWindow.hide()
} else if (page == "main") {
uiWindow.getSize(landingWindow.getSize()[0],landingWindow.getSize()[1])
uiWindow.setPosition(landingWindow.getPosition()[0],landingWindow.getPosition()[1])
uiWindow.show()
landingWindow.hide()
}
exports.loadPage = loadPage;
And you can expose this function to window with a preload script like this:
const electron = require('electron')
const remote = electron.remote
const mainProcess = remote.require('./main')
window.loadPage = mainProcess.loadPage;
Don't forget to initialize both windows on the main process:
function createWindow() {
// Create the browser window.
landingWindow = new BrowserWindow({
width: 1820,
height: 720,
/* fullscreen: true, */
webPreferences: {
nodeIntegration: false,
preload: path.resolve(path.join(__dirname, "preloads/preload.js"))
},
show: false,
backgroundColor: "#222831"
});
landingWindow.loadURL(
url.format({
pathname: path.join(__dirname, "src/landing.html"),
protocol: "file:",
slashes: true
})
);
uiWindow = new BrowserWindow({
width: 1820,
height: 720,
/* fullscreen: true, */
webPreferences: {
nodeIntegration: false,
preload: path.resolve(path.join(__dirname, "preloads/preload.js"))
},
show: false,
backgroundColor: "#222831"
});
uiWindow.loadURL(
url.format({
pathname: path.join(__dirname, "src/mainui.html"),
protocol: "file:",
slashes: true
})
);
// and load the index.html of the app.
// Open the DevTools.
landingWindow.webContents.openDevTools();
// Emitted when the window is closed.
landingWindow.on("closed", () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
landingWindow = null;
});
landingWindow.once("ready-to-show", () => {
landingWindow.show();
});
}

Resources