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

commit3b8b5b9a926b0f66a80c9f018bd0b91f4c20411b
parent08b6abd4ad
authorHugo Machet <[email protected]>
date2022-02-08 12:27
command: Remove allocator arg

 river/Control.zig                      |  2 +-
 river/Seat.zig                         |  2 +-
 river/command.zig                      |  5 ++-
 river/command/attach_mode.zig          |  3 --
 river/command/close.zig                |  1 -
 river/command/config.zig               |  6 ----
 river/command/declare_mode.zig         |  1 -
 river/command/enter_mode.zig           |  8 ++---
 river/command/exit.zig                 |  1 -
 river/command/filter.zig               |  4 ---
 river/command/focus_follows_cursor.zig |  2 --
 river/command/focus_view.zig           |  1 -
 river/command/input.zig                |  9 ++---
 river/command/layout.zig               |  3 --
 river/command/map.zig                  | 64 +++++++++++++---------------------
 river/command/move.zig                 |  3 --
 river/command/output.zig               |  2 --
 river/command/set_repeat.zig           |  1 -
 river/command/spawn.zig                |  6 ++--
 river/command/swap.zig                 |  1 -
 river/command/tags.zig                 | 21 ++++-------
 river/command/toggle_float.zig         |  1 -
 river/command/toggle_fullscreen.zig    |  1 -
 river/command/xcursor_theme.zig        |  1 -
 river/command/zoom.zig                 |  1 -
 25 files changed, 44 insertions(+), 106 deletions(-)

