mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-01-11 22:12:53 +01:00
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:
@@ -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();
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user