Skip to content

Commit

Permalink
Refactor event handling in WindowManager (#131)
Browse files Browse the repository at this point in the history
- `IWindowManager` now has separate events for each event type. As a result, the `WindowUpdated` event, the `WindowUpdateEventArgs` class, and the `WindowUpdateType` enum have been removed.
- The `WindowMoved` event is used for both `EVENT_OBJECT_LOCATION_CHANGE` and `EVENT_SYSTEM_MOVESIZEEND` (previously they were separate `WindowUpdateType`s).
- Removed `WindowManager.Trigger*` methods in favor of the `OnWindow*` methods used for responding to Windows events.
- Updated consumers of `IWindowManager` events.
  • Loading branch information
dalyIsaac authored Jul 9, 2022
1 parent 307c641 commit 86a9f97
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 242 deletions.
1 change: 1 addition & 0 deletions src/Whim.FocusIndicator/FocusIndicatorConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public int BorderSize

/// <summary>
/// When <see langword="true"/>, the focus indicator is visible.
/// Updating this will cause the plugin to redraw the indicator.
/// </summary>
public bool IsVisible
{
Expand Down
42 changes: 11 additions & 31 deletions src/Whim.FocusIndicator/FocusIndicatorPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,17 @@ public FocusIndicatorPlugin(IConfigContext configContext, FocusIndicatorConfig f
public void PreInitialize()
{
_configContext.FilterManager.IgnoreTitleMatch(FocusIndicatorConfig.Title);
_configContext.WindowManager.WindowFocused += WindowManager_WindowFocused;
_configContext.WindowManager.WindowUnregistered += WindowManager_WindowUnregistered;
_configContext.WindowManager.WindowUpdated += WindowManager_WindowUpdated;

_focusIndicatorConfig.PropertyChanged += FocusIndicatorConfig_PropertyChanged;

_configContext.WindowManager.WindowFocused += WindowManager_WindowFocused;

_configContext.WindowManager.WindowRegistered += WindowManager_EventSink;
_configContext.WindowManager.WindowUnregistered += WindowManager_EventSink;
_configContext.WindowManager.WindowMoveStart += WindowManager_EventSink;
_configContext.WindowManager.WindowMoved += WindowManager_EventSink;
_configContext.WindowManager.WindowMinimizeStart += WindowManager_EventSink;
_configContext.WindowManager.WindowMinimizeEnd += WindowManager_EventSink;
}

/// <inheritdoc/>
Expand All @@ -55,38 +62,11 @@ private void DispatcherTimer_Tick(object? sender, object e)
_focusIndicatorConfig.IsVisible = false;
}

private void WindowManager_WindowStartedMoving(object? sender, WindowEventArgs e)
{
_focusIndicatorConfig.IsVisible = false;
}

private void WindowManager_WindowUnregistered(object? sender, WindowEventArgs e)
private void WindowManager_EventSink(object? sender, WindowEventArgs e)
{
Show();
}

private void WindowManager_WindowUpdated(object? sender, WindowUpdateEventArgs e)
{
Logger.Verbose($"Window {e.Window} updated with update type {e.UpdateType}");
switch (e.UpdateType)
{
case WindowUpdateType.Cloaked:
case WindowUpdateType.MoveStart:
case WindowUpdateType.MinimizeStart:
case WindowUpdateType.Move:
Hide();
break;
case WindowUpdateType.Uncloaked:
case WindowUpdateType.Foreground:
case WindowUpdateType.MoveEnd:
case WindowUpdateType.MinimizeEnd:
Show();
break;
default:
break;
}
}

private void FocusIndicatorConfig_PropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(FocusIndicatorConfig.IsVisible))
Expand Down
6 changes: 2 additions & 4 deletions src/Whim.Tests/WindowManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Whim.Tests;
public class WindowManagerTests
{
[Fact]
public void TriggerWindowFocused_MonitorManager_WindowFocused()
public void OnWindowFocused_MonitorManager_WindowFocused()
{
// Given
Mock<IWorkspaceManager> workspaceManagerMock = new();
Expand All @@ -27,11 +27,9 @@ public void TriggerWindowFocused_MonitorManager_WindowFocused()
#pragma warning restore CA2000 // Dispose objects before losing scope

// When the window manager calls TriggerWindowFocused
WindowEventArgs windowEventArgs = new(new Mock<IWindow>().Object);
windowManager.TriggerWindowFocused(windowEventArgs);
windowManager.OnWindowFocused(new Mock<IWindow>().Object);

// Then the monitor manager was called and updated the focused monitor.
Assert.Equal(monitorMock.Object, monitorManager.FocusedMonitor);
}
}

2 changes: 1 addition & 1 deletion src/Whim.TreeLayout/PhantomNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected PhantomNode(IWindow windowModel, Microsoft.UI.Xaml.Window? phantomWind
{
PhantomWindow phantomWindow = new();

IWindow? windowModel = Whim.IWindow.CreateWindow(phantomWindow.GetHandle(), configContext);
IWindow? windowModel = IWindow.CreateWindow(phantomWindow.GetHandle(), configContext);

if (windowModel == null)
{
Expand Down
29 changes: 24 additions & 5 deletions src/Whim/Window/IWindowManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ public interface IWindowManager : IDisposable
/// </summary>
public event EventHandler<WindowEventArgs>? WindowRegistered;

/// <summary>
/// Event for when a window is updated by Windows.
/// </summary>
public event EventHandler<WindowUpdateEventArgs>? WindowUpdated;

/// <summary>
/// Event for when a window is focused.
/// </summary>
Expand All @@ -32,4 +27,28 @@ public interface IWindowManager : IDisposable
/// Event for when a window is unregistered from Whim.
/// </summary>
public event EventHandler<WindowEventArgs>? WindowUnregistered;

/// <summary>
/// Event for when a window is being moved or resized.
/// </summary>
public event EventHandler<WindowEventArgs>? WindowMoveStart;

/// <summary>
/// Event for when a window has changed location, shape, or size.
///
/// This event is fired when Windows sends a <see cref="Windows.Win32.PInvoke.EVENT_OBJECT_LOCATIONCHANGE"/>
/// or <see cref="Windows.Win32.PInvoke.EVENT_SYSTEM_MOVESIZEEND"/> event.
/// See https://docs.microsoft.com/en-us/windows/win32/winauto/event-constants for more information.
/// </summary>
public event EventHandler<WindowEventArgs>? WindowMoved;

/// <summary>
/// Event for when a window has started being minimized.
/// </summary>
public event EventHandler<WindowEventArgs>? WindowMinimizeStart;

/// <summary>
/// Event for when a window has ended being minimized.
/// </summary>
public event EventHandler<WindowEventArgs>? WindowMinimizeEnd;
}
16 changes: 7 additions & 9 deletions src/Whim/Window/Window.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public void Close()
{
Logger.Debug(ToString());
Win32Helper.QuitApplication(Handle);
(_configContext.WindowManager as WindowManager)?.TriggerWindowUnregistered(new WindowEventArgs(this));
}

/// <inheritdoc/>
Expand All @@ -77,28 +76,27 @@ public void Focus()
PInvoke.SetForegroundWindow(Handle);
}

// Sometimes we want to let listeners that the window is focused, but
// other things might have changed, like the monitor the window's on.
// For example, <see cref="MonitorManager.FocusMonitor"/> relies on
// <see cref="IWindowManager.WindowFocused"/> to be called.
// Admittedly, this is a bit of a hack.
(_configContext.WindowManager as WindowManager)?.TriggerWindowFocused(new WindowEventArgs(this));
// We manually call OnWindowFocused as n already focused window may have switched to a
// different workspace.
(_configContext.WindowManager as WindowManager)?.OnWindowFocused(this);
}

/// <inheritdoc/>
public void FocusForceForeground()
{
Logger.Debug(ToString());
PInvoke.SetForegroundWindow(Handle);
(_configContext.WindowManager as WindowManager)?.TriggerWindowFocused(new WindowEventArgs(this));

// We manually call OnWindowFocused as n already focused window may have switched to a
// different workspace.
(_configContext.WindowManager as WindowManager)?.OnWindowFocused(this);
}

/// <inheritdoc/>
public void Hide()
{
Logger.Debug(ToString());
Win32Helper.HideWindow(Handle);
(_configContext.WindowManager as WindowManager)?.TriggerWindowUpdated(new WindowUpdateEventArgs(this, WindowUpdateType.Cloaked));
}

/// <inheritdoc/>
Expand Down
23 changes: 23 additions & 0 deletions src/Whim/Window/WindowEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;

namespace Whim;

/// <summary>
/// Event arguments for when a <see cref="IWindow"/> has had something happen to it.
/// </summary>
public class WindowEventArgs : EventArgs
{
/// <summary>
/// The <see cref="IWindow"/> that had something happen to it.
/// </summary>
public IWindow Window { get; private set; }

/// <summary>
/// Create a new <see cref="WindowEventArgs"/>.
/// </summary>
/// <param name="window"></param>
public WindowEventArgs(IWindow window)
{
Window = window;
}
}
45 changes: 0 additions & 45 deletions src/Whim/Window/WindowEvents.cs

This file was deleted.

Loading

0 comments on commit 86a9f97

Please sign in to comment.