JavaScript Window Management Table

PieceWhat it doesField note
window.getScreenDetails()The ensemble callone promise behind the window-management permission - resolve it once, keep the ScreenDetails object for the session
ScreenDetailsThe live inventorythe whole display set plus your own location on it, with change events attached - the object is the session, not a snapshot
details.screens[]The screen arrayone ScreenDetailed per connected display: label, left/top/width/height bounds, devicePixelRatio - rebuild layout from this after any change
ScreenDetailed.isPrimary / isInternalThe identity flagsprimary display versus not, laptop panel versus external - the facts that let a console remember which physical monitor is which
details.currentScreenThe self-locationthe screen this window occupies right now - the presenter-console fact: notes here, slides there
screen.isExtendedThe free tiersynchronous boolean on the classic screen object, no permission - the cheap check before you spend a prompt
screenschange / currentscreenchangeThe two tickershardware set changed versus this window moved - rebuild the array on one, re-highlight your panel on the other
the permission gateThe fingerprint taxscreen topology is a superb fingerprint, so the prompt is deliberate - denial is a normal product state, not an error
Reference: the MDN Window Management API, ScreenDetails and ScreenDetailed. One call returns the whole display ensemble, your place in it, and the events that keep both honest.
Bottom line: screen.isExtended first, getScreenDetails() behind a button, catch the rejection into a single-screen layout, attach both change listeners the moment the promise resolves, and debounce screenschange bursts from waking docks.
Related tools: the fullscreen table (put content on the screen you have), the presentation table (send a receiver page to another screen), the screen capture table (pixels instead of topology), the permissions table (the grant model behind the prompt), and the wake lock table (keep the display alive while you show).

The Window Management API is the answer to a question web apps could never ask before: which physical screens does this user have, and which one is my window on right now? Before it, window.screen described only the current screen, multi-monitor setups were invisible, and a trading dashboard or kiosk system had to guess where its windows landed. window.getScreenDetails() returns a live ScreenDetails object - the full display ensemble with per-screen facts (label, bounds, devicePixelRatio, internal-versus-external, which one is primary) plus the screen your window currently occupies - and the API keeps you updated as screens plug in, unplug, or your windows hop between them.

Bottom line: one call, one collection, two events. getScreenDetails() (from a secure context, behind a permission prompt that typically rides on a user gesture) resolves ScreenDetails; details.screens is the array of every display as a ScreenDetailed object, details.currentScreen is the one your window is on now, and the two events keep both answers fresh - screenschange when the physical set changes, currentscreenchange when your window moves. The everyday companion is screen.isExtended: a synchronous boolean on the classic screen object that answers just the is-there-a-second-monitor question without the prompt, perfect for deciding whether to even show a multi-screen UI.

The honest scope: this is a Chromium-led API for control-room-class web apps - trading dashboards, POS and kiosk systems, stream decks, presenter consoles that put speaker notes on one screen and slides on another - and it stops exactly where the OS begins: it observes and reports screens, it does not (by itself) move windows for you; window placement still goes through window.open features, fullscreen, or the browser UI. Permission is deliberately conservative because screen topology is a fingerprinting goldmine: expect a prompt, gate the call behind a button, and degrade gracefully when the user declines - isExtended and plain window.screen still work without any grant.

How to use

  1. Cheap-check first: if (screen.isExtended) offer the multi-screen features; the synchronous boolean needs no permission and tells you whether the full API is worth a prompt at all.
  2. Ask behind a button: detailsBtn.onclick = async () => { const d = await window.getScreenDetails(); render(d); } - first call surfaces the window-management permission prompt; denied means fall back to single-screen UI, never an error toast.
  3. Enumerate and place by name: d.screens.forEach(s => console.log(s.label, s.width, s.height, s.left, s.top, s.isPrimary, s.isInternal)) - labels are human-readable (for example the monitor model string) and bounds are desktop coordinates you can reason about.
  4. Track your own window: d.addEventListener('currentscreenchange', () => highlightScreen(d.currentScreen)) - the screen your window sits on changes when the user drags it, and your in-window UI should follow.
  5. React to hardware changes: d.addEventListener('screenschange', e => rebuildLayout(d.screens)) - monitors hot-plug mid-presentation; a projector vanishing should reflow your console, not crash it.

Frequently asked questions

What exactly does getScreenDetails() give me that window.screen never did?

