From 7045b215348fbde0072eda18abd07652113a0962 Mon Sep 17 00:00:00 2001 From: Ben Buhse Date: Thu, 19 Feb 2026 13:56:37 -0600 Subject: [PATCH] Handle {exit_}fullscreen_requested events on Windows --- docs/TODO.md | 1 + src/Context.zig | 2 +- src/Output.zig | 5 +++-- src/Window.zig | 18 ++++++++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/TODO.md b/docs/TODO.md index d2c1e77..a7f0aea 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -2,6 +2,7 @@ These are in rough order of my priority, though no promises I do them in this order. +- [ ] Use set_xcursor_theme request - [ ] Add focused window title to bar - [ ] Support overriding config location - [ ] Support configuring primary vs secondary stack side diff --git a/src/Context.zig b/src/Context.zig index 30d0802..1d867ec 100644 --- a/src/Context.zig +++ b/src/Context.zig @@ -54,7 +54,7 @@ pub const Options = struct { river_input_manager_v1: *river.InputManagerV1, river_libinput_config_v1: *river.LibinputConfigV1, - river_layer_shell_v1: *river.LayerShellV1, // TODO + river_layer_shell_v1: *river.LayerShellV1, river_window_manager_v1: *river.WindowManagerV1, river_xkb_bindings_v1: *river.XkbBindingsV1, diff --git a/src/Output.zig b/src/Output.zig index c07e682..7e7d0ea 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -626,9 +626,10 @@ fn calculateLayout(output: *Output) void { // window rules are reflected in the first frame's layout. window.initialize(); if (output.tags & window.tags != 0x0000) { - // Floating windows should be shown but not included in this layout generation + // Fullscreen and floating windows should be shown but not included in layout generation + const will_be_fullscreen = window.pending_manage.fullscreen orelse window.fullscreen; const will_float = window.pending_manage.floating orelse window.floating; - if (!will_float) { + if (!will_be_fullscreen and !will_float) { active_count += 1; active_list.append(&window.active_list_node); } diff --git a/src/Window.zig b/src/Window.zig index a21004e..75209e8 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -193,6 +193,7 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event, null; }, .parent => |ev| { + // Nothing to do if ev.parent is null const parent = ev.parent orelse return; window.parent = parent; @@ -204,6 +205,23 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event, .y = parent_window.rect.y + @divTrunc(parent_window.rect.height, 2), }; }, + .fullscreen_requested => |ev| { + window.pending_manage.fullscreen = true; + + // This event allows the window to provide an output preference, + // so we should move the window if it wants + if (ev.output) |river_output_v1| { + if (river_output_v1.getUserData()) |user_data| { + const output: *Output = @ptrCast(@alignCast(user_data)); + // We have to remove window from current output's windows list first + window.link.remove(); + output.windows.append(window); + + window.pending_manage.pending_output = .{ .output = output }; + } + } + }, + .exit_fullscreen_requested => window.pending_manage.fullscreen = false, else => |ev| { log.debug("unhandled event: {s}", .{@tagName(ev)}); },