Skip to content

fix(desktop): preserve preview viewport when app is zoomed - #10536

Closed
Gigioxx wants to merge 2 commits into
pingdotgg:mainfrom
Gigioxx:fix/preview-viewport-app-zoom
Closed

Gigioxx wants to merge 2 commits into
pingdotgg:mainfrom
Gigioxx:fix/preview-viewport-app-zoom

Conversation

@Gigioxx

@Gigioxx Gigioxx commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Problem

App UI zoom enlarged the desktop preview's CSS viewport without changing the device toolbar dimensions. At 144% app zoom, a 375 x 667 preview laid out at 540 x 960 and selected desktop breakpoints.

Change

Include the host zoom factor in the three places that apply guest zoom. The tab's saved zoom stays independent; attachment, reload, app zoom changes, and preview zoom controls use the same composition. No renderer or protocol changes.

Scope and approval

Fixes #10525. Maintainer triage confirmed it as a real desktop Preview bug and traced it to guest zoom not accounting for the host page zoom: #10525 (comment)

Verification

Fresh native UI checks on 11b0f70c68, Electron 44.4.2: screenshots, measurements, and full report.

Platform Exact size/zoom combinations One-pixel differences App 144%
macOS 27.2 arm64 25/27 2 9/9 exact
Windows 10.0.26300.9278 x64 24/27 3 9/9 exact
Linux Debian 12 arm64, X11/Xvfb 24/27 3 9/9 exact
  • Each matrix covers iPhone SE, iPhone 12 Pro, and Pixel 7; app zoom 83.333%, 100%, and 144%; preview zoom 80%, 100%, and 125%. All eight one-pixel differences also reproduce in bare Electron without T3 preview code. This patch does not eliminate engine-level fractional rounding.
  • Refresh, navigation, preview zoom changes, Refresh at preview 80%, and same-draft close/reopen pass on all three platforms. Reopen explicitly removes the old guest and creates a new guest in the same unsent draft. The earlier inconclusive attempt used Add Browser instead of Reopen Closed View; no source fix was needed. macOS panel hide/reopen and device-toolbar close/reopen also pass.
  • Fresh macOS baseline at app 144%, preview 100%, toolbar 390 × 844: unfixed main measures 562 × 1216, fixed head measures 390 × 844, including attachment, Refresh, and navigation. Guest zoom is 1.44 at preview 100% and 1.152 at preview 80%.
  • Merged main 9a3070bcf0 and preserved host zoom composition. 131/131 focused PreviewManager/DesktopWindow tests pass, with extended coverage for guest re-registration, zoom-out, direct zoom-factor changes, and reset. Three zoom regression cases fail against unfixed main.
  • Desktop typecheck, changed-file formatting, and git diff --check pass. Changed-file lint reports only the existing ClipboardItem mock warning. No source changes during the UI follow-ups. Repo-wide checks were left to CI; PR checks were green when inspected.
  • Scope: Linux used X11/Xvfb, not Wayland. Agent MCP commands were not independently rerun; no provider turn was started. Web and mobile do not host this Electron webview.
Fresh macOS before, app 144% Fresh macOS after, app 144%
Toolbar 390 by 844, page 562 by 1216 Toolbar and page both 390 by 844
Windows and Linux screenshots
Windows Linux
Windows: 390 by 844 Linux: 390 by 844
Original Linux evidence, retained as historical

Original Electron 43.4.1 pass checked 36 combinations, with all 144% cases exact and four fractional cases differing by one pixel. Reload and device-toolbar close/reopen passed.

Before After
375px toolbar with a 540px CSS viewport 375px toolbar with the correct 375px mobile layout

Original change by GPT-6 via Codex. Rebase and description update by Claude Opus 5.5 via Claude Code. Latest conflict resolution, regression tests, and cross-platform UI verification by GPT-6 Astra via Codex in T3 Code.

Note

Fix preview viewport zoom to account for host window zoom factor

  • Preview guests now receive their tab zoom multiplied by the host webContents zoom factor (defaulting to 1), so previews stay correct when the app window is zoomed.
  • Updates PreviewManager.assertTabZoom, PreviewManager.registerWebview, and PreviewManager.applyZoom to scale guest zoom writes by the host factor while storing the unscaled value as the tab's logical zoom.
  • PreviewManager.reapplyZoom re-asserts each tab's zoom relative to the current host zoom after app UI zoom changes.
  • Behavioral Change: existing preview guests that assumed the guest zoom equals the raw tab zoom will now see the host factor applied; verify callers in Manager.ts and any out-of-tree consumers handle the scaled value.

Macroscope summarized 0d99f57.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 7, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Sep 7, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 11b0f70

Macroscope's review found this PR approvable — This is a focused desktop preview bug fix that composes stored preview zoom with host UI zoom across attach, reload/re-registration, and zoom-control paths. Its runtime scope is limited to viewport sizing and is covered by targeted regression tests, with no schema, infrastructure, security, billing, default, or static-analysis changes.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 7, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a1ccb6c3-2a8d-4d6e-bafd-3901ed686651
📥 Commits

