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 Year End Sale!Save up to 50% on our desktop apps during our big Year End Sale, including DisplayFusion, ClipboardFusion, FileSeek, LogFusion, TrayStatus, and VoiceBot!Save up to 50% on our desktop apps during our big Year End Sale!

Swap Focused Target-App Window With Topmost Target-App Window on Selected Monitor

Description
What it does: Swap Two Application Windows Between Monitors (Prompted). See notes in the code comments at the top of the script.
Language
C#.net
Minimum Version
Created By
machodao
Contributors
-
Date Created
2d ago
Date Last Modified
2d ago

Scripted Function (Macro) Code

/*
What it does:
1) Requires the currently focused window to belong to the TARGET app (or it exits).
2) Prompts you to choose a destination monitor.
3) On that destination monitor, finds the TOPMOST window that belongs to the TARGET app.
4) Swaps the two windows by moving each to the other's monitor.

Nuances:
- Swaps exactly TWO windows:
  A) The focused TARGET-app window (must be the target app)
  B) The topmost TARGET-app window on the chosen monitor
- Not "all windows" on a monitor.
- No drag detection. Trigger with hotkey or mouse (e.g., XMouseButtonControl).
- If the chosen monitor has no TARGET-app window, nothing happens.
- Uses process-based detection (BFS.Application.GetMainFileByWindow), so titles and skins do not matter.

How to adapt:
- Change TARGET_EXE to the executable you want to swap.
- Optionally adjust TARGET_EXE_MATCH_FALLBACK.
*/

using System;

public static class DisplayFusionFunction
{
    private const string TARGET_EXE = "PotPlayerMini64.exe";
    private const string TARGET_EXE_MATCH_FALLBACK = "PotPlayer";

    public static void Run(IntPtr windowHandle)
    {
        if (windowHandle == IntPtr.Zero)
            return;

        if (!IsTargetAppWindow(windowHandle))
            return;

        uint sourceMonitor = BFS.Monitor.GetMonitorIDByWindow(windowHandle);

        uint destMonitor = BFS.Monitor.ShowMonitorSelector();
        if (destMonitor == 0)
            return;

        if (destMonitor == sourceMonitor)
            return;

        IntPtr destTopmostTarget = GetTopmostTargetAppWindowOnMonitor(destMonitor);
        if (destTopmostTarget == IntPtr.Zero)
            return;

        BFS.Window.MoveToMonitor(destMonitor, windowHandle);
        BFS.Window.MoveToMonitor(sourceMonitor, destTopmostTarget);

        BFS.Window.Focus(windowHandle);
    }

    private static IntPtr GetTopmostTargetAppWindowOnMonitor(uint monitorId)
    {
        IntPtr[] windows = BFS.Window.GetVisibleWindowHandlesByMonitor(monitorId);

        foreach (IntPtr w in windows)
        {
            if (w == IntPtr.Zero)
                continue;

            if (IsTargetAppWindow(w))
                return w;
        }

        return IntPtr.Zero;
    }

    private static bool IsTargetAppWindow(IntPtr window)
    {
        string mainFile = BFS.Application.GetMainFileByWindow(window);
        if (string.IsNullOrEmpty(mainFile))
            return false;

        if (mainFile.IndexOf(TARGET_EXE, StringComparison.OrdinalIgnoreCase) >= 0)
            return true;

        if (!string.IsNullOrEmpty(TARGET_EXE_MATCH_FALLBACK) &&
            mainFile.IndexOf(TARGET_EXE_MATCH_FALLBACK, StringComparison.OrdinalIgnoreCase) >= 0)
            return true;

        return false;
    }
}