node-mac-recorder 2.24.8 β†’ 2.24.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.24.8",
3
+ "version": "2.24.9",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -865,9 +865,30 @@ static bool g_leftMouseDown = false;
865
865
  static bool g_rightMouseDown = false;
866
866
  static NSString *g_lastEventType = @"move";
867
867
 
868
+ // Erisilebilirlik izni durumu (istem GOSTERMEDEN).
869
+ // NEDEN: izin yokken bile AX cagrilari yapiliyordu; macOS bunun uzerine
870
+ // "Erisilebilirlik" izin dialogunu aciyor ve bu fonksiyon kayit boyunca
871
+ // yuksek frekansta cagrildigi icin istem tekrar tekrar cikiyor. Durum
872
+ // saniyede bir tazelenir: kullanici izni verdigi anda yol kendiliginden
873
+ // devreye girer.
874
+ static bool accessibilityTrustedCached(void) {
875
+ static CFAbsoluteTime lastCheck = 0;
876
+ static bool trusted = false;
877
+ CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
878
+ if (lastCheck == 0 || now - lastCheck > 1.0) {
879
+ trusted = AXIsProcessTrusted();
880
+ lastCheck = now;
881
+ }
882
+ return trusted;
883
+ }
884
+
868
885
  // Accessibility tabanlΔ± cursor tip tespiti
869
886
  static NSString* detectCursorTypeUsingAccessibility(CGPoint cursorPos) {
870
887
  @autoreleasepool {
888
+ if (!accessibilityTrustedCached()) {
889
+ return nil;
890
+ }
891
+
871
892
  AXUIElementRef systemWide = AXUIElementCreateSystemWide();
872
893
  if (!systemWide) {
873
894
  return nil;
@@ -898,10 +898,57 @@ bool activateWindowOwnerApp(int windowId) {
898
898
  }
899
899
  }
900
900
 
901
+ // Hedef pencerenin sahibi uygulamayi ONE ALIR (Accessibility GEREKTIRMEZ).
902
+ // bringWindowToFront'un AX yolu izin isterken bu yol yalnizca
903
+ // NSRunningApplication kullanir; izin yokken tek calisan yol budur.
904
+ static bool activateOwnerAppForWindow(int windowId) {
905
+ @autoreleasepool {
906
+ // Method 2: Light activation fallback (minimal app activation)
907
+ NSLog(@" πŸ”„ Trying minimal activation for window %d", windowId);
908
+
909
+ // Get window info to find the process
910
+ CFArrayRef cgWindowList = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
911
+ if (cgWindowList) {
912
+ NSArray *windowArray = (__bridge NSArray *)cgWindowList;
913
+
914
+ for (NSDictionary *windowInfo in windowArray) {
915
+ NSNumber *cgWindowId = [windowInfo objectForKey:(NSString *)kCGWindowNumber];
916
+ if ([cgWindowId intValue] == windowId) {
917
+ // Get process ID
918
+ NSNumber *processId = [windowInfo objectForKey:(NSString *)kCGWindowOwnerPID];
919
+ if (processId) {
920
+ // Light activation - only bring app to front, don't activate all windows
921
+ NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:[processId intValue]];
922
+ if (app) {
923
+ // Use NSApplicationActivateIgnoringOtherApps only (no NSApplicationActivateAllWindows)
924
+ [app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
925
+ NSLog(@" βœ… App minimally activated: PID %d (specific window should be frontmost)", [processId intValue]);
926
+ CFRelease(cgWindowList);
927
+ return true;
928
+ }
929
+ }
930
+ break;
931
+ }
932
+ }
933
+ CFRelease(cgWindowList);
934
+ }
935
+ return false;
936
+ }
937
+ }
938
+
901
939
  // Bring window to front using Accessibility API
902
940
  bool bringWindowToFront(int windowId) {
903
941
  @autoreleasepool {
904
942
  @try {
943
+ // TCC istemi CIKMASIN: untrusted bir surecin systemWide element
944
+ // uzerindeki AX cagrilari macOS'a "Erisilebilirlik" dialogunu
945
+ // actiriyor β€” pencere kaydi HER baslatildiginda yeniden. Izin yoksa
946
+ // AX yolunu hic deneme; hafif aktivasyon zaten ayni isi goruyor.
947
+ // AXIsProcessTrusted() kendisi istem GOSTERMEZ.
948
+ if (!AXIsProcessTrusted()) {
949
+ return activateOwnerAppForWindow(windowId);
950
+ }
951
+
905
952
  // Method 1: Using Accessibility API (most reliable)
906
953
  AXUIElementRef systemWide = AXUIElementCreateSystemWide();
907
954
  if (!systemWide) return false;
@@ -965,35 +1012,8 @@ bool bringWindowToFront(int windowId) {
965
1012
 
966
1013
  CFRelease(systemWide);
967
1014
 
968
- // Method 2: Light activation fallback (minimal app activation)
969
- NSLog(@" πŸ”„ Trying minimal activation for window %d", windowId);
970
-
971
- // Get window info to find the process
972
- CFArrayRef cgWindowList = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
973
- if (cgWindowList) {
974
- NSArray *windowArray = (__bridge NSArray *)cgWindowList;
975
-
976
- for (NSDictionary *windowInfo in windowArray) {
977
- NSNumber *cgWindowId = [windowInfo objectForKey:(NSString *)kCGWindowNumber];
978
- if ([cgWindowId intValue] == windowId) {
979
- // Get process ID
980
- NSNumber *processId = [windowInfo objectForKey:(NSString *)kCGWindowOwnerPID];
981
- if (processId) {
982
- // Light activation - only bring app to front, don't activate all windows
983
- NSRunningApplication *app = [NSRunningApplication runningApplicationWithProcessIdentifier:[processId intValue]];
984
- if (app) {
985
- // Use NSApplicationActivateIgnoringOtherApps only (no NSApplicationActivateAllWindows)
986
- [app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
987
- NSLog(@" βœ… App minimally activated: PID %d (specific window should be frontmost)", [processId intValue]);
988
- CFRelease(cgWindowList);
989
- return true;
990
- }
991
- }
992
- break;
993
- }
994
- }
995
- CFRelease(cgWindowList);
996
- }
1015
+ // AX yolu pencereyi bulamadi β†’ izinsiz de calisan hafif aktivasyon.
1016
+ if (activateOwnerAppForWindow(windowId)) return true;
997
1017
 
998
1018
  return false;
999
1019