Reduce Information overhead and catch closed windows.

This commit is contained in:
glax 2024-04-16 04:46:17 +02:00
parent 073c2beebc
commit e2851dd811
4 changed files with 74 additions and 66 deletions

View File

@ -20,7 +20,6 @@ public class Blur
{ {
this.enabledScenes = enabledScenes; this.enabledScenes = enabledScenes;
this.blurPrograms = blurPrograms; this.blurPrograms = blurPrograms;
windowManager.UpdateInterval = 1;
_websocket.CurrentProgramSceneChanged += WebsocketOnCurrentProgramSceneChanged; _websocket.CurrentProgramSceneChanged += WebsocketOnCurrentProgramSceneChanged;
_websocket.Connected += WebsocketOnConnected; _websocket.Connected += WebsocketOnConnected;
_websocket.Disconnected += WebsocketOnDisconnected; _websocket.Disconnected += WebsocketOnDisconnected;
@ -40,34 +39,35 @@ public class Blur
windowInfos ??= windowManager.WindowInfos; windowInfos ??= windowManager.WindowInfos;
zOrder ??= windowManager.WindowZOrder; zOrder ??= windowManager.WindowZOrder;
bool addRemove = true; bool maximixedWindowReached = false;
foreach (IntPtr window in zOrder) foreach (IntPtr window in zOrder)
{ {
WindowInfo windowInfo = windowInfos.FirstOrDefault(w => w.WindowHandle == window); WindowInfo windowInfo = windowInfos.FirstOrDefault(w => w.WindowHandle == window);
if(windowInfo is {WindowHandle: 0x0}) if(windowInfo is {WindowHandle: 0x0})//No WindowInfo found
continue; continue;
bool blur = false;
foreach(string program in blurPrograms)
if (windowInfo.ProcessInfo.ProcessName.Contains(program, StringComparison.OrdinalIgnoreCase))
blur = true;
if(blur && addRemove) if(GetBlurWindow(windowInfo))
BlurWindow(windowInfo); if(!maximixedWindowReached)
else if(blur && addRemove is false) BlurWindow(windowInfo);
DeleteBlur(windowInfo); else if(maximixedWindowReached)
DeleteBlur(windowInfo);
if (windowInfo.WindowPlacement.ShowCmd is ShowWindowCommands.Maximize) if (windowInfo.WindowCommands is ShowWindowCommands.Maximize)
addRemove = false; maximixedWindowReached = true;
} }
foreach(WindowInfo windowInfo in windowInfos) foreach(IntPtr blurredWindow in windowHandleSceneItems.Keys.ToArray())
if (windowInfo.WindowPlacement.ShowCmd is ShowWindowCommands.ShowMinimized && if(!windowInfos.Any(w => w.WindowHandle == blurredWindow))
windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle)) DeleteBlur(blurredWindow);
{ }
DeleteBlur(windowInfo);
windowHandleSceneItems.Remove(windowInfo.WindowHandle); 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) private void BlurWindow(WindowInfo windowInfo)
@ -103,26 +103,14 @@ public class Blur
if (!windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle)) if (!windowHandleSceneItems.ContainsKey(windowInfo.WindowHandle))
return; return;
SceneItemTransformInfo info = windowInfo.WindowPlacement.ShowCmd switch SceneItemTransformInfo info = new()
{ {
ShowWindowCommands.Maximize => new () X = windowInfo.WindowRectangle.X,
{ Y = windowInfo.WindowRectangle.Y,
X = 0, BoundsHeight = windowInfo.WindowRectangle.Height,
Y = 0, BoundsWidth = windowInfo.WindowRectangle.Width,
BoundsHeight = 1080, //TODO desktop res BoundsType = SceneItemBoundsType.OBS_BOUNDS_STRETCH,
BoundsWidth = 1920, Alignnment = 5
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
},
}; };
Dictionary<string, object> request = new() Dictionary<string, object> request = new()
@ -143,17 +131,22 @@ public class Blur
_websocket.SendRequest("SetSceneItemEnabled", JObject.FromObject(request2)); _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; return;
Dictionary<string, object> request = new() Dictionary<string, object> request = new()
{ {
{"sceneName", currentScene}, {"sceneName", currentScene},
{"sceneItemId", windowHandleSceneItems[windowInfo.WindowHandle]} {"sceneItemId", windowHandleSceneItems[windowHandle]}
}; };
_websocket.SendRequest("RemoveSceneItem", JObject.FromObject(request)); _websocket.SendRequest("RemoveSceneItem", JObject.FromObject(request));
windowHandleSceneItems.Remove(windowInfo.WindowHandle); windowHandleSceneItems.Remove(windowHandle);
}
private void DeleteBlur(WindowInfo windowInfo)
{
DeleteBlur(windowInfo.WindowHandle);
} }
private uint GetBlurSource() private uint GetBlurSource()
@ -177,19 +170,18 @@ public class Blur
private void WindowManagerOnWindowZOrderChanged(IntPtr[] neworder) private void WindowManagerOnWindowZOrderChanged(IntPtr[] neworder)
{ {
/*
uint i = 0; uint i = 0;
string prnt = ""; string prnt = "";
foreach (IntPtr windowHandle in order) foreach (IntPtr windowHandle in neworder)
{ {
WindowInfo windowInfo = windowManager.WindowInfos.FirstOrDefault(w => w.WindowHandle == windowHandle); WindowInfo windowInfo = windowManager.WindowInfos.FirstOrDefault(w => w.WindowHandle == windowHandle);
if(windowInfo.WindowHandle is 0x0) if (windowInfo.WindowHandle is 0x0)
continue; continue;
prnt += $"{++i,3} {windowInfo}\n"; prnt += $"{++i,3} {windowInfo}\n";
} }
Console.Clear(); Console.WriteLine(prnt);
Console.WriteLine(prnt);*/
Console.WriteLine($"Z-order changed {DateTime.UtcNow:O}"); Console.WriteLine($"Z-order changed {DateTime.UtcNow:O}");
UpdateBlurs(zOrder: neworder); UpdateBlurs(zOrder: neworder);
} }

