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

commit5d25dc180e65ab53609b8c1c53455eb7f0909f6c
parentbcc32cde8a
authorIsaac Freund <[email protected]>
date2024-12-21 14:47
WindowManager: actually destroy windows

 river/Window.zig        | 18 +++++++-----------
 river/WindowManager.zig | 33 +++++++++++++++++----------------
 2 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/river/Window.zig b/river/Window.zig
index d914810..54c2564 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -234,7 +234,7 @@ pub fn destroy(window: *Window, when: enum { lazy, assert }) void {
 
     // If there are still saved buffers, then this window needs to be kept
     // around until the current transaction completes. This function will be
-    // called again in Root.commitTransaction()
+    // called again in WindowManager.commitTransaction()
     if (!window.saved_surface_tree.node.enabled) {
         window.tree.node.destroy();
         window.popup_tree.node.destroy();
@@ -265,17 +265,15 @@ fn dirtyPending(window: *Window) void {
 }
 
 pub fn ready(window: *Window) void {
-    if (window.pending.state != .ready) {
-        window.pending.state = .ready;
-        window.dirtyPending();
-    }
+    assert(window.pending.state != .ready);
+    window.pending.state = .ready;
+    window.dirtyPending();
 }
 
 pub fn closing(window: *Window) void {
-    if (window.pending.state != .closing) {
-        window.pending.state = .closing;
-        window.dirtyPending();
-    }
+    assert(window.pending.state != .closing);
+    window.pending.state = .closing;
+    window.dirtyPending();
 }
 
 pub fn setDecorationHint(window: *Window, hint: river.WindowV1.DecorationHint) void {
@@ -481,8 +479,6 @@ pub fn resizeUpdatePosition(window: *Window, width: i32, height: i32) void {
 pub fn commitTransaction(window: *Window) void {
     window.foreign_toplevel_handle.update();
 
-    window.dropSavedSurfaceTree();
-
     switch (window.impl) {
         .toplevel => |*toplevel| {
             switch (toplevel.configure_state) {
diff --git a/river/WindowManager.zig b/river/WindowManager.zig
index f80b888..e91d7e9 100644
--- a/river/WindowManager.zig
+++ b/river/WindowManager.zig
@@ -197,7 +197,10 @@ fn handleRequest(
 
             wm.committed.dirty = true;
             switch (wm.state) {
-                .idle, .update_acked => wm.sendConfigures(),
+                .idle, .update_acked => {
+                    wm.cancelTimeoutTimer();
+                    wm.sendConfigures();
+                },
                 .update_sent, .inflight_configures => {},
             }
         },
@@ -348,6 +351,10 @@ fn startTimeoutTimer(wm: *WindowManager) void {
     };
 }
 
+fn cancelTimeoutTimer(wm: *WindowManager) void {
+    wm.timeout.timerUpdate(0) catch log.err("error disarming timer", .{});
+}
+
 fn handleTimeout(wm: *WindowManager) c_int {
     log.err("timeout occurred, some imperfect frames may be shown", .{});
 
@@ -366,8 +373,7 @@ fn handleTimeout(wm: *WindowManager) c_int {
 pub fn notifyConfigured(wm: *WindowManager) void {
     wm.state.inflight_configures -= 1;
     if (wm.state.inflight_configures == 0) {
-        // Disarm the timer, as we didn't timeout
-        wm.timeout.timerUpdate(0) catch log.err("error disarming timer", .{});
+        wm.cancelTimeoutTimer();
         wm.commitTransaction();
     }
 }
@@ -382,6 +388,14 @@ fn commitTransaction(wm: *WindowManager) void {
 
     log.debug("commiting transaction", .{});
 
+    {
+        var it = wm.windows.safeIterator(.forward);
+        while (it.next()) |window| {
+            window.dropSavedSurfaceTree();
+            if (window.destroying) window.destroy(.assert);
+        }
+    }
+
     {
         var it = wm.inflight.render_list.iterator(.forward);
         while (it.next()) |node| {
@@ -404,19 +418,6 @@ fn commitTransaction(wm: *WindowManager) void {
         while (it) |node| : (it = node.next) node.data.cursor.updateState();
     }
 
-    {
-        // This must be done after updating cursor state in case the window was the target of move/resize.
-        var it = wm.inflight.render_list.safeIterator(.forward);
-        while (it.next()) |node| {
-            switch (node.get()) {
-                .window => |window| {
-                    window.dropSavedSurfaceTree();
-                    if (window.destroying) window.destroy(.assert);
-                },
-            }
-        }
-    }
-
     server.idle_inhibit_manager.checkActive();
 
     log.debug("finished committing transaction", .{});