How to set the devTools window position in electron - electron

I got this from the docs
app.on('ready', function(){
devtools = new BrowserWindow()
window = new BrowserWindow({width:800, height:600})
window.loadURL(path.join('file://', __dirname, 'static/index.html'))
window.webContents.setDevToolsWebContents(devtools.webContents)
window.webContents.openDevTools({mode: 'detach'})
})
It opens two windows, on is the dev tools. But it's exactly underneath the main window.
Is there a way to get them side by side (the screen is big enough)?

Once you've called setDevToolsWebContents then you can move the devtools window around just by calling devtools.setPosition(x, y).
Here is a example of moving the devtools next to the window by setting it's position whenever it's moved:
app.on('ready', function () {
var devtools = new BrowserWindow();
var window = new BrowserWindow({width: 800, height: 600});
window.loadURL('https://stackoverflow.com/questions/52178592/how-to-set-the-devtools-window-position-in-electron');
window.webContents.setDevToolsWebContents(devtools.webContents);
window.webContents.openDevTools({mode: 'detach'});
// Set the devtools position when the parent window has finished loading.
window.webContents.once('did-finish-load', function () {
var windowBounds = window.getBounds();
devtools.setPosition(windowBounds.x + windowBounds.width, windowBounds.y);
});
// Set the devtools position when the parent window is moved.
window.on('move', function () {
var windowBounds = window.getBounds();
devtools.setPosition(windowBounds.x + windowBounds.width, windowBounds.y);
});
});

Related

Close all windows on Reload on an Electron Application

I have an electron desktop application which opens 2 new windows when I load it, the code to open the new windows is this:
electron = require('electron')
win = electron.remote.getCurrentWindow();
BrowserWindow = electron.remote.BrowserWindow;
wind = new BrowserWindow({
width: 400,
height: 200,
x:3,
y:12,
frame: false,
// transparent: true,
alwaysOnTop: true, // Add this line
// skipTaskbar:true, // don't show icon on taskbar
opacity:0.9,
})
Now when I'm testing my application, I use the Reload command a lot (ctrl+R on windows). My problem is that when I do it, the windows remain open and it opens more windows on top of it.
How can I make Reload close all windows?
The onbeforeunload event is triggered (In the renderer) when a window is closed or reloaded. You can use this to close the individual window.
Otherwise you can inform electron via a IPC message to close all your windows for you.
Something like this should do the job.
// renderer/index.js
const {ipcRenderer} = require('electron')
ipcRenderer.send('my-closeallwindowsasap-channel') // can have arguments
// -------------------------------------------------------
// main/index.js
ipcMain.on('my-closeallwindowsasap-channel', (event, arg) => {
BrowserWindow.getAllWindows().forEach(window => {
window.close()
})
})

How to restore default window size in an electron app?

