mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-07 03:13:31 +02:00
fix(borders): floating window z-order handling
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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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(¬ification.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 == ¬ification.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;
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
@@ -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() {
|
||||
@@ -436,17 +445,14 @@ 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 {
|
||||
@@ -454,6 +460,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
||||
} else {
|
||||
WindowKind::Single
|
||||
};
|
||||
border.window_kind = new_focus_state;
|
||||
|
||||
// Update the focused state for all containers on this workspace
|
||||
{
|
||||
@@ -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(),
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
if should_destroy {
|
||||
border.destroy()?;
|
||||
borders.remove(&window.hwnd.to_string());
|
||||
borders_monitors.remove(&window.hwnd.to_string());
|
||||
continue 'windows;
|
||||
}
|
||||
|
||||
#[allow(unused_assignments)]
|
||||
let mut last_focus_state = None;
|
||||
let new_focus_state = WindowKind::Floating;
|
||||
let mut new_focus_state = WindowKind::Unfocused;
|
||||
|
||||
if foreground_window == window.hwnd {
|
||||
new_focus_state = WindowKind::Floating;
|
||||
}
|
||||
|
||||
border.window_kind = new_focus_state;
|
||||
{
|
||||
let mut focus_state = FOCUS_STATE.lock();
|
||||
last_focus_state =
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user