Skip to content

Desktop zoom resets to 100% after restarting the app #50168

Closed

Description

@mitivil

Description

OpenCode Desktop does not remember the zoom selected with Ctrl++ / Ctrl+- (Cmd on macOS). After quitting and reopening the app, the interface returns to 100%. Expected: restore the last selected zoom.

In current v2, wireZoom() explicitly sets the factor to 1 and zoom changes are not persisted. This is still reproducible despite the earlier request #10423 being closed. Disabling pinch zoom also resets keyboard-selected zoom (#49096).

OpenCode version

2.0.11 / current v2

Steps to reproduce

  1. Increase the desktop UI zoom with Ctrl++.
  2. Quit OpenCode Desktop completely.
  3. Open it again: zoom returns to 100%.

Operating System

Linux

Activity

  1. onelpawarai-X commented on Sep 20, 2026

    @onelpawarai-X

    🚀 Introducing ZYRAXON-AI: My Ultimate All-in-One Powerful Desktop Agent!

    I am thrilled to share my passion project—ZYRAXON-AI—a next-level, open-source desktop AI coding and automation agent designed to push the boundaries of what is possible.

    Check it out here: https://github.com/onelpawarai-X/ZYRAXON-AI.git

    This isn’t just another tool; it's an all-in-one powerhouse featuring Beast Mode (with self-evolution, persistent memory, mission control, and a sub-agent army), real-time Screen Vision, advanced code analysis for 40+ languages, system monitoring, and API testing capabilities.

    🌍 Looking for Collaborators & Visionaries:
    I am not building this just for today; my vision is to take ZYRAXON-AI to a level far beyond anything else out there, keeping it miles ahead of the competition. To achieve this, I am actively looking for trustworthy, passionate, and skilled individuals who want to collaborate, build, and grow together on this journey.

    Give it a try, star the repo, and if you share the same drive to create something extraordinary, let’s connect and make it happen! 💡✨

  2. MirceaZahan commented on Sep 24, 2026

    @MirceaZahan

    Please fix this.

  3. DonMecca commented on Sep 26, 2026

    @DonMecca

    Reproduction confirmed on the current stable build, with the mechanism isolated.

    • App: OpenCode Desktop 2.0.18, macOS 27.0 (arm64), Electron 44.4.3 / Chrome 152
    • Repro: zoom in with Cmd +, quit fully, reopen → back to 100%

    The reset is an unguarded line in wireZoom

    packages/desktop/src/main/windows.ts resets zoom on every window creation, with no guard:

    function wireZoom(win: BrowserWindow) {
      pinchZoomEnabled.set(win, getPinchZoomEnabled())
      win.webContents.setZoomFactor(1)          // line 520 — unconditional
      ...

    Note the asymmetry with line 528 in the same function, which is guarded:

    if (win.webContents.getZoomFactor() !== 1) win.webContents.setZoomFactor(1)   // line 528

    So the handler carefully avoids redundant resets, while window setup performs one unconditionally — discarding the persisted value before the UI settles.

    Chromium is persisting the zoom correctly

    This is not a failure to save. Preferences contains a live per-origin entry:

    "partition": { "per_host_zoom_levels": { "12321934231736050979": { "renderer": 1.7967234568371628 } } }

    That value tracks my zoom gestures precisely (it changed from 1.8454 to 1.7967 across sessions). Chromium restores it, and the app then overwrites it.

    Visible signature

    At launch the shell renders large, then shrinks to 100% — the restored zoom is briefly visible before wireZoom clobbers it. This is observable and may be a useful regression-test signal.

    Enabling Pinch Zoom does not help

    Turning on Settings → General → Pinch Zoom (pinchZoomEnabled: true is written to opencode.settings correctly) only affects the zoom-changed handler. It cannot undo the unconditional reset at line 520, so zoom still returns to 100% after restart. This is distinct from #49096 — here pinch zoom is enabled.

    No user-side workaround exists

    • ZOOM_FACTOR_KEY / zoomFactor is absent from the 2.0.18 bundle, so pre-seeding opencode.settings has no effect.
    • The menu (view.zoomIn / view.zoomOut) and keyboard paths call the same setter with no store write.
    • No OPENCODE_ZOOM env var or zoom config field exists.

    Note

    PR #50169 ("fix(desktop): persist zoom across app restarts") appears to address this and is currently CI-green and mergeable, but unreviewed. Flagging in case that helps it get picked up.

  4. vokasug commented on Sep 29, 2026

    @vokasug

    Confirmed on the latest stable build — this is a regression introduced in the 2.0 desktop line (zoom persisted fine in 1.x).

    • App: OpenCode Desktop 2.0.19 (CFBundleShortVersionString/CFBundleVersion = 2.0.19, "/Applications/opencode.app")
    • OS: macOS 26.7.1 (build 25G241), Darwin kernel 25.6.0, arm64
    • Shell: /bin/zsh
    • Channel: latest

    Reproduction

    1. Open OpenCode Desktop.
    2. Increase the UI scale with Cmd + (View → Zoom In) a few steps.
    3. Quit the app completely (Cmd Q).
    4. Reopen it — the interface is back to 100%.

    Reproduces every time, not intermittently.

    Expected

    The last selected zoom factor is restored on relaunch, as it was in the 1.x desktop builds.

    Actual

    Scale resets to 100% on every launch. There is no user-side workaround: no zoomFactor/ZOOM_FACTOR_KEY in opencode.settings, and the native View menu and keyboard shortcuts write nothing to the store — they all funnel through the same non-persisting setter that wireZoom() overwrites with setZoomFactor(1) on window creation.

    Regression detail

    This worked in the 1.x desktop app (the selected scale survived a restart). It broke when the desktop shell was rewritten for 2.0, so it should be treated as a V2 regression rather than a new feature request.

    Also relevant: #49096 (disabling pinch zoom also resets the scale) and the open fix PR #50169, which is CI-green and mergeable but still unreviewed. Bumping in case it helps get the fix merged — this is a small but very noticeable papercut for anyone who needs a larger UI on macOS.

  5. TurboBinCN commented on Oct 7, 2026

    @TurboBinCN

    Confirmed on Linux desktop. Two facts that make this more than "the value isn't saved":

    1. There is no field to save into. The settings object I can find has no zoom/font key at all — only defaultServerUrl, firstLaunchOnboardingComplete, wslServers, pinchZoomEnabled, keepScreenActive, backgroundColor, windowIds, bundledCliVersion. And after zooming to 1.2x, localStorage contains no zoom entry (only language, per-window last-active-url, notification flags, opencode-theme-css-dark). So wireZoom() setting the factor to 1 on startup is not overwriting a stored value — there is nothing stored to overwrite.

    2. Verification note for whoever writes the fix: devicePixelRatio is the zoom factor (the ±0.2 steps map to dpr 1.2 / 1.4 / 1.6). Don't infer the factor from innerWidth — it changes with zoom, so using it as a denominator is self-contradictory (this produced a false "1.00x" reading during my own testing).

    Suggested shape, borrowing what already exists:

    • add zoomFactor (or defaultZoomLevel + rememberLastZoom) to settings;
    • persist per window id — settings already has windowIds, so the storage shape is there;
    • apply on window creation before first paint, keeping the existing 0.2–10 clamp;
    • and guard the startup reset so it only fires when no persisted value exists.

    Until that lands, the only way to get a stable zoom is replaying Ctrl+0 then Ctrl+= after the window loads (the app's own zoom path), which is what a small external watchdog has to do — no fork needed, but it does show that the persistence gap is real rather than a settings-UI oversight.

  6. wc4440222 commented on Oct 13, 2026

    @wc4440222

    Confirming this is still reproducible on Windows 10 + Desktop 2.0.27 — same behavior (Ctrl+ zoom lost after full quit).

    Additional finding from inspecting the 2.0.27 desktop bundle (app.asar): the zoom reset is not accidental.
    On window creation the main process calls something equivalent to qd(u), which does
    webContents.setZoomFactor(1) unconditionally, and the zoom-changed handler also forces
    setZoomFactor(1) whenever pinch-zoom is disabled. So the persisted value in Electron
    Preferences (partition.per_host_zoom_levels) is read but immediately discarded.

    Workaround that works today: launch with --force-device-scale-factor=1.25 (Chromium-level,
    applies before the app-level reset). A window.defaultZoomLevel config option or
    "remember last zoom" would fix this properly.

  7. wc4440222 commented on Oct 13, 2026

    @wc4440222

    Correction to my comment above: the OS is Windows 11 (not Windows 10), Desktop 2.0.27. Same repro steps and findings apply.

  8. Railander commented on Oct 15, 2026

    @Railander

    Confirming this is still reproducible from the update path too.

    • App: OpenCode Desktop v2 (CLI sidecar 2.0.29), Windows desktop + WSL server
    • Repro: set UI zoom with Ctrl +/- , let the desktop app update / restart οποία — zoom is back at 100% afterwards.
    • Expected: last selected zoom is restored after update/restart.

    Same root cause as described above (zoom not persisted, reset on window creation) — just flagging that an app update triggers it as well, not only a manual quit/reopen.

  9. darknose commented on Oct 16, 2026

    @darknose

    Independent confirmation on the current latest build.

    • App: OpenCode Desktop 2.0.31 (CFBundleShortVersionString = 2.0.31), macOS 27.0 (Darwin 27.0.0, arm64), /Applications/OpenCode.app
    • Channel: latest (the auto-updater reports 2.0.31 is the newest version)
    • Repro: Cmd + a few steps → quit the app completely → reopen → back to 100%. Reproduces every time, not intermittently.

    Bundle inspection of 2.0.31 matches the findings earlier in this thread:

    • On window creation the main process runs wireZoom (minified as qd), which calls win.webContents.setZoomFactor(1) unconditionally; the zoom-changed handler later in the same function is guarded, matching the asymmetry described above.
    • The renderer keeps zoom only in memory (a module-level value initialised to 1) and goes through getZoomFactor() / setZoomFactor() over IPC. There is no store write anywhere.
    • opencode.settings has no zoom key and the bundle contains no ZOOM_FACTOR_KEY, so there is no user-side workaround.
    • Chromium still writes the per-origin value into Preferences → partition.per_host_zoom_levels (observed on this machine), which the startup reset then discards.

    Still reproducible on 2.0.31. PR #50169 (CI-green, reviewed by @DonMecca) is the fix.

  10. peihao0928 commented on Oct 24, 2026

    @peihao0928

    Independent confirmation on 2.1.4 (macOS).

    • App: OpenCode Desktop 2.1.4, macOS 26.3.1 (Darwin 25.3.0, arm64), /Applications/OpenCode.app
    • Channel: latest (the updater feed currently serves 2.1.4)
    • Repro: Cmd + twice → quit the app → relaunch → back to 100%. Reproduces every time, not intermittently.

    Bundle inspection of 2.1.4 matches the earlier findings:

    • The window-setup path (qd / wireZoom in out/main/desktop-*.js) unconditionally runs webContents.setZoomFactor(1) on every window creation.
    • WindowSetZoomFactor only calls setZoomFactor(); nothing writes the factor to persistent storage.
    • ~/Library/Application Support/ai.opencode.desktop/opencode.settings contains firstLaunchOnboardingComplete, windowIds, backgroundColor, pinchZoomEnabled — no zoom key.

    Related gap in the same build: the desktop settings schema already defines appearance.fontSize (default 14), and the Appearance panel exposes UI/code/terminal font families but no font-size control, and I could not find appearance.fontSize applied anywhere in the renderer. So users have no persistent way to enlarge text at all.

    Minor detail: zoom survives while the window stays open (minimizing and Cmd+W on a tab are fine); only window recreation / quitting resets it.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions