diff --git a/komorebi/src/lib.rs b/komorebi/src/lib.rs index 260b16a8..166cafc6 100644 --- a/komorebi/src/lib.rs +++ b/komorebi/src/lib.rs @@ -9,6 +9,7 @@ pub mod monitor_reconciliator; pub mod process_command; pub mod process_event; pub mod process_movement; +pub mod reaper; pub mod set_window_position; pub mod stackbar_manager; pub mod static_config; diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index 6ba1663e..0929625f 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -30,6 +30,7 @@ use komorebi::process_command::listen_for_commands; use komorebi::process_command::listen_for_commands_tcp; use komorebi::process_event::listen_for_events; use komorebi::process_movement::listen_for_movements; +use komorebi::reaper; use komorebi::stackbar_manager; use komorebi::static_config::StaticConfig; use komorebi::window_manager::WindowManager; @@ -258,6 +259,7 @@ fn main() -> Result<()> { stackbar_manager::listen_for_notifications(wm.clone()); workspace_reconciliator::listen_for_notifications(wm.clone()); monitor_reconciliator::listen_for_notifications(wm.clone())?; + reaper::watch_for_orphans(wm.clone()); let (ctrlc_sender, ctrlc_receiver) = crossbeam_channel::bounded(1); ctrlc::set_handler(move || { diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 0cd9dd12..5337aa7c 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -24,6 +24,7 @@ use crate::window::RuleDebug; use crate::window_manager::WindowManager; use crate::window_manager_event::WindowManagerEvent; use crate::windows_api::WindowsApi; +use crate::winevent::WinEvent; use crate::workspace_reconciliator; use crate::workspace_reconciliator::ALT_TAB_HWND; use crate::workspace_reconciliator::ALT_TAB_HWND_INSTANT; @@ -120,37 +121,11 @@ impl WindowManager { _ => {} } - let offset = self.work_area_offset; - - for (i, monitor) in self.monitors_mut().iter_mut().enumerate() { - let work_area = *monitor.work_area_size(); - let window_based_work_area_offset = ( - monitor.window_based_work_area_offset_limit(), - monitor.window_based_work_area_offset(), - ); - - let offset = if monitor.work_area_offset().is_some() { - monitor.work_area_offset() - } else { - offset - }; - - for (j, workspace) in monitor.workspaces_mut().iter_mut().enumerate() { + for monitor in self.monitors_mut() { + for workspace in monitor.workspaces_mut() { if let WindowManagerEvent::FocusChange(_, window) = event { let _ = workspace.focus_changed(window.hwnd); } - - let reaped_orphans = workspace.reap_orphans()?; - if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 { - workspace.update(&work_area, offset, window_based_work_area_offset)?; - tracing::info!( - "reaped {} orphan window(s) and {} orphaned container(s) on monitor: {}, workspace: {}", - reaped_orphans.0, - reaped_orphans.1, - i, - j - ); - } } } @@ -637,7 +612,16 @@ impl WindowManager { border_manager::event_tx().send(border_manager::Notification)?; stackbar_manager::event_tx().send(stackbar_manager::Notification)?; - tracing::info!("processed: {}", event.window().to_string()); + // Too many spammy OBJECT_NAMECHANGE events from JetBrains IDEs + if !matches!( + event, + WindowManagerEvent::Show(WinEvent::ObjectNameChange, _) + ) { + tracing::info!("processed: {}", event.window().to_string()); + } else { + tracing::trace!("processed: {}", event.window().to_string()); + } + Ok(()) } } diff --git a/komorebi/src/reaper.rs b/komorebi/src/reaper.rs new file mode 100644 index 00000000..9524e7b2 --- /dev/null +++ b/komorebi/src/reaper.rs @@ -0,0 +1,66 @@ +#![deny(clippy::unwrap_used, clippy::expect_used)] + +use crate::border_manager; +use crate::WindowManager; +use parking_lot::Mutex; +use std::sync::Arc; +use std::time::Duration; + +pub fn watch_for_orphans(wm: Arc>) { + std::thread::spawn(move || loop { + match find_orphans(wm.clone()) { + Ok(()) => { + tracing::warn!("restarting finished thread"); + } + Err(error) => { + if cfg!(debug_assertions) { + tracing::error!("restarting failed thread: {:?}", error) + } else { + tracing::error!("restarting failed thread: {}", error) + } + } + } + }); +} + +pub fn find_orphans(wm: Arc>) -> color_eyre::Result<()> { + tracing::info!("watching"); + + let arc = wm.clone(); + + loop { + std::thread::sleep(Duration::from_secs(1)); + + let mut wm = arc.lock(); + let offset = wm.work_area_offset; + + for (i, monitor) in wm.monitors_mut().iter_mut().enumerate() { + let work_area = *monitor.work_area_size(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; + + for (j, workspace) in monitor.workspaces_mut().iter_mut().enumerate() { + let reaped_orphans = workspace.reap_orphans()?; + if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 { + workspace.update(&work_area, offset, window_based_work_area_offset)?; + border_manager::event_tx().send(border_manager::Notification)?; + tracing::info!( + "reaped {} orphan window(s) and {} orphaned container(s) on monitor: {}, workspace: {}", + reaped_orphans.0, + reaped_orphans.1, + i, + j + ); + } + } + } + } +} diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index a2ccb130..98316c62 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -357,7 +357,7 @@ impl Workspace { layout.bottom -= total_height; } - window.set_position(&layout, false)?; + window.set_position(layout, false)?; } }