Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
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", .{});