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

commit3e7d290f48ed7e82bb53f6ab5d14c9ad5ab95b70
parentd863318f37
authorIsaac Freund <[email protected]>
date2024-12-29 15:01
Window: send dimensions event on change

 river/Seat.zig           | 55 +++++++++++++++++++++++++-----------------------
 river/Window.zig         | 20 +++++++++++++-----
 river/WindowManager.zig  |  2 +-
 river/XdgToplevel.zig    | 10 ++-------
 river/XwaylandWindow.zig |  4 +---
 5 files changed, 48 insertions(+), 43 deletions(-)

diff --git a/river/Seat.zig b/river/Seat.zig
index 643cd6f..d43dc79 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -238,27 +238,13 @@ pub fn queueEvent(seat: *Seat, event: Event) void {
 pub fn processEvents(seat: *Seat) void {
     assert(server.wm.state == .idle);
 
+    // Only process events while there is no pending state to be sent to the window manager.
+    // The window manager might decide to change focus or redefine keyboard/pointer bindings
+    // in response to the pending update.
     var expect_frame: bool = false;
-    while (seat.event_queue.readItem()) |event| {
-        const pg = server.input_manager.pointer_gestures;
-        switch (event) {
-            .keyboard_key => |ev| ev.keyboard.processKey(&ev.key),
-            .keyboard_modifiers => |ev| ev.keyboard.processModifiers(&ev.modifiers),
-
-            .pointer_motion_relative => |ev| seat.cursor.processMotionRelative(&ev),
-            .pointer_motion_absolute => |ev| seat.cursor.processMotionAbsolute(&ev),
-            .pointer_button => |ev| seat.cursor.processButton(&ev),
-            .pointer_axis => |ev| seat.cursor.processAxis(&ev),
-            .pointer_frame => seat.wlr_seat.pointerNotifyFrame(),
-
-            .pointer_swipe_begin => |ev| pg.sendSwipeBegin(seat.wlr_seat, ev.time_msec, ev.fingers),
-            .pointer_swipe_update => |ev| pg.sendSwipeUpdate(seat.wlr_seat, ev.time_msec, ev.dx, ev.dy),
-            .pointer_swipe_end => |ev| pg.sendSwipeEnd(seat.wlr_seat, ev.time_msec, ev.cancelled),
-
-            .pointer_pinch_begin => |ev| pg.sendPinchBegin(seat.wlr_seat, ev.time_msec, ev.fingers),
-            .pointer_pinch_update => |ev| pg.sendPinchUpdate(seat.wlr_seat, ev.time_msec, ev.dx, ev.dy, ev.scale, ev.rotation),
-            .pointer_pinch_end => |ev| pg.sendPinchEnd(seat.wlr_seat, ev.time_msec, ev.cancelled),
-        }
+    while (!server.wm.pending.dirty or expect_frame) {
+        const event = seat.event_queue.readItem() orelse break;
+        seat.processEvent(event);
 
         // Don't split up pointer events grouped by a frame event
         switch (event) {
@@ -268,17 +254,34 @@ pub fn processEvents(seat: *Seat) void {
             .pointer_axis,
             => {
                 expect_frame = true;
-                continue;
             },
             .pointer_frame => expect_frame = false,
             else => assert(!expect_frame),
         }
+    }
 
-        if (server.wm.pending.dirty) {
-            // Wait for feedback from the window manager before further processing.
-            // The window manager might decide to change focus or redefine keyboard/pointer bindings.
-            break;
-        }
+    assert(!expect_frame);
+}
+
+fn processEvent(seat: *Seat, event: Event) void {
+    const pg = server.input_manager.pointer_gestures;
+    switch (event) {
+        .keyboard_key => |ev| ev.keyboard.processKey(&ev.key),
+        .keyboard_modifiers => |ev| ev.keyboard.processModifiers(&ev.modifiers),
+
+        .pointer_motion_relative => |ev| seat.cursor.processMotionRelative(&ev),
+        .pointer_motion_absolute => |ev| seat.cursor.processMotionAbsolute(&ev),
+        .pointer_button => |ev| seat.cursor.processButton(&ev),
+        .pointer_axis => |ev| seat.cursor.processAxis(&ev),
+        .pointer_frame => seat.wlr_seat.pointerNotifyFrame(),
+
+        .pointer_swipe_begin => |ev| pg.sendSwipeBegin(seat.wlr_seat, ev.time_msec, ev.fingers),
+        .pointer_swipe_update => |ev| pg.sendSwipeUpdate(seat.wlr_seat, ev.time_msec, ev.dx, ev.dy),
+        .pointer_swipe_end => |ev| pg.sendSwipeEnd(seat.wlr_seat, ev.time_msec, ev.cancelled),
+
+        .pointer_pinch_begin => |ev| pg.sendPinchBegin(seat.wlr_seat, ev.time_msec, ev.fingers),
+        .pointer_pinch_update => |ev| pg.sendPinchUpdate(seat.wlr_seat, ev.time_msec, ev.dx, ev.dy, ev.scale, ev.rotation),
+        .pointer_pinch_end => |ev| pg.sendPinchEnd(seat.wlr_seat, ev.time_msec, ev.cancelled),
     }
 }
 
diff --git a/river/Window.zig b/river/Window.zig
index 989f526..950b458 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -279,6 +279,18 @@ pub fn closing(window: *Window) void {
     window.dirtyPending();
 }
 
+pub fn setDimensions(window: *Window, width: i32, height: i32) void {
+    window.pending.box.width = width;
+    window.pending.box.height = height;
+
+    window.inflight.box.width = width;
+    window.inflight.box.height = height;
+
+    if (width != window.sent.box.width or height != window.sent.box.height) {
+        window.dirtyPending();
+    }
+}
+
 pub fn setDecorationHint(window: *Window, hint: river.WindowV1.DecorationHint) void {
     window.pending.decoration_hint = hint;
     if (hint != window.sent.decoration_hint) {
@@ -345,7 +357,8 @@ pub fn sendDirty(window: *Window) void {
             const sent = &window.sent;
 
             // XXX send all dirty pending state
-            if ((pending.box.width != sent.box.width or
+            log.debug("XXXXXXXXXXXXXX pending {any} sent {any}", .{ pending.box, sent.box });
+            if ((new or pending.box.width != sent.box.width or
                 pending.box.height != sent.box.height) and !pending.box.empty())
             {
                 window_v1.sendDimensions(window.pending.box.width, window.pending.box.height);
@@ -545,10 +558,7 @@ pub fn commitTransaction(window: *Window) void {
                 );
             }
 
-            window.inflight.box.width = xwindow.xsurface.width;
-            window.inflight.box.height = xwindow.xsurface.height;
-            window.pending.box.width = xwindow.xsurface.width;
-            window.pending.box.height = xwindow.xsurface.height;
+            window.setDimensions(xwindow.xsurface.width, xwindow.xsurface.height);
 
             window.current = window.inflight;
         },
diff --git a/river/WindowManager.zig b/river/WindowManager.zig
index 2535ae2..3f8fd10 100644
--- a/river/WindowManager.zig
+++ b/river/WindowManager.zig
@@ -442,7 +442,7 @@ fn commitTransaction(wm: *WindowManager) void {
     if (wm.committed.dirty) {
         wm.sendConfigures();
     } else if (wm.pending.dirty) {
-        wm.sendUpdate();
+        wm.dirtyPending();
     } else {
         server.input_manager.processEvents();
     }
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index b3063d5..db36d11 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -344,10 +344,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
                     });
                 }
 
-                window.inflight.box.width = toplevel.geometry.width;
-                window.inflight.box.height = toplevel.geometry.height;
-                window.pending.box.width = toplevel.geometry.width;
-                window.pending.box.height = toplevel.geometry.height;
+                window.setDimensions(toplevel.geometry.width, toplevel.geometry.height);
                 window.current = window.inflight;
                 window.updateSceneState();
             } else if (old_geometry.x != toplevel.geometry.x or
@@ -369,10 +366,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
                 window.resizeUpdatePosition(toplevel.geometry.width, toplevel.geometry.height);
             }
 
-            window.inflight.box.width = toplevel.geometry.width;
-            window.inflight.box.height = toplevel.geometry.height;
-            window.pending.box.width = toplevel.geometry.width;
-            window.pending.box.height = toplevel.geometry.height;
+            window.setDimensions(toplevel.geometry.width, toplevel.geometry.height);
 
             switch (toplevel.configure_state) {
                 .acked => {
diff --git a/river/XwaylandWindow.zig b/river/XwaylandWindow.zig
index ca6dd85..d52775a 100644
--- a/river/XwaylandWindow.zig
+++ b/river/XwaylandWindow.zig
@@ -234,9 +234,7 @@ fn handleRequestConfigure(
         return;
     }
 
-    xwindow.window.pending.box.width = event.width;
-    xwindow.window.pending.box.height = event.height;
-    server.wm.dirtyPending();
+    @panic("TODO");
 }
 
 fn handleSetOverrideRedirect(listener: *wl.Listener(void)) void {