Make CTRL-T track windows with scroll lock on

This commit is contained in:
2025-06-26 17:47:38 +02:00
parent 435710c350
commit eabda5da67
3 changed files with 170 additions and 1 deletions

View File

@@ -7,6 +7,9 @@ using System.Net;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
using System.Runtime.InteropServices;
using System.Text;
using System.Diagnostics;
using EveOPreview.Configuration;
using EveOPreview.Mediator.Messages;
using EveOPreview.UI.Hotkeys;
@@ -49,6 +52,7 @@ namespace EveOPreview.Services
private int _hideThumbnailsDelay;
private List<HotkeyHandler> _cycleClientHotkeyHandlers = new List<HotkeyHandler>();
private HotkeyHandler _toggleTrackingHotkey;
#endregion
public ThumbnailManager(IMediator mediator, IThumbnailConfiguration configuration, IProcessMonitor processMonitor, IWindowManager windowManager, IThumbnailViewFactory factory)
@@ -91,6 +95,51 @@ namespace EveOPreview.Services
RegisterCycleClientHotkey(this._configuration.CycleGroup5ForwardHotkeys?.Select(x => this._configuration.StringToKey(x)), true, this._configuration.CycleGroup5ClientsOrder);
RegisterCycleClientHotkey(this._configuration.CycleGroup5BackwardHotkeys?.Select(x => this._configuration.StringToKey(x)), false, this._configuration.CycleGroup5ClientsOrder);
// Setup toggle tracking hotkey (Ctrl+T)
var mainHandle = this._processMonitor.GetMainProcess().Handle;
System.Diagnostics.Debug.WriteLine($"Registering hotkey with main window handle: {mainHandle}");
this._toggleTrackingHotkey = new HotkeyHandler(mainHandle, Keys.Control | Keys.T);
this._toggleTrackingHotkey.Pressed += (object s, HandledEventArgs e) =>
{
System.Diagnostics.Debug.WriteLine("Hotkey handler triggered!");
if (!Control.IsKeyLocked(Keys.Scroll))
{
System.Diagnostics.Debug.WriteLine("Scroll lock is off, passing through");
e.Handled = false;
return;
}
var foregroundHandle = this._windowManager.GetForegroundWindowHandle();
if (foregroundHandle != IntPtr.Zero)
{
uint processId;
GetWindowThreadProcessId(foregroundHandle, out processId);
var process = Process.GetProcessById((int)processId);
if (process != null)
{
System.Diagnostics.Debug.WriteLine($"Found process: {process.ProcessName}");
if (_configuration.IsExecutableToPreview(process.ProcessName))
{
System.Diagnostics.Debug.WriteLine("Removing from executables to preview");
var exesToPreview = _configuration.ExecutablesToPreview.ToList();
exesToPreview.Remove(process.ProcessName.ToLower());
_configuration.ExecutablesToPreview = exesToPreview;
}
else
{
System.Diagnostics.Debug.WriteLine("Adding to executables to preview");
var exesToPreview = _configuration.ExecutablesToPreview.ToList();
exesToPreview.Add(process.ProcessName.ToLower());
_configuration.ExecutablesToPreview = exesToPreview;
}
e.Handled = true;
}
}
};
var registered = this._toggleTrackingHotkey.Register();
System.Diagnostics.Debug.WriteLine($"Hotkey registration result: {registered}");
}
public IThumbnailView GetClientByTitle(string title)
@@ -954,5 +1003,118 @@ namespace EveOPreview.Services
&& (top > ThumbnailManager.WINDOW_POSITION_THRESHOLD_LOW) && (top < ThumbnailManager.WINDOW_POSITION_THRESHOLD_HIGH)
&& (width > ThumbnailManager.WINDOW_SIZE_THRESHOLD) && (height > ThumbnailManager.WINDOW_SIZE_THRESHOLD);
}
private bool IsTrackedProcess(int processId)
{
return _thumbnailViews.Any(x => Process.GetProcessById(processId)?.MainWindowHandle == x.Key);
}
private void TrackProcess(System.Diagnostics.Process process)
{
if (process == null || IsTrackedProcess(process.Id))
{
return;
}
System.Diagnostics.Debug.WriteLine($"Tracking process {process.ProcessName} (PID: {process.Id})");
// Get all windows belonging to this process
var windows = new List<IntPtr>();
EnumWindows((IntPtr hWnd, IntPtr lParam) =>
{
uint processId;
GetWindowThreadProcessId(hWnd, out processId);
if (processId == process.Id && IsWindow(hWnd) && IsWindowVisible(hWnd))
{
windows.Add(hWnd);
}
return true;
}, IntPtr.Zero);
foreach (var windowHandle in windows)
{
if (_thumbnailViews.ContainsKey(windowHandle))
{
continue;
}
System.Diagnostics.Debug.WriteLine($"Creating thumbnail for window handle: {windowHandle}");
Size initialSize = this._configuration.ThumbnailSize;
string windowTitle = GetWindowTitle(windowHandle);
string title = $"{windowTitle} (PID: {process.Id})";
IThumbnailView view = this._thumbnailViewFactory.Create(windowHandle, title, initialSize);
view.IsOverlayEnabled = this._configuration.ShowThumbnailOverlays;
view.SetFrames(this._configuration.ShowThumbnailFrames);
view.SetSizeLimitations(this._configuration.ThumbnailMinimumSize, this._configuration.ThumbnailMaximumSize);
view.SetTopMost(this._configuration.ShowThumbnailsAlwaysOnTop);
view.ThumbnailLocation = this._configuration.GetThumbnailLocation(view.Title, this._activeClient.Title, view.ThumbnailLocation);
this._thumbnailViews.Add(view.Id, view);
view.ThumbnailResized = this.ThumbnailViewResized;
view.ThumbnailMoved = this.ThumbnailViewMoved;
view.ThumbnailFocused = this.ThumbnailViewFocused;
view.ThumbnailLostFocus = this.ThumbnailViewLostFocus;
view.ThumbnailActivated = this.ThumbnailActivated;
view.ThumbnailDeactivated = this.ThumbnailDeactivated;
view.RegisterHotkey(this._configuration.GetClientHotkey(view.Title));
this.ApplyClientLayout(view);
}
}
private void UntrackProcess(int processId)
{
var windowsToRemove = _thumbnailViews
.Where(x => {
uint windowProcessId;
GetWindowThreadProcessId(x.Key, out windowProcessId);
return windowProcessId == processId;
})
.ToList();
foreach (var entry in windowsToRemove)
{
IThumbnailView view = entry.Value;
this._thumbnailViews.Remove(entry.Key);
view.UnregisterHotkey();
view.ThumbnailResized = null;
view.ThumbnailMoved = null;
view.ThumbnailFocused = null;
view.ThumbnailLostFocus = null;
view.ThumbnailActivated = null;
view.ThumbnailDeactivated = null;
view.Close();
}
}
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
[DllImport("user32.dll")]
private static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
private static string GetWindowTitle(IntPtr hWnd)
{
StringBuilder sb = new StringBuilder(256);
GetWindowText(hWnd, sb, 256);
return sb.ToString();
}
}
}