build: update to zig 0.14.0

This commit is contained in:
Isaac Freund 2025-03-07 12:37:11 +01:00
parent 0eb478b06a
commit 933701d7f9
No known key found for this signature in database
GPG Key ID: 86DED400DDFD7A11
26 changed files with 85 additions and 88 deletions

View File

@ -43,10 +43,10 @@ tasks:
cd .. cd ..
# Eat Github's resources rather than the Zig Software Foundation's resources! # Eat Github's resources rather than the Zig Software Foundation's resources!
wget -nv https://github.com/ifreund/zig-tarball-mirror/releases/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz wget -nv https://github.com/ifreund/zig-tarball-mirror/releases/download/0.14.0/zig-linux-x86_64-0.14.0.tar.xz
tar xf zig-linux-x86_64-0.13.0.tar.xz tar xf zig-linux-x86_64-0.14.0.tar.xz
sudo mv zig-linux-x86_64-0.13.0/zig /usr/bin/ sudo mv zig-linux-x86_64-0.14.0/zig /usr/bin/
sudo mv zig-linux-x86_64-0.13.0/lib /usr/lib/zig sudo mv zig-linux-x86_64-0.14.0/lib /usr/lib/zig
- build: | - build: |
cd river cd river
zig build --summary all zig build --summary all

View File

@ -41,10 +41,10 @@ tasks:
cd .. cd ..
# Eat Github's resources rather than the Zig Software Foundation's resources! # Eat Github's resources rather than the Zig Software Foundation's resources!
wget -nv https://github.com/ifreund/zig-tarball-mirror/releases/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz wget -nv https://github.com/ifreund/zig-tarball-mirror/releases/download/0.14.0/zig-linux-x86_64-0.14.0.tar.xz
tar xf zig-linux-x86_64-0.13.0.tar.xz tar xf zig-linux-x86_64-0.14.0.tar.xz
sudo mv zig-linux-x86_64-0.13.0/zig /usr/bin/ sudo mv zig-linux-x86_64-0.14.0/zig /usr/bin/
sudo mv zig-linux-x86_64-0.13.0/lib /usr/lib/zig sudo mv zig-linux-x86_64-0.14.0/lib /usr/lib/zig
- build: | - build: |
cd river cd river
zig build --summary all zig build --summary all

View File

@ -46,10 +46,10 @@ tasks:
cd .. cd ..
# Eat Github's resources rather than the Zig Software Foundation's resources! # Eat Github's resources rather than the Zig Software Foundation's resources!
wget -nv https://github.com/ifreund/zig-tarball-mirror/releases/download/0.13.0/zig-freebsd-x86_64-0.13.0.tar.xz wget -nv https://github.com/ifreund/zig-tarball-mirror/releases/download/0.14.0/zig-freebsd-x86_64-0.14.0-unofficial.tar.xz
tar xf zig-freebsd-x86_64-0.13.0.tar.xz tar xf zig-freebsd-x86_64-0.14.0-unofficial.tar.xz
sudo mv zig-freebsd-x86_64-0.13.0/zig /usr/bin/ sudo mv zig-freebsd-x86_64-0.14.0-unofficial/zig /usr/bin/
sudo mv zig-freebsd-x86_64-0.13.0/lib /usr/lib/zig sudo mv zig-freebsd-x86_64-0.14.0-unofficial/lib /usr/lib/zig
- build: | - build: |
cd river cd river
zig build --summary all zig build --summary all

View File

