diff --git a/GlazeWM.Domain/Common/Enums/TilingDirection.cs b/GlazeWM.Domain/Common/Enums/TilingDirection.cs index aa80428b..dbce6f0a 100644 --- a/GlazeWM.Domain/Common/Enums/TilingDirection.cs +++ b/GlazeWM.Domain/Common/Enums/TilingDirection.cs @@ -1,3 +1,5 @@ +using System; + namespace GlazeWM.Domain.Common.Enums { public enum TilingDirection @@ -5,4 +7,21 @@ public enum TilingDirection Vertical, Horizontal, } + + public static class TilingDirectionExtensions + { + /// + /// Get the inverse of a given tiling direction. + /// + /// + public static TilingDirection Inverse(this TilingDirection tilingDirection) + { + return tilingDirection switch + { + TilingDirection.Vertical => TilingDirection.Horizontal, + TilingDirection.Horizontal => TilingDirection.Vertical, + _ => throw new ArgumentOutOfRangeException(nameof(tilingDirection)), + }; + } + } } diff --git a/GlazeWM.Domain/Containers/CommandHandlers/AttachAndResizeContainerHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/AttachAndResizeContainerHandler.cs deleted file mode 100644 index 649968dd..00000000 --- a/GlazeWM.Domain/Containers/CommandHandlers/AttachAndResizeContainerHandler.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Linq; -using GlazeWM.Domain.Containers.Commands; -using GlazeWM.Infrastructure.Bussing; - -namespace GlazeWM.Domain.Containers.CommandHandlers -{ - internal sealed class AttachAndResizeContainerHandler : ICommandHandler - { - private readonly Bus _bus; - - public AttachAndResizeContainerHandler(Bus bus) - { - _bus = bus; - } - - public CommandResponse Handle(AttachAndResizeContainerCommand command) - { - var childToAdd = command.ChildToAdd; - var targetParent = command.TargetParent; - var targetIndex = command.TargetIndex; - - if (childToAdd is not IResizable) - throw new Exception("Cannot resize a non-resizable container. This is a bug."); - - _bus.Invoke(new AttachContainerCommand(childToAdd, targetParent, targetIndex)); - - var resizableSiblings = childToAdd.SiblingsOfType(); - - if (!resizableSiblings.Any()) - { - (childToAdd as IResizable).SizePercentage = 1; - return CommandResponse.Ok; - } - - var defaultPercent = 1.0 / (resizableSiblings.Count() + 1); - - // Set initial size percentage to 0, and then size up the container to `defaultPercent`. - (childToAdd as IResizable).SizePercentage = 0; - _bus.Invoke(new ResizeContainerCommand(childToAdd, defaultPercent)); - - return CommandResponse.Ok; - } - } -} diff --git a/GlazeWM.Domain/Containers/CommandHandlers/AttachContainerHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/AttachContainerHandler.cs index bfd2b855..8cfda404 100644 --- a/GlazeWM.Domain/Containers/CommandHandlers/AttachContainerHandler.cs +++ b/GlazeWM.Domain/Containers/CommandHandlers/AttachContainerHandler.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using GlazeWM.Domain.Containers.Commands; using GlazeWM.Infrastructure.Bussing; @@ -6,10 +7,12 @@ namespace GlazeWM.Domain.Containers.CommandHandlers { internal sealed class AttachContainerHandler : ICommandHandler { + private readonly Bus _bus; private readonly ContainerService _containerService; - public AttachContainerHandler(ContainerService containerService) + public AttachContainerHandler(Bus bus, ContainerService containerService) { + _bus = bus; _containerService = containerService; } @@ -22,13 +25,31 @@ public CommandResponse Handle(AttachContainerCommand command) if (!childToAdd.IsDetached()) throw new Exception("Cannot attach an already attached container. This is a bug."); - childToAdd.Parent = targetParent; - targetParent.Children.Insert(targetIndex, childToAdd); - targetParent.ChildFocusOrder.Add(childToAdd); + targetParent.InsertChild(targetIndex, childToAdd); + + if (childToAdd is IResizable) + ResizeAttachedContainer(childToAdd); _containerService.ContainersToRedraw.Add(targetParent); return CommandResponse.Ok; } + + public void ResizeAttachedContainer(Container attachedContainer) + { + var resizableSiblings = attachedContainer.SiblingsOfType(); + + if (!resizableSiblings.Any()) + { + (attachedContainer as IResizable).SizePercentage = 1; + return; + } + + var defaultPercent = 1.0 / (resizableSiblings.Count() + 1); + + // Set initial size percentage to 0, and then size up the container to `defaultPercent`. + (attachedContainer as IResizable).SizePercentage = 0; + _bus.Invoke(new ResizeContainerCommand(attachedContainer, defaultPercent)); + } } } diff --git a/GlazeWM.Domain/Containers/CommandHandlers/ChangeTilingDirectionHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/ChangeTilingDirectionHandler.cs index 641ad969..61a87ecb 100644 --- a/GlazeWM.Domain/Containers/CommandHandlers/ChangeTilingDirectionHandler.cs +++ b/GlazeWM.Domain/Containers/CommandHandlers/ChangeTilingDirectionHandler.cs @@ -70,10 +70,10 @@ private void ChangeWindowTilingDirection( // the split container after the replacement. _bus.Invoke(new ReplaceContainerCommand(splitContainer, parent, window.Index)); - // The child window takes up the full size of its parent split container. + // Add the window as a child of the split container and ensure it takes up the full size + // of its parent split container. + splitContainer.InsertChild(0, window); (window as IResizable).SizePercentage = 1; - _bus.Invoke(new DetachContainerCommand(window)); - _bus.Invoke(new AttachContainerCommand(window, splitContainer)); } private void ChangeWorkspaceTilingDirection( diff --git a/GlazeWM.Domain/Containers/CommandHandlers/DetachAndResizeContainerHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/DetachAndResizeContainerHandler.cs deleted file mode 100644 index 88c5eb37..00000000 --- a/GlazeWM.Domain/Containers/CommandHandlers/DetachAndResizeContainerHandler.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Linq; -using GlazeWM.Domain.Containers.Commands; -using GlazeWM.Domain.Workspaces; -using GlazeWM.Infrastructure.Bussing; - -namespace GlazeWM.Domain.Containers.CommandHandlers -{ - internal sealed class DetachAndResizeContainerHandler : ICommandHandler - { - private readonly Bus _bus; - - public DetachAndResizeContainerHandler(Bus bus) - { - _bus = bus; - } - - public CommandResponse Handle(DetachAndResizeContainerCommand command) - { - var childToRemove = command.ChildToRemove; - var parent = childToRemove.Parent; - var grandparent = parent.Parent; - - if (childToRemove is not IResizable) - throw new Exception("Cannot resize a non-resizable container. This is a bug."); - - var isEmptySplitContainer = - parent is SplitContainer && - parent.Children.Count == 1 && - parent is not Workspace; - - // Get the freed up space after container is detached. - var availableSizePercentage = isEmptySplitContainer - ? (parent as IResizable).SizePercentage - : (childToRemove as IResizable).SizePercentage; - - // Resize children of grandparent if `childToRemove`'s parent is also to be detached. - var containersToResize = isEmptySplitContainer - ? grandparent.ChildrenOfType() - : parent.ChildrenOfType(); - - _bus.Invoke(new DetachContainerCommand(childToRemove)); - - var sizePercentageIncrement = availableSizePercentage / containersToResize.Count(); - - // Adjust `SizePercentage` of the siblings of the removed container. - foreach (var containerToResize in containersToResize) - { - ((IResizable)containerToResize).SizePercentage += sizePercentageIncrement; - } - - return CommandResponse.Ok; - } - } -} diff --git a/GlazeWM.Domain/Containers/CommandHandlers/DetachContainerHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/DetachContainerHandler.cs index 26960cc2..6bd66417 100644 --- a/GlazeWM.Domain/Containers/CommandHandlers/DetachContainerHandler.cs +++ b/GlazeWM.Domain/Containers/CommandHandlers/DetachContainerHandler.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using GlazeWM.Domain.Containers.Commands; using GlazeWM.Domain.Workspaces; using GlazeWM.Infrastructure.Bussing; @@ -20,26 +21,63 @@ public CommandResponse Handle(DetachContainerCommand command) { var childToRemove = command.ChildToRemove; var parent = childToRemove.Parent; + var grandparent = parent.Parent; + var siblings = childToRemove.Siblings; if (parent == null) throw new Exception("Cannot detach an already detached container. This is a bug."); - childToRemove.Parent = null; - parent.Children.Remove(childToRemove); - parent.ChildFocusOrder.Remove(childToRemove); + parent.RemoveChild(childToRemove); - var isEmptySplitContainer = parent is SplitContainer && !parent.HasChildren() - && parent is not Workspace; + var parentSiblings = parent.Siblings; + var isEmptySplitContainer = + !parent.HasChildren() && parent is SplitContainer and not Workspace; - // If the parent of the removed child is an empty split container, detach the split container - // as well. + // Get the freed up space after container is detached. + var availableSizePercentage = isEmptySplitContainer + ? (parent as IResizable).SizePercentage + : (childToRemove as IResizable)?.SizePercentage ?? 0; + + // Resize children of grandparent if `childToRemove`'s parent is also to be detached. + var containersToResize = isEmptySplitContainer + ? grandparent.ChildrenOfType() + : parent.ChildrenOfType(); + + // If the parent of the removed child is now an empty split container, detach the + // split container as well. + // TODO: Move out calls to `ContainersToRedraw.Add(...)`, since detaching might not + // always require a redraw. if (isEmptySplitContainer) { - _bus.Invoke(new DetachContainerCommand(parent)); - return CommandResponse.Ok; + _containerService.ContainersToRedraw.Add(parent.Parent); + grandparent.RemoveChild(parent); + } + else + _containerService.ContainersToRedraw.Add(parent); + + if (availableSizePercentage != 0) + { + var sizePercentageIncrement = availableSizePercentage / containersToResize.Count(); + + // Adjust `SizePercentage` of the siblings of the removed container. + foreach (var containerToResize in containersToResize) + ((IResizable)containerToResize).SizePercentage += sizePercentageIncrement; } - _containerService.ContainersToRedraw.Add(parent); + var detachedSiblings = isEmptySplitContainer ? parentSiblings : siblings; + var detachedParent = isEmptySplitContainer ? grandparent : parent; + + // If there is exactly *one* sibling to the detached container, then flatten that + // sibling if it's a split container. This is to handle layouts like H[1 V[2 H[3]]], + // where container 2 gets detached. + if (detachedSiblings.Count() == 1 && detachedSiblings.ElementAt(0) is SplitContainer && childToRemove is not Workspace) + { + _bus.Invoke( + new FlattenSplitContainerCommand(detachedSiblings.ElementAt(0) as SplitContainer) + ); + + _bus.Invoke(new FlattenSplitContainerCommand(detachedParent as SplitContainer)); + } return CommandResponse.Ok; } diff --git a/GlazeWM.Domain/Containers/CommandHandlers/FlattenSplitContainerHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/FlattenSplitContainerHandler.cs index b57cb876..dfb5ec1d 100644 --- a/GlazeWM.Domain/Containers/CommandHandlers/FlattenSplitContainerHandler.cs +++ b/GlazeWM.Domain/Containers/CommandHandlers/FlattenSplitContainerHandler.cs @@ -1,4 +1,5 @@ using System.Linq; +using GlazeWM.Domain.Common.Enums; using GlazeWM.Domain.Containers.Commands; using GlazeWM.Infrastructure.Bussing; using GlazeWM.Infrastructure.Utils; @@ -7,45 +8,47 @@ namespace GlazeWM.Domain.Containers.CommandHandlers { internal sealed class FlattenSplitContainerHandler : ICommandHandler { - private readonly Bus _bus; private readonly ContainerService _containerService; - public FlattenSplitContainerHandler(Bus bus, ContainerService containerService) + public FlattenSplitContainerHandler(ContainerService containerService) { - _bus = bus; _containerService = containerService; } public CommandResponse Handle(FlattenSplitContainerCommand command) { - var containerToFlatten = command.ContainerToFlatten; + var splitContainer = command.ContainerToFlatten; // Keep references to properties of container to flatten prior to detaching. - var originalParent = containerToFlatten.Parent; - var originalChildren = containerToFlatten.Children.ToList(); - var originalFocusIndex = containerToFlatten.FocusIndex; - var originalIndex = containerToFlatten.Index; - var originalFocusOrder = containerToFlatten.ChildFocusOrder.ToList(); + var parent = splitContainer.Parent; + var index = splitContainer.Index; + var focusIndex = splitContainer.FocusIndex; + var children = splitContainer.Children.ToList(); + var focusOrder = splitContainer.ChildFocusOrder.ToList(); - foreach (var (child, index) in originalChildren.WithIndex()) + foreach (var (child, childIndex) in children.WithIndex()) { - // Insert children of the split container at its original index in the parent. The split - // container will automatically detach once its last child is detached. - _bus.Invoke(new DetachContainerCommand(child)); - _bus.Invoke(new AttachContainerCommand(child, originalParent, originalIndex + index)); + // Insert child at its original index in the parent. + splitContainer.RemoveChild(child); + parent.Children.Insert(index + childIndex, child); + child.Parent = parent; - (child as IResizable).SizePercentage = (containerToFlatten as IResizable).SizePercentage - * (child as IResizable).SizePercentage; + if (child is IResizable childResizable) + childResizable.SizePercentage = splitContainer.SizePercentage * childResizable.SizePercentage; + + // Inverse the tiling direction of any child split containers. + if (child is SplitContainer childSplitContainer) + childSplitContainer.TilingDirection = childSplitContainer.TilingDirection.Inverse(); } + // Remove the split container from the tree. + parent.RemoveChild(splitContainer); + // Correct focus order of the inserted containers. - foreach (var child in originalChildren) - { - var childFocusIndex = originalFocusOrder.IndexOf(child); - originalParent.ChildFocusOrder.ShiftToIndex(originalFocusIndex + childFocusIndex, child); - } + parent.ChildFocusOrder.InsertRange(focusIndex, focusOrder); - _containerService.ContainersToRedraw.Add(originalParent); + // TODO: Remove unnecessary redraws. + _containerService.ContainersToRedraw.Add(parent); return CommandResponse.Ok; } diff --git a/GlazeWM.Domain/Containers/CommandHandlers/MoveContainerWithinTreeHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/MoveContainerWithinTreeHandler.cs index 882b1273..7f8893ef 100644 --- a/GlazeWM.Domain/Containers/CommandHandlers/MoveContainerWithinTreeHandler.cs +++ b/GlazeWM.Domain/Containers/CommandHandlers/MoveContainerWithinTreeHandler.cs @@ -23,10 +23,6 @@ public CommandResponse Handle(MoveContainerWithinTreeCommand command) var containerToMove = command.ContainerToMove; var targetParent = command.TargetParent; var targetIndex = command.TargetIndex; - var shouldAdjustSize = command.ShouldAdjustSize; - - if (shouldAdjustSize && containerToMove is not IResizable) - throw new Exception("Cannot resize a non-resizable container. This is a bug."); // Get lowest common ancestor (LCA) between `containerToMove` and `targetParent`. This could // be the `targetParent` itself. @@ -44,8 +40,7 @@ public CommandResponse Handle(MoveContainerWithinTreeCommand command) MoveToLowestCommonAncestor( containerToMove, lowestCommonAncestor, - targetIndex, - shouldAdjustSize + targetIndex ); if (containerToMove == focusedContainer) @@ -71,16 +66,8 @@ public CommandResponse Handle(MoveContainerWithinTreeCommand command) var originalFocusIndex = containerToMoveAncestor.FocusIndex; var isSubtreeFocused = originalFocusIndex < targetParentAncestor.FocusIndex; - if (shouldAdjustSize) - { - _bus.Invoke(new DetachAndResizeContainerCommand(containerToMove)); - _bus.Invoke(new AttachAndResizeContainerCommand(containerToMove, targetParent, targetIndex)); - } - else - { - _bus.Invoke(new DetachContainerCommand(containerToMove)); - _bus.Invoke(new AttachContainerCommand(containerToMove, targetParent, targetIndex)); - } + _bus.Invoke(new DetachContainerCommand(containerToMove)); + _bus.Invoke(new AttachContainerCommand(containerToMove, targetParent, targetIndex)); // Set `containerToMove` as focused descendant within target subtree if its original subtree // had focus more recently (even if the container is not the last focused within that subtree). @@ -104,8 +91,7 @@ public CommandResponse Handle(MoveContainerWithinTreeCommand command) private void MoveToLowestCommonAncestor( Container containerToMove, Container lowestCommonAncestor, - int targetIndex, - bool shouldAdjustSize) + int targetIndex) { // Keep reference to focus index of container's ancestor in LCA's `ChildFocusOrder`. var originalFocusIndex = containerToMove.SelfAndAncestors @@ -116,10 +102,7 @@ private void MoveToLowestCommonAncestor( var originalIndex = containerToMove.Index; var originalLcaChildCount = lowestCommonAncestor.Children.Count; - if (shouldAdjustSize) - _bus.Invoke(new DetachAndResizeContainerCommand(containerToMove)); - else - _bus.Invoke(new DetachContainerCommand(containerToMove)); + _bus.Invoke(new DetachContainerCommand(containerToMove)); var newLcaChildCount = lowestCommonAncestor.Children.Count; var shouldAdjustTargetIndex = originalLcaChildCount > newLcaChildCount @@ -129,22 +112,13 @@ private void MoveToLowestCommonAncestor( // top-level container to the right in a workspace. var adjustedTargetIndex = shouldAdjustTargetIndex ? targetIndex - 1 : targetIndex; - if (shouldAdjustSize) - _bus.Invoke( - new AttachAndResizeContainerCommand( - containerToMove, - lowestCommonAncestor, - adjustedTargetIndex - ) - ); - else - _bus.Invoke( - new AttachContainerCommand( - containerToMove, - lowestCommonAncestor, - adjustedTargetIndex - ) - ); + _bus.Invoke( + new AttachContainerCommand( + containerToMove, + lowestCommonAncestor, + adjustedTargetIndex + ) + ); lowestCommonAncestor.ChildFocusOrder.ShiftToIndex(originalFocusIndex, containerToMove); } diff --git a/GlazeWM.Domain/Containers/Commands/AttachAndResizeContainerCommand.cs b/GlazeWM.Domain/Containers/Commands/AttachAndResizeContainerCommand.cs deleted file mode 100644 index bc5c310a..00000000 --- a/GlazeWM.Domain/Containers/Commands/AttachAndResizeContainerCommand.cs +++ /dev/null @@ -1,31 +0,0 @@ -using GlazeWM.Infrastructure.Bussing; - -namespace GlazeWM.Domain.Containers.Commands -{ - public class AttachAndResizeContainerCommand : Command - { - public Container ChildToAdd { get; } - public Container TargetParent { get; } - public int TargetIndex { get; } - - /// - /// Insert child as end element if `targetIndex` is not provided. - /// - public AttachAndResizeContainerCommand(Container childToAdd, Container targetParent) - { - ChildToAdd = childToAdd; - TargetParent = targetParent; - TargetIndex = targetParent.Children.Count; - } - - public AttachAndResizeContainerCommand( - Container childToAdd, - Container targetParent, - int targetIndex) - { - ChildToAdd = childToAdd; - TargetParent = targetParent; - TargetIndex = targetIndex; - } - } -} diff --git a/GlazeWM.Domain/Containers/Commands/DetachAndResizeContainerCommand.cs b/GlazeWM.Domain/Containers/Commands/DetachAndResizeContainerCommand.cs deleted file mode 100644 index 0233a4e1..00000000 --- a/GlazeWM.Domain/Containers/Commands/DetachAndResizeContainerCommand.cs +++ /dev/null @@ -1,14 +0,0 @@ -using GlazeWM.Infrastructure.Bussing; - -namespace GlazeWM.Domain.Containers.Commands -{ - public class DetachAndResizeContainerCommand : Command - { - public Container ChildToRemove { get; } - - public DetachAndResizeContainerCommand(Container childToRemove) - { - ChildToRemove = childToRemove; - } - } -} diff --git a/GlazeWM.Domain/Containers/Commands/MoveContainerWithinTreeCommand.cs b/GlazeWM.Domain/Containers/Commands/MoveContainerWithinTreeCommand.cs index 975e633c..28a9426a 100644 --- a/GlazeWM.Domain/Containers/Commands/MoveContainerWithinTreeCommand.cs +++ b/GlazeWM.Domain/Containers/Commands/MoveContainerWithinTreeCommand.cs @@ -7,32 +7,27 @@ public class MoveContainerWithinTreeCommand : Command public Container ContainerToMove { get; } public Container TargetParent { get; } public int TargetIndex { get; } - public bool ShouldAdjustSize { get; } /// /// Insert child as end element if `targetIndex` is not provided. /// public MoveContainerWithinTreeCommand( Container containerToMove, - Container targetParent, - bool shouldAdjustSize) + Container targetParent) { ContainerToMove = containerToMove; TargetParent = targetParent; TargetIndex = targetParent.Children.Count; - ShouldAdjustSize = shouldAdjustSize; } public MoveContainerWithinTreeCommand( Container containerToMove, Container targetParent, - int targetIndex, - bool shouldAdjustSize) + int targetIndex) { ContainerToMove = containerToMove; TargetParent = targetParent; TargetIndex = targetIndex; - ShouldAdjustSize = shouldAdjustSize; } } } diff --git a/GlazeWM.Domain/Containers/Container.cs b/GlazeWM.Domain/Containers/Container.cs index cad31ea8..c9fe480b 100644 --- a/GlazeWM.Domain/Containers/Container.cs +++ b/GlazeWM.Domain/Containers/Container.cs @@ -148,6 +148,20 @@ public IEnumerable DescendantFocusOrder } } + public void InsertChild(int targetIndex, Container child) + { + Children.Insert(targetIndex, child); + ChildFocusOrder.Add(child); + child.Parent = this; + } + + public void RemoveChild(Container child) + { + child.Parent = null; + Children.Remove(child); + ChildFocusOrder.Remove(child); + } + public bool IsDetached() { return Parent is null || Index == -1; diff --git a/GlazeWM.Domain/DependencyInjection.cs b/GlazeWM.Domain/DependencyInjection.cs index 2180e2eb..948ee68d 100644 --- a/GlazeWM.Domain/DependencyInjection.cs +++ b/GlazeWM.Domain/DependencyInjection.cs @@ -37,13 +37,11 @@ public static IServiceCollection AddDomainServices(this IServiceCollection servi services.AddSingleton, PopulateInitialStateHandler>(); services.AddSingleton, ExecProcessHandler>(); services.AddSingleton, SetBindingModeHandler>(); - services.AddSingleton, AttachAndResizeContainerHandler>(); services.AddSingleton, AttachContainerHandler>(); services.AddSingleton, CenterCursorOnContainerHandler>(); services.AddSingleton, SetActiveWindowBorderHandler>(); services.AddSingleton, ChangeTilingDirectionHandler>(); services.AddSingleton, ToggleTilingDirectionHandler>(); - services.AddSingleton, DetachAndResizeContainerHandler>(); services.AddSingleton, DetachContainerHandler>(); services.AddSingleton, FlattenSplitContainerHandler>(); services.AddSingleton, FocusInDirectionHandler>(); diff --git a/GlazeWM.Domain/Monitors/CommandHandlers/RemoveMonitorHandler.cs b/GlazeWM.Domain/Monitors/CommandHandlers/RemoveMonitorHandler.cs index fe50c18b..aa97cd8a 100644 --- a/GlazeWM.Domain/Monitors/CommandHandlers/RemoveMonitorHandler.cs +++ b/GlazeWM.Domain/Monitors/CommandHandlers/RemoveMonitorHandler.cs @@ -37,7 +37,7 @@ public CommandResponse Handle(RemoveMonitorCommand command) foreach (var workspace in workspacesToMove.ToList()) { // Move workspace to target monitor. - _bus.Invoke(new MoveContainerWithinTreeCommand(workspace, targetMonitor, false)); + _bus.Invoke(new MoveContainerWithinTreeCommand(workspace, targetMonitor)); // Update workspaces displayed in bar window. // TODO: Consider creating separate event `WorkspaceMovedEvent`. diff --git a/GlazeWM.Domain/Windows/CommandHandlers/IgnoreWindowHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/IgnoreWindowHandler.cs index 8399c579..0d0d8afc 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/IgnoreWindowHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/IgnoreWindowHandler.cs @@ -23,10 +23,7 @@ public CommandResponse Handle(IgnoreWindowCommand command) // Store handle to ignored window. _windowService.IgnoredHandles.Add(windowToIgnore.Handle); - if (windowToIgnore is IResizable) - _bus.Invoke(new DetachAndResizeContainerCommand(windowToIgnore)); - else - _bus.Invoke(new DetachContainerCommand(windowToIgnore)); + _bus.Invoke(new DetachContainerCommand(windowToIgnore)); return CommandResponse.Ok; } diff --git a/GlazeWM.Domain/Windows/CommandHandlers/ManageWindowHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/ManageWindowHandler.cs index 8c03d829..0587864f 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/ManageWindowHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/ManageWindowHandler.cs @@ -53,11 +53,7 @@ public CommandResponse Handle(ManageWindowCommand command) // Create the window instance. var window = CreateWindow(windowHandle, targetParent); - - if (window is IResizable) - _bus.Invoke(new AttachAndResizeContainerCommand(window, targetParent, targetIndex)); - else - _bus.Invoke(new AttachContainerCommand(window, targetParent, targetIndex)); + _bus.Invoke(new AttachContainerCommand(window, targetParent, targetIndex)); // The OS might spawn the window on a different monitor to the target parent, so adjustments // might need to be made because of DPI. diff --git a/GlazeWM.Domain/Windows/CommandHandlers/MoveWindowHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/MoveWindowHandler.cs index 220a1c62..ceb3562a 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/MoveWindowHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/MoveWindowHandler.cs @@ -73,18 +73,13 @@ private void SwapSiblingContainers(Window windowToMove, Direction direction) // Swap the window with sibling in given direction. if (siblingInDirection is Window) { - var targetIndex = direction is Direction.Up or Direction.Left ? - siblingInDirection.Index : siblingInDirection.Index + 1; - - _bus.Invoke( - new MoveContainerWithinTreeCommand( - windowToMove, - windowToMove.Parent, - targetIndex, - false - ) + windowToMove.Parent.Children.ShiftToIndex( + siblingInDirection.Index, + windowToMove ); + _containerService.ContainersToRedraw.Add(windowToMove); + _containerService.ContainersToRedraw.Add(siblingInDirection); return; } @@ -102,7 +97,7 @@ private void SwapSiblingContainers(Window windowToMove, Direction direction) var insertionIndex = shouldInsertAfter ? targetDescendant.Index + 1 : targetDescendant.Index; _bus.Invoke( - new MoveContainerWithinTreeCommand(windowToMove, targetParent, insertionIndex, true) + new MoveContainerWithinTreeCommand(windowToMove, targetParent, insertionIndex) ); } @@ -125,9 +120,9 @@ private void MoveToWorkspaceInDirection(Window windowToMove, Direction direction // TODO: Descend into container if possible. if (direction is Direction.Up or Direction.Left) - _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, workspaceInDirection, true)); + _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, workspaceInDirection)); else - _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, workspaceInDirection, 0, true)); + _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, workspaceInDirection, 0)); } private void ChangeWorkspaceTilingDirection(Window windowToMove, Direction direction) @@ -174,7 +169,7 @@ private void InsertIntoAncestor( ? targetDescendant.Index + 1 : targetDescendant.Index; - _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, targetParent, insertionIndex, true)); + _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, targetParent, insertionIndex)); } else { @@ -186,8 +181,7 @@ private void InsertIntoAncestor( new MoveContainerWithinTreeCommand( windowToMove, ancestorWithTilingDirection, - insertionIndex, - true + insertionIndex ) ); } @@ -285,7 +279,7 @@ private void MoveFloatingWindow(Window windowToMove, Direction direction) } // Change the window's parent workspace. - _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, workspaceInDirection, false)); + _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, workspaceInDirection)); // Redrawing twice to fix weird WindowsOS dpi behaviour windowToMove.HasPendingDpiAdjustment = true; diff --git a/GlazeWM.Domain/Windows/CommandHandlers/ResizeWindowHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/ResizeWindowHandler.cs index ff8f555a..e7887b58 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/ResizeWindowHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/ResizeWindowHandler.cs @@ -130,7 +130,7 @@ private void ResizeFloatingWindow(Window windowToResize, ResizeDimension dimensi } // Change the window's parent workspace. - _bus.Invoke(new MoveContainerWithinTreeCommand(windowToResize, targetWorkspace, false)); + _bus.Invoke(new MoveContainerWithinTreeCommand(windowToResize, targetWorkspace)); windowToResize.HasPendingDpiAdjustment = true; } diff --git a/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs index 929973d8..48842d8d 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs @@ -25,10 +25,7 @@ public CommandResponse Handle(SetFloatingCommand command) // Keep reference to the window's ancestor workspace prior to detaching. var workspace = WorkspaceService.GetWorkspaceFromChildContainer(window); - if (window is IResizable) - _bus.Invoke(new MoveContainerWithinTreeCommand(window, workspace, true)); - else - _bus.Invoke(new MoveContainerWithinTreeCommand(window, workspace, false)); + _bus.Invoke(new MoveContainerWithinTreeCommand(window, workspace)); // Create a floating window and place it in the center of the workspace. var floatingWindow = new FloatingWindow( diff --git a/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs index 60e4d623..eceac73c 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs @@ -42,14 +42,13 @@ public CommandResponse Handle(SetTilingCommand command) // Insert the created tiling window after the last focused descendant of the workspace. if (insertionTarget is null) - _bus.Invoke(new MoveContainerWithinTreeCommand(tilingWindow, workspace, 0, true)); + _bus.Invoke(new MoveContainerWithinTreeCommand(tilingWindow, workspace, 0)); else _bus.Invoke( new MoveContainerWithinTreeCommand( tilingWindow, insertionTarget.Parent, - insertionTarget.Index + 1, - true + insertionTarget.Index + 1 ) ); diff --git a/GlazeWM.Domain/Windows/CommandHandlers/UnmanageWindowHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/UnmanageWindowHandler.cs index e71a4d0f..6b7428a1 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/UnmanageWindowHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/UnmanageWindowHandler.cs @@ -32,11 +32,7 @@ public CommandResponse Handle(UnmanageWindowCommand command) ? WindowService.GetFocusTargetAfterRemoval(window) : null; - if (window is IResizable) - _bus.Invoke(new DetachAndResizeContainerCommand(window)); - else - _bus.Invoke(new DetachContainerCommand(window)); - + _bus.Invoke(new DetachContainerCommand(window)); _bus.Emit(new WindowUnmanagedEvent(window.Id, window.Handle)); if (focusTarget is null) diff --git a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs index a3a54f6b..2962bffd 100644 --- a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs +++ b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs @@ -51,14 +51,13 @@ public void Handle(WindowMinimizeEndedEvent @event) // Insert the created tiling window after the last focused descendant of the workspace. if (insertionTarget == null) - _bus.Invoke(new MoveContainerWithinTreeCommand(restoredWindow, workspace, 0, true)); + _bus.Invoke(new MoveContainerWithinTreeCommand(restoredWindow, workspace, 0)); else _bus.Invoke( new MoveContainerWithinTreeCommand( restoredWindow, insertionTarget.Parent, - insertionTarget.Index + 1, - true + insertionTarget.Index + 1 ) ); diff --git a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs index 508f78f1..479e638f 100644 --- a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs +++ b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs @@ -42,7 +42,7 @@ public void Handle(WindowMinimizedEvent @event) // Move tiling windows to be direct children of workspace (in case they aren't already). if (window is TilingWindow) - _bus.Invoke(new MoveContainerWithinTreeCommand(window, workspace, true)); + _bus.Invoke(new MoveContainerWithinTreeCommand(window, workspace)); var previousState = WindowService.GetWindowType(window); var minimizedWindow = new MinimizedWindow( diff --git a/GlazeWM.Domain/Windows/EventHandlers/WindowMovedOrResizedHandler.cs b/GlazeWM.Domain/Windows/EventHandlers/WindowMovedOrResizedHandler.cs index a6b37af5..58078196 100644 --- a/GlazeWM.Domain/Windows/EventHandlers/WindowMovedOrResizedHandler.cs +++ b/GlazeWM.Domain/Windows/EventHandlers/WindowMovedOrResizedHandler.cs @@ -108,7 +108,7 @@ private void UpdateParentWorkspace(Window window) return; // Change the window's parent workspace. - _bus.Invoke(new MoveContainerWithinTreeCommand(window, targetWorkspace, false)); + _bus.Invoke(new MoveContainerWithinTreeCommand(window, targetWorkspace)); _bus.Emit(new FocusChangedEvent(window)); } } diff --git a/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs b/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs index f4c7acc0..4c0e923e 100644 --- a/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs +++ b/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs @@ -62,7 +62,7 @@ public CommandResponse Handle(MoveWindowToWorkspaceCommand command) if (windowToMove is TilingWindow) MoveTilingWindowToWorkspace(windowToMove as TilingWindow, targetWorkspace); else - _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, targetWorkspace, false)); + _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, targetWorkspace)); if (focusResetTarget is not null) _bus.Invoke(new SetFocusedDescendantCommand(focusResetTarget)); @@ -102,14 +102,13 @@ private void MoveTilingWindowToWorkspace(TilingWindow windowToMove, Workspace ta // Insert the window into the target workspace. if (insertionTarget == null) - _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, targetWorkspace, true)); + _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, targetWorkspace)); else _bus.Invoke( new MoveContainerWithinTreeCommand( windowToMove, insertionTarget.Parent, - insertionTarget.Index + 1, - true + insertionTarget.Index + 1 ) ); } diff --git a/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWorkspaceInDirectionHandler.cs b/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWorkspaceInDirectionHandler.cs index 0f5cd52d..3b37ead9 100644 --- a/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWorkspaceInDirectionHandler.cs +++ b/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWorkspaceInDirectionHandler.cs @@ -45,7 +45,7 @@ public CommandResponse Handle(MoveWorkspaceInDirectionCommand command) // Move workspace to target monitor. _bus.Invoke( - new MoveContainerWithinTreeCommand(focusedWorkspace, targetMonitor, false) + new MoveContainerWithinTreeCommand(focusedWorkspace, targetMonitor) ); // Update floating placement since the windows have to cross monitors.