diff --git a/river/Control.zig b/river/Control.zig
index 9850b29..083e820 100644
--- a/river/Control.zig
+++ b/river/Control.zig
@@ -103,7 +103,7 @@ fn handleRequest(control: *zriver.ControlV1, request: zriver.ControlV1.Request,
 
             var out: ?[]const u8 = null;
             defer if (out) |s| util.gpa.free(s);
-            command.run(util.gpa, seat, args.items, &out) catch |err| {
+            command.run(seat, args.items, &out) catch |err| {
                 const failure_message = switch (err) {
                     command.Error.OutOfMemory => {
                         callback.getClient().postNoMemory();
diff --git a/river/Seat.zig b/river/Seat.zig
index 90b4963..76d4d84 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -361,7 +361,7 @@ fn runMappedCommand(self: *Self, mapping: *const Mapping) void {
     var out: ?[]const u8 = null;
     defer if (out) |s| util.gpa.free(s);
     const args = mapping.command_args;
-    command.run(util.gpa, self, args, &out) catch |err| {
+    command.run(self, args, &out) catch |err| {
         const failure_message = switch (err) {
             command.Error.Other => out.?,
             else => command.errToMsg(err),
diff --git a/river/command.zig b/river/command.zig
index adaf73b..0a0bcc4 100644
--- a/river/command.zig
+++ b/river/command.zig
@@ -38,7 +38,7 @@ pub const Orientation = enum {
 
 // zig fmt: off
 const command_impls = std.ComptimeStringMap(
-    fn (std.mem.Allocator, *Seat, []const [:0]const u8, *?[]const u8) Error!void,
+    fn (*Seat, []const [:0]const u8, *?[]const u8) Error!void,
     .{
         .{ "attach-mode",               @import("command/attach_mode.zig").attachMode },
         .{ "background-color",          @import("command/config.zig").backgroundColor },
@@ -118,7 +118,6 @@ pub const Error = error{
 /// The caller is then responsible for freeing that slice, which will be
 /// allocated using the provided allocator.
 pub fn run(
-    allocator: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
@@ -126,7 +125,7 @@ pub fn run(
     assert(out.* == null);
     if (args.len == 0) return Error.NoCommand;
     const impl_fn = command_impls.get(args[0]) orelse return Error.UnknownCommand;
-    try impl_fn(allocator, seat, args, out);
+    try impl_fn(seat, args, out);
 }
 
 /// Return a short error message for the given error. Passing Error.Other is UB
diff --git a/river/command/attach_mode.zig b/river/command/attach_mode.zig
index 803955d..7ca3663 100644
--- a/river/command/attach_mode.zig
+++ b/river/command/attach_mode.zig
@@ -17,15 +17,12 @@
 const std = @import("std");
 const mem = std.mem;
 
-const util = @import("../util.zig");
-
 const server = &@import("../main.zig").server;
 
 const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
 pub fn attachMode(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/close.zig b/river/command/close.zig
index 2f58b2d..6deaad5 100644
--- a/river/command/close.zig
+++ b/river/command/close.zig
@@ -21,7 +21,6 @@ const Seat = @import("../Seat.zig");
 
 /// Close the focused view, if any.
 pub fn close(
-    _: std.mem.Allocator,
     seat: *Seat,
     _: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/config.zig b/river/command/config.zig
index 82c2bfe..3580048 100644
--- a/river/command/config.zig
+++ b/river/command/config.zig
@@ -25,7 +25,6 @@ const Seat = @import("../Seat.zig");
 const Config = @import("../Config.zig");
 
 pub fn borderWidth(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -39,7 +38,6 @@ pub fn borderWidth(
 }
 
 pub fn backgroundColor(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -54,7 +52,6 @@ pub fn backgroundColor(
 }
 
 pub fn borderColorFocused(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -69,7 +66,6 @@ pub fn borderColorFocused(
 }
 
 pub fn borderColorUnfocused(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -84,7 +80,6 @@ pub fn borderColorUnfocused(
 }
 
 pub fn borderColorUrgent(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -99,7 +94,6 @@ pub fn borderColorUrgent(
 }
 
 pub fn setCursorWarp(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/declare_mode.zig b/river/command/declare_mode.zig
index d9f119b..8b0d7a6 100644
--- a/river/command/declare_mode.zig
+++ b/river/command/declare_mode.zig
@@ -26,7 +26,6 @@ const Seat = @import("../Seat.zig");
 
 /// Declare a new keymap mode
 pub fn declareMode(
-    _: std.mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/enter_mode.zig b/river/command/enter_mode.zig
index 9a8a7c0..f5ae8e1 100644
--- a/river/command/enter_mode.zig
+++ b/river/command/enter_mode.zig
@@ -17,13 +17,13 @@
 const std = @import("std");
 
 const server = &@import("../main.zig").server;
+const util = @import("../util.zig");
 
 const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
 /// Switch to the given mode
 pub fn enterMode(
-    allocator: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
@@ -33,7 +33,7 @@ pub fn enterMode(
 
     if (seat.mode_id == 1) {
         out.* = try std.fmt.allocPrint(
-            allocator,
+            util.gpa,
             "manually exiting mode 'locked' is not allowed",
             .{},
         );
@@ -43,7 +43,7 @@ pub fn enterMode(
     const target_mode = args[1];
     const mode_id = server.config.mode_to_id.get(target_mode) orelse {
         out.* = try std.fmt.allocPrint(
-            allocator,
+            util.gpa,
             "cannot enter non-existant mode '{s}'",
             .{target_mode},
         );
@@ -52,7 +52,7 @@ pub fn enterMode(
 
     if (mode_id == 1) {
         out.* = try std.fmt.allocPrint(
-            allocator,
+            util.gpa,
             "manually entering mode 'locked' is not allowed",
             .{},
         );
diff --git a/river/command/exit.zig b/river/command/exit.zig
index 7c9049e..7d9ba0c 100644
--- a/river/command/exit.zig
+++ b/river/command/exit.zig
@@ -23,7 +23,6 @@ const Seat = @import("../Seat.zig");
 
 /// Exit the compositor, terminating the wayland session.
 pub fn exit(
-    _: std.mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/filter.zig b/river/command/filter.zig
index 63217c2..678ff62 100644
--- a/river/command/filter.zig
+++ b/river/command/filter.zig
@@ -31,7 +31,6 @@ const FilterKind = enum {
 };
 
 pub fn floatFilterAdd(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -53,7 +52,6 @@ pub fn floatFilterAdd(
 }
 
 pub fn floatFilterRemove(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -72,7 +70,6 @@ pub fn floatFilterRemove(
 }
 
 pub fn csdFilterAdd(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -96,7 +93,6 @@ pub fn csdFilterAdd(
 }
 
 pub fn csdFilterRemove(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/focus_follows_cursor.zig b/river/command/focus_follows_cursor.zig
index 2c945bb..a374b8b 100644
--- a/river/command/focus_follows_cursor.zig
+++ b/river/command/focus_follows_cursor.zig
@@ -17,14 +17,12 @@
 const std = @import("std");
 
 const server = &@import("../main.zig").server;
-const util = @import("../util.zig");
 
 const Config = @import("../Config.zig");
 const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
 pub fn focusFollowsCursor(
-    _: std.mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/focus_view.zig b/river/command/focus_view.zig
index 4bcfcf9..4ca255a 100644
--- a/river/command/focus_view.zig
+++ b/river/command/focus_view.zig
@@ -27,7 +27,6 @@ const ViewStack = @import("../view_stack.zig").ViewStack;
 /// Focus either the next or the previous visible view, depending on the enum
 /// passed. Does nothing if there are 1 or 0 views in the stack.
 pub fn focusView(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/input.zig b/river/command/input.zig
index cbd4a1e..19bb402 100644
--- a/river/command/input.zig
+++ b/river/command/input.zig
@@ -28,14 +28,13 @@ const InputConfig = @import("../InputConfig.zig");
 const InputManager = @import("../InputManager.zig");
 
 pub fn listInputs(
-    allocator: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!void {
     if (args.len > 1) return error.TooManyArguments;
 
-    var input_list = std.ArrayList(u8).init(allocator);
+    var input_list = std.ArrayList(u8).init(util.gpa);
     const writer = input_list.writer();
     var prev = false;
 
@@ -61,14 +60,13 @@ pub fn listInputs(
 }
 
 pub fn listInputConfigs(
-    allocator: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!void {
     if (args.len > 1) return error.TooManyArguments;
 
-    var input_list = std.ArrayList(u8).init(allocator);
+    var input_list = std.ArrayList(u8).init(util.gpa);
     const writer = input_list.writer();
 
     for (server.input_manager.input_configs.items) |*input_config, i| {
@@ -126,7 +124,6 @@ pub fn listInputConfigs(
 }
 
 pub fn input(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -140,8 +137,6 @@ pub fn input(
     const input_config = for (server.input_manager.input_configs.items) |*input_config| {
         if (mem.eql(u8, input_config.identifier, args[1])) break input_config;
     } else blk: {
-        // Use util.gpa instead of allocator to assure the identifier is
-        // allocated by the same allocator as the ArrayList.
         try server.input_manager.input_configs.ensureUnusedCapacity(1);
         server.input_manager.input_configs.appendAssumeCapacity(.{
             .identifier = try util.gpa.dupe(u8, args[1]),
diff --git a/river/command/layout.zig b/river/command/layout.zig
index a8a493c..4fc7de1 100644
--- a/river/command/layout.zig
+++ b/river/command/layout.zig
@@ -25,7 +25,6 @@ const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
 pub fn outputLayout(
-    _: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -39,7 +38,6 @@ pub fn outputLayout(
 }
 
 pub fn defaultLayout(
-    _: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -62,7 +60,6 @@ pub fn defaultLayout(
 /// riverctl send-layout-cmd rivertile "mod-main-factor -0.1"
 /// riverctl send-layout-cmd rivertile "main-location top"
 pub fn sendLayoutCmd(
-    _: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/map.zig b/river/command/map.zig
index 33b5942..80abda8 100644
--- a/river/command/map.zig
+++ b/river/command/map.zig
@@ -34,7 +34,6 @@ const Seat = @import("../Seat.zig");
 /// Example:
 /// map normal Mod4+Shift Return spawn foot
 pub fn map(
-    allocator: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
@@ -50,9 +49,9 @@ pub fn map(
     const modifiers_raw = args[2 + offset];
     const keysym_raw = args[3 + offset];
 
-    const mode_id = try modeNameToId(allocator, mode_raw, out);
-    const modifiers = try parseModifiers(allocator, modifiers_raw, out);
-    const keysym = try parseKeysym(allocator, keysym_raw, out);
+    const mode_id = try modeNameToId(mode_raw, out);
+    const modifiers = try parseModifiers(modifiers_raw, out);
+    const keysym = try parseKeysym(keysym_raw, out);
 
     const mode_mappings = &server.config.modes.items[mode_id].mappings;
 
@@ -65,7 +64,7 @@ pub fn map(
         // Warn user if they overwrote an existing keybinding using riverctl.
         const opts = if (optionals.release) "-release " else "";
         out.* = try fmt.allocPrint(
-            allocator,
+            util.gpa,
             "overwrote an existing keybinding: {s} {s}{s} {s}",
             .{ mode_raw, opts, modifiers_raw, keysym_raw },
         );
@@ -83,7 +82,6 @@ pub fn map(
 /// Example:
 /// map-pointer normal Mod4 BTN_LEFT move-view
 pub fn mapPointer(
-    allocator: mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
@@ -91,9 +89,9 @@ pub fn mapPointer(
     if (args.len < 5) return Error.NotEnoughArguments;
     if (args.len > 5) return Error.TooManyArguments;
 
-    const mode_id = try modeNameToId(allocator, args[1], out);
-    const modifiers = try parseModifiers(allocator, args[2], out);
-    const event_code = try parseEventCode(allocator, args[3], out);
+    const mode_id = try modeNameToId(args[1], out);
+    const modifiers = try parseModifiers(args[2], out);
+    const event_code = try parseEventCode(args[3], out);
 
     const action = if (mem.eql(u8, args[4], "move-view"))
         PointerMapping.Action.move
@@ -101,7 +99,7 @@ pub fn mapPointer(
         PointerMapping.Action.resize
     else {
         out.* = try fmt.allocPrint(
-            allocator,
+            util.gpa,
             "invalid pointer action {s}, must be move-view or resize-view",
             .{args[4]},
         );
@@ -122,11 +120,11 @@ pub fn mapPointer(
     }
 }
 
-fn modeNameToId(allocator: mem.Allocator, mode_name: []const u8, out: *?[]const u8) !usize {
+fn modeNameToId(mode_name: []const u8, out: *?[]const u8) !usize {
     const config = &server.config;
     return config.mode_to_id.get(mode_name) orelse {
         out.* = try fmt.allocPrint(
-            allocator,
+            util.gpa,
             "cannot add/remove mapping to/from non-existant mode '{s}'",
             .{mode_name},
         );
@@ -165,30 +163,26 @@ fn pointerMappingExists(
     return null;
 }
 
-fn parseEventCode(allocator: mem.Allocator, name: [:0]const u8, out: *?[]const u8) !u32 {
+fn parseEventCode(name: [:0]const u8, out: *?[]const u8) !u32 {
     const event_code = c.libevdev_event_code_from_name(c.EV_KEY, name);
     if (event_code < 1) {
-        out.* = try fmt.allocPrint(allocator, "unknown button {s}", .{name});
+        out.* = try fmt.allocPrint(util.gpa, "unknown button {s}", .{name});
         return Error.Other;
     }
 
     return @intCast(u32, event_code);
 }
 
-fn parseKeysym(allocator: mem.Allocator, name: [:0]const u8, out: *?[]const u8) !xkb.Keysym {
+fn parseKeysym(name: [:0]const u8, out: *?[]const u8) !xkb.Keysym {
     const keysym = xkb.Keysym.fromName(name, .case_insensitive);
     if (keysym == .NoSymbol) {
-        out.* = try fmt.allocPrint(allocator, "invalid keysym '{s}'", .{name});
+        out.* = try fmt.allocPrint(util.gpa, "invalid keysym '{s}'", .{name});
         return Error.Other;
     }
     return keysym;
 }
 
-fn parseModifiers(
-    allocator: mem.Allocator,
-    modifiers_str: []const u8,
-    out: *?[]const u8,
-) !wlr.Keyboard.ModifierMask {
+fn parseModifiers(modifiers_str: []const u8, out: *?[]const u8) !wlr.Keyboard.ModifierMask {
     var it = mem.split(u8, modifiers_str, "+");
     var modifiers = wlr.Keyboard.ModifierMask{};
     outer: while (it.next()) |mod_name| {
@@ -210,7 +204,7 @@ fn parseModifiers(
                 continue :outer;
             }
         }
-        out.* = try fmt.allocPrint(allocator, "invalid modifier '{s}'", .{mod_name});
+        out.* = try fmt.allocPrint(util.gpa, "invalid modifier '{s}'", .{mod_name});
         return Error.Other;
     }
     return modifiers;
@@ -257,20 +251,15 @@ fn parseOptionalArgs(args: []const []const u8) OptionalArgsContainer {
 ///
 /// Example:
 /// unmap normal Mod4+Shift Return
-pub fn unmap(
-    allocator: mem.Allocator,
-    seat: *Seat,
-    args: []const [:0]const u8,
-    out: *?[]const u8,
-) Error!void {
+pub fn unmap(seat: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!void {
     const optionals = parseOptionalArgs(args[1..]);
     // offset caused by optional arguments
     const offset = optionals.i;
     if (args.len - offset < 4) return Error.NotEnoughArguments;
 
-    const mode_id = try modeNameToId(allocator, args[1 + offset], out);
-    const modifiers = try parseModifiers(allocator, args[2 + offset], out);
-    const keysym = try parseKeysym(allocator, args[3 + offset], out);
+    const mode_id = try modeNameToId(args[1 + offset], out);
+    const modifiers = try parseModifiers(args[2 + offset], out);
+    const keysym = try parseKeysym(args[3 + offset], out);
 
     const mode_mappings = &server.config.modes.items[mode_id].mappings;
     const mapping_idx = mappingExists(mode_mappings, modifiers, keysym, optionals.release) orelse return;
@@ -288,18 +277,13 @@ pub fn unmap(
 ///
 /// Example:
 /// unmap-pointer normal Mod4 BTN_LEFT
-pub fn unmapPointer(
-    allocator: mem.Allocator,
-    _: *Seat,
-    args: []const [:0]const u8,
-    out: *?[]const u8,
-) Error!void {
+pub fn unmapPointer(_: *Seat, args: []const [:0]const u8, out: *?[]const u8) Error!void {
     if (args.len < 4) return Error.NotEnoughArguments;
     if (args.len > 4) return Error.TooManyArguments;
 
-    const mode_id = try modeNameToId(allocator, args[1], out);
-    const modifiers = try parseModifiers(allocator, args[2], out);
-    const event_code = try parseEventCode(allocator, args[3], out);
+    const mode_id = try modeNameToId(args[1], out);
+    const modifiers = try parseModifiers(args[2], out);
+    const event_code = try parseEventCode(args[3], out);
 
     const mode_pointer_mappings = &server.config.modes.items[mode_id].pointer_mappings;
     const mapping_idx = pointerMappingExists(mode_pointer_mappings, modifiers, event_code) orelse return;
diff --git a/river/command/move.zig b/river/command/move.zig
index 44b0547..cc09a54 100644
--- a/river/command/move.zig
+++ b/river/command/move.zig
@@ -27,7 +27,6 @@ const View = @import("../View.zig");
 const Box = @import("../Box.zig");
 
 pub fn move(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -51,7 +50,6 @@ pub fn move(
 }
 
 pub fn snap(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -78,7 +76,6 @@ pub fn snap(
 }
 
 pub fn resize(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/output.zig b/river/command/output.zig
index 0a17c48..34fa108 100644
--- a/river/command/output.zig
+++ b/river/command/output.zig
@@ -29,7 +29,6 @@ const Output = @import("../Output.zig");
 const Seat = @import("../Seat.zig");
 
 pub fn focusOutput(
-    _: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
@@ -49,7 +48,6 @@ pub fn focusOutput(
 }
 
 pub fn sendToOutput(
-    _: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/set_repeat.zig b/river/command/set_repeat.zig
index 4369523..819eafb 100644
--- a/river/command/set_repeat.zig
+++ b/river/command/set_repeat.zig
@@ -23,7 +23,6 @@ const Seat = @import("../Seat.zig");
 
 /// Set the repeat rate and delay for all keyboards.
 pub fn setRepeat(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/spawn.zig b/river/command/spawn.zig
index 3f31a7a..1bc5c42 100644
--- a/river/command/spawn.zig
+++ b/river/command/spawn.zig
@@ -18,13 +18,13 @@ const std = @import("std");
 const os = std.os;
 
 const c = @import("../c.zig");
+const util = @import("../util.zig");
 
 const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
 /// Spawn a program.
 pub fn spawn(
-    allocator: std.mem.Allocator,
     _: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
@@ -35,7 +35,7 @@ pub fn spawn(
     const child_args = [_:null]?[*:0]const u8{ "/bin/sh", "-c", args[1], null };
 
     const pid = os.fork() catch {
-        out.* = try std.fmt.allocPrint(allocator, "fork/execve failed", .{});
+        out.* = try std.fmt.allocPrint(util.gpa, "fork/execve failed", .{});
         return Error.Other;
     };
 
@@ -55,7 +55,7 @@ pub fn spawn(
     if (!os.W.IFEXITED(ret.status) or
         (os.W.IFEXITED(ret.status) and os.W.EXITSTATUS(ret.status) != 0))
     {
-        out.* = try std.fmt.allocPrint(allocator, "fork/execve failed", .{});
+        out.* = try std.fmt.allocPrint(util.gpa, "fork/execve failed", .{});
         return Error.Other;
     }
 }
diff --git a/river/command/swap.zig b/river/command/swap.zig
index 739eb28..7345479 100644
--- a/river/command/swap.zig
+++ b/river/command/swap.zig
@@ -26,7 +26,6 @@ const ViewStack = @import("../view_stack.zig").ViewStack;
 
 /// Swap the currently focused view with either the view higher or lower in the visible stack
 pub fn swap(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/tags.zig b/river/command/tags.zig
index a0d54e1..c8b4338 100644
--- a/river/command/tags.zig
+++ b/river/command/tags.zig
@@ -18,18 +18,18 @@ const std = @import("std");
 const mem = std.mem;
 
 const server = &@import("../main.zig").server;
+const util = @import("../util.zig");
 
 const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
 /// Switch focus to the passed tags.
 pub fn setFocusedTags(
-    allocator: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!void {
-    const tags = try parseTags(allocator, args, out);
+    const tags = try parseTags(args, out);
     if (seat.focused_output.pending.tags != tags) {
         seat.focused_output.previous_tags = seat.focused_output.pending.tags;
         seat.focused_output.pending.tags = tags;
@@ -41,23 +41,21 @@ pub fn setFocusedTags(
 
 /// Set the spawn tagmask
 pub fn spawnTagmask(
-    allocator: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!void {
-    const tags = try parseTags(allocator, args, out);
+    const tags = try parseTags(args, out);
     seat.focused_output.spawn_tagmask = tags;
 }
 
 /// Set the tags of the focused view.
 pub fn setViewTags(
-    allocator: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!void {
-    const tags = try parseTags(allocator, args, out);
+    const tags = try parseTags(args, out);
     if (seat.focused == .view) {
         const view = seat.focused.view;
         view.pending.tags = tags;
@@ -68,12 +66,11 @@ pub fn setViewTags(
 
 /// Toggle focus of the passsed tags.
 pub fn toggleFocusedTags(
-    allocator: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!void {
-    const tags = try parseTags(allocator, args, out);
+    const tags = try parseTags(args, out);
     const output = seat.focused_output;
     const new_focused_tags = output.pending.tags ^ tags;
     if (new_focused_tags != 0) {
@@ -87,12 +84,11 @@ pub fn toggleFocusedTags(
 
 /// Toggle the passed tags of the focused view
 pub fn toggleViewTags(
-    allocator: mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!void {
-    const tags = try parseTags(allocator, args, out);
+    const tags = try parseTags(args, out);
     if (seat.focused == .view) {
         const new_tags = seat.focused.view.pending.tags ^ tags;
         if (new_tags != 0) {
@@ -106,7 +102,6 @@ pub fn toggleViewTags(
 
 /// Switch focus to tags that were selected previously
 pub fn focusPreviousTags(
-    _: mem.Allocator,
     seat: *Seat,
     args: []const []const u8,
     _: *?[]const u8,
@@ -124,7 +119,6 @@ pub fn focusPreviousTags(
 
 /// Set the tags of the focused view to the tags that were selected previously
 pub fn sendToPreviousTags(
-    _: mem.Allocator,
     seat: *Seat,
     args: []const []const u8,
     _: *?[]const u8,
@@ -140,7 +134,6 @@ pub fn sendToPreviousTags(
 }
 
 fn parseTags(
-    allocator: mem.Allocator,
     args: []const [:0]const u8,
     out: *?[]const u8,
 ) Error!u32 {
@@ -150,7 +143,7 @@ fn parseTags(
     const tags = try std.fmt.parseInt(u32, args[1], 10);
 
     if (tags == 0) {
-        out.* = try std.fmt.allocPrint(allocator, "tags may not be 0", .{});
+        out.* = try std.fmt.allocPrint(util.gpa, "tags may not be 0", .{});
         return Error.Other;
     }
 
diff --git a/river/command/toggle_float.zig b/river/command/toggle_float.zig
index 598a4d7..41418c1 100644
--- a/river/command/toggle_float.zig
+++ b/river/command/toggle_float.zig
@@ -24,7 +24,6 @@ const Seat = @import("../Seat.zig");
 /// Make the focused view float or stop floating, depending on its current
 /// state.
 pub fn toggleFloat(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/toggle_fullscreen.zig b/river/command/toggle_fullscreen.zig
index 9b0e761..a4ae724 100644
--- a/river/command/toggle_fullscreen.zig
+++ b/river/command/toggle_fullscreen.zig
@@ -24,7 +24,6 @@ const Seat = @import("../Seat.zig");
 
 /// Toggle fullscreen state of the currently focused view
 pub fn toggleFullscreen(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/xcursor_theme.zig b/river/command/xcursor_theme.zig
index fb93808..0e1e065 100644
--- a/river/command/xcursor_theme.zig
+++ b/river/command/xcursor_theme.zig
@@ -20,7 +20,6 @@ const Error = @import("../command.zig").Error;
 const Seat = @import("../Seat.zig");
 
 pub fn xcursorTheme(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,
diff --git a/river/command/zoom.zig b/river/command/zoom.zig
index 0eb2072..ecd1dc5 100644
--- a/river/command/zoom.zig
+++ b/river/command/zoom.zig
@@ -26,7 +26,6 @@ const ViewStack = @import("../view_stack.zig").ViewStack;
 /// Bump the focused view to the top of the stack. If the view on the top of
 /// the stack is focused, bump the second view to the top.
 pub fn zoom(
-    _: std.mem.Allocator,
     seat: *Seat,
     args: []const [:0]const u8,
     _: *?[]const u8,