This document specifies a set of technologies that allow a Web developer to take control over the area that would generally be occupied by the title bar in an installed web application running on a desktop environment. These technologies are known as (WCO).
This draft is meant to serve as a starting point for the standardization process of WCO and the technologies described in it might be migrated to other specifications on different working groups.
Applications targeting non-mobile devices are hosted within frames that commonly have a title bar. A title bar is a UI element generally represented as a horizontal bar at the top of a window, bearing the name of the active program or the name of the current active document and and the [=window controls=]. Modern applications can take advantage of the area in the title bar in order to display UI content to create a better UX.
For installed web apps hosted within a user agent (UA) frame, it is possible to get some form of customization in the frame by declaring which type of display mode is preferred. Developers can select the mode that best meets the needs of the application via the [=manifest=] file's `display` member. However, these modes are limited and do not provide the same level of control over the title bar, therefore developers looking to create an immersive, native-like title bar for their installed application can't achieve this with the aforementioned member. Instead, the client area begins immediately below the reserved title bar region, which can create a cramped application space specially on portable devices with smaller screens.
WCO enables the creation of custom title bar UI by leaving only the [=window controls=] [=overlaid=] on the frame, in which case web content can flow into the area previously held by the title bar.
The [[HTML]] specification defines the Navigator interface, which this specification extends:
[SecureContext, Exposed=(Window)] partial interface Navigator { [SameObject] readonly attribute WindowControlsOverlay windowControlsOverlay; };
Internal slot | Initial value | Description |
---|---|---|
[[\TitleBarArea]] | Empty [=struct=] for the title bar region. | A [=struct=] that stores the values of the area that defines the title bar region. These values are `x`, `y`, `width`, `height`. |
[Exposed=Window] interface WindowControlsOverlay : EventTarget { readonly attribute boolean visible; DOMRect getTitlebarAreaRect(); attribute EventHandler ongeometrychange; }; [Exposed=Window] interface WindowControlsOverlayGeometryChangeEvent : Event { constructor(DOMString type, WindowControlsOverlayGeometryChangeEventInit eventInitDict); [SameObject] readonly attribute DOMRect titlebarAreaRect; readonly attribute boolean visible; }; dictionary WindowControlsOverlayGeometryChangeEventInit : EventInit { required DOMRect titlebarAreaRect; boolean visible = false; };
The `visible` attribute is a [=boolean=] that returns `true` when the values of the {{Window/window}}.[[\TitleBarArea]] are not 0.
The `getTitlebarAreaRect()` method returns a DOMRect that represents the available area for displaying web content. This available title bar region does not include the area under the [=window controls=] [=overlay=].
The `ongeometrychange` attribute is an event handler whose corresponding event handler event type is "change".
This specification defines the following [=display mode=]:
The [=display mode/window-controls-overlay=]
[=display mode=] can be specified in the
[=manifest/display_override=]
member of the manifest.
Name | Value |
---|---|
`titlebar-area-x` | length |
`titlebar-area-y` | length |
`titlebar-area-width` | length |
`titlebar-area-height` | length |
The [=title bar area environmental variables=] are four env variables that define a rectangle by the width and height from a starting point in the viewport. This area corresponds to the available area of the title bar, and allows to position dynamic Web content inside its bounds.
This specification integrates with the [[cssom-view]] specification by patching the algorithm below:
In the viewport [=Window/resize=] algorithm, run [=resize the title bar area=] after step 1.
To resize the title bar area for a window |win|, run these steps:
To update the overlay area information, run these steps:
Displaying installed web apps in a frameless window leaves room for developers to spoof content in what was previously a trusted, UA-controlled region.
Currently in Chromium browsers, `standalone` mode includes a title bar which on initial launch displays the title of the webpage on the left, and the origin of the page on the right (followed by the "settings and more" button and the window controls). After a few seconds, the origin text disappears.
In RTL configured browsers, this layout is flipped such that the origin text is on the left. This open the window controls overlay to spoofing the origin if there is insufficient padding between the origin and the right edge of the overlay. For example, the origin "evil.ltd" could be appended with a trusted site "google.com", leading users to believe that the source is trustworthy.
Another existing security feature for installed web apps is an indicator of when a user has left the declared scope of the app. When a user navigates out of scope, a black bar appears between the title bar and the web content, and it includes the following information:
With the window controls overlay enabled, if a user navigates out-of-scope the overlay will be temporarily replaced with a standalone title bar. When the user navigates back to into scope, the standalone title bar will be hidden again and the overlay displayed.
Enabling Window Controls Overlay poses an increased fingerprinting surface since the size of the overlay can vary depending on the OS, the text scale, the OS font size, the OS zoom factor, and the web content’s zoom factor.
Although this is a potential fingerprinting issue, it only applies to installed desktop web apps that use the window controls overlay feature and does not apply to general browser usage. Additionally, the windowControlsOverlay API will not be available to iframes embedded inside of an installed web app.
Huge thanks to Amanda Baker, Joshua Bell and Yoav Weiss for their contributions to this work.