feat(bar): hide when leaving komorebi's virtual desktop

This commit adds a new VirtualDesktopNotification which is used to
notify subscribers when the user leaves and enters the virtual desktop
associated with komorebi.

komorebi-bar consumes these notifications to minmize and restore the bar
appropriately depending on the currently focused virtual desktop.

re #1420
This commit is contained in:
LGUG2Z
2025-04-28 14:33:37 -07:00
parent 17cd0308cb
commit 577364a556
5 changed files with 82 additions and 1 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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;

View File

@@ -228,6 +228,8 @@ lazy_static! {
Arc::new(Mutex::new(HashMap::new()));
static ref FLOATING_WINDOW_TOGGLE_ASPECT_RATIO: Arc<Mutex<AspectRatio>> = Arc::new(Mutex::new(AspectRatio::Predefined(PredefinedAspectRatio::Widescreen)));
static ref CURRENT_VIRTUAL_DESKTOP: Arc<Mutex<Option<Vec<u8>>>> = 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)]

View File

@@ -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,
)?;
}
}
}