mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-05-26 00:55:16 -07:00
fix(macos): release overlay when mpv loses focus
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
// It works with both bundled and unbundled mpv installations.
|
||||
//
|
||||
// Usage: swift get-mpv-window-macos.swift
|
||||
// Output: "x,y,width,height,focused", "minimized", "active", or "not-found"
|
||||
// Output: "x,y,width,height,focused", "minimized", "active", "inactive", or "not-found"
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
@@ -34,6 +34,7 @@ private enum WindowLookupResult {
|
||||
case visible(WindowState)
|
||||
case minimized
|
||||
case active
|
||||
case inactive
|
||||
}
|
||||
|
||||
private let targetMpvSocketPath: String? = {
|
||||
@@ -176,11 +177,17 @@ private func isFocusedMpvWindow(ownerPid: pid_t, frontmost: FrontmostApplication
|
||||
}
|
||||
|
||||
private func isFrontmostTargetMpv(_ frontmost: FrontmostApplicationState?) -> Bool {
|
||||
guard let frontmost = frontmost else {
|
||||
guard let frontmost = frontmost, frontmost.isMpv else {
|
||||
return false
|
||||
}
|
||||
|
||||
return frontmost.isMpv && windowHasTargetSocket(frontmost.pid)
|
||||
if windowHasTargetSocket(frontmost.pid) {
|
||||
return true
|
||||
}
|
||||
|
||||
// When macOS says mpv is frontmost but geometry APIs miss, keep the
|
||||
// overlay stable even if ps cannot expose the socket argument.
|
||||
return targetMpvSocketPath != nil
|
||||
}
|
||||
|
||||
private func windowStateFromAccessibilityAPI() -> WindowLookupResult? {
|
||||
@@ -307,9 +314,13 @@ private let lookupResult: WindowLookupResult? = {
|
||||
if let cgWindow = windowStateFromCoreGraphics() {
|
||||
return .visible(cgWindow)
|
||||
}
|
||||
if isFrontmostTargetMpv(frontmostApplicationState()) {
|
||||
let frontmost = frontmostApplicationState()
|
||||
if isFrontmostTargetMpv(frontmost) {
|
||||
return .active
|
||||
}
|
||||
if frontmost != nil {
|
||||
return .inactive
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
|
||||
@@ -323,6 +334,8 @@ if let result = lookupResult {
|
||||
print("minimized")
|
||||
case .active:
|
||||
print("active")
|
||||
case .inactive:
|
||||
print("inactive")
|
||||
}
|
||||
} else {
|
||||
print("not-found")
|
||||
|
||||
@@ -59,12 +59,16 @@ test('focused mpv window follows the frontmost mpv app signal', () => {
|
||||
|
||||
test('frontmost mpv app emits active state when geometry lookup misses', () => {
|
||||
assert.ok(
|
||||
source.includes('case active'),
|
||||
/case\s+\.active:/.test(source),
|
||||
'helper should expose an active state without window geometry',
|
||||
);
|
||||
assert.ok(
|
||||
source.includes('frontmost.isMpv && windowHasTargetSocket(frontmost.pid)'),
|
||||
'active state should be limited to the frontmost target mpv process',
|
||||
source.includes('if windowHasTargetSocket(frontmost.pid)'),
|
||||
'active state should still accept a matching target socket when available',
|
||||
);
|
||||
assert.ok(
|
||||
source.includes('return targetMpvSocketPath != nil'),
|
||||
'active state should preserve frontmost mpv even if command-line socket detection fails',
|
||||
);
|
||||
assert.ok(
|
||||
source.includes('return .active'),
|
||||
@@ -72,3 +76,19 @@ test('frontmost mpv app emits active state when geometry lookup misses', () => {
|
||||
);
|
||||
assert.ok(source.includes('print("active")'), 'active state should be printed for the tracker');
|
||||
});
|
||||
|
||||
test('frontmost non-mpv app emits inactive state when geometry lookup misses', () => {
|
||||
assert.ok(
|
||||
/case\s+\.inactive:/.test(source),
|
||||
'helper should expose an inactive state without window geometry',
|
||||
);
|
||||
assert.ok(
|
||||
source.includes('if frontmost != nil'),
|
||||
'helper should distinguish a known non-mpv frontmost app from an unknown miss',
|
||||
);
|
||||
assert.ok(source.includes('return .inactive'), 'known non-mpv focus should return inactive');
|
||||
assert.ok(
|
||||
source.includes('print("inactive")'),
|
||||
'inactive state should be printed for the tracker',
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user