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
|
// See LICENSE file for copyright and license details.
// needed for clippy.
#![allow(unknown_lints)]
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
extern crate libc;
extern crate x11;
extern crate unix_socket;
#[macro_use]
extern crate lazy_static;
pub mod safe_x11;
pub mod command;
pub mod dotwm;
pub mod event;
pub mod socket;
pub mod desktop;
use dotwm::DotWM;
use command::*;
use event::{Event,select_event};
use socket::parser;
use std::collections::HashMap;
use std::mem::uninitialized;
use x11::xlib;
use x11::keysym;
use std::fs;
use std::io::{Read,Write};
use unix_socket::UnixListener;
const SOCKET_PATH: &'static str = "./dotwm.sock";
fn run_autostart() {
let paths = &["./autostart", "/home/matias/.config/dotwm/autostart"];
for path in paths {
if exec_cmd(path, &[]).is_ok() {
break;
}
}
}
fn main() {
println!("Creating dotwm");
let mut dotwm = DotWM::new();
let mut bindings: BindingHash = HashMap::new();
let x11_fd = safe_x11::x11_fd(dotwm.display);
add_binding(&mut dotwm, &mut bindings, keysym::XK_q, xlib::Mod4Mask | xlib::ShiftMask, quit_dotwm, &[]);
let listener = UnixListener::bind(SOCKET_PATH).unwrap();
run_autostart();
// Main loop
while !dotwm.finish {
let event = unsafe { select_event(dotwm.display, x11_fd, &listener) };
//println!("Event: {:?}", event);
match event {
Event::Key(mut e, true) => {
let keysym = unsafe { xlib::XLookupKeysym(&mut e, 0) as u32 };
let mask = e.state;
exec_func(&mut dotwm, &mut bindings, keysym, mask, xlib::XEvent::from(e));
},
Event::Map(e) => {
// If the window has override_redirect setted to true, this should not
// be handled by the wm.
let map_event = xlib::XMapEvent::from(e);
if map_event.override_redirect == 0 {
dotwm.add_window(map_event.window);
}
}
Event::Unmap(e) => {
dotwm.remove_window(e.window);
},
Event::Enter(e) => {
if let Some(idx) = dotwm.window_idx(e.window) {
dotwm.change_focus_of(idx);
}
},
Event::Expose(_) => {
},
Event::Drag(e) => {
// We can "compress" the drag notify here.
unsafe{
let mut new_ev = uninitialized();
while xlib::XCheckTypedEvent(dotwm.display, xlib::MotionNotify, &mut new_ev) != 0 {};
};
exec_func(&mut dotwm, &mut bindings, 1, e.state, xlib::XEvent::from(e));
},
Event::Socket(stream) => {
let mut s = stream.try_clone().unwrap();
let mut buf = String::new();
s.read_to_string(&mut buf).unwrap();
for line in buf.lines() {
let res = parser::parse(line);
match res {
Ok(pcmd) => {
pcmd.handle(&mut dotwm, &mut bindings);
let _ = write!(s, "+ok");
},
Err(e) => {
let _ = write!(s, "-{}", e);
},
}
}
},
_ => (),
}
collect_zombies();
}
let _ = fs::remove_file(SOCKET_PATH);
}
|