Implement configuration for keybindings

Keybinds go in a "keybinds" block and follow the format

<command> <modifiers> <keysym> <options>

But there's also a special "tag_bind" command that just takes modifiers
and one of set_output_tags, set_window_tags, toggle_output_tags, and
toggle_window_tags. It will automatically be used to loop through the
1-9 keys on tags 1<<0 to 1<<9, however, you can still implement those
commands individually if you want.
This commit is contained in:
Ben Buhse 2026-01-30 19:43:49 -06:00
commit fd8b6d0d41
No known key found for this signature in database
GPG key ID: 7916ACFCD38FD0B4
9 changed files with 350 additions and 84 deletions

View file

@ -11,14 +11,12 @@ const Globals = struct {
pub fn main() !void {
const wayland_display_var = try utils.allocator.dupeZ(u8, process.getEnvVarOwned(utils.allocator, "WAYLAND_DISPLAY") catch {
log.err("Error getting WAYLAND_DISPLAY environment variable. Exiting", .{});
std.posix.exit(1);
fatal("Error getting WAYLAND_DISPLAY environment variable. Exiting", .{});
});
defer utils.allocator.free(wayland_display_var);
const wl_display = wl.Display.connect(null) catch {
log.err("Error connecting to Wayland server. Exiting", .{});
std.posix.exit(1);
fatal("Error connecting to Wayland server. Exiting", .{});
};
defer wl_display.disconnect();
@ -29,8 +27,7 @@ pub fn main() !void {
const errno = wl_display.roundtrip();
if (errno != .SUCCESS) {
log.err("Initial roundtrip failed: E{s}", .{@tagName(errno)});
std.posix.exit(1);
fatal("Initial roundtrip failed: E{s}", .{@tagName(errno)});
}
const wl_compositor = globals.wl_compositor orelse utils.interfaceNotAdvertised(wl.Compositor);
@ -51,8 +48,7 @@ pub fn main() !void {
while (true) {
if (wl_display.dispatch() != .SUCCESS) {
log.err("wayland display dispatch failed", .{});
std.posix.exit(1);
fatal("wayland display dispatch failed", .{});
}
}
@ -65,18 +61,15 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *
if (mem.orderZ(u8, ev.interface, wl.Compositor.interface.name) == .eq) {
if (ev.version < 4) utils.versionNotSupported(wl.Compositor, ev.version, 4);
globals.wl_compositor = registry.bind(ev.name, wl.Compositor, 4) catch |e| {
log.err("Failed to bind to compositor: {any}", .{@errorName(e)});
std.posix.exit(1);
fatal("Failed to bind to compositor: {any}", .{@errorName(e)});
};
} else if (mem.orderZ(u8, ev.interface, river.WindowManagerV1.interface.name) == .eq) {
globals.river_window_manager_v1 = registry.bind(ev.name, river.WindowManagerV1, 3) catch |e| {
log.err("Failed to bind to window_manager_v1: {any}", .{@errorName(e)});
std.posix.exit(1);
fatal("Failed to bind to window_manager_v1: {any}", .{@errorName(e)});
};
} else if (mem.orderZ(u8, ev.interface, river.XkbBindingsV1.interface.name) == .eq) {
globals.river_xkb_bindings_v1 = registry.bind(ev.name, river.XkbBindingsV1, 2) catch |e| {
log.err("Failed to bind to xkb_bindings_v1: {any}", .{@errorName(e)});
std.posix.exit(1);
fatal("Failed to bind to xkb_bindings_v1: {any}", .{@errorName(e)});
};
}
},
@ -87,6 +80,7 @@ fn registryListener(registry: *wl.Registry, event: wl.Registry.Event, globals: *
const std = @import("std");
const mem = std.mem;
const fatal = std.process.fatal;
const process = std.process;
const wayland = @import("wayland");