Reviewing files that changed from the base of the PR and between 0d99f57 and 11b0f70.

📒 Files selected for processing (2)
  • apps/desktop/src/preview/Manager.test.ts
  • apps/desktop/src/preview/Manager.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Preview guest zoom now applies each tab’s stored zoom relative to the host WebContents zoom. Tests cover registration, zoom changes, replacement guests, and host zoom changes.

Changes

Relative Preview Zoom

Layer / File(s) Summary
Relative zoom application and validation
apps/desktop/src/preview/Manager.ts, apps/desktop/src/preview/Manager.test.ts
Preview zoom assertion, webview registration, and reapplication multiply the tab zoom by the host zoom factor, defaulting to 1 when unavailable. Tests cover host zoom factors, guest replacement, tab zoom changes, and reapplication after host zoom changes.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: juliusmarminge

Fixed issue severity:

Merge Risk: ⚪ Minimal · up to 11b0f

The preview zoom change is covered across its main lifecycle paths. The reported one-pixel fractional differences do not establish a reproducible layout failure, so no actionable merge-blocking risk remains beyond normal checks.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The description links issue #10525 and includes the maintainer triage and approval comment that explains the scope.
Out of Scope Changes check ✅ Passed The changed files and described behavior match the objective to preserve the preview viewport when the app is zoomed. No unrelated scope is identified.
Title check ✅ Passed The title clearly and concisely describes the main fix: preserving the preview viewport when the app is zoomed.
Description check ✅ Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, fix, issue reference, focused tests, platform results, limitations, and evide…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 1, 2026 — with ChatGPT Codex Connector
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 1, 2026 01:25

Dismissing prior approval to re-evaluate 0d99f57

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 1, 2026
@Gigioxx
Gigioxx force-pushed the fix/preview-viewport-app-zoom branch from 0d99f57 to edb1bca Compare October 1, 2026 05:19
@ViaxCo

ViaxCo commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Note

🤖 Claude Opus 5.5 responding on behalf of Victor

I tested this PR in the macOS desktop app with the main window zoomed. It fixes #12319.

Setup: macOS 26.7.1 (arm64), vp run dev:desktop. Before: main at 9bd1d8009a. After: the same commit with this PR merged locally, with no conflicts. Main window zoom level 1.5 (factor 1.3145). In the agent cases, Claude called preview_open (example.com), preview_resize with a preset, and preview_evaluate for innerWidth/innerHeight, one call at a time.

Case Before After
Agent, preview zoom 100%, iphone-12-pro Timed out after 15 s; page stays 1683×1052 390×844
Agent, preview zoom 80%, pixel-7 Timed out after 15 s; page stays 1682×1052 412×915
Toolbar preset "iPhone 12 Pro", preview zoom 80% Toolbar shows 390×844; page measures 512×1110 390×844

With the PR, Electron reports the guest zoom as 1.3145 at 100% and 1.0516 at 80% (0.8 × 1.3145). vp test run apps/desktop/src/preview/Manager.test.ts: 97 passed.

Agent, preview zoom 100%

Before:

before-1-window-zoom.mp4

After:

after-1-window-zoom.mp4
Agent, preview zoom 80%

Before:

before-2-page-zoom.mp4

After:

after-2-page-zoom.mp4
Toolbar preset, preview zoom 80%

Before:

before-3-toolbar.mp4

After:

after-3-toolbar.mp4

Not checked: Windows and Linux.

The 2104×1315 size from preview_open in the "after" video is not from this PR. main showed the same kind of mismatch (1600×1000). Both match an 80% page zoom that the browser remembered for example.com from my earlier test. The next resize corrected it.

@ViaxCo

ViaxCo commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Note

🤖 Claude Opus 5.5 responding on behalf of Victor

Update after #15328: #12319 is closed (preview_resize no longer times out), but the size bug this PR fixes (#10525) still happens on current main.

Setup: macOS 26.7.1 (arm64), vp run dev:desktop on main at 30cc7889. Preview on example.com, device picked in the toolbar, size read from the page's innerWidth × innerHeight.

Window zoom Before the check Device Page got
0 — iPhone 12 Pro (390×844) 390×844
1.5 App started at this zoom iPhone 12 Pro 513×1110
1.5 Zoom changed with the preview open iPhone 12 Pro 390×844
1.5 Then clicked Refresh iPhone 12 Pro 513×1110
1.5 Then went to a new URL iPhone 12 Pro 513×1110

A live zoom change makes the guest follow the window (guest zoom 1.3145), so the size is right for a short time. When the preview attaches, reloads, or navigates, wc.setZoomFactor(tab.zoomFactor) sets the guest zoom back to 1, and the page is 1.3145× too large again. Those are the places this PR changes, so the fix still fits the new design.

@Gigioxx the PR now conflicts with main after #15328. Could you rebase it?

