Processing Ajax...
Save 25% on our desktop apps during our Black Friday/Cyber Monday sale!Save 25% on our desktop apps during our Black Friday/Cyber Monday sale, including DisplayFusion, ClipboardFusion, FileSeek, LogFusion, TrayStatus, and VoiceBot!Save 25% on our desktop apps during our Black Friday/Cyber Monday sale!

Title
Close Dialog

Message

Confirm
Close Dialog

Confirm
Close Dialog

Tile Windows on Current Monitor

Description
Tiles the windows on the current monitor.
Language
C#.net
Minimum Version
Created By
Thomas Malloch (BFS)
Contributors
-
Date Created
Jul 12, 2018
Date Last Modified
Jul 12, 2018

Scripted Function (Macro) Code

using System;
using System.Drawing;
using System.Collections.Generic;

// The 'windowHandle' parameter will contain the window handle for the:
//   - Active window when run by hotkey
//   - Trigger target when run by a Trigger rule
//   - TitleBar Button owner when run by a TitleBar Button
//   - Jump List owner when run from a Taskbar Jump List
//   - Currently focused window if none of these match
public static class DisplayFusionFunction
{
	public static void Run(IntPtr windowHandle)
	{
        // Get the current monitor id from the current mouse position
		uint monitor = BFS.Monitor.GetMonitorIDByXY(BFS.Input.GetMousePositionX(), BFS.Input.GetMousePositionY());
		
		// Get the visible windows on that monitor
		List<IntPtr> windows = new List<IntPtr>();
		foreach(IntPtr window in BFS.Window.GetVisibleWindowHandlesByMonitor(monitor))
		{
            if(IsDisplayFusionWindowOrHiddenExplorerWindow(window))
                continue;
                
            windows.Add(window);
		}
		
		// Compute the bounds for the windows
        List<Rectangle> bounds = GetWindowBounds(windows.Count, monitor);
		
		// Loop through each window, and set it's bounds to the computed bounds
		for(int i = 0; (i < windows.Count) && (i < bounds.Count); i++)		
            BFS.Window.SetSizeAndLocation(windows[i], bounds[i].X, bounds[i].Y, bounds[i].Width, bounds[i].Height);			
	}
	
	// This function takes the bounds of the current monitor, then figures out where each window should be to stack them nicely
	private static List<Rectangle> GetWindowBounds(int numberOfWindows, uint monitor)
	{
        Rectangle bounds = BFS.Monitor.GetMonitorWorkAreaByID(monitor);
        List<Rectangle> windowBounds = new List<Rectangle>();
        if (numberOfWindows == 1)
        {
            windowBounds.Add(bounds);                
        }
        else
        {
            int rows = (numberOfWindows <= 8) ? 2 : 3;
            if (numberOfWindows == 2)
                rows = 1;

            int leftover = numberOfWindows % rows;
            int cols = (numberOfWindows + leftover) / rows;
            int topCols = numberOfWindows % cols;

            for (int i = 0; i < numberOfWindows; i++)
            {
                if (i < topCols)
                {
                    windowBounds.Add(new Rectangle(bounds.X + bounds.Width * i / topCols, bounds.Y, bounds.Width / topCols, bounds.Height / rows));
                }
                else
                {
                    int currentCol = (i - topCols) % cols;
                    int currentRow = i / cols;
                    if (topCols > 0)
                        currentRow = (i + (cols - topCols)) / cols;

                    windowBounds.Add(new Rectangle(bounds.X + bounds.Width * currentCol / cols, bounds.Y + bounds.Height * currentRow / rows, bounds.Width / cols, bounds.Height / rows));
                }
            }
        }
        
        return windowBounds;
	}
	
	private static bool IsDisplayFusionWindowOrHiddenExplorerWindow(IntPtr window)
	{
        //ignore any DisplayFusion windows (title bar buttons, etc.)
        //ignore pesky hidden explorer.exe windows
        if((BFS.Window.GetClass(window).StartsWith("DF", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("EdgeUiInputTopWndClass", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("EdgeUiInputWndClass", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("NativeHWNDHost", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("ModeInputWnd", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("MetroGhostWindow", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("ImmersiveLauncher", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("ApplicationManager_ImmersiveShellWindow", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("Shell_TrayWnd", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("WorkerW", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("Progman", StringComparison.OrdinalIgnoreCase)) ||
            (BFS.Window.GetClass(window).Equals("SearchPane", StringComparison.OrdinalIgnoreCase)))
        {
            return true;
        }
        
        return false;
	}
}