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

commit2406b21dda643e68ecd6555a1a45f23fa4dca98d
parent1dc982bf72
authorLeon Henrik Plickat <[email protected]>
date2021-06-19 08:52
river: add commands to remove filter entries

 doc/riverctl.1.scd       | 14 +++++++++++--
 river/command.zig        |  2 ++
 river/command/filter.zig | 54 ++++++++++++++++++++++++++++++++++--------------
 3 files changed, 52 insertions(+), 18 deletions(-)

diff --git a/doc/riverctl.1.scd b/doc/riverctl.1.scd
index cebac70..7a96398 100644
--- a/doc/riverctl.1.scd
+++ b/doc/riverctl.1.scd
@@ -23,14 +23,24 @@ over the Wayland protocol.
 *csd-filter-add* _app-id_
 	Add _app-id_ to the CSD filter list. Views with this _app-id_ are
 	told to use client side decoration instead of the default server
-	side decoration.
+	side decoration. Note that this affects only new views, not already
+	existing ones.
+
+*csd-filter-remove* _app-id_
+	Remove an _app-id_ from the CSD filter list. Note that this affects only new
+	views, not already existing ones.
 
 *exit*
 	Exit the compositor, terminating the Wayland session.
 
 *float-filter-add* _app-id_
 	Add _app-id_ to the float filter list. Views with this _app-id_
-	will start floating.
+	will start floating. Note that this affects only new views, not already
+	existing ones.
+
+*float-filter-remove* _app-id_
+	Remove an _app-id_ from the float filter list. Note that this affects only
+	new views, not already existing ones.
 
 *focus-output* *next*|*previous*|*up*|*right*|*down*|*left*
 	Focus the next or previous output or the closest output in any direction.
diff --git a/river/command.zig b/river/command.zig
index eb55343..e033b00 100644
--- a/river/command.zig
+++ b/river/command.zig
@@ -49,11 +49,13 @@ const str_to_impl_fn = [_]struct {
     .{ .name = "border-width",           .impl = @import("command/config.zig").borderWidth },
     .{ .name = "close",                  .impl = @import("command/close.zig").close },
     .{ .name = "csd-filter-add",         .impl = @import("command/filter.zig").csdFilterAdd },
+    .{ .name = "csd-filter-remove",      .impl = @import("command/filter.zig").csdFilterRemove },
     .{ .name = "declare-mode",           .impl = @import("command/declare_mode.zig").declareMode },
     .{ .name = "default-layout",         .impl = @import("command/layout.zig").defaultLayout },
     .{ .name = "enter-mode",             .impl = @import("command/enter_mode.zig").enterMode },
     .{ .name = "exit",                   .impl = @import("command/exit.zig").exit },
     .{ .name = "float-filter-add",       .impl = @import("command/filter.zig").floatFilterAdd },
+    .{ .name = "float-filter-remove",    .impl = @import("command/filter.zig").floatFilterRemove },
     .{ .name = "focus-follows-cursor",   .impl = @import("command/focus_follows_cursor.zig").focusFollowsCursor },
     .{ .name = "focus-output",           .impl = @import("command/output.zig").focusOutput },
     .{ .name = "focus-view",             .impl = @import("command/focus_view.zig").focusView },
diff --git a/river/command/filter.zig b/river/command/filter.zig
index 240f1d1..a7d79fa 100644
--- a/river/command/filter.zig
+++ b/river/command/filter.zig
@@ -23,27 +23,22 @@ const util = @import("../util.zig");
 const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
-fn appendFilter(
+pub fn floatFilterAdd(
     allocator: *std.mem.Allocator,
-    list: *std.ArrayList([]const u8),
+    seat: *Seat,
     args: []const []const u8,
+    out: *?[]const u8,
 ) Error!void {
-    if (args.len < 2) return Error.NotEnoughArguments;
-    if (args.len > 2) return Error.TooManyArguments;
-    try list.append(try std.mem.dupe(allocator, u8, args[1]));
+    try modifyFilter(allocator, &server.config.float_filter, args, .add);
 }
 
-pub fn floatFilterAdd(
+pub fn floatFilterRemove(
     allocator: *std.mem.Allocator,
     seat: *Seat,
     args: []const []const u8,
     out: *?[]const u8,
 ) Error!void {
-    try appendFilter(
-        allocator,
-        &server.config.float_filter,
-        args,
-    );
+    try modifyFilter(allocator, &server.config.float_filter, args, .remove);
 }
 
 pub fn csdFilterAdd(
@@ -52,9 +47,36 @@ pub fn csdFilterAdd(
     args: []const []const u8,
     out: *?[]const u8,
 ) Error!void {
-    try appendFilter(
-        allocator,
-        &server.config.csd_filter,
-        args,
-    );
+    try modifyFilter(allocator, &server.config.csd_filter, args, .add);
+}
+
+pub fn csdFilterRemove(
+    allocator: *std.mem.Allocator,
+    seat: *Seat,
+    args: []const []const u8,
+    out: *?[]const u8,
+) Error!void {
+    try modifyFilter(allocator, &server.config.csd_filter, args, .remove);
+}
+
+fn modifyFilter(
+    allocator: *std.mem.Allocator,
+    list: *std.ArrayList([]const u8),
+    args: []const []const u8,
+    operation: enum { add, remove },
+) Error!void {
+    if (args.len < 2) return Error.NotEnoughArguments;
+    if (args.len > 2) return Error.TooManyArguments;
+    for (list.items) |*filter, i| {
+        if (std.mem.eql(u8, filter.*, args[1])) {
+            if (operation == .remove) {
+                allocator.free(list.orderedRemove(i));
+            }
+            return;
+        }
+    }
+    if (operation == .add) {
+        try list.ensureUnusedCapacity(1);
+        list.appendAssumeCapacity(try std.mem.dupe(allocator, u8, args[1]));
+    }
 }