diff --git a/Cargo.lock b/Cargo.lock index 27a8ae19..7da396e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -841,6 +841,16 @@ dependencies = [ "winreg 0.52.0", ] +[[package]] +name = "komorebi-client" +version = "0.1.22-dev.0" +dependencies = [ + "komorebi", + "komorebi-core", + "serde_json", + "uds_windows", +] + [[package]] name = "komorebi-core" version = "0.1.22-dev.0" diff --git a/Cargo.toml b/Cargo.toml index a19813fe..ad6df9e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ resolver = "2" members = [ "derive-ahk", "komorebi", + "komorebi-client", "komorebi-core", "komorebic", "komorebic-no-console", diff --git a/README.md b/README.md index 8bca40ba..6f9b17b3 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ if you want to test them together or create a build with everything integrated. ## Refactors to the codebase must have prior approval -`komorebi` is mature codebase with an internal consistency and structure that has developed organically over close to +`komorebi` is a mature codebase with an internal consistency and structure that has developed organically over close to half a decade. There are [countless hours of live coding videos](https://youtube.com/@LGUG2Z) demonstrating work on this project and @@ -138,8 +138,8 @@ distinguishing monitors by manufacturer hardware identifiers and video card port Refactors to the structure of the codebase are not taken lightly and require prior discussion and approval. -Please do not start refactoring the codebase with the expectation of having your changes integrated into the codebase -until you receive an explicit approval or a request to do so. +Please do not start refactoring the codebase with the expectation of having your changes integrated until you receive an +explicit approval or a request to do so. Similarly, when implementing features and bug fixes, please stick to the structure of the codebase as much as possible and do not take this as an opportunity to do some "refactoring along the way". diff --git a/komorebi-client/Cargo.toml b/komorebi-client/Cargo.toml new file mode 100644 index 00000000..3ce29195 --- /dev/null +++ b/komorebi-client/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "komorebi-client" +version = "0.1.22-dev.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +komorebi = { path = "../komorebi" } +komorebi-core = { path = "../komorebi-core" } +uds_windows = "1" +serde_json = "1" diff --git a/komorebi-client/src/lib.rs b/komorebi-client/src/lib.rs new file mode 100644 index 00000000..589142c0 --- /dev/null +++ b/komorebi-client/src/lib.rs @@ -0,0 +1,79 @@ +#![warn(clippy::all, clippy::nursery, clippy::pedantic)] +#![allow(clippy::missing_errors_doc)] + +pub use komorebi::container::Container; +pub use komorebi::monitor::Monitor; +pub use komorebi::ring::Ring; +pub use komorebi::window::Window; +pub use komorebi::window_manager_event::WindowManagerEvent; +pub use komorebi::workspace::Workspace; +pub use komorebi::Notification; +pub use komorebi::NotificationEvent; +pub use komorebi::State; +pub use komorebi_core::Arrangement; +pub use komorebi_core::Axis; +pub use komorebi_core::CustomLayout; +pub use komorebi_core::CycleDirection; +pub use komorebi_core::DefaultLayout; +pub use komorebi_core::Direction; +pub use komorebi_core::Layout; +pub use komorebi_core::OperationDirection; +pub use komorebi_core::Rect; +pub use komorebi_core::SocketMessage; + +use komorebi::DATA_DIR; + +use std::io::BufReader; +use std::io::Read; +use std::io::Write; +use std::net::Shutdown; +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 connected = false; + while !connected { + if let Ok(mut stream) = UnixStream::connect(&socket) { + connected = true; + stream.write_all(serde_json::to_string(message)?.as_bytes())?; + } + } + + Ok(()) +} +pub fn send_query(message: &SocketMessage) -> std::io::Result { + let socket = DATA_DIR.join(KOMOREBI); + + let mut stream = UnixStream::connect(socket)?; + 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) +} diff --git a/komorebi/src/lib.rs b/komorebi/src/lib.rs index 1fb868a8..413c93ba 100644 --- a/komorebi/src/lib.rs +++ b/komorebi/src/lib.rs @@ -170,7 +170,7 @@ lazy_static! { } }) }; - static ref DATA_DIR: PathBuf = dirs::data_local_dir().expect("there is no local data directory").join("komorebi"); + pub static ref DATA_DIR: PathBuf = dirs::data_local_dir().expect("there is no local data directory").join("komorebi"); pub static ref AHK_EXE: String = { let mut ahk: String = String::from("autohotkey.exe"); diff --git a/komorebi/src/winevent.rs b/komorebi/src/winevent.rs index 53eb3505..9d0968bd 100644 --- a/komorebi/src/winevent.rs +++ b/komorebi/src/winevent.rs @@ -227,7 +227,9 @@ impl TryFrom for WinEvent { EVENT_OBJECT_SELECTIONWITHIN => Ok(Self::ObjectSelectionWithin), EVENT_OBJECT_SHOW => Ok(Self::ObjectShow), EVENT_OBJECT_STATECHANGE => Ok(Self::ObjectStateChange), - EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED => Ok(Self::ObjectTextEditConversionTargetChanged), + EVENT_OBJECT_TEXTEDIT_CONVERSIONTARGETCHANGED => { + Ok(Self::ObjectTextEditConversionTargetChanged) + } EVENT_OBJECT_TEXTSELECTIONCHANGED => Ok(Self::ObjectTextSelectionChanged), EVENT_OBJECT_UNCLOAKED => Ok(Self::ObjectUncloaked), EVENT_OBJECT_VALUECHANGE => Ok(Self::ObjectValueChange), @@ -272,4 +274,4 @@ impl TryFrom for WinEvent { _ => Err(()), } } -} \ No newline at end of file +}