mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-02-27 18:22:41 -08:00
Track mpv overlays by configured socket window only
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import Foundation
|
||||
|
||||
private struct WindowGeometry {
|
||||
let x: Int
|
||||
@@ -19,6 +20,58 @@ private struct WindowGeometry {
|
||||
let height: Int
|
||||
}
|
||||
|
||||
private let targetMpvSocketPath: String? = {
|
||||
guard CommandLine.arguments.count > 1 else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let value = CommandLine.arguments[1].trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return value.isEmpty ? nil : value
|
||||
}()
|
||||
|
||||
private func windowCommandLineForPid(_ pid: pid_t) -> String? {
|
||||
let process = Process()
|
||||
process.executableURL = URL(fileURLWithPath: "/bin/ps")
|
||||
process.arguments = ["-p", "\(pid)", "-o", "args="]
|
||||
|
||||
let pipe = Pipe()
|
||||
process.standardOutput = pipe
|
||||
process.standardError = pipe
|
||||
|
||||
do {
|
||||
try process.run()
|
||||
process.waitUntilExit()
|
||||
} catch {
|
||||
return nil
|
||||
}
|
||||
|
||||
if process.terminationStatus != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||
guard let commandLine = String(data: data, encoding: .utf8) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return commandLine
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
.replacingOccurrences(of: "\n", with: " ")
|
||||
}
|
||||
|
||||
private func windowHasTargetSocket(_ pid: pid_t) -> Bool {
|
||||
guard let socketPath = targetMpvSocketPath else {
|
||||
return true
|
||||
}
|
||||
|
||||
guard let commandLine = windowCommandLineForPid(pid) else {
|
||||
return false
|
||||
}
|
||||
|
||||
return commandLine.contains("--input-ipc-server=\(socketPath)") ||
|
||||
commandLine.contains("--input-ipc-server \(socketPath)")
|
||||
}
|
||||
|
||||
private func geometryFromRect(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) -> WindowGeometry {
|
||||
let minX = Int(floor(x))
|
||||
let minY = Int(floor(y))
|
||||
@@ -93,6 +146,10 @@ private func geometryFromAccessibilityAPI() -> WindowGeometry? {
|
||||
|
||||
for app in runningApps {
|
||||
let appElement = AXUIElementCreateApplication(app.processIdentifier)
|
||||
if !windowHasTargetSocket(app.processIdentifier) {
|
||||
continue
|
||||
}
|
||||
|
||||
var windowsRef: CFTypeRef?
|
||||
let status = AXUIElementCopyAttributeValue(appElement, kAXWindowsAttribute as CFString, &windowsRef)
|
||||
guard status == .success, let windows = windowsRef as? [AXUIElement], !windows.isEmpty else {
|
||||
@@ -106,6 +163,15 @@ private func geometryFromAccessibilityAPI() -> WindowGeometry? {
|
||||
continue
|
||||
}
|
||||
|
||||
var windowPid: pid_t = 0
|
||||
if AXUIElementGetPid(window, &windowPid) != .success {
|
||||
continue
|
||||
}
|
||||
|
||||
if !windowHasTargetSocket(windowPid) {
|
||||
continue
|
||||
}
|
||||
|
||||
if let geometry = geometryFromAXWindow(window) {
|
||||
return geometry
|
||||
}
|
||||
@@ -127,6 +193,14 @@ private func geometryFromCoreGraphics() -> WindowGeometry? {
|
||||
continue
|
||||
}
|
||||
|
||||
guard let ownerPid = window[kCGWindowOwnerPID as String] as? pid_t else {
|
||||
continue
|
||||
}
|
||||
|
||||
if !windowHasTargetSocket(ownerPid) {
|
||||
continue
|
||||
}
|
||||
|
||||
if let layer = window[kCGWindowLayer as String] as? Int, layer != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user