oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
4,587 bytes raw
1
const std = @import("std");
2
const testing = std.testing;
3
4
const Rect = struct {
5
    x: i32,
6
    y: i32,
7
    w: i32,
8
    h: i32,
9
};
10
11
fn calculate_master_stack_layout(
12
    area: Rect,
13
    num_clients: usize,
14
    num_master: usize,
15
    master_factor: f32,
16
    gap: i32,
17
) []Rect {
18
    var rects: [16]Rect = undefined;
19
    if (num_clients == 0) return rects[0..0];
20
21
    const actual_master = @min(num_master, num_clients);
22
    const stack_count = if (num_clients > actual_master) num_clients - actual_master else 0;
23
24
    const master_width: i32 = if (stack_count > 0)
25
        @intFromFloat(@as(f32, @floatFromInt(area.w - gap)) * master_factor)
26
    else
27
        area.w;
28
29
    var i: usize = 0;
30
    while (i < actual_master) : (i += 1) {
31
        const h = @divTrunc(area.h - @as(i32, @intCast(actual_master - 1)) * gap, @as(i32, @intCast(actual_master)));
32
        rects[i] = .{
33
            .x = area.x,
34
            .y = area.y + @as(i32, @intCast(i)) * (h + gap),
35
            .w = master_width,
36
            .h = h,
37
        };
38
    }
39
40
    const stack_width = area.w - master_width - gap;
41
    var j: usize = 0;
42
    while (j < stack_count) : (j += 1) {
43
        const h = @divTrunc(area.h - @as(i32, @intCast(stack_count - 1)) * gap, @as(i32, @intCast(stack_count)));
44
        rects[actual_master + j] = .{
45
            .x = area.x + master_width + gap,
46
            .y = area.y + @as(i32, @intCast(j)) * (h + gap),
47
            .w = stack_width,
48
            .h = h,
49
        };
50
    }
51
52
    return rects[0..num_clients];
53
}
54
55
test "tiling layout: single window fills area" {
56
    const area = Rect{ .x = 0, .y = 0, .w = 800, .h = 600 };
57
    const rects = calculate_master_stack_layout(area, 1, 1, 0.55, 5);
58
59
    try testing.expectEqual(@as(usize, 1), rects.len);
60
    try testing.expectEqual(@as(i32, 0), rects[0].x);
61
    try testing.expectEqual(@as(i32, 0), rects[0].y);
62
    try testing.expectEqual(@as(i32, 800), rects[0].w);
63
    try testing.expectEqual(@as(i32, 600), rects[0].h);
64
}
65
66
test "tiling layout: two windows split horizontally" {
67
    const area = Rect{ .x = 0, .y = 0, .w = 800, .h = 600 };
68
    const rects = calculate_master_stack_layout(area, 2, 1, 0.5, 0);
69
70
    try testing.expectEqual(@as(usize, 2), rects.len);
71
    try testing.expectEqual(@as(i32, 400), rects[0].w);
72
    try testing.expectEqual(@as(i32, 400), rects[1].w);
73
}
74
75
test "tiling layout: respects master factor" {
76
    const area = Rect{ .x = 0, .y = 0, .w = 1000, .h = 600 };
77
    const rects = calculate_master_stack_layout(area, 2, 1, 0.6, 0);
78
79
    try testing.expectEqual(@as(usize, 2), rects.len);
80
    try testing.expectEqual(@as(i32, 600), rects[0].w);
81
    try testing.expectEqual(@as(i32, 400), rects[1].w);
82
}
83
84
test "tiling layout: no clients returns empty" {
85
    const area = Rect{ .x = 0, .y = 0, .w = 800, .h = 600 };
86
    const rects = calculate_master_stack_layout(area, 0, 1, 0.55, 5);
87
88
    try testing.expectEqual(@as(usize, 0), rects.len);
89
}
90
91
test "tiling layout: multiple stack windows divide height" {
92
    const area = Rect{ .x = 0, .y = 0, .w = 800, .h = 600 };
93
    const rects = calculate_master_stack_layout(area, 3, 1, 0.5, 0);
94
95
    try testing.expectEqual(@as(usize, 3), rects.len);
96
    try testing.expectEqual(@as(i32, 600), rects[0].h);
97
    try testing.expectEqual(@as(i32, 300), rects[1].h);
98
    try testing.expectEqual(@as(i32, 300), rects[2].h);
99
}
100
101
fn calculate_monocle_layout(area: Rect, num_clients: usize) []Rect {
102
    var rects: [16]Rect = undefined;
103
    if (num_clients == 0) return rects[0..0];
104
105
    var i: usize = 0;
106
    while (i < num_clients) : (i += 1) {
107
        rects[i] = area;
108
    }
109
    return rects[0..num_clients];
110
}
111
112
test "monocle layout: all windows get full area" {
113
    const area = Rect{ .x = 0, .y = 0, .w = 800, .h = 600 };
114
    const rects = calculate_monocle_layout(area, 3);
115
116
    try testing.expectEqual(@as(usize, 3), rects.len);
117
    for (rects) |rect| {
118
        try testing.expectEqual(@as(i32, 0), rect.x);
119
        try testing.expectEqual(@as(i32, 0), rect.y);
120
        try testing.expectEqual(@as(i32, 800), rect.w);
121
        try testing.expectEqual(@as(i32, 600), rect.h);
122
    }
123
}
124
125
test "monocle layout: no clients returns empty" {
126
    const area = Rect{ .x = 0, .y = 0, .w = 800, .h = 600 };
127
    const rects = calculate_monocle_layout(area, 0);
128
129
    try testing.expectEqual(@as(usize, 0), rects.len);
130
}
131
132
test "monocle layout: respects area offset" {
133
    const area = Rect{ .x = 100, .y = 50, .w = 800, .h = 600 };
134
    const rects = calculate_monocle_layout(area, 1);
135
136
    try testing.expectEqual(@as(i32, 100), rects[0].x);
137
    try testing.expectEqual(@as(i32, 50), rects[0].y);
138
}