Is there a way to restore main window in an electron app to a certain size? To explain what I am trying to accomplish, let me give you an example:
When I open Windows Explorer, it opens with a certain size and at a certain position. Then I maximize that window and close the explorer. Next time when I restart the explorer, it opens in the same state as when I closed it i.e. in maximized state. However when I click on the restore button, explorer restores to the width/height and position before it was maximized.
I would like to accomplish the same in my electron application as well. However that is not happening.
What I am doing is when my application closes, I capture the dimensions (width, height) and position (x, y coordinates) of the application window using (win.getBounds())and save those in a config file using electron-config. This is what my code looks like:
const Config = require('electron-config')
const config = new Config();
mainWindow.on('close', () => {
config.set('winBounds', mainWindow.getBounds())
});
Now when I start the application, I read the settings from the config file (actually electron-config does that for me) and use that to set the initial dimensions/position of the window. I am using code like below:
let opts = {
show: false,
icon: path.join(__dirname, 'app-window-icon.png')
};
Object.assign(opts, config.get('winBounds'));
mainWindow = new BrowserWindow(opts);
This is also working great. However the only option I get now is maximize the window. I'm not able to find any option to restore the window to a size before it was maximized.
For example, let's say the user launches the application with 1024x768 px dimensions. User then maximizes the application window and then closes it. When the user relaunches the application, it opens with the size it was closed and the only option I see is to maximize the window. What I am looking for is an option to restore the window size to 1024x768px.
I looked up the documentation here: https://github.com/electron/electron/blob/master/docs/api/browser-window.md but unfortunately couldn't find anything there.
I used the solution here which involves persisting your windows size and position in electron-settings and it works perfectly.
Include the windowStateKeeper function in your code and then adapt your createMainWindow function as follows:
function createMainWindow() {
const mainWindowStateKeeper = windowStateKeeper('main');
const win = new electron.BrowserWindow({
title: 'main',
x: mainWindowStateKeeper.x,
y: mainWindowStateKeeper.y,
width: mainWindowStateKeeper.width,
height: mainWindowStateKeeper.height
});
mainWindowStateKeeper.track(win);
win.loadURL(`file://${__dirname}/index.html`);
win.on('closed', onClosed);
return win;
}
Here is complete solution:
stateKeeper.ts:
import {screen} from 'electron';
import settings from 'electron-settings';
export const windowStateKeeper = async (windowName) => {
let window, windowState;
const setBounds = async () => {
// Restore from appConfig
if (await settings.has(`windowState.${windowName}`)) {
windowState = await settings.get(`windowState.${windowName}`);
return;
}
const size = screen.getPrimaryDisplay().workAreaSize;
// Default
windowState = {
x: undefined,
y: undefined,
width: size.width / 2,
height: size.height / 2,
};
};
const saveState = async () => {
// bug: lots of save state events are called. they should be debounced
if (!windowState.isMaximized) {
windowState = window.getBounds();
}
windowState.isMaximized = window.isMaximized();
await settings.set(`windowState.${windowName}`, windowState);
};
const track = async (win) => {
window = win;
['resize', 'move', 'close'].forEach((event) => {
win.on(event, saveState);
});
};
await setBounds();
return {
x: windowState.x,
y: windowState.y,
width: windowState.width,
height: windowState.height,
isMaximized: windowState.isMaximized,
track,
};
};
main.ts
import {windowStateKeeper} from './utils/windowStateKeeper';
const mainWindowStateKeeper = await windowStateKeeper('main');
// Create the browser window.
mainWin = new BrowserWindow({
title: 'Desktop',
x: mainWindowStateKeeper.x,
y: mainWindowStateKeeper.y,
width: mainWindowStateKeeper.width,
height: mainWindowStateKeeper.height,
webPreferences: {
nodeIntegration: true,
allowRunningInsecureContent: serve ? true : false,
contextIsolation: false, // false if you want to run e2e test with Spectron
enableRemoteModule: true, // true if you want to run e2e test with Spectron or use remote module in renderer context (ie. Angular)
},
});
// Track window state
mainWindowStateKeeper.track(mainWin);
I implemented this after a lot of testing this is the most accurate and simple solution to remember window properties.
i used electron-store to store values, you can use any storage methods you like.
main.js
let windowConfig = {
width: 1280,
height: 680,
}
function createWindow() {
Object.assign(windowConfig, CONFIG.get("winBounds"))
mainWindow = new BrowserWindow(windowConfig)
if (windowConfig.isMaximized) {
mainWindow.maximize()
}
mainWindow.on("close", () => {
Object.assign(windowConfig, {
isMaximized: mainWindow.isMaximized()
}, mainWindow.getNormalBounds())
CONFIG.set("winBounds", windowConfig) // saves window's properties using electron-store
})
}

Electron app across 2 displays?

