From e2851dd8118866bf5c5dd63a16db3fef07924a4b Mon Sep 17 00:00:00 2001 From: glax Date: Tue, 16 Apr 2024 04:46:17 +0200 Subject: [PATCH] Reduce Information overhead and catch closed windows. --- OBSBlur/OBS/Blur.cs | 102 +++++++++++------------ OBSBlur/Window/WindowInfo.cs | 17 ++-- OBSBlur/Window/WindowManager.cs | 14 ++-- OBSBlur/Window/WindowManagerUser32Dll.cs | 7 ++ 4 files changed, 74 insertions(+), 66 deletions(-) diff --git a/OBSBlur/OBS/Blur.cs b/OBSBlur/OBS/Blur.cs index a587a7c..68627a3 100644 --- a/OBSBlur/OBS/Blur.cs +++ b/OBSBlur/OBS/Blur.cs @@ -20,7 +20,6 @@ public class Blur { this.enabledScenes = enabledScenes; this.blurPrograms = blurPrograms; - windowManager.UpdateInterval = 1; _websocket.CurrentProgramSceneChanged += WebsocketOnCurrentProgramSceneChanged; _websocket.Connected += WebsocketOnConnected; _websocket.Disconnected += WebsocketOnDisconnected; @@ -40,34 +39,35 @@ public class Blur windowInfos ??= windowManager.WindowInfos; zOrder ??= windowManager.WindowZOrder; - bool addRemove = true; + bool maximixedWindowReached = false; foreach (IntPtr window in zOrder) { WindowInfo windowInfo = windowInfos.FirstOrDefault(w => w.WindowHandle == window); - if(windowInfo is {WindowHandle: 0x0}) + if(windowInfo is {WindowHandle: 0x0})//No WindowInfo found continue; - bool blur = false; - foreach(string program in blurPrograms) - if (windowInfo.ProcessInfo.ProcessName.Contains(program, StringComparison.OrdinalIgnoreCase)) - blur = true; - if(blur && addRemove) - BlurWindow(windowInfo); - else if(blur && addRemove is false) - DeleteBlur(windowInfo); + if(GetBlurWindow(windowInfo)) + if(!maximixedWindowReached) + BlurWindow(windowInfo); + else if(maximixedWindowReached) + DeleteBlur(windowInfo); - if (windowInfo.WindowPlacement.ShowCmd is ShowWindowCommands.Maximize) - addRemove = false; + if (windowInfo.WindowCommands is ShowWindowCommands.Maximize) + maximixedWindowReached = true; } - foreach(WindowInfo windowInfo in windowInfos) - if (windowInfo.WindowPlacement.ShowCmd is ShowWindowCommands.ShowMinimized && - windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle)) - { - DeleteBlur(windowInfo); - windowHandleSceneItems.Remove(windowInfo.WindowHandle); - } + foreach(IntPtr blurredWindow in windowHandleSceneItems.Keys.ToArray()) + if(!windowInfos.Any(w => w.WindowHandle == blurredWindow)) + DeleteBlur(blurredWindow); + } + + private bool GetBlurWindow(WindowInfo windowInfo) + { + foreach(string program in blurPrograms) + if (windowInfo.ProcessInfo.ProcessName.Contains(program)) + return true; + return false; } private void BlurWindow(WindowInfo windowInfo) @@ -103,26 +103,14 @@ public class Blur if (!windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle)) return; - SceneItemTransformInfo info = windowInfo.WindowPlacement.ShowCmd switch + SceneItemTransformInfo info = new() { - ShowWindowCommands.Maximize => new () - { - X = 0, - Y = 0, - BoundsHeight = 1080, //TODO desktop res - BoundsWidth = 1920, - BoundsType = SceneItemBoundsType.OBS_BOUNDS_STRETCH, - Alignnment = 5 - }, - _ => new() - { - X = windowInfo.WindowPlacement.NormalPosition.Left, - Y = windowInfo.WindowPlacement.NormalPosition.Top, - BoundsHeight = windowInfo.WindowPlacement.NormalPosition.Height, - BoundsWidth = windowInfo.WindowPlacement.NormalPosition.Width, - BoundsType = SceneItemBoundsType.OBS_BOUNDS_STRETCH, - Alignnment = 5 - }, + X = windowInfo.WindowRectangle.X, + Y = windowInfo.WindowRectangle.Y, + BoundsHeight = windowInfo.WindowRectangle.Height, + BoundsWidth = windowInfo.WindowRectangle.Width, + BoundsType = SceneItemBoundsType.OBS_BOUNDS_STRETCH, + Alignnment = 5 }; Dictionary request = new() @@ -143,17 +131,22 @@ public class Blur _websocket.SendRequest("SetSceneItemEnabled", JObject.FromObject(request2)); } - private void DeleteBlur(WindowInfo windowInfo) + private void DeleteBlur(IntPtr windowHandle) { - if (!windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle)) + if (!windowHandleSceneItems.ContainsKey(windowHandle)) return; Dictionary request = new() { {"sceneName", currentScene}, - {"sceneItemId", windowHandleSceneItems[windowInfo.WindowHandle]} + {"sceneItemId", windowHandleSceneItems[windowHandle]} }; _websocket.SendRequest("RemoveSceneItem", JObject.FromObject(request)); - windowHandleSceneItems.Remove(windowInfo.WindowHandle); + windowHandleSceneItems.Remove(windowHandle); + } + + private void DeleteBlur(WindowInfo windowInfo) + { + DeleteBlur(windowInfo.WindowHandle); } private uint GetBlurSource() @@ -177,19 +170,18 @@ public class Blur private void WindowManagerOnWindowZOrderChanged(IntPtr[] neworder) { - /* - uint i = 0; - string prnt = ""; - foreach (IntPtr windowHandle in order) - { - WindowInfo windowInfo = windowManager.WindowInfos.FirstOrDefault(w => w.WindowHandle == windowHandle); - if(windowInfo.WindowHandle is 0x0) - continue; - prnt += $"{++i,3} {windowInfo}\n"; - } + + uint i = 0; + string prnt = ""; + foreach (IntPtr windowHandle in neworder) + { + WindowInfo windowInfo = windowManager.WindowInfos.FirstOrDefault(w => w.WindowHandle == windowHandle); + if (windowInfo.WindowHandle is 0x0) + continue; + prnt += $"{++i,3} {windowInfo}\n"; + } - Console.Clear(); - Console.WriteLine(prnt);*/ + Console.WriteLine(prnt); Console.WriteLine($"Z-order changed {DateTime.UtcNow:O}"); UpdateBlurs(zOrder: neworder); } diff --git a/OBSBlur/Window/WindowInfo.cs b/OBSBlur/Window/WindowInfo.cs index 0634369..eaf8baa 100644 --- a/OBSBlur/Window/WindowInfo.cs +++ b/OBSBlur/Window/WindowInfo.cs @@ -5,15 +5,19 @@ namespace OBSBlur.Window; public struct WindowInfo { internal IntPtr WindowHandle { get; init; } - public WindowPlacement WindowPlacement { get; init; } + public bool IsVisible { get; init; } + public ShowWindowCommands WindowCommands { get; init; } + public Rectangle WindowRectangle { get; init; } public string WindowTitle { get; init; } public Process ProcessInfo { get; init; } - public WindowInfo(IntPtr windowHandle, string windowTitle, Process processInfo, WindowPlacement windowPlacement) + public WindowInfo(IntPtr windowHandle, string windowTitle, Process processInfo, bool isWindowVisible, ShowWindowCommands windowCommands, Rectangle windowRectangle) { this.WindowHandle = windowHandle; this.ProcessInfo = processInfo; - this.WindowPlacement = windowPlacement; + this.IsVisible = isWindowVisible; + this.WindowCommands = windowCommands; + this.WindowRectangle = windowRectangle; this.WindowTitle = windowTitle; } @@ -25,7 +29,8 @@ public struct WindowInfo public bool Equals(WindowInfo other) { return WindowHandle == other.WindowHandle && - WindowPlacement.Equals(other.WindowPlacement) && + IsVisible == other.IsVisible && + WindowCommands == other.WindowCommands && WindowTitle.Equals(other.WindowTitle) && ProcessInfo.ProcessName.Equals(other.ProcessInfo.ProcessName) && ProcessInfo.Id == other.ProcessInfo.Id; @@ -33,7 +38,7 @@ public struct WindowInfo public override int GetHashCode() { - return HashCode.Combine(WindowHandle, WindowPlacement, WindowTitle, ProcessInfo); + return HashCode.Combine(WindowHandle, IsVisible, WindowTitle, ProcessInfo); } public override string ToString() @@ -41,6 +46,6 @@ public struct WindowInfo const int cutoffStr = 17; string processNameStr = ProcessInfo.ProcessName.Substring(0, Math.Min(cutoffStr, ProcessInfo.ProcessName.Length)); string windowTitleStr = WindowTitle.Substring(0, Math.Min(cutoffStr, WindowTitle.Length)); - return $"{WindowHandle,8} {ProcessInfo.Id,8} {processNameStr,cutoffStr} {windowTitleStr,-cutoffStr} {WindowPlacement}"; + return $"{WindowHandle,8} {ProcessInfo.Id,8} {processNameStr,cutoffStr} {windowTitleStr,-cutoffStr} {(IsVisible ? "visible" : "hidden"),-8} {WindowCommands,-13} {WindowRectangle}"; } } \ No newline at end of file diff --git a/OBSBlur/Window/WindowManager.cs b/OBSBlur/Window/WindowManager.cs index 6ecf22c..e6e3d67 100644 --- a/OBSBlur/Window/WindowManager.cs +++ b/OBSBlur/Window/WindowManager.cs @@ -58,12 +58,13 @@ public partial class WindowManager : IDisposable private bool GetWindowInfo(IntPtr windowHandle, IntPtr lParam) { - WindowPlacement windowPlacement = new (); - GetWindowPlacement(windowHandle, ref windowPlacement); - Rectangle n = windowPlacement.NormalPosition; + bool isVisible = IsWindowVisible(windowHandle); //Do not add if Window is not a drawable - if (n is { Left: 0, Top: 0, Right: 0, Bottom: 0 }) + if (!isVisible) return true; + + WindowPlacement placement = new (); + GetWindowPlacement(windowHandle, ref placement); uint pid; GetWindowThreadProcessId(windowHandle, out pid); @@ -76,7 +77,10 @@ public partial class WindowManager : IDisposable if (windowTitle.Length < 1) return true; - _windows.Add(new WindowInfo(windowHandle, windowTitle, processInfo, windowPlacement)); + Rectangle rect; + GetWindowRect(windowHandle, out rect); + + _windows.Add(new WindowInfo(windowHandle, windowTitle, processInfo, isVisible, placement.ShowCmd, rect)); return true; } diff --git a/OBSBlur/Window/WindowManagerUser32Dll.cs b/OBSBlur/Window/WindowManagerUser32Dll.cs index 5a7b4ce..1c69ecb 100644 --- a/OBSBlur/Window/WindowManagerUser32Dll.cs +++ b/OBSBlur/Window/WindowManagerUser32Dll.cs @@ -16,6 +16,13 @@ public partial class WindowManager [DllImport("user32.dll")] static extern IntPtr GetTopWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + static extern bool GetWindowRect(IntPtr hWnd, out Rectangle rectangle); + + [DllImport("user32.dll")] + static extern bool IsWindowVisible(IntPtr hWnd); + static List GetWindowZOrder() { const uint GW_HWNDNEXT = 2;