{ "name": "Reposition Maximized Windows in their Closest Monitors/Splits", "language": 0, "code": "using System;\r\nusing System.Drawing;\r\nusing System.Collections.Generic;\r\n\r\n// The 'windowHandle' parameter will contain the window handle for the:\r\n// - Active window when run by hotkey\r\n// - Trigger target when run by a Trigger rule\r\n// - TitleBar Button owner when run by a TitleBar Button\r\n// - Jump List owner when run from a Taskbar Jump List\r\n// - Currently focused window if none of these match\r\npublic static class DisplayFusionFunction\r\n{\r\n\tpublic static void Run(IntPtr windowHandle)\r\n\t{\r\n\t\t// Store info about the monitors\r\n\t\tList info = new List();\t\t\r\n\t\tforeach(uint id in BFS.Monitor.GetMonitorIDs())\r\n\t\t\tinfo.Add(new MonitorInfo(id));\r\n\t\t\r\n\t\t// Enumerate through each visible window\r\n\t\tforeach(IntPtr window in BFS.Window.GetVisibleWindowHandles()) \r\n\t\t{\r\n\t\t\t// Make sure the window is valid\r\n\t\t\tif(IsDisplayFusionWindowOrHiddenExplorerWindow(window))\r\n\t\t\t\tcontinue;\r\n\t\t\t\r\n\t\t\t// Find the center of the window\r\n\t\t\tRectangle bounds = BFS.Window.GetBounds(window);\r\n\t\t\tPoint center = new Point(bounds.X + bounds.Width / 2, bounds.Y + bounds.Height / 2);\r\n\t\t\t\r\n\t\t\t// Compare the center of the window to each monitor's center\r\n\t\t\tList<(float distanceSquared, MonitorInfo info)> distances = new();\r\n\t\t\tforeach(MonitorInfo monitor in info) \r\n\t\t\t{\r\n\t\t\t\tfloat dx = monitor.Center.X - center.X;\r\n\t\t\t\tfloat dy = monitor.Center.Y - center.Y;\r\n\t\t\t\tfloat distanceSquared = dx*dx + dy*dy;\t\t\t\t\r\n\t\t\t\tdistances.Add((distanceSquared, monitor));\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t// Sort each monitor by its distance to the window\r\n\t\t\tdistances.Sort((a,b)=>\r\n\t\t\t{\r\n\t\t\t\treturn a.distanceSquared.CompareTo(b.distanceSquared);\r\n\t\t\t});\r\n\t\t\t\r\n\t\t\t// Check to see if the window size is similar to the closest monitor\r\n\t\t\tint widthMin = (int)(distances[0].info.Bounds.Width * 0.8);\r\n\t\t\tint widthMax = (int)(distances[0].info.Bounds.Width * 1.2);\r\n\t\t\tint heightMin = (int)(distances[0].info.Bounds.Height * 0.8);\r\n\t\t\tint heightMax = (int)(distances[0].info.Bounds.Height * 1.2);\r\n\t\t\tif( bounds.Width >= widthMin &&\r\n\t\t\t\tbounds.Width <= widthMax &&\r\n\t\t\t\tbounds.Height >= heightMin &&\r\n\t\t\t\tbounds.Height <= heightMax)\r\n\t\t\t{\r\n\t\t\t\t// If it is, Maximize the window in the closest monitor\r\n\t\t\t\tBFS.Window.MoveToMonitorMaximized(distances[0].info.Id, window);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\t\r\n\tprivate static bool IsDisplayFusionWindowOrHiddenExplorerWindow(IntPtr window)\r\n\t{\r\n // Ignore any DisplayFusion windows (title bar buttons, etc.)\r\n // Ignore pesky hidden explorer.exe windows\r\n string windowClass = BFS.Window.GetClass(window);\r\n if((windowClass.StartsWith(\"DF\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"EdgeUiInputTopWndClass\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"EdgeUiInputWndClass\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"NativeHWNDHost\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"ModeInputWnd\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"MetroGhostWindow\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"ImmersiveLauncher\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"ApplicationManager_ImmersiveShellWindow\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"Shell_TrayWnd\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"WorkerW\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"Progman\", StringComparison.OrdinalIgnoreCase)) ||\r\n (windowClass.Equals(\"SearchPane\", StringComparison.OrdinalIgnoreCase)))\r\n {\r\n return true;\r\n }\r\n \r\n return false;\r\n\t}\r\n\t\r\n\t// A class to calculate some useful info about each monitor/split\r\n\tpublic class MonitorInfo\r\n\t{\r\n\t\tpublic Rectangle Bounds {get; private set;}\r\n\t\tpublic Point Center {get; private set;}\r\n\t\tpublic uint Id {get; private set;}\r\n\t\t\r\n\t\tpublic MonitorInfo(uint id)\r\n\t\t{\r\n\t\t\tthis.Id = id;\r\n\t\t\tthis.Bounds = BFS.Monitor.GetMonitorWorkAreaByID(id);\r\n\t\t\tthis.Center = new Point(this.Bounds.X + this.Bounds.Width / 2, this.Bounds.Y + this.Bounds.Height / 2);\t\t\t\r\n\t\t}\r\n\t}\r\n}", "description": "", "references": "Microsoft.VisualBasic.Core.dll|Microsoft.Win32.Primitives.dll|Microsoft.Win32.Registry.dll|netstandard.dll|Newtonsoft.Json.dll|System.Collections.Concurrent.dll|System.Collections.dll|System.Collections.Immutable.dll|System.Collections.NonGeneric.dll|System.Collections.Specialized.dll|System.ComponentModel.Primitives.dll|System.ComponentModel.TypeConverter.dll|System.Console.dll|System.Core.dll|System.Data.dll|System.Diagnostics.Process.dll|System.dll|System.Drawing.Common.dll|System.Drawing.dll|System.Drawing.Primitives.dll|System.IO.Compression.dll|System.IO.dll|System.IO.FileSystem.Watcher.dll|System.Linq.dll|System.Linq.Expressions.dll|System.Linq.Parallel.dll|System.Linq.Queryable.dll|System.Management.dll|System.Net.dll|System.Net.Primitives.dll|System.Net.Requests.dll|System.Net.WebClient.dll|System.Net.WebHeaderCollection.dll|System.Private.CoreLib.dll|System.Private.Uri.dll|System.Private.Xml.dll|System.Runtime.dll|System.Runtime.InteropServices.dll|System.Runtime.Serialization.Formatters.dll|System.Security.Cryptography.Algorithms.dll|System.Security.Cryptography.Csp.dll|System.Security.Cryptography.dll|System.Security.Cryptography.Primitives.dll|System.Text.Json.dll|System.Text.RegularExpressions.dll|System.Threading.dll|System.Threading.Tasks.dll|System.Threading.Tasks.Parallel.dll|System.Web.dll|System.Web.HttpUtility.dll|System.Windows.Extensions.dll|System.Windows.Forms.dll|System.Windows.Forms.Primitives.dll|System.Xml.dll" }