I created a very simple site to create a popup on my second screen.
The Multi-Screen Window Placement Api promises to do the trick, but i am not able to make it work.
I get all the informations about both screens, but cant open the popup on the correct display.
Does anyone have an idea? Is it because of the "window-placement" permission or something?
Here is the simple site I made:
<!DOCTYPE html>
<html>
<title>Window Placement</title>
<head>
<script type="text/javascript">
let url = "file:///C:/Users/path/to/file.html";
let x = "1000";
let y = "250";
let width = "250";
let height = "250";
let popup;
async function screenDetails() {
if (window.screen.isExtended) {
console.log("Multiple screens detected");
try {
const screens = await window.getScreenDetails();
let primary;
let second;
for (let element of screens.screens) {
if (element.isPrimary) {
primary = element;
} else {
second = element;
}
}
let features = "left=" + x + ",top=" + y +
",width=" + width + ",height=" + height;
popup = window.open(url, 'Popup', features);
} catch (err) {
console.error(err);
}
} else {
console.log("Single screen detected");
}
}
</script>
</head>
<body>
<button type="button" onclick="open()">Open</button>
</body>
</html>
So, I got it to work, albeit not in the Stack Snippet environment I'm providing the code in.
It does indeed have to do with permissions; you must ask for permission to get screen details. In the code below, I created a new function which will query for doing this, getPermissionAndScreenDetails in the code below. It verifies the API is available, that the permission is present and not denied (it is automatically 'denied' in a Stack Snippet for security reasons). It then returns the result of calling window.getScreenDetails() as that is necessary to get permission if the state is set to 'prompt'.
I altered your function to use that function's return value.
I also added some code that will open the popup in the middle of the first secondary screen it finds.
let url = "about:blank";
let x = "1000";
let y = "250";
let width = "250";
let height = "250";
let popup;
async function getPermissionAndScreenDetails() {
if ('getScreenDetails' in window) {
let granted = false;
try {
const permission = await navigator.permissions.query({
name: 'window-placement'
});
console.log(permission, permission.state);
if (permission.state !== 'denied') {
return window.getScreenDetails();
} else {
return null;
}
} catch {
// Nothing.
return null;
}
} else {
return null;
}
}
async function screenDetails() {
const screens = await getPermissionAndScreenDetails();
if (screens != null && window.screen.isExtended) {
console.log("Multiple screens detected");
try {
console.log(screens);
let primary;
let secondaries = [];
for (let element of screens.screens) {
if (element.isPrimary) {
primary = element;
} else {
secondaries.push(element);
}
}
console.log('primary: ', primary);
console.log('secondaries: ', secondaries);
// find secondary screen we can place the popup on
const secondary = secondaries[0];
x = secondary.left + (secondary.availWidth / 2) - (width / 2);
y = secondary.top + (secondary.availHeight / 2) - (height / 2);
let features = "left=" + (second.left + 1000) + ",top=" + (second.top + 400) +
",width=" + width + ",height=" + height;
popup = window.open(url, 'Popup', features);
} catch (err) {
console.error(err);
}
} else {
console.log("Single screen detected (or permission not granted)");
}
}
document.getElementById("open").addEventListener('click', screenDetails);
<button type="button" id="open">Open</button>