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 +1 -1
- package/src/cursor_tracker.mm +21 -0
- package/src/window_selector.mm +49 -29
package/package.json
CHANGED
package/src/cursor_tracker.mm
CHANGED
|
@@ -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;
|
package/src/window_selector.mm
CHANGED
|
@@ -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
|
-
//
|
|
969
|
-
|
|
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
|
|