1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use miette::Result;
pub async fn arrange_windows(_client_count: u8) -> Result<()> {
#[cfg(windows)]
{
use windows_sys::Win32::Foundation::{BOOL, HWND, LPARAM};
use windows_sys::Win32::UI::WindowsAndMessaging::{
EnumWindows, GetSystemMetrics, GetWindowTextW, MoveWindow, SM_CXMAXIMIZED,
SM_CYMAXIMIZED,
};
tokio::time::sleep(std::time::Duration::from_secs(_client_count as u64)).await;
static mut HWNDS: Vec<HWND> = Vec::new();
extern "system" fn enum_window(window: HWND, _: LPARAM) -> BOOL {
unsafe {
let mut text: [u16; 512] = [0; 512];
let len = GetWindowTextW(window, text.as_mut_ptr(), text.len().try_into().unwrap());
let text = String::from_utf16_lossy(&text[..len as usize]);
if !text.is_empty() && text.contains("Factorio ") && !text.contains("Factorio Bot")
{
HWNDS.push(window);
}
1
}
}
unsafe {
EnumWindows(Some(enum_window), 0_isize);
let max_width = GetSystemMetrics(SM_CXMAXIMIZED);
let max_height = GetSystemMetrics(SM_CYMAXIMIZED);
let count = HWNDS.len();
for (index, window) in HWNDS.iter().enumerate() {
let (x, y, w, h) = window_size(max_width, max_height, count, index);
MoveWindow(*window, x, y, w, h, 1);
}
HWNDS.clear();
}
}
Ok(())
}
pub fn window_size(
width_full: i32,
height_full: i32,
client_count: usize,
client_index: usize,
) -> (i32, i32, i32, i32) {
let cols = 2;
let col_index = (client_index % 2) as i32;
let rows = (client_count as f64 / 2.0).ceil() as i32;
let row_index = (client_index / 2) as i32;
let col_width = width_full / cols;
let row_height = height_full / rows;
(
col_width * col_index,
row_height * row_index,
if client_count % 2 == 1 && client_index == client_count - 1 {
width_full
} else {
col_width
},
row_height,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_window_size_1() {
assert_eq!(window_size(800, 600, 1, 0), (0, 0, 800, 600));
}
#[test]
fn test_window_size_2() {
assert_eq!(window_size(800, 600, 2, 0), (0, 0, 400, 600));
assert_eq!(window_size(800, 600, 2, 1), (400, 0, 400, 600));
}
#[test]
fn test_window_size_3() {
assert_eq!(window_size(800, 600, 3, 0), (0, 0, 400, 300));
assert_eq!(window_size(800, 600, 3, 1), (400, 0, 400, 300));
assert_eq!(window_size(800, 600, 3, 2), (0, 300, 800, 300));
}
#[test]
fn test_window_size_4() {
assert_eq!(window_size(800, 600, 4, 0), (0, 0, 400, 300));
assert_eq!(window_size(800, 600, 4, 1), (400, 0, 400, 300));
assert_eq!(window_size(800, 600, 4, 2), (0, 300, 400, 300));
assert_eq!(window_size(800, 600, 4, 3), (400, 300, 400, 300));
}
}