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?

Smart Window Manager

Description
This script displays a persistent window listing all open windows, categorized by two monitors. It automatically moves specific windows to a designated monitor based on their title. Additionally, users can manually move windows by double-clicking them. The script updates every 3 seconds to reflect real-time window changes. To configure the script for your specific use case, replace "insert window name here" in the code with the exact window titles you want to move. Windows with matching names, including numbered instances (e.g., "Window (1)", "Window (2)"), will also be moved.
Language
C#.net
Minimum Version
Created By
ADJADI
Contributors
-
Date Created
3d ago
Date Last Modified
3d ago

Scripted Function (Macro) Code

using System;
using System.Drawing;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Forms;

public class PersistentWindowSelector : Form
{
    private SplitContainer splitContainer;
    private ListView lvMonitor1;
    private ListView lvMonitor2;
    private Timer refreshTimer;

    // Rules for automatic window movement (replace "insert window name here" with actual window titles)
    private Dictionary<string, uint> windowRules = new Dictionary<string, uint>
    {
        { "insert window name here", 2 }, // Move to Monitor 2
        { "insert window name here", 1 }  // Move to Monitor 1
    };

    public PersistentWindowSelector()
    {
        this.Text = "Select the window to move...";
        this.Size = new Size(600, 600);

        splitContainer = new SplitContainer { Dock = DockStyle.Fill, Orientation = Orientation.Horizontal };
        this.Controls.Add(splitContainer);

        lvMonitor1 = new ListView { View = View.List, Dock = DockStyle.Fill, FullRowSelect = true };
        lvMonitor1.DoubleClick += ListView_DoubleClick;
        
        lvMonitor2 = new ListView { View = View.List, Dock = DockStyle.Fill, FullRowSelect = true };
        lvMonitor2.DoubleClick += ListView_DoubleClick;

        splitContainer.Panel1.Controls.Add(lvMonitor1);
        splitContainer.Panel2.Controls.Add(lvMonitor2);

        refreshTimer = new Timer { Interval = 3000 };
        refreshTimer.Tick += RefreshTimer_Tick;
        refreshTimer.Start();
    }

    private void RefreshTimer_Tick(object sender, EventArgs e)
    {
        string currentSelection = lvMonitor1.SelectedItems.Count > 0 ? lvMonitor1.SelectedItems[0].Text :
                                  lvMonitor2.SelectedItems.Count > 0 ? lvMonitor2.SelectedItems[0].Text : null;

        lvMonitor1.BeginUpdate();
        lvMonitor2.BeginUpdate();
        lvMonitor1.Items.Clear();
        lvMonitor2.Items.Clear();

        HashSet<string> addedTitlesMonitor1 = new HashSet<string>();
        HashSet<string> addedTitlesMonitor2 = new HashSet<string>();

        IntPtr[] windows = BFS.Window.GetVisibleAndMinimizedWindowHandles();
        uint[] monitors = BFS.Monitor.GetMonitorIDs();
        if (monitors.Length < 2)
        {
            lvMonitor1.Items.Add("There are not two monitors available.");
            lvMonitor1.EndUpdate();
            lvMonitor2.EndUpdate();
            return;
        }
        uint monitor1 = monitors[0], monitor2 = monitors[1];

        Dictionary<string, int> windowTitleCounts = new Dictionary<string, int>();

        foreach (IntPtr window in windows)
        {
            string title = BFS.Window.GetText(window);
            if (string.IsNullOrEmpty(title)) continue;

            string baseTitle = GetBaseTitle(title);

            if (windowTitleCounts.ContainsKey(baseTitle))
            {
                windowTitleCounts[baseTitle]++;
                title = $"{baseTitle} ({windowTitleCounts[baseTitle]})";
            }
            else
            {
                windowTitleCounts[baseTitle] = 0;
            }

            uint windowMonitorID = BFS.Monitor.GetMonitorIDByWindow(window);

            // Automatic movement based on strict name matching (ignoring numbering)
            if (windowRules.TryGetValue(baseTitle, out uint targetMonitor))
            {
                targetMonitor = (targetMonitor == 1) ? monitor1 : monitor2;
                if (windowMonitorID != targetMonitor)
                {
                    BFS.Window.MoveToMonitor(targetMonitor, window);
                    windowMonitorID = targetMonitor; // Update for display
                }
            }

            ListView targetList = (windowMonitorID == monitor1) ? lvMonitor1 : lvMonitor2;
            HashSet<string> addedTitles = (windowMonitorID == monitor1) ? addedTitlesMonitor1 : addedTitlesMonitor2;

            // Prevent duplicate entries in the ListView
            if (!addedTitles.Contains(title))
            {
                ListViewItem item = new ListViewItem(title) { Tag = window };
                targetList.Items.Add(item);
                addedTitles.Add(title);
            }
        }

        lvMonitor1.EndUpdate();
        lvMonitor2.EndUpdate();
        
        RestoreSelection(lvMonitor1, currentSelection);
        RestoreSelection(lvMonitor2, currentSelection);
    }

    private void RestoreSelection(ListView listView, string selection)
    {
        if (!string.IsNullOrEmpty(selection))
        {
            foreach (ListViewItem item in listView.Items)
            {
                if (item.Text == selection)
                {
                    item.Selected = true;
                    break;
                }
            }
        }
    }

    private void ListView_DoubleClick(object sender, EventArgs e)
    {
        ListView lv = sender as ListView;
        if (lv.SelectedItems.Count == 0) return;

        IntPtr windowToMove = (IntPtr)lv.SelectedItems[0].Tag;
        if (windowToMove == IntPtr.Zero) return;

        uint[] monitors = BFS.Monitor.GetMonitorIDs();
        if (monitors.Length < 2) return;
        uint monitor1 = monitors[0], monitor2 = monitors[1];

        uint currentMonitorID = BFS.Monitor.GetMonitorIDByWindow(windowToMove);
        uint targetMonitorID = (currentMonitorID == monitor1) ? monitor2 : monitor1;

        BFS.Window.MoveToMonitor(targetMonitorID, windowToMove);
    }

    private string GetBaseTitle(string title)
    {
        return Regex.Replace(title, @"\s\(\d+\)$", ""); // Remove numbering such as " (1)", " (2)", etc.
    }
}

public static class DisplayFusionFunction
{
    public static void Run(IntPtr windowHandle)
    {
        using (PersistentWindowSelector selector = new PersistentWindowSelector())
        {
            selector.ShowDialog();
        }
    }
}