From 2fce891a922ef87f5480c5b8474c86fc75a865b3 Mon Sep 17 00:00:00 2001 From: sudacode Date: Wed, 21 Oct 2026 08:54:33 -0700 Subject: [PATCH] fix(jellyfin): keep invalid mpv.executablePath from falling back in preview - Timing preview passes an invalid configured path through so the spawn fails, instead of the preview silently running mpv from PATH - Docs: Accessibility is not strictly required on macOS; without it the window helper uses a Core Graphics lookup that cannot detect a minimized mpv window --- README.md | 2 +- docs-site/installation.md | 2 +- docs-site/troubleshooting.md | 2 +- src/main.ts | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 87a14f66..d48e661d 100644 --- a/README.md +++ b/README.md @@ -199,7 +199,7 @@ The AppImage is all you need. First-run setup can install the optional `subminer Download the latest DMG from [GitHub Releases](https://github.com/ksyasuda/SubMiner/releases/latest) and drag `SubMiner.app` into `/Applications`. -Then enable SubMiner under **System Settings > Privacy & Security > Accessibility** (named **Device Control and Data Access** on macOS 27), or the overlay cannot follow the mpv window. If macOS blocks the first launch, right-click the app and choose **Open**. +Then enable SubMiner under **System Settings > Privacy & Security > Accessibility** (named **Device Control and Data Access** on macOS 27) so the overlay can track the mpv window. Without it, SubMiner falls back to a basic window lookup that cannot tell when mpv is minimized. If macOS blocks the first launch, right-click the app and choose **Open**. diff --git a/docs-site/installation.md b/docs-site/installation.md index 08f7b3fb..b169d401 100644 --- a/docs-site/installation.md +++ b/docs-site/installation.md @@ -187,7 +187,7 @@ First-run setup can install the `subminer` command for you. xattr -d com.apple.quarantine /Applications/SubMiner.app ``` -3. Open **System Settings > Privacy & Security > Accessibility** and enable SubMiner (add it if it is missing). On macOS 27 this list is named **Device Control and Data Access**. The overlay cannot follow the mpv window without this. +3. Open **System Settings > Privacy & Security > Accessibility** and enable SubMiner (add it if it is missing). On macOS 27 this list is named **Device Control and Data Access**. SubMiner uses it to track the mpv window. Without it, SubMiner falls back to a basic window lookup that cannot tell when mpv is minimized. First-run setup can install the `subminer` command for you. diff --git a/docs-site/troubleshooting.md b/docs-site/troubleshooting.md index cb0e3984..13c1952a 100644 --- a/docs-site/troubleshooting.md +++ b/docs-site/troubleshooting.md @@ -262,5 +262,5 @@ mpv --gpu-context=x11vk,x11egl,x11 video.mkv ## macOS -- Accessibility permission is required for window tracking: System Settings > Privacy & Security > Accessibility. On macOS 27 this list is named **Device Control and Data Access**. +- Grant Accessibility permission under System Settings > Privacy & Security > Accessibility (named **Device Control and Data Access** on macOS 27). Without it, SubMiner falls back to a basic window lookup that cannot tell when mpv is minimized. - If Gatekeeper blocks the app, right-click it and choose Open, or run `xattr -d com.apple.quarantine /path/to/SubMiner.app`. diff --git a/src/main.ts b/src/main.ts index 8b73bb97..5553366f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2999,7 +2999,11 @@ const mediaTimingReviewRuntime = createMediaTimingReviewRuntime({ getMpvClient: () => appState.mpvClient, getCurrentMediaPath: () => appState.currentMediaPath?.trim() || appState.mpvClient?.currentVideoPath?.trim() || null, - getMpvExecutablePath: () => findMpvExecutablePath(configService.getConfig().mpv.executablePath), + // An invalid configured path is passed through so the preview fails instead of using PATH mpv. + getMpvExecutablePath: () => { + const configuredPath = configService.getConfig().mpv.executablePath; + return findMpvExecutablePath(configuredPath) || configuredPath; + }, createPreviewSession: () => new MediaTimingPreviewSession(), generateWaveform: (options) => generateSpeechWaveform(options), generateFrame: (options) => mediaTimingFrameExtractor.generate(options),