Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Decoration: make frame perfect on window close
river/Decoration.zig | 21 ++++++++++++++++-----
river/Window.zig | 9 +++++++--
rivercompat/Window.zig | 4 ++++
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/river/Decoration.zig b/river/Decoration.zig
index 1b91c5f..32086e1 100644
--- a/river/Decoration.zig
+++ b/river/Decoration.zig
@@ -38,7 +38,7 @@ const role: wlr.Surface.Role = .{
.destroy = null,
};
-object: *river.DecorationV1,
+object: ?*river.DecorationV1,
surface: *wlr.Surface,
tree: *wlr.SceneTree,
surfaces: Scene.SaveableSurfaces,
@@ -88,12 +88,20 @@ pub fn create(
}
pub fn destroy(decoration: *Decoration) void {
- decoration.object.setHandler(?*anyopaque, handleRequestInert, null, null);
+ assert(decoration.object == null);
decoration.tree.node.destroy();
decoration.link.remove();
util.gpa.destroy(decoration);
}
+pub fn makeInert(decoration: *Decoration) void {
+ if (decoration.object) |object| {
+ object.setHandler(?*anyopaque, handleRequestInert, null, null);
+ decoration.object = null;
+ }
+ decoration.surfaces.save();
+}
+
fn handleRequestInert(
node_v1: *river.DecorationV1,
request: river.DecorationV1.Request,
@@ -103,6 +111,7 @@ fn handleRequestInert(
}
fn handleDestroy(_: *river.DecorationV1, decoration: *Decoration) void {
+ decoration.object = null;
decoration.destroy();
}
@@ -149,9 +158,11 @@ pub fn updateRenderingFinish(decoration: *Decoration) void {
rendering_requested.sync_next_commit = false;
if (!decoration.surfaces.saved.node.enabled) {
- decoration.object.postError(.no_commit,
- \\no wl_surface.commit after sync_next_commit and before update_rendering_finish
- );
+ if (decoration.object) |object| {
+ object.postError(.no_commit,
+ \\no wl_surface.commit after sync_next_commit and before update_rendering_finish
+ );
+ }
}
}
diff --git a/river/Window.zig b/river/Window.zig
index 960eb7c..da57a10 100644
--- a/river/Window.zig
+++ b/river/Window.zig
@@ -304,6 +304,11 @@ pub fn destroy(window: *Window) void {
}
}
+ inline for (.{ &window.decorations_above, &window.decorations_below }) |decorations| {
+ var it = decorations.safeIterator(.forward);
+ while (it.next()) |decoration| decoration.destroy();
+ }
+
window.tree.node.destroy();
window.popup_tree.node.destroy();
@@ -427,8 +432,8 @@ fn makeInert(window: *Window) void {
window_v1.setHandler(?*anyopaque, handleRequestInert, null, null);
window.node.makeInert();
inline for (.{ &window.decorations_above, &window.decorations_below }) |decorations| {
- var it = decorations.safeIterator(.forward);
- while (it.next()) |decoration| decoration.destroy();
+ var it = decorations.iterator(.forward);
+ while (it.next()) |decoration| decoration.makeInert();
}
} else {
assert(window.node.object == null);
diff --git a/rivercompat/Window.zig b/rivercompat/Window.zig
index 6d35380..4a30d3e 100644
--- a/rivercompat/Window.zig
+++ b/rivercompat/Window.zig
@@ -123,6 +123,10 @@ pub fn updateWindowing(window: *Window) void {
}
}
}
+ window.shadow_decoration.destroy();
+ window.shadow_viewport.destroy();
+ window.shadow_surface.destroy();
+ window.shadow_buffer.destroy();
gpa.destroy(window);
return;
}