Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure?
Save up to 50% on our desktop apps during our big Summer Sale!Save up to 50% on our desktop apps during our big Summer Sale, including DisplayFusion, ClipboardFusion, FileSeek, LogFusion, TrayStatus, and VoiceBot!Save up to 50% on our desktop apps during our big Summer Sale!

Cascade Windows of Focused App

Description
Cascades all windows belonging to the same application as the currently focused window, restoring the classic Windows "Cascade windows" behavior on a per-app basis (removed in Windows 11).
Windows are restored if minimized or maximized, then laid out diagonally on the monitor containing the focused window at roughly 60% of its work area size. The layout wraps back to the top-left if it would run off the screen. The focused window is cascaded last and stays on top and active.
Language
C#.net
Minimum Version
Created By
Yirg
Contributors
-
Date Created
3d ago
Date Last Modified
3d ago

Scripted Function (Macro) Code

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

// DisplayFusion Scripted Function, created with Anthropic Fable 5
// Cascades all visible top-level windows of the currently focused application,
// replicating the classic "Cascade windows" behavior removed in Windows 11.
// Windows are stacked diagonally on the monitor containing the focused window.

public static class DisplayFusionFunction
{
    public static void Run(IntPtr windowHandle)
    {
        // Get the focused window; fall back to the handle DisplayFusion passes in
        IntPtr focused = BFS.Window.GetFocusedWindow();
        if (focused == IntPtr.Zero)
            focused = windowHandle;
        if (focused == IntPtr.Zero)
            return;

        // Identify the owning application by process ID
        uint processId = BFS.Application.GetAppIDByWindow(focused);
        if (processId == 0)
            return;

        // Collect all candidate windows belonging to this process
        List<IntPtr> windows = new List<IntPtr>();
        foreach (IntPtr handle in BFS.Window.GetVisibleAndMinimizedWindowHandles())
        {
            if (BFS.Application.GetAppIDByWindow(handle) != processId)
                continue;

            // Skip tool windows, borderless popups, and windows without a title
            if (string.IsNullOrEmpty(BFS.Window.GetText(handle)))
                continue;

            windows.Add(handle);
        }

        if (windows.Count == 0)
            return;

        // Cascade on the monitor that contains the focused window
        Rectangle workArea = BFS.Monitor.GetMonitorWorkAreaByWindow(focused);

        // Classic cascade metrics: offset roughly one title bar height per step,
        // window sized to a large fraction of the work area
        int offset = 32; // approximate title bar height at 100% DPI
        int width = (int)(workArea.Width * 0.6);
        int height = (int)(workArea.Height * 0.6);

        // Sort by Z-order is not directly exposed, so keep enumeration order
        // but move the focused window to the end so it lands on top
        windows.Remove(focused);
        windows.Add(focused);

        int x = workArea.X;
        int y = workArea.Y;

        foreach (IntPtr handle in windows)
        {
            // Restore minimized or maximized windows so they can be positioned
            if (BFS.Window.IsMinimized(handle) || BFS.Window.IsMaximized(handle))
                BFS.Window.Restore(handle);

            // Wrap around if the cascade would run off the work area
            if (x + width > workArea.Right || y + height > workArea.Bottom)
            {
                x = workArea.X;
                y = workArea.Y;
            }

            BFS.Window.SetSizeAndLocation(handle, x, y, width, height);
            BFS.Window.Focus(handle);

            x += offset;
            y += offset;
        }

        // Leave the originally focused window active and on top
        BFS.Window.Focus(focused);
    }
}