Skip to content

Fix halved Screen Bounds, WorkArea, and Size on Retina Macs#5168

Merged
leaanthony merged 5 commits into
wailsapp:v3-alphafrom
wayneforrest:v3-alpha-sync
Apr 20, 2026
Merged

Fix halved Screen Bounds, WorkArea, and Size on Retina Macs#5168
leaanthony merged 5 commits into
wailsapp:v3-alphafrom
wayneforrest:v3-alpha-sync

Conversation

@wayneforrest

@wayneforrest wayneforrest commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Description

Fix halved Screen Bounds, WorkArea, and Size on Retina Macs.

With the Fix.
INFO[15:44:17.959] [screen-probe] [0] scale=2.00 size=1496x967 bounds={X:0 Y:0
Width:1496 Height:967} physicalBounds={X:0 Y:0 Width:2992 Height:1934} workArea={X:0
Y:80 Width:1496 Height:858} physicalWorkArea={X:0 Y:160 Width:2992 Height:1716}

Without the Fix.
INFO[15:47:10.655] [screen-probe] [0] scale=2.00 size=748x484 bounds={X:0 Y:0 Width:748 Height:484} physicalBounds={X:0 Y:0 Width:1496 Height:967} workArea={X:0 Y:40 Width:748 Height:429} physicalWorkArea={X:0 Y:80 Width:1496 Height:858}

Fixes #5167

Type of change

Please select the option that is relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration using wails doctor.

  • Windows
  • macOS
  • Linux

If you checked Linux, please specify the distro and version.

Test Configuration

Please paste the output of wails doctor. If you are unable to run this command, please describe your environment in as much detail as possible.

Checklist:

  • I have updated website/src/pages/changelog.mdx with details of this PR
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • Bug Fixes
    • Corrected macOS Retina screen geometry so coordinates and sizes are converted to device pixels.
    • Improved multi-monitor behavior for edge-touch detection and work-area placement across displays by ensuring top-level screen coordinates are populated.
    • Fixed inconsistencies in coordinate and work-area calculations when using Retina/high-DPI displays.

@coderabbitai

coderabbitai Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e0cc0f30-2ce8-4f5d-a77b-9d95defe51cd

📥 Commits

Reviewing files that changed from the base of the PR and between a8acddf and a146f0f.

📒 Files selected for processing (1)
  • v3/UNRELEASED_CHANGELOG.md

Walkthrough

Converts NSScreen point-based coordinates and dimensions to device pixels in cScreenToScreen on macOS, updating top-level Screen.X/Y, Bounds, PhysicalBounds, and WorkArea assignments; updates the unreleased changelog to document the Retina-specific fix.

Changes

Cohort / File(s) Summary
Changelog Update
v3/UNRELEASED_CHANGELOG.md
Adds an entry describing the Retina-specific correction: point-based NSScreen values are converted to device pixels when assigning Physical* fields and top-level Screen.X/Y are set.
Retina Coordinate Scaling
v3/pkg/application/screen_darwin.go
Modifies cScreenToScreen to pre-multiply NSScreen-derived point coordinates/dimensions by screen.scaleFactor (via a toPhysical helper), affecting Screen.X/Y, Bounds, PhysicalBounds, WorkArea, and PhysicalWorkArea while leaving Size, ScaleFactor, ID, Name, IsPrimary, and Rotation unchanged.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

Bug, Documentation, MacOS, v3-alpha, size:M

Suggested reviewers

  • atterpac

Poem

