diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 117 |
1 files changed, 93 insertions, 24 deletions
diff --git a/src/main.rs b/src/main.rs index 6ac9dce..25b4bb9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,16 @@ //! A lightweight X11 window manager, inspired by dwm. -use atoms::InternedAtoms; +use atoms::Atoms; use clients::ClientState; use colours::Colours; use cursors::Cursors; use error::*; use keys::KeyboardInfo; use xcb::{ - x::{self, ChangeWindowAttributes, PropertyNotifyEvent, Window}, + x::{ + self, ChangeProperty, ChangeWindowAttributes, CreateWindow, DeleteProperty, + PropertyNotifyEvent, Window, WindowClass, + }, Connection, Event, Extension, }; @@ -44,6 +47,10 @@ struct WM<'a> { /// The root window root: Window, + /// A window used to prove we're actually EWMH compliant. + /// See [the EWMH spec](https://specifications.freedesktop.org/wm-spec/wm-spec-1.3.html#idm46187912047344) + check_window: Window, + /// WM client state clients: ClientState, @@ -54,7 +61,7 @@ struct WM<'a> { cursors: Cursors, /// Cached atoms - atoms: InternedAtoms, + atoms: Atoms, /// Cached keyboard layout information keyboard_state: KeyboardInfo, @@ -83,10 +90,11 @@ impl WM<'_> { Ok(WM { colours: Colours::new_with(conn, screen.default_colormap())?, - atoms: InternedAtoms::new_with(conn)?, + atoms: Atoms::intern_all(conn)?, cursors: Cursors::new_with(conn)?, keyboard_state: KeyboardInfo::new_with(conn)?, clients: Default::default(), + check_window: conn.generate_id(), conn, screen_num, root: screen.root(), @@ -95,29 +103,90 @@ impl WM<'_> { /// Set the correct properties on the root window fn setup_root(&mut self) -> Result<()> { - // TODO: Set EHWM properties on root window - - self.conn - .check_request(self.conn.send_request_checked(&ChangeWindowAttributes { - window: self.root, - value_list: &[ - x::Cw::EventMask( - x::EventMask::SUBSTRUCTURE_REDIRECT - | x::EventMask::SUBSTRUCTURE_NOTIFY - | x::EventMask::BUTTON_PRESS - | x::EventMask::ENTER_WINDOW - | x::EventMask::FOCUS_CHANGE - | x::EventMask::STRUCTURE_NOTIFY - | x::EventMask::PROPERTY_CHANGE, - ), - x::Cw::Cursor(self.cursors.normal()), - ], - }))?; + // Check window + self.conn.send_request(&CreateWindow { + wid: self.check_window, + parent: self.root, + depth: 0, + x: 0, + y: 0, + width: 0, + height: 0, + border_width: 0, + class: WindowClass::InputOutput, + visual: 0, + value_list: &[], + }); + + self.conn.send_request(&ChangeProperty { + mode: x::PropMode::Replace, + window: self.root, + property: self.atoms.net_wm_check, + r#type: x::ATOM_WINDOW, + data: &[self.check_window], + }); + + self.conn.send_request(&ChangeProperty { + mode: x::PropMode::Replace, + window: self.check_window, + property: self.atoms.net_wm_check, + r#type: x::ATOM_WINDOW, + data: &[self.check_window], + }); + + self.conn.send_request(&ChangeProperty { + mode: x::PropMode::Replace, + window: self.check_window, + property: self.atoms.net_wm_name, + r#type: x::ATOM_STRING, + data: b"blow", + }); + + // Supported flag + self.conn.send_request(&ChangeProperty { + mode: x::PropMode::Replace, + window: self.root, + property: self.atoms.net_supported, + r#type: x::ATOM_ATOM, + data: &[ + self.atoms.net_active_window, + self.atoms.net_wm_name, + self.atoms.net_wm_state, + self.atoms.net_wm_check, + self.atoms.net_wm_fullscreen, + self.atoms.net_wm_window_type, + self.atoms.net_wm_window_type_dialog, + self.atoms.net_client_list, + ], + }); + + // Cleanup state + self.conn.send_request(&DeleteProperty { + window: self.root, + property: self.atoms.net_client_list, + }); + + // Get the right events + self.conn.send_request(&ChangeWindowAttributes { + window: self.root, + value_list: &[ + x::Cw::EventMask( + x::EventMask::SUBSTRUCTURE_REDIRECT + | x::EventMask::SUBSTRUCTURE_NOTIFY + | x::EventMask::BUTTON_PRESS + | x::EventMask::ENTER_WINDOW + | x::EventMask::FOCUS_CHANGE + | x::EventMask::STRUCTURE_NOTIFY + | x::EventMask::PROPERTY_CHANGE, + ), + x::Cw::Cursor(self.cursors.normal()), + ], + }); self.grab_keys()?; - // TODO: reset focus - self.unfocus(); + self.refocus(usize::MAX, usize::MAX); + self.conn.flush()?; Ok(()) } |