aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 8bf3caa129508c55532e329248c64471536ad2dc (plain)
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
// See LICENSE file for copyright and license details.

extern crate libc;
extern crate x11;
extern crate unix_socket;

pub mod safe_x11;
pub mod command;
pub mod dotwm;
pub mod event;
pub mod socket;

use dotwm::DotWM;
use command::*;
use event::{Event,next_event};
use socket::{configure_wm, listen_socket};
use safe_x11::event as x11_event;

use std::collections::HashMap;

use x11::xlib;
use x11::xlib::XEvent;
use x11::keysym;

use std::thread;
use std::sync::mpsc::channel;
use unix_socket::UnixListener;

fn main() {
    println!("Creating dotwm");
    let mut dotwm = DotWM::new();
    let mut bindings: BindingHash = HashMap::new();
    let x11_fd = x11_event::x11_fd(dotwm.display);

    add_binding(&mut dotwm,&mut  bindings, keysym::XK_Return, xlib::Mod4Mask, exec,
                &["xterm"]);
    add_binding(&mut dotwm,&mut  bindings, keysym::XK_p, xlib::Mod4Mask, exec,
                &["dmenu_run"]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_Tab, xlib::Mod4Mask, focus_next, &[]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_h, xlib::Mod4Mask, move_win, &["-10", "0"]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_j, xlib::Mod4Mask, move_win, &["0", "10"]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_k, xlib::Mod4Mask, move_win, &["0", "-10"]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_l, xlib::Mod4Mask, move_win, &["10", "0"]);

    // Resize
    add_binding(&mut dotwm,&mut bindings, keysym::XK_h, xlib::Mod4Mask | xlib::ControlMask,
                resize_win, &["-10", "0"]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_j, xlib::Mod4Mask | xlib::ControlMask,
                resize_win, &["0", "10"]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_k, xlib::Mod4Mask | xlib::ControlMask,
                resize_win, &["0", "-10"]);
    add_binding(&mut dotwm,&mut bindings, keysym::XK_l, xlib::Mod4Mask | xlib::ControlMask,
                resize_win, &["10", "0"]);

    add_binding(&mut dotwm, &mut bindings, keysym::XK_q, xlib::Mod4Mask | xlib::ShiftMask, quit_dotwm, &[]);

    let (transmission, receiver) = channel();

    thread::spawn(move || {
        println!("Creating socket");
        let listener = UnixListener::bind("./dotwm.sock").unwrap();

        for stream in listener.incoming() {
            match stream {
                Ok(stream) => transmission.send(stream).unwrap() ,
                Err(e) => println!("{}", e),
            }
        }
    });
    configure_wm(&mut dotwm, &receiver);

    // Main loop
    loop {
        println!("Listening socket");
        listen_socket(&mut dotwm, &receiver);
        // Event handling.
        println!("Waiting event");
        let event = next_event(dotwm.display, x11_fd);
        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 {
                    println!("Adding window");
                    dotwm.add_window(map_event.window);
                } else {
                    println!("Map event 0 :(");
                }
            }
            Event::Unmap(e) => {
                dotwm.remove_window(e.window);
            },
            Event::Enter(e) => {
                if let Some(idx) = dotwm.find_window(e.window) {
                    dotwm.change_focus_of(idx);
                }
            },
            _ => println!("Unknown event"),
        }
        collect_zombies();
    }
}