aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsaac Freund <ifreund@ifreund.xyz>2020-06-16 22:08:36 +0200
committerIsaac Freund <ifreund@ifreund.xyz>2020-06-16 22:48:08 +0200
commitc5de1641dc5574d13fad67ffdcf36c2b0def7585 (patch)
tree8563331dc11ef50b497921cf7fcc9e4aa7a905f3
parentfb8d855ec984ab2e94878d47bbfe8f9ce5adae02 (diff)
downloadriver-c5de1641dc5574d13fad67ffdcf36c2b0def7585.tar.gz
river-c5de1641dc5574d13fad67ffdcf36c2b0def7585.tar.xz
code: create util.allocator and use globally
river is not a library and passing a general purpose allocators around everywhere does not make sense and leads to ugly code. This does not prevent us from using local arenas if they are fitting.
-rw-r--r--river/Config.zig15
-rw-r--r--river/Control.zig20
-rw-r--r--river/Decoration.zig4
-rw-r--r--river/DecorationManager.zig5
-rw-r--r--river/InputManager.zig4
-rw-r--r--river/LayerSurface.zig5
-rw-r--r--river/Output.zig32
-rw-r--r--river/Root.zig2
-rw-r--r--river/Seat.zig17
-rw-r--r--river/Server.zig18
-rw-r--r--river/StatusManager.zig8
-rw-r--r--river/View.zig11
-rw-r--r--river/XdgPopup.zig6
-rw-r--r--river/XdgToplevel.zig3
-rw-r--r--river/XwaylandUnmanaged.zig2
-rw-r--r--river/main.zig5
-rw-r--r--river/util.zig5
17 files changed, 76 insertions, 86 deletions
diff --git a/river/Config.zig b/river/Config.zig
index c0355ba..9791019 100644
--- a/river/Config.zig
+++ b/river/Config.zig
@@ -20,6 +20,7 @@ const Self = @This();
const std = @import("std");
const c = @import("c.zig");
+const util = @import("util.zig");
const Log = @import("log.zig").Log;
const Server = @import("Server.zig");
@@ -49,29 +50,29 @@ modes: std.ArrayList(std.ArrayList(Mapping)),
/// List of app_ids which will be started floating
float_filter: std.ArrayList([*:0]const u8),
-pub fn init(self: *Self, allocator: *std.mem.Allocator) !void {
+pub fn init(self: *Self) !void {
self.border_width = 2;
self.border_color_focused = [_]f32{ 0.57647059, 0.63137255, 0.63137255, 1.0 }; // Solarized base1
self.border_color_unfocused = [_]f32{ 0.34509804, 0.43137255, 0.45882353, 1.0 }; // Solarized base0
self.view_padding = 8;
self.outer_padding = 8;
- self.mode_to_id = std.StringHashMap(usize).init(allocator);
+ self.mode_to_id = std.StringHashMap(usize).init(util.allocator);
try self.mode_to_id.putNoClobber("normal", 0);
- self.modes = std.ArrayList(std.ArrayList(Mapping)).init(allocator);
- try self.modes.append(std.ArrayList(Mapping).init(allocator));
+ self.modes = std.ArrayList(std.ArrayList(Mapping)).init(util.allocator);
+ try self.modes.append(std.ArrayList(Mapping).init(util.allocator));
- self.float_filter = std.ArrayList([*:0]const u8).init(allocator);
+ self.float_filter = std.ArrayList([*:0]const u8).init(util.allocator);
// Float views with app_id "float"
try self.float_filter.append("float");
}
-pub fn deinit(self: Self, allocator: *std.mem.Allocator) void {
+pub fn deinit(self: Self) void {
self.mode_to_id.deinit();
for (self.modes.items) |mode| {
- for (mode.items) |mapping| mapping.deinit(allocator);
+ for (mode.items) |mapping| mapping.deinit(util.allocator);
mode.deinit();
}
self.modes.deinit();
diff --git a/river/Control.zig b/river/Control.zig
index 3da1f28..5a8657a 100644
--- a/river/Control.zig
+++ b/river/Control.zig
@@ -35,7 +35,6 @@ const implementation = c.struct_zriver_control_v1_interface{
.run_command = runCommand,
};
-server: *Server,
wl_global: *c.wl_global,
args_map: std.AutoHashMap(u32, std.ArrayList([]const u8)),
@@ -43,7 +42,6 @@ args_map: std.AutoHashMap(u32, std.ArrayList([]const u8)),
listen_display_destroy: c.wl_listener,
pub fn init(self: *Self, server: *Server) !void {
- self.server = server;
self.wl_global = c.wl_global_create(
server.wl_display,
&c.zriver_control_v1_interface,
@@ -52,7 +50,7 @@ pub fn init(self: *Self, server: *Server) !void {
bind,
) orelse return error.CantCreateWlGlobal;
- self.args_map = std.AutoHashMap(u32, std.ArrayList([]const u8)).init(server.allocator);
+ self.args_map = std.AutoHashMap(u32, std.ArrayList([]const u8)).init(util.allocator);
self.listen_display_destroy.notify = handleDisplayDestroy;
c.wl_display_add_destroy_listener(server.wl_display, &self.listen_display_destroy);
@@ -76,7 +74,7 @@ fn bind(wl_client: ?*c.wl_client, data: ?*c_void, version: u32, id: u32) callcon
c.wl_client_post_no_memory(wl_client);
return;
};
- self.args_map.putNoClobber(id, std.ArrayList([]const u8).init(self.server.allocator)) catch {
+ self.args_map.putNoClobber(id, std.ArrayList([]const u8).init(util.allocator)) catch {
c.wl_resource_destroy(wl_resource);
c.wl_client_post_no_memory(wl_client);
return;
@@ -100,16 +98,15 @@ fn destroy(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource) callconv(.C)
fn addArgument(wl_client: ?*c.wl_client, wl_resource: ?*c.wl_resource, arg: ?[*:0]const u8) callconv(.C) void {
const self = util.voidCast(Self, c.wl_resource_get_user_data(wl_resource).?);
const id = c.wl_resource_get_id(wl_resource);
- const allocator = self.server.allocator;
- const owned_slice = std.mem.dupe(allocator, u8, std.mem.span(arg.?)) catch {
+ const owned_slice = std.mem.dupe(util.allocator, u8, std.mem.span(arg.?)) catch {
c.wl_client_post_no_memory(wl_client);
return;
};
self.args_map.get(id).?.value.append(owned_slice) catch {
c.wl_client_post_no_memory(wl_client);
- allocator.free(owned_slice);
+ util.allocator.free(owned_slice);
return;
};
}
@@ -124,7 +121,6 @@ fn runCommand(
// This can be null if the seat is inert, in which case we ignore the request
const wlr_seat_client = c.wlr_seat_client_from_resource(seat_wl_resource) orelse return;
const seat = util.voidCast(Seat, wlr_seat_client.*.seat.*.data.?);
- const allocator = self.server.allocator;
const callback_resource = c.wl_resource_create(
wl_client,
@@ -140,14 +136,14 @@ fn runCommand(
const args = self.args_map.get(c.wl_resource_get_id(wl_resource)).?.value.items;
var failure_message: []const u8 = undefined;
- command.run(allocator, seat, args, &failure_message) catch |err| {
+ command.run(util.allocator, seat, args, &failure_message) catch |err| {
if (err == command.Error.CommandFailed) {
- defer allocator.free(failure_message);
- const out = std.cstr.addNullByte(allocator, failure_message) catch {
+ defer util.allocator.free(failure_message);
+ const out = std.cstr.addNullByte(util.allocator, failure_message) catch {
c.zriver_command_callback_v1_send_failure(callback_resource, "out of memory");
return;
};
- defer allocator.free(out);
+ defer util.allocator.free(out);
c.zriver_command_callback_v1_send_failure(callback_resource, out);
} else {
c.zriver_command_callback_v1_send_failure(
diff --git a/river/Decoration.zig b/river/Decoration.zig
index b96450c..149fe8d 100644
--- a/river/Decoration.zig
+++ b/river/Decoration.zig
@@ -20,6 +20,7 @@ const Self = @This();
const std = @import("std");
const c = @import("c.zig");
+const util = @import("util.zig");
const DecorationManager = @import("DecorationManager.zig");
@@ -49,11 +50,10 @@ pub fn init(
fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_destroy", listener.?);
- const allocator = self.decoration_manager.server.allocator;
const node = @fieldParentPtr(std.SinglyLinkedList(Self).Node, "data", self);
self.decoration_manager.decorations.remove(node);
- allocator.destroy(node);
+ util.allocator.destroy(node);
}
fn handleRequestMode(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
diff --git a/river/DecorationManager.zig b/river/DecorationManager.zig
index 0e280d1..4a78025 100644
--- a/river/DecorationManager.zig
+++ b/river/DecorationManager.zig
@@ -25,8 +25,6 @@ const util = @import("util.zig");
const Decoration = @import("Decoration.zig");
const Server = @import("Server.zig");
-server: *Server,
-
wlr_xdg_decoration_manager: *c.wlr_xdg_decoration_manager_v1,
decorations: std.SinglyLinkedList(Decoration),
@@ -34,7 +32,6 @@ decorations: std.SinglyLinkedList(Decoration),
listen_new_toplevel_decoration: c.wl_listener,
pub fn init(self: *Self, server: *Server) !void {
- self.server = server;
self.wlr_xdg_decoration_manager = c.wlr_xdg_decoration_manager_v1_create(server.wl_display) orelse
return error.CantCreateWlrXdgDecorationManager;
@@ -49,7 +46,7 @@ fn handleNewToplevelDecoration(listener: ?*c.wl_listener, data: ?*c_void) callco
const self = @fieldParentPtr(Self, "listen_new_toplevel_decoration", listener.?);
const wlr_xdg_toplevel_decoration = util.voidCast(c.wlr_xdg_toplevel_decoration_v1, data.?);
- const node = self.decorations.allocateNode(self.server.allocator) catch unreachable;
+ const node = self.decorations.allocateNode(util.allocator) catch unreachable;
node.data.init(self, wlr_xdg_toplevel_decoration);
self.decorations.prepend(node);
}
diff --git a/river/InputManager.zig b/river/InputManager.zig
index 62acc2d..7c1337c 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -51,7 +51,7 @@ pub fn init(self: *Self, server: *Server) !void {
self.seats = std.TailQueue(Seat).init();
- const seat_node = try server.allocator.create(std.TailQueue(Seat).Node);
+ const seat_node = try util.allocator.create(std.TailQueue(Seat).Node);
try seat_node.data.init(self, default_seat_name);
self.default_seat = &seat_node.data;
self.seats.prepend(seat_node);
@@ -78,7 +78,7 @@ pub fn init(self: *Self, server: *Server) !void {
pub fn deinit(self: *Self) void {
while (self.seats.pop()) |seat_node| {
seat_node.data.deinit();
- self.server.allocator.destroy(seat_node);
+ util.allocator.destroy(seat_node);
}
}
diff --git a/river/LayerSurface.zig b/river/LayerSurface.zig
index c33678f..6fa6822 100644
--- a/river/LayerSurface.zig
+++ b/river/LayerSurface.zig
@@ -87,7 +87,7 @@ fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
c.wl_list_remove(&self.listen_unmap.link);
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
- output.root.server.allocator.destroy(node);
+ util.allocator.destroy(node);
}
fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
@@ -189,9 +189,8 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_new_popup", listener.?);
const wlr_xdg_popup = util.voidCast(c.wlr_xdg_popup, data.?);
- const allocator = self.output.root.server.allocator;
// This will free itself on destroy
- var xdg_popup = allocator.create(XdgPopup) catch unreachable;
+ var xdg_popup = util.allocator.create(XdgPopup) catch unreachable;
xdg_popup.init(self.output, &self.box, wlr_xdg_popup);
}
diff --git a/river/Output.zig b/river/Output.zig
index bc125b8..67c70e7 100644
--- a/river/Output.zig
+++ b/river/Output.zig
@@ -22,6 +22,7 @@ const std = @import("std");
const c = @import("c.zig");
const render = @import("render.zig");
+const util = @import("util.zig");
const Box = @import("Box.zig");
const LayerSurface = @import("LayerSurface.zig");
@@ -30,7 +31,8 @@ const Root = @import("Root.zig");
const View = @import("View.zig");
const ViewStack = @import("view_stack.zig").ViewStack;
const OutputStatus = @import("OutputStatus.zig");
-/// Minimum width/height for surfaces.
+
+// Minimum width/height for surfaces.
// This is needed, because external layouts and large padding and border sizes
// may cause surfaces so small, that bugs in client applications are encountered,
// or even surfaces of zero or negative size,which are a protocol error and would
@@ -109,7 +111,7 @@ pub fn init(self: *Self, root: *Root, wlr_output: *c.wlr_output) !void {
self.master_factor = 0.6;
- self.layout = try std.fmt.allocPrint(self.root.server.allocator, "full", .{});
+ self.layout = try std.fmt.allocPrint(util.allocator, "full", .{});
self.status_trackers = std.SinglyLinkedList(OutputStatus).init();
@@ -226,8 +228,6 @@ test "parse window configuration" {
/// Execute an external layout function, parse its output and apply the layout
/// to the output.
fn layoutExternal(self: *Self, visible_count: u32, output_tags: u32) !void {
- const allocator = self.root.server.allocator;
-
const border_width = self.root.server.config.border_width;
const view_padding = self.root.server.config.view_padding;
const outer_padding = self.root.server.config.outer_padding;
@@ -237,13 +237,19 @@ fn layoutExternal(self: *Self, visible_count: u32, output_tags: u32) !void {
const layout_height = @intCast(u32, self.usable_box.height) - outer_padding * 2;
// Assemble command
- const parameters = std.fmt.allocPrint(allocator, "{} {} {d} {} {}", .{ visible_count, self.master_count, self.master_factor, layout_width, layout_height }) catch @panic("Out of memory.");
- defer allocator.free(parameters);
- const layout_command = try std.mem.join(allocator, " ", &[_][]const u8{
+ const parameters = std.fmt.allocPrint(util.allocator, "{} {} {d} {} {}", .{
+ visible_count,
+ self.master_count,
+ self.master_factor,
+ layout_width,
+ layout_height,
+ }) catch @panic("Out of memory.");
+ defer util.allocator.free(parameters);
+ const layout_command = try std.mem.join(util.allocator, " ", &[_][]const u8{
self.layout,
parameters,
});
- defer allocator.free(layout_command);
+ defer util.allocator.free(layout_command);
const cmd = [_][]const u8{
"/bin/sh",
"-c",
@@ -252,14 +258,14 @@ fn layoutExternal(self: *Self, visible_count: u32, output_tags: u32) !void {
// Execute layout executable
// TODO abort after 1 second
- const child = try std.ChildProcess.init(&cmd, allocator);
+ const child = try std.ChildProcess.init(&cmd, util.allocator);
defer child.deinit();
child.stdin_behavior = .Ignore;
child.stdout_behavior = .Pipe;
try std.ChildProcess.spawn(child);
const max_output_size = 400 * 1024;
- const buffer = try child.stdout.?.inStream().readAllAlloc(allocator, max_output_size);
- defer allocator.free(buffer);
+ const buffer = try child.stdout.?.inStream().readAllAlloc(util.allocator, max_output_size);
+ defer util.allocator.free(buffer);
const term = try child.wait();
switch (term) {
.Exited, .Signal, .Stopped, .Unknown => |code| {
@@ -270,7 +276,7 @@ fn layoutExternal(self: *Self, visible_count: u32, output_tags: u32) !void {
}
// Parse layout command output
- var view_boxen = std.ArrayList(Box).init(self.root.server.allocator);
+ var view_boxen = std.ArrayList(Box).init(util.allocator);
defer view_boxen.deinit();
var parse_it = std.mem.split(buffer, "\n");
while (parse_it.next()) |token| {
@@ -621,7 +627,7 @@ fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// Remove the destroyed output from the list
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
root.outputs.remove(node);
- root.server.allocator.destroy(node);
+ util.allocator.destroy(node);
// Arrange the root in case evacuated views affect the layout
root.arrange();
diff --git a/river/Root.zig b/river/Root.zig
index 806d0a5..70a1426 100644
--- a/river/Root.zig
+++ b/river/Root.zig
@@ -95,7 +95,7 @@ pub fn deinit(self: *Self) void {
pub fn addOutput(self: *Self, wlr_output: *c.wlr_output) void {
// TODO: Handle failure
- const node = self.outputs.allocateNode(self.server.allocator) catch unreachable;
+ const node = self.outputs.allocateNode(util.allocator) catch unreachable;
node.data.init(self, wlr_output) catch unreachable;
self.outputs.append(node);
diff --git a/river/Seat.zig b/river/Seat.zig
index 40d64a9..b2676c3 100644
--- a/river/Seat.zig
+++ b/river/Seat.zig
@@ -103,13 +103,11 @@ pub fn init(self: *Self, input_manager: *InputManager, name: []const u8) !void {
pub fn deinit(self: *Self) void {
self.cursor.deinit();
- while (self.keyboards.pop()) |node| {
- self.input_manager.server.allocator.destroy(node);
- }
+ while (self.keyboards.pop()) |node| util.allocator.destroy(node);
while (self.focus_stack.first) |node| {
self.focus_stack.remove(node);
- self.input_manager.server.allocator.destroy(node);
+ util.allocator.destroy(node);
}
}
@@ -154,7 +152,7 @@ pub fn focus(self: *Self, _view: ?*View) void {
}
} else {
// The view is not in the stack, so allocate a new node and prepend it
- const new_focus_node = self.input_manager.server.allocator.create(
+ const new_focus_node = util.allocator.create(
ViewStack(*View).Node,
) catch unreachable;
new_focus_node.view = view_to_focus;
@@ -258,7 +256,7 @@ pub fn handleViewUnmap(self: *Self, view: *View) void {
while (it) |node| : (it = node.next) {
if (node.view == view) {
self.focus_stack.remove(node);
- self.input_manager.server.allocator.destroy(node);
+ util.allocator.destroy(node);
break;
}
}
@@ -278,12 +276,11 @@ pub fn handleMapping(self: *Self, keysym: c.xkb_keysym_t, modifiers: u32) bool {
for (modes.items[self.mode_id].items) |mapping| {
if (modifiers == mapping.modifiers and keysym == mapping.keysym) {
// Execute the bound command
- const allocator = self.input_manager.server.allocator;
var failure_message: []const u8 = undefined;
- command.run(allocator, self, mapping.command_args, &failure_message) catch |err| {
+ command.run(util.allocator, self, mapping.command_args, &failure_message) catch |err| {
// TODO: log the error
if (err == command.Error.CommandFailed)
- allocator.free(failure_message);
+ util.allocator.free(failure_message);
};
return true;
}
@@ -314,7 +311,7 @@ pub fn addDevice(self: *Self, device: *c.wlr_input_device) !void {
fn addKeyboard(self: *Self, device: *c.wlr_input_device) !void {
c.wlr_seat_set_keyboard(self.wlr_seat, device);
- const node = try self.keyboards.allocateNode(self.input_manager.server.allocator);
+ const node = try util.allocator.create(std.TailQueue(Keyboard).Node);
try node.data.init(self, device);
self.keyboards.append(node);
}
diff --git a/river/Server.zig b/river/Server.zig
index 27eebba..6f99d18 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -36,8 +36,6 @@ const View = @import("View.zig");
const ViewStack = @import("view_stack.zig").ViewStack;
const XwaylandUnmanaged = @import("XwaylandUnmanaged.zig");
-allocator: *std.mem.Allocator,
-
wl_display: *c.wl_display,
wl_event_loop: *c.wl_event_loop,
@@ -61,9 +59,7 @@ config: Config,
control: Control,
status_manager: StatusManager,
-pub fn init(self: *Self, allocator: *std.mem.Allocator) !void {
- self.allocator = allocator;
-
+pub fn init(self: *Self) !void {
// The Wayland display is managed by libwayland. It handles accepting
// clients from the Unix socket, managing Wayland globals, and so on.
self.wl_display = c.wl_display_create() orelse
@@ -120,7 +116,7 @@ pub fn init(self: *Self, allocator: *std.mem.Allocator) !void {
c.wl_signal_add(&self.wlr_xwayland.events.new_surface, &self.listen_new_xwayland_surface);
}
- try self.config.init(self.allocator);
+ try self.config.init();
try self.decoration_manager.init(self);
try self.root.init(self);
// Must be called after root is initialized
@@ -150,7 +146,7 @@ pub fn deinit(self: *Self) void {
c.river_wlr_backend_destory(self.noop_backend);
self.input_manager.deinit();
- self.config.deinit(self.allocator);
+ self.config.deinit();
}
/// Create the socket, set WAYLAND_DISPLAY, and start the backend
@@ -204,7 +200,7 @@ fn handleNewXdgSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) v
// The View will add itself to the output's view stack on map
const output = self.input_manager.default_seat.focused_output;
- const node = self.allocator.create(ViewStack(View).Node) catch unreachable;
+ const node = util.allocator.create(ViewStack(View).Node) catch unreachable;
node.view.init(output, output.current_focused_tags, wlr_xdg_surface);
}
@@ -251,7 +247,7 @@ fn handleNewLayerSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C)
// The layer surface will add itself to the proper list of the output on map
const output = util.voidCast(Output, wlr_layer_surface.output.*.data.?);
- const node = self.allocator.create(std.TailQueue(LayerSurface).Node) catch unreachable;
+ const node = util.allocator.create(std.TailQueue(LayerSurface).Node) catch unreachable;
node.data.init(output, wlr_layer_surface);
}
@@ -263,7 +259,7 @@ fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(
Log.Debug.log("New unmanaged xwayland surface", .{});
// The unmanged surface will add itself to the list of unmanaged views
// in Root when it is mapped.
- const node = self.allocator.create(std.TailQueue(XwaylandUnmanaged).Node) catch unreachable;
+ const node = util.allocator.create(std.TailQueue(XwaylandUnmanaged).Node) catch unreachable;
node.data.init(&self.root, wlr_xwayland_surface);
return;
}
@@ -275,6 +271,6 @@ fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(
// The View will add itself to the output's view stack on map
const output = self.input_manager.default_seat.focused_output;
- const node = self.allocator.create(ViewStack(View).Node) catch unreachable;
+ const node = util.allocator.create(ViewStack(View).Node) catch unreachable;
node.view.init(output, output.current_focused_tags, wlr_xwayland_surface);
}
diff --git a/river/StatusManager.zig b/river/StatusManager.zig
index 69f77fb..0fe3d6e 100644
--- a/river/StatusManager.zig
+++ b/river/StatusManager.zig
@@ -92,9 +92,8 @@ fn getRiverOutputStatus(
// This can be null if the output is inert, in which case we ignore the request
const wlr_output = c.wlr_output_from_resource(output_wl_resource) orelse return;
const output = util.voidCast(Output, wlr_output.*.data.?);
- const allocator = self.server.allocator;
- const node = allocator.create(std.SinglyLinkedList(OutputStatus).Node) catch {
+ const node = util.allocator.create(std.SinglyLinkedList(OutputStatus).Node) catch {
c.wl_client_post_no_memory(wl_client);
Log.Error.log("out of memory\n", .{});
return;
@@ -107,6 +106,7 @@ fn getRiverOutputStatus(
new_id,
) orelse {
c.wl_client_post_no_memory(wl_client);
+ util.allocator.destroy(node);
Log.Error.log("out of memory\n", .{});
return;
};
@@ -125,9 +125,8 @@ fn getRiverSeatStatus(
// This can be null if the seat is inert, in which case we ignore the request
const wlr_seat_client = c.wlr_seat_client_from_resource(seat_wl_resource) orelse return;
const seat = util.voidCast(Seat, wlr_seat_client.*.seat.*.data.?);
- const allocator = self.server.allocator;
- const node = allocator.create(std.SinglyLinkedList(SeatStatus).Node) catch {
+ const node = util.allocator.create(std.SinglyLinkedList(SeatStatus).Node) catch {
c.wl_client_post_no_memory(wl_client);
Log.Error.log("out of memory\n", .{});
return;
@@ -140,6 +139,7 @@ fn getRiverSeatStatus(
new_id,
) orelse {
c.wl_client_post_no_memory(wl_client);
+ util.allocator.destroy(node);
Log.Error.log("out of memory\n", .{});
return;
};
diff --git a/river/View.zig b/river/View.zig
index 6d6e147..0ff2344 100644
--- a/river/View.zig
+++ b/river/View.zig
@@ -88,12 +88,7 @@ pending_tags: ?u32,
pending_serial: ?u32,
-pub fn init(
- self: *Self,
- output: *Output,
- tags: u32,
- surface: var,
-) void {
+pub fn init(self: *Self, output: *Output, tags: u32, surface: var) void {
self.output = output;
self.wlr_surface = null;
@@ -113,7 +108,7 @@ pub fn init(
self.pending_serial = null;
- self.saved_buffers = std.ArrayList(SavedBuffer).init(output.root.server.allocator);
+ self.saved_buffers = std.ArrayList(SavedBuffer).init(util.allocator);
if (@TypeOf(surface) == *c.wlr_xdg_surface) {
self.impl = .{ .xdg_toplevel = undefined };
@@ -323,5 +318,5 @@ pub fn unmap(self: *Self) void {
pub fn destroy(self: *const Self) void {
self.deinit();
const node = @fieldParentPtr(ViewStack(Self).Node, "view", self);
- self.output.root.server.allocator.destroy(node);
+ util.allocator.destroy(node);
}
diff --git a/river/XdgPopup.zig b/river/XdgPopup.zig
index d56b7a2..ca172ff 100644
--- a/river/XdgPopup.zig
+++ b/river/XdgPopup.zig
@@ -63,21 +63,19 @@ pub fn init(
fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_destroy", listener.?);
- const allocator = self.output.root.server.allocator;
c.wl_list_remove(&self.listen_destroy.link);
c.wl_list_remove(&self.listen_new_popup.link);
- allocator.destroy(self);
+ util.allocator.destroy(self);
}
/// Called when a new xdg popup is requested by the client
fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_new_popup", listener.?);
const wlr_xdg_popup = util.voidCast(c.wlr_xdg_popup, data.?);
- const allocator = self.output.root.server.allocator;
// This will free itself on destroy
- var xdg_popup = allocator.create(Self) catch unreachable;
+ var xdg_popup = util.allocator.create(Self) catch unreachable;
xdg_popup.init(self.output, self.parent_box, wlr_xdg_popup);
}
diff --git a/river/XdgToplevel.zig b/river/XdgToplevel.zig
index f329d9a..a217742 100644
--- a/river/XdgToplevel.zig
+++ b/river/XdgToplevel.zig
@@ -244,9 +244,8 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
fn handleNewPopup(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
const self = @fieldParentPtr(Self, "listen_new_popup", listener.?);
const wlr_xdg_popup = util.voidCast(c.wlr_xdg_popup, data.?);
- const allocator = self.view.output.root.server.allocator;
// This will free itself on destroy
- var xdg_popup = allocator.create(XdgPopup) catch unreachable;
+ var xdg_popup = util.allocator.create(XdgPopup) catch unreachable;
xdg_popup.init(self.view.output, &self.view.current_box, wlr_xdg_popup);
}
diff --git a/river/XwaylandUnmanaged.zig b/river/XwaylandUnmanaged.zig
index ca70fa8..f21f064 100644
--- a/river/XwaylandUnmanaged.zig
+++ b/river/XwaylandUnmanaged.zig
@@ -93,7 +93,7 @@ fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
// Deallocate the node
const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self);
- self.root.server.allocator.destroy(node);
+ util.allocator.destroy(node);
}
/// Called when the xwayland surface is mapped, or ready to display on-screen.
diff --git a/river/main.zig b/river/main.zig
index 5b64241..0e95b5c 100644
--- a/river/main.zig
+++ b/river/main.zig
@@ -18,6 +18,7 @@
const std = @import("std");
const c = @import("c.zig");
+const util = @import("util.zig");
const Log = @import("log.zig").Log;
const Server = @import("Server.zig");
@@ -63,14 +64,14 @@ pub fn main() !void {
Log.Info.log("Initializing server", .{});
var server: Server = undefined;
- try server.init(std.heap.c_allocator);
+ try server.init();
defer server.deinit();
try server.start();
if (startup_command) |cmd| {
const child_args = [_][]const u8{ "/bin/sh", "-c", cmd };
- const child = try std.ChildProcess.init(&child_args, std.heap.c_allocator);
+ const child = try std.ChildProcess.init(&child_args, util.allocator);
defer child.deinit();
try std.ChildProcess.spawn(child);
}
diff --git a/river/util.zig b/river/util.zig
index c1064cb..28eb840 100644
--- a/river/util.zig
+++ b/river/util.zig
@@ -15,6 +15,11 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
+const std = @import("std");
+
+/// The global general-purpose allocator used throughout river's code
+pub const allocator = std.heap.c_allocator;
+
/// Take a pointer to c_void and cast it to a pointer to T. This function
/// exists to avoid having the verbosity of the required alignment casts all
/// over the code.