Can an electron app run one window across 2 monitors? I'm not able to drag the edge across to the other monitor. is this possible?
I know I can do this to access the second screen.
const electron = require('electron')
const {app, BrowserWindow} = require('electron')
let win
app.on('ready', () => {
let displays = electron.screen.getAllDisplays()
let externalDisplay = displays.find((display) => {
return display.bounds.x !== 0 || display.bounds.y !== 0
})
if (externalDisplay) {
win = new BrowserWindow({
x: externalDisplay.bounds.x + 50,
y: externalDisplay.bounds.y + 50
})
win.loadURL('https://github.com')
}
})
however, I dont want 2 windows just one across 2 displays.
You can drag the electron window like any other window.
If you want to set the window size, you either do it when a BrowserWindow is created or via BrowserWindow.setSize() to modify the size see BrowserWindow docs
That was real problem, that it was impossible to set via BrowserWindow.setSize() values gather than height and width of first screen, to open window stretched on few screens
But finally I have found, the solution is
BrowserWindow.setMinimumSize(W, H);
that allows to set width, like 10`000px, for few monitors, and it will be applied unlike setSize

Reusable Panel from hiddenDOMWindow

I have a CustomizableUI.jsm button i add to the toolbar. On click of this it opens a panel which has a chrome page loaded.
I want all windows to open this same panel. So my thought was to add the panel to Services.appShell.hiddenDOMWindow and then open it anchored to the the CustomizableUI.jsm button.
However I'm having trouble adding the panel to the hidddenDOMWindow.
This code works fine from scratchpad if you make the first line be var win = window. But if you make it be var win = Services.appShell.hiddenDOMWindow it has trouble appending the panel to the popupset. So weird.
Code here is the appShell hidden window code. If you make it var win= window it works fine:
var win = window; //Services.appShell.hiddenDOMWindow;
var panel = win.document.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul','panel');
var props = {
type: 'arrow',
style: 'width:300px;height:100px;'
}
for (var p in props) {
panel.setAttribute(p, props[p]);
}
var popupset = win.document.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul','popupset');
popupset.appendChild(panel);
win.document.documentElement.appendChild(popupset);
panel.addEventListener('popuphiding', function (e) {
e.preventDefault();
e.stopPropagation();
//panel.removeEventListener('popuphiding', arguments.callee, false); //if dont have this then cant do hidepopup after animation as hiding will be prevented
panel.addEventListener('transitionend', function () {
panel.hidePopup(); //just hide it, if want this then comment out line 19 also uncomment line 16
//panel.parentNode.removeChild(panel); //remove it from dom //if want this then comment out line 18
}, false);
panel.ownerDocument.getAnonymousNodes(panel)[0].setAttribute('style', 'transform:translate(0,-50px);opacity:0.9;transition: transform 0.2s ease-in, opacity 0.15s ease-in');
}, false);
panel.openPopup(window.document.documentElement, 'overlap', 100, 100);

Titanium: WebView using Navigation Bar

I'm using Titanium.
I am trying to show web page with navigation bar.
I want to put Back button at the top left position inside navigation bar which works as browser's back.
Below is my current code.
Could anybody help me with this??
Thanks in advance.
var w = Titanium.UI.createWindow({
backgroundColor:'#fff',
leftNavButtonLabel:'back',});
var navGroup = Ti.UI.iPhone.createNavigationGroup({
window:w
});
var backBtn = Titanium.UI.createButton({
title:'Back',
style:Titanium.UI.iPhone.SystemButtonStyle.BORDERED
});
var webView = Titanium.UI.createWebView({
url : 'http://gooogle.com',
canGoBack : true,
});
backBtn.addEventListener( 'click', function() {
webview.goBack();
});
w.add.setLeftNavButton(backBtn);
w.add(webView);
w.add(navGroup);
w.open();
w.navGroup.open();
Try, This... or
var main_win = Ti.UI.createWindow({
});
var w = Titanium.UI.createWindow({
backgroundColor:'#fff',
leftNavButtonLabel:'back',
});
var navGroup = Ti.UI.iPhone.createNavigationGroup({
window:w
});
var backBtn = Titanium.UI.createButton({
title:'Back',
style:Titanium.UI.iPhone.SystemButtonStyle.BORDERED
});
var webView = Titanium.UI.createWebView({
url : 'http://gooogle.com',
canGoBack : true,
});
backBtn.addEventListener( 'click', function() {
webview.goBack();// Goes back one entry in the web view's history list. to the previous page.
});
w.add.setLeftNavButton(backBtn);
w.add(webView);
main_win.add(navGroup);
main_win.open();
for Navigation new window
navGroup.open(Window name);
for Closing last open window;
navGroup.close(Window name);

Resources