diff --git a/docs/TODO.md b/docs/TODO.md index e9ef37c..9b87dd5 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -2,7 +2,6 @@ These are in rough order of my priority, though no promises I do them in this order. -- [ ] Support window rules (float/tags/SSD by app-id/title) - [ ] Support overriding config location - [ ] Support configuring primary vs secondary stack side - [ ] Support switch handling (e.g. lid close) @@ -31,3 +30,4 @@ These are in rough order of my priority, though no promises I do them in this or - [x] Add options to the tag overlay - [x] Add options to the bar - [x] Make a Rect struct to combine x, y, width, and height +- [x] Support window rules (float/tags by app-id/title) diff --git a/src/Output.zig b/src/Output.zig index ec65420..fdfff0a 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -617,6 +617,9 @@ fn calculatePrimaryStackLayout(output: *Output) void { var active_count: u31 = 0; var it = output.windows.iterator(.forward); while (it.next()) |window| { + // Initialize new windows before checking tags/float so that + // 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 const will_float = window.pending_manage.floating orelse window.floating; diff --git a/src/Window.zig b/src/Window.zig index 7ff9be0..5c38bfb 100644 --- a/src/Window.zig +++ b/src/Window.zig @@ -164,31 +164,38 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event, } } -pub fn manage(window: *Window) void { - const river_window_v1 = window.river_window_v1; - if (!window.initialized) { - // Only happens once per Window +/// Apply one-time initialization for newly created windows. +/// Called before calculatePrimaryStackLayout() so that tag and float +/// rules are reflected in the first frame's layout. +pub fn initialize(window: *Window) void { + if (window.initialized) { @branchHint(.unlikely); - window.initialized = true; - - // TODO: We might want to think about paying attention to the decoration_hint event - // If we do, this would need to move, I think? - river_window_v1.useSsd(); - - river_window_v1.setCapabilities(.{ .fullscreen = true, .maximize = true }); - river_window_v1.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true }); - - const res = window.applyRules(); - if (res.tags) |tags| window.tags = tags; - if (res.float) |should_float| - window.pending_manage.floating = should_float - else - window.pending_manage.floating = false; + return; } + window.initialized = true; + const river_window_v1 = window.river_window_v1; + + // TODO: We might want to think about paying attention to the decoration_hint event + // If we do, this would need to move, I think? + river_window_v1.useSsd(); + + river_window_v1.setCapabilities(.{ .fullscreen = true, .maximize = true }); + river_window_v1.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true }); + + const res = window.applyRules(); + if (res.tags) |tags| window.tags = tags; + if (res.float) |should_float| + window.pending_manage.floating = should_float + else + window.pending_manage.floating = false; +} + +pub fn manage(window: *Window) void { // Updating state since the last manage event defer window.pending_manage = .{}; const pending_manage = window.pending_manage; + const river_window_v1 = window.river_window_v1; // Floating status if (pending_manage.floating) |floating| blk: { // This needs to be before proposing the new dimensions since we want to save the current ones!