mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-27 12:55:20 -07:00
Fix Windows mpv handoff and tray setup (#82)
This commit is contained in:
@@ -256,6 +256,7 @@ test('buildConfiguredMpvDefaultArgs appends maximized launch mode to configured
|
||||
'--sub-file-paths=.;subs;subtitles',
|
||||
'--sid=auto',
|
||||
'--secondary-sid=auto',
|
||||
'--sub-visibility=no',
|
||||
'--secondary-sub-visibility=no',
|
||||
'--alang=ja,jp,jpn,japanese,en,eng,english,enus,en-us',
|
||||
'--slang=ja,jp,jpn,japanese,en,eng,english,enus,en-us',
|
||||
|
||||
+13
-4
@@ -47,7 +47,10 @@ type SpawnTarget = {
|
||||
env?: NodeJS.ProcessEnv;
|
||||
};
|
||||
|
||||
type PathModule = Pick<typeof path, 'join' | 'extname' | 'delimiter' | 'sep' | 'resolve'>;
|
||||
type PathModule = Pick<
|
||||
typeof path,
|
||||
'dirname' | 'join' | 'extname' | 'delimiter' | 'sep' | 'resolve' | 'isAbsolute' | 'normalize'
|
||||
>;
|
||||
|
||||
const DETACHED_IDLE_MPV_PID_FILE = path.join(os.tmpdir(), 'subminer-idle-mpv.pid');
|
||||
const OVERLAY_START_SOCKET_READY_TIMEOUT_MS = 900;
|
||||
@@ -62,6 +65,12 @@ export interface LauncherRuntimePluginPlan {
|
||||
errorMessage: string | null;
|
||||
}
|
||||
|
||||
function resolvePluginCandidatePath(candidate: string, pathModule: PathModule): string {
|
||||
return pathModule.isAbsolute(candidate)
|
||||
? pathModule.normalize(candidate)
|
||||
: pathModule.resolve(candidate);
|
||||
}
|
||||
|
||||
export function parseMpvArgString(input: string): string[] {
|
||||
const chars = input;
|
||||
const args: string[] = [];
|
||||
@@ -291,12 +300,12 @@ export function resolveLauncherRuntimePluginPath(options: {
|
||||
pathModule?: typeof path;
|
||||
existsSync?: (candidate: string) => boolean;
|
||||
}): string | null {
|
||||
const platform = options.platform ?? process.platform;
|
||||
const pathModule = options.pathModule ?? path;
|
||||
const existsSync = options.existsSync ?? fs.existsSync;
|
||||
const env = options.env ?? process.env;
|
||||
const dirname = options.dirname ?? __dirname;
|
||||
const cwd = options.cwd ?? process.cwd();
|
||||
const platform = options.platform ?? process.platform;
|
||||
const homeDir = options.homeDir ?? os.homedir();
|
||||
const candidates: string[] = [];
|
||||
|
||||
@@ -344,7 +353,7 @@ export function resolveLauncherRuntimePluginPath(options: {
|
||||
|
||||
const seen = new Set<string>();
|
||||
for (const candidate of candidates) {
|
||||
const resolved = pathModule.resolve(candidate);
|
||||
const resolved = resolvePluginCandidatePath(candidate, pathModule);
|
||||
if (seen.has(resolved)) continue;
|
||||
seen.add(resolved);
|
||||
const entrypoint = normalizeRuntimePluginEntrypoint(resolved, { pathModule, existsSync });
|
||||
@@ -1704,7 +1713,7 @@ export async function waitForUnixSocketReady(
|
||||
const deadline = nowMs() + timeoutMs;
|
||||
while (nowMs() < deadline) {
|
||||
try {
|
||||
if (fs.existsSync(socketPath)) {
|
||||
if (process.platform === 'win32' || fs.existsSync(socketPath)) {
|
||||
const ready = await canConnectUnixSocket(socketPath);
|
||||
if (ready) return true;
|
||||
}
|
||||
|
||||
+2
-2
@@ -365,8 +365,8 @@ export function findRofiTheme(scriptPath: string): string | null {
|
||||
} else {
|
||||
const xdgDataHome = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local/share');
|
||||
candidates.push(path.join(xdgDataHome, 'SubMiner/themes', ROFI_THEME_FILE));
|
||||
candidates.push(path.join('/usr/local/share/SubMiner/themes', ROFI_THEME_FILE));
|
||||
candidates.push(path.join('/usr/share/SubMiner/themes', ROFI_THEME_FILE));
|
||||
candidates.push(path.posix.join('/usr/local/share/SubMiner/themes', ROFI_THEME_FILE));
|
||||
candidates.push(path.posix.join('/usr/share/SubMiner/themes', ROFI_THEME_FILE));
|
||||
}
|
||||
|
||||
candidates.push(path.join(scriptDir, 'assets', 'themes', ROFI_THEME_FILE));
|
||||
|
||||
@@ -40,6 +40,19 @@ function writeExecutable(filePath: string, body: string): void {
|
||||
fs.chmodSync(filePath, 0o755);
|
||||
}
|
||||
|
||||
function writeFixtureExecutable(basePath: string, body: string): string {
|
||||
if (process.platform !== 'win32') {
|
||||
writeExecutable(basePath, body);
|
||||
return basePath;
|
||||
}
|
||||
|
||||
const scriptPath = `${basePath}.js`;
|
||||
const commandPath = `${basePath}.cmd`;
|
||||
fs.writeFileSync(scriptPath, body);
|
||||
fs.writeFileSync(commandPath, `@echo off\r\n"${process.execPath}" "${scriptPath}" %*\r\n`);
|
||||
return commandPath;
|
||||
}
|
||||
|
||||
function createSmokeCase(name: string): SmokeCase {
|
||||
const baseDir = path.join(process.cwd(), '.tmp', 'launcher-smoke');
|
||||
fs.mkdirSync(baseDir, { recursive: true });
|
||||
@@ -52,8 +65,8 @@ function createSmokeCase(name: string): SmokeCase {
|
||||
const socketDir = fs.mkdtempSync(path.join(os.tmpdir(), 'subminer-smoke-sock-'));
|
||||
const socketPath = path.join(socketDir, 'subminer.sock');
|
||||
const videoPath = path.join(root, 'video.mkv');
|
||||
const fakeAppPath = path.join(binDir, 'fake-subminer');
|
||||
const fakeMpvPath = path.join(binDir, 'mpv');
|
||||
const fakeAppBasePath = path.join(binDir, 'fake-subminer');
|
||||
const fakeMpvBasePath = path.join(binDir, 'mpv');
|
||||
const mpvOverlayLogPath = path.join(artifactsDir, 'mpv-overlay.log');
|
||||
|
||||
fs.mkdirSync(artifactsDir, { recursive: true });
|
||||
@@ -74,8 +87,8 @@ function createSmokeCase(name: string): SmokeCase {
|
||||
const fakeAppStartLogPath = path.join(artifactsDir, 'fake-app-start.log');
|
||||
const fakeAppStopLogPath = path.join(artifactsDir, 'fake-app-stop.log');
|
||||
|
||||
writeExecutable(
|
||||
fakeMpvPath,
|
||||
const fakeMpvPath = writeFixtureExecutable(
|
||||
fakeMpvBasePath,
|
||||
`#!/usr/bin/env bun
|
||||
const fs = require('node:fs');
|
||||
const net = require('node:net');
|
||||
@@ -113,8 +126,8 @@ process.on('SIGTERM', closeAndExit);
|
||||
`,
|
||||
);
|
||||
|
||||
writeExecutable(
|
||||
fakeAppPath,
|
||||
const fakeAppPath = writeFixtureExecutable(
|
||||
fakeAppBasePath,
|
||||
`#!/usr/bin/env bun
|
||||
const fs = require('node:fs');
|
||||
|
||||
@@ -157,14 +170,21 @@ process.exit(0);
|
||||
}
|
||||
|
||||
function makeTestEnv(smokeCase: SmokeCase): NodeJS.ProcessEnv {
|
||||
return {
|
||||
const env: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
HOME: smokeCase.homeDir,
|
||||
XDG_CONFIG_HOME: smokeCase.xdgConfigHome,
|
||||
SUBMINER_APPIMAGE_PATH: smokeCase.fakeAppPath,
|
||||
SUBMINER_MPV_LOG: smokeCase.mpvOverlayLogPath,
|
||||
PATH: `${smokeCase.binDir}${path.delimiter}${process.env.PATH || ''}`,
|
||||
};
|
||||
const pathKey = Object.keys(env).find((key) => key.toLowerCase() === 'path') ?? 'PATH';
|
||||
env[pathKey] = `${smokeCase.binDir}${path.delimiter}${env[pathKey] || ''}`;
|
||||
for (const key of Object.keys(env)) {
|
||||
if (key !== pathKey && key.toLowerCase() === 'path') {
|
||||
delete env[key];
|
||||
}
|
||||
}
|
||||
return env;
|
||||
}
|
||||
|
||||
function runLauncher(
|
||||
|
||||
@@ -60,6 +60,7 @@ export const DEFAULT_MPV_SUBMINER_ARGS = [
|
||||
'--sub-file-paths=.;subs;subtitles',
|
||||
'--sid=auto',
|
||||
'--secondary-sid=auto',
|
||||
'--sub-visibility=no',
|
||||
'--secondary-sub-visibility=no',
|
||||
'--alang=ja,jp,jpn,japanese,en,eng,english,enus,en-us',
|
||||
'--slang=ja,jp,jpn,japanese,en,eng,english,enus,en-us',
|
||||
|
||||
Reference in New Issue
Block a user