Skip to content

Add interface zoom (⌘+ / ⌘- / ⌘0) to scale the whole app up or down #68

Description

@DragonnZhang

Problem or Motivation

Every mainstream desktop app that OpenWork is benchmarked against exposes an interface zoom control that scales the entire UI up or down, driven by the platform-standard keyboard shortcuts ⌘+ / ⌘- / ⌘0 (Ctrl on Windows/Linux):

  • Claude Desktop — View → Zoom In / Zoom Out / Actual Size (⌘+ / ⌘- / ⌘0).
  • VS Code — View → Appearance → Zoom In/Out/Reset (same shortcuts).
  • Codex desktop / ChatGPT desktop / Slack / Discord — all ship the same ⌘+/⌘-/⌘0 zoom.

OpenWork has no interface zoom today. grep -rn "setZoomLevel\|zoomFactor\|webFrame\|zoom" apps/electron/src finds nothing, and there is no ⌘+/⌘-/⌘0 binding in the action registry (apps/electron/src/renderer/actions/definitions.ts). Users on high-DPI displays who want everything (sidebar, chat, settings, dialogs) larger — or users who want to fit more on screen — have no way to do it. This is an accessibility and comfort gap, and a basic desktop-app expectation.

Note: this is distinct from any per-surface "chat text size" / "conversation width" proposals — interface zoom scales the whole renderer (sidebars, navigator, settings, dialogs, composer), not just message text.

Proposed Solution

A renderer-only, frontend-only interface-zoom preference:

  • A ZoomProvider (renderer context, mirrors the merged ReduceMotionProvider pattern) that owns a discrete zoom factor from a Chrome-like step list (50%–200%), applies it by setting document.documentElement.style.zoom, and persists it in localStorage (craft-zoom-level) so it survives restarts. No IPC, no backend, no config.json.
  • Three new action-registry entries — view.zoomIn (mod+=), view.zoomOut (mod+-), view.zoomReset (mod+0) — under the existing View category. Registering them means they automatically appear in the Command Palette (⌘K) and the Settings → Keyboard Shortcuts reference for free.
  • A Zoom control in Settings → Appearance → Interface: a / percentage / + stepper with a Reset affordance, for discoverability and mouse-only users (parallels Claude Desktop's View menu entries).
  • i18n keys added to all 7 locales (en, de, es, hu, ja, pl, zh-Hans).

Feasibility: frontend-only. CSS zoom on <html> is a Chromium-native property that scales the whole tree including portalled dialogs; persistence reuses the existing lib/local-storage.ts helper; the shortcuts reuse the existing action-registry/hotkey infrastructure. The qwen-code backend is untouched.

Acceptance criteria (what the CDP assertion will check)

Driving the real built app over CDP, entirely in the draft/no-session state (Settings only, no backend):

  1. Open Settings → Appearance → Interface; the Zoom control renders, showing 100% initially, with no inline zoom style on <html>.
  2. Click Zoom in → the percentage rises (e.g. 110%), document.documentElement.style.zoom becomes the matching factor, and localStorage["craft-zoom-level"] persists it.
  3. Click Reset → back to 100%, the inline zoom style is cleared, and the persisted value returns to the default — proving it applies, persists, and reverts, not merely renders.

Alternatives Considered

  • Electron webFrame.setZoomFactor (native webContents zoom): would require exposing webFrame through the preload bridge and does not persist across reloads on its own. The CSS-zoom approach is purely renderer, persists via the existing localStorage helper, and is trivially assertable over CDP — strictly simpler for a frontend-only change.

Filed by the autonomous desktop-feature loop (loop-bot).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions