Add interface zoom (⌘+ / ⌘- / ⌘0) to scale the whole app#69
Open
DragonnZhang wants to merge 2 commits into
Open
Add interface zoom (⌘+ / ⌘- / ⌘0) to scale the whole app#69DragonnZhang wants to merge 2 commits into
DragonnZhang wants to merge 2 commits into
Conversation
Adds an app-wide interface-zoom preference that scales the entire renderer (sidebar, navigator, chat, settings, dialogs) up or down, matching the standard desktop zoom in Claude Desktop, VS Code, and other apps. - ZoomProvider (renderer context, mirrors ReduceMotionProvider): owns a discrete zoom factor from a Chrome-like step ladder (50%-200%), applies it via document.documentElement.style.zoom, and persists it in localStorage (craft-zoom-level). Frontend-only; no IPC, no backend, no config.json. - Three action-registry entries under View - view.zoomIn (mod+=), view.zoomOut (mod+-), view.zoomReset (mod+0) - so the shortcuts appear in the Command Palette and Keyboard Shortcuts reference for free. Wired to the provider via a ZoomHotkeys bridge component. - A Zoom stepper (-/percentage/+ with reset) in Settings > Appearance > Interface for discoverability and mouse-only users. - i18n keys added to all 7 locales. - CDP e2e assertion (zoom.assert.ts) drives the stepper and asserts the percentage, the inline zoom on <html>, and the persisted value. Closes #68
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.
Closes #68
What & why
Every desktop app OpenWork is benchmarked against — Claude Desktop, VS Code, Codex/ChatGPT desktop, Slack, Discord — exposes an interface zoom that scales the whole UI up or down via the platform-standard ⌘+ / ⌘- / ⌘0 (Ctrl on Windows/Linux). OpenWork had none:
grep -rn "setZoomLevel\|zoomFactor\|webFrame\|zoom" apps/electron/srcfound nothing, and there was no such binding in the action registry. Users on high-DPI displays (or who want to fit more on screen) had no way to resize the whole app.This adds an app-wide interface-zoom preference — frontend-only, no backend / qwen-code change.
How
context/ZoomContext.tsx(new) —ZoomProvider, mirroring the mergedReduceMotionProvider. Owns a discrete zoom factor from a Chrome-like step ladder (50%–200%), applies it by settingdocument.documentElement.style.zoom(a Chromium-native property that scales the whole tree, including portalled dialogs), and clears the inline style at 100%. Persists inlocalStorage(craft-zoom-level) via the existinglib/local-storage.tshelper — no IPC, noconfig.json.actions/definitions.ts— three new View actions:view.zoomIn(mod+=),view.zoomOut(mod+-),view.zoomReset(mod+0). Registering them means they appear automatically in the Command Palette (⌘K) and the Settings → Keyboard Shortcuts reference.components/ZoomHotkeys.tsx(new) — a render-null bridge mounted insideActionRegistryProviderthat wires those actions to the provider viauseAction.main.tsx— mountsZoomProviderat the renderer root (insideReduceMotionProvider).pages/settings/AppearanceSettingsPage.tsx— a Zoom stepper (−/ percentage /+with reset) in Appearance → Interface, for discoverability and mouse-only users.lib/local-storage.ts— newzoomLevelkey.actions/action-i18n.ts+locales/*.json— 5 new i18n keys across all 7 locales.e2e/assertions/zoom.assert.ts(new) — CDP assertion (below).Verification (DoD)
Run in this PR's sandbox; all checks that don't require launching Electron pass with zero delta vs
main:bun run typecheck:all— no new errors.apps/electronreports exactly the 11 pre-existing errors (auto-update.tsowner/repo, asettings-default-thinkingtest tuple, two test files importingvitest) — none in files this PR touches; all other packages clean.bun test— the failing-test set is byte-for-byte identical to a cleanmainrun in the same environment: 56 failing tests on both, diff empty. This change adds zero new failures. (The rawN failline is order-dependent when the whole suite runs unisolated; the deterministic signal is the failing-test set.)bun run lint:i18n:parity— OK (1549 keys per locale, 7 locales). The 5 new keys are in every locale.eslinton all changed files — 0 errors. The new files add no warnings; the pre-existingno-localstorage/exhaustive-depswarnings are unchanged.bun run build:renderer, where this change lives) — ✅ built cleanly.bun build e2e/assertions/zoom.assert.ts) — ✅.CDP e2e assertion (
zoom.assert.ts)Drives the real built app over CDP entirely in the draft/no-session state (Settings only, no backend):
zoomstyle on<html>.document.documentElement.style.zoom === '1.1', andlocalStorage["craft-zoom-level"]is1.1— proving it applies and persists, not merely renders.zoomstyle is cleared, and the persisted value returns to1.Part of the autonomous desktop-feature loop (
loop-bot).🤖 Generated with Claude Code
Generated by Claude Code