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.
This commit is contained in:
Isaac Freund 2020-06-16 22:08:36 +02:00
parent fb8d855ec9
commit c5de1641dc
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
17 changed files with 76 additions and 86 deletions

View file

@ -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();

View file

@ -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(

View file

@ -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 {

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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();

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
};

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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.

View file

@ -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);
}

View file

@ -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.