@ -57,7 +57,7 @@ To compile river first ensure that you have the following dependencies
installed. The "development" versions are required if applicable to your installed. The "development" versions are required if applicable to your
distribution. distribution.
- [zig](https://ziglang.org/download/) 0.13 - [zig](https://ziglang.org/download/) 0.14
- wayland - wayland
- wayland-protocols - wayland-protocols
- [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.18 - [wlroots](https://gitlab.freedesktop.org/wlroots/wlroots) 0.18

View File

@ -4,7 +4,7 @@ const Build = std.Build;
const fs = std.fs; const fs = std.fs;
const mem = std.mem; const mem = std.mem;
const Scanner = @import("zig-wayland").Scanner; const Scanner = @import("wayland").Scanner;
/// While a river release is in development, this string should contain the version in development /// While a river release is in development, this string should contain the version in development
/// with the "-dev" suffix. /// with the "-dev" suffix.
@ -71,7 +71,7 @@ pub fn build(b: *Build) !void {
.Inherit, .Inherit,
) catch break :blk version; ) catch break :blk version;
var it = mem.split(u8, mem.trim(u8, git_describe_long, &std.ascii.whitespace), "-"); var it = mem.splitScalar(u8, mem.trim(u8, git_describe_long, &std.ascii.whitespace), '-');
_ = it.next().?; // previous tag _ = it.next().?; // previous tag
const commit_count = it.next().?; const commit_count = it.next().?;
const commit_hash = it.next().?; const commit_hash = it.next().?;
@ -100,11 +100,11 @@ pub fn build(b: *Build) !void {
scanner.addSystemProtocol("unstable/pointer-gestures/pointer-gestures-unstable-v1.xml"); scanner.addSystemProtocol("unstable/pointer-gestures/pointer-gestures-unstable-v1.xml");
scanner.addSystemProtocol("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"); scanner.addSystemProtocol("unstable/xdg-decoration/xdg-decoration-unstable-v1.xml");
scanner.addCustomProtocol("protocol/river-control-unstable-v1.xml"); scanner.addCustomProtocol(b.path("protocol/river-control-unstable-v1.xml"));
scanner.addCustomProtocol("protocol/river-status-unstable-v1.xml"); scanner.addCustomProtocol(b.path("protocol/river-status-unstable-v1.xml"));
scanner.addCustomProtocol("protocol/river-layout-v3.xml"); scanner.addCustomProtocol(b.path("protocol/river-layout-v3.xml"));
scanner.addCustomProtocol("protocol/wlr-layer-shell-unstable-v1.xml"); scanner.addCustomProtocol(b.path("protocol/wlr-layer-shell-unstable-v1.xml"));
scanner.addCustomProtocol("protocol/wlr-output-power-management-unstable-v1.xml"); scanner.addCustomProtocol(b.path("protocol/wlr-output-power-management-unstable-v1.xml"));
// Some of these versions may be out of date with what wlroots implements. // Some of these versions may be out of date with what wlroots implements.
// This is not a problem in practice though as long as river successfully compiles. // This is not a problem in practice though as long as river successfully compiles.
@ -136,10 +136,10 @@ pub fn build(b: *Build) !void {
const wayland = b.createModule(.{ .root_source_file = scanner.result }); const wayland = b.createModule(.{ .root_source_file = scanner.result });
const xkbcommon = b.dependency("zig-xkbcommon", .{}).module("xkbcommon"); const xkbcommon = b.dependency("xkbcommon", .{}).module("xkbcommon");
const pixman = b.dependency("zig-pixman", .{}).module("pixman"); const pixman = b.dependency("pixman", .{}).module("pixman");
const wlroots = b.dependency("zig-wlroots", .{}).module("wlroots"); const wlroots = b.dependency("wlroots", .{}).module("wlroots");
wlroots.addImport("wayland", wayland); wlroots.addImport("wayland", wayland);
wlroots.addImport("xkbcommon", xkbcommon); wlroots.addImport("xkbcommon", xkbcommon);
wlroots.addImport("pixman", pixman); wlroots.addImport("pixman", pixman);
@ -185,9 +185,6 @@ pub fn build(b: *Build) !void {
.flags = &.{ "-std=c99", "-O2" }, .flags = &.{ "-std=c99", "-O2" },
}); });
// TODO: remove when zig issue #131 is implemented
scanner.addCSource(river);
river.pie = pie; river.pie = pie;
river.root_module.omit_frame_pointer = omit_frame_pointer; river.root_module.omit_frame_pointer = omit_frame_pointer;
@ -211,8 +208,6 @@ pub fn build(b: *Build) !void {
riverctl.linkLibC(); riverctl.linkLibC();
riverctl.linkSystemLibrary("wayland-client"); riverctl.linkSystemLibrary("wayland-client");
scanner.addCSource(riverctl);
riverctl.pie = pie; riverctl.pie = pie;
riverctl.root_module.omit_frame_pointer = omit_frame_pointer; riverctl.root_module.omit_frame_pointer = omit_frame_pointer;
@ -236,8 +231,6 @@ pub fn build(b: *Build) !void {
rivertile.linkLibC(); rivertile.linkLibC();
rivertile.linkSystemLibrary("wayland-client"); rivertile.linkSystemLibrary("wayland-client");
scanner.addCSource(rivertile);
rivertile.pie = pie; rivertile.pie = pie;
rivertile.root_module.omit_frame_pointer = omit_frame_pointer; rivertile.root_module.omit_frame_pointer = omit_frame_pointer;

View File

@ -1,23 +1,24 @@
.{ .{
.name = "river", .name = .river,
.version = "0.3.8-dev", .version = "0.3.8-dev",
.paths = .{""}, .paths = .{""},
.dependencies = .{ .dependencies = .{
.@"zig-pixman" = .{ .pixman = .{
.url = "https://codeberg.org/ifreund/zig-pixman/archive/v0.2.0.tar.gz", .url = "https://codeberg.org/ifreund/zig-pixman/archive/v0.3.0.tar.gz",
.hash = "12209db20ce873af176138b76632931def33a10539387cba745db72933c43d274d56", .hash = "pixman-0.3.0-LClMnz2VAAAs7QSCGwLimV5VUYx0JFnX5xWU6HwtMuDX",
}, },
.@"zig-wayland" = .{ .wayland = .{
.url = "https://codeberg.org/ifreund/zig-wayland/archive/v0.2.0.tar.gz", .url = "https://codeberg.org/ifreund/zig-wayland/archive/v0.3.0.tar.gz",
.hash = "1220687c8c47a48ba285d26a05600f8700d37fc637e223ced3aa8324f3650bf52242", .hash = "wayland-0.3.0-lQa1kjPIAQDmhGYpY-zxiRzQJFHQ2VqhJkQLbKKdt5wl",
}, },
.@"zig-wlroots" = .{ .wlroots = .{
.url = "https://codeberg.org/ifreund/zig-wlroots/archive/v0.18.1.tar.gz", .url = "https://codeberg.org/ifreund/zig-wlroots/archive/v0.18.2.tar.gz",
.hash = "122083317b028705b5d27be12976feebf17066a4e51802b3b5e9f970bec580e433e1", .hash = "wlroots-0.18.2-jmOlchnIAwBq45_cxU1V3OWErxxJjQZlc9PyJfR-l3uk",
}, },
.@"zig-xkbcommon" = .{ .xkbcommon = .{
.url = "https://codeberg.org/ifreund/zig-xkbcommon/archive/v0.2.0.tar.gz", .url = "https://codeberg.org/ifreund/zig-xkbcommon/archive/v0.3.0.tar.gz",
.hash = "1220c90b2228d65fd8427a837d31b0add83e9fade1dcfa539bb56fd06f1f8461605f", .hash = "xkbcommon-0.3.0-VDqIe3K9AQB2fG5ZeRcMC9i7kfrp5m2rWgLrmdNn9azr",
}, },
}, },
.fingerprint = 0xf5e3672b8e8d6efc,
} }

View File

@ -42,21 +42,21 @@ pub fn parser(comptime Arg: type, comptime flags: []const Flag) type {
.boolean => .{ .boolean => .{
.name = flag.name, .name = flag.name,
.type = bool, .type = bool,
.default_value = &false, .default_value_ptr = &false,
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(bool), .alignment = @alignOf(bool),
}, },
.arg => .{ .arg => .{
.name = flag.name, .name = flag.name,
.type = ?[:0]const u8, .type = ?[:0]const u8,
.default_value = &@as(?[:0]const u8, null), .default_value_ptr = &@as(?[:0]const u8, null),
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(?[:0]const u8), .alignment = @alignOf(?[:0]const u8),
}, },
}; };
fields = fields ++ [_]std.builtin.Type.StructField{field}; fields = fields ++ [_]std.builtin.Type.StructField{field};
} }
break :flags_type @Type(.{ .Struct = .{ break :flags_type @Type(.{ .@"struct" = .{
.layout = .auto, .layout = .auto,
.fields = fields, .fields = fields,
.decls = &.{}, .decls = &.{},

View File

@ -1089,13 +1089,12 @@ pub fn updateState(cursor: *Cursor) void {
.passthrough => { .passthrough => {
cursor.updateFocusFollowsCursorTarget(); cursor.updateFocusFollowsCursorTarget();
if (!cursor.hidden) { if (!cursor.hidden) {
var now: posix.timespec = undefined; const now = posix.clock_gettime(.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported");
posix.clock_gettime(posix.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
// 2^32-1 milliseconds is ~50 days, which is a realistic uptime. // 2^32-1 milliseconds is ~50 days, which is a realistic uptime.
// This means that we must wrap if the monotonic time is greater than // This means that we must wrap if the monotonic time is greater than
// 2^32-1 milliseconds and hope that clients don't get too confused. // 2^32-1 milliseconds and hope that clients don't get too confused.
const msec: u32 = @intCast(@rem( const msec: u32 = @intCast(@rem(
now.tv_sec *% std.time.ms_per_s +% @divTrunc(now.tv_nsec, std.time.ns_per_ms), now.sec *% std.time.ms_per_s +% @divTrunc(now.nsec, std.time.ns_per_ms),
math.maxInt(u32), math.maxInt(u32),
)); ));
cursor.passthrough(msec); cursor.passthrough(msec);

View File

@ -30,7 +30,7 @@ const View = @import("View.zig");
wlr_manager: *wlr.IdleInhibitManagerV1, wlr_manager: *wlr.IdleInhibitManagerV1,
new_idle_inhibitor: wl.Listener(*wlr.IdleInhibitorV1) = new_idle_inhibitor: wl.Listener(*wlr.IdleInhibitorV1) =
wl.Listener(*wlr.IdleInhibitorV1).init(handleNewIdleInhibitor), wl.Listener(*wlr.IdleInhibitorV1).init(handleNewIdleInhibitor),
inhibitors: std.TailQueue(IdleInhibitor) = .{}, inhibitors: std.DoublyLinkedList(IdleInhibitor) = .{},
pub fn init(inhibit_manager: *IdleInhibitManager) !void { pub fn init(inhibit_manager: *IdleInhibitManager) !void {
inhibit_manager.* = .{ inhibit_manager.* = .{
@ -79,7 +79,7 @@ pub fn checkActive(inhibit_manager: *IdleInhibitManager) void {
fn handleNewIdleInhibitor(listener: *wl.Listener(*wlr.IdleInhibitorV1), inhibitor: *wlr.IdleInhibitorV1) void { fn handleNewIdleInhibitor(listener: *wl.Listener(*wlr.IdleInhibitorV1), inhibitor: *wlr.IdleInhibitorV1) void {
const inhibit_manager: *IdleInhibitManager = @fieldParentPtr("new_idle_inhibitor", listener); const inhibit_manager: *IdleInhibitManager = @fieldParentPtr("new_idle_inhibitor", listener);
const inhibitor_node = util.gpa.create(std.TailQueue(IdleInhibitor).Node) catch return; const inhibitor_node = util.gpa.create(std.DoublyLinkedList(IdleInhibitor).Node) catch return;
inhibitor_node.data.init(inhibitor, inhibit_manager) catch { inhibitor_node.data.init(inhibitor, inhibit_manager) catch {
util.gpa.destroy(inhibitor_node); util.gpa.destroy(inhibitor_node);
return; return;

View File

@ -49,7 +49,7 @@ fn handleDestroy(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
inhibitor.destroy.link.remove(); inhibitor.destroy.link.remove();
const node: *std.TailQueue(IdleInhibitor).Node = @fieldParentPtr("data", inhibitor); const node: *std.DoublyLinkedList(IdleInhibitor).Node = @fieldParentPtr("data", inhibitor);
server.idle_inhibit_manager.inhibitors.remove(node); server.idle_inhibit_manager.inhibitors.remove(node);
inhibitor.inhibit_manager.checkActive(); inhibitor.inhibit_manager.checkActive();

View File

@ -307,7 +307,7 @@ pub fn apply(config: *const InputConfig, device: *InputDevice) void {
const libinput_device: *c.libinput_device = @ptrCast(device.wlr_device.getLibinputDevice() orelse return); const libinput_device: *c.libinput_device = @ptrCast(device.wlr_device.getLibinputDevice() orelse return);
log.debug("applying input configuration '{s}' to device '{s}'.", .{ config.glob, device.identifier }); log.debug("applying input configuration '{s}' to device '{s}'.", .{ config.glob, device.identifier });
inline for (@typeInfo(InputConfig).Struct.fields) |field| { inline for (@typeInfo(InputConfig).@"struct".fields) |field| {
if (comptime mem.eql(u8, field.name, "glob")) continue; if (comptime mem.eql(u8, field.name, "glob")) continue;
if (@field(config, field.name)) |setting| { if (@field(config, field.name)) |setting| {
@ -324,7 +324,7 @@ pub fn apply(config: *const InputConfig, device: *InputDevice) void {
} }
pub fn parse(config: *InputConfig, setting: []const u8, value: []const u8) !void { pub fn parse(config: *InputConfig, setting: []const u8, value: []const u8) !void {
inline for (@typeInfo(InputConfig).Struct.fields) |field| { inline for (@typeInfo(InputConfig).@"struct".fields) |field| {
if (comptime mem.eql(u8, field.name, "glob")) continue; if (comptime mem.eql(u8, field.name, "glob")) continue;
if (mem.eql(u8, setting, field.name)) { if (mem.eql(u8, setting, field.name)) {
@ -358,8 +358,8 @@ pub fn parse(config: *InputConfig, setting: []const u8, value: []const u8) !void
} }
config.@"map-to-output" = .{ .output_name = output_name_owned }; config.@"map-to-output" = .{ .output_name = output_name_owned };
} else { } else {
const T = @typeInfo(field.type).Optional.child; const T = @typeInfo(field.type).optional.child;
if (@typeInfo(T) != .Enum) { if (@typeInfo(T) != .@"enum") {
@compileError("You forgot to implement parsing for an input configuration setting."); @compileError("You forgot to implement parsing for an input configuration setting.");
} }
@field(config, field.name) = meta.stringToEnum(T, value) orelse @field(config, field.name) = meta.stringToEnum(T, value) orelse
@ -376,7 +376,7 @@ pub fn parse(config: *InputConfig, setting: []const u8, value: []const u8) !void
pub fn write(config: *InputConfig, writer: anytype) !void { pub fn write(config: *InputConfig, writer: anytype) !void {
try writer.print("{s}\n", .{config.glob}); try writer.print("{s}\n", .{config.glob});
inline for (@typeInfo(InputConfig).Struct.fields) |field| { inline for (@typeInfo(InputConfig).@"struct".fields) |field| {
if (comptime mem.eql(u8, field.name, "glob")) continue; if (comptime mem.eql(u8, field.name, "glob")) continue;
if (comptime mem.eql(u8, field.name, "map-to-output")) { if (comptime mem.eql(u8, field.name, "map-to-output")) {
@ -396,8 +396,8 @@ pub fn write(config: *InputConfig, writer: anytype) !void {
mem.sliceTo(c.libevdev_event_code_get_name(c.EV_KEY, setting.button), 0), mem.sliceTo(c.libevdev_event_code_get_name(c.EV_KEY, setting.button), 0),
}); });
} else { } else {
const T = @typeInfo(field.type).Optional.child; const T = @typeInfo(field.type).optional.child;
if (@typeInfo(T) != .Enum) { if (@typeInfo(T) != .@"enum") {
@compileError("You forgot to implement listing for an input configuration setting."); @compileError("You forgot to implement listing for an input configuration setting.");
} }
try writer.print("\t{s}: {s}\n", .{ field.name, @tagName(setting) }); try writer.print("\t{s}: {s}\n", .{ field.name, @tagName(setting) });

View File

@ -58,7 +58,7 @@ tablet_manager: *wlr.TabletManagerV2,
configs: std.ArrayList(InputConfig), configs: std.ArrayList(InputConfig),
devices: wl.list.Head(InputDevice, .link), devices: wl.list.Head(InputDevice, .link),
seats: std.TailQueue(Seat) = .{}, seats: std.DoublyLinkedList(Seat) = .{},
exclusive_client: ?*wl.Client = null, exclusive_client: ?*wl.Client = null,
@ -74,7 +74,7 @@ new_text_input: wl.Listener(*wlr.TextInputV3) =
wl.Listener(*wlr.TextInputV3).init(handleNewTextInput), wl.Listener(*wlr.TextInputV3).init(handleNewTextInput),
pub fn init(input_manager: *InputManager) !void { pub fn init(input_manager: *InputManager) !void {
const seat_node = try util.gpa.create(std.TailQueue(Seat).Node); const seat_node = try util.gpa.create(std.DoublyLinkedList(Seat).Node);
errdefer util.gpa.destroy(seat_node); errdefer util.gpa.destroy(seat_node);
input_manager.* = .{ input_manager.* = .{

View File

@ -54,7 +54,7 @@ pub const Pressed = struct {
// Furthermore, wlroots will continue to forward key press/release events to river if more // Furthermore, wlroots will continue to forward key press/release events to river if more
// than 32 keys are pressed. Therefore river chooses to ignore keypresses that would take // than 32 keys are pressed. Therefore river chooses to ignore keypresses that would take
// the keyboard beyond 32 simultaneously pressed keys. // the keyboard beyond 32 simultaneously pressed keys.
assert(capacity == @typeInfo(std.meta.fieldInfo(wlr.Keyboard, .keycodes).type).Array.len); assert(capacity == @typeInfo(std.meta.fieldInfo(wlr.Keyboard, .keycodes).type).array.len);
} }
keys: std.BoundedArray(Key, capacity) = .{}, keys: std.BoundedArray(Key, capacity) = .{},

View File

@ -41,7 +41,7 @@ globs: std.ArrayListUnmanaged([]const u8) = .{},
pub fn create(seat: *Seat, name: []const u8) !void { pub fn create(seat: *Seat, name: []const u8) !void {
log.debug("new keyboard group: '{s}'", .{name}); log.debug("new keyboard group: '{s}'", .{name});
const node = try util.gpa.create(std.TailQueue(KeyboardGroup).Node); const node = try util.gpa.create(std.DoublyLinkedList(KeyboardGroup).Node);
errdefer util.gpa.destroy(node); errdefer util.gpa.destroy(node);
const wlr_group = try wlr.KeyboardGroup.create(); const wlr_group = try wlr.KeyboardGroup.create();
@ -72,7 +72,7 @@ pub fn destroy(group: *KeyboardGroup) void {
group.wlr_group.destroy(); group.wlr_group.destroy();
const node: *std.TailQueue(KeyboardGroup).Node = @fieldParentPtr("data", group); const node: *std.DoublyLinkedList(KeyboardGroup).Node = @fieldParentPtr("data", group);
group.seat.keyboard_groups.remove(node); group.seat.keyboard_groups.remove(node);
util.gpa.destroy(node); util.gpa.destroy(node);
} }

View File

@ -47,7 +47,7 @@ pub fn create(client: *wl.Client, version: u32, id: u32, output: *Output, namesp
return; return;
} }
const node = try util.gpa.create(std.TailQueue(Layout).Node); const node = try util.gpa.create(std.DoublyLinkedList(Layout).Node);
errdefer util.gpa.destroy(node); errdefer util.gpa.destroy(node);
node.data = .{ node.data = .{
.layout_v3 = layout_v3, .layout_v3 = layout_v3,
@ -186,7 +186,7 @@ pub fn destroy(layout: *Layout) void {
); );
// Remove layout from the list // Remove layout from the list
const node: *std.TailQueue(Layout).Node = @fieldParentPtr("data", layout); const node: *std.DoublyLinkedList(Layout).Node = @fieldParentPtr("data", layout);
layout.output.layouts.remove(node); layout.output.layouts.remove(node);
// If we are the currently active layout of an output, clean up. // If we are the currently active layout of an output, clean up.

View File

@ -171,7 +171,7 @@ previous_tags: u32 = 1 << 0,
attach_mode: ?Config.AttachMode = null, attach_mode: ?Config.AttachMode = null,
/// List of all layouts /// List of all layouts
layouts: std.TailQueue(Layout) = .{}, layouts: std.DoublyLinkedList(Layout) = .{},
/// The current layout namespace of the output. If null, /// The current layout namespace of the output. If null,
/// config.default_layout_namespace should be used instead. /// config.default_layout_namespace should be used instead.
@ -536,8 +536,7 @@ fn handleFrame(listener: *wl.Listener(*wlr.Output), _: *wlr.Output) void {
error.CommitFailed => log.err("output commit failed for {s}", .{output.wlr_output.name}), error.CommitFailed => log.err("output commit failed for {s}", .{output.wlr_output.name}),
}; };
var now: posix.timespec = undefined; var now = posix.clock_gettime(.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported");
posix.clock_gettime(posix.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
scene_output.sendFrameDone(&now); scene_output.sendFrameDone(&now);
} }

View File

@ -84,7 +84,7 @@ mapping_repeat_timer: *wl.EventSource,
/// Currently repeating mapping, if any /// Currently repeating mapping, if any
repeating_mapping: ?*const Mapping = null, repeating_mapping: ?*const Mapping = null,
keyboard_groups: std.TailQueue(KeyboardGroup) = .{}, keyboard_groups: std.DoublyLinkedList(KeyboardGroup) = .{},
/// Currently focused output. Null only when there are no outputs at all. /// Currently focused output. Null only when there are no outputs at all.
focused_output: ?*Output = null, focused_output: ?*Output = null,

View File

@ -303,8 +303,8 @@ fn allowlist(server: *Server, global: *const wl.Global) bool {
// For other globals I like the current pointer comparison approach as it // For other globals I like the current pointer comparison approach as it
// should catch river accidentally exposing multiple copies of e.g. wl_shm // should catch river accidentally exposing multiple copies of e.g. wl_shm
// with an assertion failure. // with an assertion failure.
return global.getInterface() == wl.Output.getInterface() or return global.getInterface() == wl.Output.interface or
global.getInterface() == wl.Seat.getInterface() or global.getInterface() == wl.Seat.interface or
global == server.shm.global or global == server.shm.global or
global == server.single_pixel_buffer_manager.global or global == server.single_pixel_buffer_manager.global or
global == server.viewporter.global or global == server.viewporter.global or

View File

@ -482,8 +482,7 @@ pub fn rootSurface(view: View) ?*wlr.Surface {
pub fn sendFrameDone(view: View) void { pub fn sendFrameDone(view: View) void {
assert(view.mapped and !view.destroying); assert(view.mapped and !view.destroying);
var now: posix.timespec = undefined; const now = posix.clock_gettime(.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported");
posix.clock_gettime(posix.CLOCK.MONOTONIC, &now) catch @panic("CLOCK_MONOTONIC not supported");
view.rootSurface().?.sendFrameDone(&now); view.rootSurface().?.sendFrameDone(&now);
} }

View File

@ -285,7 +285,7 @@ fn parseKeysym(name: [:0]const u8, out: *?[]const u8) !xkb.Keysym {
} }
fn parseModifiers(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 it = mem.splitScalar(u8, modifiers_str, '+');
var modifiers = wlr.Keyboard.ModifierMask{}; var modifiers = wlr.Keyboard.ModifierMask{};
outer: while (it.next()) |mod_name| { outer: while (it.next()) |mod_name| {
if (mem.eql(u8, mod_name, "None")) continue; if (mem.eql(u8, mod_name, "None")) continue;

View File

@ -26,6 +26,7 @@ const util = @import("../util.zig");
const Error = @import("../command.zig").Error; const Error = @import("../command.zig").Error;
const Seat = @import("../Seat.zig"); const Seat = @import("../Seat.zig");
const View = @import("../View.zig"); const View = @import("../View.zig");
const RuleGlobs = @import("../rule_list.zig").RuleGlobs;
const Action = enum { const Action = enum {
float, float,
@ -157,7 +158,7 @@ pub fn ruleDel(_: *Seat, args: []const [:0]const u8, _: *?[]const u8) Error!void
const action = std.meta.stringToEnum(Action, result.args[0]) orelse return Error.UnknownOption; const action = std.meta.stringToEnum(Action, result.args[0]) orelse return Error.UnknownOption;
const rule = .{ const rule: RuleGlobs = .{
.app_id_glob = result.flags.@"app-id" orelse "*", .app_id_glob = result.flags.@"app-id" orelse "*",
.title_glob = result.flags.title orelse "*", .title_glob = result.flags.title orelse "*",
}; };

View File

@ -29,7 +29,7 @@ pub fn setup() void {
.mask = posix.empty_sigset, .mask = posix.empty_sigset,
.flags = 0, .flags = 0,
}; };
posix.sigaction(posix.SIG.PIPE, &sig_ign, null) catch unreachable; posix.sigaction(posix.SIG.PIPE, &sig_ign, null);
// Most unix systems have a default limit of 1024 file descriptors and it // Most unix systems have a default limit of 1024 file descriptors and it
// seems unlikely for this default to be universally raised due to the // seems unlikely for this default to be universally raised due to the
@ -68,7 +68,7 @@ pub fn cleanupChild() void {
.mask = posix.empty_sigset, .mask = posix.empty_sigset,
.flags = 0, .flags = 0,
}; };
posix.sigaction(posix.SIG.PIPE, &sig_dfl, null) catch unreachable; posix.sigaction(posix.SIG.PIPE, &sig_dfl, null);
if (original_rlimit) |original| { if (original_rlimit) |original| {
posix.setrlimit(.NOFILE, original) catch { posix.setrlimit(.NOFILE, original) catch {

View File

@ -23,6 +23,11 @@ const util = @import("util.zig");
const View = @import("View.zig"); const View = @import("View.zig");
pub const RuleGlobs = struct {
app_id_glob: []const u8,
title_glob: []const u8,
};
pub const MaxGlobLen = struct { pub const MaxGlobLen = struct {
app_id: usize, app_id: usize,
title: usize, title: usize,
@ -83,7 +88,7 @@ pub fn RuleList(comptime T: type) type {
}); });
} }
pub fn del(list: *List, rule: struct { app_id_glob: []const u8, title_glob: []const u8 }) ?T { pub fn del(list: *List, rule: RuleGlobs) ?T {
for (list.rules.items, 0..) |existing, i| { for (list.rules.items, 0..) |existing, i| {
if (mem.eql(u8, rule.app_id_glob, existing.app_id_glob) and if (mem.eql(u8, rule.app_id_glob, existing.app_id_glob) and
mem.eql(u8, rule.title_glob, existing.title_glob)) mem.eql(u8, rule.title_glob, existing.title_glob))

View File

@ -110,10 +110,10 @@ fn _main() !void {
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *Globals) void { fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *Globals) void {
switch (event) { switch (event) {
.global => |global| { .global => |global| {
if (mem.orderZ(u8, global.interface, wl.Seat.getInterface().name) == .eq) { if (mem.orderZ(u8, global.interface, wl.Seat.interface.name) == .eq) {
assert(globals.seat == null); // TODO: support multiple seats assert(globals.seat == null); // TODO: support multiple seats
globals.seat = registry.bind(global.name, wl.Seat, 1) catch @panic("out of memory"); globals.seat = registry.bind(global.name, wl.Seat, 1) catch @panic("out of memory");
} else if (mem.orderZ(u8, global.interface, zriver.ControlV1.getInterface().name) == .eq) { } else if (mem.orderZ(u8, global.interface, zriver.ControlV1.interface.name) == .eq) {
globals.control = registry.bind(global.name, zriver.ControlV1, 1) catch @panic("out of memory"); globals.control = registry.bind(global.name, zriver.ControlV1, 1) catch @panic("out of memory");
} }
}, },

View File

@ -91,12 +91,12 @@ const gpa = std.heap.c_allocator;
const Context = struct { const Context = struct {
initialized: bool = false, initialized: bool = false,
layout_manager: ?*river.LayoutManagerV3 = null, layout_manager: ?*river.LayoutManagerV3 = null,
outputs: std.TailQueue(Output) = .{}, outputs: std.DoublyLinkedList(Output) = .{},
fn addOutput(context: *Context, registry: *wl.Registry, name: u32) !void { fn addOutput(context: *Context, registry: *wl.Registry, name: u32) !void {
const wl_output = try registry.bind(name, wl.Output, 3); const wl_output = try registry.bind(name, wl.Output, 3);
errdefer wl_output.release(); errdefer wl_output.release();
const node = try gpa.create(std.TailQueue(Output).Node); const node = try gpa.create(std.DoublyLinkedList(Output).Node);
errdefer gpa.destroy(node); errdefer gpa.destroy(node);
try node.data.init(context, wl_output, name); try node.data.init(context, wl_output, name);
context.outputs.append(node); context.outputs.append(node);
@ -140,7 +140,7 @@ const Output = struct {
.namespace_in_use => fatal("namespace 'rivertile' already in use.", .{}), .namespace_in_use => fatal("namespace 'rivertile' already in use.", .{}),
.user_command => |ev| { .user_command => |ev| {
var it = mem.tokenize(u8, mem.span(ev.command), " "); var it = mem.tokenizeScalar(u8, mem.span(ev.command), ' ');
const raw_cmd = it.next() orelse { const raw_cmd = it.next() orelse {
std.log.err("not enough arguments", .{}); std.log.err("not enough arguments", .{});
return; return;
@ -382,9 +382,9 @@ pub fn main() !void {
fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, context: *Context) void { fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, context: *Context) void {
switch (event) { switch (event) {
.global => |global| { .global => |global| {
if (mem.orderZ(u8, global.interface, river.LayoutManagerV3.getInterface().name) == .eq) { if (mem.orderZ(u8, global.interface, river.LayoutManagerV3.interface.name) == .eq) {
context.layout_manager = registry.bind(global.name, river.LayoutManagerV3, 1) catch return; context.layout_manager = registry.bind(global.name, river.LayoutManagerV3, 1) catch return;
} else if (mem.orderZ(u8, global.interface, wl.Output.getInterface().name) == .eq) { } else if (mem.orderZ(u8, global.interface, wl.Output.interface.name) == .eq) {
context.addOutput(registry, global.name) catch |err| fatal("failed to bind output: {}", .{err}); context.addOutput(registry, global.name) catch |err| fatal("failed to bind output: {}", .{err});
} }
}, },