diff --git a/scripts/get-mpv-window-windows.ps1 b/scripts/get-mpv-window-windows.ps1
deleted file mode 100644
index e0a041a5..00000000
--- a/scripts/get-mpv-window-windows.ps1
+++ /dev/null
@@ -1,401 +0,0 @@
-param(
- [ValidateSet('geometry', 'foreground-process', 'bind-overlay', 'lower-overlay', 'set-owner', 'clear-owner', 'target-hwnd')]
- [string]$Mode = 'geometry',
- [string]$SocketPath,
- [string]$OverlayWindowHandle
-)
-
-$ErrorActionPreference = 'Stop'
-
-try {
- Add-Type -TypeDefinition @"
-using System;
-using System.Runtime.InteropServices;
-
-public static class SubMinerWindowsHelper {
- public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
-
- [StructLayout(LayoutKind.Sequential)]
- public struct RECT {
- public int Left;
- public int Top;
- public int Right;
- public int Bottom;
- }
-
- [DllImport("user32.dll")]
- public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
-
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool IsWindowVisible(IntPtr hWnd);
-
- [DllImport("user32.dll")]
- public static extern bool IsIconic(IntPtr hWnd);
-
- [DllImport("user32.dll")]
- public static extern IntPtr GetForegroundWindow();
-
- [DllImport("user32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool SetWindowPos(
- IntPtr hWnd,
- IntPtr hWndInsertAfter,
- int X,
- int Y,
- int cx,
- int cy,
- uint uFlags
- );
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
-
- [DllImport("user32.dll", SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
-
- [DllImport("kernel32.dll")]
- public static extern void SetLastError(uint dwErrCode);
-
- [DllImport("dwmapi.dll")]
- public static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out RECT pvAttribute, int cbAttribute);
-}
-"@
-
- $DWMWA_EXTENDED_FRAME_BOUNDS = 9
- $SWP_NOSIZE = 0x0001
- $SWP_NOMOVE = 0x0002
- $SWP_NOACTIVATE = 0x0010
- $SWP_NOOWNERZORDER = 0x0200
- $SWP_FLAGS = $SWP_NOSIZE -bor $SWP_NOMOVE -bor $SWP_NOACTIVATE -bor $SWP_NOOWNERZORDER
- $GWL_EXSTYLE = -20
- $WS_EX_TOPMOST = 0x00000008
- $GWLP_HWNDPARENT = -8
- $HWND_TOP = [IntPtr]::Zero
- $HWND_BOTTOM = [IntPtr]::One
- $HWND_TOPMOST = [IntPtr](-1)
- $HWND_NOTOPMOST = [IntPtr](-2)
-
- function Assert-SetWindowLongPtrSucceeded {
- param(
- [IntPtr]$Result,
- [string]$Operation
- )
-
- if ($Result -ne [IntPtr]::Zero) {
- return
- }
-
- if ([Runtime.InteropServices.Marshal]::GetLastWin32Error() -eq 0) {
- return
- }
-
- $lastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
- throw "$Operation failed ($lastError)"
- }
-
- function Assert-SetWindowPosSucceeded {
- param(
- [bool]$Result,
- [string]$Operation
- )
-
- if ($Result) {
- return
- }
-
- $lastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()
- throw "$Operation failed ($lastError)"
- }
-
- if ($Mode -eq 'foreground-process') {
- $foregroundWindow = [SubMinerWindowsHelper]::GetForegroundWindow()
- if ($foregroundWindow -eq [IntPtr]::Zero) {
- Write-Output 'not-found'
- exit 0
- }
-
- [uint32]$foregroundProcessId = 0
- [void][SubMinerWindowsHelper]::GetWindowThreadProcessId($foregroundWindow, [ref]$foregroundProcessId)
- if ($foregroundProcessId -eq 0) {
- Write-Output 'not-found'
- exit 0
- }
-
- try {
- $foregroundProcess = Get-Process -Id $foregroundProcessId -ErrorAction Stop
- } catch {
- Write-Output 'not-found'
- exit 0
- }
-
- Write-Output "process=$($foregroundProcess.ProcessName)"
- exit 0
- }
-
- if ($Mode -eq 'clear-owner') {
- if ([string]::IsNullOrWhiteSpace($OverlayWindowHandle)) {
- [Console]::Error.WriteLine('overlay-window-handle-required')
- exit 1
- }
-
- [IntPtr]$overlayWindow = [IntPtr]([int64]$OverlayWindowHandle)
- [SubMinerWindowsHelper]::SetLastError(0)
- $result = [SubMinerWindowsHelper]::SetWindowLongPtr($overlayWindow, $GWLP_HWNDPARENT, [IntPtr]::Zero)
- Assert-SetWindowLongPtrSucceeded -Result $result -Operation 'clear-owner'
- Write-Output 'ok'
- exit 0
- }
-
- function Get-WindowBounds {
- param([IntPtr]$hWnd)
-
- $rect = New-Object SubMinerWindowsHelper+RECT
- $size = [System.Runtime.InteropServices.Marshal]::SizeOf($rect)
- $dwmResult = [SubMinerWindowsHelper]::DwmGetWindowAttribute(
- $hWnd,
- $DWMWA_EXTENDED_FRAME_BOUNDS,
- [ref]$rect,
- $size
- )
-
- if ($dwmResult -ne 0) {
- if (-not [SubMinerWindowsHelper]::GetWindowRect($hWnd, [ref]$rect)) {
- return $null
- }
- }
-
- $width = $rect.Right - $rect.Left
- $height = $rect.Bottom - $rect.Top
- if ($width -le 0 -or $height -le 0) {
- return $null
- }
-
- return [PSCustomObject]@{
- X = $rect.Left
- Y = $rect.Top
- Width = $width
- Height = $height
- Area = $width * $height
- }
- }
-
- $commandLineByPid = @{}
- if (-not [string]::IsNullOrWhiteSpace($SocketPath)) {
- foreach ($process in Get-CimInstance Win32_Process) {
- $commandLineByPid[[uint32]$process.ProcessId] = $process.CommandLine
- }
- }
-
- $mpvMatches = New-Object System.Collections.Generic.List[object]
- $targetWindowState = 'not-found'
- $foregroundWindow = [SubMinerWindowsHelper]::GetForegroundWindow()
- $callback = [SubMinerWindowsHelper+EnumWindowsProc]{
- param([IntPtr]$hWnd, [IntPtr]$lParam)
-
- if (-not [SubMinerWindowsHelper]::IsWindowVisible($hWnd)) {
- return $true
- }
-
- [uint32]$windowProcessId = 0
- [void][SubMinerWindowsHelper]::GetWindowThreadProcessId($hWnd, [ref]$windowProcessId)
- if ($windowProcessId -eq 0) {
- return $true
- }
-
- try {
- $process = Get-Process -Id $windowProcessId -ErrorAction Stop
- } catch {
- return $true
- }
-
- if ($process.ProcessName -ine 'mpv') {
- return $true
- }
-
- if (-not [string]::IsNullOrWhiteSpace($SocketPath)) {
- $commandLine = $commandLineByPid[[uint32]$windowProcessId]
- if ([string]::IsNullOrWhiteSpace($commandLine)) {
- return $true
- }
- if (
- ($commandLine -notlike "*--input-ipc-server=$SocketPath*") -and
- ($commandLine -notlike "*--input-ipc-server $SocketPath*")
- ) {
- return $true
- }
- }
-
- if ([SubMinerWindowsHelper]::IsIconic($hWnd)) {
- if (-not [string]::IsNullOrWhiteSpace($SocketPath) -and $targetWindowState -ne 'visible') {
- $targetWindowState = 'minimized'
- }
- return $true
- }
-
- $bounds = Get-WindowBounds -hWnd $hWnd
- if ($null -eq $bounds) {
- return $true
- }
-
- if (-not [string]::IsNullOrWhiteSpace($SocketPath)) {
- $targetWindowState = 'visible'
- }
-
- $mpvMatches.Add([PSCustomObject]@{
- HWnd = $hWnd
- X = $bounds.X
- Y = $bounds.Y
- Width = $bounds.Width
- Height = $bounds.Height
- Area = $bounds.Area
- IsForeground = ($foregroundWindow -ne [IntPtr]::Zero -and $hWnd -eq $foregroundWindow)
- })
-
- return $true
- }
-
- [void][SubMinerWindowsHelper]::EnumWindows($callback, [IntPtr]::Zero)
-
- if ($Mode -eq 'lower-overlay') {
- if ([string]::IsNullOrWhiteSpace($OverlayWindowHandle)) {
- [Console]::Error.WriteLine('overlay-window-handle-required')
- exit 1
- }
-
- [IntPtr]$overlayWindow = [IntPtr]([int64]$OverlayWindowHandle)
-
- [void][SubMinerWindowsHelper]::SetWindowPos(
- $overlayWindow,
- $HWND_NOTOPMOST,
- 0,
- 0,
- 0,
- 0,
- $SWP_FLAGS
- )
- [void][SubMinerWindowsHelper]::SetWindowPos(
- $overlayWindow,
- $HWND_BOTTOM,
- 0,
- 0,
- 0,
- 0,
- $SWP_FLAGS
- )
- Write-Output 'ok'
- exit 0
- }
-
- $focusedMatch = $mpvMatches | Where-Object { $_.IsForeground } | Select-Object -First 1
- if ($null -ne $focusedMatch) {
- [Console]::Error.WriteLine('focus=focused')
- } else {
- [Console]::Error.WriteLine('focus=not-focused')
- }
- if (-not [string]::IsNullOrWhiteSpace($SocketPath)) {
- [Console]::Error.WriteLine("state=$targetWindowState")
- }
-
- if ($mpvMatches.Count -eq 0) {
- Write-Output 'not-found'
- exit 0
- }
-
- $bestMatch = if ($null -ne $focusedMatch) {
- $focusedMatch
- } else {
- $mpvMatches | Sort-Object -Property Area, Width, Height -Descending | Select-Object -First 1
- }
-
- if ($Mode -eq 'target-hwnd') {
- Write-Output "$($bestMatch.HWnd)"
- exit 0
- }
-
- if ($Mode -eq 'set-owner') {
- if ([string]::IsNullOrWhiteSpace($OverlayWindowHandle)) {
- [Console]::Error.WriteLine('overlay-window-handle-required')
- exit 1
- }
-
- [IntPtr]$overlayWindow = [IntPtr]([int64]$OverlayWindowHandle)
- $targetWindow = [IntPtr]$bestMatch.HWnd
- [SubMinerWindowsHelper]::SetLastError(0)
- $result = [SubMinerWindowsHelper]::SetWindowLongPtr($overlayWindow, $GWLP_HWNDPARENT, $targetWindow)
- Assert-SetWindowLongPtrSucceeded -Result $result -Operation 'set-owner'
- Write-Output 'ok'
- exit 0
- }
-
- if ($Mode -eq 'bind-overlay') {
- if ([string]::IsNullOrWhiteSpace($OverlayWindowHandle)) {
- [Console]::Error.WriteLine('overlay-window-handle-required')
- exit 1
- }
-
- [IntPtr]$overlayWindow = [IntPtr]([int64]$OverlayWindowHandle)
- $targetWindow = [IntPtr]$bestMatch.HWnd
- [SubMinerWindowsHelper]::SetLastError(0)
- $result = [SubMinerWindowsHelper]::SetWindowLongPtr($overlayWindow, $GWLP_HWNDPARENT, $targetWindow)
- Assert-SetWindowLongPtrSucceeded -Result $result -Operation 'bind-overlay owner assignment'
- $targetWindowExStyle = [SubMinerWindowsHelper]::GetWindowLong($targetWindow, $GWL_EXSTYLE)
- $targetWindowIsTopmost = ($targetWindowExStyle -band $WS_EX_TOPMOST) -ne 0
-
- $overlayExStyle = [SubMinerWindowsHelper]::GetWindowLong($overlayWindow, $GWL_EXSTYLE)
- $overlayIsTopmost = ($overlayExStyle -band $WS_EX_TOPMOST) -ne 0
- if ($targetWindowIsTopmost -and -not $overlayIsTopmost) {
- [SubMinerWindowsHelper]::SetLastError(0)
- $result = [SubMinerWindowsHelper]::SetWindowPos(
- $overlayWindow, $HWND_TOPMOST, 0, 0, 0, 0, $SWP_FLAGS
- )
- Assert-SetWindowPosSucceeded -Result $result -Operation 'bind-overlay topmost adjustment'
- } elseif (-not $targetWindowIsTopmost -and $overlayIsTopmost) {
- [SubMinerWindowsHelper]::SetLastError(0)
- $result = [SubMinerWindowsHelper]::SetWindowPos(
- $overlayWindow, $HWND_NOTOPMOST, 0, 0, 0, 0, $SWP_FLAGS
- )
- Assert-SetWindowPosSucceeded -Result $result -Operation 'bind-overlay notopmost adjustment'
- }
-
- $GW_HWNDPREV = 3
- $windowAboveMpv = [SubMinerWindowsHelper]::GetWindow($targetWindow, $GW_HWNDPREV)
-
- if ($windowAboveMpv -ne [IntPtr]::Zero -and $windowAboveMpv -eq $overlayWindow) {
- Write-Output 'ok'
- exit 0
- }
-
- $insertAfter = $HWND_TOP
- if ($windowAboveMpv -ne [IntPtr]::Zero) {
- $aboveExStyle = [SubMinerWindowsHelper]::GetWindowLong($windowAboveMpv, $GWL_EXSTYLE)
- $aboveIsTopmost = ($aboveExStyle -band $WS_EX_TOPMOST) -ne 0
- if ($aboveIsTopmost -eq $targetWindowIsTopmost) {
- $insertAfter = $windowAboveMpv
- }
- }
-
- [SubMinerWindowsHelper]::SetLastError(0)
- $result = [SubMinerWindowsHelper]::SetWindowPos(
- $overlayWindow, $insertAfter, 0, 0, 0, 0, $SWP_FLAGS
- )
- Assert-SetWindowPosSucceeded -Result $result -Operation 'bind-overlay z-order adjustment'
- Write-Output 'ok'
- exit 0
- }
-
- Write-Output "$($bestMatch.X),$($bestMatch.Y),$($bestMatch.Width),$($bestMatch.Height)"
-} catch {
- [Console]::Error.WriteLine($_.Exception.Message)
- exit 1
-}
diff --git a/scripts/prepare-build-assets.mjs b/scripts/prepare-build-assets.mjs
index 38cad99f..575a2869 100644
--- a/scripts/prepare-build-assets.mjs
+++ b/scripts/prepare-build-assets.mjs
@@ -8,8 +8,6 @@ const repoRoot = path.resolve(scriptDir, '..');
const rendererSourceDir = path.join(repoRoot, 'src', 'renderer');
const rendererOutputDir = path.join(repoRoot, 'dist', 'renderer');
const scriptsOutputDir = path.join(repoRoot, 'dist', 'scripts');
-const windowsHelperSourcePath = path.join(scriptDir, 'get-mpv-window-windows.ps1');
-const windowsHelperOutputPath = path.join(scriptsOutputDir, 'get-mpv-window-windows.ps1');
const macosHelperSourcePath = path.join(scriptDir, 'get-mpv-window-macos.swift');
const macosHelperBinaryPath = path.join(scriptsOutputDir, 'get-mpv-window-macos');
const macosHelperSourceCopyPath = path.join(scriptsOutputDir, 'get-mpv-window-macos.swift');
@@ -33,11 +31,6 @@ function copyRendererAssets() {
process.stdout.write(`Staged renderer assets in ${rendererOutputDir}\n`);
}
-function stageWindowsHelper() {
- copyFile(windowsHelperSourcePath, windowsHelperOutputPath);
- process.stdout.write(`Staged Windows helper: ${windowsHelperOutputPath}\n`);
-}
-
function fallbackToMacosSource() {
copyFile(macosHelperSourcePath, macosHelperSourceCopyPath);
process.stdout.write(`Staged macOS helper source fallback: ${macosHelperSourceCopyPath}\n`);
@@ -77,7 +70,6 @@ function buildMacosHelper() {
function main() {
copyRendererAssets();
- stageWindowsHelper();
buildMacosHelper();
}
diff --git a/src/window-trackers/windows-helper.test.ts b/src/window-trackers/windows-helper.test.ts
index ea08532d..88a0c4ab 100644
--- a/src/window-trackers/windows-helper.test.ts
+++ b/src/window-trackers/windows-helper.test.ts
@@ -1,323 +1,60 @@
import test from 'node:test';
import assert from 'node:assert/strict';
-import * as windowsHelper from './windows-helper';
-import {
- lowerWindowsOverlayInZOrder,
- parseWindowTrackerHelperForegroundProcess,
- parseWindowTrackerHelperFocusState,
- parseWindowTrackerHelperOutput,
- parseWindowTrackerHelperState,
- queryWindowsForegroundProcessName,
- queryWindowsTargetWindowHandle,
- queryWindowsTrackerMpvWindows,
- resolveWindowsTrackerHelper,
- syncWindowsOverlayToMpvZOrder,
-} from './windows-helper';
+import { findWindowsMpvTargetWindowHandle } from './windows-helper';
+import type { MpvPollResult } from './win32';
-test('parseWindowTrackerHelperOutput parses helper geometry output', () => {
- assert.deepEqual(parseWindowTrackerHelperOutput('120,240,1280,720'), {
- x: 120,
- y: 240,
- width: 1280,
- height: 720,
- });
-});
-
-test('parseWindowTrackerHelperOutput returns null for misses and invalid payloads', () => {
- assert.equal(parseWindowTrackerHelperOutput('not-found'), null);
- assert.equal(parseWindowTrackerHelperOutput('1,2,3'), null);
- assert.equal(parseWindowTrackerHelperOutput('1,2,0,4'), null);
-});
-
-test('parseWindowTrackerHelperFocusState parses helper stderr metadata', () => {
- assert.equal(parseWindowTrackerHelperFocusState('focus=focused'), true);
- assert.equal(parseWindowTrackerHelperFocusState('focus=not-focused'), false);
- assert.equal(parseWindowTrackerHelperFocusState('warning\nfocus=focused\nnote'), true);
- assert.equal(parseWindowTrackerHelperFocusState(''), null);
-});
-
-test('parseWindowTrackerHelperState parses helper stderr metadata', () => {
- assert.equal(parseWindowTrackerHelperState('state=visible'), 'visible');
- assert.equal(parseWindowTrackerHelperState('focus=not-focused\nstate=minimized'), 'minimized');
- assert.equal(parseWindowTrackerHelperState('state=unknown'), null);
- assert.equal(parseWindowTrackerHelperState(''), null);
-});
-
-test('parseWindowTrackerHelperForegroundProcess parses helper stdout metadata', () => {
- assert.equal(parseWindowTrackerHelperForegroundProcess('process=mpv'), 'mpv');
- assert.equal(parseWindowTrackerHelperForegroundProcess('process=chrome'), 'chrome');
- assert.equal(parseWindowTrackerHelperForegroundProcess('not-found'), null);
- assert.equal(parseWindowTrackerHelperForegroundProcess(''), null);
-});
-
-test('queryWindowsForegroundProcessName reads foreground process from powershell helper', async () => {
- const processName = await queryWindowsForegroundProcessName({
- resolveHelper: () => ({
- kind: 'powershell',
- command: 'powershell.exe',
- args: ['-File', 'helper.ps1'],
- helperPath: 'helper.ps1',
- }),
- runHelper: async () => ({
- stdout: 'process=mpv',
- stderr: '',
- }),
- });
-
- assert.equal(processName, 'mpv');
-});
-
-test('queryWindowsForegroundProcessName returns null when no powershell helper is available', async () => {
- const processName = await queryWindowsForegroundProcessName({
- resolveHelper: () => ({
- kind: 'native',
- command: 'helper.exe',
- args: [],
- helperPath: 'helper.exe',
- }),
- });
-
- assert.equal(processName, null);
-});
-
-test('syncWindowsOverlayToMpvZOrder forwards socket path and overlay handle to powershell helper', async () => {
- let capturedMode: string | null = null;
- let capturedArgs: string[] | null = null;
-
- const synced = await syncWindowsOverlayToMpvZOrder({
- overlayWindowHandle: '12345',
- targetMpvSocketPath: '\\\\.\\pipe\\subminer-socket',
- resolveHelper: () => ({
- kind: 'powershell',
- command: 'powershell.exe',
- args: ['-File', 'helper.ps1'],
- helperPath: 'helper.ps1',
- }),
- runHelper: async (_spec, mode, extraArgs = []) => {
- capturedMode = mode;
- capturedArgs = extraArgs;
- return {
- stdout: 'ok',
- stderr: '',
- };
- },
- });
-
- assert.equal(synced, true);
- assert.equal(capturedMode, 'bind-overlay');
- assert.deepEqual(capturedArgs, ['\\\\.\\pipe\\subminer-socket', '12345']);
-});
-
-test('lowerWindowsOverlayInZOrder forwards overlay handle to powershell helper', async () => {
- let capturedMode: string | null = null;
- let capturedArgs: string[] | null = null;
-
- const lowered = await lowerWindowsOverlayInZOrder({
- overlayWindowHandle: '67890',
- resolveHelper: () => ({
- kind: 'powershell',
- command: 'powershell.exe',
- args: ['-File', 'helper.ps1'],
- helperPath: 'helper.ps1',
- }),
- runHelper: async (_spec, mode, extraArgs = []) => {
- capturedMode = mode;
- capturedArgs = extraArgs;
- return {
- stdout: 'ok',
- stderr: '',
- };
- },
- });
-
- assert.equal(lowered, true);
- assert.equal(capturedMode, 'lower-overlay');
- assert.deepEqual(capturedArgs, ['', '67890']);
-});
-
-test('queryWindowsTrackerMpvWindows resolves geometry from the powershell helper', () => {
- let capturedMode: string | null = null;
- let capturedArgs: string[] | null = null;
-
- const result = queryWindowsTrackerMpvWindows({
- targetMpvSocketPath: '\\\\.\\pipe\\subminer-socket',
- resolveHelper: () => ({
- kind: 'powershell',
- command: 'powershell.exe',
- args: ['-File', 'helper.ps1'],
- helperPath: 'helper.ps1',
- }),
- runHelperSync: (_spec, mode, extraArgs = []) => {
- capturedMode = mode;
- capturedArgs = extraArgs;
- return {
- stdout: '120,240,1280,720',
- stderr: 'focus=focused\nstate=visible',
- };
- },
- });
-
- assert.deepEqual(result, {
+test('findWindowsMpvTargetWindowHandle prefers the focused mpv window', () => {
+ const result: MpvPollResult = {
matches: [
{
- hwnd: 0,
- bounds: {
- x: 120,
- y: 240,
- width: 1280,
- height: 720,
- },
+ hwnd: 111,
+ bounds: { x: 0, y: 0, width: 1280, height: 720 },
area: 1280 * 720,
+ isForeground: false,
+ },
+ {
+ hwnd: 222,
+ bounds: { x: 10, y: 10, width: 800, height: 600 },
+ area: 800 * 600,
isForeground: true,
},
],
focusState: true,
windowState: 'visible',
- });
- assert.equal(capturedMode, 'geometry');
- assert.deepEqual(capturedArgs, ['\\\\.\\pipe\\subminer-socket']);
+ };
+
+ assert.equal(findWindowsMpvTargetWindowHandle(result), 222);
});
-test('queryWindowsTargetWindowHandle resolves the selected hwnd from the powershell helper', () => {
- let capturedMode: string | null = null;
- let capturedArgs: string[] | null = null;
-
- const hwnd = queryWindowsTargetWindowHandle({
- targetMpvSocketPath: '\\\\.\\pipe\\subminer-socket',
- resolveHelper: () => ({
- kind: 'powershell',
- command: 'powershell.exe',
- args: ['-File', 'helper.ps1'],
- helperPath: 'helper.ps1',
- }),
- runHelperSync: (_spec, mode, extraArgs = []) => {
- capturedMode = mode;
- capturedArgs = extraArgs;
- return {
- stdout: '12345',
- stderr: '',
- };
- },
- });
-
- assert.equal(hwnd, 12345);
- assert.equal(capturedMode, 'target-hwnd');
- assert.deepEqual(capturedArgs, ['\\\\.\\pipe\\subminer-socket']);
-});
-
-test('shouldUseWindowsTrackerPowershellFallback returns true for explicit powershell mode', () => {
- assert.equal(
- windowsHelper.shouldUseWindowsTrackerPowershellFallback({
- helperModeEnv: 'powershell',
- }),
- true,
- );
-});
-
-test('shouldUseWindowsTrackerPowershellFallback returns true for ps1 helper path override', () => {
- assert.equal(
- windowsHelper.shouldUseWindowsTrackerPowershellFallback({
- helperPathEnv: 'C:\\custom\\tracker.ps1',
- }),
- true,
- );
-});
-
-test('shouldUseWindowsTrackerPowershellFallback returns false for default and native modes', () => {
- assert.equal(
- windowsHelper.shouldUseWindowsTrackerPowershellFallback({
- helperModeEnv: 'auto',
- helperPathEnv: undefined,
- }),
- false,
- );
- assert.equal(
- windowsHelper.shouldUseWindowsTrackerPowershellFallback({
- helperModeEnv: 'native',
- helperPathEnv: 'C:\\custom\\tracker.exe',
- }),
- false,
- );
-});
-
-test('resolveWindowsTrackerHelper auto mode prefers native helper when present', () => {
- const helper = resolveWindowsTrackerHelper({
- dirname: 'C:\\repo\\dist\\window-trackers',
- resourcesPath: 'C:\\repo\\resources',
- existsSync: (candidate) =>
- candidate === 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.exe',
- helperModeEnv: 'auto',
- });
-
- assert.deepEqual(helper, {
- kind: 'native',
- command: 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.exe',
- args: [],
- helperPath: 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.exe',
- });
-});
-
-test('resolveWindowsTrackerHelper auto mode falls back to powershell helper', () => {
- const helper = resolveWindowsTrackerHelper({
- dirname: 'C:\\repo\\dist\\window-trackers',
- resourcesPath: 'C:\\repo\\resources',
- existsSync: (candidate) =>
- candidate === 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.ps1',
- helperModeEnv: 'auto',
- });
-
- assert.deepEqual(helper, {
- kind: 'powershell',
- command: 'powershell.exe',
- args: [
- '-NoProfile',
- '-ExecutionPolicy',
- 'Bypass',
- '-File',
- 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.ps1',
+test('findWindowsMpvTargetWindowHandle falls back to the largest visible mpv window', () => {
+ const result: MpvPollResult = {
+ matches: [
+ {
+ hwnd: 111,
+ bounds: { x: 0, y: 0, width: 640, height: 360 },
+ area: 640 * 360,
+ isForeground: false,
+ },
+ {
+ hwnd: 222,
+ bounds: { x: 10, y: 10, width: 1920, height: 1080 },
+ area: 1920 * 1080,
+ isForeground: false,
+ },
],
- helperPath: 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.ps1',
- });
+ focusState: false,
+ windowState: 'visible',
+ };
+
+ assert.equal(findWindowsMpvTargetWindowHandle(result), 222);
});
-test('resolveWindowsTrackerHelper explicit powershell mode ignores native helper', () => {
- const helper = resolveWindowsTrackerHelper({
- dirname: 'C:\\repo\\dist\\window-trackers',
- resourcesPath: 'C:\\repo\\resources',
- existsSync: (candidate) =>
- candidate === 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.exe' ||
- candidate === 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.ps1',
- helperModeEnv: 'powershell',
- });
+test('findWindowsMpvTargetWindowHandle returns null when no mpv windows are visible', () => {
+ const result: MpvPollResult = {
+ matches: [],
+ focusState: false,
+ windowState: 'not-found',
+ };
- assert.equal(helper?.kind, 'powershell');
- assert.equal(helper?.helperPath, 'C:\\repo\\resources\\scripts\\get-mpv-window-windows.ps1');
-});
-
-test('resolveWindowsTrackerHelper explicit native mode fails cleanly when helper is missing', () => {
- const helper = resolveWindowsTrackerHelper({
- dirname: 'C:\\repo\\dist\\window-trackers',
- resourcesPath: 'C:\\repo\\resources',
- existsSync: () => false,
- helperModeEnv: 'native',
- });
-
- assert.equal(helper, null);
-});
-
-test('resolveWindowsTrackerHelper explicit helper path overrides default search', () => {
- const helper = resolveWindowsTrackerHelper({
- dirname: 'C:\\repo\\dist\\window-trackers',
- resourcesPath: 'C:\\repo\\resources',
- existsSync: (candidate) => candidate === 'D:\\custom\\tracker.ps1',
- helperModeEnv: 'auto',
- helperPathEnv: 'D:\\custom\\tracker.ps1',
- });
-
- assert.deepEqual(helper, {
- kind: 'powershell',
- command: 'powershell.exe',
- args: ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', 'D:\\custom\\tracker.ps1'],
- helperPath: 'D:\\custom\\tracker.ps1',
- });
+ assert.equal(findWindowsMpvTargetWindowHandle(result), null);
});
diff --git a/src/window-trackers/windows-helper.ts b/src/window-trackers/windows-helper.ts
index 856612a2..c71787ff 100644
--- a/src/window-trackers/windows-helper.ts
+++ b/src/window-trackers/windows-helper.ts
@@ -16,503 +16,41 @@
along with this program. If not, see .
*/
-import * as fs from 'node:fs';
-import * as os from 'node:os';
-import * as path from 'node:path';
-import { execFile, spawnSync, type ExecFileException } from 'child_process';
-import type { WindowGeometry } from '../types';
import type { MpvPollResult } from './win32';
-import { createLogger } from '../logger';
-const log = createLogger('tracker').child('windows-helper');
-
-export type WindowsTrackerHelperKind = 'powershell' | 'native';
-export type WindowsTrackerHelperMode = 'auto' | 'powershell' | 'native';
-export type WindowsTrackerHelperRunMode =
- | 'geometry'
- | 'foreground-process'
- | 'bind-overlay'
- | 'lower-overlay'
- | 'set-owner'
- | 'clear-owner'
- | 'target-hwnd';
-
-export type WindowsTrackerHelperLaunchSpec = {
- kind: WindowsTrackerHelperKind;
- command: string;
- args: string[];
- helperPath: string;
-};
-
-type ResolveWindowsTrackerHelperOptions = {
- dirname?: string;
- resourcesPath?: string;
- helperModeEnv?: string | undefined;
- helperPathEnv?: string | undefined;
- existsSync?: (candidate: string) => boolean;
- mkdirSync?: (candidate: string, options: { recursive: true }) => void;
- copyFileSync?: (source: string, destination: string) => void;
-};
-
-const windowsPath = path.win32;
-
-function normalizeHelperMode(value: string | undefined): WindowsTrackerHelperMode {
- const normalized = value?.trim().toLowerCase();
- if (normalized === 'powershell' || normalized === 'native') {
- return normalized;
- }
- return 'auto';
+function loadWin32(): typeof import('./win32') {
+ return require('./win32') as typeof import('./win32');
}
-export function shouldUseWindowsTrackerPowershellFallback(options: {
- helperModeEnv?: string | undefined;
- helperPathEnv?: string | undefined;
-} = {}): boolean {
- const mode = normalizeHelperMode(
- options.helperModeEnv ?? process.env.SUBMINER_WINDOWS_TRACKER_HELPER,
- );
- if (mode === 'powershell') {
- return true;
- }
-
- const helperPath = options.helperPathEnv ?? process.env.SUBMINER_WINDOWS_TRACKER_HELPER_PATH;
- return helperPath?.trim().toLowerCase().endsWith('.ps1') ?? false;
+export function findWindowsMpvTargetWindowHandle(result?: MpvPollResult): number | null {
+ const poll = result ?? loadWin32().findMpvWindows();
+ const focused = poll.matches.find((match) => match.isForeground);
+ const best =
+ focused ?? [...poll.matches].sort((a, b) => b.area - a.area || b.bounds.width - a.bounds.width)[0];
+ return best?.hwnd ?? null;
}
-function inferHelperKindFromPath(helperPath: string): WindowsTrackerHelperKind | null {
- const normalized = helperPath.trim().toLowerCase();
- if (normalized.endsWith('.exe')) return 'native';
- if (normalized.endsWith('.ps1')) return 'powershell';
- return null;
-}
-
-function materializeAsarHelper(
- sourcePath: string,
- kind: WindowsTrackerHelperKind,
- deps: Required>,
-): string | null {
- if (!sourcePath.includes('.asar')) {
- return sourcePath;
- }
-
- const fileName = kind === 'native' ? 'get-mpv-window-windows.exe' : 'get-mpv-window-windows.ps1';
- const targetDir = windowsPath.join(os.tmpdir(), 'subminer', 'helpers');
- const targetPath = windowsPath.join(targetDir, fileName);
-
+export function setWindowsOverlayOwner(overlayHwnd: number, mpvHwnd: number): boolean {
try {
- deps.mkdirSync(targetDir, { recursive: true });
- deps.copyFileSync(sourcePath, targetPath);
- log.info(`Materialized Windows helper from asar: ${targetPath}`);
- return targetPath;
- } catch (error) {
- log.warn(`Failed to materialize Windows helper from asar: ${sourcePath}`, error);
- return null;
- }
-}
-
-function createLaunchSpec(
- helperPath: string,
- kind: WindowsTrackerHelperKind,
-): WindowsTrackerHelperLaunchSpec {
- if (kind === 'native') {
- return {
- kind,
- command: helperPath,
- args: [],
- helperPath,
- };
- }
-
- return {
- kind,
- command: 'powershell.exe',
- args: ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', helperPath],
- helperPath,
- };
-}
-
-function normalizeHelperPathOverride(
- helperPathEnv: string | undefined,
- mode: WindowsTrackerHelperMode,
-): { path: string; kind: WindowsTrackerHelperKind } | null {
- const helperPath = helperPathEnv?.trim();
- if (!helperPath) {
- return null;
- }
-
- const inferredKind = inferHelperKindFromPath(helperPath);
- const kind = mode === 'auto' ? inferredKind : mode;
- if (!kind) {
- log.warn(
- `Ignoring SUBMINER_WINDOWS_TRACKER_HELPER_PATH with unsupported extension: ${helperPath}`,
- );
- return null;
- }
-
- return { path: helperPath, kind };
-}
-
-function getHelperCandidates(
- dirname: string,
- resourcesPath: string | undefined,
-): Array<{
- path: string;
- kind: WindowsTrackerHelperKind;
-}> {
- const scriptFileBase = 'get-mpv-window-windows';
- const candidates: Array<{ path: string; kind: WindowsTrackerHelperKind }> = [];
-
- if (resourcesPath) {
- candidates.push({
- path: windowsPath.join(resourcesPath, 'scripts', `${scriptFileBase}.exe`),
- kind: 'native',
- });
- candidates.push({
- path: windowsPath.join(resourcesPath, 'scripts', `${scriptFileBase}.ps1`),
- kind: 'powershell',
- });
- }
-
- candidates.push({
- path: windowsPath.join(dirname, '..', 'scripts', `${scriptFileBase}.exe`),
- kind: 'native',
- });
- candidates.push({
- path: windowsPath.join(dirname, '..', 'scripts', `${scriptFileBase}.ps1`),
- kind: 'powershell',
- });
- candidates.push({
- path: windowsPath.join(dirname, '..', '..', 'scripts', `${scriptFileBase}.exe`),
- kind: 'native',
- });
- candidates.push({
- path: windowsPath.join(dirname, '..', '..', 'scripts', `${scriptFileBase}.ps1`),
- kind: 'powershell',
- });
-
- return candidates;
-}
-
-export function parseWindowTrackerHelperOutput(output: string): WindowGeometry | null {
- const result = output.trim();
- if (!result || result === 'not-found') {
- return null;
- }
-
- const parts = result.split(',');
- if (parts.length !== 4) {
- return null;
- }
-
- const [xText, yText, widthText, heightText] = parts;
- const x = Number.parseInt(xText!, 10);
- const y = Number.parseInt(yText!, 10);
- const width = Number.parseInt(widthText!, 10);
- const height = Number.parseInt(heightText!, 10);
- if (
- !Number.isFinite(x) ||
- !Number.isFinite(y) ||
- !Number.isFinite(width) ||
- !Number.isFinite(height) ||
- width <= 0 ||
- height <= 0
- ) {
- return null;
- }
-
- return { x, y, width, height };
-}
-
-export function parseWindowTrackerHelperFocusState(output: string): boolean | null {
- const focusLine = output
- .split(/\r?\n/)
- .map((line) => line.trim())
- .find((line) => line.startsWith('focus='));
-
- if (!focusLine) {
- return null;
- }
-
- const value = focusLine.slice('focus='.length).trim().toLowerCase();
- if (value === 'focused') {
- return true;
- }
- if (value === 'not-focused') {
- return false;
- }
-
- return null;
-}
-
-export function parseWindowTrackerHelperState(output: string): 'visible' | 'minimized' | null {
- const stateLine = output
- .split(/\r?\n/)
- .map((line) => line.trim())
- .find((line) => line.startsWith('state='));
-
- if (!stateLine) {
- return null;
- }
-
- const value = stateLine.slice('state='.length).trim().toLowerCase();
- if (value === 'visible') {
- return 'visible';
- }
- if (value === 'minimized') {
- return 'minimized';
- }
-
- return null;
-}
-
-export function parseWindowTrackerHelperForegroundProcess(output: string): string | null {
- const processLine = output
- .split(/\r?\n/)
- .map((line) => line.trim())
- .find((line) => line.startsWith('process='));
-
- if (!processLine) {
- return null;
- }
-
- const value = processLine.slice('process='.length).trim();
- return value.length > 0 ? value : null;
-}
-
-type WindowsTrackerHelperRunnerResult = {
- stdout: string;
- stderr: string;
-};
-
-function runWindowsTrackerHelperWithSpawnSync(
- spec: WindowsTrackerHelperLaunchSpec,
- mode: WindowsTrackerHelperRunMode,
- extraArgs: string[] = [],
-): WindowsTrackerHelperRunnerResult | null {
- const modeArgs = spec.kind === 'native' ? ['--mode', mode] : ['-Mode', mode];
- const result = spawnSync(spec.command, [...spec.args, ...modeArgs, ...extraArgs], {
- encoding: 'utf-8',
- timeout: 1000,
- maxBuffer: 1024 * 1024,
- windowsHide: true,
- });
-
- if (result.error || result.status !== 0) {
- return null;
- }
-
- return {
- stdout: result.stdout ?? '',
- stderr: result.stderr ?? '',
- };
-}
-
-function runWindowsTrackerHelperWithExecFile(
- spec: WindowsTrackerHelperLaunchSpec,
- mode: WindowsTrackerHelperRunMode,
- extraArgs: string[] = [],
-): Promise {
- return new Promise((resolve, reject) => {
- const modeArgs = spec.kind === 'native' ? ['--mode', mode] : ['-Mode', mode];
- execFile(
- spec.command,
- [...spec.args, ...modeArgs, ...extraArgs],
- {
- encoding: 'utf-8',
- timeout: 1000,
- maxBuffer: 1024 * 1024,
- windowsHide: true,
- },
- (error: ExecFileException | null, stdout: string, stderr: string) => {
- if (error) {
- reject(Object.assign(error, { stderr }));
- return;
- }
- resolve({ stdout, stderr });
- },
- );
- });
-}
-
-export async function queryWindowsForegroundProcessName(deps: {
- resolveHelper?: () => WindowsTrackerHelperLaunchSpec | null;
- runHelper?: (
- spec: WindowsTrackerHelperLaunchSpec,
- mode: WindowsTrackerHelperRunMode,
- extraArgs?: string[],
- ) => Promise;
-} = {}): Promise {
- const spec =
- deps.resolveHelper?.() ??
- resolveWindowsTrackerHelper({
- helperModeEnv: 'powershell',
- });
- if (!spec || spec.kind !== 'powershell') {
- return null;
- }
-
- const runHelper = deps.runHelper ?? runWindowsTrackerHelperWithExecFile;
- const { stdout } = await runHelper(spec, 'foreground-process');
- return parseWindowTrackerHelperForegroundProcess(stdout);
-}
-
-export function queryWindowsTrackerMpvWindows(deps: {
- targetMpvSocketPath?: string | null;
- resolveHelper?: () => WindowsTrackerHelperLaunchSpec | null;
- runHelperSync?: (
- spec: WindowsTrackerHelperLaunchSpec,
- mode: WindowsTrackerHelperRunMode,
- extraArgs?: string[],
- ) => WindowsTrackerHelperRunnerResult | null;
-} = {}): MpvPollResult | null {
- const targetMpvSocketPath = deps.targetMpvSocketPath?.trim();
- if (!targetMpvSocketPath) {
- return null;
- }
-
- const spec =
- deps.resolveHelper?.() ??
- resolveWindowsTrackerHelper({
- helperModeEnv: 'powershell',
- });
- if (!spec || spec.kind !== 'powershell') {
- return null;
- }
-
- const runHelper = deps.runHelperSync ?? runWindowsTrackerHelperWithSpawnSync;
- const result = runHelper(spec, 'geometry', [targetMpvSocketPath]);
- if (!result) {
- return null;
- }
-
- const geometry = parseWindowTrackerHelperOutput(result.stdout);
- if (!geometry) {
- return {
- matches: [],
- focusState: parseWindowTrackerHelperFocusState(result.stderr) ?? false,
- windowState: parseWindowTrackerHelperState(result.stderr) ?? 'not-found',
- };
- }
-
- const focusState = parseWindowTrackerHelperFocusState(result.stderr) ?? false;
- return {
- matches: [
- {
- hwnd: 0,
- bounds: geometry,
- area: geometry.width * geometry.height,
- isForeground: focusState,
- },
- ],
- focusState,
- windowState: parseWindowTrackerHelperState(result.stderr) ?? 'visible',
- };
-}
-
-export function queryWindowsTargetWindowHandle(deps: {
- targetMpvSocketPath?: string | null;
- resolveHelper?: () => WindowsTrackerHelperLaunchSpec | null;
- runHelperSync?: (
- spec: WindowsTrackerHelperLaunchSpec,
- mode: WindowsTrackerHelperRunMode,
- extraArgs?: string[],
- ) => WindowsTrackerHelperRunnerResult | null;
-} = {}): number | null {
- const targetMpvSocketPath = deps.targetMpvSocketPath?.trim();
- if (!targetMpvSocketPath) {
- return null;
- }
-
- const spec =
- deps.resolveHelper?.() ??
- resolveWindowsTrackerHelper({
- helperModeEnv: 'powershell',
- });
- if (!spec || spec.kind !== 'powershell') {
- return null;
- }
-
- const runHelper = deps.runHelperSync ?? runWindowsTrackerHelperWithSpawnSync;
- const result = runHelper(spec, 'target-hwnd', [targetMpvSocketPath]);
- if (!result) {
- return null;
- }
-
- const handle = Number.parseInt(result.stdout.trim(), 10);
- return Number.isFinite(handle) && handle > 0 ? handle : null;
-}
-
-export async function syncWindowsOverlayToMpvZOrder(deps: {
- overlayWindowHandle: string;
- targetMpvSocketPath?: string | null;
- resolveHelper?: () => WindowsTrackerHelperLaunchSpec | null;
- runHelper?: (
- spec: WindowsTrackerHelperLaunchSpec,
- mode: WindowsTrackerHelperRunMode,
- extraArgs?: string[],
- ) => Promise;
-}): Promise {
- const spec =
- deps.resolveHelper?.() ??
- resolveWindowsTrackerHelper({
- helperModeEnv: 'powershell',
- });
- if (!spec || spec.kind !== 'powershell') {
- return false;
- }
-
- const runHelper = deps.runHelper ?? runWindowsTrackerHelperWithExecFile;
- const extraArgs = [deps.targetMpvSocketPath ?? '', deps.overlayWindowHandle];
- const { stdout } = await runHelper(spec, 'bind-overlay', extraArgs);
- return stdout.trim() === 'ok';
-}
-
-export async function lowerWindowsOverlayInZOrder(deps: {
- overlayWindowHandle: string;
- resolveHelper?: () => WindowsTrackerHelperLaunchSpec | null;
- runHelper?: (
- spec: WindowsTrackerHelperLaunchSpec,
- mode: WindowsTrackerHelperRunMode,
- extraArgs?: string[],
- ) => Promise;
-}): Promise {
- const spec =
- deps.resolveHelper?.() ??
- resolveWindowsTrackerHelper({
- helperModeEnv: 'powershell',
- });
- if (!spec || spec.kind !== 'powershell') {
- return false;
- }
-
- const runHelper = deps.runHelper ?? runWindowsTrackerHelperWithExecFile;
- const { stdout } = await runHelper(spec, 'lower-overlay', ['', deps.overlayWindowHandle]);
- return stdout.trim() === 'ok';
-}
-
-export function setWindowsOverlayOwnerNative(overlayHwnd: number, mpvHwnd: number): boolean {
- try {
- const win32 = require('./win32') as typeof import('./win32');
- win32.setOverlayOwner(overlayHwnd, mpvHwnd);
+ loadWin32().setOverlayOwner(overlayHwnd, mpvHwnd);
return true;
} catch {
return false;
}
}
-export function ensureWindowsOverlayTransparencyNative(overlayHwnd: number): boolean {
+export function ensureWindowsOverlayTransparency(overlayHwnd: number): boolean {
try {
- const win32 = require('./win32') as typeof import('./win32');
- win32.ensureOverlayTransparency(overlayHwnd);
+ loadWin32().ensureOverlayTransparency(overlayHwnd);
return true;
} catch {
return false;
}
}
-export function bindWindowsOverlayAboveMpvNative(overlayHwnd: number, mpvHwnd: number): boolean {
+export function bindWindowsOverlayAboveMpv(overlayHwnd: number, mpvHwnd: number): boolean {
try {
- const win32 = require('./win32') as typeof import('./win32');
+ const win32 = loadWin32();
win32.bindOverlayAboveMpv(overlayHwnd, mpvHwnd);
win32.ensureOverlayTransparency(overlayHwnd);
return true;
@@ -521,85 +59,19 @@ export function bindWindowsOverlayAboveMpvNative(overlayHwnd: number, mpvHwnd: n
}
}
-export function clearWindowsOverlayOwnerNative(overlayHwnd: number): boolean {
+export function clearWindowsOverlayOwner(overlayHwnd: number): boolean {
try {
- const win32 = require('./win32') as typeof import('./win32');
- win32.clearOverlayOwner(overlayHwnd);
+ loadWin32().clearOverlayOwner(overlayHwnd);
return true;
} catch {
return false;
}
}
-export function getWindowsForegroundProcessNameNative(): string | null {
+export function getWindowsForegroundProcessName(): string | null {
try {
- const win32 = require('./win32') as typeof import('./win32');
- return win32.getForegroundProcessName();
+ return loadWin32().getForegroundProcessName();
} catch {
return null;
}
}
-
-export function resolveWindowsTrackerHelper(
- options: ResolveWindowsTrackerHelperOptions = {},
-): WindowsTrackerHelperLaunchSpec | null {
- const existsSync = options.existsSync ?? fs.existsSync;
- const mkdirSync = options.mkdirSync ?? fs.mkdirSync;
- const copyFileSync = options.copyFileSync ?? fs.copyFileSync;
- const dirname = options.dirname ?? __dirname;
- const resourcesPath = options.resourcesPath ?? process.resourcesPath;
- const mode = normalizeHelperMode(
- options.helperModeEnv ?? process.env.SUBMINER_WINDOWS_TRACKER_HELPER,
- );
- const override = normalizeHelperPathOverride(
- options.helperPathEnv ?? process.env.SUBMINER_WINDOWS_TRACKER_HELPER_PATH,
- mode,
- );
-
- if (override) {
- if (!existsSync(override.path)) {
- log.warn(`Configured Windows tracker helper path does not exist: ${override.path}`);
- return null;
- }
- const helperPath = materializeAsarHelper(override.path, override.kind, {
- mkdirSync,
- copyFileSync,
- });
- return helperPath ? createLaunchSpec(helperPath, override.kind) : null;
- }
-
- const candidates = getHelperCandidates(dirname, resourcesPath);
- const orderedCandidates =
- mode === 'powershell'
- ? candidates.filter((candidate) => candidate.kind === 'powershell')
- : mode === 'native'
- ? candidates.filter((candidate) => candidate.kind === 'native')
- : candidates;
-
- for (const candidate of orderedCandidates) {
- if (!existsSync(candidate.path)) {
- continue;
- }
-
- const helperPath = materializeAsarHelper(candidate.path, candidate.kind, {
- mkdirSync,
- copyFileSync,
- });
- if (!helperPath) {
- continue;
- }
-
- log.info(`Using Windows helper (${candidate.kind}): ${helperPath}`);
- return createLaunchSpec(helperPath, candidate.kind);
- }
-
- if (mode === 'native') {
- log.warn('Windows native tracker helper requested but no helper was found.');
- } else if (mode === 'powershell') {
- log.warn('Windows PowerShell tracker helper requested but no helper was found.');
- } else {
- log.warn('Windows tracker helper not found.');
- }
-
- return null;
-}
diff --git a/src/window-trackers/windows-tracker.ts b/src/window-trackers/windows-tracker.ts
index 648d8de5..f7375799 100644
--- a/src/window-trackers/windows-tracker.ts
+++ b/src/window-trackers/windows-tracker.ts
@@ -19,10 +19,6 @@
import { BaseWindowTracker } from './base-tracker';
import type { WindowGeometry } from '../types';
import type { MpvPollResult } from './win32';
-import {
- queryWindowsTrackerMpvWindows,
- shouldUseWindowsTrackerPowershellFallback,
-} from './windows-helper';
import { createLogger } from '../logger';
const log = createLogger('tracker').child('windows');
@@ -35,16 +31,8 @@ type WindowsTrackerDeps = {
now?: () => number;
};
-function defaultPollMpvWindows(targetMpvSocketPath?: string | null): MpvPollResult {
- if (targetMpvSocketPath && shouldUseWindowsTrackerPowershellFallback()) {
- const helperResult = queryWindowsTrackerMpvWindows({
- targetMpvSocketPath,
- });
- if (helperResult) {
- return helperResult;
- }
- }
-
+function defaultPollMpvWindows(_targetMpvSocketPath?: string | null): MpvPollResult {
+ void _targetMpvSocketPath;
const win32 = require('./win32') as typeof import('./win32');
return win32.findMpvWindows();
}