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
125
126
127
128
#[allow(unused_imports)]
pub mod imports {
pub use std::process::exit;
pub use x11rb::{
self,
connection::Connection,
errors::{ReplyError, ReplyOrIdError},
protocol::{xproto::*, ErrorKind, Event},
};
}
pub mod traits {
use std::error::Error;
pub type WmReply<T> = Result<T, Box<dyn Error>>;
pub use super::x11::traits::*;
}
pub mod errors;
pub mod window_manager;
pub mod x11;
use imports::*;
use std::cell::RefCell;
use std::rc::Rc;
use traits::*;
use window_manager::RedWm;
pub mod window;
#[doc(inline)]
pub use window::*;
pub const TITLEBAR_HEIGHT: u16 = 0;
pub const DRAG_BUTTON: Button = 1;
pub fn run<C: Connection + 'static + Send + Sync>(x_reply: (C, usize)) -> WmReply<()> {
let (conn, screen_num) = x_reply;
let screen = &conn.setup().roots[screen_num];
x11::check_access(&conn, &screen)?;
let conn = Rc::new(RefCell::new(&conn));
let mut wm = RedWm::new(conn, screen_num)?;
wm.scan()?;
run_event_loop(&mut wm)?;
Ok(())
}
#[allow(unreachable_code)]
fn run_event_loop<C: Connection + Send + Sync>(wm: &mut RedWm<C>) -> WmReply<()> {
let wm = Rc::new(RefCell::new(wm));
loop {
{
wm.borrow_mut().refresh();
}
let event;
{
let wm = wm.borrow();
let conn = wm.conn.borrow();
conn.flush()?;
event = conn.wait_for_event()?;
}
let mut event_option = Some(event);
while let Some(event) = event_option {
if let Event::ClientMessage(_) = event {
return Ok(());
}
{
wm.borrow_mut().handle_event(event)?;
}
{
let wm = wm.borrow();
let conn = wm.conn.borrow();
event_option = conn.poll_for_event()?;
}
}
}
Ok(())
}
#[macro_export]
macro_rules! define_event_request {
() => {
EventMask::SUBSTRUCTURE_REDIRECT | EventMask::SUBSTRUCTURE_REDIRECT
};
}
#[macro_export]
macro_rules! define_window_event_request {
() => {
EventMask::EXPOSURE
| EventMask::SUBSTRUCTURE_NOTIFY
| EventMask::BUTTON_PRESS
| EventMask::BUTTON_RELEASE
| EventMask::POINTER_MOTION
| EventMask::ENTER_WINDOW
};
}
#[macro_export]
macro_rules! match_event_request {
($self: tt, $event: tt) => {
match $event {
Event::UnmapNotify(event) => $self.handle_unmap_notify(event)?,
Event::ConfigureRequest(event) => $self.handle_configure_request(event)?,
Event::MapRequest(event) => $self.handle_map_request(event)?,
Event::Expose(event) => $self.handle_expose(event),
Event::EnterNotify(event) => $self.handle_enter(event)?,
Event::ButtonPress(event) => $self.handle_button_press(event),
Event::ButtonRelease(event) => $self.handle_button_release(event)?,
Event::MotionNotify(event) => $self.handle_motion_notify(event)?,
_ => {}
}
};
}