From aafc52f42d03410fd809064329eedd5e9f7c1956 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Fri, 30 Oct 2026 17:13:08 -0700 Subject: [PATCH] feat(process_command): toggle-float and stack act on a maximized window komorebi for Windows does not ignore them while a window is maximized: toggle-float floats the maximized window, which ends the maximize, and stack left and stack right stack the tiles that are left. The other layout commands stay ignored. The tests that listed the two as ignored say so no more, and two new ones say what they do. --- komorebi/src/process_command.rs | 12 ++++++--- komorebi/tests/maximize_commands.rs | 2 -- komorebi/tests/user_maximize.rs | 38 +++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 6446c300..24d48610 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -332,14 +332,19 @@ pub fn listen_for_commands(wm: Arc>) { } /// Commands that are about the tiles of the layout (moving, stacking, resizing, promoting, -/// locking, floating, the monocle, and sending containers to other monitors and workspaces), which -/// a maximized window has left +/// locking, the monocle, and sending containers to other monitors and workspaces), which a +/// maximized window has left +/// +/// Two commands that look like them are not here, because komorebi for Windows does not ignore +/// them either (`maximizing.user` in the end-to-end suite has them as what both ports do): +/// `toggle-float` floats the maximized window, which ends the maximize +/// ([`Workspace::new_floating_window`](crate::workspace::Workspace::new_floating_window)), and +/// `stack left` and `stack right` stack the tiles that are left. fn is_layout_command(message: &SocketMessage) -> bool { matches!( message, SocketMessage::MoveWindow(_) | SocketMessage::CycleMoveWindow(_) - | SocketMessage::StackWindow(_) | SocketMessage::UnstackWindow | SocketMessage::CycleStack(_) | SocketMessage::CycleStackIndex(_) @@ -354,7 +359,6 @@ fn is_layout_command(message: &SocketMessage) -> bool { | SocketMessage::PromoteFocus | SocketMessage::PromoteWindow(_) | SocketMessage::ToggleLock - | SocketMessage::ToggleFloat | SocketMessage::ToggleMonocle | SocketMessage::MoveContainerToLastWorkspace | SocketMessage::SendContainerToLastWorkspace diff --git a/komorebi/tests/maximize_commands.rs b/komorebi/tests/maximize_commands.rs index ca5f6d9c..67490cef 100644 --- a/komorebi/tests/maximize_commands.rs +++ b/komorebi/tests/maximize_commands.rs @@ -174,7 +174,6 @@ fn while_a_window_is_maximized_what_is_about_the_tiles_does_nothing() { for message in [ SocketMessage::MoveWindow(OperationDirection::Left), SocketMessage::CycleMoveWindow(CycleDirection::Next), - SocketMessage::StackWindow(OperationDirection::Left), SocketMessage::UnstackWindow, SocketMessage::StackAll, SocketMessage::UnstackAll, @@ -187,7 +186,6 @@ fn while_a_window_is_maximized_what_is_about_the_tiles_does_nothing() { SocketMessage::SendContainerToMonitorNumber(1), SocketMessage::Promote, SocketMessage::ToggleLock, - SocketMessage::ToggleFloat, SocketMessage::ToggleMonocle, SocketMessage::PreselectDirection(OperationDirection::Left), ] { diff --git a/komorebi/tests/user_maximize.rs b/komorebi/tests/user_maximize.rs index d4282e83..d44a9c94 100644 --- a/komorebi/tests/user_maximize.rs +++ b/komorebi/tests/user_maximize.rs @@ -114,11 +114,9 @@ fn nothing_that_is_about_the_layout_happens_while_a_window_is_maximized() { for message in [ SocketMessage::MoveWindow(OperationDirection::Left), SocketMessage::MoveWindow(OperationDirection::Right), - SocketMessage::StackWindow(OperationDirection::Left), SocketMessage::UnstackWindow, SocketMessage::StackAll, SocketMessage::Promote, - SocketMessage::ToggleFloat, SocketMessage::ToggleMonocle, SocketMessage::ToggleLock, SocketMessage::SendContainerToWorkspaceNumber(1), @@ -235,3 +233,39 @@ fn a_window_that_opens_maximized_is_the_maximized_one() { assert_eq!(workspace.containers().len(), 2, "the two tiles that were"); assert!(fake.is_maximized(30_113)); } + +#[test] +fn toggle_float_floats_the_window_the_user_maximized_and_ends_the_maximize() { + let (fake, mut wm) = tiled(30_081, 3); + user_maximizes(&fake, &mut wm, 30_082, true); + + command(&fake, &mut wm, SocketMessage::ToggleFloat); + + let workspace = wm.focused_workspace().unwrap(); + assert!(workspace.maximized_window.is_none(), "still maximized"); + assert_eq!( + workspace + .floating_windows() + .iter() + .map(|w| w.id) + .collect::>(), + [30_082] + ); + assert_eq!(workspace.containers().len(), 2); +} + +#[test] +fn stack_left_stacks_the_tiles_that_are_left_while_a_window_is_maximized() { + let (fake, mut wm) = tiled(30_091, 3); + user_maximizes(&fake, &mut wm, 30_092, true); + + command( + &fake, + &mut wm, + SocketMessage::StackWindow(OperationDirection::Left), + ); + + let workspace = wm.focused_workspace().unwrap(); + assert_eq!(workspace.maximized_window.map(|w| w.id), Some(30_092)); + assert_eq!(workspace.containers().len(), 1, "the two tiles are stacked"); +}