Make window rules frame perfect

This moves window initialization earlier in the manage sequence.
Previously, it was on the Window's first manage() call, but this is
after the layout has already been calculated, which matters both because
of tags and whether the window starts floating or not.

Now, initialization is handled in a separate function that gets called
in Output.calculatePrimaryStackLayout() instead.
This commit is contained in:
Ben Buhse 2026-02-17 16:51:57 -06:00
commit c4da4ef30a
No known key found for this signature in database
GPG key ID: 7916ACFCD38FD0B4
3 changed files with 30 additions and 20 deletions

View file

@ -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!