This content originally appeared on web.dev and was authored by Thomas Steiner
The Multi-Screen Window Placement API is part of the capabilities project and is currently in development. This post will be updated as the implementation progresses.
The Multi-Screen Window Placement API allows you to enumerate the displays connected to your machine and to place windows on specific screens.
Suggested use cases
Examples of sites that may use this API include:
- Multi-window graphics editors à la Gimp can place various editing tools in accurately positioned windows.
- Virtual trading desks can show market trends in multiple windows any of which can be viewed in fullscreen mode.
- Slideshow apps can show speaker notes on the internal primary screen and the presentation on an external projector.
Current status
Step | Status |
---|---|
1. Create explainer | Complete |
2. Create initial draft of specification | Complete |
3. Gather feedback & iterate on design | In progress |
4. Origin trial | In progress |
5. Launch | Not started |
How to use the Multi-Screen Window Placement API
Enabling via chrome://flags
To experiment with the Multi-Screen Window Placement API locally, without an origin trial token,
enable the #enable-experimental-web-platform-features
flag in chrome://flags
.
Enabling support during the origin trial phase
Starting in Chrome 86, the Multi-Screen Window Placement API will be available as an origin trial in Chrome. The origin trial is expected to end in Chrome 88 (February 24, 2021).
Origin trials allow you to try new features and give feedback on their usability, practicality, and effectiveness to the web standards community. For more information, see the Origin Trials Guide for Web Developers. To sign up for this or another origin trial, visit the registration page.
Register for the origin trial
- Request a token for your origin.
- Add the token to your pages. There are two ways to do that:
- Add an
origin-trial
<meta>
tag to the head of each page. For example, this may look something like:
<meta http-equiv="origin-trial" content="TOKEN_GOES_HERE">
- If you can configure your server, you can also add the token
using an
Origin-Trial
HTTP header. The resulting response header should look something like:
Origin-Trial: TOKEN_GOES_HERE
- Add an
The problem
The time-tested approach to controlling windows,
Window.open()
,
is unfortunately unaware of additional screens.
While some aspects of this API seem a little archaic, such as its
windowFeatures
DOMString
parameter, it has nevertheless served us well over the years. To specify a window's
position, you can pass the
coordinates as left
and top
(or screenX
and screenY
respectively) and pass the desired
size as
width
and height
(or innerWidth
and innerHeight
respectively). For example, to open a
400×300 window at 50 pixels from the left and 50 pixels from the top, this is the code that you
could use:
const popup = window.open(
"https://example.com/",
"My Popup",
"left=50,top=50,width=400,height=300"
);
You can get information about the current screen by looking at the
window.screen
property, which
returns a Screen
object. This is the
output on my MacBook Air 13″:
window.screen;
/* Output from my MacBook Air 13″:
availHeight: 975
availLeft: 0
availTop: 23
availWidth: 1680
colorDepth: 30
height: 1050
id: ""
internal: false
left: 0
orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 30
primary: false
scaleFactor: 2
top: 0
touchSupport: false
width: 1680
*/
Like most people working in tech, I have had to adapt myself to the new work reality and set up my personal home office. Mine looks like on the photo below (if you are interested, you can read the full details about my setup). The iPad next to my MacBook Air is connected to the laptop via Sidecar, so whenever I need to, I can quickly turn the iPad into a second screen.

