Native page bounds in the built-in browser

The Electron shell DOM toolbar and native WebContentsView must maintain the same page bounds at any shell zoom factor.

Verified gaps

At a shell zoom factor of approximately 1.095 , the renderer sends x=812.63, width=518.64 CSS px, which the main process uses directly as DIP. Correct native bounds should be approximately x=890, width=568. The webpage consequently covers the left chat pane and leaves blank space on the right.

The old occlusion check hides every native Web pane whenever any role=dialog exists in the document. Local working-directory, project and permission menus at the bottom blank the neighboring webpage even when entirely inside the chat pane. Meanwhile, role=menu, role=listbox and several custom fullscreen confirmation overlays are not covered by the same rule.

Unified overlay rules for multiple Web panes

Overlay typeDetectionNative Web behavior
Local Popover, Dropdown, listbox and tab/split menusrole=dialog/menu/listboxCalculate rectangles per Web body; hide only panes that actually intersect.
Fullscreen modals, confirmation backdrops and attachment previewsdata-native-view-occluder=true or the existing merge backdropThe fullscreen rectangle intersects each Web body, hiding every covered pane.
Tooltips, toasts, drag cues and ordinary portaled contentExcluded from the occlusion selectorTransient hints do not blank the whole webpage.
Desktop main/context/bookmark native menusSeparate overlay owner in the main processRetain native-menu lifecycle management; do not manage it again through renderer DOM.

Multiple split Web panes do not share a global visible flag. Each WebTabPane uses its own body bounds against the same set of current overlays. If a menu covers only the left Web pane, the right pane stays visible. Agent picture-in-picture previews reuse the same registerVisibleWebTabBounds / syncVisible path and publish only the small-window body rectangle, keeping toolbar buttons and the lower-right resize handle outside the native view. Existing MutationObserver, ResizeObserver and scroll/resize listeners republish bounds after overlays close, move or resize. During small-window dragging/resizing the renderer throttles calls to syncVisible to 100ms and publishes immediately on pointer release, avoiding per-frame IPC. Global flush still batches microtasks within the same tick.

Design

Boundaries and exclusions

Do not forcibly reset user zoom or change split ratios, DOM layout, preload APIs, site zoom, Browser Agent, dependencies or configuration. Electron WebContentsView.setBounds takes DIP while renderer DOM measurements use CSS px. The renderer retains measurement precision; the main process converts units and performs final rounding.

Task files and acceptance

Production code: apps/desktop/main.js, apps/web/components/center-tabs/web-tab-pane.tsx and apps/web/lib/browser/web-tab-bounds.ts. Public gates: apps/desktop/scripts/check-webtab-zoom-bounds.js and existing web split gates.

Implementation evidence

Implementation status

Unit conversion, automated gates and installed-App acceptance are complete.