#![warn(clippy::all)] #![allow(clippy::missing_errors_doc)] pub use komorebi::AnimationsConfig; pub use komorebi::AppSpecificConfigurationPath; pub use komorebi::AspectRatio; pub use komorebi::BorderColours; pub use komorebi::Colour; pub use komorebi::CrossBoundaryBehaviour; pub use komorebi::GridLayoutOptions; pub use komorebi::KomorebiTheme; pub use komorebi::LayoutOptions; pub use komorebi::MonitorConfig; pub use komorebi::Notification; pub use komorebi::NotificationEvent; pub use komorebi::Placement; pub use komorebi::PredefinedAspectRatio; pub use komorebi::Rgb; pub use komorebi::RuleDebug; pub use komorebi::ScrollingLayoutOptions; pub use komorebi::StackbarConfig; pub use komorebi::StaticConfig; pub use komorebi::SubscribeOptions; pub use komorebi::TabsConfig; pub use komorebi::ThemeOptions; pub use komorebi::VirtualDesktopNotification; pub use komorebi::Wallpaper; pub use komorebi::WindowContainerBehaviour; pub use komorebi::WindowHandlingBehaviour; pub use komorebi::WindowsApi; pub use komorebi::WorkspaceConfig; pub use komorebi::animation::PerAnimationPrefixConfig; pub use komorebi::animation::prefix::AnimationPrefix; pub use komorebi::asc::ApplicationSpecificConfiguration; pub use komorebi::border_manager::BorderInfo; pub use komorebi::config_generation::ApplicationConfiguration; pub use komorebi::config_generation::IdWithIdentifier; pub use komorebi::config_generation::IdWithIdentifierAndComment; pub use komorebi::config_generation::MatchingRule; pub use komorebi::config_generation::MatchingStrategy; pub use komorebi::container::Container; pub use komorebi::core::AnimationStyle; pub use komorebi::core::ApplicationIdentifier; pub use komorebi::core::Arrangement; pub use komorebi::core::Axis; pub use komorebi::core::BorderImplementation; pub use komorebi::core::BorderStyle; pub use komorebi::core::Column; pub use komorebi::core::ColumnSplit; pub use komorebi::core::ColumnSplitWithCapacity; pub use komorebi::core::ColumnWidth; pub use komorebi::core::CustomLayout; pub use komorebi::core::CycleDirection; pub use komorebi::core::DefaultLayout; pub use komorebi::core::Direction; pub use komorebi::core::FloatingLayerBehaviour; pub use komorebi::core::FocusFollowsMouseImplementation; pub use komorebi::core::HidingBehaviour; pub use komorebi::core::Layout; pub use komorebi::core::MoveBehaviour; pub use komorebi::core::OperationBehaviour; pub use komorebi::core::OperationDirection; pub use komorebi::core::PathExt; pub use komorebi::core::Rect; pub use komorebi::core::Sizing; pub use komorebi::core::SocketMessage; pub use komorebi::core::StackbarLabel; pub use komorebi::core::StackbarMode; pub use komorebi::core::StateQuery; pub use komorebi::core::WindowKind; pub use komorebi::core::config_generation::ApplicationConfigurationGenerator; pub use komorebi::core::replace_env_in_path; pub use komorebi::monitor::Monitor; pub use komorebi::monitor_reconciliator::MonitorNotification; pub use komorebi::ring::Ring; pub use komorebi::splash; pub use komorebi::state::GlobalState; pub use komorebi::state::State; pub use komorebi::win32_display_data; pub use komorebi::window::Window; pub use komorebi::window_manager_event::WindowManagerEvent; pub use komorebi::workspace::Workspace; pub use komorebi::workspace::WorkspaceGlobals; pub use komorebi::workspace::WorkspaceLayer; use komorebi::DATA_DIR; use std::borrow::Borrow; use std::io::BufReader; use std::io::Read; use std::io::Write; use std::net::Shutdown; use std::time::Duration; pub use uds_windows::UnixListener; use uds_windows::UnixStream; const KOMOREBI: &str = "komorebi.sock"; pub fn send_message(message: &SocketMessage) -> std::io::Result<()> { let socket = DATA_DIR.join(KOMOREBI); let mut stream = UnixStream::connect(socket)?; stream.set_write_timeout(Some(Duration::from_secs(1)))?; stream.write_all(serde_json::to_string(message)?.as_bytes()) } pub fn send_batch(messages: impl IntoIterator) -> std::io::Result<()> where Q: Borrow, { let socket = DATA_DIR.join(KOMOREBI); let mut stream = UnixStream::connect(socket)?; stream.set_write_timeout(Some(Duration::from_secs(1)))?; let msgs = messages.into_iter().fold(String::new(), |mut s, m| { if let Ok(m_str) = serde_json::to_string(m.borrow()) { s.push_str(&m_str); s.push('\n'); } s }); stream.write_all(msgs.as_bytes()) } pub fn send_query(message: &SocketMessage) -> std::io::Result { let socket = DATA_DIR.join(KOMOREBI); let mut stream = UnixStream::connect(socket)?; stream.set_read_timeout(Some(Duration::from_secs(1)))?; stream.set_write_timeout(Some(Duration::from_secs(1)))?; stream.write_all(serde_json::to_string(message)?.as_bytes())?; stream.shutdown(Shutdown::Write)?; let mut reader = BufReader::new(stream); let mut response = String::new(); reader.read_to_string(&mut response)?; Ok(response) } pub fn subscribe(name: &str) -> std::io::Result { let socket = DATA_DIR.join(name); match std::fs::remove_file(&socket) { Ok(()) => {} Err(error) => match error.kind() { std::io::ErrorKind::NotFound => {} _ => { return Err(error); } }, }; let listener = UnixListener::bind(&socket)?; send_message(&SocketMessage::AddSubscriberSocket(name.to_string()))?; Ok(listener) } pub fn subscribe_with_options( name: &str, options: SubscribeOptions, ) -> std::io::Result { let socket = DATA_DIR.join(name); match std::fs::remove_file(&socket) { Ok(()) => {} Err(error) => match error.kind() { std::io::ErrorKind::NotFound => {} _ => { return Err(error); } }, }; let listener = UnixListener::bind(&socket)?; send_message(&SocketMessage::AddSubscriberSocketWithOptions( name.to_string(), options, ))?; Ok(listener) }