Electron/Javascript: Detect when window is un/maximized - javascript

I am creating an electron application with a custom window bar in place of the default Windows one. I need to know when the window is maximized or un-maximized in order to change the icon on the window bar to reflect the window's state.

maximize / unmaximized event is availble for browserwindow. https://github.com/electron/electron/blob/master/docs/api/browser-window.md#event-maximize

you can use:
const { remote } = require("electron");
var win = remote.BrowserWindow.getFocusedWindow();
if(win.isFullScreen()) {
// your code here
}
or :
const { remote } = require("electron");
var win = remote.BrowserWindow.getFocusedWindow();
if(win.isMaximized()) {
// your code here
}

Related

Is there a way to watch screenX and screenY positions and have a method run when they change?

I am trying to run a method whenever the screenX or screenY position of a rendered window changes. I have set up a a default value for these positions in my data section here:
data() {
return {
initialX: window.screenX,
initialY: window.screenY
};
},
I have computed properties here:
currentPopupX() {
return window.screenX;
},
currentPopupY() {
return window.screenY;
}
},
Finally, I have a watch set up here:
watch: {
currentPopupX() {
if (this.currentPopupX !== this.initialX) {
movePopup(this.popup, this.currentPopupX, this.currentPopupY);
}
},
currentPopupY() {
if (this.currentPopupY !== this.initialY) {
movePopup(this.popup, this.currentPopupX, this.currentPopupY);
}
},
However the computed property seems to only return on initial render and does not update after that. Is there something I am missing?
I have tried comparing initial data to computed properties in the watch expecting for the method to be executed on change, however it never changes.
Note:
The rendered window is a popup notification. A user wants to drag that notification to a new location (currently it renders in the center of the screen) and have that popup render in the position they dragged it to the next time it is rendered. For additional context, I'm trying to grab the new positions to pass them along to an IPC event.
At my opinion, you have to use an interval to detect the browser position since there's no window move event.
if the browser position.x or the browser position.y change, you may dispatch a custom event.
The event here when you move the window will change the color of the text from black to red.
const event = new CustomEvent("browserMove",{ detail: "browserPosition" });
window.addEventListener("browserMove", onBrowserMove);
let moveTimer=null;
let content=null;
let oldX = 0;
let oldY = 0;
document.addEventListener("DOMContentLoaded",onReady);
function onReady(e){
content = document.getElementById("content");
oldX = window.screenX;
oldY = window.screenY;
moveTimer = setInterval(detectBrowserMove,200);
}
function detectBrowserMove(){
let r = browserPosition();
if(r.x !== oldX || r.y !== oldY){
// dispatch an event here
window.dispatchEvent(event);
oldX = window.screenX;
oldY = window.screenY;
}
content.innerHTML = ("browser.x = " + r.x + ", browser.y = " + r.y);
}
function browserPosition() {
let position={};
position = {x:window.screenX, y:window.screenY};
return(position);
}
function onBrowserMove(e){
// write your code here
let x = window.screenX;
let y = window.screenY;
content.style.color="#ff0000";
}
<div id="content">
</div>
If I catch your problem correctly, you are saying that-
A notification window will open in the center by default. The user can
drag it anywhere and when next time the notification window will appear, it should pop up at the position where the user last dragged it.
If we take the problem in some other way, you need the last dragged position of the window to send to the API for the next time opening. So, instead of checking the window's position every time why not check for only the last/latest position before it closes?
What I mean is-
Let the notification window open.
Attach a unload listener to it.
Drag it anywhere you want multiple times.
When the window is about to close, look into the listener, and grab the latest position.
Here is how you can do it in Vue-
Create a window data variable in your Vue and assign your newly opened window object to it-
data() {
return {
// Save notification window object to this data property
vue_window: null;
}
}
Apply a watcher that when vue_window has some value, set a listener to it-
watch: {
vue_window(newVal) {
// Only if vue_window variable has some value
if (newVal) {
// this will fire when the window is about to close
newVal.onunload = () => {
// Here are the latest screen positions of the window
console.log(this.vue_window.screenX, this.vue_window.screenY);
};
}
},
},
That's it. When the window will be about to close, you will have the last and latest position of the window which you can save wherever you want.
Here is the demo of this logic- CodeSandBox Link
I couldn't create a snippet because the window is not opening in the snippet environment. I will add the snippet if found any solution to work with the window obj.

Remove scaled up setting from device settings in React Native app

How can I disable the display setting changes in the device settings?
I solved the font side of the same problem with the following code:
if (Text.defaultProps) {
Text.defaultProps.allowFontScaling = false
} else {
Text.defaultProps = {}
Text.defaultProps.allowFontScaling = false
View.defaultProps = {}
}
but I can't do the same for 'Display Settings'.
here is my ask screen on phone settings:
I hope that has been revealing

Electron - close renderer from main handler

TLDR: Best way to close a renderer window from main (or the renderer itself).
I am splitting up a process between X invisible renderer windows. When a renderer finishes its work, I want it to send an event to the main process and then close. Right now I have
//invisibleRenderer.js
doStuff().then(() => {
ipcRenderer.invoke('finish');
}
What is the best way to close the window? Is it in the ipcMain.handle? I can't figure out which method to call with which id.
ipcMain.handle('finish', (event, args) => {
//do what? event.frameId, event.processId, event.sender.id...
})
You can use BrowserWindow.fromId(event.sender.id) to get a reference to the window from where the IPC call originated, as demonstrated in this question.
This works fine in the main process. The following example opens 5 windows and loads the same contents. Each renderer script invocation picks a random delay (to simulate some work) and then dispatches the finish message to the main process. There, the main process picks up the BrowserWindow reference using event.sender.id and closes the corresponding window.
app.js
const {app, BrowserWindow, ipcMain} = require("electron");
const windows = [];
app.on("ready", function() {
for (let i=0; i<5; i++) {
let win;
win = new BrowserWindow( {
width: 300,
height: 300,
x: i*100,
y: i*100,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
},
});
win.loadURL(`file://${__dirname}/index.html`);
windows.push(win);
}
});
ipcMain.handle("finish", (event, args) => {
const win = BrowserWindow.fromId(event.sender.id);
win.close();
});
index.html
<html>
<body>
Renderer
</body>
<script type="text/javascript" src="renderer.js"></script>
</html>
renderer.js
const {ipcRenderer} = require("electron");
// Simulate some work by choosing a random delay..
const delay = Math.round(Math.random()*10000);
setTimeout(() => ipcRenderer.invoke("finish"), delay);

WkWebview javascript animation froze when screen locked

Xcode 12.3 iOS 12.4+ iPhone Application
I have a view controller which contains wkwebview which gets initialized on startup. This is on the framework side. An enclosing app adds this view onto their view controller as a subview. The app is purely HTML and javascript-based app. We render HTML pages based on user interaction. Everything works fine except for an issue with the Lock Screen
On a particular screen, there is some animation running while updating some values on the screen as well. When the app is moved to the background, the app runs fine but when I Lock the Screen and come back to the app, the animation and all processing on the screen are frozen. I would have to start the process back from the home screen.
I noticed that both moving to background and lock screen have the same state changes such as did enter the background and will enter foreground but in one case, everything is frozen. Could someone please let me know what might be the problem and what would be a solution in this scenario?
Thank you.
Edit
This is the animation called on the html page...the screen is expecting some values which is sent from framework once done processing
let showNextItemJS = """
function startNextAnimation() {
var box = document.querySelector('\(boxElement)');
if(box) {
var thisItem = box.querySelector('\(diagnosticItem)');
var statusStr = '\(statusStr)'
if (thisItem) {
thisItem.classList.add('start');
if (statusStr != 'none') {
thisItem.classList.add(statusStr);
}
}
} else {
var thisItem = document.querySelector('\(diagnosticItem)');
var statusStr = '\(statusStr)'
if (thisItem) {
thisItem.classList.add('start');
if (statusStr != 'none') {
thisItem.classList.add(statusStr);
}
}
}
};
function stopLastAnimaation() {
var box = document.querySelector('\(boxElement)');
if(box) {
var lastItem = box.querySelector('\(lastDiagnosticItem)');
if (lastItem) {
lastItem.classList.add('finish');
}
} else {
var lastItem = document.querySelector('\(lastDiagnosticItem)');
if (lastItem) {
lastItem.classList.add('finish');
}
}
};
startNextAnimation()
stopLastAnimaation()
"""
callJavaScript(showNextItemJS)

Why window.open displays a blank screen in a desktop PWA (looks obfuscated)?

On an installed Desktop PWA, since Chrome 73 (on MacOS) when I do a window.open() on a click event with a regular URL, the page loads fully but the window is blank.
It looks obfuscated but there's no overlay tag of anything visible (everything is OK in the devtools's console and network tabs)
I tried with the default Chrome theme, both with Mojave's dark an light mode.
The HTML markup:
<a href="https://jakearchibald.github.io/svgomg/" data-index="2" data-category="svg" rel="noopener noreferrer" class="data-app-button">
<span class="app-name">SVGOMG</span>
</a>
The JavaScript:
// clicks
document.addEventListener(
"click",
function (event) {
if (event.target.closest("[data-app-index]")) {
let appID = event.target.closest("[data-app-index]").getAttribute("data-app-index");
return openApp(appID);
}
},
false
);
// openApp() - a regular window.open()
const openApp = appID => {
event.preventDefault();
// get app options
let appOptions = State.appList[appID];
appOptions.window = appOptions.window || {};
// merge with defaults
let defaultWindow = State.getDefaultWindow;
let options = Object.assign({}, defaultWindow, appOptions.window);
// center window
options.left = screen.width / 2 - options.width / 2;
options.top = screen.height / 2 - options.height / 2;
// translate to window.open args
let args = [];
for (let [key, val] of Object.entries(options)) args.push(`${key}=${val}`);
args = args.join(",");
// open app
return window.open(appOptions.url, appOptions.name, args);
};
Before updating to Chrome 73 everything worked as expected: the window.open() function displayed the web page correctly.
Now the window opens but nothing is visible.
OK I think I found the solution: I noticed that right after the window was open, the parent window (PWA) got the focus back. So it behaved like a pop-under. As pop-under are a really bad/malicious practice I think Chrome is blocking the child popup window.
So I removed the return statement on the event callback:
// I changed this:
return openApp(appID);
// to this:
openApp(appID);
It seems that the parent window do not steal the focus anymore and the popup content is displayed correctly.

Categories

Resources