Add change_ratio keybind

This commit is contained in:
Ben Buhse 2026-01-30 21:47:16 -06:00
commit 365c000b6e
No known key found for this signature in database
GPG key ID: 7916ACFCD38FD0B4
5 changed files with 49 additions and 16 deletions

View file

@ -7,15 +7,17 @@ borders {
color_unfocused "0x1e1e2e" color_unfocused "0x1e1e2e"
} }
keybinds { keybinds {
spawn mod4 t foot spawn Mod4 T foot
focus_next mod4 j focus_next Mod4 J
focus_prev mod4 k focus_prev Mod4 K
zoom mod4 z zoom Mod4 Z
toggle_fullscreen mod4 f change_ratio Mod4 H +0.05
close_window mod4+Shift q change_ratio Mod4 L -0.05
toggle_fullscreen Mod4 F
close_window Mod4+Shift Q
// Generates keybinds for keys 1-9 → tags 1<<0 through 1<<9 // Generates keybinds for keys 1-9 → tags 1<<0 through 1<<9
tag_bind mod4 set_output_tags tag_bind Mod4 set_output_tags
tag_bind mod4+shift set_window_tags tag_bind Mod4+shift set_window_tags
tag_bind mod4+ctrl toggle_output_tags tag_bind Mod4+ctrl toggle_output_tags
tag_bind mod4+ctrl+shift toggle_window_tags tag_bind Mod4+ctrl+shift toggle_window_tags
} }

View file

@ -322,6 +322,17 @@ fn loadKeybindsChildBlock(config: *Config, parser: *kdl.Parser) !void {
.zoom => { .zoom => {
break :sw .zoom; break :sw .zoom;
}, },
.change_ratio => {
const diff_str = utils.stripQuotes(node.arg(parser, 2) orelse {
logWarnMissingNodeArg(name, "diff");
continue;
});
const diff = fmt.parseFloat(f32, diff_str) catch {
logWarnInvalidNodeArg(name, diff_str);
continue;
};
break :sw .{ .change_ratio = diff };
},
.toggle_fullscreen => { .toggle_fullscreen => {
break :sw .toggle_fullscreen; break :sw .toggle_fullscreen;
}, },

View file

@ -4,8 +4,6 @@
const WindowManager = @This(); const WindowManager = @This();
const PRIMARY_RATIO: f32 = 0.55;
const MIN_RIVER_SEAT_V1_VERSION: u2 = 3; const MIN_RIVER_SEAT_V1_VERSION: u2 = 3;
context: *Context, context: *Context,
@ -18,6 +16,15 @@ windows: wl.list.Head(Window, .link),
window_count: u8 = 0, window_count: u8 = 0,
primary_ratio: f32 = 0.55,
/// State consumed in manage phase, reset at end of manage_start().
pending_manage: PendingManage = .{},
pub const PendingManage = struct {
primary_ratio: ?f32 = null,
};
pub fn create(context: *Context, window_manager_v1: *river.WindowManagerV1) !*WindowManager { pub fn create(context: *Context, window_manager_v1: *river.WindowManagerV1) !*WindowManager {
const wm = try utils.allocator.create(WindowManager); const wm = try utils.allocator.create(WindowManager);
errdefer wm.destroy(); errdefer wm.destroy();
@ -133,7 +140,7 @@ fn calculatePrimaryStackLayout(wm: *WindowManager) void {
} else { } else {
// Multiple windows: primary/stack layout // Multiple windows: primary/stack layout
// TODO: Support multiple windows in primary stack // TODO: Support multiple windows in primary stack
const primary_width: u31 = @intFromFloat(@as(f32, @floatFromInt(output_width)) * PRIMARY_RATIO); const primary_width: u31 = @intFromFloat(@as(f32, @floatFromInt(output_width)) * wm.primary_ratio);
const stack_width: u31 = output_width - primary_width; const stack_width: u31 = output_width - primary_width;
const stack_count = active_count - 1; const stack_count = active_count - 1;
const stack_height: u31 = @divFloor(output_height, stack_count); const stack_height: u31 = @divFloor(output_height, stack_count);
@ -175,6 +182,8 @@ fn calculatePrimaryStackLayout(wm: *WindowManager) void {
} }
fn manage_start(wm: *WindowManager) void { fn manage_start(wm: *WindowManager) void {
defer wm.pending_manage = .{};
const river_window_manager_v1 = wm.river_window_manager_v1; const river_window_manager_v1 = wm.river_window_manager_v1;
const context = wm.context; const context = wm.context;
if (!context.initialized) { if (!context.initialized) {
@ -211,6 +220,13 @@ fn manage_start(wm: *WindowManager) void {
} }
} }
// Manage the WM itself first
if (wm.pending_manage.primary_ratio) |primary_ratio| {
// Ratios outside of this range can cause crashes anyways (when doing the layout calulcation)
std.debug.assert(primary_ratio >= 0.10 and primary_ratio <= 0.90);
wm.primary_ratio = primary_ratio;
}
{ {
var it = wm.outputs.iterator(.forward); var it = wm.outputs.iterator(.forward);
while (it.next()) |output| { while (it.next()) |output| {

View file

@ -9,8 +9,7 @@ pub const Command = union(enum) {
focus_next, focus_next,
focus_prev, focus_prev,
zoom, zoom,
// ratio_up, // TODO change_ratio: f32,
// ratio_down, // TODO
// reload_config, // TODO // reload_config, // TODO
toggle_fullscreen, toggle_fullscreen,
close_window, close_window,
@ -128,6 +127,12 @@ const XkbBinding = struct {
}; };
current_focus.link.swapWith(&first_window.link); current_focus.link.swapWith(&first_window.link);
}, },
.change_ratio => |diff| {
const new_ratio = context.wm.primary_ratio + diff;
if (new_ratio >= 0.10 and new_ratio <= 0.90) {
context.wm.pending_manage.primary_ratio = context.wm.primary_ratio + diff;
}
},
.toggle_fullscreen => { .toggle_fullscreen => {
const seat = context.wm.seats.first() orelse return; const seat = context.wm.seats.first() orelse return;
const window = seat.focused orelse return; const window = seat.focused orelse return;

View file

@ -108,7 +108,6 @@ pub fn tokenizeToOwnedSlices(input: []const u8, delimiter: u8) ![]const []const
while (it.next()) |part| { while (it.next()) |part| {
const duped = try allocator.dupe(u8, part); const duped = try allocator.dupe(u8, part);
try list.append(utils.allocator, duped); try list.append(utils.allocator, duped);
log.debug("{s}", .{duped});
} }
return list.toOwnedSlice(utils.allocator); return list.toOwnedSlice(utils.allocator);
} }