Start adding tags

Right now, essentially nothing has changed, there is still no multi-
output support and not even a way to change/set/toggle/view/etc. tags.

However, tags *are* implemented at a core level. Next step is to add
keybinds for the various tag actions.

After that, I will work on multi-output support.
This commit is contained in:
Ben Buhse 2026-01-26 15:04:41 -06:00
commit b8d31de3ef
No known key found for this signature in database
GPG key ID: 7916ACFCD38FD0B4
6 changed files with 160 additions and 106 deletions

View file

@ -28,6 +28,10 @@ pending_manage: PendingManage = .{},
/// State consumed in render() phase, reset at end of render().
pending_render: PendingRender = .{},
/// Used to put Windows into a list in
/// WindowManager.calculatePriamryStackLayout()
active_list_node: DoublyLinkedList.Node = .{},
link: wl.list.Link,
pub const PendingManage = struct {
@ -36,6 +40,8 @@ pub const PendingManage = struct {
fullscreen: ?bool = null,
maximized: ?bool = null,
tags: ?u32 = null,
};
pub const PendingRender = struct {
@ -45,7 +51,7 @@ pub const PendingRender = struct {
focused: ?bool = null,
};
pub fn create(context: *Context, river_window_v1: *river.WindowV1, output: ?*Output) !*Window {
pub fn create(context: *Context, river_window_v1: *river.WindowV1, output: *Output) !*Window {
var window = try utils.allocator.create(Window);
errdefer window.destroy();
@ -53,15 +59,10 @@ pub fn create(context: *Context, river_window_v1: *river.WindowV1, output: ?*Out
.context = context,
.river_window_v1 = river_window_v1,
.river_node_v1 = river_window_v1.getNode() catch @panic("Failed to get node"),
.output = output,
.tags = if (output.tags != 0) output.tags else 0x0001,
.link = undefined, // Handled by the wl.list
};
if (output) |out| {
window.tags = if (out.tags != 0) out.tags else 0x0001;
} else {
window.tags = 0x0001;
}
window.river_window_v1.setListener(*Window, windowListener, window);
@ -119,6 +120,7 @@ fn windowListener(river_window_v1: *river.WindowV1, event: river.WindowV1.Event,
pub fn manage(window: *Window) void {
if (!window.initialized) {
// Only happens once per Window
@branchHint(.unlikely);
window.initialized = true;
@ -130,7 +132,7 @@ pub fn manage(window: *Window) void {
window.river_window_v1.setTiled(.{ .top = true, .bottom = true, .left = true, .right = true });
}
// Any new state since the last manage event
// Updating state since the last manage event
defer window.pending_manage = .{};
const pending_manage = window.pending_manage;
// Layout (pre-computed by WindowManager.calculatePrimaryStackLayout())
@ -141,7 +143,6 @@ pub fn manage(window: *Window) void {
window.river_window_v1.proposeDimensions(new_width, new_height);
}
}
// Fullscreen and maximize operations
if (pending_manage.fullscreen) |fullscreen| {
window.fullscreen = fullscreen;
@ -162,6 +163,10 @@ pub fn manage(window: *Window) void {
window.river_window_v1.informUnmaximized();
}
}
// New tags
if (pending_manage.tags) |tags| {
window.tags = tags;
}
}
pub fn render(window: *Window) void {
@ -202,6 +207,7 @@ fn applyBorders(window: *Window, color: utils.RiverColor) void {
const std = @import("std");
const assert = std.debug.assert;
const DoublyLinkedList = std.DoublyLinkedList;
const wayland = @import("wayland");
const wl = wayland.client.wl;