Skip to content

Commit

Permalink
fix(transparency): handle stackbar tab clicks
Browse files Browse the repository at this point in the history
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
  • Loading branch information
LGUG2Z committed Jun 4, 2024
1 parent 9a0ee8e commit a488890
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 24 deletions.
11 changes: 0 additions & 11 deletions komorebi/src/border_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

Expand Down
28 changes: 27 additions & 1 deletion komorebi/src/process_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
42 changes: 30 additions & 12 deletions komorebi/src/transparency_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
)
}
}
}
};
}
Expand Down

0 comments on commit a488890

Please sign in to comment.