window.screen is a single-screen snapshot: it describes whichever display your window happens to be on - its dimensions, its availHeight, its devicePixelRatio - and stays silent about everything else. getScreenDetails() returns the whole ensemble. ScreenDetails carries: screens, an array of ScreenDetailed objects - one per connected display, each with its own label, left/top/width/height bounds in desktop coordinates, devicePixelRatio, color depth, and the isPrimary and isInternal flags (primary display versus the screen your OS designates, internal laptop panel versus external monitor); currentScreen, the ScreenDetailed your window occupies right now; and the two change events. Two practical consequences. First, layout math becomes real: knowing each screen is at left 0 and 1920 versus left 1920 means you can reason about a two-display desktop as one coordinate space instead of guessing. Second, identity becomes real: labels let a presenter console remember that the HDMI monitor shows slides while the laptop shows notes - preferences pinned to a physical screen instead of to the window you dragged last. And the boundary to respect: the API reports the desktop as the OS sees it (including workarea exclusions on some platforms), but it gives you no power to open, move or size windows beyond what window.open and the browser already allow - it is situational awareness, not a window manager.

How do the permission gate and privacy story actually work?

The call sits behind the window-management permission: first getScreenDetails() surfaces a prompt (browsers typically want a user gesture in the call chain), and denying it makes the promise reject - your code should catch and run a single-screen layout, not surface an exception. The reason browsers gate this hard is that screen topology is a superb fingerprint: two external monitors at specific resolutions and positions narrows a user to one desk in the world, so the same information that makes kiosk dashboards possible makes drive-by tracking possible. The settlement has three tiers. Tier one, free: window.screen basics and the synchronous screen.isExtended boolean - enough to adapt UI coarsely with no prompt at all. Tier two, prompt: getScreenDetails() grants the full per-screen inventory; grant it once per origin and it persists until the user revokes it in site settings. Tier three, never: no events, no enumeration without the grant - backgrounded tabs do not keep monitoring hardware changes silently. Engineering-wise this maps to a clean pattern: build your layout on tier-one signals, request tier two only when the user activates an explicitly multi-screen feature, and treat a denial as a normal product state - a user on a locked-down corporate browser may never grant it, and those users still deserve a working single-screen experience.

What are the screenschange and currentscreenchange events for, and how do they differ?

They track two different kinds of change. screenschange fires on the ScreenDetails object when the physical or logical display set changes: a monitor plugged in or unplugged, a display sleeping or waking, a virtual display appearing - the screens array after the event is the new truth, so the handler pattern is rebuild-from-scratch (re-read d.screens, re-render your layout) rather than trying to diff the old array; the event carries no payload of what changed precisely because the reliable source is the array itself. currentscreenchange fires when the screen your window is on changes identity - most commonly because the user dragged your window across displays, but also when a screen your window occupied disappears and the window relocates. Both matter to real products and both fail differently: skip screenschange and your trading dashboard shows phantom screens after the projector disconnects mid-meeting; skip currentscreenchange and your presenter console keeps highlighting speaker-notes controls after the user drags it to the projector screen. Two hygiene rules: attach both listeners at the same moment you receive ScreenDetails (they live on that object, not on window), and debounce rebuilds - a docking station waking up can fire a burst of screenschange events, and rebuilding a complex layout five times in half a second shows.

When is this API the wrong tool - and what are the alternatives?

Four boundary cases, each with its own exit. If you need to move or size windows, not just know about screens: the API is read-only by design - your tools remain window.open with feature strings, fullscreen placement, and the browser UI; apps that truly script window layout (trading floors) often end up as installed PWAs where the OS window management is richer. If you need content on a second screen without your window going there: the Presentation API casts a receiver page to a cast device or second display deliberately - different transport, better fit for slides-to-TV. If you need to capture what is on a screen: that is the Screen Capture API (getDisplayMedia) - pixels, not topology, with its own consent surface. And if you just want to show a fullscreen dashboard on whatever screen the user put you on: fullscreen plus a responsive layout solves it with zero new permissions - the honest first question before reaching for getScreenDetails() is whether you actually need to know about the other screens, or just to look good on this one. The genuine sweet spots for Window Management are the products that span displays by design: presenter consoles, multi-panel trading or monitoring walls, POS with a customer-facing display, kiosk clusters - apps where a screen is part of the configuration, not an accident of where the window landed.

Related tools