Skip to content

fix(desktop): preserve UI scale across hash-route navigation - #75015

Closed
clarkvines wants to merge 1 commit into
NousResearch:mainfrom
clarkvines:fix/desktop-preserve-zoom-on-route
Closed

clarkvines wants to merge 1 commit into
NousResearch:mainfrom
clarkvines:fix/desktop-preserve-zoom-on-route

Conversation

@clarkvines

Copy link
Copy Markdown
Contributor

Bug Description

Desktop UI scale can reset to 100% when an action changes the in-page hash route. One visible path is Cmd/Ctrl+N from Settings after selecting a non-default scale.

Fixes #38854
Fixes #48658

Related: #38908, #43517, #66989

Root Cause

Packaged Desktop loads the renderer from a file:// URL and uses hash routing. Electron can reset webContents zoom to level 0 during main-frame hash navigation. The existing did-finish-load restoration does not run for these in-page navigations.

Fix

  • Reapply the persisted zoom level after main-frame did-navigate-in-page events.
  • Retain the existing full-load and window-lifecycle restoration paths.
  • Ignore subframe navigation and destroyed webContents.
  • Add unit coverage for the navigation lifecycle and an Electron E2E for the Cmd/Ctrl+N path.

Scope

This change addresses resets caused by main-frame hash navigation. Startup persistence and renderer-state synchronization remain separate zoom paths and are unchanged by this PR.

How to Verify

  1. Open Settings → Appearance and choose 110% UI Scale.
  2. Press Cmd+N on macOS or Ctrl+N on Windows/Linux.
  3. Confirm the fresh chat opens and UI Scale remains 110%.

Test Plan

  • Regression test fails on the parent commit: expected 110%, received 100%.
  • Regression test passes on the candidate commit.
  • Desktop Electron suite: 868 passed, 2 skipped.
  • TypeScript typecheck passes.
  • ESLint reports 0 errors.
  • Clean macOS arm64 package build from Electron 40.10.2.
  • Credential-free sandbox tests across 90%, 110%, and 125%; repeated hash routes, Cmd+N, reload, resize, hide/show, and app relaunch.
  • Live configuration and session state remain unchanged by sandbox tests.

Risk Assessment

Low — the production change only reasserts the already-persisted zoom level after a main-frame navigation event. Existing clamping, persistence, renderer notification, and window-specific wiring remain unchanged.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/desktop Electron desktop app (apps/desktop/*) labels Jul 30, 2026
@teknium1

Copy link
Copy Markdown
Collaborator

Thanks — this is a focused fix for an unfixed hash-navigation restoration gap. Current main restores zoom on did-finish-load only in apps/desktop/electron/main.ts:8596-8597, while the renderer uses HashRouter at apps/desktop/src/main.tsx:67. Electron defines did-navigate-in-page specifically for hash changes and supplies isMainFrame as its third argument (node_modules/electron/electron.d.ts:16292-16302).

The extracted helper preserves the existing persisted-state funnel, scopes the action to main-frame navigation, and retains the existing window-kind zoom opt-out. The unit coverage and Cmd/Ctrl+N Electron E2E exercise the relevant lifecycle path.

No blocking problems found. Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 30, 2026
@zqy1-1

zqy1-1 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

version 0.20.0
I meet the same bug.

@OutThisLife

Copy link
Copy Markdown
Contributor

Superseded by #94396 — thanks for finding this one, @clarkvines. Your diagnosis of the mechanism was right, and the fix in #94396 is your installZoomReassertOnNavigation verbatim, cherry-picked so authorship stays with you.

Two things changed on top of it:

It isn't macOS-specific. This PR described it as "Chromium resets file:// zoom to level 0 on hash-route navigation on macOS." The cause is Chromium's per-URL zoom store, and it reproduces on Windows — confirmed on real Electron 40.10.2 / Chromium 144 (win32), where a hash route with no zoom record reports 100% at did-navigate-in-page. A reporter's Preferences showed one record per route, including a session stranded at its own stale scale. Keeping the macOS framing would have sent the next reader looking in the wrong place.

The E2E now drives the reported path. The Cmd+N case is kept, but the primary test navigates to routes Chromium holds no record for, which is what opening a new session actually looks like to the per-URL store.

Worth noting for anyone reading later: the Desktop E2E job is disabled repo-wide right now (#76627), so neither spec runs in CI. What backs the fix is the live win32 probe plus the electron unit suite (1735 passing).

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

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Desktop Bug]: Zoom level resets unexpectedly when switching sessions/routes Desktop zoom level is persisted per hash route instead of app-wide

5 participants