If I want to take advantage of the bigger screen, I can put the popup from the code sample above on to the second screen. I do it like this:
popup.moveTo(2500, 50);
This is a rough guess, since there is no way to know the dimensions of the second
screen. The info from window.screen
only covers the built-in screen, but not the iPad screen.
The reported width
of the built-in screen was 1680
pixels, so moving to
2500
pixels might work to shift the window over to the iPad, since I happen to know that it is
located on the right of my MacBook Air. How can I do this in the general case? Turns out, there is a
better way than guessing. That way is the Multi-Screen Window Placement API.
Feature detection
To check if the Multi-Screen Window Placement API is supported, use:
if ("getScreens" in window) {
// The Multi-Screen Window Placement API is supported.
}
The window-placement
permission
Before I can use the Multi-Screen Window Placement API, I must ask the user for permission to do so.
The new window-placement
permission can be queried with the
Permissions API like so:
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: "window-placement" });
granted = state === "granted";
} catch {
// Nothing.
}
The browser can choose to show the permission prompt dynamically upon the first attempt to use any of the methods of the new API. Read on to learn more.
The isMultiScreen()
method
To use the the Multi-Screen Window Placement API, I will first call the
Window.isMultiScreen()
method. It returns a promise that resolves with either true
or false
,
depending on whether one or multiple screens are currently connected to the machine. For my setup,
it returns true
.
await window.isMultiScreen();
// Returns `true` or `false`.
The getScreens()
method
Now that I know that the current setup is multi-screen, I can obtain more
information about the second screen using Window.getScreens()
. It returns a promise
that resolves with an array of Screen
objects. On my MacBook Air 13 with a connected iPad, this
returns an array of two Screen
objects:
await window.getScreens();
/* Output from my MacBook Air 13″ with the iPad attached:
Screen 1 (built-in display):
availHeight: 975
availLeft: 0
availTop: 23
availWidth: 1680
colorDepth: 30
height: 1050
id: "0"
internal: true
left: 0
orientation: null
pixelDepth: 30
primary: true
scaleFactor: 2
top: 0
touchSupport: false
width: 1680
Screen 2 (iPad):
availHeight: 1001
availLeft: 1680
availTop: 23
availWidth: 1366
colorDepth: 24
height: 1024
id: "1"
internal: false
left: 1680
orientation: null
pixelDepth: 24
primary: false
scaleFactor: 2
top: 0
touchSupport: false
width: 1366
*/
Note how the value of left
for the iPad starts at 1680
, which is exactly the width
of the
built-in display. This allows me to determine exactly how the screens are arranged logically (next
to each other, on top of each other, etc.). There is also data now for each screen to show whether
it is an internal
one and whether it is a primary
one.
Note that the built-in screen
is not necessarily the primary screen.
Both also have an id
, which, if
persisted across browser sessions, allows for window arrangements to be restored.
The screenschange
event
The only thing missing now is a way to detect when my screen setup changes. A new event,
screenschange
, does exactly that: it fires whenever the screen constellation
is modified.
(Notice that "screens" is plural in the event name.)
It also fires when the resolution of one of the connected screens changes or when a
new or an existing screen is (physically or virtually in the case of Sidecar) plugged in or unplugged.
Note that you need to look up the new screen details asynchronously, the screenschange
event
itself does not provide this data. This may change in the
future. For now you
can look up the screen details by calling window.getScreens()
as shown below.
window.addEventListener('screenschange', async (event) => {
console.log('I am there, but mostly useless', event);
const details = await window.getScreens();
});
New fullscreen options
Until now, you could request that elements be displayed in fullscreen mode via the aptly named
requestFullScreen()
method. The method takes an options
parameter where you can pass
FullscreenOptions
. So far, its only property has been
navigationUI
.
The Multi-Screen Window Placement API adds a new screen
property that allows you to determine
which screen to start the fullscreen view on. For example, if you want to make the primary screen fullscreen:
try {
const primaryScreen = (await getScreens()).filter((screen) => screen.primary)[0];
await document.body.requestFullscreen({ screen: primaryScreen });
} catch (err) {
console.error(err.name, err.message);
}
Polyfill
It is not possible to polyfill the Multi-Screen Window Placement API, but you can shim its shape so you can code exclusively against the new API:
if (!("getScreens" in window)) {
// Returning a one-element array with the current screen,
// noting that there might be more.
window.getScreens = async () => [window.screen];
// Returning `false`, noting that this might be a lie.
window.isMultiScreen = async () => false;
}
The other aspects of the API—the onscreenschange
event and the screen
property of the
FullscreenOptions
—would simply never fire or silently be ignored respectively by non-supporting
browsers.
Demo
If you are anything like me, you keep a close eye on the development of the various cryptocurrencies. (In reality I very much do not, but, for the sake of this article, just assume I do.) To keep track of the cryptocurrencies that I own, I have developed a web app that allows me to watch the markets in all life situations, such as from the comfort of my bed, where I have a decent single-screen setup.

This being about crypto, the markets can get hectic at any time. Should this happen, I can quickly move over to my desk where I have a multi-screen setup. I can click on any currency's window and quickly see the full details in a fullscreen view on the opposite screen. Below is a recent photo of me taken during the last YCY bloodbath. It caught me completely off-guard and left me with my hands on my face.

You can play with the demo embedded below, or see its source code on glitch.
Security and permissions
The Chrome team has designed and implemented the Multi-Screen Window Placement API using the core principles defined in Controlling Access to Powerful Web Platform Features, including user control, transparency, and ergonomics. The Multi-Screen Window Placement API exposes new information about the screens connected to a device, increasing the fingerprinting surface of users, especially those with multiple screens consistently connected to their devices. As one mitigation of this privacy concern, the exposed screen properties are limited to the minimum needed for common placement use cases. User permission is required for sites to get multi-screen information and place windows on other screens.
User control
The user is in full control of the exposure of their setup. They can accept or decline the permission prompt, and revoke a previously granted permission via the site information feature in the browser.
Transparency
The fact whether the permission to use the Multi-Screen Window Placement API has been granted is exposed in the browser's site information and is also queryable via the Permissions API.
Permission persistence
The browser persists permission grants. The permission can be revoked via the browser's site information.
Feedback
The Chrome team wants to hear about your experiences with the Multi-Screen Window Placement API.
Tell us about the API design
Is there something about the API that does not work like you expected? Or are there missing methods or properties that you need to implement your idea? Have a question or comment on the security model?
- File a spec issue on the corresponding GitHub repo, or add your thoughts to an existing issue.
Report a problem with the implementation
Did you find a bug with Chrome's implementation? Or is the implementation different from the spec?
- File a bug at new.crbug.com. Be sure to include as much detail as you
can, simple instructions for reproducing, and enter
Blink>WindowDialog
in the Components box. Glitch works great for sharing quick and easy repros.
Show support for the API
Are you planning to use the Multi-Screen Window Placement API? Your public support helps the Chrome team to prioritize features and shows other browser vendors how critical it is to support them.
- Share how you plan to use it on the WICG Discourse thread
- Send a tweet to @ChromiumDev with the
#WindowPlacement
hashtag and let us know where and how you are using it. - Ask other browser vendors to implement the API.
Helpful links
- Spec draft
- Public explainer
- Multi-Screen Window Placement API demo | Multi-Screen Window Placement API demo source
- Chromium tracking bug
- ChromeStatus.com entry
- Blink Component:
Blink>WindowDialog
Wanna go deeper
Acknowledgements
The Multi-Screen Window Placement API spec was edited by Victor Costan and Joshua Bell. The API was implemented by Mike Wasserman. This article was reviewed by Joe Medley, François Beaufort, and Kayce Basques. Thanks to Laura Torrent Puig for the photos.
This content originally appeared on web.dev and was authored by Thomas Steiner

Thomas Steiner | Sciencx (2020-09-14T00:00:00+00:00) Managing several displays with the Multi-Screen Window Placement API. Retrieved from https://www.scien.cx/2020/09/14/managing-several-displays-with-the-multi-screen-window-placement-api/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.