Skip to content

feat(desktop): add auto-zoom scaling for high-DPI displays#406

Open
SuperComboGamer wants to merge 6 commits intopingdotgg:mainfrom
SuperComboGamer:feat/desktop-4k-auto-zoom
Open

feat(desktop): add auto-zoom scaling for high-DPI displays#406
SuperComboGamer wants to merge 6 commits intopingdotgg:mainfrom
SuperComboGamer:feat/desktop-4k-auto-zoom

Conversation

@SuperComboGamer
Copy link

@SuperComboGamer SuperComboGamer commented Mar 7, 2026

Windows does not automatically scale Electron app content for high-DPI displays the way macOS does, causing the app to
appear tiny on 4K/1440p monitors. This adds automatic zoom scaling to fix that.

  • Auto-detect display resolution and scale the desktop app UI for 4K/1440p monitors while keeping 1080p unchanged
  • Compute zoom factor from the display's DIP short edge relative to 1080p, snapped to 0.25 increments (max 3.0×)
  • Apply zoom on window creation, display change, move/resize across monitors, unmaximize, and leave-fullscreen
  • Clamp window bounds and minimum size to the display work area after zoom changes
  • Replace built-in viewMenu with custom View menu fixing Ctrl++ (zoom in) , and adding Ctrl+0 to reset to
    auto-zoom baseline
  • Re-entrancy guards prevent recursive setBounds → move loops; fullscreen/maximized states are skipped
  • On macOS the auto-zoom is a no-op since macOS handles HiDPI scaling natively

Note

Add auto-zoom scaling for high-DPI displays in the desktop app

  • On Windows and Linux, the app now computes a zoom factor based on the display's short edge relative to a reference size, scaling up for high-resolution displays; macOS always uses zoom factor 1.0.
  • Zoom In/Out menu actions adjust a persisted delta stored in a JSON preferences file, so user zoom preference survives restarts.
  • Reset Zoom clears the stored delta and recomputes zoom from display metrics.
  • Windows opened or moved to a different display recompute their zoom, minimum size, and on-screen bounds to fit the new display's work area.
  • Behavioral Change: window minimum size and bounds are now clamped to the display work area when not maximized or fullscreen; display metric changes (e.g. resolution/DPI changes) clear any user zoom delta on Windows/Linux.

Macroscope summarized 27ca07a.

@coderabbitai
Copy link

coderabbitai bot commented Mar 7, 2026

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7bab0b6d-5ff6-46c3-8ee1-a22a620f9ad3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.

Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present.

Auto-detect display resolution and scale the UI proportionally so the
app is usable on 4K/1440p monitors without affecting 1080p users.

- Compute zoom factor from the display's DIP short edge relative to
  1080p, snapped to 0.25 increments (max 3.0x)
- Apply zoom on window creation, display change, move/resize across
  monitors, unmaximize, and leave-fullscreen
- Clamp window bounds to the display work area after zoom changes
- Scale minimum window size with zoom, capped to the work area
- Replace built-in viewMenu with custom View menu supporting
  Ctrl+=/Ctrl+Plus (zoom in), Ctrl+- (zoom out), Ctrl+0 (reset)
- Guard against re-entrant setBounds->move loops and skip zoom
  adjustments while fullscreen or maximized
@t3dotgg
Copy link
Member

t3dotgg commented Mar 9, 2026

Couple Qs:

  1. If I set a zoom myself, will this override it?
  2. Is this windows-only? Can it be?
  3. How does it handle multiple monitors? Esp. if I have some that are HighDPI and others that are not

… zoom logic

- Store user zoom preference as a delta from auto-computed zoom so it
  transfers correctly across monitors with different DPIs
- Skip auto-zoom on macOS (Retina handles DPI natively)
- Clamp delta in adjustZoom to prevent unbounded accumulation
- Add NaN guard on zoom delta read/write
- Debounce display-metrics-changed handler
- Move reentrancy guard into applyAutoZoom (global Set, protects all call sites)
- Reset Zoom now applies to all windows
- Set zoom factor even when maximized/fullscreen
- Extract computeEffectiveZoom helper
@SuperComboGamer
Copy link
Author

SuperComboGamer commented Mar 9, 2026

@t3dotgg

If I set a zoom myself, will this override it?
No. Your manual zoom (Ctrl+= / Ctrl+-) is persisted and respected, I added zoom persistence in this PR since Electron doesn't have it built-in. Auto-zoom won't override it. Ctrl+0 resets back to auto.

Is this windows-only? Can it be?
Auto-zoom is Windows + Linux only. macOS is skipped since Retina handles DPI natively. Zoom persistence works on all platforms.

How does it handle multiple monitors?
Zoom is stored as a delta from each display's auto-computed, baseline not an absolute value. So if you bump zoom by +0.25 on a 4K monitor (auto 2.0 → 2.25), dragging to a 1080p monitor gives you 1.0 + 0.25 = 1.25, not 2.25. Your intent (“slightly bigger than default”) transfers correctly across displays.

Note: I don't have a Mac or Linux machine so I couldn't test on those platforms, but it should work, macOS just skips auto-zoom entirely and the zoom persistence uses standard Electron/Node APIs.

@github-actions github-actions bot added the vouch:unvouched PR author is not yet trusted in the VOUCHED list. label Mar 9, 2026
@SuperComboGamer
Copy link
Author

Closes #861

@github-actions github-actions bot added the size:L 100-499 changed lines (additions + deletions). label Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants