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();
}
}
}