Skip to content

Wayland: fix min/max size hints and resize increments - #4717

Open
njallam wants to merge 5 commits into
rust-windowing:masterfrom
njallam:wayland-size-hints-and-increments
Open

njallam wants to merge 5 commits into
rust-windowing:masterfrom
njallam:wayland-size-hints-and-increments

Conversation

@njallam

@njallam njallam commented Sep 26, 2026 •

Copy link
Copy Markdown

Fixes #4713
Fixes #4715

Having a go at fixing my above bug reports; this PR fixes all problems I listed on those two issues, tested in the same way.

Notable changes

  • A minimum or maximum size set while not resizable now waits for set_resizable(true), where X11 sends it straight away.

    • xdg-shell has no resizable flag, so a non-resizable window sends the same size as both minimum and maximum.
    • Sending a new limit would replace one of them, either letting the window resize or putting the minimum above the maximum (invalid_size).
  • A window made non-resizable while maximized is fixed to the size it restores to, and maximizing a non-resizable window does not change this.

  • With no requested minimum, a surface is never smaller than one increment. Before, an axis below one increment fell to 2x1.

    • E.g. a 5x5 request with 10x20 increments now opens at 10x20 instead of 2x1.
  • A zero increment counts as 1 on that axis rather than panicking. Windows ignores both increments if either is zero, and macOS clamps each axis to 1 when set but ignores both at window creation, so this is a best guess.

  • The hints are sent on every resize, including each configure of a drag.

    • They include the decoration borders, which the first configure, fullscreen, set_decorate and decoration mode changes can add or remove.
    • resize already sends the window geometry, opaque region, blur and viewport each time, so the hints aren't cached either.
  • Tested on all platforms changed

  • Added an entry to the changelog module if knowledge of this change could be valuable to users

  • Updated documentation to reflect any user-facing changes, including notes of platform-specific behavior

  • Created or updated an example program if it would help users understand this functionality

`set_min_surface_size` and `set_max_surface_size` stored the sizes with the decoration borders added, so `reload_min_max_hints` added the borders a second time.
`set_resizable(false)` also overwrote the stored sizes with the current size, so the window stayed fixed at that size after `set_resizable(true)`.

Store the sizes as requested, as X11 does, and let `reload_min_max_hints` alone build the hints, adding the borders and fixing both hints to the current size while not resizable.
Unlike X11, a limit set while not resizable is now only sent once the window is resizable again.
Sending it straight away would replace one of the two fixed hints, either letting the window resize or putting the minimum above the maximum.
The stored minimum is no longer clamped to `MIN_WINDOW_SIZE`, so clamp the size snapped to resize increments instead.
The hints were sent before the frame existed and never re-sent, so they left out the titlebar and went stale when fullscreen or decorations changed the borders.

Reload them on every resize.
A non-resizable window is pinned to its stateless size, so maximizing it does not move the pin.
Changing the decoration mode now also resizes, so the window geometry and hints follow the frame being added or removed.
Increments were aligned from the internal `2x1` minimum, so an aligned `w x h` with increments `a x b` snapped to `(w - a + 2) x (h - b + 1)`.

Align from the requested minimum, or from zero, and round a size below one increment up to the first aligned size.
The configure that clears `RESIZING` was not snapped, so releasing the mouse returned the window to the unaligned pointer-derived size.
Also snap the configure that follows a resize.
An increment of `0` panicked with a division by zero on the first snapped configure.

Treat it as `1`, which constrains nothing.
@njallam
njallam requested a review from kchibisov as a code owner September 26, 2026 11:57

This branch has not been deployed

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Wayland: min/max hints don't match the requested surface sizes Wayland: resize increments shrink the axis that isn't being dragged

1 participant