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

commit23b9c6f44b062a273c75c3a256bcba4292277975
parente6824646e7
authorIsaac Freund <[email protected]>
date2024-02-21 13:34
rules: fix assertion failure

If a view that is currently being destroyed is matched by a newly added
rule river crashes due to an assertion failure.

Fix this and add another assertion to make this precondition more
visible to the users of RuleList.match().

 river/command/rule.zig | 2 ++
 river/rule_list.zig    | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/river/command/rule.zig b/river/command/rule.zig
index fc90cc3..7703955 100644
--- a/river/command/rule.zig
+++ b/river/command/rule.zig
@@ -183,6 +183,8 @@ pub fn ruleDel(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
 fn apply_ssd_rules() void {
     var it = server.root.views.iterator(.forward);
     while (it.next()) |view| {
+        if (view.destroying) continue;
+
         if (server.config.rules.ssd.match(view)) |ssd| {
             view.pending.ssd = ssd;
         }
diff --git a/river/rule_list.zig b/river/rule_list.zig
index ad6fbf8..b73dc85 100644
--- a/river/rule_list.zig
+++ b/river/rule_list.zig
@@ -15,6 +15,7 @@
 // along with this program. If not, see <https://www.gnu.org/licenses/>.
 
 const std = @import("std");
+const assert = std.debug.assert;
 const mem = std.mem;
 
 const globber = @import("globber");
@@ -98,6 +99,7 @@ pub fn RuleList(comptime T: type) type {
         /// Returns the value of the most specific rule matching the view.
         /// Returns null if no rule matches.
         pub fn match(list: *Self, view: *View) ?T {
+            assert(!view.destroying);
             const app_id = mem.sliceTo(view.getAppId(), 0) orelse "";
             const title = mem.sliceTo(view.getTitle(), 0) orelse "";