🐰 I hopped through frames where pixels hide,
Scaled every point so screens align wide,
Retina no longer halves the view,
Windows snug where they’re meant to do,
Hooray — display and rabbit, both true! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: correcting halved Screen Bounds, WorkArea, and Size on Retina Macs.
Description check ✅ Passed The description covers the issue, includes before-and-after output demonstrating the fix, references the linked issue (#5167), and completes most required checklist items.
Linked Issues check ✅ Passed The PR directly addresses the objective in #5167 by fixing halved Screen Bounds, WorkArea, and Size values on Retina displays through proper scale factor handling.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the Retina display issue: changelog entry and the screen_darwin.go conversion logic with no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
v3/pkg/application/screen_darwin.go (1)

128-178: ⚠️ Potential issue | 🔴 Critical

Top-level Screen.X/Y are not rescaled by applyDPIScaling(), breaking the invariant that they must mirror Bounds.X/Y.

The applyDPIScaling() implementation (screenmanager.go:289–306) rescales Bounds, WorkArea, and Size, but does not touch top-level Screen.X or Screen.Y. After your change, both will initially be in device pixels from toPhysical(), but applyDPIScaling() will divide Bounds.X/Y into DIPs while leaving the top-level X/Y in device pixels. This violates the documented invariant that Screen.X/Y must mirror Bounds.X/Y (which is relied upon by move(), areScreensTouching(), and calculateScreenPlacement()). Either extend applyDPIScaling() to rescale top-level X/Y, or set them here to unscaled point values so they align with post-scaling Bounds.

Note: Size is handled correctly—it is reassigned to match scaled Bounds at lines 304–305, so it will end up in DIPs as intended.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@v3/pkg/application/screen_darwin.go` around lines 128 - 178, cScreenToScreen
currently sets top-level Screen.X and Screen.Y using toPhysical (device pixels)
while applyDPIScaling rescales Bounds.* into DIPs, breaking the invariant that
Screen.X/Y mirror Bounds.X/Y; fix by making Screen.X and Screen.Y use the
unscaled point values (i.e., use the raw screen.x/screen.y points rather than
toPhysical) so they match Bounds after applyDPIScaling, or alternatively update
applyDPIScaling to also rescale top-level Screen.X/Screen.Y (modify
applyDPIScaling in screenmanager.go to divide Screen.X/Screen.Y by ScaleFactor);
update cScreenToScreen or applyDPIScaling accordingly (see function
cScreenToScreen, struct Screen, and applyDPIScaling).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@v3/pkg/application/screen_darwin.go`:
- Around line 128-178: cScreenToScreen currently sets top-level Screen.X and
Screen.Y using toPhysical (device pixels) while applyDPIScaling rescales
Bounds.* into DIPs, breaking the invariant that Screen.X/Y mirror Bounds.X/Y;
fix by making Screen.X and Screen.Y use the unscaled point values (i.e., use the
raw screen.x/screen.y points rather than toPhysical) so they match Bounds after
applyDPIScaling, or alternatively update applyDPIScaling to also rescale
top-level Screen.X/Screen.Y (modify applyDPIScaling in screenmanager.go to
divide Screen.X/Screen.Y by ScaleFactor); update cScreenToScreen or
applyDPIScaling accordingly (see function cScreenToScreen, struct Screen, and
applyDPIScaling).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ff8fe672-0bdc-4792-ac3e-8f90dfb80649

📥 Commits

Reviewing files that changed from the base of the PR and between 103b3de and 3d3e74a.

📒 Files selected for processing (2)
  • v3/UNRELEASED_CHANGELOG.md
  • v3/pkg/application/screen_darwin.go

@wayneforrest

Copy link
Copy Markdown
Contributor Author

wails3 doctor
Wails (v3.0.0-alpha.71) Wails Doctor

System

┌──────────────────────────────────────────────────┐
| Name | MacOS |
| Version | 26.4.1 |
| ID | 25E253 |
| Branding | MacOS 26.4.1 |
| Platform | darwin |
| Architecture | arm64 |
| Apple Silicon | true |
| CPU | Apple M1 Max |
| CPU 1 | Apple M1 Max |
| CPU 2 | Apple M1 Max |
| GPU | 32 cores, Metal Support: Metal 4 |
| Memory | 64 GB |
└──────────────────────────────────────────────────┘

Build Environment

┌────────────────────────────────┐
| Wails CLI | v3.0.0-alpha.71 |
| Go Version | go1.25.3 |
| -buildmode | exe |
| -compiler | gc |
| CGO_CFLAGS | |
| CGO_CPPFLAGS | |
| CGO_CXXFLAGS | |
| CGO_ENABLED | 1 |
| CGO_LDFLAGS | |
| GOARCH | arm64 |
| GOARM64 | v8.0 |
| GOOS | darwin |
└────────────────────────────────┘

Dependencies

┌──────────────────────────────────────────────────────────────────────────────┐
| Xcode cli tools | 2416 |
| npm | 11.5.2 |
| *NSIS | Not Installed. Install with brew install makensis. |
| docker | *Docker version 27.4.0, build bde2b89 (daemon not running) |
| |
└────────────────────────── * - Optional Dependency ───────────────────────────┘

Checking for issues

SUCCESS No issues found

@atterpac

Copy link
Copy Markdown
Member

Thanks for the PR! This looks good to me, I believe @leaanthony setup an automated change log?

Lea does this mean PR's shouldnt include change to v3/UNRELEASED_CHANGELOG.md? Should it just be removed?

Pending that clarification good to merge imo

@wayneforrest

Copy link
Copy Markdown
Contributor Author

Hi @leaanthony - Can you please update what to do regarding the v3/UNRELEASED_CHANGELOG.md - thanks.

@leaanthony leaanthony merged commit 2ae7e42 into wailsapp:v3-alpha Apr 20, 2026
2 of 5 checks passed
@leaanthony

Copy link
Copy Markdown
Member

Thanks @wayneforrest 🙏

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants