forked from OctoWoW/OctoLauncher
Fix monitor resolution issue with correct monitor detection
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "octo-launcher",
|
||||
"version": "1.2.0",
|
||||
"version": "1.2.1",
|
||||
"description": "An Electron application for launching and updating the OctoWoW client",
|
||||
"author": "OctoWoW",
|
||||
"copyright": "Copyright © 2026 OctoWoW",
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import os from 'node:os';
|
||||
import { spawn } from 'node:child_process';
|
||||
|
||||
import Logger from 'electron-log/main';
|
||||
|
||||
const SCRIPT = [
|
||||
'$ErrorActionPreference = "Stop"',
|
||||
"Add-Type -TypeDefinition @'",
|
||||
'using System;',
|
||||
'using System.Runtime.InteropServices;',
|
||||
'public static class VmmfDisplays {',
|
||||
' [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]',
|
||||
' public struct DISPLAY_DEVICE {',
|
||||
' public int cb;',
|
||||
' [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string DeviceName;',
|
||||
' [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string DeviceString;',
|
||||
' public int StateFlags;',
|
||||
' [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string DeviceID;',
|
||||
' [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public string DeviceKey;',
|
||||
' }',
|
||||
' [DllImport("user32.dll", EntryPoint="EnumDisplayDevicesA", CharSet=CharSet.Ansi)]',
|
||||
' public static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);',
|
||||
'}',
|
||||
"'@",
|
||||
'$dd = New-Object VmmfDisplays+DISPLAY_DEVICE',
|
||||
'$dd.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($dd)',
|
||||
'for ($i = 0; [VmmfDisplays]::EnumDisplayDevices([NullString]::Value, $i, [ref]$dd, 0); $i++) {',
|
||||
' if ($dd.StateFlags -band 4) { Write-Output $i; exit 0 }',
|
||||
'}',
|
||||
'exit 1'
|
||||
].join('\n');
|
||||
|
||||
export const detectPrimaryDisplayIndex = (): Promise<number> => {
|
||||
if (os.platform() !== 'win32') return Promise.resolve(0);
|
||||
|
||||
const encoded = Buffer.from(SCRIPT, 'utf16le').toString('base64');
|
||||
|
||||
return new Promise(resolve => {
|
||||
let settled = false;
|
||||
const finish = (index: number) => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
resolve(index);
|
||||
};
|
||||
|
||||
const child = spawn(
|
||||
'powershell.exe',
|
||||
['-NoProfile', '-NonInteractive', '-EncodedCommand', encoded],
|
||||
{ windowsHide: true }
|
||||
);
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
child.kill();
|
||||
Logger.warn('Primary display detection timed out');
|
||||
finish(0);
|
||||
}, 8000);
|
||||
|
||||
let stdout = '';
|
||||
child.stdout.on('data', d => (stdout += String(d)));
|
||||
child.on('error', e => {
|
||||
Logger.warn('Primary display detection failed to launch PowerShell', e);
|
||||
finish(0);
|
||||
});
|
||||
child.on('exit', code => {
|
||||
const index = Number(stdout.trim());
|
||||
if (code === 0 && Number.isInteger(index) && index >= 0) {
|
||||
Logger.info(`Detected primary display at device index ${index}`);
|
||||
finish(index);
|
||||
} else {
|
||||
Logger.warn('Primary display detection failed, defaulting to 0');
|
||||
finish(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -13,6 +13,7 @@ import Preferences from './preferences';
|
||||
import Observable from './observable';
|
||||
import Updater from './updater';
|
||||
import { addDll, removeDll } from './dllsTxt';
|
||||
import { detectPrimaryDisplayIndex } from './displays';
|
||||
|
||||
const MOD_DOWNLOAD_TIMEOUT_MS = 60_000;
|
||||
|
||||
@@ -113,8 +114,10 @@ class ModsClass extends Observable<ModsStatus> {
|
||||
if (clientDir) {
|
||||
const vmmfDll = path.join(clientDir, 'VanillaMultiMonitorFix.dll');
|
||||
const vmmfCfg = path.join(clientDir, 'VMMFix_preferred_monitor.txt');
|
||||
if ((await fs.pathExists(vmmfDll)) && !(await fs.pathExists(vmmfCfg)))
|
||||
await fs.writeFile(vmmfCfg, '0\n', 'utf8').catch(() => {});
|
||||
if ((await fs.pathExists(vmmfDll)) && !(await fs.pathExists(vmmfCfg))) {
|
||||
const index = await detectPrimaryDisplayIndex();
|
||||
await fs.writeFile(vmmfCfg, `${index}\n`, 'utf8').catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
for (const m of MODS) {
|
||||
|
||||
Reference in New Issue
Block a user