use crate::{
core::{
config::Config,
hooks::{Hook, Hooks},
manager::WindowManager,
xconnection::{XError, Xid},
},
ErrorHandler,
};
#[cfg(feature = "x11rb-xcb")]
use x11rb::xcb_ffi::XCBConnection;
use x11rb::{
connection::Connection,
errors::{ConnectError, ConnectionError, ReplyError, ReplyOrIdError},
rust_connection::RustConnection,
x11_utils::X11Error,
};
pub(crate) mod atom;
pub(crate) mod event;
pub mod xconn;
#[doc(inline)]
pub use xconn::X11rbConnection;
pub type Result<T> = std::result::Result<T, X11rbError>;
pub type X11rbHooks = Hooks<X11rbConnection<RustConnection>>;
pub fn new_x11rb_rust_backed_window_manager(
config: Config,
hooks: Vec<Box<dyn Hook<X11rbConnection<RustConnection>>>>,
error_handler: ErrorHandler,
) -> crate::Result<WindowManager<X11rbConnection<RustConnection>>> {
let (conn, _) = RustConnection::connect(None).map_err(X11rbError::from)?;
new_x11rb_backed_window_manager(conn, config, hooks, error_handler)
}
#[cfg(feature = "x11rb-xcb")]
pub fn new_x11rb_xcb_backed_window_manager(
config: Config,
hooks: Vec<Box<dyn Hook<X11rbConnection<XCBConnection>>>>,
error_handler: ErrorHandler,
) -> crate::Result<WindowManager<X11rbConnection<XCBConnection>>> {
let (conn, _) = XCBConnection::connect(None).map_err(X11rbError::from)?;
new_x11rb_backed_window_manager(conn, config, hooks, error_handler)
}
pub fn new_x11rb_backed_window_manager<C: Connection>(
connection: C,
config: Config,
hooks: Vec<Box<dyn Hook<X11rbConnection<C>>>>,
error_handler: ErrorHandler,
) -> crate::Result<WindowManager<X11rbConnection<C>>> {
let conn = X11rbConnection::new_for_connection(connection)?;
let mut wm = WindowManager::new(config, conn, hooks, error_handler);
wm.init()?;
Ok(wm)
}
#[derive(thiserror::Error, Debug)]
pub enum X11rbError {
#[error(transparent)]
Connect(#[from] ConnectError),
#[error(transparent)]
Connection(#[from] ConnectionError),
#[error(transparent)]
ReplyError(#[from] ReplyError),
#[error(transparent)]
ReplyOrIdError(#[from] ReplyOrIdError),
#[error("'{0}' prop is not set for client {1}")]
MissingProp(String, Xid),
#[error("Something was expected to be UTF8, but is not")]
NonUtf8(#[from] std::string::FromUtf8Error),
#[error("invalid property data: {0}")]
InvalidPropertyData(String),
#[error("randr query failed: {0}")]
Randr(String),
#[error("X11 error: {0:?}")]
X11Error(X11Error),
}
macro_rules! from_error {
($type:ident) => {
impl From<$type> for XError {
fn from(error: $type) -> Self {
X11rbError::from(error).into()
}
}
};
}
from_error!(ConnectError);
from_error!(ConnectionError);
from_error!(ReplyError);
from_error!(ReplyOrIdError);