Skip to content

Commit

Permalink
feat: add intermediary display states
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger committed Sep 7, 2023
1 parent 099f614 commit 559b256
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 16 deletions.
12 changes: 12 additions & 0 deletions GlazeWM.Domain/Common/Enums/DisplayState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace GlazeWM.Domain.Common.Enums
{
public enum DisplayState
{
Shown,
Showing,
Hidden,
Hiding,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,19 @@ private void SetWindowPosition(Window window)
SetWindowPosFlags.NoCopyBits |
SetWindowPosFlags.NoSendChanging;

var workspace = window.Ancestors.OfType<Workspace>().First();

// Show or hide the window depending on whether the workspace is displayed.
if (window.IsDisplayed)
if (workspace.IsDisplayed)
{
defaultFlags |= SetWindowPosFlags.ShowWindow;
window.DisplayState = DisplayState.Showing;
}
else
{
defaultFlags |= SetWindowPosFlags.HideWindow;
window.DisplayState = DisplayState.Hiding;
}

if (window is TilingWindow)
{
Expand Down
14 changes: 12 additions & 2 deletions GlazeWM.Domain/Windows/EventHandlers/WindowFocusedHandler.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Linq;
using GlazeWM.Domain.Common.Enums;
using GlazeWM.Domain.Common.Utils;
using GlazeWM.Domain.Containers;
using GlazeWM.Domain.Containers.Commands;
Expand All @@ -8,7 +9,6 @@
using GlazeWM.Infrastructure.Bussing;
using GlazeWM.Infrastructure.Common.Events;
using Microsoft.Extensions.Logging;
using static GlazeWM.Infrastructure.WindowsApi.WindowsApiService;

namespace GlazeWM.Domain.Windows.EventHandlers
{
Expand Down Expand Up @@ -68,9 +68,19 @@ public void Handle(WindowFocusedEvent @event)
var window = _windowService.GetWindows()
.FirstOrDefault(window => window.Handle == @event.WindowHandle);

if (window is null || window?.IsDisplayed == false)
if (window is null)
return;

// TODO: Need to return early for other display states.
// TODO: Should this be moved to `WindowShownHandler`. Is show event
// emitted first, or foreground?
if (window.DisplayState is DisplayState.Hidden)
{
_logger.LogWindowEvent("Focusing off-screen window", window);
var workspace = WorkspaceService.GetWorkspaceFromChildContainer(window);
_bus.Invoke(new FocusWorkspaceCommand(workspace.Name));
}

_logger.LogWindowEvent("Window focused", window);

_bus.Invoke(new SetFocusedDescendantCommand(window));
Expand Down
16 changes: 11 additions & 5 deletions GlazeWM.Domain/Windows/EventHandlers/WindowHiddenHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,22 @@ public void Handle(WindowHiddenEvent @event)
var window = _windowService.GetWindows()
.FirstOrDefault(window => window.Handle == windowHandle);

// Ignore events where the window isn't managed or is actually supposed to be hidden. Since
// window events are processed in a sequence, also handle case where the window is not
// actually hidden anymore when the event is processed.
if (window?.IsDisplayed != true || WindowService.IsHandleVisible(window.Handle))
// Ignore event if window is unmanaged.
if (window is null)
return;

_logger.LogWindowEvent("Window hidden", window);

// Update display state.
if (window.DisplayState is DisplayState.Hiding)
{
window.DisplayState = DisplayState.Hidden;
return;
}

// Detach the hidden window from its parent.
_bus.Invoke(new UnmanageWindowCommand(window));
if (window.DisplayState is DisplayState.Shown)
_bus.Invoke(new UnmanageWindowCommand(window));
}
}
}
11 changes: 8 additions & 3 deletions GlazeWM.Domain/Windows/EventHandlers/WindowShownHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,16 @@ public void Handle(WindowShownEvent @event)
var window = _windowService.GetWindows()
.FirstOrDefault(window => window.Handle == windowHandle);

// Ignore cases where window is already managed.
if (window is not null || !WindowService.IsHandleManageable(windowHandle))
// Manage the window if it's manageable.
if (window is null && WindowService.IsHandleManageable(windowHandle))
{
_bus.Invoke(new ManageWindowCommand(@event.WindowHandle));
return;
}

_bus.Invoke(new ManageWindowCommand(@event.WindowHandle));
// Update display state if window is already managed.
if (window?.DisplayState == DisplayState.Showing)
window.DisplayState = DisplayState.Shown;
}
}
}
10 changes: 5 additions & 5 deletions GlazeWM.Domain/Windows/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ public abstract class Window : Container

public IntPtr Handle { get; }

/// <summary>
/// Whether window is shown, hidden, or in an intermediary state.
/// </summary>
public DisplayState DisplayState { get; set; } = DisplayState.Displayed;

/// <summary>
/// The placement of the window when floating. Initialized with window's placement on launch
/// and updated on resize/move whilst floating.
Expand All @@ -39,11 +44,6 @@ protected Window(IntPtr handle, Rect floatingPlacement, RectDelta borderDelta)
BorderDelta = borderDelta;
}

/// <summary>
/// Windows are displayed if their parent workspace is displayed.
/// </summary>
public bool IsDisplayed => WorkspaceService.GetWorkspaceFromChildContainer(this).IsDisplayed;

public string ProcessName =>
WindowService.GetProcessOfHandle(Handle)?.ProcessName ?? string.Empty;

Expand Down

0 comments on commit 559b256

Please sign in to comment.