diff --git a/Cargo.lock b/Cargo.lock index 33d53100..e5017149 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -179,9 +179,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -373,11 +373,14 @@ dependencies = [ name = "komorebic" version = "0.1.0" dependencies = [ + "bindings", "clap", "color-eyre", "dirs", "komorebi-core", "powershell_script", + "serde", + "serde_json", "uds_windows", ] @@ -756,18 +759,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" dependencies = [ "proc-macro2", "quote", @@ -776,9 +779,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" dependencies = [ "itoa", "ryu", @@ -787,9 +790,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79c719719ee05df97490f80a45acfc99e5a30ce98a1e4fb67aee422745ae14e3" +checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" dependencies = [ "lazy_static", ] diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 1131d870..e9491621 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -1,3 +1,4 @@ +use std::fs::OpenOptions; use std::sync::Arc; use std::sync::Mutex; use std::thread; @@ -31,7 +32,7 @@ pub fn listen_for_events(wm: Arc>) { } impl WindowManager { - #[allow(clippy::too_many_lines)] + #[allow(clippy::too_many_lines, clippy::cognitive_complexity)] pub fn process_event(&mut self, event: &mut WindowManagerEvent) -> Result<()> { if self.is_paused { tracing::info!("ignoring events while paused"); @@ -70,7 +71,7 @@ impl WindowManager { } } - if matches!(event, WindowManagerEvent::MouseCapture(_, _)) { + if matches!(event, WindowManagerEvent::MouseCapture(..)) { tracing::trace!("only reaping orphans for mouse capture event"); return Ok(()); } @@ -162,6 +163,28 @@ impl WindowManager { WindowManagerEvent::MouseCapture(..) => {} }; + tracing::debug!("updating list of known hwnds"); + let mut known_hwnds = vec![]; + for monitor in self.monitors() { + for workspace in monitor.workspaces() { + for container in workspace.containers() { + for window in container.windows() { + known_hwnds.push(window.hwnd); + } + } + } + } + + let mut hwnd_json = dirs::home_dir().context("there is no home directory")?; + hwnd_json.push("komorebi.hwnd.json"); + let file = OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(hwnd_json)?; + + serde_json::to_writer_pretty(&file, &known_hwnds)?; + tracing::info!("finished processing event: {}", event); Ok(()) } diff --git a/komorebic/Cargo.toml b/komorebic/Cargo.toml index f795421c..3ac31bb4 100644 --- a/komorebic/Cargo.toml +++ b/komorebic/Cargo.toml @@ -6,10 +6,13 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +bindings = { package = "bindings", path = "../bindings" } komorebi-core = { path = "../komorebi-core" } clap = "3.0.0-beta.2" +color-eyre = "0.5.11" dirs = "3" powershell_script = "0.1.5" -uds_windows = "1" -color-eyre = "0.5.11" \ No newline at end of file +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +uds_windows = "1" \ No newline at end of file diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 7633ca1c..849d1e07 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -1,3 +1,4 @@ +use std::fs::File; use std::io::BufRead; use std::io::BufReader; use std::io::ErrorKind; @@ -9,6 +10,10 @@ use color_eyre::Result; use uds_windows::UnixListener; use uds_windows::UnixStream; +use bindings::Windows::Win32::Foundation::HWND; +use bindings::Windows::Win32::UI::WindowsAndMessaging::ShowWindow; +use bindings::Windows::Win32::UI::WindowsAndMessaging::SHOW_WINDOW_CMD; +use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_RESTORE; use komorebi_core::CycleDirection; use komorebi_core::Layout; use komorebi_core::LayoutFlip; @@ -44,6 +49,7 @@ enum SubCommand { ToggleFloat, TogglePause, ToggleMonocle, + RestoreWindows, State, Start, Stop, @@ -291,7 +297,29 @@ fn main() -> Result<()> { } } } + SubCommand::RestoreWindows => { + let mut hwnd_json = dirs::home_dir().context("there is no home directory")?; + hwnd_json.push("komorebi.hwnd.json"); + + let file = File::open(hwnd_json)?; + let reader = BufReader::new(file); + let hwnds: Vec = serde_json::from_reader(reader)?; + + for hwnd in hwnds { + restore_window(HWND(hwnd)); + } + } } Ok(()) } + +fn show_window(hwnd: HWND, command: SHOW_WINDOW_CMD) { + // BOOL is returned but does not signify whether or not the operation was succesful + // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow + unsafe { ShowWindow(hwnd, command) }; +} + +fn restore_window(hwnd: HWND) { + show_window(hwnd, SW_RESTORE); +}