use crate::{
core::{bindings::KeyEventHandler, layout::IntoMessage, ClientSet, State},
util,
x::{XConn, XConnExt},
Result,
};
use tracing::info;
pub mod floating;
pub fn key_handler<F, X>(f: F) -> Box<dyn KeyEventHandler<X>>
where
F: FnMut(&mut State<X>, &X) -> Result<()> + 'static,
X: XConn,
{
Box::new(f)
}
pub fn modify_with<F, X>(f: F) -> Box<dyn KeyEventHandler<X>>
where
F: FnMut(&mut ClientSet) + Clone + 'static,
X: XConn,
{
Box::new(move |s: &mut State<X>, x: &X| x.modify_and_refresh(s, f.clone()))
}
pub fn send_layout_message<F, M, X>(f: F) -> Box<dyn KeyEventHandler<X>>
where
F: Fn() -> M + 'static,
M: IntoMessage,
X: XConn,
{
key_handler(move |s: &mut State<X>, x: &X| {
x.modify_and_refresh(s, |cs| {
cs.current_workspace_mut().handle_message(f());
})
})
}
pub fn broadcast_layout_message<F, M, X>(f: F) -> Box<dyn KeyEventHandler<X>>
where
F: Fn() -> M + 'static,
M: IntoMessage,
X: XConn,
{
key_handler(move |s: &mut State<X>, x: &X| {
x.modify_and_refresh(s, |cs| {
cs.current_workspace_mut().broadcast_message(f());
})
})
}
pub fn spawn<X>(program: &'static str) -> Box<dyn KeyEventHandler<X>>
where
X: XConn,
{
key_handler(move |_, _| util::spawn(program))
}
pub fn exit<X: XConn>() -> Box<dyn KeyEventHandler<X>> {
key_handler(|s: &mut State<X>, _| {
s.running = false;
Ok(())
})
}
pub fn log_current_state<X: XConn + std::fmt::Debug>() -> Box<dyn KeyEventHandler<X>> {
key_handler(|s: &mut State<X>, _| {
info!("Current Window Manager State: {s:#?}");
Ok(())
})
}
pub fn remove_and_unmap_focused_client<X: XConn>() -> Box<dyn KeyEventHandler<X>> {
key_handler(|s: &mut State<X>, x: &X| {
if let Some(client) = s.client_set.remove_focused() {
info!(
?client,
"Unmapping previously focused client following removal from state"
);
x.unmap(client)
} else {
Ok(())
}
})
}