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.