Skip to content

fix(window): compensate Windows text-size scaling in the content-fit resizer#341

Merged
lshw54 merged 1 commit into
codefrom
fix/text-scale-window-fit
Jul 12, 2026
Merged

fix(window): compensate Windows text-size scaling in the content-fit resizer#341
lshw54 merged 1 commit into
codefrom
fix/text-scale-window-fit

Conversation

@lshw54

@lshw54 lshw54 commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

What

Windows Accessibility "Text size" ≥ 130% clips the app again on 6.0.5 (regression of the problem #257 originally fixed, reported in #339). #337 removed #257's --force-device-scale-factor=1 to fix the oversized-window bug at >100% display scaling and kept --force-text-scale-factor=1 as a text-size guard — but that switch does not exist in Chromium (zero matches in the Chromium source), so it was silently ignored and nothing guarded against text scaling.

Root cause of the clipping: WebView2's rasterization scale is monitor DPI scale × system text scale and is surfaced to the page as devicePixelRatio, while Tauri's LogicalSize multiplies by the window's monitor-DPI scale only. At text size 130%, one CSS px paints 1.3× larger than the logical px fitWindow sized the window in — content overflows the window by exactly that ratio.

Fix

Have both: keep #337's correct display-scaling behaviour AND respect the user's enlarged text (instead of #257's approach of forcing the webview back to 100%, which defeated the accessibility setting).

Derive the text scale at runtime —

textScale = devicePixelRatio / (windowScaleFactor × appliedWebviewZoom)

— and multiply it into every LogicalSize the content-fit resizer emits. The window simply grows to fit the enlarged text. At text size 100% the ratio is 1, so behaviour at every display scaling is byte-identical to #337.

  • src/services/windowFit.ts — scale tracking + clamped textScaleFactor() (dependency-free, unit-tested). Clamp to [1, 3]: Windows text size spans 100–225%, so out-of-band values (transient mid-resize readings, persisted Ctrl-zoom-out) fall back to 1.
  • src/router/index.ts — track Window.scaleFactor() / onScaleChanged, multiply the factor into fitWindow and resizeWindow, record the zoom fitWindow applies so it can be divided back out of devicePixelRatio.
  • src-tauri/src/lib.rs — drop the fictional flag; only set WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS when there are real args.
  • 10 new vitest specs covering the factor maths (text-only scale, display+text combined, zoom division, clamps, invalid inputs).

Notes for reviewers

  • Frontend typecheck / eslint / prettier / vitest (639) and Rust cargo check + clippy all pass.
  • A text-scale change re-fits automatically: it changes the rasterization scale → CSS-px viewport shrinks → the existing resize listener fires. No new event wiring needed.
  • Like fix(window): correct oversized window at >100% scaling + add Maintenance recovery controls #337, the actual accessibility behaviour needs on-device verification (set Accessibility → Text size to 130–225% and check login + account list) — CI has no scaled desktop.

Closes #339

…resizer

Windows Accessibility 'Text size' >= 130% clipped the app again after
#337. The '--force-text-scale-factor=1' switch #337 kept as a guard is
not a real Chromium switch (zero matches in the Chromium source) and
was silently ignored.

The text scale reaches the webview through WebView2's rasterization
scale (monitor DPI x text scale), surfaced as devicePixelRatio, while
Tauri's LogicalSize multiplies by the window's monitor-DPI scale only —
so at 130% text size every CSS px paints 1.3x larger than the logical
px the window was sized in, clipping content by exactly that ratio.

Fix: derive textScale = devicePixelRatio / (windowScaleFactor x
appliedWebviewZoom) at runtime and multiply it into every LogicalSize
the resizer emits. Big text stays big (unlike #257's forced 100%
webview scale), the window grows to fit, and at text size 100% the
ratio is 1 so #337's >100% display-scaling behaviour is untouched.

- services/windowFit.ts: scale tracking + clamped textScaleFactor()
  (dependency-free, unit-tested; clamp [1,3] rejects transient and
  Ctrl-zoom-out readings)
- router/index.ts: track Window.scaleFactor()/onScaleChanged, multiply
  the factor into fitWindow and resizeWindow sizes, record applied zoom
- lib.rs: drop the fictional --force-text-scale-factor flag; only set
  WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS when args exist
- tests: 10 new specs for textScaleFactor
@lshw54 lshw54 self-assigned this Jul 12, 2026
@lshw54
lshw54 merged commit 7190441 into code Jul 12, 2026
3 checks passed
@lshw54
lshw54 deleted the fix/text-scale-window-fit branch July 12, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6.0.5 #257問題被重現

1 participant