Skip to content

Commit

Permalink
feat: add FocusedContainerMovedEvent and `NativeFocusReassignedEven…
Browse files Browse the repository at this point in the history
…t` (#378)
  • Loading branch information
HolbyFPV authored Sep 5, 2023
1 parent dfbfe08 commit 7f2e1de
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 10 deletions.
1 change: 1 addition & 0 deletions GlazeWM.App.IpcServer/IpcMessageHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public sealed class IpcMessageHandler
{
DomainEvent.BindingModeChanged,
DomainEvent.FocusChanged,
DomainEvent.FocusedContainerMoved,
DomainEvent.MonitorAdded,
DomainEvent.MonitorRemoved,
DomainEvent.TilingDirectionChanged,
Expand Down
29 changes: 27 additions & 2 deletions GlazeWM.App.WindowManager/WmStartup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,23 @@ public ExitCode Run()
_systemTrayIcon = new SystemTrayIcon(systemTrayIconConfig);
_systemTrayIcon.Show();

var nativeFocusReassigned = _bus.Events
.OfType<NativeFocusReassignedEvent>()
.Select((@event) => @event.FocusedContainer);

if (_userConfigService.FocusBorderConfig.Active.Enabled ||
_userConfigService.FocusBorderConfig.Inactive.Enabled)
_bus.Events.OfType<FocusChangedEvent>().Subscribe((@event) =>
_bus.InvokeAsync(new SetActiveWindowBorderCommand(@event.FocusedContainer as Window)));
{
var focusChanged = _bus.Events
.OfType<FocusChangedEvent>()
.Select(@event => @event.FocusedContainer);

focusChanged
.Merge(nativeFocusReassigned)
.Subscribe((container) =>
_bus.InvokeAsync(new SetActiveWindowBorderCommand(container as Window))
);
}

// Hook mouse event for focus follows cursor.
if (_userConfigService.GeneralConfig.FocusFollowsCursor)
Expand All @@ -87,6 +100,18 @@ public ExitCode Run()
_bus.InvokeAsync(new FocusContainerUnderCursorCommand(@event.Point));
});

// Setup cursor follows focus
if (_userConfigService.GeneralConfig.CursorFollowsFocus)
{
var focusedContainerMoved = _bus.Events
.OfType<FocusedContainerMovedEvent>()
.Select(@event => @event.FocusedContainer);

focusedContainerMoved.Merge(nativeFocusReassigned)
.Where(container => container is Window)
.Subscribe((window) => _bus.InvokeAsync(new CenterCursorOnContainerCommand(window)));
}

System.Windows.Forms.Application.Run();
return ExitCode.Success;
}
Expand Down
2 changes: 2 additions & 0 deletions GlazeWM.Domain/Common/DomainEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ public static class DomainEvent
{
public const string BindingModeChanged = "binding_mode_changed";
public const string FocusChanged = "focus_changed";
public const string FocusedContainerMoved = "focused_container_moved";
public const string MonitorAdded = "monitor_added";
public const string MonitorRemoved = "monitor_removed";
public const string NativeFocusReassigned = "native_focus_reassigned";
public const string TilingDirectionChanged = "tiling_direction_changed";
public const string UserConfigReloaded = "user_config_reloaded";
public const string WindowManaged = "window_managed";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using GlazeWM.Domain.Containers.Commands;
using GlazeWM.Domain.Containers.Events;
using GlazeWM.Infrastructure.Bussing;
using GlazeWM.Infrastructure.Utils;

Expand All @@ -9,10 +10,12 @@ namespace GlazeWM.Domain.Containers.CommandHandlers
internal sealed class MoveContainerWithinTreeHandler : ICommandHandler<MoveContainerWithinTreeCommand>
{
private readonly Bus _bus;
private readonly ContainerService _containerService;

public MoveContainerWithinTreeHandler(Bus bus)
public MoveContainerWithinTreeHandler(Bus bus, ContainerService containerService)
{
_bus = bus;
_containerService = containerService;
}

public CommandResponse Handle(MoveContainerWithinTreeCommand command)
Expand All @@ -32,6 +35,8 @@ public CommandResponse Handle(MoveContainerWithinTreeCommand command)
targetParent
);

var focusedContainer = _containerService.FocusedContainer;

// Handle case where target parent is the LCA (eg. in the case of swapping sibling containers
// or moving a container to a direct ancestor).
if (targetParent == lowestCommonAncestor)
Expand All @@ -43,8 +48,8 @@ public CommandResponse Handle(MoveContainerWithinTreeCommand command)
shouldAdjustSize
);

// Center cursor in focused window's new location
_bus.InvokeAsync(new CenterCursorOnContainerCommand(containerToMove));
if (containerToMove == focusedContainer)
_bus.Emit(new FocusedContainerMovedEvent(containerToMove));

return CommandResponse.Ok;
}
Expand Down Expand Up @@ -90,8 +95,8 @@ public CommandResponse Handle(MoveContainerWithinTreeCommand command)
targetParentAncestor
);

// Center cursor in focused window's new location
_bus.InvokeAsync(new CenterCursorOnContainerCommand(containerToMove));
if (containerToMove == focusedContainer)
_bus.Emit(new FocusedContainerMovedEvent(containerToMove));

return CommandResponse.Ok;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public CommandResponse Handle(SetNativeFocusCommand command)
KeybdEvent(0, 0, 0, 0);
SetForegroundWindow(handleToFocus);

_bus.Emit(new NativeFocusReassignedEvent(containerToFocus));

// Setting focus to the desktop window does not emit `EVENT_SYSTEM_FOREGROUND` window event,
// so `SetFocusedDescendantCommand` has to be manually called.
// TODO: This is called twice unnecessarily when setting workspace focus on unmanage.
Expand All @@ -45,9 +47,6 @@ public CommandResponse Handle(SetNativeFocusCommand command)
_bus.Emit(new FocusChangedEvent(containerToFocus));
}

// Center cursor in focused window's new location
_bus.InvokeAsync(new CenterCursorOnContainerCommand(containerToFocus));

return CommandResponse.Ok;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using GlazeWM.Domain.Common;
using GlazeWM.Infrastructure.Bussing;

namespace GlazeWM.Domain.Containers.Events
{
public record FocusedContainerMovedEvent(Container FocusedContainer)
: Event(DomainEvent.FocusedContainerMoved);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using GlazeWM.Domain.Common;
using GlazeWM.Infrastructure.Bussing;

namespace GlazeWM.Domain.Containers.Events
{
public record NativeFocusReassignedEvent(Container FocusedContainer)
: Event(DomainEvent.NativeFocusReassigned);
}

0 comments on commit 7f2e1de

Please sign in to comment.