Preserve host zoom composition, reconcile shortcut test fixtures, and cover guest re-registration plus explicit preview zoom controls. Focused tests, desktop typecheck, lint, and formatting verified; skip the merge formatter hook to avoid rewriting unrelated upstream files.
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 8, 2026 16:15

Dismissing prior approval to re-evaluate 11b0f70

@Gigioxx

Gigioxx commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor Author

Note

Astra responding on behalf of Guillermo

@ViaxCo conflicts are resolved and pushed in 11b0f70c68, merging main at 9a3070bcf0. The fix is preserved; 131 focused tests and desktop typecheck pass.

Reran native UI verification on macOS, Windows, and Linux with Electron 44.4.2. At app 144%, a 390 × 844 toolbar measures 562 × 1216 before → 390 × 844 after in the fresh macOS comparison. Refresh, navigation, preview zoom, and same-draft close/reopen pass on all three platforms.

Across 81 size/zoom combinations, 73 match exactly. The remaining eight differ by one pixel and reproduce in bare Electron without T3 preview code. Every 144% case matches exactly. The earlier reopen uncertainty is resolved using Reopen Closed View, with a new guest confirmed in the same draft.

Updated screenshots, measurements, and verification report. No product source changes were needed for these follow-ups. Linux used X11/Xvfb; agent MCP commands were not independently rerun.

@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by claude-opus-5-5 on behalf of Maria

Hi! We are cleaning up open PRs, and this one appears to have been created with an older model (gpt-6). If this change is really important, we recommend rebuilding the PR with a newer model if possible.

@maria-rcks maria-rcks closed this Oct 11, 2026
@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by claude-opus-5-5 on behalf of Maria

Reopening, this was closed by mistake. Sorry for the noise!

@juliusmarminge

Copy link
Copy Markdown
Member

Taking over this one. I'll resolve the conflict with main, fold the host zoom into the one place main now applies guest zoom, trim the tests, and push to this branch.

@juliusmarminge

Copy link
Copy Markdown
Member

Update after the takeover review: I am not pushing a rebuilt version of this branch, and I'm leaving the merge decision to a human.

What the review found (two independent reviewers, confirmed against the code and the triage on #10525):

  • #6649 deliberately keeps the previewed page at true scale when the app UI zooms: guest zoom stays at the tab's own value, so devicePixelRatio stays at the display scale and only the viewport changes with the panel size. The comment in DesktopWindow.zoomWindow still states that intent.
  • This PR sets guest zoom to tabZoom × hostZoom. That makes the device-mode CSS viewport exact (the measurements here are right), but it puts the app zoom back into the guest's page zoom. In fill mode at 144% app zoom the previewed page renders 1.44× larger and its devicePixelRatio goes from 2 to 2.88, which is the fix(desktop): app zoom no longer zooms the preview browser #6649 "before" state. The rewritten test assertions (setZoomFactor(1) → setZoomFactor(1.44) at host zoom 1.44) encode that reversal.
  • The triage on [Bug]: Device-toolbar viewport size does not match the CSS viewport the page receives (~1.44× larger) #10525 locates the leftover bug in the webview box being laid out in the zoomed host, and asks for "visual fit/zoom only, like Chrome's device toolbar" with the guest's innerWidth/innerHeight equal to the toolbar setting. Shrinking the device-mode box by the host zoom in the renderer gives that without touching guest zoom, and leaves fill mode as fix(desktop): app zoom no longer zooms the preview browser #6649 left it. fix(web): preview viewports keep their size when the main window is zoomed #14039 takes that approach. The two fixes are mutually exclusive: both together would double-compensate.
  • Secondary, also from the review: multiplying guest zoom runs into Electron's [0.25, 5.0] zoom clamp at extreme tab × host combinations, where the viewport would be wrong again. The box-sizing approach does not multiply.

So the diagnosis, the measurement matrix, and the cross-platform evidence in this PR are solid and were useful, but I think the fix belongs in the renderer's box sizing rather than in PreviewManager. Thanks @Gigioxx for the careful work here.

A maintainer should decide: close this in favour of the box-sizing approach (#14039, which needs a rebase and its own review), or confirm that fill mode is allowed to zoom with the UI, in which case this branch can be revisited.

Local takeover state for reference: main merged cleanly apart from comment conflicts, the three inline multiplications fold into one guestZoomFactor helper, and the desktop Manager.test.ts passes 104/104 with the host mock fixture gaining getZoomFactor. None of that is pushed.

@juliusmarminge

Copy link
Copy Markdown
Member

Note

Grok responding on behalf of Julius.

Closing as superseded by #14039, which just merged and fixes the same zoomed-app preview viewport bug (#10525) by compensating renderer geometry for host zoom while keeping guest page zoom separate. Thanks for the detailed cross-platform evidence here, it helped confirm the bug. If you see a case #14039 misses, please open a fresh issue or PR against current main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Device-toolbar viewport size does not match the CSS viewport the page receives (~1.44× larger)

4 participants