git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit3d02fbd5c1b286e36bd2b11fcd247793e336ca6d
parent415c6dded7
authorIsaac Freund <[email protected]>
date2026-02-09 11:11
protocol: clarify fullscreen initial configure

Currently if the window manager wants a new window to be rendered
fullscreen, it must make a propose_dimensions request (which does
not actually affect window dimensions) as well as a fullscreen request.

With this commit, it is now sufficient to make either a fullscreen
request or a propose_dimensions request in order for a window to be
mapped.

 protocol/river-window-management-v1.xml | 26 +++++++++++++++++---------
 river/Window.zig                        |  9 +++++----
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/protocol/river-window-management-v1.xml b/protocol/river-window-management-v1.xml
index a39ab79..d59fb26 100644
--- a/protocol/river-window-management-v1.xml
+++ b/protocol/river-window-management-v1.xml
@@ -311,9 +311,9 @@
       an xdg_toplevel or Xwayland window.
 
       A newly created window will not be displayed until the window manager
-      proposes window dimensions with the propose_dimensions request as part of
-      a manage sequence, the server replies with a dimensions event as part of
-      a render sequence, and that render sequence is finished.
+      makes a propose_dimensions or fullscreen request as part of a manage
+      sequence, the server replies with a dimensions event as part of a render
+      sequence, and that render sequence is finished.
     </description>
 
     <enum name="error">
@@ -412,9 +412,12 @@
         This event is sent as part of a render sequence before the render_start
         event.
 
-        It may be sent due to a propose_dimensions request in a previous manage
-        sequence or because a window independently decides to change its
-        dimensions.
+        It may be sent due to a propose_dimensions or fullscreen request in a
+        previous manage sequence or because a window independently decides to
+        change its dimensions.
+
+        The window will not be displayed until the first dimensions event is
+        received and the render sequence is finished.
       </description>
       <arg name="width" type="int"/>
       <arg name="height" type="int"/>
@@ -437,10 +440,9 @@
         When a propose_dimensions request is made, the server must send a
         dimensions event in response as soon as possible. It may not be possible
         to send a dimensions event in the very next render sequence if, for
-        example, the window takes too long to respond to the first proposed
+        example, the window takes too long to respond to the proposed
         dimensions. In this case, the server will send the dimensions event in a
-        future render sequence. The window will not be displayed until the first
-        dimensions event is received and the render sequence is finished.
+        future render sequence.
 
         Note that the dimensions of a river_window_v1 refer to the dimensions of
         the window content and are unaffected by the presence of borders or
@@ -908,6 +910,12 @@
         shall not affect the current position and dimensions of a fullscreen
         window.
 
+        When a fullscreen request is made, the server must send a dimensions
+        event in response as soon as possible. It may not be possible to send a
+        dimensions event in the very next render sequence if, for example, the
+        window takes too long to respond. In this case, the server will send the
+        dimensions event in a future render sequence.
+
         The compositor will clip window content, decoration surfaces, and
         borders to the given output's dimensions while the window is fullscreen.
         The effects of set_clip_box and set_content_clip_box are ignored while
diff --git a/river/Window.zig b/river/Window.zig
index 6c8fea9..2deeae6 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -692,7 +692,7 @@ pub fn manageFinish(window: *Window) bool {
     switch (window.state) {
         .init => unreachable,
         .ready => {
-            if (wm_requested.dimensions == null) {
+            if (wm_requested.dimensions == null and wm_requested.fullscreen == null) {
                 return false;
             }
             window.state = .initialized;
@@ -726,11 +726,12 @@ pub fn manageFinish(window: *Window) bool {
 
     if (wm_requested.fullscreen) |output| {
         const width, const height = output.sent.dimensions();
-        if (window.configure_sent.width != width) {
+        if (window.configure_sent.width != width or
+            window.configure_sent.height != height)
+        {
             window.configure_scheduled.width = width;
-        }
-        if (window.configure_sent.height != height) {
             window.configure_scheduled.height = height;
+            window.rendering_scheduled.resend_dimensions = true;
         }
     } else if (wm_requested.dimensions) |dimensions| {
         window.configure_scheduled.width = dimensions.width;