@@ -88,6 +88,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
88
88
private var wasRecordingBeforeSleep : Bool = false
89
89
private var wasRecordingBeforeTimelineView : Bool = false
90
90
private var wasRecordingBeforeSearchView : Bool = false
91
+
92
+ private var lastImageData : Data ? = nil
93
+ private var lastActiveApplication : String ? = nil
91
94
92
95
func applicationDidFinishLaunching( _ notification: Notification ) {
93
96
let _ = DatabaseManager . shared
@@ -321,6 +324,17 @@ class AppDelegate: NSObject, NSApplicationDelegate {
321
324
let text = TextMerger . shared. mergeTexts ( texts: texts)
322
325
ClipboardManager . shared. replaceClipboardContents ( with: text)
323
326
}
327
+
328
+ private func displayImageChangedFromLast( imageData: Data ) -> Bool {
329
+ if let prevImage = lastImageData {
330
+ return prevImage. withUnsafeBytes { ptr1 in
331
+ imageData. withUnsafeBytes { ptr2 in
332
+ memcmp ( ptr1. baseAddress, ptr2. baseAddress, imageData. count) != 0
333
+ }
334
+ }
335
+ }
336
+ return false
337
+ }
324
338
325
339
private func scheduleScreenshot( shareableContent: SCShareableContent ) {
326
340
Task {
@@ -335,27 +349,38 @@ class AppDelegate: NSObject, NSApplicationDelegate {
335
349
// Do we want to record the timeline being searched?
336
350
guard let image = CGDisplayCreateImage ( display. displayID, rect: display. frame) else { return }
337
351
338
- let frameId = DatabaseManager . shared. insertFrame ( activeApplicationName: activeApplicationName)
352
+ let bitmapRep = NSBitmapImageRep ( cgImage: image)
353
+ guard let imageData = bitmapRep. representation ( using: . png, properties: [ : ] ) else { return }
339
354
340
- if settingsManager. settings. onlyOCRFrontmostWindow {
341
- // User wants to perform OCR on only active window.
355
+ // Might as well only check if the applications are the same, otherwise obviously different
356
+ if activeApplicationName != lastActiveApplication || displayImageChangedFromLast ( imageData: imageData) {
357
+ lastImageData = imageData;
358
+ lastActiveApplication = activeApplicationName;
342
359
343
- // We need to determine the scale factor for cropping. CGImage is
344
- // measured in pixels, display sizes are measured in points.
345
- let scale = max ( CGFloat ( image. width) / CGFloat( display. width) , CGFloat ( image. height) / CGFloat( display. height) )
360
+ let frameId = DatabaseManager . shared. insertFrame ( activeApplicationName: activeApplicationName)
346
361
347
- if
348
- let window = shareableContent. windows. first ( where: { $0. isOnScreen && $0. owningApplication? . processID == NSWorkspace . shared. frontmostApplication? . processIdentifier } ) ,
349
- let cropped = ImageHelper . cropImage ( image: image, frame: window. frame, scale: scale)
350
- {
351
- self . performOCR ( frameId: frameId, on: cropped)
362
+ if settingsManager. settings. onlyOCRFrontmostWindow {
363
+ // User wants to perform OCR on only active window.
364
+
365
+ // We need to determine the scale factor for cropping. CGImage is
366
+ // measured in pixels, display sizes are measured in points.
367
+ let scale = max ( CGFloat ( image. width) / CGFloat( display. width) , CGFloat ( image. height) / CGFloat( display. height) )
368
+
369
+ if
370
+ let window = shareableContent. windows. first ( where: { $0. isOnScreen && $0. owningApplication? . processID == NSWorkspace . shared. frontmostApplication? . processIdentifier } ) ,
371
+ let cropped = ImageHelper . cropImage ( image: image, frame: window. frame, scale: scale)
372
+ {
373
+ self . performOCR ( frameId: frameId, on: cropped)
374
+ }
375
+ } else {
376
+ // default: User wants to perform OCR on full display.
377
+ self . performOCR ( frameId: frameId, on: image)
352
378
}
379
+
380
+ await processScreenshot ( frameId: frameId, imageData: imageData, frame: display. frame)
353
381
} else {
354
- // default: User wants to perform OCR on full display.
355
- self . performOCR ( frameId: frameId, on: image)
382
+ logger. info ( " Screen didn't change! Not processing frame. " )
356
383
}
357
-
358
- await processScreenshot ( frameId: frameId, image: image, frame: display. frame)
359
384
} catch {
360
385
logger. error ( " Error taking screenshot: \( error) " )
361
386
}
@@ -406,14 +431,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
406
431
// }
407
432
// }
408
433
409
- private func processScreenshot( frameId: Int64 , image: CGImage , frame: CGRect ) async {
410
- let bitmapRep = NSBitmapImageRep ( cgImage: image)
411
- guard let data = bitmapRep. representation ( using: . png, properties: [ : ] ) else { return }
412
-
434
+ private func processScreenshot( frameId: Int64 , imageData: Data , frame: CGRect ) async {
413
435
imageBufferQueue. async ( flags: . barrier) { [ weak self] in
414
436
guard let strongSelf = self else { return }
415
437
416
- strongSelf. imageDataBuffer. append ( data )
438
+ strongSelf. imageDataBuffer. append ( imageData )
417
439
418
440
// Quickly move the images to a temporary buffer if the threshold is reached
419
441
var tempBuffer : [ Data ] = [ ]
0 commit comments