From fd37dc08ba5d0b412ddf8a0128e3713fb35d0ae8 Mon Sep 17 00:00:00 2001 From: lars-berger Date: Fri, 8 Sep 2023 04:32:38 +0800 Subject: [PATCH] fix: update id when the `Container` type changes (#384) --- .../Containers/CommandHandlers/RedrawContainersHandler.cs | 3 +-- GlazeWM.Domain/Containers/Container.cs | 2 +- .../CommandHandlers/RegisterKeybindingsHandler.cs | 1 - .../CommandHandlers/RunWithSubjectContainerHandler.cs | 7 ++++--- .../Windows/CommandHandlers/SetFloatingHandler.cs | 5 ++++- .../Windows/CommandHandlers/SetTilingHandler.cs | 5 ++++- .../Windows/EventHandlers/WindowFocusedHandler.cs | 7 +------ .../Windows/EventHandlers/WindowMinimizeEndedHandler.cs | 5 ++++- .../Windows/EventHandlers/WindowMinimizedHandler.cs | 5 ++++- .../CommandHandlers/MoveWindowToWorkspaceHandler.cs | 8 -------- 10 files changed, 23 insertions(+), 25 deletions(-) diff --git a/GlazeWM.Domain/Containers/CommandHandlers/RedrawContainersHandler.cs b/GlazeWM.Domain/Containers/CommandHandlers/RedrawContainersHandler.cs index 9a7269fbe..aa4f33c76 100644 --- a/GlazeWM.Domain/Containers/CommandHandlers/RedrawContainersHandler.cs +++ b/GlazeWM.Domain/Containers/CommandHandlers/RedrawContainersHandler.cs @@ -68,8 +68,7 @@ private void SetWindowPosition(Window window) SetWindowPosFlags.FrameChanged | SetWindowPosFlags.NoActivate | SetWindowPosFlags.NoCopyBits | - SetWindowPosFlags.NoSendChanging | - SetWindowPosFlags.AsyncWindowPos; + SetWindowPosFlags.NoSendChanging; // Show or hide the window depending on whether the workspace is displayed. if (window.IsDisplayed) diff --git a/GlazeWM.Domain/Containers/Container.cs b/GlazeWM.Domain/Containers/Container.cs index cfbb91fd5..91943de5b 100644 --- a/GlazeWM.Domain/Containers/Container.cs +++ b/GlazeWM.Domain/Containers/Container.cs @@ -11,7 +11,7 @@ public abstract class Container /// /// A unique identifier for the container. /// - public Guid Id { get; } = Guid.NewGuid(); + public Guid Id { get; set; } = Guid.NewGuid(); /// /// Derived container type (eg. `ContainerType.Monitor`). diff --git a/GlazeWM.Domain/UserConfigs/CommandHandlers/RegisterKeybindingsHandler.cs b/GlazeWM.Domain/UserConfigs/CommandHandlers/RegisterKeybindingsHandler.cs index 0090d8f04..e41470a41 100644 --- a/GlazeWM.Domain/UserConfigs/CommandHandlers/RegisterKeybindingsHandler.cs +++ b/GlazeWM.Domain/UserConfigs/CommandHandlers/RegisterKeybindingsHandler.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Threading.Tasks; -using GlazeWM.Domain.Containers; using GlazeWM.Domain.UserConfigs.Commands; using GlazeWM.Domain.Windows; using GlazeWM.Infrastructure.Bussing; diff --git a/GlazeWM.Domain/UserConfigs/CommandHandlers/RunWithSubjectContainerHandler.cs b/GlazeWM.Domain/UserConfigs/CommandHandlers/RunWithSubjectContainerHandler.cs index c1ce148be..9a241902d 100644 --- a/GlazeWM.Domain/UserConfigs/CommandHandlers/RunWithSubjectContainerHandler.cs +++ b/GlazeWM.Domain/UserConfigs/CommandHandlers/RunWithSubjectContainerHandler.cs @@ -2,6 +2,7 @@ using GlazeWM.Domain.Containers; using GlazeWM.Domain.UserConfigs.Commands; using GlazeWM.Infrastructure.Bussing; +using GlazeWM.Infrastructure.Utils; namespace GlazeWM.Domain.UserConfigs.CommandHandlers { @@ -24,15 +25,15 @@ public RunWithSubjectContainerHandler( public CommandResponse Handle(RunWithSubjectContainerCommand command) { - var commandStrings = command.CommandStrings; + var commandStrings = command.CommandStrings.ToList(); var subjectContainer = command.SubjectContainer ?? _containerService.FocusedContainer; var subjectContainerId = subjectContainer.Id; - // Return early if any of the commands is an ignore command. + // Evaluate ignore rules first (avoids jitters if another rule triggers a redraw). if (commandStrings.Any(command => command == "ignore")) - return CommandResponse.Ok; + commandStrings.MoveToFront("ignore"); // Invoke commands in sequence. foreach (var commandString in commandStrings) diff --git a/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs index 1a84b2187..3c4bcf377 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/SetFloatingHandler.cs @@ -35,7 +35,10 @@ public CommandResponse Handle(SetFloatingCommand command) window.Handle, window.FloatingPlacement, window.BorderDelta - ); + ) + { + Id = window.Id + }; _bus.Invoke(new ReplaceContainerCommand(floatingWindow, window.Parent, window.Index)); _bus.Invoke(new RedrawContainersCommand()); diff --git a/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs index 0abcabab3..8ef607532 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/SetTilingHandler.cs @@ -32,7 +32,10 @@ public CommandResponse Handle(SetTilingCommand command) window.FloatingPlacement, window.BorderDelta, 0 - ); + ) + { + Id = window.Id + }; // Replace the original window with the created tiling window. _bus.Invoke(new ReplaceContainerCommand(tilingWindow, window.Parent, window.Index)); diff --git a/GlazeWM.Domain/Windows/EventHandlers/WindowFocusedHandler.cs b/GlazeWM.Domain/Windows/EventHandlers/WindowFocusedHandler.cs index e3142a9d4..5be8315c5 100644 --- a/GlazeWM.Domain/Windows/EventHandlers/WindowFocusedHandler.cs +++ b/GlazeWM.Domain/Windows/EventHandlers/WindowFocusedHandler.cs @@ -68,13 +68,8 @@ public void Handle(WindowFocusedEvent @event) var window = _windowService.GetWindows() .FirstOrDefault(window => window.Handle == @event.WindowHandle); - if (window is null) + if (window is null || window?.IsDisplayed == false) return; - if (!window.IsDisplayed) - { - var offScreenWorkspace = WorkspaceService.GetWorkspaceFromChildContainer(window); - _bus.Invoke(new FocusWorkspaceCommand(offScreenWorkspace.Name)); - } _logger.LogWindowEvent("Window focused", window); diff --git a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs index a95726770..a3a54f6b1 100644 --- a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs +++ b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizeEndedHandler.cs @@ -68,7 +68,7 @@ public void Handle(WindowMinimizeEndedEvent @event) private static Window CreateWindowFromPreviousState(MinimizedWindow window) { - return window.PreviousState switch + Window restoredWindow = window.PreviousState switch { WindowType.Floating => new FloatingWindow( window.Handle, @@ -95,6 +95,9 @@ private static Window CreateWindowFromPreviousState(MinimizedWindow window) WindowType.Minimized => throw new ArgumentException(null, nameof(window)), _ => throw new ArgumentException(null, nameof(window)), }; + + restoredWindow.Id = window.Id; + return restoredWindow; } } } diff --git a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs index 07f2dff27..dfdb097c8 100644 --- a/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs +++ b/GlazeWM.Domain/Windows/EventHandlers/WindowMinimizedHandler.cs @@ -50,7 +50,10 @@ public void Handle(WindowMinimizedEvent @event) window.FloatingPlacement, window.BorderDelta, previousState - ); + ) + { + Id = window.Id + }; // Get container to switch focus to after the window has been minimized. var focusTarget = WindowService.GetFocusTargetAfterRemoval(window); diff --git a/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs b/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs index 3919cc9cc..8ff474f89 100644 --- a/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs +++ b/GlazeWM.Domain/Workspaces/CommandHandlers/MoveWindowToWorkspaceHandler.cs @@ -54,19 +54,11 @@ public CommandResponse Handle(MoveWindowToWorkspaceCommand command) var focusTarget = WindowService.GetFocusTargetAfterRemoval(windowToMove); - // Since the workspace that gets displayed is the last focused child, focus needs to be - // reassigned to the displayed workspace. - var targetMonitor = targetWorkspace.Parent as Monitor; - var focusResetTarget = targetWorkspace.IsDisplayed ? null : targetMonitor.LastFocusedDescendant; - if (windowToMove is TilingWindow) MoveTilingWindowToWorkspace(windowToMove as TilingWindow, targetWorkspace); else _bus.Invoke(new MoveContainerWithinTreeCommand(windowToMove, targetWorkspace, false)); - if (focusResetTarget is not null) - _bus.Invoke(new SetFocusedDescendantCommand(focusResetTarget)); - // Reassign focus to descendant within the current workspace. Need to call // `SetFocusedDescendantCommand` for when commands like `FocusWorkspaceCommand` are called // immediately afterwards and they should behave as if `focusTarget` is the focused