From cca9b5ad57d4c51bf76714fdbcd507c584bef069 Mon Sep 17 00:00:00 2001 From: Korkyzer Date: Wed, 4 Mar 2026 13:34:10 +0100 Subject: [PATCH 1/3] fix: use NSApplication.shared for proper WindowServer connection CGDisplayCreateImage returns desktop wallpaper instead of actual screen content when running as a background process. This is because RunLoop.main.run() does not establish a WindowServer connection, so macOS TCC silently denies real screen capture. Fix: Initialize NSApplication.shared with .accessory activation policy before setting up capture timers, and use app.run() instead of RunLoop.main.run(). --- Sources/ScreenTextKit/Capture/DaemonRunner.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sources/ScreenTextKit/Capture/DaemonRunner.swift b/Sources/ScreenTextKit/Capture/DaemonRunner.swift index 3be0ee0..a27fa01 100644 --- a/Sources/ScreenTextKit/Capture/DaemonRunner.swift +++ b/Sources/ScreenTextKit/Capture/DaemonRunner.swift @@ -27,6 +27,10 @@ public final class DaemonRunner { } public func run() -> Never { + // FIX: Register with WindowServer for proper screen capture + let app = NSApplication.shared + app.setActivationPolicy(.accessory) + observer = NSWorkspace.shared.notificationCenter.addObserver( forName: NSWorkspace.didActivateApplicationNotification, object: nil, @@ -55,7 +59,7 @@ public final class DaemonRunner { capture(trigger: .manual) logger.info("Daemon started") - RunLoop.main.run() + app.run() fatalError("Run loop exited unexpectedly") } From 838b5fc1ea6bbe024819f07084d28fbbfb48e3b2 Mon Sep 17 00:00:00 2001 From: Korkyzer Date: Wed, 4 Mar 2026 15:32:09 +0100 Subject: [PATCH 2/3] feat: add app icon for macOS bundle --- assets/AppIcon.png | Bin 0 -> 69054 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/AppIcon.png diff --git a/assets/AppIcon.png b/assets/AppIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..7a16638bb4fb1f748106dc624c27ad8c62acc810 GIT binary patch literal 69054 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 Av;Y7A literal 0 HcmV?d00001 From 6f95ceafd8948f50c4fb90fe7b354cc8b9a9e9f5 Mon Sep 17 00:00:00 2001 From: Korkyzer Date: Wed, 4 Mar 2026 19:15:08 +0100 Subject: [PATCH 3/3] fix: OCR capture resolution and dark theme support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - maxDimension 1280→2560, jpegQuality 0.45→0.85 - Run both accessibility + OCR, keep longer result - Color-invert frames before OCR for dark UIs - minimumTextHeight 0.005→0.002 Co-Authored-By: Claude Opus 4.6 --- .../Capture/FrameBufferStore.swift | 4 +-- .../Capture/NativeTextExtractor.swift | 26 +++++++++------ .../Capture/OCRTextExtractor.swift | 33 +++++++++++++++++-- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/Sources/ScreenTextKit/Capture/FrameBufferStore.swift b/Sources/ScreenTextKit/Capture/FrameBufferStore.swift index f9a6250..b025581 100644 --- a/Sources/ScreenTextKit/Capture/FrameBufferStore.swift +++ b/Sources/ScreenTextKit/Capture/FrameBufferStore.swift @@ -14,8 +14,8 @@ public final class FrameBufferStore { paths: ScreenTextPaths, retentionSeconds: Int, maxFrames: Int, - maxDimension: Int = 1280, - jpegQuality: Double = 0.45 + maxDimension: Int = 2560, + jpegQuality: Double = 0.85 ) { self.paths = paths self.retentionSeconds = retentionSeconds diff --git a/Sources/ScreenTextKit/Capture/NativeTextExtractor.swift b/Sources/ScreenTextKit/Capture/NativeTextExtractor.swift index cc64ee3..462b9c6 100644 --- a/Sources/ScreenTextKit/Capture/NativeTextExtractor.swift +++ b/Sources/ScreenTextKit/Capture/NativeTextExtractor.swift @@ -27,19 +27,25 @@ public final class NativeTextExtractor: TextExtractor { public func extract() throws -> ExtractedText? { let metadata = metadataProvider.currentMetadata() - if !forceOCR { - if let accessibilityText = accessibilityExtractor.extractText(), - accessibilityText.count >= minimumAccessibilityChars { - return ExtractedText(text: accessibilityText, source: .accessibility, metadata: metadata) - } - } + let accessibilityText = accessibilityExtractor.extractText() + let hasGoodAccessibility = (accessibilityText?.count ?? 0) >= minimumAccessibilityChars - guard ocrEnabled else { - return nil + // Always run OCR too (if enabled) and keep the longer result + var ocrText: String? = nil + if ocrEnabled { + ocrText = try ocrExtractor.extractText() } - if let ocrText = try ocrExtractor.extractText(), !ocrText.isEmpty { - return ExtractedText(text: ocrText, source: .ocr, metadata: metadata) + let accLen = accessibilityText?.count ?? 0 + let ocrLen = ocrText?.count ?? 0 + + // Return whichever extracted more text + if ocrLen > accLen && ocrLen > 0 { + return ExtractedText(text: ocrText!, source: .ocr, metadata: metadata) + } else if accLen > 0 && hasGoodAccessibility { + return ExtractedText(text: accessibilityText!, source: .accessibility, metadata: metadata) + } else if ocrLen > 0 { + return ExtractedText(text: ocrText!, source: .ocr, metadata: metadata) } return nil diff --git a/Sources/ScreenTextKit/Capture/OCRTextExtractor.swift b/Sources/ScreenTextKit/Capture/OCRTextExtractor.swift index 3d763e6..25fa5b6 100644 --- a/Sources/ScreenTextKit/Capture/OCRTextExtractor.swift +++ b/Sources/ScreenTextKit/Capture/OCRTextExtractor.swift @@ -1,4 +1,5 @@ import CoreGraphics +import CoreImage import Foundation import ImageIO import Vision @@ -7,7 +8,7 @@ public final class OCRTextExtractor { private let minimumTextHeight: Float private let recognitionLevel: VNRequestTextRecognitionLevel - public init(minimumTextHeight: Float = 0.005, recognitionLevel: VNRequestTextRecognitionLevel = .accurate) { + public init(minimumTextHeight: Float = 0.002, recognitionLevel: VNRequestTextRecognitionLevel = .accurate) { self.minimumTextHeight = minimumTextHeight self.recognitionLevel = recognitionLevel } @@ -17,7 +18,24 @@ public final class OCRTextExtractor { return nil } - return try extractText(from: image) + // Run OCR on both original and inverted image, keep the one with more text. + // Dark UIs (WhatsApp, Slack, etc.) yield much more text when colors are inverted. + let originalText = try extractText(from: image) + let invertedText: String? + if let inverted = invertColors(image) { + invertedText = try extractText(from: inverted) + } else { + invertedText = nil + } + + let orig = originalText ?? "" + let inv = invertedText ?? "" + + if orig.isEmpty && inv.isEmpty { + return nil + } + + return inv.count > orig.count ? inv : orig } public func extractText(fromImageURL imageURL: URL) throws -> String? { @@ -54,4 +72,15 @@ public final class OCRTextExtractor { return lines.joined(separator: "\n") } + + /// Invert image colors using CoreImage — turns dark UIs light for better OCR + private func invertColors(_ image: CGImage) -> CGImage? { + let ciImage = CIImage(cgImage: image) + guard let filter = CIFilter(name: "CIColorInvert") else { return nil } + filter.setValue(ciImage, forKey: kCIInputImageKey) + guard let output = filter.outputImage else { return nil } + + let context = CIContext(options: [.useSoftwareRenderer: false]) + return context.createCGImage(output, from: output.extent) + } }