Skip to content

fix: accurate window sizing and support for content sizing on Linux/Wayland with CSD#49209

Merged
jkleinsc merged 10 commits intoelectron:mainfrom
mitchchn:mitch/logical-bounds
Feb 17, 2026
Merged

fix: accurate window sizing and support for content sizing on Linux/Wayland with CSD#49209
jkleinsc merged 10 commits intoelectron:mainfrom
mitchchn:mitch/logical-bounds

Conversation

@mitchchn
Copy link
Copy Markdown
Member

@mitchchn mitchchn commented Dec 12, 2025

Description of Change

Fixes #48589.
Fixes #48588.

Background reading for maintainers: https://electronhq.slack.com/docs/T394SAQKC/F09ME0YPPV1.

This PR affects Linux environments which use CSD on Wayland. Today that means mostly just GNOME, but in the near future it will include frameless windows on any desktop environment. I regularized bounds handling and fixed edge cases to ensure:

  • Windows are created at the exact size requested by the user, both with and without without content sizing.
  • Windows can be resized accurately with setBounds/SetSize/setContentSize (if the compositor supports this).
  • BrowserWindow.getBounds reports the logical size of the window, without leaking invisible decoration insets
  • Windows first appear in the center of the screen instead of the top left corner.
  • Windows preserve their expected bounds across minimize, maximize, restoring, tiling, etc., without shrinking or flickering or suddenly "jumping" to a new size on focus changes or when the resize handle is grabbed.
  • Min and max sizes are respected (with one edge case for max size that will require a separate Chromium patch).

e.g.: A window created at 800x600 on GNOME will now visually measure 800x600 including the titlebar, just like on other platforms, and getBounds will report 800x600. If the window is created with useContentSize: true, it will visually measure something like 800x650, with an 800x600 content area. Bounds will be stable throughout the window lifecycle, and future bounds operations will work consistently and as expected.

Thought process

When CSD is in use, Chromium's accelerated widget is larger than the visible window frame. An 800x600 window might be inset into an 844x844 widget, with the outer part being used for shadows and resize targets. Electron is now aware of this possibility and has tools to manage it consistently.

good diagram drawio

Stabilizing CSD bounds fixes a large class of interaction quirks on Wayland which were caused by the compositor fighting with Electron over confcliting size constraints.It is also a necessary pre-req to introduce shadows to frameless windows: #48570. (Some of this PR anticipates that upcoming work by hoisting shared methods into FramelessView.)

The bulk of the PR is about adding awareness of the difference between the window's "logical bounds" and the total "widget bounds" to native_window_views. This code is used on both Linux and Windows, and I tried to keep the logic as platform-independent as possible, both to avoid ifdefs, but also because Windows also has similar issues with resize target bounds that extend past the logical/client area which these interfaces may be able to help with in the future.

In general, Electron should now be able to handle "widgets that are larger than the actually visible window/frame" as a platform-independent problem, whenever it comes up. At a high level, the philosophy here is:

  • Public bounds APIs (setBounds, getBounds and derivatives) deal in logical geometric bounds instead of the total bounds of the accelerated widget. These APIs always strip out/convert invisible insets used by the widget for shadows, decorations, and resize targets.
  • FramelessView impls control how this conversion works according to their platform-specific needs. The base case is that they have 0-width insets, so logical bounds are equivalent to widget bounds.
  • Callers can still operate on the widget() directly if they need to manipulate or read the total underlying bounds.

So there is some more internal complexity to negotiate the difference between logical and widget bounds spaces, but most callers should only care about logical bounds, especially in APIs exposed to JS.

Checklist

Release Notes

