refactor(windows): Windows router arms call the shared window, named-workspace and toggle commands

The arms MoveWindow, FocusWindow, CycleFocusWindow, PreselectDirection,
CancelPreselect, PromoteWindow, FocusNamedWorkspace,
MoveContainerToNamedWorkspace, SendContainerToNamedWorkspace,
ToggleWindowContainerBehaviour, ToggleCrossMonitorMoveBehaviour and
ToggleMonocleFocusBehaviour are one call each into komorebi_core::command
(12 arms; the 16 of the earlier batch are already there). The Windows
WindowManager implements WindowCommandHost (thin forwards to its own
direction functions, and Workspace::update) and BehaviourCommandHost (its
three settings). The arm text was identical on all three daemons, so the
same functions are called in the same order. Two small differences: a
missing workspace is reported as "there is no workspace" by the shared
code, and the named lookup is a shared function instead of
WindowManager::monitor_workspace_index_by_name (which stays for its other
callers).

BEHAVIOUR (expected none; marked because arms moved): Windows e2e commands, workspaces, focus, stacking and monocle scenarios (the gated functions are called as before).
Verified: cargo clippy -p komorebi-windows --all-targets -D warnings passes; tools/format-all --check clean. Windows tests and e2e cannot run on Linux.
This commit is contained in:
LGUG2Z committed 2026-11-05 15:03:27 -08:00
1 parent 596271c38b
commit 491707469b
1 file changed
+102 -106
+102 -106
View File
@@ -59,8 +59,6 @@ use crate::core::CycleDirection;
use crate::core::FocusFollowsMouseImplementation;
use crate::core::Layout;
use crate::core::LayoutOptions;
use crate::core::MonocleFocusBehaviour;
use crate::core::MoveBehaviour;
use crate::core::OperationDirection;
use crate::core::Rect;
use crate::core::Sizing;
@@ -359,66 +357,19 @@ impl WindowManager {
SocketMessage::PromoteSwap => self.promote_container_swap()?,
SocketMessage::PromoteFocus => self.promote_focus_to_front()?,
SocketMessage::PromoteWindow(direction) => {
self.focus_container_in_direction(direction)?;
self.promote_container_to_front()?
komorebi_core::promote_window(self, direction)?
}
SocketMessage::EagerFocus(ref exe) => {
self.eager_focus(exe)?;
}
SocketMessage::FocusWindow(direction) => {
let focused_workspace = self.focused_workspace()?;
match focused_workspace.layer {
WorkspaceLayer::Tiling => {
self.focus_container_in_direction(direction)?;
}
WorkspaceLayer::Floating => {
self.focus_floating_window_in_direction(direction)?;
}
}
}
SocketMessage::FocusWindow(direction) => komorebi_core::focus_window(self, direction)?,
SocketMessage::PreselectDirection(direction) => {
let focused_workspace = self.focused_workspace()?;
let mut update = false;
if focused_workspace.preselected_container_idx.is_some() {
tracing::warn!(
"ignoring command as this workspace already has a direction preselect set"
);
} else if matches!(focused_workspace.layer, WorkspaceLayer::Tiling) {
self.preselect_container_in_direction(direction)?;
update = true;
}
if update {
self.focused_workspace_mut()?.update()?;
}
}
SocketMessage::CancelPreselect => {
let focused_workspace = self.focused_workspace_mut()?;
focused_workspace.cancel_preselect();
focused_workspace.update()?;
}
SocketMessage::MoveWindow(direction) => {
let focused_workspace = self.focused_workspace()?;
match focused_workspace.layer {
WorkspaceLayer::Tiling => {
self.move_container_in_direction(direction)?;
}
WorkspaceLayer::Floating => {
self.move_floating_window_in_direction(direction)?;
}
}
komorebi_core::preselect_direction(self, direction)?
}
SocketMessage::CancelPreselect => komorebi_core::cancel_preselect(self)?,
SocketMessage::MoveWindow(direction) => komorebi_core::move_window(self, direction)?,
SocketMessage::CycleFocusWindow(direction) => {
let focused_workspace = self.focused_workspace()?;
match focused_workspace.layer {
WorkspaceLayer::Tiling => {
self.focus_container_in_cycle_direction(direction)?;
}
WorkspaceLayer::Floating => {
self.focus_floating_window_in_cycle_direction(direction)?;
}
}
komorebi_core::cycle_focus_window(self, direction)?
}
SocketMessage::CycleMoveWindow(direction) => {
self.move_container_in_cycle_direction(direction)?;
@@ -706,30 +657,10 @@ impl WindowManager {
)?
}
SocketMessage::SendContainerToNamedWorkspace(ref workspace) => {
if let Some((monitor_idx, workspace_idx)) =
self.monitor_workspace_index_by_name(workspace)
{
let direction = self.direction_from_monitor_idx(monitor_idx);
self.move_container_to_monitor(
monitor_idx,
Option::from(workspace_idx),
false,
direction,
)?;
}
komorebi_core::move_container_to_named_workspace(self, workspace, false)?
}
SocketMessage::MoveContainerToNamedWorkspace(ref workspace) => {
if let Some((monitor_idx, workspace_idx)) =
self.monitor_workspace_index_by_name(workspace)
{
let direction = self.direction_from_monitor_idx(monitor_idx);
self.move_container_to_monitor(
monitor_idx,
Option::from(workspace_idx),
true,
direction,
)?;
}
komorebi_core::move_container_to_named_workspace(self, workspace, true)?
}
SocketMessage::MoveWorkspaceToMonitorNumber(monitor_idx) => {
@@ -936,12 +867,7 @@ impl WindowManager {
komorebi_core::focus_monitor_workspace_number(self, monitor_idx, workspace_idx)?
}
SocketMessage::FocusNamedWorkspace(ref name) => {
if let Some((monitor_idx, workspace_idx)) =
self.monitor_workspace_index_by_name(name)
{
self.focus_monitor(monitor_idx)?;
self.focus_workspace(workspace_idx)?;
}
komorebi_core::focus_named_workspace(self, name)?
}
SocketMessage::ToggleWorkspaceLayer => {
self.toggle_workspace_layer()?;
@@ -1211,16 +1137,7 @@ impl WindowManager {
self.resize_delta = delta;
}
SocketMessage::ToggleWindowContainerBehaviour => {
match self.window_management_behaviour.current_behaviour {
WindowContainerBehaviour::Create => {
self.window_management_behaviour.current_behaviour =
WindowContainerBehaviour::Append;
}
WindowContainerBehaviour::Append => {
self.window_management_behaviour.current_behaviour =
WindowContainerBehaviour::Create;
}
}
komorebi_core::toggle_window_container_behaviour(self)
}
SocketMessage::ToggleFloatOverride => {
self.window_management_behaviour.float_override =
@@ -1260,24 +1177,13 @@ impl WindowManager {
*hiding_behaviour = behaviour;
}
SocketMessage::ToggleCrossMonitorMoveBehaviour => {
match self.cross_monitor_move_behaviour {
MoveBehaviour::Swap => {
self.cross_monitor_move_behaviour = MoveBehaviour::Insert;
}
MoveBehaviour::Insert => {
self.cross_monitor_move_behaviour = MoveBehaviour::Swap;
}
_ => {}
}
komorebi_core::toggle_cross_monitor_move_behaviour(self)
}
SocketMessage::CrossMonitorMoveBehaviour(behaviour) => {
self.cross_monitor_move_behaviour = behaviour;
}
SocketMessage::ToggleMonocleFocusBehaviour => {
self.monocle_focus_behaviour = match self.monocle_focus_behaviour {
MonocleFocusBehaviour::Cycle => MonocleFocusBehaviour::NoOp,
MonocleFocusBehaviour::NoOp => MonocleFocusBehaviour::Cycle,
};
komorebi_core::toggle_monocle_focus_behaviour(self)
}
SocketMessage::MonocleFocusBehaviour(behaviour) => {
self.monocle_focus_behaviour = behaviour;
@@ -2343,6 +2249,96 @@ impl komorebi_core::ContainerCommandHost for WindowManager {
}
}
/// The window manager as the window commands of `komorebi_core::command` see it
impl komorebi_core::WindowCommandHost for WindowManager {
fn move_container_in_direction(&mut self, direction: OperationDirection) -> eyre::Result<()> {
WindowManager::move_container_in_direction(self, direction)
}
fn move_floating_window_in_direction(
&mut self,
direction: OperationDirection,
) -> eyre::Result<()> {
WindowManager::move_floating_window_in_direction(self, direction)
}
fn focus_container_in_direction(&mut self, direction: OperationDirection) -> eyre::Result<()> {
WindowManager::focus_container_in_direction(self, direction)
}
fn focus_floating_window_in_direction(
&mut self,
direction: OperationDirection,
) -> eyre::Result<()> {
WindowManager::focus_floating_window_in_direction(self, direction)
}
fn focus_container_in_cycle_direction(
&mut self,
direction: CycleDirection,
) -> eyre::Result<()> {
WindowManager::focus_container_in_cycle_direction(self, direction)
}
fn focus_floating_window_in_cycle_direction(
&mut self,
direction: CycleDirection,
) -> eyre::Result<()> {
WindowManager::focus_floating_window_in_cycle_direction(self, direction)
}
fn preselect_container_in_direction(
&mut self,
direction: OperationDirection,
) -> eyre::Result<()> {
WindowManager::preselect_container_in_direction(self, direction)
}
fn promote_container_to_front(&mut self) -> eyre::Result<()> {
WindowManager::promote_container_to_front(self)
}
fn update_focused_workspace_layout(&mut self) -> eyre::Result<()> {
self.focused_workspace_mut()?.update()
}
}
/// The window manager as the behaviour toggles of `komorebi_core::command` see it
impl komorebi_core::BehaviourCommandHost for WindowManager {
fn window_container_behaviour(&self) -> komorebi_config::behaviour::WindowContainerBehaviour {
self.window_management_behaviour.current_behaviour
}
fn set_window_container_behaviour(
&mut self,
behaviour: komorebi_config::behaviour::WindowContainerBehaviour,
) {
self.window_management_behaviour.current_behaviour = behaviour;
}
fn cross_monitor_move_behaviour(&self) -> komorebi_protocol::types::MoveBehaviour {
self.cross_monitor_move_behaviour
}
fn set_cross_monitor_move_behaviour(
&mut self,
behaviour: komorebi_protocol::types::MoveBehaviour,
) {
self.cross_monitor_move_behaviour = behaviour;
}
fn monocle_focus_behaviour(&self) -> komorebi_protocol::types::MonocleFocusBehaviour {
self.monocle_focus_behaviour
}
fn set_monocle_focus_behaviour(
&mut self,
behaviour: komorebi_protocol::types::MonocleFocusBehaviour,
) {
self.monocle_focus_behaviour = behaviour;
}
}
#[cfg(test)]
mod tests {
use super::push_simple_rule;