add multimonitor

This commit is contained in:
2026-08-18 21:30:51 +02:00
parent 7d117f4ae5
commit f60dd06e7e
10 changed files with 470 additions and 34 deletions
+40
View File
@@ -32,6 +32,46 @@ pub fn tagSlot(tags: u32) usize {
return @ctz(t) + 1;
}
/// The tags belonging to output `index` of `count`, when the tag set is split
/// across the displays.
///
/// The tags are divided into contiguous ranges in the order the outputs are
/// arranged on the desk, so with two monitors the left one owns 15 and the
/// right 69. Contiguous rather than interleaved because the keys are what the
/// user reaches for: 15 under the left hand for the left screen reads as one
/// screen's worth of workspaces, 1,3,5,7,9 does not.
///
/// A lone output owns every tag, which is what makes the split invisible on a
/// laptop with nothing plugged in.
pub fn tagsForOutput(index: usize, count: usize) u32 {
if (count <= 1 or index >= count) return all_tags;
// More outputs than tags: one each, and the outputs left over share the
// last tag rather than getting none. An output owning no tag could show no
// window at all, which is worse than two screens showing the same one.
if (count >= tag_count) {
return @as(u32, 1) << @intCast(@min(index, tag_count - 1));
}
// Earlier outputs take one of the leftover tags each, so the ranges differ
// by at most one and it is never the first screen that comes up short.
const base = tag_count / count;
const rem = tag_count % count;
const start = index * base + @min(index, rem);
const len = base + @as(usize, @intFromBool(index < rem));
const ones: u32 = (@as(u32, 1) << @intCast(len)) - 1;
return ones << @intCast(start);
}
/// The lowest tag in a mask, as a mask of its own. What a view falls back to
/// when the tags it was showing have moved to another screen.
pub fn lowestTag(tags: u32) u32 {
const t = tags & all_tags;
if (t == 0) return 0;
return @as(u32, 1) << @intCast(@ctz(t));
}
/// Keyboard modifiers, matching the values of river_seat_v1.modifiers so the
/// mask can be bit-cast straight into the protocol type.
pub const Mods = struct {