fix(transparency): handle stackbar tab clicks

This commit ensures that stackbar clicks will be handled properly by the
transparency manager by creating an override to process events for
windows which may not be at the top of the stack and may have previously
been made transparent before they were hidden.

fix #864
This commit is contained in:
LGUG2Z
2024-06-03 17:39:28 -07:00
parent 9a0ee8e8dd
commit a488890a04
3 changed files with 57 additions and 24 deletions

View File

@@ -18,8 +18,6 @@ use std::sync::atomic::AtomicI32;
use std::sync::atomic::AtomicU32;
use std::sync::Arc;
use std::sync::OnceLock;
use std::time::Duration;
use std::time::Instant;
use windows::Win32::Foundation::HWND;
use crate::workspace_reconciliator::ALT_TAB_HWND;
@@ -123,18 +121,9 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
tracing::info!("listening");
let receiver = event_rx();
let mut instant: Option<Instant> = None;
event_tx().send(Notification)?;
'receiver: for _ in receiver {
if let Some(instant) = instant {
if instant.elapsed().lt(&Duration::from_millis(50)) {
continue 'receiver;
}
}
instant = Some(Instant::now());
let mut borders = BORDER_STATE.lock();
let mut borders_monitors = BORDERS_MONITORS.lock();

View File

@@ -6,6 +6,7 @@ use std::time::Instant;
use color_eyre::eyre::anyhow;
use color_eyre::Result;
use crossbeam_utils::atomic::AtomicConsume;
use parking_lot::Mutex;
use komorebi_core::OperationDirection;
@@ -75,7 +76,32 @@ impl WindowManager {
// All event handlers below this point should only be processed if the event is
// related to a window that should be managed by the WindowManager.
if !should_manage {
return Ok(());
let mut transparency_override = false;
if transparency_manager::TRANSPARENCY_ENABLED.load_consume() {
for m in self.monitors() {
for w in m.workspaces() {
let event_hwnd = event.window().hwnd;
let visible_hwnds = w
.visible_windows()
.iter()
.flatten()
.map(|w| w.hwnd)
.collect::<Vec<_>>();
if w.contains_managed_window(event_hwnd)
&& !visible_hwnds.contains(&event_hwnd)
{
transparency_override = true;
}
}
}
}
if !transparency_override {
return Ok(());
}
}
if let Some(virtual_desktop_id) = &self.virtual_desktop_id {

View File

@@ -126,24 +126,42 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
// make it transparent
#[allow(clippy::collapsible_else_if)]
if idx != ws.focused_container_idx() || monitor_idx != focused_monitor_idx {
let unfocused_window = c.focused_window().copied().unwrap_or_default();
match unfocused_window.transparent() {
Err(error) => {
let hwnd = foreground_hwnd;
tracing::error!(
let focused_window_idx = c.focused_window_idx();
for (window_idx, window) in c.windows().iter().enumerate() {
if window_idx == focused_window_idx {
match window.transparent() {
Err(error) => {
let hwnd = foreground_hwnd;
tracing::error!(
"failed to make unfocused window {hwnd} transparent: {error}"
)
}
Ok(..) => {
known_hwnds.lock().push(unfocused_window.hwnd);
}
Ok(..) => {
known_hwnds.lock().push(window.hwnd);
}
}
} else {
// just in case, this is useful when people are clicking around
// on unfocused stackbar tabs
known_hwnds.lock().push(window.hwnd);
}
}
// Otherwise, make it opaque
} else {
if let Err(error) = c.focused_window().copied().unwrap_or_default().opaque()
{
let hwnd = foreground_hwnd;
tracing::error!("failed to make focused window {hwnd} opaque: {error}")
let focused_window_idx = c.focused_window_idx();
for (window_idx, window) in c.windows().iter().enumerate() {
if window_idx != focused_window_idx {
known_hwnds.lock().push(window.hwnd);
} else {
if let Err(error) =
c.focused_window().copied().unwrap_or_default().opaque()
{
let hwnd = foreground_hwnd;
tracing::error!(
"failed to make focused window {hwnd} opaque: {error}"
)
}
}
}
};
}