From 05db0e53b8ce03c9e585f321b05cadbc8c6099fd Mon Sep 17 00:00:00 2001 From: Max Lefebvre Date: Sat, 16 Sep 2023 09:17:51 -0300 Subject: [PATCH] insepector updated to follow cursor --- .../Properties/launchSettings.json | 12 ++++++ GlazeWM.Domain/GlazeWM.Domain.csproj | 15 ++++++++ .../UserConfigs/CommandParsingService.cs | 4 +- .../CommandHandlers/InspectWindowHandler.cs | 32 +++++++++++----- GlazeWM.Domain/Windows/Inspector.Designer.cs | 36 +++++++----------- GlazeWM.Domain/Windows/Inspector.cs | 38 ++++++++++++++++++- GlazeWM.Infrastructure/WindowsApi/Point.cs | 16 ++++++++ 7 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 GlazeWM.App.IpcServer/Properties/launchSettings.json diff --git a/GlazeWM.App.IpcServer/Properties/launchSettings.json b/GlazeWM.App.IpcServer/Properties/launchSettings.json new file mode 100644 index 000000000..9a7ce8b8c --- /dev/null +++ b/GlazeWM.App.IpcServer/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "GlazeWM.App.IpcServer": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:61214;http://localhost:61215" + } + } +} \ No newline at end of file diff --git a/GlazeWM.Domain/GlazeWM.Domain.csproj b/GlazeWM.Domain/GlazeWM.Domain.csproj index dc36b139a..8c7e03ab1 100644 --- a/GlazeWM.Domain/GlazeWM.Domain.csproj +++ b/GlazeWM.Domain/GlazeWM.Domain.csproj @@ -12,4 +12,19 @@ + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + diff --git a/GlazeWM.Domain/UserConfigs/CommandParsingService.cs b/GlazeWM.Domain/UserConfigs/CommandParsingService.cs index 9fdd257bf..386879cb4 100644 --- a/GlazeWM.Domain/UserConfigs/CommandParsingService.cs +++ b/GlazeWM.Domain/UserConfigs/CommandParsingService.cs @@ -94,9 +94,7 @@ public Command ParseCommand(string commandString, Container subjectContainer) ? new IgnoreWindowCommand(subjectContainer as Window) : new NoopCommand(), "binding" => ParseBindingCommand(commandParts), - "inspect" => subjectContainer is Window - ? new InspectWindowCommand(subjectContainer as Window) - : new NoopCommand(), + "inspect" => new InspectWindowCommand(subjectContainer as Window), _ => throw new ArgumentException(null, nameof(commandString)), }; } diff --git a/GlazeWM.Domain/Windows/CommandHandlers/InspectWindowHandler.cs b/GlazeWM.Domain/Windows/CommandHandlers/InspectWindowHandler.cs index 2ca09e7b9..c24e4b005 100644 --- a/GlazeWM.Domain/Windows/CommandHandlers/InspectWindowHandler.cs +++ b/GlazeWM.Domain/Windows/CommandHandlers/InspectWindowHandler.cs @@ -1,3 +1,5 @@ +using System.Threading; +using System.Windows.Forms; using GlazeWM.Domain.Windows.Commands; using GlazeWM.Infrastructure.Bussing; @@ -7,18 +9,30 @@ internal class InspectWindowHandler : ICommandHandler { public CommandResponse Handle(InspectWindowCommand command) { - var inspector = new Inspector(); - inspector.SetTitle(command.WindowToInspect.Title); - inspector.SetClassName(command.WindowToInspect.ClassName); - inspector.SetProcessName(command.WindowToInspect.ProcessName); - inspector.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + // open inspector on a separate thread + var thread = new Thread(() => + { + using var inspector = new Inspector(); + inspector.ShowDialog(GetParentWindow(command.WindowToInspect)); + }); - // show dialog as child of parent window - var parentWindow = new System.Windows.Forms.NativeWindow(); - parentWindow.AssignHandle(command.WindowToInspect.Handle); - inspector.ShowDialog(parentWindow); + thread.SetApartmentState(ApartmentState.STA); + thread.Start(); return CommandResponse.Ok; } + + private static NativeWindow GetParentWindow(Window windowToInspect) + { + if (windowToInspect == null) + { + return null; + } + + var parentWindow = new NativeWindow(); + parentWindow.AssignHandle(windowToInspect.Handle); + + return parentWindow; + } } } diff --git a/GlazeWM.Domain/Windows/Inspector.Designer.cs b/GlazeWM.Domain/Windows/Inspector.Designer.cs index 588400248..2706696e0 100644 --- a/GlazeWM.Domain/Windows/Inspector.Designer.cs +++ b/GlazeWM.Domain/Windows/Inspector.Designer.cs @@ -1,3 +1,5 @@ +using System.Windows.Forms; + namespace GlazeWM.Domain.Windows { partial class Inspector @@ -17,6 +19,9 @@ protected override void Dispose(bool disposing) { components.Dispose(); } + + EventListener?.Dispose(); + base.Dispose(disposing); } @@ -28,12 +33,12 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - processNameLabel = new System.Windows.Forms.Label(); - classNameLabel = new System.Windows.Forms.Label(); - titleLabel = new System.Windows.Forms.Label(); - titleValue = new System.Windows.Forms.TextBox(); - classNameValue = new System.Windows.Forms.TextBox(); - processNameValue = new System.Windows.Forms.TextBox(); + processNameLabel = new Label(); + classNameLabel = new Label(); + titleLabel = new Label(); + titleValue = new TextBox(); + classNameValue = new TextBox(); + processNameValue = new TextBox(); SuspendLayout(); // // processNameLabel @@ -96,9 +101,9 @@ private void InitializeComponent() // Inspector // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + AutoScaleMode = AutoScaleMode.Font; BackColor = System.Drawing.SystemColors.Control; - ClientSize = new System.Drawing.Size(412, 116); + ClientSize = new System.Drawing.Size(414, 116); Controls.Add(processNameValue); Controls.Add(classNameValue); Controls.Add(titleValue); @@ -119,20 +124,5 @@ private void InitializeComponent() private System.Windows.Forms.TextBox titleValue; private System.Windows.Forms.TextBox classNameValue; private System.Windows.Forms.TextBox processNameValue; - - public void SetTitle(string title) - { - titleValue.Text = title; - } - - public void SetClassName(string className) - { - classNameValue.Text = className; - } - - public void SetProcessName(string processName) - { - processNameValue.Text = processName; - } } } diff --git a/GlazeWM.Domain/Windows/Inspector.cs b/GlazeWM.Domain/Windows/Inspector.cs index 0bb75d9e5..5f92cc0c2 100644 --- a/GlazeWM.Domain/Windows/Inspector.cs +++ b/GlazeWM.Domain/Windows/Inspector.cs @@ -1,16 +1,52 @@ +using System; +using System.Reactive.Linq; using System.Windows.Forms; +using GlazeWM.Infrastructure.WindowsApi; +using static GlazeWM.Infrastructure.WindowsApi.WindowsApiService; namespace GlazeWM.Domain.Windows { public partial class Inspector : Form { + public IDisposable EventListener { get; } + public Inspector() { InitializeComponent(); - MaximizeBox = false; MinimizeBox = false; FormBorderStyle = FormBorderStyle.FixedSingle; + StartPosition = FormStartPosition.CenterParent; + + var point = new Point(); + EventListener = MouseEvents.MouseMoves + .Sample(TimeSpan.FromMilliseconds(50)) + .Subscribe((@event) => + { + if (point.X == @event.Point.X && point.Y == @event.Point.Y) + { + return; + } + + point.X = @event.Point.X; + point.Y = @event.Point.Y; + var handle = WindowFromPoint(point); + + // get handle details + var processName = WindowService.GetProcessOfHandle(handle)?.ProcessName ?? string.Empty; + if (processName == "GlazeWM") + { + return; + } + + var title = WindowService.GetTitleOfHandle(handle) ?? string.Empty; + var className = WindowService.GetClassNameOfHandle(handle) ?? string.Empty; + + // update the inspector info + titleValue.Text = title; + classNameValue.Text = className; + processNameValue.Text = processName; + }); } } } diff --git a/GlazeWM.Infrastructure/WindowsApi/Point.cs b/GlazeWM.Infrastructure/WindowsApi/Point.cs index 93d8bd7fa..205cfaef3 100644 --- a/GlazeWM.Infrastructure/WindowsApi/Point.cs +++ b/GlazeWM.Infrastructure/WindowsApi/Point.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace GlazeWM.Infrastructure.WindowsApi @@ -7,5 +8,20 @@ public struct Point { public int X; public int Y; + + public static bool operator ==(Point obj1, Point obj2) + { + return obj1.Equals(obj2); + } + + public static bool operator !=(Point obj1, Point obj2) + { + return !(obj1 == obj2); + } + + public override bool Equals([NotNullWhen(true)] object obj) + { + return obj is Point other && other.X == X && other.Y == Y; + } } }