| 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 |
}
|