summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-11-11 21:03:30 -0700
committerIrene Knapp <ireneista@irenes.space>2026-11-11 21:32:53 -0700
commit960663d476d8a1391b8bcc4424f3f716147068ab (patch)
tree3bf7e3372295f67c4afcad07c0b74e23624ab60f
parent89a6a257f89bba997e778160c53938be371ec6ac (diff)
all the xcb wrapper types are in individual files now
the trait inheritance structure isn't THAT convoluted, but having more than one of these in a file was obscuring things.

Change-Id: I5132a6304796654d778d731be1ecb1c7b4e77120
Force-Push: yes
-rw-r--r--src/main.rs24
-rw-r--r--src/x.rs13
-rw-r--r--src/x/atoms.rs12
-rw-r--r--src/x/color.rs (renamed from src/xcolor.rs)9
-rw-r--r--src/x/connection.rs97
-rw-r--r--src/x/context.rs (renamed from src/xcontext.rs)2
-rw-r--r--src/x/display.rs56
-rw-r--r--src/x/window.rs134
-rw-r--r--src/xtypes.rs280
9 files changed, 328 insertions, 299 deletions
diff --git a/src/main.rs b/src/main.rs
index 57eabf0..51cb7bf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,15 +1,11 @@
-use crate::xtypes::*;
-use crate::xcolor::DisplayColorExt;
-use crate::xcontext::GraphicContext;
+use crate::x::*;
 
 use std::sync::Arc;
 
 use xcb::{ Xid };
 use xcb::x::{
-  self,
   ClientMessageData,
   Cw, CreateWindow,
-  CreateGc, FreeGc,
   Drawable,
   EventMask,
   PolyFillRectangle,
@@ -17,9 +13,7 @@ use xcb::x::{
   WindowClass
 };
 
-mod xcolor;
-mod xcontext;
-mod xtypes;
+mod x;
 
 
 #[derive(Clone, Copy, PartialEq, Eq)]
@@ -66,15 +60,15 @@ fn main() -> xcb::Result<()> {
 
   loop {
     match display.wait_for_event()? {
-      xcb::Event::X(x::Event::Expose(_event)) => {
+      xcb::Event::X(xcb::x::Event::Expose(_event)) => {
 	let _ = dock.redraw(); // TODO
       }
 
-      xcb::Event::X(x::Event::ButtonPress(event)) => {
+      xcb::Event::X(xcb::x::Event::ButtonPress(event)) => {
         println!("click {:?}", event);
       }
 
-      xcb::Event::X(x::Event::ClientMessage(event)) => {
+      xcb::Event::X(xcb::x::Event::ClientMessage(event)) => {
         if let ClientMessageData::Data32([atom, ..]) = event.data() {
           if atom == display.atoms().wm_delete_window.resource_id() {
             break;
@@ -99,8 +93,8 @@ impl Dock {
     let dock_bounds = Dock::compute_bounds(&screen, &configuration);
 
     let window = Window::new(Arc::clone(&display), &mut CreateWindow {
-      depth: x::COPY_FROM_PARENT as u8,
-      wid: x::Window::none(),
+      depth: xcb::x::COPY_FROM_PARENT as u8,
+      wid: xcb::x::Window::none(),
       parent: screen.root(),
       x: dock_bounds.left as i16,
       y: dock_bounds.top as i16,
@@ -116,7 +110,7 @@ impl Dock {
     })?;
     let dock = Dock { window, configuration, bounds: Arc::new(dock_bounds) };
 
-    dock.set_string_property(&x::ATOM_WM_NAME, b"sandbar")?;
+    dock.set_string_property(&xcb::x::ATOM_WM_NAME, b"sandbar")?;
 
     dock.set_atom_property(&dock.atoms().wm_protocols,
                            &[dock.atoms().wm_delete_window])?;
@@ -221,7 +215,7 @@ impl Dock {
     let cookie = connection.send_request_checked(&PolyFillRectangle {
       drawable: Drawable::Window(self.window_id()),
       property: *property,
-      r#type: x::ATOM_CARDINAL,
+      r#type: xcb::x::ATOM_CARDINAL,
       data: values,
     });
     connection.check_request(cookie)?;
diff --git a/src/x.rs b/src/x.rs
new file mode 100644
index 0000000..dcef69b
--- /dev/null
+++ b/src/x.rs
@@ -0,0 +1,13 @@
+pub use color::DisplayColorExt;
+pub use context::GraphicContext;
+pub use connection::{ Connection, HasConnection, ConnectionExt };
+pub use display::{ Display, HasDisplay, DisplayExt };
+pub use window::{ Window, HasWindow, WindowExt };
+
+pub mod atoms;
+pub mod color;
+pub mod connection;
+pub mod context;
+pub mod display;
+pub mod window;
+
diff --git a/src/x/atoms.rs b/src/x/atoms.rs
new file mode 100644
index 0000000..9f489a3
--- /dev/null
+++ b/src/x/atoms.rs
@@ -0,0 +1,12 @@
+use xcb::x::Atom;
+
+
+pub struct Atoms {
+  pub wm_protocols: Atom,
+  pub wm_delete_window: Atom,
+  pub wm_type: Atom,
+  pub wm_type_dock: Atom,
+  pub wm_strut: Atom,
+  pub wm_strut_partial: Atom,
+}
+
diff --git a/src/xcolor.rs b/src/x/color.rs
index 0fab0c8..10ad651 100644
--- a/src/xcolor.rs
+++ b/src/x/color.rs
@@ -4,7 +4,8 @@
  *
  * [1] https://xcb.freedesktop.org/xlibtoxcbtranslationguide/
  */
-use crate::xtypes::*;
+use crate::x::connection::*;
+use crate::x::display::*;
 
 use xcb::x::{ AllocColor, Visualtype };
 
@@ -31,14 +32,16 @@ pub trait DisplayColorExt: DisplayExt {
   fn allocate_color(&self, red: u16, green: u16, blue: u16)
     -> xcb::Result<u32>
   {
+    let connection = self.connection();
+
     let colormap = self.screen().default_colormap();
 
-    let cookie = self.send_request(&AllocColor {
+    let cookie = connection.send_request(&AllocColor {
       cmap: colormap,
       red, green, blue,
     });
 
-    Ok(self.wait_for_reply(cookie)?.pixel())
+    Ok(connection.wait_for_reply(cookie)?.pixel())
   }
 }
 
diff --git a/src/x/connection.rs b/src/x/connection.rs
new file mode 100644
index 0000000..d9ed9ca
--- /dev/null
+++ b/src/x/connection.rs
@@ -0,0 +1,97 @@
+use crate::x::atoms::Atoms;
+
+use xcb::XidNew;
+use xcb::x::{ Atom, InternAtom };
+
+
+pub struct Connection(xcb::Connection);
+
+impl Connection {
+  pub fn connect(display_name: Option<&str>)
+    -> xcb::ConnResult<(Connection, i32)>
+  {
+    let (connection, screen_index)
+        = xcb::Connection::connect(display_name)?;
+
+    Ok((Connection(connection), screen_index))
+  }
+}
+
+
+pub trait HasConnection {
+  fn connection(&self) -> &Connection;
+}
+
+impl HasConnection for Connection {
+  fn connection(&self) -> &Connection { self }
+}
+
+
+pub trait ConnectionExt: HasConnection {
+  fn get_setup(&self) -> &xcb::x::Setup {
+    self.connection().0.get_setup()
+  }
+
+  fn send_request<R: xcb::Request>(&self, request: &R) -> R::Cookie {
+    self.connection().0.send_request(request)
+  }
+
+  fn wait_for_reply<C: xcb::CookieWithReplyChecked>(&self, cookie: C)
+    -> xcb::Result<C::Reply>
+  {
+    self.connection().0.wait_for_reply(cookie)
+  }
+
+  fn send_request_checked<R: xcb::RequestWithoutReply>(&self, request: &R)
+    -> xcb::VoidCookieChecked
+  {
+    self.connection().0.send_request_checked(request)
+  }
+
+  fn check_request(&self, cookie: xcb::VoidCookieChecked)
+    -> xcb::ProtocolResult<()>
+  {
+    self.connection().0.check_request(cookie)
+  }
+
+  fn wait_for_event(&self) -> xcb::Result<xcb::Event> {
+    self.connection().0.wait_for_event()
+  }
+
+  fn generate_id<T: XidNew>(&self) -> T {
+    let connection = self.connection();
+
+    connection.0.generate_id()
+  }
+
+  fn get_atom(&self, name: &[u8]) -> xcb::Result<Atom> {
+    let connection = self.connection();
+
+    let cookie = connection.send_request(&InternAtom {
+      only_if_exists: true,
+      name: name,
+    });
+
+    Ok(connection.wait_for_reply(cookie)?.atom())
+  }
+
+  fn get_atoms(&self) -> xcb::Result<Atoms> {
+    let wm_protocols = self.get_atom(b"WM_PROTOCOLS")?;
+    let wm_delete_window = self.get_atom(b"WM_DELETE_WINDOW")?;
+
+    let wm_type = self.get_atom(b"_NET_WM_WINDOW_TYPE")?;
+    let wm_type_dock = self.get_atom(b"_NET_WM_WINDOW_TYPE_DOCK")?;
+
+    let wm_strut = self.get_atom(b"_NET_WM_STRUT")?;
+    let wm_strut_partial = self.get_atom(b"_NET_WM_STRUT_PARTIAL")?;
+
+    Ok(Atoms {
+      wm_protocols, wm_delete_window,
+      wm_type, wm_type_dock,
+      wm_strut, wm_strut_partial,
+    })
+  }
+}
+
+impl<T: HasConnection> ConnectionExt for T { }
+
diff --git a/src/xcontext.rs b/src/x/context.rs
index d9543f7..0a8d11e 100644
--- a/src/xcontext.rs
+++ b/src/x/context.rs
@@ -1,4 +1,4 @@
-use crate::xtypes::*;
+use crate::x::*;
 
 use std::sync::Arc;
 
diff --git a/src/x/display.rs b/src/x/display.rs
new file mode 100644
index 0000000..ca552db
--- /dev/null
+++ b/src/x/display.rs
@@ -0,0 +1,56 @@
+use crate::x::atoms::Atoms;
+use crate::x::connection::*;
+
+use std::sync::Arc;
+
+use xcb::x::Screen;
+
+
+pub struct Display {
+  connection: Connection,
+  screen_index: i32,
+  atoms: Atoms,
+}
+
+impl HasConnection for Arc<Display> {
+  fn connection(&self) -> &Connection { &self.connection }
+}
+
+
+impl Display {
+  pub fn new() -> xcb::Result<Display> {
+    let (connection, screen_index) = Connection::connect(None)?;
+
+    let atoms = connection.get_atoms()?;
+
+    Ok(Display { connection, screen_index, atoms })
+  }
+
+  pub fn screen_index(&self) -> i32 {
+    self.screen_index
+  }
+}
+
+
+pub trait HasDisplay {
+  fn display(&self) -> &Arc<Display>;
+
+  fn atoms(&self) -> &Atoms { &self.display().atoms }
+}
+
+impl HasDisplay for Arc<Display> {
+  fn display(&self) -> &Arc<Display> { self }
+}
+
+
+pub trait DisplayExt: HasDisplay + HasConnection {
+  fn screen(&self) -> &Screen {
+    let setup = self.connection().get_setup();
+    let screen_index = self.display().screen_index() as usize;
+
+    &setup.roots().nth(screen_index).unwrap()
+  }
+}
+
+impl<T: HasDisplay + HasConnection> DisplayExt for T { }
+
diff --git a/src/x/window.rs b/src/x/window.rs
new file mode 100644
index 0000000..d264eb9
--- /dev/null
+++ b/src/x/window.rs
@@ -0,0 +1,134 @@
+use crate::x::*;
+
+use std::sync::Arc;
+use std::ops::Deref;
+
+use xcb::x::{
+  self,
+  Atom,
+  ChangeProperty,
+  CreateWindow,
+  MapWindow,
+  PropMode,
+};
+
+
+pub struct Window {
+  display: Arc<Display>,
+  window_id: x::Window,
+}
+
+
+
+impl Window {
+  pub fn new(display: Arc<Display>, create_window: &mut CreateWindow)
+    -> xcb::Result<Window>
+  {
+    let connection = display.connection();
+
+    let window_id: x::Window = connection.generate_id();
+
+    create_window.wid = window_id;
+    let cookie = connection.send_request_checked(create_window);
+    connection.check_request(cookie)?;
+
+    Ok(Window { display, window_id })
+  }
+}
+
+
+pub trait HasWindow {
+  fn window(&self) -> &Window;
+
+  fn window_id(&self) -> x::Window { self.window().window_id }
+}
+
+impl HasWindow for Window {
+  fn window(&self) -> &Window { self }
+}
+
+impl<T: Deref<Target=Window>> HasWindow for T {
+  fn window(&self) -> &Window { &*self }
+}
+
+
+impl HasConnection for Window {
+  fn connection(&self) -> &Connection { self.display.connection() }
+}
+
+
+impl HasDisplay for Window {
+  fn display(&self) -> &Arc<Display> { &self.display }
+}
+
+
+
+
+pub trait WindowExt: HasWindow + HasDisplay + HasConnection {
+  fn map_window(&self) -> xcb::Result<()> {
+    let connection = self.connection();
+
+    let cookie = connection.send_request_checked(&MapWindow {
+      window: self.window_id()
+    });
+    connection.check_request(cookie)?;
+
+    Ok(())
+  }
+
+  fn set_string_property(&self, property: &Atom, value: &[u8])
+    -> xcb::Result<()>
+  {
+    let connection = self.connection();
+
+    let cookie = connection.send_request_checked(&ChangeProperty {
+      mode: PropMode::Replace,
+      window: self.window_id(),
+      property: *property,
+      r#type: x::ATOM_STRING,
+      data: value,
+    });
+    connection.check_request(cookie)?;
+
+    Ok(())
+  }
+
+
+  fn set_atom_property(&self, property: &Atom, values: &[Atom])
+    -> xcb::Result<()>
+  {
+    let connection = self.connection();
+
+    let cookie = connection.send_request_checked(&ChangeProperty {
+      mode: PropMode::Replace,
+      window: self.window_id(),
+      property: *property,
+      r#type: x::ATOM_ATOM,
+      data: values,
+    });
+    connection.check_request(cookie)?;
+
+    Ok(())
+  }
+
+
+  fn set_cardinal_property(&self, property: &Atom, values: &[u32])
+    -> xcb::Result<()>
+  {
+    let connection = self.connection();
+
+    let cookie = connection.send_request_checked(&ChangeProperty {
+      mode: PropMode::Replace,
+      window: self.window_id(),
+      property: *property,
+      r#type: x::ATOM_CARDINAL,
+      data: values,
+    });
+    connection.check_request(cookie)?;
+
+    Ok(())
+  }
+}
+
+impl<T: HasWindow + HasDisplay + HasConnection> WindowExt for T { }
+
diff --git a/src/xtypes.rs b/src/xtypes.rs
deleted file mode 100644
index 89bb622..0000000
--- a/src/xtypes.rs
+++ /dev/null
@@ -1,280 +0,0 @@
-use std::borrow::Borrow;
-use std::sync::Arc;
-use std::ops::Deref;
-
-use xcb::XidNew;
-use xcb::x::{
-  self,
-  Atom,
-  ChangeProperty,
-  CreateWindow,
-  InternAtom,
-  MapWindow,
-  PropMode,
-  Screen,
-};
-
-
-pub struct Atoms {
-  pub wm_protocols: Atom,
-  pub wm_delete_window: Atom,
-  pub wm_type: Atom,
-  pub wm_type_dock: Atom,
-  pub wm_strut: Atom,
-  pub wm_strut_partial: Atom,
-}
-
-
-pub struct Connection(xcb::Connection);
-
-pub struct Display {
-  connection: Connection,
-  screen_index: i32,
-  atoms: Atoms,
-}
-
-pub struct Window {
-  display: Arc<Display>,
-  window_id: x::Window,
-}
-
-
-impl Connection {
-  pub fn connect(display_name: Option<&str>)
-    -> xcb::ConnResult<(Connection, i32)>
-  {
-    let (connection, screen_index)
-        = xcb::Connection::connect(display_name)?;
-
-    Ok((Connection(connection), screen_index))
-  }
-}
-
-
-impl Display {
-  pub fn new() -> xcb::Result<Display> {
-    let (connection, screen_index) = Connection::connect(None)?;
-
-    let atoms = connection.get_atoms()?;
-
-    Ok(Display { connection, screen_index, atoms })
-  }
-
-  pub fn screen_index(&self) -> i32 {
-    self.screen_index
-  }
-}
-
-
-impl Window {
-  pub fn new(display: Arc<Display>, create_window: &mut CreateWindow)
-    -> xcb::Result<Window>
-  {
-    let display_ref: &Display = display.borrow();
-    let connection: &Connection = &display_ref.connection;
-
-    let window_id: x::Window = connection.generate_id();
-
-    create_window.wid = window_id;
-    let cookie = connection.send_request_checked(create_window);
-    connection.check_request(cookie)?;
-
-    Ok(Window { display, window_id })
-  }
-}
-
-
-pub trait HasWindow {
-  fn window(&self) -> &Window;
-
-  fn window_id(&self) -> x::Window { self.window().window_id }
-}
-
-impl HasWindow for Window {
-  fn window(&self) -> &Window { self }
-}
-
-impl<T: Deref<Target=Window>> HasWindow for T {
-  fn window(&self) -> &Window { &*self }
-}
-
-
-pub trait HasConnection {
-  fn connection(&self) -> &Connection;
-
-  fn get_setup(&self) -> &xcb::x::Setup {
-    self.connection().0.get_setup()
-  }
-
-  fn send_request<R: xcb::Request>(&self, request: &R) -> R::Cookie {
-    self.connection().0.send_request(request)
-  }
-
-  fn wait_for_reply<C: xcb::CookieWithReplyChecked>(&self, cookie: C)
-    -> xcb::Result<C::Reply>
-  {
-    self.connection().0.wait_for_reply(cookie)
-  }
-
-  fn send_request_checked<R: xcb::RequestWithoutReply>(&self, request: &R)
-    -> xcb::VoidCookieChecked
-  {
-    self.connection().0.send_request_checked(request)
-  }
-
-  fn check_request(&self, cookie: xcb::VoidCookieChecked)
-    -> xcb::ProtocolResult<()>
-  {
-    self.connection().0.check_request(cookie)
-  }
-
-  fn wait_for_event(&self) -> xcb::Result<xcb::Event> {
-    self.connection().0.wait_for_event()
-  }
-}
-
-impl HasConnection for Connection {
-  fn connection(&self) -> &Connection { self }
-}
-
-impl HasConnection for Arc<Display> {
-  fn connection(&self) -> &Connection { &self.connection }
-}
-
-impl HasConnection for Window {
-  fn connection(&self) -> &Connection { &self.display.connection }
-}
-
-
-pub trait HasDisplay {
-  fn display(&self) -> &Arc<Display>;
-
-  fn atoms(&self) -> &Atoms { &self.display().atoms }
-}
-
-impl HasDisplay for Arc<Display> {
-  fn display(&self) -> &Arc<Display> { self }
-}
-
-impl HasDisplay for Window {
-  fn display(&self) -> &Arc<Display> { &self.display }
-}
-
-
-pub trait ConnectionExt: HasConnection {
-  fn generate_id<T: XidNew>(&self) -> T {
-    let connection = self.connection();
-
-    connection.0.generate_id()
-  }
-
-  fn get_atom(&self, name: &[u8]) -> xcb::Result<Atom> {
-    let connection = self.connection();
-
-    let cookie = connection.send_request(&InternAtom {
-      only_if_exists: true,
-      name: name,
-    });
-
-    Ok(connection.wait_for_reply(cookie)?.atom())
-  }
-
-  fn get_atoms(&self) -> xcb::Result<Atoms> {
-    let wm_protocols = self.get_atom(b"WM_PROTOCOLS")?;
-    let wm_delete_window = self.get_atom(b"WM_DELETE_WINDOW")?;
-
-    let wm_type = self.get_atom(b"_NET_WM_WINDOW_TYPE")?;
-    let wm_type_dock = self.get_atom(b"_NET_WM_WINDOW_TYPE_DOCK")?;
-
-    let wm_strut = self.get_atom(b"_NET_WM_STRUT")?;
-    let wm_strut_partial = self.get_atom(b"_NET_WM_STRUT_PARTIAL")?;
-
-    Ok(Atoms {
-      wm_protocols, wm_delete_window,
-      wm_type, wm_type_dock,
-      wm_strut, wm_strut_partial,
-    })
-  }
-}
-
-impl<T: HasConnection> ConnectionExt for T { }
-
-
-pub trait DisplayExt: HasDisplay + HasConnection {
-  fn screen(&self) -> &Screen {
-    let setup = self.connection().get_setup();
-    let screen_index = self.display().screen_index() as usize;
-
-    &setup.roots().nth(screen_index).unwrap()
-  }
-}
-
-impl<T: HasDisplay + HasConnection> DisplayExt for T { }
-
-
-pub trait WindowExt: HasWindow + HasDisplay + HasConnection {
-  fn map_window(&self) -> xcb::Result<()> {
-    let cookie = self.send_request_checked(&MapWindow {
-      window: self.window_id()
-    });
-    self.check_request(cookie)?;
-
-    Ok(())
-  }
-
-  fn set_string_property(&self, property: &Atom, value: &[u8])
-    -> xcb::Result<()>
-  {
-    let connection = self.connection();
-
-    let cookie = connection.send_request_checked(&ChangeProperty {
-      mode: PropMode::Replace,
-      window: self.window_id(),
-      property: *property,
-      r#type: x::ATOM_STRING,
-      data: value,
-    });
-    connection.check_request(cookie)?;
-
-    Ok(())
-  }
-
-
-  fn set_atom_property(&self, property: &Atom, values: &[Atom])
-    -> xcb::Result<()>
-  {
-    let connection = self.connection();
-
-    let cookie = connection.send_request_checked(&ChangeProperty {
-      mode: PropMode::Replace,
-      window: self.window_id(),
-      property: *property,
-      r#type: x::ATOM_ATOM,
-      data: values,
-    });
-    connection.check_request(cookie)?;
-
-    Ok(())
-  }
-
-
-  fn set_cardinal_property(&self, property: &Atom, values: &[u32])
-    -> xcb::Result<()>
-  {
-    let connection = self.connection();
-
-    let cookie = connection.send_request_checked(&ChangeProperty {
-      mode: PropMode::Replace,
-      window: self.window_id(),
-      property: *property,
-      r#type: x::ATOM_CARDINAL,
-      data: values,
-    });
-    connection.check_request(cookie)?;
-
-    Ok(())
-  }
-}
-
-impl<T: HasWindow + HasDisplay + HasConnection> WindowExt for T { }
-