I'm making an app using Electron framework and I tried using buttons to close and minimize the window. I've tried multiple things for it to do this but without success.
This is what I have for the moment:
HTML:
<body>
<!-- Titlebar -->
<button id="minimize-button">-</button>
<button id="close-button">x</button>
<!-- Script -->
<script src="./js/minimize-close.js"></script>
</body>
JS (minimize-close.js):
const { ipcRenderer } = require('electron');
document.getElementById("minimize-button").addEventListener('click', () => {
ipcRenderer.send('minimize-window');
});
document.getElementById("close-button").addEventListener('click', () => {
ipcRenderer.send('close-window');
});
JS (index.js):
const { app, BrowserWindow, ipcMain } = require('electron');
function createWindow(){
const window = new BrowserWindow({
width: 960, height: 580,
resizable: false, maximizable: false,
frame: false, autoHideMenuBar: true,
icon: './icon.ico',
webPreferences: {
nodeIntegration: true,
devTools: false
}
});
window.loadFile('./src/index.html');
}
// Minimize and close window
ipcMain.on('minimize-window', () => {
window.minimize();
});
ipcMain.on('close-window', () => {
window.close();
});
app.whenReady().then(() => {
createWindow();
app.on('activate', function(){
if(BrowserWindow.getAllWindows().length === 0){
createWindow();
}
});
});
app.on('window-all-closed', function(){
if(process.platform !== 'darwin'){
app.quit();
}
});
You need to set contextIsolation: false.
Also I have read around that window must be global. If not at some point it will be collected by the garbage collector because function which created it has already finished.
let window;
function createWindow(){
window = new BrowserWindow({
width: 960, height: 580,
resizable: false, maximizable: false,
frame: false, autoHideMenuBar: true,
icon: './icon.ico',
webPreferences: {
nodeIntegration: true,
// devTools: false, // commented for debugging purposes
contextIsolation: false
}
});
window.loadFile('./src/index.html');
window.webContents.openDevTools(); // Open dev tools to see if any error arised. In this case I saw 'require is not defined' before setting contextIsolation. Remove it when going into production.
}
Option B: more "secure"
If security is a concern and you want nodeIntegration and contextIsolation to retain their default secure values then preload.js scheme is needed.
This should be the case if remote content is loaded by your App.
HTML
<body>
<!-- Titlebar -->
<button id="minimize-button">-</button>
<button id="close-button">x</button>
</body>
preload.js
const { ipcRenderer } = require('electron');
window.addEventListener('DOMContentLoaded', () => {
document.getElementById("minimize-button").addEventListener('click', () => {
ipcRenderer.send('minimize-window');
});
document.getElementById("close-button").addEventListener('click', () => {
ipcRenderer.send('close-window');
});
})
index.js
const path = require('path');
function createWindow(){
window = new BrowserWindow({
width: 960, height: 580,
resizable: false, maximizable: false,
frame: false, autoHideMenuBar: true,
icon: './icon.ico',
webPreferences: {
// devTools: false, // commented for debugging purposes
preload: path.join(__dirname, 'preload.js')
}
});
window.loadFile('./src/index.html');
window.webContents.openDevTools(); // Open dev tools to see if any error arised. In this case I saw 'require is not defined' before setting contextIsolation. Remove it when going into production.
}
Related
I try to loadurl https://www.google.com and always get an error electron: Failed to load URL: https://www.google.com/ with error: ERR_PROXY_CONNECTION_FAILED . This problem has been bothering me for a week and I hope I can get your help
newWin = new BrowserWindow({
width: 400,
height: 600,
frame: true,
maximizable: true,
webPreferences: {
devTools: true,
webviewTag: true,
nodeIntegration: true,
enableRemoteModule: true,
contextIsolation: false,
preload: link
},
});
newWin.index = arg.index;
newWin.type = arg.type;
//I have set ip and port here
newWin.webContents.session.setProxy({
proxyRules: "http://129.226.148.192:3128",
}).then(() => {
newWin.loadURL(`${arg.href}`);
}).catch((err) => console.error(err));
// I have configured the proxy account and password when I am here (login)
newWin.on('login', (event, webContents, details, authInfo, callback) => {
event.preventDefault();
if (authInfo.isProxy) {
callback('sub_1kni3wjb4g9i6pkhmbsz5qzd', 'stat900')
}
});
If anyone knows how to answer it would be greatly appreciated.
I have created a createParentWindow that can invoke a createChildWindow and loads a separate html file. This createChildWindow loads my renderer.js and the renderer loads my webworker.js using Web Worker new operator for processing. Now, if I want to close the createChildWindow using close('X') button,
Does this introduce a memory leak?
Will the object created on the heap be cleaned automatically?
If there is a memory leak, how can I call my worker.terminate() to terminate my worker when the createChildWindow close('X') button is clicked?
Preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('windowExec', {
ExecFunct: () => ipcRenderer.send('asynchronous-message', 'OpenChildWindow')
})
Renderer.js
var worker = new Worker('./worker.js');
worker.addEventListener('message', function(e)
{
//..... code here
}, false);
// Stop the web worker.
function stop() {
console.log('Worker Terminated.');
worker.terminate();
worker = undefined;
}
Worker.js
const {datadecider,getosname} = require("./DatabaseWalker.node");
self.addEventListener('message', function(e)
{
var data = e.data;
switch (data.cmd)
{
case 'datadecider':
self.postMessage(datadecider(data.firstParam, data.secondParam));
break;
case 'getosname':
self.postMessage( "getosname," + getosname());
break;
case 'stop':
self.postMessage('WORKER STOPPED: ' + data.msg +
'. (buttons will no longer work)');
self.close(); // Terminates our worker.
break;
default:
self.postMessage('Unknown command: ' + data.msg);
};
}, false);
Main.js
// Create the browser child window.
function createChildWindow ()
{
singleTon = true;
datatableWindow = new BrowserWindow({
width: 1400,
height: 900,
title: 'Database',
icon: path.join(__dirname, './images/doc.ico'),
parent: parentWindow,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
nodeIntegrationInWorker: true,
enableRemoteModule: true,
contextIsolation: true
}
})
datatableWindow.loadFile('datatable.html')
datatableWindow.on('closed', function(){ // When the child windows is closed, set this to false.
singleTon = false;
datatableWindow = null;
//datatableWindow.webContents.send('destroy_childwindow', 'closed.');
console.log("Deleted datatableWindow.");
})
}
app.whenReady().then(() => {
createParentWindow()
app.on('activate', function ()
{
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0)
{
createParentWindow()
}
});
// Call the child windows when button was clicked from main renderer.
ipcMain.on('asynchronous-message', function (evt, message) {
console.log(message + " - " + singleTon);
if (message == 'OpenChildWindow' && singleTon == false)
{
createChildWindow();
}
else{
console.log("Child window is already running.");
}
})
})
// Create the browser parent window.
function createParentWindow ()
{
RunShellCommand(); // Get the OS distro name.
const parentWindow = new BrowserWindow({
width: 800,
height: 500,
title: 'Database Utility Launcher',
icon: path.join(__dirname, './images/doc.ico'),
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
nodeIntegrationInWorker: true,
enableRemoteModule: true,
contextIsolation: true
},
resizable: false
})
parentWindow.loadFile('parent.html') // Load the parent.html of the app.
parentWindow.on('closed', function(){ // Close all the window when the parent windows is closed.
app.quit();
})
}
const printWindow = new BrowserWindow({
width: 800,
height: 600,
show: false,
webPreferences: {
nodeIntegration: true,
webSecurity: false,
devTools: false,
},
dpi: 96,
});
const options = {
silent: true,
deviceName: SelectedPrinter,
}
const callback = (success, errorType) => {
if (!success) console.log(errorType)
}
printWindow.loadURL(tmpPath);
printWindow.webContents.on('did-finish-load', () => {
printWindow.webContents.print(options, callback)
})
That's my code upon, I create a document as HTML file, and load in a new BrowerWindow.
On some computer, there OS are all windows 7, doen't have callback.
It can executing the function 'webContent.print', and no callback response.
I saw printer has received an HTML file, but pages is N/A, and size is empty.
I don't know what is going on those devices, is that an OS problem or a hardware problem?
so In electron i have a parent window, and on a ipc event it opens up a child window, how would i open up the child window (which is set to a modal window) but still be able to drag the parent window? so i want the parent window of the child modal window, to still be able to be dragged even though the child window is a modal one
const { app, BrowserWindow, ipcMain } = require('electron')
let win;
let taskWin;
function createWindow() {
win = new BrowserWindow({
height: 800,
width: 1300,
webPreferences: {
nodeIntegration: true,
}
})
win.webContents.openDevTools()
win.loadFile('index.html')
win.on('closed', () => {
win = null
})
}
ipcMain.on('createTask', () => {
taskWin = new BrowserWindow({
height: 600,
width: 1000,
parent: win,
modal: true,
webPreferences: {
nodeIntegration: true,
}
})
taskWin.loadFile('createtask.html')
taskWin.on('closed', () => {
taskWin = null
})
})
app.on('ready', createWindow)
I'm using electron JS to build an app. I want to reload my app after reconnect. Need to show a loader window while reloading and hide after complete. Is there any way to do it?
I don't want to put loader inside my app. I like to show it in a separate browser window.
I'm expecting like this
BrowserWindow.on('reload-complete', (e) => {
hideLoadingWindow();
})
Finally, I got another method to overcome this situation. I'm not sure is it a good solution. but it looks simple to me.
var mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: false,
preload: path.join(app.getAppPath(), 'preload.js')
},
minWidth: 1018,
width: 640,
minHeight: 1018,
height: 640,
title: 'Electron app',
show: false
});
createLoadingWindow();
mainWindow.once('ready-to-show', () => {
mainWindow.show();
});
mainWindow.webContents.on('did-start-loading', (e) => {
createLoadingWindow();
});
mainWindow.webContents.on('did-stop-loading', (e) => {
closeLoadingWindow();
});
The event below is the correct one for you:
BrowserWindow.webContents.once('did-finish-load', (e) => {
//hideLoadingWindow();
})
the 'did-finish-load' event will be triggered after the page is reloaded.
You can use show method and then use 'dom-ready' to detect your app loading ,
let loading= new BrowserWindow({show: false, frame: false})
loading.once('show', () => {
main = new BrowserWindow({show: false})
main.webContents.once('dom-ready', () => {
console.log('main loaded')
main.show()
loading.hide()
loading.close()
})
// load your app
main.loadURL(url);
})