mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-07-14 09:02:45 +02:00
feat(wm): floating over monocle
This commit allows for floating windows on the floating workspace layer to be toggled on and off when monocle mode is enabled on a workspace.
This commit is contained in:
@@ -6,6 +6,7 @@ use crate::core::BorderStyle;
|
|||||||
use crate::core::WindowKind;
|
use crate::core::WindowKind;
|
||||||
use crate::ring::Ring;
|
use crate::ring::Ring;
|
||||||
use crate::windows_api;
|
use crate::windows_api;
|
||||||
|
use crate::workspace::Workspace;
|
||||||
use crate::workspace::WorkspaceLayer;
|
use crate::workspace::WorkspaceLayer;
|
||||||
use crate::WindowManager;
|
use crate::WindowManager;
|
||||||
use crate::WindowsApi;
|
use crate::WindowsApi;
|
||||||
@@ -212,6 +213,8 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
[focused_workspace_idx]
|
[focused_workspace_idx]
|
||||||
.layer();
|
.layer();
|
||||||
let foreground_window = WindowsApi::foreground_window().unwrap_or_default();
|
let foreground_window = WindowsApi::foreground_window().unwrap_or_default();
|
||||||
|
let layer_changed = previous_layer != workspace_layer;
|
||||||
|
let forced_update = matches!(notification, Notification::ForceUpdate);
|
||||||
|
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
@@ -234,6 +237,17 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.set_accent(window_kind_colour(window_kind))?;
|
.set_accent(window_kind_colour(window_kind))?;
|
||||||
|
|
||||||
|
if ws.layer() == &WorkspaceLayer::Floating {
|
||||||
|
for window in ws.floating_windows() {
|
||||||
|
let mut window_kind = WindowKind::Unfocused;
|
||||||
|
|
||||||
|
if foreground_window == window.hwnd {
|
||||||
|
window_kind = WindowKind::Floating;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.set_accent(window_kind_colour(window_kind))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
continue 'monitors;
|
continue 'monitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,6 +462,32 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
windows_borders.insert(focused_window_hwnd, id);
|
windows_borders.insert(focused_window_hwnd, id);
|
||||||
|
|
||||||
let border_hwnd = border.hwnd;
|
let border_hwnd = border.hwnd;
|
||||||
|
|
||||||
|
if ws.layer() == &WorkspaceLayer::Floating {
|
||||||
|
handle_floating_borders(
|
||||||
|
&mut borders,
|
||||||
|
&mut windows_borders,
|
||||||
|
ws,
|
||||||
|
monitor_idx,
|
||||||
|
foreground_window,
|
||||||
|
layer_changed,
|
||||||
|
forced_update,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Remove all borders on this monitor except monocle and floating borders
|
||||||
|
remove_borders(
|
||||||
|
&mut borders,
|
||||||
|
&mut windows_borders,
|
||||||
|
monitor_idx,
|
||||||
|
|_, b| {
|
||||||
|
border_hwnd != b.hwnd
|
||||||
|
&& !ws
|
||||||
|
.floating_windows()
|
||||||
|
.iter()
|
||||||
|
.any(|w| w.hwnd == b.tracking_hwnd)
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
// Remove all borders on this monitor except monocle
|
// Remove all borders on this monitor except monocle
|
||||||
remove_borders(
|
remove_borders(
|
||||||
&mut borders,
|
&mut borders,
|
||||||
@@ -455,7 +495,7 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
monitor_idx,
|
monitor_idx,
|
||||||
|_, b| border_hwnd != b.hwnd,
|
|_, b| border_hwnd != b.hwnd,
|
||||||
)?;
|
)?;
|
||||||
|
}
|
||||||
continue 'monitors;
|
continue 'monitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,9 +609,6 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
};
|
};
|
||||||
border.window_rect = rect;
|
border.window_rect = rect;
|
||||||
|
|
||||||
let layer_changed = previous_layer != workspace_layer;
|
|
||||||
let forced_update = matches!(notification, Notification::ForceUpdate);
|
|
||||||
|
|
||||||
let should_invalidate = new_border
|
let should_invalidate = new_border
|
||||||
|| (last_focus_state != new_focus_state)
|
|| (last_focus_state != new_focus_state)
|
||||||
|| layer_changed
|
|| layer_changed
|
||||||
@@ -591,22 +628,52 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
windows_borders.insert(focused_window_hwnd, id);
|
windows_borders.insert(focused_window_hwnd, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
handle_floating_borders(
|
||||||
|
&mut borders,
|
||||||
|
&mut windows_borders,
|
||||||
|
ws,
|
||||||
|
monitor_idx,
|
||||||
|
foreground_window,
|
||||||
|
layer_changed,
|
||||||
|
forced_update,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previous_snapshot = monitors;
|
||||||
|
previous_pending_move_op = pending_move_op;
|
||||||
|
previous_is_paused = is_paused;
|
||||||
|
previous_notification = Some(notification);
|
||||||
|
previous_layer = workspace_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_floating_borders(
|
||||||
|
borders: &mut HashMap<String, Box<Border>>,
|
||||||
|
windows_borders: &mut HashMap<isize, String>,
|
||||||
|
ws: &Workspace,
|
||||||
|
monitor_idx: usize,
|
||||||
|
foreground_window: isize,
|
||||||
|
layer_changed: bool,
|
||||||
|
forced_update: bool,
|
||||||
|
) -> color_eyre::Result<()> {
|
||||||
for window in ws.floating_windows() {
|
for window in ws.floating_windows() {
|
||||||
let mut new_border = false;
|
let mut new_border = false;
|
||||||
let id = window.hwnd.to_string();
|
let id = window.hwnd.to_string();
|
||||||
let border = match borders.entry(id.clone()) {
|
let border = match borders.entry(id.clone()) {
|
||||||
Entry::Occupied(entry) => entry.into_mut(),
|
Entry::Occupied(entry) => entry.into_mut(),
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
if let Ok(border) = Border::create(
|
if let Ok(border) =
|
||||||
&window.hwnd.to_string(),
|
Border::create(&window.hwnd.to_string(), window.hwnd, monitor_idx)
|
||||||
window.hwnd,
|
{
|
||||||
monitor_idx,
|
|
||||||
) {
|
|
||||||
new_border = true;
|
new_border = true;
|
||||||
entry.insert(border)
|
entry.insert(border)
|
||||||
} else {
|
} else {
|
||||||
continue 'monitors;
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -627,14 +694,8 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
let rect = WindowsApi::window_rect(window.hwnd)?;
|
let rect = WindowsApi::window_rect(window.hwnd)?;
|
||||||
border.window_rect = rect;
|
border.window_rect = rect;
|
||||||
|
|
||||||
let layer_changed = previous_layer != workspace_layer;
|
let should_invalidate =
|
||||||
let forced_update =
|
new_border || (last_focus_state != new_focus_state) || layer_changed || forced_update;
|
||||||
matches!(notification, Notification::ForceUpdate);
|
|
||||||
|
|
||||||
let should_invalidate = new_border
|
|
||||||
|| (last_focus_state != new_focus_state)
|
|
||||||
|| layer_changed
|
|
||||||
|| forced_update;
|
|
||||||
|
|
||||||
if should_invalidate {
|
if should_invalidate {
|
||||||
if forced_update && !new_border {
|
if forced_update && !new_border {
|
||||||
@@ -649,18 +710,6 @@ pub fn handle_notifications(wm: Arc<Mutex<WindowManager>>) -> color_eyre::Result
|
|||||||
|
|
||||||
windows_borders.insert(window.hwnd, id);
|
windows_borders.insert(window.hwnd, id);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
previous_snapshot = monitors;
|
|
||||||
previous_pending_move_op = pending_move_op;
|
|
||||||
previous_is_paused = is_paused;
|
|
||||||
previous_notification = Some(notification);
|
|
||||||
previous_layer = workspace_layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1281,6 +1281,7 @@ impl WindowManager {
|
|||||||
if i == focused_idx {
|
if i == focused_idx {
|
||||||
to_focus = Some(*window);
|
to_focus = Some(*window);
|
||||||
} else {
|
} else {
|
||||||
|
window.restore();
|
||||||
window.raise()?;
|
window.raise()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1288,6 +1289,7 @@ impl WindowManager {
|
|||||||
if let Some(focused_window) = &to_focus {
|
if let Some(focused_window) = &to_focus {
|
||||||
// The focused window should be the last one raised to make sure it is
|
// The focused window should be the last one raised to make sure it is
|
||||||
// on top
|
// on top
|
||||||
|
focused_window.restore();
|
||||||
focused_window.raise()?;
|
focused_window.raise()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1296,12 +1298,28 @@ impl WindowManager {
|
|||||||
window.lower()?;
|
window.lower()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(monocle) = workspace.monocle_container() {
|
||||||
|
if let Some(window) = monocle.focused_window() {
|
||||||
|
window.lower()?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WorkspaceLayer::Floating => {
|
WorkspaceLayer::Floating => {
|
||||||
workspace.set_layer(WorkspaceLayer::Tiling);
|
workspace.set_layer(WorkspaceLayer::Tiling);
|
||||||
|
|
||||||
|
if let Some(monocle) = workspace.monocle_container() {
|
||||||
|
if let Some(window) = monocle.focused_window() {
|
||||||
|
to_focus = Some(*window);
|
||||||
|
window.raise()?;
|
||||||
|
}
|
||||||
|
for window in workspace.floating_windows() {
|
||||||
|
window.hide();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
let focused_container_idx = workspace.focused_container_idx();
|
let focused_container_idx = workspace.focused_container_idx();
|
||||||
for (i, container) in workspace.containers_mut().iter_mut().enumerate() {
|
for (i, container) in workspace.containers_mut().iter_mut().enumerate()
|
||||||
|
{
|
||||||
if let Some(window) = container.focused_window() {
|
if let Some(window) = container.focused_window() {
|
||||||
if i == focused_container_idx {
|
if i == focused_container_idx {
|
||||||
to_focus = Some(*window);
|
to_focus = Some(*window);
|
||||||
@@ -1326,6 +1344,7 @@ impl WindowManager {
|
|||||||
window.lower()?;
|
window.lower()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if let Some(window) = to_focus {
|
if let Some(window) = to_focus {
|
||||||
window.focus(mouse_follows_focus)?;
|
window.focus(mouse_follows_focus)?;
|
||||||
|
|||||||
@@ -500,7 +500,11 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !monocle_window_event && monocle_container.is_some() {
|
let workspace = self.focused_workspace()?;
|
||||||
|
if !(monocle_window_event
|
||||||
|
|| workspace.layer() != &WorkspaceLayer::Tiling)
|
||||||
|
&& monocle_container.is_some()
|
||||||
|
{
|
||||||
window.hide();
|
window.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user