From 4e02a07bf13faef82128bc120b05f6dee4fa5767 Mon Sep 17 00:00:00 2001 From: Ben Buhse Date: Fri, 30 Jan 2026 21:09:02 -0600 Subject: [PATCH] Implement zoom keybind --- examples/config.kdl | 1 + src/Config.zig | 3 +++ src/XkbBindings.zig | 27 +++++++++++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/examples/config.kdl b/examples/config.kdl index e1c345a..38a1fae 100644 --- a/examples/config.kdl +++ b/examples/config.kdl @@ -10,6 +10,7 @@ keybinds { spawn mod4 t foot focus_next mod4 j focus_prev mod4 k + zoom mod4 z toggle_fullscreen mod4 f close_window mod4+Shift q // Generates keybinds for keys 1-9 → tags 1<<0 through 1<<9 diff --git a/src/Config.zig b/src/Config.zig index f45abea..6be61bb 100644 --- a/src/Config.zig +++ b/src/Config.zig @@ -319,6 +319,9 @@ fn loadKeybindsChildBlock(config: *Config, parser: *kdl.Parser) !void { .focus_prev => { break :sw .focus_prev; }, + .zoom => { + break :sw .zoom; + }, .toggle_fullscreen => { break :sw .toggle_fullscreen; }, diff --git a/src/XkbBindings.zig b/src/XkbBindings.zig index 7ce1c2f..d8b9e52 100644 --- a/src/XkbBindings.zig +++ b/src/XkbBindings.zig @@ -8,7 +8,7 @@ pub const Command = union(enum) { spawn: []const []const u8, focus_next, focus_prev, - // zoom, // TODO + zoom, // ratio_up, // TODO // ratio_down, // TODO // reload_config, // TODO @@ -104,7 +104,29 @@ const XkbBinding = struct { } else { seat.pending_manage.pending_focus = .clear_focus; } - // context.wm.window_manager_v1.manageDirty(); + }, + .zoom => { + const wm = context.wm; + const seat = wm.seats.first() orelse return; + const current_focus = if (seat.pending_manage.pending_focus) |pending_focus| blk: { + switch (pending_focus) { + .clear_focus => return, + .window => |window| break :blk window, + } + } else seat.focused orelse return; + const first_window: *Window = if (wm.windows.first()) |first| blk: { + if (current_focus == first) { + // Try get the second window instead + break :blk @fieldParentPtr("link", first.link.next orelse return); + } else { + seat.pending_manage.should_warp_pointer = true; + break :blk first; + } + } else { + // If current_focus is not null, we know that first_window *must not* be null. + unreachable; + }; + current_focus.link.swapWith(&first_window.link); }, .toggle_fullscreen => { const seat = context.wm.seats.first() orelse return; @@ -215,5 +237,6 @@ const xkbcommon = @import("xkbcommon"); const utils = @import("utils.zig"); const Context = @import("Context.zig"); const Seat = @import("Seat.zig"); +const Window = @import("Window.zig"); const log = std.log.scoped(.XkbBindings);