diff --git a/komorebi/src/border_manager/mod.rs b/komorebi/src/border_manager/mod.rs index 51e40fa1..07a2a882 100644 --- a/komorebi/src/border_manager/mod.rs +++ b/komorebi/src/border_manager/mod.rs @@ -6,6 +6,7 @@ use crossbeam_channel::Receiver; use crossbeam_channel::Sender; use crossbeam_utils::atomic::AtomicConsume; use komorebi_core::BorderStyle; +use komorebi_core::StackbarMode; use lazy_static::lazy_static; use parking_lot::Mutex; use schemars::JsonSchema; @@ -22,6 +23,8 @@ use std::time::Duration; use std::time::Instant; use windows::Win32::Foundation::HWND; +use crate::stackbar_manager; +use crate::stackbar_manager::STACKBAR_MODE; use crate::workspace_reconciliator::ALT_TAB_HWND; use crate::Colour; use crate::Rect; @@ -56,7 +59,10 @@ lazy_static! { static ref FOCUS_STATE: Mutex> = Mutex::new(HashMap::new()); } -pub struct Notification; +pub enum Notification { + Default, + Move, +} static CHANNEL: OnceLock<(Sender, Receiver)> = OnceLock::new(); @@ -124,9 +130,9 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result let receiver = event_rx(); let mut instant: Option = None; - event_tx().send(Notification)?; + event_tx().send(Notification::Default)?; - 'receiver: for _ in receiver { + 'receiver: for notification in receiver { if let Some(instant) = instant { if instant.elapsed().lt(&Duration::from_millis(50)) { continue 'receiver; @@ -270,6 +276,40 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result borders.remove(id); } + let workspace_has_stack = { + let mut should = false; + for c in ws.containers() { + if stackbar_manager::should_have_stackbar(c.windows().len()) { + should = true; + } + } + + should + }; + + let stackbar_mode = STACKBAR_MODE.load(); + let workspace_has_stackbar = matches!(stackbar_mode, StackbarMode::Always) + || workspace_has_stack && matches!(stackbar_mode, StackbarMode::OnStack); + + if matches!(notification, Notification::Move) && workspace_has_stackbar { + let focus_state = FOCUS_STATE.lock(); + + let mut to_remove = vec![]; + for (id, border) in borders.iter() { + if borders_monitors.get(id).copied().unwrap_or_default() == monitor_idx + && container_ids.contains(id) + && matches!(focus_state.get(&border.hwnd), Some(&WindowKind::Unfocused)) + { + border.destroy()?; + to_remove.push(id.clone()); + } + } + + for id in &to_remove { + borders.remove(id); + } + } + for (idx, c) in ws.containers().iter().enumerate() { // Update border when moving or resizing with mouse if state.pending_move_op.is_some() && idx == ws.focused_container_idx() { diff --git a/komorebi/src/monitor_reconciliator/mod.rs b/komorebi/src/monitor_reconciliator/mod.rs index 7a444bc2..6efd9494 100644 --- a/komorebi/src/monitor_reconciliator/mod.rs +++ b/komorebi/src/monitor_reconciliator/mod.rs @@ -160,7 +160,7 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result if should_update { tracing::info!("updated work area for {}", monitor.device_id()); monitor.update_focused_workspace(offset)?; - border_manager::event_tx().send(border_manager::Notification)?; + border_manager::event_tx().send(border_manager::Notification::Default)?; } else { tracing::debug!( "work areas match, reconciliation not required for {}", @@ -207,7 +207,7 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result ); monitor.update_focused_workspace(offset)?; - border_manager::event_tx().send(border_manager::Notification)?; + border_manager::event_tx().send(border_manager::Notification::Default)?; } else { tracing::debug!( "resolutions match, reconciliation not required for {}", @@ -394,7 +394,7 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result // Second retile to fix DPI/resolution related jank wm.retile_all(true)?; // Border updates to fix DPI/resolution related jank - border_manager::event_tx().send(border_manager::Notification)?; + border_manager::event_tx().send(border_manager::Notification::Default)?; } } } diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 47d93628..e45f8cc3 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -196,6 +196,7 @@ impl WindowManager { } SocketMessage::MoveWindow(direction) => { self.move_container_in_direction(direction)?; + border_manager::event_tx().send(border_manager::Notification::Move)?; } SocketMessage::CycleFocusWindow(direction) => { self.focus_container_in_cycle_direction(direction)?; @@ -1334,7 +1335,7 @@ impl WindowManager { }; notify_subscribers(&serde_json::to_string(¬ification)?)?; - border_manager::event_tx().send(border_manager::Notification)?; + border_manager::event_tx().send(border_manager::Notification::Default)?; stackbar_manager::event_tx().send(stackbar_manager::Notification)?; tracing::info!("processed"); diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 5625fb9a..c04f6d0f 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -620,7 +620,7 @@ impl WindowManager { }; notify_subscribers(&serde_json::to_string(¬ification)?)?; - border_manager::event_tx().send(border_manager::Notification)?; + border_manager::event_tx().send(border_manager::Notification::Default)?; stackbar_manager::event_tx().send(stackbar_manager::Notification)?; tracing::info!("processed: {}", event.window().to_string()); diff --git a/komorebi/src/workspace_reconciliator.rs b/komorebi/src/workspace_reconciliator.rs index 973e4b2e..383cd23a 100644 --- a/komorebi/src/workspace_reconciliator.rs +++ b/komorebi/src/workspace_reconciliator.rs @@ -106,7 +106,7 @@ pub fn handle_notifications(wm: Arc>) -> color_eyre::Result // Unblock the border manager ALT_TAB_HWND.store(None); // Send a notification to the border manager to update the borders - border_manager::event_tx().send(border_manager::Notification)?; + border_manager::event_tx().send(border_manager::Notification::Default)?; } } }