diff --git a/komorebi-bar/src/bar.rs b/komorebi-bar/src/bar.rs index 1defb9ee..92d7d862 100644 --- a/komorebi-bar/src/bar.rs +++ b/komorebi-bar/src/bar.rs @@ -51,6 +51,7 @@ use komorebi_client::MonitorNotification; use komorebi_client::NotificationEvent; use komorebi_client::PathExt; use komorebi_client::SocketMessage; +use komorebi_client::VirtualDesktopNotification; use komorebi_themes::catppuccin_egui; use komorebi_themes::Base16Value; use komorebi_themes::Base16Wrapper; @@ -758,6 +759,30 @@ impl eframe::App for Komobar { self.monitor_index = monitor_index; let mut should_apply_config = false; + match notification.event { + NotificationEvent::VirtualDesktop( + VirtualDesktopNotification::EnteredAssociatedVirtualDesktop, + ) => { + tracing::debug!( + "back on komorebi's associated virtual desktop - restoring bar" + ); + if let Some(hwnd) = self.hwnd { + komorebi_client::WindowsApi::restore_window(hwnd); + } + } + NotificationEvent::VirtualDesktop( + VirtualDesktopNotification::LeftAssociatedVirtualDesktop, + ) => { + tracing::debug!( + "no longer on komorebi's associated virtual desktop - minimizing bar" + ); + if let Some(hwnd) = self.hwnd { + komorebi_client::WindowsApi::minimize_window(hwnd); + } + } + _ => {} + } + if self.monitor_index.is_none() || self .monitor_index diff --git a/komorebi-bar/src/widgets/komorebi.rs b/komorebi-bar/src/widgets/komorebi.rs index 04ddd29b..36659494 100644 --- a/komorebi-bar/src/widgets/komorebi.rs +++ b/komorebi-bar/src/widgets/komorebi.rs @@ -718,6 +718,7 @@ impl KomorebiNotificationState { let show_all_icons = render_config.borrow().show_all_icons; match notification.event { + NotificationEvent::VirtualDesktop(_) => {} NotificationEvent::WindowManager(_) => {} NotificationEvent::Monitor(_) => {} NotificationEvent::Socket(message) => match message { diff --git a/komorebi-client/src/lib.rs b/komorebi-client/src/lib.rs index 4c138813..909d85ba 100644 --- a/komorebi-client/src/lib.rs +++ b/komorebi-client/src/lib.rs @@ -70,6 +70,7 @@ pub use komorebi::State; pub use komorebi::StaticConfig; pub use komorebi::SubscribeOptions; pub use komorebi::TabsConfig; +pub use komorebi::VirtualDesktopNotification; pub use komorebi::WindowContainerBehaviour; pub use komorebi::WindowsApi; pub use komorebi::WorkspaceConfig; diff --git a/komorebi/src/lib.rs b/komorebi/src/lib.rs index dcce4d90..0bac3780 100644 --- a/komorebi/src/lib.rs +++ b/komorebi/src/lib.rs @@ -228,6 +228,8 @@ lazy_static! { Arc::new(Mutex::new(HashMap::new())); static ref FLOATING_WINDOW_TOGGLE_ASPECT_RATIO: Arc> = Arc::new(Mutex::new(AspectRatio::Predefined(PredefinedAspectRatio::Widescreen))); + + static ref CURRENT_VIRTUAL_DESKTOP: Arc>>> = Arc::new(Mutex::new(None)); } pub static DEFAULT_WORKSPACE_PADDING: AtomicI32 = AtomicI32::new(10); @@ -297,6 +299,14 @@ pub enum NotificationEvent { WindowManager(WindowManagerEvent), Socket(SocketMessage), Monitor(MonitorNotification), + VirtualDesktop(VirtualDesktopNotification), +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +pub enum VirtualDesktopNotification { + EnteredAssociatedVirtualDesktop, + LeftAssociatedVirtualDesktop, } #[derive(Debug, Serialize, Deserialize)] diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 291b51d5..1d653da2 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -28,7 +28,9 @@ use crate::workspace::WorkspaceLayer; use crate::Notification; use crate::NotificationEvent; use crate::State; +use crate::VirtualDesktopNotification; use crate::Window; +use crate::CURRENT_VIRTUAL_DESKTOP; use crate::FLOATING_APPLICATIONS; use crate::HIDDEN_HWNDS; use crate::REGEX_IDENTIFIERS; @@ -116,8 +118,17 @@ impl WindowManager { } } + let mut last_known_virtual_desktop_id = CURRENT_VIRTUAL_DESKTOP.lock(); + if let Some(virtual_desktop_id) = &self.virtual_desktop_id { - if let Some(id) = current_virtual_desktop() { + let latest_virtual_desktop_id = current_virtual_desktop(); + if let Some(id) = latest_virtual_desktop_id { + // if we are on the vd associated with komorebi + let should_retile = id == *virtual_desktop_id + // and we came from a vd not associated with komorebi + && (*last_known_virtual_desktop_id).clone().unwrap_or_default() != id; + + *last_known_virtual_desktop_id = Some(id.clone()); if id != *virtual_desktop_id { tracing::info!( "ignoring events and commands while not on virtual desktop {:?}", @@ -128,8 +139,41 @@ impl WindowManager { // if borders are enabled, they will not be drawn again until the user interacts // with the workspace or forces a retile border_manager::destroy_all_borders()?; + + // to be consumed by integrating gui applications like bars to know + // when to hide visual components which don't make sense when not on + // komorebi's associated virtual desktop + tracing::debug!("notifying subscribers that we have left komorebi's associated virtual desktop"); + notify_subscribers( + Notification { + event: NotificationEvent::VirtualDesktop( + VirtualDesktopNotification::LeftAssociatedVirtualDesktop, + ), + state: self.as_ref().into(), + }, + true, + )?; + return Ok(()); } + + if should_retile { + self.retile_all(true)?; + + // to be consumed by integrating gui applications like bars to know + // when to show visual components associated with komorebi's virtual + // desktop + tracing::error!("notifying subscribers that we are back on komorebi's associated virtual desktop"); + notify_subscribers( + Notification { + event: NotificationEvent::VirtualDesktop( + VirtualDesktopNotification::EnteredAssociatedVirtualDesktop, + ), + state: self.as_ref().into(), + }, + true, + )?; + } } }