diff options
author | tcmal <me@aria.rip> | 2024-06-21 22:13:45 +0100 |
---|---|---|
committer | tcmal <me@aria.rip> | 2024-06-21 22:13:45 +0100 |
commit | 210ea31e39370336464fec76368aa77bf0411681 (patch) | |
tree | 68288fd85ed0e3da6d4bab8b1b52465ce39ea6f4 /src/main.rs | |
parent | 1c893ed1ff1dc26f4dcc425e756d56f752142ebd (diff) |
documentation cleanup
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/src/main.rs b/src/main.rs index 54d893c..64e9203 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,20 @@ //! A lightweight X11 window manager, inspired by dwm. +//! +//! # Structure +//! +//! The main thing a WM has to do is respond to events: this is done in the [`WM::event_loop`] function, which dispatches to the `handle_*` methods of that struct. +//! +//! [`conn_info`] wraps XCB's [`xcb::Connection`] type and caches common resources such as atoms, colours, cursors, and keyboard layout info. +//! +//! `focus.rs`, [`keys`], and [`clients`] all add some event handlers to [`WM`], but most of the important code is in [`clients`]. +//! +//! [`config`] holds all of the variables that a user might want to change. +//! +//! # XCB +//! +//! Unlike dwm, blow uses XCB rather than Xlib. This means requests are asynchronous by default. +//! In most places, we avoid checking for errors unless we need to see the response to a request. +//! Errors will be caught and logged in the event loop instead. See [`xcb`] documentation for more details. #![deny(clippy::all, clippy::pedantic, clippy::nursery)] use clients::ClientState; @@ -9,12 +25,14 @@ use xcb::{ Connection as RawConnection, Event, Extension, }; -mod clients; -mod config; -mod conn_info; +pub mod clients; +pub mod config; +pub mod conn_info; +#[doc(hidden)] mod error; +#[doc(hidden)] mod focus; -mod keys; +pub mod keys; fn main() -> Result<()> { cleanup_process_children(); @@ -29,12 +47,14 @@ fn main() -> Result<()> { Ok(()) } -struct WM<'a> { +/// All of the state used by the window manager +pub struct WM<'a> { conn: Connection<'a>, clients: ClientState, } impl<'a> WM<'a> { + /// Prepare to start the window manager, using the given connection and scren number. pub fn new(conn: &'a RawConnection, screen_num: usize) -> Result<Self> { let mut this = Self { conn: Connection::new(conn, screen_num)?, @@ -45,6 +65,8 @@ impl<'a> WM<'a> { Ok(this) } + /// Run the main event loop until we encounter a non-recoverable error (usually connection). + /// This will only ever return an error. pub fn event_loop(&mut self) -> Result<()> { loop { match self.conn.wait_for_event() { @@ -68,15 +90,19 @@ impl<'a> WM<'a> { Event::X(x::Event::PropertyNotify(e)) => self.handle_property_notify(&e), _ => {} }, + Err(Error::Xcb(xcb::Error::Protocol(e))) => { + eprintln!("protocol error in event loop: {e:#?}\ncontinuing anyway"); + } Err(e) => { - eprintln!("error in event loop: {e:#?}\ncontinuing anyway"); + eprintln!("unrecoverable error: {e:#?}\nexiting event loop"); + return Err(e); } }; self.conn.flush()?; } } - /// Handle a property notify event, by doing *todo* + /// Update client properties when they change in X11. fn handle_property_notify(&mut self, e: &PropertyNotifyEvent) { if x::ATOM_WM_HINTS == e.atom() { let focused = self.clients.is_focused(e.window()); @@ -88,9 +114,9 @@ impl<'a> WM<'a> { } /// Cleanup this process' children and set some flags. -/// This is necessary when used with `startx` +/// This is necessary when used with `startx`. fn cleanup_process_children() { // TODO: dont transform children into zombies when they terminate // TODO: cleanup zombies - todo!() + // todo!() } |