summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs117
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(())
}