← Window Shape API

v152 · window shape api · method

IsolatedWebApp.setShape()

Limited availability

  • Chrome · ChromeOS only, from 152, allowlisted IWAs
  • Edge · not available (ChromeOS-only API)
  • Firefox · no signal
  • Safari · no signal

ChromeOS Blink extension, allowlisted Isolated Web Apps only — not a Baseline feature and not intended for other browsers (Intent to Ship).

Sets the shape of the calling IWA’s window to the union of the given rectangles, in Device Independent Pixels. Only areas covered by at least one rectangle stay visible and interactive. Pass an empty array to restore the default rectangular window.

Prerequisites — all three are enforced Source: spec §3.1; explainer — requirements.

Syntax

// WebIDL (specification):
partial interface IsolatedWebApp {
  Promise<undefined> setShape(sequence<DOMRectReadOnly> rects);
};

// Call form:
await window.chromeos.isolatedWebApp.setShape(rects);
Source: spec §3.3 API Extension.

Parameters

rects A sequence<DOMRectReadOnly> — an array of rectangles (plain objects with x, y, width, height, or DOMRect/DOMRectReadOnly instances) in Device Independent Pixels in the OS window’s local coordinate space. Constraints, in evaluation order:
  • At most 10,000 entries; more rejects with TypeError.
  • Every x, y, width, height must be finite; NaNInfinity rejects with TypeError.
  • width and height must be ≥ 0; negative values reject with TypeError.
  • If the array is non-empty, at least one rectangle must be ≥ 10×10 (the minimum-size guard); otherwise rejects with TypeError.
  • An empty array is valid and resets the shape (see return value).
Before application, each rectangle’s values are truncated to integers and clamped to the 32-bit signed integer range (see coordinate space and scaling).
Source: spec §3.4 The setShape() method.

Return value

A Promise<undefined>. It resolves once the host operating system has been asked to apply the union of the (converted) rectangles to the window. With an empty array, the union is empty and the window returns to its default rectangular shape. The method returns the promise synchronously; validation failures that are detected before the parallel step reject that same promise (they do not throw synchronously).

Source: spec §3.4; explainer — example usage.

Exceptions

All failure modes are promise rejections (no synchronous throw):

RejectionCondition
InvalidStateErrorThe window’s display mode is not unframed (checked both when the method is called and again in the parallel step before application).
InvalidStateErrorNo OS window is associated with the current global object at application time.
TypeErrorrects has more than 10,000 entries.
TypeErrorAny rectangle has a non-finite x, y, width, or height.
TypeErrorAny rectangle has width < 0 or height < 0.
TypeErrorThe array is non-empty but no rectangle meets the 10×10 minimum size (the anti-invisible-window guard).
Source: spec §3.4.

Application algorithm

The specification’s steps, in order:

  1. Create a new promise; let window be the current global object.
  2. If window’s display mode is not unframed, reject with InvalidStateError and return.
  3. If rects has more than 10,000 entries, reject with TypeError and return.
  4. For each rectangle: reject with TypeError on non-finite members or negative width/height; note whether any rectangle is ≥ 10×10; append a converted rectangle (members truncated to integers, clamped to int32) to the working list.
  5. If the array is non-empty and no rectangle met the 10×10 minimum, reject with TypeError and return.
  6. In parallel: resolve the OS window for the global object (reject InvalidStateError if none); re-check the display mode is still unframed (reject InvalidStateError if not); ask the host OS to set the window’s shape to the union of the converted rectangles, interpreted in the window’s DIP coordinate space.
  7. Resolve the promise with undefined.
Source: spec §3.4 The setShape() method (steps paraphrased without semantic change; consult the linked spec for the verbatim text).

Lifecycle and state transitions

ApplyEach fulfilled call replaces the window’s custom shape wholesale with the new union of rectangles — calls are not additive across invocations.
ResetsetShape([]) clears the custom shape; the window returns to its default rectangular form.
IdempotenceCalling with the same rectangles repeatedly is safe and produces the same shape.
Display-mode couplingThe unframed display mode is fixed for the lifetime of the window (per Manifest Incubations), so an unframed window cannot silently become ineligible mid-life; the spec still re-checks the mode in the parallel application step as a defense.
Policy-forced removalIf an administrator blocks window management via WindowManagementBlockedForUrls, Chrome removes any custom window shape and falls back to another available display mode (ChromeStatus summary).
No eventsThe API fires no events; shape changes are observable only visually (or via the demo pattern of re-reading window geometry through the Window Management API).
Source: spec §3.4; Manifest Incubations — unframed; ChromeStatus summary.

Examples

A donut-style overlay panel anchored to the window’s bottom edge, with the required minimum-size rectangle:

const iwa = window.chromeos?.isolatedWebApp;
if (!iwa) throw new Error("Not an allowlisted IWA");

// Window is 800x600 DIPs. Show only a 800x120 strip at the bottom
// and a 200x200 floating badge at the top-right.
await iwa.setShape([
  new DOMRect(0, 480, 800, 120),   // main strip (>= 10x10 ✓)
  new DOMRect(600, 0, 200, 200),   // floating badge
]);

Resetting to the default rectangular window:

await window.chromeos.isolatedWebApp.setShape([]);

Handling the documented rejection paths:

try {
  await iwa.setShape([{ x: 0, y: 0, width: 4, height: 4 }]);
} catch (e) {
  // TypeError: no rectangle meets the 10x10 minimum-size guard.
}
try {
  await iwa.setShape(new Array(10_001).fill(new DOMRect(0, 0, 10, 10)));
} catch (e) {
  // TypeError: more than 10,000 rectangles.
}
Source: spec §3.4; explainer — example usage; Set-Shape-demo src/main.ts.

Browser compatibility

Interim table (no BCD or web-features entry exists; compiled from the linked primary sources, 2026-07-28):

BrowserSupportEvidence
Chrome (ChromeOS)152+, allowlisted IWAs onlymilestone=152 listing; Intent to Ship
Chrome (other platforms)Not availableIntent to Ship (“not available in any other platform”)
EdgeNot availableChromeOS-only Blink extension (explainer)
Firefox / SafariNo signalChromeStatus record vendor views

Security and privacy

Source: spec §3.1; explainer — security & privacy considerations.

Sources