From 9d64ca01240ed1b73fa5c2c45097411623438297 Mon Sep 17 00:00:00 2001 From: Ben Buhse Date: Sun, 3 Aug 2025 20:49:06 -0500 Subject: [PATCH] Add focus to my single window --- examples/init | 1 + src/Output.zig | 19 ++++++++++++++----- src/Seat.zig | 28 ++++++++++++++++++++++++++-- src/Window.zig | 39 ++++++++++++++++++++++++++++++++++----- src/WindowManager.zig | 21 +++++++++++++++++---- 5 files changed, 92 insertions(+), 16 deletions(-) diff --git a/examples/init b/examples/init index ebb98bc..2d1da04 100755 --- a/examples/init +++ b/examples/init @@ -5,4 +5,5 @@ echo ">>>>> before foot" /usr/bin/foot & +# /usr/bin/foot & echo "<<<<< after foot" diff --git a/src/Output.zig b/src/Output.zig index b543c92..5b3e570 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -28,8 +28,12 @@ pub fn init(output: *Output, context: *Context, river_output_v1: *river.OutputV1 fn outputListener(river_output_v1: *river.OutputV1, event: river.OutputV1.Event, output: *Output) void { assert(output.output_v1 == river_output_v1); switch (event) { - .wl_output => |ev| { - log.debug("initializing new river_ouput_v1 corresponding to wl_output: {d}", .{ev.name}); + .removed => { + river_output_v1.destroy(); + output.context.allocator.destroy(output); + }, + .wl_output => { + // log.debug("initializing new river_output_v1 corresponding to wl_output: {d}", .{ev.name}); }, .dimensions => |ev| { output.width = ev.width; @@ -39,12 +43,17 @@ fn outputListener(river_output_v1: *river.OutputV1, event: river.OutputV1.Event, output.x = ev.x; output.y = ev.y; }, - else => |ev| { - log.debug("unhandled event: {s}", .{@tagName(ev)}); - }, } } +pub fn manage(output: *Output) void { + _ = output; +} + +pub fn render(output: *Output) void { + _ = output; +} + const std = @import("std"); const assert = std.debug.assert; diff --git a/src/Seat.zig b/src/Seat.zig index b834148..b22faaa 100644 --- a/src/Seat.zig +++ b/src/Seat.zig @@ -8,12 +8,15 @@ context: *Context, seat_v1: *river.SeatV1, +hovered: ?*Window, + link: wl.list.Link, pub fn init(seat: *Seat, context: *Context, river_seat_v1: *river.SeatV1) void { seat.* = .{ .context = context, .seat_v1 = river_seat_v1, + .hovered = null, .link = undefined, // Handled by the wl.list }; @@ -23,8 +26,17 @@ pub fn init(seat: *Seat, context: *Context, river_seat_v1: *river.SeatV1) void { fn seatListener(river_seat_v1: *river.SeatV1, event: river.SeatV1.Event, seat: *Seat) void { assert(seat.seat_v1 == river_seat_v1); switch (event) { - .wl_seat => |ev| { - log.debug("initializing new river_ouput_v1 corresponding to wl_seat: {d}", .{ev.name}); + .removed => { + river_seat_v1.destroy(); + seat.context.allocator.destroy(seat); + }, + .wl_seat => { + // log.debug("initializing new river_seat_v1 corresponding to wl_seat: {d}", .{ev.name}); + }, + .pointer_enter => |ev| { + const window_v1 = ev.window orelse return; + const window: *Window = @ptrCast(@alignCast(window_v1.getUserData())); + seat.hovered = window; }, else => |ev| { log.debug("unhandled event: {s}", .{@tagName(ev)}); @@ -32,6 +44,17 @@ fn seatListener(river_seat_v1: *river.SeatV1, event: river.SeatV1.Event, seat: * } } +pub fn manage(seat: *Seat) void { + if (seat.hovered) |window| { + seat.seat_v1.focusWindow(window.window_v1); + seat.hovered = null; + } +} + +pub fn render(seat: *Seat) void { + _ = seat; +} + const std = @import("std"); const assert = std.debug.assert; @@ -40,5 +63,6 @@ const wl = wayland.client.wl; const river = wayland.client.river; const Context = @import("main.zig").Context; +const Window = @import("Window.zig"); const log = std.log.scoped(.Seat); diff --git a/src/Window.zig b/src/Window.zig index 20eeb47..fced985 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -8,11 +8,16 @@ context: *Context, window_v1: *river.WindowV1, -width: i32 = 0, -height: i32 = 0, +width: u31 = 0, +height: u31 = 0, x: i32 = 0, y: i32 = 0, +new_width: u31 = 0, +new_height: u31 = 0, +new_x: i32 = 0, +new_y: i32 = 0, + link: wl.list.Link, pub fn init(window: *Window, context: *Context, river_window_v1: *river.WindowV1) void { @@ -28,6 +33,19 @@ pub fn init(window: *Window, context: *Context, river_window_v1: *river.WindowV1 fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event, window: *Window) void { assert(window.window_v1 == river_window_v1); switch (event) { + .closed => { + river_window_v1.destroy(); + window.context.allocator.destroy(window); + }, + .dimensions => |ev| { + // Part of the protocol requires these are strictly greater-than zero + assert(ev.width > 0 and ev.height > 0); + window.width = @intCast(ev.width); + window.height = @intCast(ev.height); + }, + .dimensions_hint => { + // TODO: Maybe could use this for floating windows + }, else => |ev| { log.debug("unhandled event: {s}", .{@tagName(ev)}); }, @@ -35,18 +53,29 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event, } pub fn manage(window: *Window) void { + if (window.context.wm.outputs.length() == 0) { + window.new_width = 0; + window.new_height = 0; + window.new_x = 0; + window.new_y = 0; + } + + // TODO: Remove this -- just fullscreen for now if (window.width != window.context.wm.outputs.first().?.width or window.height != window.context.wm.outputs.first().?.height) { - window.width = window.context.wm.outputs.first().?.width; - window.height = window.context.wm.outputs.first().?.height; + window.width = @intCast(window.context.wm.outputs.first().?.width); + window.height = @intCast(window.context.wm.outputs.first().?.height); log.debug("setting window width={d} and height={d}", .{ window.width, window.height }); } window.window_v1.proposeDimensions(window.width, window.height); + // window.window_v1.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true }); + window.window_v1.informFullscreen(); + // window.window_v1.informMaximized(); } pub fn render(window: *Window) void { - _ = window; + _ = window; // TODO ??? } const std = @import("std"); diff --git a/src/WindowManager.zig b/src/WindowManager.zig index 51994f5..759d5c4 100644 --- a/src/WindowManager.zig +++ b/src/WindowManager.zig @@ -38,10 +38,23 @@ fn windowManagerV1Listener(window_manager_v1: *river.WindowManagerV1, event: riv std.posix.exit(1); }, .manage_start => { - log.debug("1", .{}); - var it = wm.windows.iterator(.forward); - while (it.next()) |window| { - window.manage(); + { + var it = wm.seats.iterator(.forward); + while (it.next()) |seat| { + seat.manage(); + } + } + { + var it = wm.outputs.iterator(.forward); + while (it.next()) |output| { + output.manage(); + } + } + { + var it = wm.windows.iterator(.forward); + while (it.next()) |window| { + window.manage(); + } } window_manager_v1.manageFinish(); },