Skip to content

Commit

Permalink
feat: maximized windows stay maximized (#421)
Browse files Browse the repository at this point in the history
  • Loading branch information
phisko authored Oct 16, 2023
1 parent f292744 commit a521537
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public CommandResponse Handle(RedrawContainersCommand command)
var windowsToRestore = windowsToRedraw
.Where(
(window) =>
window is not MinimizedWindow &&
window.HasWindowStyle(WindowStyles.Maximize | WindowStyles.Minimize)
(window is not MinimizedWindow && window.HasWindowStyle(WindowStyles.Minimize)) ||
(window is not MaximizedWindow && window.HasWindowStyle(WindowStyles.Maximize))
)
.ToList();

Expand Down Expand Up @@ -85,6 +85,9 @@ private void SetWindowPosition(Window window)
else
defaultFlags |= SetWindowPosFlags.HideWindow;

if (window is MaximizedWindow)
defaultFlags |= SetWindowPosFlags.NoSize;

// Transition display state depending on whether window will be shown/hidden.
window.DisplayState = window.DisplayState switch
{
Expand Down
111 changes: 110 additions & 1 deletion GlazeWM.Domain/Windows/EventHandlers/WindowLocationChangedHandler.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,139 @@
using System;
using System.Linq;
using GlazeWM.Domain.Containers;
using GlazeWM.Domain.Containers.Commands;
using GlazeWM.Domain.Monitors.Commands;
using GlazeWM.Domain.Workspaces;
using GlazeWM.Infrastructure.Bussing;
using GlazeWM.Infrastructure.Common.Events;
using static GlazeWM.Infrastructure.WindowsApi.WindowsApiService;

namespace GlazeWM.Domain.Windows.EventHandlers
{
internal sealed class WindowLocationChangedHandler : IEventHandler<WindowLocationChangedEvent>
{
private readonly Bus _bus;
private readonly ContainerService _containerService;
private readonly WindowService _windowService;

public WindowLocationChangedHandler(Bus bus, WindowService windowService)
public WindowLocationChangedHandler(Bus bus,
WindowService windowService,
ContainerService containerService)
{
_bus = bus;
_containerService = containerService;
_windowService = windowService;
}

public void Handle(WindowLocationChangedEvent @event)
{
var windowHandle = @event.WindowHandle;

HandleMaximizedWindow(windowHandle);

if (!_windowService.AppBarHandles.Contains(windowHandle))
return;

_bus.Invoke(new RefreshMonitorStateCommand());
_bus.Invoke(new RedrawContainersCommand());
}

private void HandleMaximizedWindow(IntPtr windowHandle)
{
var window = _windowService.GetWindowByHandle(windowHandle);
if (window is null)
return;

var windowPlacement = WindowService.GetPlacementOfHandle(windowHandle);
var isMaximized = windowPlacement.ShowCommand == ShowWindowFlags.Maximize;

// Window is being maximized.
if (isMaximized && window is not MaximizedWindow)
{
var previousState = WindowService.GetWindowType(window);
var maximizedWindow = new MaximizedWindow(
window.Handle,
window.FloatingPlacement,
window.BorderDelta,
previousState
)
{
Id = window.Id
};

if (!window.HasSiblings() && window.Parent is not Workspace)
_bus.Invoke(new FlattenSplitContainerCommand(window.Parent as SplitContainer));

_bus.Invoke(new ReplaceContainerCommand(maximizedWindow, window.Parent, window.Index));

_containerService.ContainersToRedraw.Concat(window.Siblings);
_bus.Invoke(new RedrawContainersCommand());
}

// Maximized window is being restored.
if (!isMaximized && window is MaximizedWindow)
{
var restoredWindow = CreateWindowFromPreviousState(window as MaximizedWindow);
_bus.Invoke(new ReplaceContainerCommand(restoredWindow, window.Parent, window.Index));

// Non-tiling window expect to be direct children of workspace.
if (restoredWindow is not TilingWindow)
{
var workspace = WorkspaceService.GetWorkspaceFromChildContainer(restoredWindow);
_bus.Invoke(new MoveContainerWithinTreeCommand(restoredWindow, workspace, false));
}
else
{
// TODO: Temporary hack to resize restored tiling window.
_bus.Invoke(
new MoveContainerWithinTreeCommand(
restoredWindow,
restoredWindow.Parent,
restoredWindow.Index,
true
)
);
}

_containerService.ContainersToRedraw.Add(restoredWindow);
_bus.Invoke(new RedrawContainersCommand());
}
}

// TODO: Share logic with `WindowMinimizedHandler`.
private static Window CreateWindowFromPreviousState(MaximizedWindow window)
{
Window restoredWindow = window.PreviousState switch
{
WindowType.Floating => new FloatingWindow(
window.Handle,
window.FloatingPlacement,
window.BorderDelta
),
WindowType.Fullscreen => new FullscreenWindow(
window.Handle,
window.FloatingPlacement,
window.BorderDelta
),
// Set `SizePercentage` to 0 to correctly resize the container when moved within tree.
WindowType.Tiling => new TilingWindow(
window.Handle,
window.FloatingPlacement,
window.BorderDelta,
0
),
WindowType.Minimized => new MinimizedWindow(
window.Handle,
window.FloatingPlacement,
window.BorderDelta,
WindowType.Tiling
),
WindowType.Maximized => throw new ArgumentException(null, nameof(window)),
_ => throw new ArgumentException(null, nameof(window)),
};

restoredWindow.Id = window.Id;
return restoredWindow;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ private static Window CreateWindowFromPreviousState(MinimizedWindow window)
WindowType.Maximized => new MaximizedWindow(
window.Handle,
window.FloatingPlacement,
window.BorderDelta
window.BorderDelta,
WindowType.Tiling
),
WindowType.Fullscreen => new FullscreenWindow(
window.Handle,
Expand Down
6 changes: 5 additions & 1 deletion GlazeWM.Domain/Windows/MaximizedWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ namespace GlazeWM.Domain.Windows
{
public sealed class MaximizedWindow : Window
{
public WindowType PreviousState;

public MaximizedWindow(
IntPtr handle,
Rect floatingPlacement,
RectDelta borderDelta
RectDelta borderDelta,
WindowType previousState
) : base(handle, floatingPlacement, borderDelta)
{
PreviousState = previousState;
}
}
}
1 change: 1 addition & 0 deletions GlazeWM.Domain/Windows/WindowService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ public static WindowType GetWindowType(Window window)
{
TilingWindow => WindowType.Tiling,
FloatingWindow => WindowType.Floating,
MinimizedWindow => WindowType.Minimized,
MaximizedWindow => WindowType.Maximized,
FullscreenWindow => WindowType.Fullscreen,
_ => throw new ArgumentException(null, nameof(window)),
Expand Down

0 comments on commit a521537

Please sign in to comment.