Notes: Fixed several issues with consistent window sizing and resizing on Linux when CSD is in use (e.g. on GNOME/Wayland) and added support for creating content-sized windows.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened recently label Dec 12, 2025
@electron-cation electron-cation bot removed the new-pr 🌱 PR opened recently label Dec 19, 2025
@mitchchn mitchchn force-pushed the mitch/logical-bounds branch from efd7de2 to e7d91d9 Compare January 2, 2026 21:04
@ckerr ckerr self-requested a review January 5, 2026 21:14
@ckerr ckerr added semver/patch backwards-compatible bug fixes wayland labels Jan 5, 2026
@mitchchn
Copy link
Copy Markdown
Member Author

FYI @ckerr this is the "separate Chromium patch" I mentioned in the description. I landed it the other day: https://chromium-review.googlesource.com/c/chromium/src/+/7442667. It makes some of the math for min/max size constraints more consistent but I think it's best saved for a followup.

Copy link
Copy Markdown
Member

@ckerr ckerr left a comment

Choose a reason for hiding this comment

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

Sorry for the extreme tardiness of this review.

This is a nice piece of work, and that "When a window isn't a window" document was extremely helpful. I learned a lot from it.

@mitchchn mitchchn requested a review from ckerr February 10, 2026 18:24
Copy link
Copy Markdown
Member

@ckerr ckerr left a comment

Choose a reason for hiding this comment

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

Looks like the only remaining thing for CI to go green is needing backport labels. @mitchchn what branches did you want to target with this?

@nikwen
Copy link
Copy Markdown
Member

nikwen commented Feb 12, 2026

This is a big change, so I'd suggest doing 41, maybe 40, but not further than that.

@mitchchn
Copy link
Copy Markdown
Member Author

Let's do 41 for this and especially the followup.

@jkleinsc jkleinsc added the target/41-x-y PR should also be added to the "41-x-y" branch. label Feb 17, 2026
@jkleinsc jkleinsc merged commit 931c257 into electron:main Feb 17, 2026
108 of 109 checks passed
@release-clerk
Copy link
Copy Markdown

release-clerk bot commented Feb 17, 2026

Release Notes Persisted

Fixed several issues with consistent window sizing and resizing on Linux when CSD is in use (e.g. on GNOME/Wayland) and added support for creating content-sized windows.

trop bot added a commit that referenced this pull request Feb 17, 2026
…ayland with CSD (#49209)

* fix window sizing and content sizing on Linux when CSD is in use

* fixed size constraints

* simplify min/max size calculation

* use base window size for min/max

* moved windows min/max size overrides

* remove unnecessary checks for client frame

* cleanup

Co-authored-by: Mitchell Cohen <mitch.cohen@me.com>
@trop
Copy link
Copy Markdown
Contributor

trop bot commented Feb 17, 2026

I have automatically backported this PR to "41-x-y", please check out #49835

@trop trop bot added in-flight/41-x-y and removed target/41-x-y PR should also be added to the "41-x-y" branch. labels Feb 17, 2026
jkleinsc pushed a commit that referenced this pull request Feb 18, 2026
…ayland with CSD (#49835)

fix: accurate window sizing and support for content sizing on Linux/Wayland with CSD (#49209)

* fix window sizing and content sizing on Linux when CSD is in use

* fixed size constraints

* simplify min/max size calculation

* use base window size for min/max

* moved windows min/max size overrides

* remove unnecessary checks for client frame

* cleanup

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Mitchell Cohen <mitch.cohen@me.com>
@trop trop bot added merged/41-x-y PR was merged to the "41-x-y" branch. and removed in-flight/41-x-y labels Feb 18, 2026
kycutler pushed a commit to kycutler/electron that referenced this pull request Feb 26, 2026
…ayland with CSD (electron#49209)

* fix window sizing and content sizing on Linux when CSD is in use

* fixed size constraints

* simplify min/max size calculation

* use base window size for min/max

* moved windows min/max size overrides

* remove unnecessary checks for client frame

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

Labels

merged/41-x-y PR was merged to the "41-x-y" branch. semver/patch backwards-compatible bug fixes wayland

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BrowserWindow.getBounds() includes transparent space taken up by shadows on Wayland Windows shrink the first time they lose focus on Wayland

5 participants