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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
use xcb::{
x::{
ConfigureNotifyEvent, ConfigureRequestEvent, DestroyNotifyEvent, MapRequestEvent,
UnmapNotifyEvent,
},
xinerama::{self, ScreenInfo},
Extension,
};
use crate::{error::*, WM};
#[derive(Debug, Default)]
pub struct ClientList(Vec<MonitorInfo>);
impl ClientList {
/// Set the new amount of screens, moving clients away if necessary
pub fn truncate_screens(&mut self, new_size: usize) {
// hack: double borrow stuff
let mut moved_clients = vec![];
for old in self.0.drain(new_size - self.0.len()..self.0.len()) {
moved_clients.extend(old.clients.into_iter());
}
self.0[0].clients.extend(moved_clients.into_iter());
}
pub fn set_screen_info(&mut self, i: usize, info: ScreenInfo) {
while i >= self.0.len() {
self.0.push(MonitorInfo::default())
}
self.0[i].screen_info = info;
}
pub fn len(&self) -> usize {
self.0.len()
}
}
#[derive(Debug)]
pub struct MonitorInfo {
clients: Vec<Client>,
screen_info: ScreenInfo,
}
impl Default for MonitorInfo {
fn default() -> Self {
Self {
clients: vec![],
screen_info: ScreenInfo {
x_org: 0,
y_org: 0,
width: 0,
height: 0,
},
}
}
}
#[derive(Debug)]
pub struct Client {}
impl WM<'_> {
/// Update the client list's recorded monitors and monitor sizes
pub(crate) fn update_geometry(&mut self) -> Result<()> {
if self
.conn
.active_extensions()
.any(|e| e == Extension::Xinerama)
{
let reply = self
.conn
.wait_for_reply(self.conn.send_request(&xinerama::QueryScreens {}))?;
// Monitor removed, move its clients away
if reply.screen_info().len() > self.clients.len() {
self.clients.truncate_screens(reply.screen_info().len());
}
// Update screen info & add new client lists if needed
for (i, monitor) in reply.screen_info().iter().enumerate() {
self.clients.set_screen_info(i, monitor.clone());
}
} else {
// Only one screen
if self.clients.len() > 1 {
self.clients.truncate_screens(1);
}
// TODO: it looks like this won't actually update when the screen size changes?
let setup = self.conn.get_setup();
let screen = setup
.roots()
.nth(self.screen_num as usize)
.ok_or(Error::NoSuchScreen)?;
self.clients.set_screen_info(
0,
ScreenInfo {
x_org: 0,
y_org: 0,
width: screen.width_in_pixels(),
height: screen.height_in_pixels(),
},
);
}
Ok(())
}
pub(crate) fn handle_configure_request(&mut self, e: ConfigureRequestEvent) -> Result<()> {
todo!()
}
pub(crate) fn handle_configure_notify(&mut self, e: ConfigureNotifyEvent) -> Result<()> {
todo!()
}
pub(crate) fn handle_destroy_notify(&mut self, e: DestroyNotifyEvent) -> Result<()> {
todo!()
}
pub(crate) fn handle_map_request(&mut self, e: MapRequestEvent) -> Result<()> {
todo!()
}
pub(crate) fn handle_unmap_notify(&mut self, e: UnmapNotifyEvent) -> Result<()> {
todo!()
}
}
|