fix(browser): restore zoom scaling for native view bounds - #2022
Merged
Conversation
PR #2020 removed the `* zoom` factor from computeBounds on the incorrect assumption that getBoundingClientRect() already reflects the page zoom in the native coordinate space. It does not. The renderer applies zoom via Electron's webContents.setZoomFactor, which scales the page so getBoundingClientRect()/innerWidth report CSS pixels DIVIDED by the zoom factor (verified live: at zoom 1.5 a 1180 DIP window measures innerWidth 786). WebContentsView.setBounds, however, expects window device-independent pixels — a fixed 1180-wide content area that does not change with zoom. So renderer rects must be multiplied back by the zoom factor to map into the native space. Restore the multiplication (keeping the rounded-edge width/height that avoids a 1px seam). At zoom = 1 the result is identical to before. Verified live via CDP at zoom 1.0 and 1.5: the native view's left/right edges and top exactly match the panel chrome (leftAligned/rightAligned true, chrome-bottom-to-view-top gap 0), and bounds auto-resync on zoom change.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jun 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After #2020, the embedded browser view is misaligned within its panel whenever the app zoom is not 100%. At zoom 1.0 it's pixel-perfect; at any other zoom the native view no longer lines up with the panel chrome.
Root cause
#2020 removed the
* zoommultiply fromcomputeBounds, on the assumption thatgetBoundingClientRect()already reports coordinates in the native view's coordinate space. That assumption is wrong.Zoom is applied via Electron's
webContents.setZoomFactor(see__setZoomFactorinmain.mjs). UndersetZoomFactor(f), the page is scaled sogetBoundingClientRect()/innerWidthreport CSS pixels divided by the zoom factor.WebContentsView.setBounds, however, takes window device-independent pixels — a content area whose size does not change with page zoom.Verified live via a temporary debug IPC (
getContentBounds/ viewgetBounds):innerWidthcontentBounds.widthSo renderer rects must be multiplied back by the zoom factor (786 × 1.5 = 1180) to map into native DIP. Removing the multiply under-scaled the view at zoom ≠ 1.
Fix
Restore the zoom multiplication in
computeBoundsandgetNativeMenuPoint(extracted into a smallgetZoomFactor()helper), while keeping the rounded-edgewidth/heightderivation from #2020 that avoids a 1px seam. At zoom = 1 the output is identical to currentdev.Testing
pnpm --filter @openwork/app typecheck→ exit 0.Verified live via CDP at zoom 1.0 and 1.5 by comparing the panel chrome rect (×zoom) to the actual native
WebContentsViewbounds:{x:705, y:81, w:431, h:739}— matches placeholder exactly.{x:745, y:122, w:369, h:698}—leftAligned: true,rightAligned: true, chrome-bottom→view-topgap: 0. Right edge (1114) leaves exactly the 66 DIP (44 CSS × 1.5) rail.autoSynced: true.Reproduce
pnpm dev, open a session.Notes