mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 01:58:51 +02: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::atomic::AtomicU32;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
use std::time::Duration;
|
|
||||||
use std::time::Instant;
|
|
||||||
use windows::Win32::Foundation::HWND;
|
use windows::Win32::Foundation::HWND;
|
||||||
|
|
||||||
use crate::workspace_reconciliator::ALT_TAB_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");
|
tracing::info!("listening");
|
||||||
|
|
||||||
let receiver = event_rx();
|
let receiver = event_rx();
|
||||||
let mut instant: Option<Instant> = None;
|
|
||||||
event_tx().send(Notification)?;
|
event_tx().send(Notification)?;
|
||||||
|
|
||||||
'receiver: for _ in receiver {
|
'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 = BORDER_STATE.lock();
|
||||||
let mut borders_monitors = BORDERS_MONITORS.lock();
|
let mut borders_monitors = BORDERS_MONITORS.lock();
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use std::time::Instant;
|
|||||||
|
|
||||||
use color_eyre::eyre::anyhow;
|
use color_eyre::eyre::anyhow;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
|
use crossbeam_utils::atomic::AtomicConsume;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
use komorebi_core::OperationDirection;
|
use komorebi_core::OperationDirection;
|
||||||
@@ -75,7 +76,32 @@ impl WindowManager {
|
|||||||
// All event handlers below this point should only be processed if the event is
|
// 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.
|
// related to a window that should be managed by the WindowManager.
|
||||||
if !should_manage {
|
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 {
|
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
|
// make it transparent
|
||||||
#[allow(clippy::collapsible_else_if)]
|
#[allow(clippy::collapsible_else_if)]
|
||||||
if idx != ws.focused_container_idx() || monitor_idx != focused_monitor_idx {
|
if idx != ws.focused_container_idx() || monitor_idx != focused_monitor_idx {
|
||||||
let unfocused_window = c.focused_window().copied().unwrap_or_default();
|
let focused_window_idx = c.focused_window_idx();
|
||||||
match unfocused_window.transparent() {
|
for (window_idx, window) in c.windows().iter().enumerate() {
|
||||||
Err(error) => {
|
if window_idx == focused_window_idx {
|
||||||
let hwnd = foreground_hwnd;
|
match window.transparent() {
|
||||||
tracing::error!(
|
Err(error) => {
|
||||||
|
let hwnd = foreground_hwnd;
|
||||||
|
tracing::error!(
|
||||||
"failed to make unfocused window {hwnd} transparent: {error}"
|
"failed to make unfocused window {hwnd} transparent: {error}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Ok(..) => {
|
Ok(..) => {
|
||||||
known_hwnds.lock().push(unfocused_window.hwnd);
|
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
|
// Otherwise, make it opaque
|
||||||
} else {
|
} else {
|
||||||
if let Err(error) = c.focused_window().copied().unwrap_or_default().opaque()
|
let focused_window_idx = c.focused_window_idx();
|
||||||
{
|
for (window_idx, window) in c.windows().iter().enumerate() {
|
||||||
let hwnd = foreground_hwnd;
|
if window_idx != focused_window_idx {
|
||||||
tracing::error!("failed to make focused window {hwnd} opaque: {error}")
|
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