oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
3,190 bytes raw
1
use super::{GapConfig, Layout, WindowGeometry};
2
use x11rb::protocol::xproto::Window;
3
4
pub struct GridLayout;
5
6
impl Layout for GridLayout {
7
    fn name(&self) -> &'static str {
8
        super::LayoutType::Grid.as_str()
9
    }
10
11
    fn symbol(&self) -> &'static str {
12
        "[#]"
13
    }
14
15
    fn arrange(
16
        &self,
17
        windows: &[Window],
18
        screen_width: u32,
19
        screen_height: u32,
20
        gaps: &GapConfig,
21
        _master_factor: f32,
22
        _num_master: i32,
23
        _smartgaps_enabled: bool,
24
    ) -> Vec<WindowGeometry> {
25
        let window_count = windows.len();
26
        if window_count == 0 {
27
            return Vec::new();
28
        }
29
30
        if window_count == 1 {
31
            let x = gaps.outer_horizontal as i32;
32
            let y = gaps.outer_vertical as i32;
33
            let width = screen_width.saturating_sub(2 * gaps.outer_horizontal);
34
            let height = screen_height.saturating_sub(2 * gaps.outer_vertical);
35
36
            return vec![WindowGeometry {
37
                x_coordinate: x,
38
                y_coordinate: y,
39
                width,
40
                height,
41
            }];
42
        }
43
44
        let cols = (window_count as f64).sqrt().ceil() as usize;
45
        let rows = (window_count as f64 / cols as f64).ceil() as usize;
46
47
        let mut geometries = Vec::new();
48
49
        let total_horizontal_gaps =
50
            gaps.outer_horizontal * 2 + gaps.inner_horizontal * (cols as u32 - 1);
51
        let total_vertical_gaps = gaps.outer_vertical * 2 + gaps.inner_vertical * (rows as u32 - 1);
52
53
        let cell_width = screen_width.saturating_sub(total_horizontal_gaps) / cols as u32;
54
        let cell_height = screen_height.saturating_sub(total_vertical_gaps) / rows as u32;
55
56
        for (index, _window) in windows.iter().enumerate() {
57
            let row = index / cols;
58
            let col = index % cols;
59
60
            let is_last_row = row == rows - 1;
61
            let windows_in_last_row = window_count - (rows - 1) * cols;
62
63
            let (x, y, width, height) = if is_last_row && windows_in_last_row < cols {
64
                let last_row_col = index % cols;
65
                let last_row_cell_width =
66
                    screen_width.saturating_sub(total_horizontal_gaps.saturating_sub(
67
                        gaps.inner_horizontal * (cols as u32 - windows_in_last_row as u32),
68
                    )) / windows_in_last_row as u32;
69
70
                let x = gaps.outer_horizontal
71
                    + last_row_col as u32 * (last_row_cell_width + gaps.inner_horizontal);
72
                let y = gaps.outer_vertical + row as u32 * (cell_height + gaps.inner_vertical);
73
74
                (x as i32, y as i32, last_row_cell_width, cell_height)
75
            } else {
76
                let x = gaps.outer_horizontal + col as u32 * (cell_width + gaps.inner_horizontal);
77
                let y = gaps.outer_vertical + row as u32 * (cell_height + gaps.inner_vertical);
78
79
                (x as i32, y as i32, cell_width, cell_height)
80
            };
81
82
            geometries.push(WindowGeometry {
83
                x_coordinate: x,
84
                y_coordinate: y,
85
                width,
86
                height,
87
            });
88
        }
89
90
        geometries
91
    }
92
}