Skip to content

Commit

Permalink
fix(borders): floating window z-order handling
Browse files Browse the repository at this point in the history
This commit makes it so a floating window only has the floating border
when it is focused, if not it has the `Unfocused` border. It also makes
the 'focused_container' have the `Unfocused` border when it is not the
foreground window, for example when we have a floating window focused
instead.

This commit also changes the border's `window_kind` so that the stored
borders actually have that value so we can check it later (This value
wasn't being updated).

This commit also makes it so we properly invalidate the borders in the
situations discussed above (for example when changing focus to/from a
floating window we need the floating window border to update its ZOrder
as well as the previously focused window).

Lastly this commit, changes the `WM_PAINT` code part of the border so
that it now sets the position of border so that the border's ZOrder
updates to it's tracking window ZOrder.
  • Loading branch information
alex-ds13 authored and LGUG2Z committed Dec 9, 2024
1 parent 192af67 commit 26f90cc
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 49 deletions.
12 changes: 12 additions & 0 deletions komorebi/src/border_manager/border.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,18 @@ impl Border {
return LRESULT(0);
}

let reference_hwnd = (*border_pointer).tracking_hwnd;

// Update position to update the ZOrder
let border_window_rect = (*border_pointer).window_rect;

tracing::trace!("updating border position");
if let Err(error) =
(*border_pointer).set_position(&border_window_rect, reference_hwnd)
{
tracing::error!("failed to update border position {error}");
}

if let Some(render_target) = (*border_pointer).render_target.get() {
(*border_pointer).width = BORDER_WIDTH.load(Ordering::Relaxed);
(*border_pointer).offset = BORDER_OFFSET.load(Ordering::Relaxed);
Expand Down
96 changes: 47 additions & 49 deletions komorebi/src/border_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
.iter()
.map(|w| w.hwnd)
.collect::<Vec<_>>();
let foreground_window = WindowsApi::foreground_window().unwrap_or_default();

drop(state);

Expand Down Expand Up @@ -238,10 +239,19 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
should_process_notification = true;
}

// when we switch focus to a floating window
if !should_process_notification
&& floating_window_hwnds.contains(&notification.0.unwrap_or_default())
{
// when we switch focus to/from a floating window
let switch_focus_to_from_floating_window = floating_window_hwnds.iter().any(|fw| {
// if we switch focus to a floating window
fw == &notification.0.unwrap_or_default() ||
// if there is any floating window with a `WindowKind::Floating` border
// that no longer is the foreground window then we need to update that
// border.
(fw != &foreground_window
&& window_border(*fw)
.map(|b| b.window_kind == WindowKind::Floating)
.unwrap_or_default())
});
if !should_process_notification && switch_focus_to_from_floating_window {
should_process_notification = true;
}

Expand Down Expand Up @@ -321,22 +331,15 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
}
};

borders_monitors.insert(monocle.id().clone(), monitor_idx);
windows_borders.insert(
monocle.focused_window().cloned().unwrap_or_default().hwnd,
border.clone(),
);

let new_focus_state = if monitor_idx != focused_monitor_idx {
WindowKind::Unfocused
} else {
WindowKind::Monocle
};
border.window_kind = new_focus_state;
{
let mut focus_state = FOCUS_STATE.lock();
focus_state.insert(
border.hwnd,
if monitor_idx != focused_monitor_idx {
WindowKind::Unfocused
} else {
WindowKind::Monocle
},
);
focus_state.insert(border.hwnd, new_focus_state);
}

let reference_hwnd =
Expand All @@ -350,6 +353,12 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result

border.invalidate();

borders_monitors.insert(monocle.id().clone(), monitor_idx);
windows_borders.insert(
monocle.focused_window().cloned().unwrap_or_default().hwnd,
border.clone(),
);

let border_hwnd = border.hwnd;
let mut to_remove = vec![];
for (id, b) in borders.iter() {
Expand Down Expand Up @@ -436,24 +445,22 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
}
};

borders_monitors.insert(c.id().clone(), monitor_idx);
windows_borders.insert(
c.focused_window().cloned().unwrap_or_default().hwnd,
border.clone(),
);

#[allow(unused_assignments)]
let mut last_focus_state = None;

let new_focus_state = if idx != ws.focused_container_idx()
|| monitor_idx != focused_monitor_idx
|| c.focused_window()
.map(|w| w.hwnd != foreground_window)
.unwrap_or_default()
{
WindowKind::Unfocused
} else if c.windows().len() > 1 {
WindowKind::Stack
} else {
WindowKind::Single
};
border.window_kind = new_focus_state;

// Update the focused state for all containers on this workspace
{
Expand All @@ -478,10 +485,16 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
if should_invalidate {
border.invalidate();
}

borders_monitors.insert(c.id().clone(), monitor_idx);
windows_borders.insert(
c.focused_window().cloned().unwrap_or_default().hwnd,
border.clone(),
);
}

{
'windows: for window in ws.floating_windows() {
for window in ws.floating_windows() {
let mut new_border = false;
let border = match borders.entry(window.hwnd.to_string()) {
Entry::Occupied(entry) => entry.into_mut(),
Expand All @@ -497,33 +510,15 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
}
};

borders_monitors.insert(window.hwnd.to_string(), monitor_idx);
windows_borders.insert(window.hwnd, border.clone());

let mut should_destroy = false;

if let Some(notification_hwnd) = notification.0 {
if notification_hwnd != window.hwnd {
should_destroy = true;
}
}

if WindowsApi::foreground_window().unwrap_or_default()
!= window.hwnd
{
should_destroy = true;
}
#[allow(unused_assignments)]
let mut last_focus_state = None;
let mut new_focus_state = WindowKind::Unfocused;

if should_destroy {
border.destroy()?;
borders.remove(&window.hwnd.to_string());
borders_monitors.remove(&window.hwnd.to_string());
continue 'windows;
if foreground_window == window.hwnd {
new_focus_state = WindowKind::Floating;
}

#[allow(unused_assignments)]
let mut last_focus_state = None;
let new_focus_state = WindowKind::Floating;
border.window_kind = new_focus_state;
{
let mut focus_state = FOCUS_STATE.lock();
last_focus_state =
Expand All @@ -544,6 +539,9 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
if should_invalidate {
border.invalidate();
}

borders_monitors.insert(window.hwnd.to_string(), monitor_idx);
windows_borders.insert(window.hwnd, border.clone());
}
}
}
Expand Down

0 comments on commit 26f90cc

Please sign in to comment.