View File

@ -5,15 +5,19 @@ namespace OBSBlur.Window;
public struct WindowInfo public struct WindowInfo
{ {
internal IntPtr WindowHandle { get; init; } 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 string WindowTitle { get; init; }
public Process ProcessInfo { 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.WindowHandle = windowHandle;
this.ProcessInfo = processInfo; this.ProcessInfo = processInfo;
this.WindowPlacement = windowPlacement; this.IsVisible = isWindowVisible;
this.WindowCommands = windowCommands;
this.WindowRectangle = windowRectangle;
this.WindowTitle = windowTitle; this.WindowTitle = windowTitle;
} }
@ -25,7 +29,8 @@ public struct WindowInfo
public bool Equals(WindowInfo other) public bool Equals(WindowInfo other)
{ {
return WindowHandle == other.WindowHandle && return WindowHandle == other.WindowHandle &&
WindowPlacement.Equals(other.WindowPlacement) && IsVisible == other.IsVisible &&
WindowCommands == other.WindowCommands &&
WindowTitle.Equals(other.WindowTitle) && WindowTitle.Equals(other.WindowTitle) &&
ProcessInfo.ProcessName.Equals(other.ProcessInfo.ProcessName) && ProcessInfo.ProcessName.Equals(other.ProcessInfo.ProcessName) &&
ProcessInfo.Id == other.ProcessInfo.Id; ProcessInfo.Id == other.ProcessInfo.Id;
@ -33,7 +38,7 @@ public struct WindowInfo
public override int GetHashCode() public override int GetHashCode()
{ {
return HashCode.Combine(WindowHandle, WindowPlacement, WindowTitle, ProcessInfo); return HashCode.Combine(WindowHandle, IsVisible, WindowTitle, ProcessInfo);
} }
public override string ToString() public override string ToString()
@ -41,6 +46,6 @@ public struct WindowInfo
const int cutoffStr = 17; const int cutoffStr = 17;
string processNameStr = ProcessInfo.ProcessName.Substring(0, Math.Min(cutoffStr, ProcessInfo.ProcessName.Length)); string processNameStr = ProcessInfo.ProcessName.Substring(0, Math.Min(cutoffStr, ProcessInfo.ProcessName.Length));
string windowTitleStr = WindowTitle.Substring(0, Math.Min(cutoffStr, WindowTitle.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}";
} }
} }

View File

@ -58,12 +58,13 @@ public partial class WindowManager : IDisposable
private bool GetWindowInfo(IntPtr windowHandle, IntPtr lParam) private bool GetWindowInfo(IntPtr windowHandle, IntPtr lParam)
{ {
WindowPlacement windowPlacement = new (); bool isVisible = IsWindowVisible(windowHandle);
GetWindowPlacement(windowHandle, ref windowPlacement);
Rectangle n = windowPlacement.NormalPosition;
//Do not add if Window is not a drawable //Do not add if Window is not a drawable
if (n is { Left: 0, Top: 0, Right: 0, Bottom: 0 }) if (!isVisible)
return true; return true;
WindowPlacement placement = new ();
GetWindowPlacement(windowHandle, ref placement);
uint pid; uint pid;
GetWindowThreadProcessId(windowHandle, out pid); GetWindowThreadProcessId(windowHandle, out pid);
@ -76,7 +77,10 @@ public partial class WindowManager : IDisposable
if (windowTitle.Length < 1) if (windowTitle.Length < 1)
return true; 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; return true;
} }

View File

@ -16,6 +16,13 @@ public partial class WindowManager
[DllImport("user32.dll")] [DllImport("user32.dll")]
static extern IntPtr GetTopWindow(IntPtr hWnd); 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<IntPtr> GetWindowZOrder() static List<IntPtr> GetWindowZOrder()
{ {
const uint GW_HWNDNEXT = 2; const uint GW_HWNDNEXT = 2;