oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
2,853 bytes raw
1
use super::{GapConfig, Layout, WindowGeometry};
2
use x11rb::protocol::xproto::Window;
3
4
pub struct ScrollingLayout;
5
6
struct GapValues {
7
    outer_horizontal: u32,
8
    outer_vertical: u32,
9
    inner_vertical: u32,
10
}
11
12
impl ScrollingLayout {
13
    fn getgaps(gaps: &GapConfig, window_count: usize, smartgaps_enabled: bool) -> GapValues {
14
        let outer_enabled = if smartgaps_enabled && window_count == 1 {
15
            0
16
        } else {
17
            1
18
        };
19
20
        GapValues {
21
            outer_horizontal: gaps.outer_horizontal * outer_enabled,
22
            outer_vertical: gaps.outer_vertical * outer_enabled,
23
            inner_vertical: gaps.inner_vertical,
24
        }
25
    }
26
}
27
28
impl Layout for ScrollingLayout {
29
    fn name(&self) -> &'static str {
30
        "scrolling"
31
    }
32
33
    fn symbol(&self) -> &'static str {
34
        "[>>]"
35
    }
36
37
    fn arrange(
38
        &self,
39
        windows: &[Window],
40
        screen_width: u32,
41
        screen_height: u32,
42
        gaps: &GapConfig,
43
        _master_factor: f32,
44
        num_master: i32,
45
        smartgaps_enabled: bool,
46
    ) -> Vec<WindowGeometry> {
47
        let window_count = windows.len();
48
        if window_count == 0 {
49
            return Vec::new();
50
        }
51
52
        let gap_values = Self::getgaps(gaps, window_count, smartgaps_enabled);
53
54
        let outer_horizontal = gap_values.outer_horizontal;
55
        let outer_vertical = gap_values.outer_vertical;
56
        let inner_vertical = gap_values.inner_vertical;
57
58
        let visible_count = if num_master > 0 {
59
            num_master as usize
60
        } else {
61
            2
62
        };
63
64
        let available_width = screen_width.saturating_sub(2 * outer_vertical);
65
        let available_height = screen_height.saturating_sub(2 * outer_horizontal);
66
67
        let total_inner_gaps = if visible_count > 1 {
68
            inner_vertical * (visible_count.min(window_count) - 1) as u32
69
        } else {
70
            0
71
        };
72
        let window_width = if window_count <= visible_count {
73
            let num_windows = window_count as u32;
74
            let total_gaps = if num_windows > 1 {
75
                inner_vertical * (num_windows - 1)
76
            } else {
77
                0
78
            };
79
            (available_width.saturating_sub(total_gaps)) / num_windows
80
        } else {
81
            (available_width.saturating_sub(total_inner_gaps)) / visible_count as u32
82
        };
83
84
        let mut geometries = Vec::with_capacity(window_count);
85
        let mut x = outer_vertical as i32;
86
87
        for _window in windows.iter() {
88
            geometries.push(WindowGeometry {
89
                x_coordinate: x,
90
                y_coordinate: outer_horizontal as i32,
91
                width: window_width,
92
                height: available_height,
93
            });
94
95
            x += window_width as i32 + inner_vertical as i32;
96
        }
97
98
        geometries
99
    }
100
}