node-mac-recorder 2.22.9 → 2.22.11
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/index.js
CHANGED
|
@@ -1604,13 +1604,15 @@ class MacRecorder extends EventEmitter {
|
|
|
1604
1604
|
windowHeight: wh
|
|
1605
1605
|
};
|
|
1606
1606
|
|
|
1607
|
-
// If this is a click event, mark click location
|
|
1608
|
-
// Native eventType values: 'mousedown', 'mouseup', 'rightmousedown', 'rightmouseup'
|
|
1607
|
+
// If this is a click/drag event, mark click location
|
|
1608
|
+
// Native eventType values: 'mousedown', 'mouseup', 'drag', 'rightmousedown', 'rightmouseup', 'rightdrag'
|
|
1609
1609
|
const eventType = position.eventType || '';
|
|
1610
1610
|
if (eventType === 'mousedown' ||
|
|
1611
1611
|
eventType === 'mouseup' ||
|
|
1612
|
+
eventType === 'drag' ||
|
|
1612
1613
|
eventType === 'rightmousedown' ||
|
|
1613
|
-
eventType === 'rightmouseup'
|
|
1614
|
+
eventType === 'rightmouseup' ||
|
|
1615
|
+
eventType === 'rightdrag') {
|
|
1614
1616
|
location.click = windowInfo.windowId;
|
|
1615
1617
|
}
|
|
1616
1618
|
break; // Found the window, stop searching
|
package/package.json
CHANGED
package/src/cursor_tracker.mm
CHANGED
|
@@ -360,10 +360,10 @@ static void InitializeCursorFingerprintMap(void) {
|
|
|
360
360
|
AddCursorIfAvailable(@selector(dragLinkCursor), @"alias");
|
|
361
361
|
AddCursorIfAvailable(@selector(resizeLeftRightCursor), @"col-resize");
|
|
362
362
|
AddCursorIfAvailable(@selector(resizeUpDownCursor), @"row-resize");
|
|
363
|
-
AddCursorIfAvailableByName(@"resizeLeftCursor", @"
|
|
364
|
-
AddCursorIfAvailableByName(@"resizeRightCursor", @"
|
|
365
|
-
AddCursorIfAvailableByName(@"resizeUpCursor", @"
|
|
366
|
-
AddCursorIfAvailableByName(@"resizeDownCursor", @"
|
|
363
|
+
AddCursorIfAvailableByName(@"resizeLeftCursor", @"col-resize");
|
|
364
|
+
AddCursorIfAvailableByName(@"resizeRightCursor", @"col-resize");
|
|
365
|
+
AddCursorIfAvailableByName(@"resizeUpCursor", @"ns-resize");
|
|
366
|
+
AddCursorIfAvailableByName(@"resizeDownCursor", @"ns-resize");
|
|
367
367
|
AddCursorIfAvailableByName(@"resizeNorthWestSouthEastCursor", @"nwse-resize");
|
|
368
368
|
AddCursorIfAvailableByName(@"resizeNorthEastSouthWestCursor", @"nesw-resize");
|
|
369
369
|
AddCursorIfAvailable(@selector(zoomInCursor), @"zoom-in");
|
|
@@ -994,10 +994,10 @@ static NSString* cursorTypeFromCursorName(NSString *value) {
|
|
|
994
994
|
return @"nwse-resize";
|
|
995
995
|
}
|
|
996
996
|
if (horizontal) {
|
|
997
|
-
return @"
|
|
997
|
+
return @"col-resize"; // Desktop SVG var: col-resize
|
|
998
998
|
}
|
|
999
999
|
if (vertical) {
|
|
1000
|
-
return @"ns-resize"; //
|
|
1000
|
+
return @"ns-resize"; // Desktop SVG var: ns-resize
|
|
1001
1001
|
}
|
|
1002
1002
|
|
|
1003
1003
|
// If contains "resize" but no specific direction, return generic resize
|
|
@@ -1332,34 +1332,35 @@ static NSString* cursorTypeFromSeed(int seed) {
|
|
|
1332
1332
|
}
|
|
1333
1333
|
}
|
|
1334
1334
|
switch(seed) {
|
|
1335
|
-
|
|
1336
|
-
case
|
|
1337
|
-
case
|
|
1335
|
+
// Desktop'ta SVG karşılığı olan tiplere normalize edilmiş seed map
|
|
1336
|
+
case 741324: return @"default"; // auto → default
|
|
1337
|
+
case 741336: return @"default"; // none → default (gizli cursor kayıtta default gösterilir)
|
|
1338
|
+
case 741338: return @"default"; // context-menu → default (SVG yok)
|
|
1338
1339
|
case 741339: return @"pointer";
|
|
1339
1340
|
case 741341: return @"progress";
|
|
1340
|
-
case 741343: return @"
|
|
1341
|
-
case 741345: return @"
|
|
1341
|
+
case 741343: return @"progress"; // wait → progress
|
|
1342
|
+
case 741345: return @"crosshair"; // cell → crosshair (en yakın SVG)
|
|
1342
1343
|
case 741347: return @"crosshair";
|
|
1343
1344
|
case 741357: return @"text";
|
|
1344
|
-
case 741359: return @"vertical-text
|
|
1345
|
+
case 741359: return @"text"; // vertical-text → text
|
|
1345
1346
|
case 741361: return @"alias";
|
|
1346
1347
|
case 741362: return @"copy";
|
|
1347
|
-
case 741364: return @"
|
|
1348
|
-
case 741368: return @"no-drop
|
|
1348
|
+
case 741364: return @"all-scroll"; // move → all-scroll
|
|
1349
|
+
case 741368: return @"not-allowed"; // no-drop → not-allowed
|
|
1349
1350
|
case 741370: return @"not-allowed";
|
|
1350
1351
|
case 741381: return @"grab";
|
|
1351
1352
|
case 741385: return @"grabbing";
|
|
1352
1353
|
case 741389: return @"col-resize";
|
|
1353
1354
|
case 741393: return @"row-resize";
|
|
1354
|
-
case 741397: return @"
|
|
1355
|
-
case 741398: return @"
|
|
1356
|
-
case 741409: return @"
|
|
1357
|
-
case 741413: return @"
|
|
1358
|
-
case 741417: return @"
|
|
1359
|
-
case 741418: return @"
|
|
1360
|
-
case 741420: return @"
|
|
1361
|
-
case 741424: return @"
|
|
1362
|
-
case 741426: return @"
|
|
1355
|
+
case 741397: return @"ns-resize"; // n-resize → ns-resize
|
|
1356
|
+
case 741398: return @"col-resize"; // e-resize → col-resize
|
|
1357
|
+
case 741409: return @"ns-resize"; // s-resize → ns-resize
|
|
1358
|
+
case 741413: return @"col-resize"; // w-resize → col-resize
|
|
1359
|
+
case 741417: return @"nesw-resize"; // ne-resize → nesw-resize
|
|
1360
|
+
case 741418: return @"nwse-resize"; // nw-resize → nwse-resize
|
|
1361
|
+
case 741420: return @"nwse-resize"; // se-resize → nwse-resize
|
|
1362
|
+
case 741424: return @"nesw-resize"; // sw-resize → nesw-resize
|
|
1363
|
+
case 741426: return @"col-resize"; // ew-resize → col-resize
|
|
1363
1364
|
case 741436: return @"ns-resize";
|
|
1364
1365
|
case 741438: return @"nesw-resize";
|
|
1365
1366
|
case 741442: return @"nwse-resize";
|
|
@@ -1787,6 +1788,71 @@ static NSString* detectSystemCursorType(void) {
|
|
|
1787
1788
|
return cursorType;
|
|
1788
1789
|
}
|
|
1789
1790
|
|
|
1791
|
+
// Desktop'ta SVG karşılığı olmayan cursor tiplerini desteklenen tiplere normalize et
|
|
1792
|
+
static NSString* normalizeCursorTypeForDesktop(NSString *cursorType) {
|
|
1793
|
+
if (!cursorType || [cursorType length] == 0) {
|
|
1794
|
+
return @"default";
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
// Desteklenen tipler — desktop/public/cursor/default/ dizinindeki SVG'lere karşılık gelir
|
|
1798
|
+
static NSSet *supportedTypes = nil;
|
|
1799
|
+
static dispatch_once_t onceToken;
|
|
1800
|
+
dispatch_once(&onceToken, ^{
|
|
1801
|
+
supportedTypes = [[NSSet alloc] initWithArray:@[
|
|
1802
|
+
@"default", @"pointer", @"grabbing", @"text", @"grab",
|
|
1803
|
+
@"alias", @"copy", @"not-allowed", @"help", @"progress",
|
|
1804
|
+
@"crosshair", @"all-scroll", @"zoom-in", @"zoom-out",
|
|
1805
|
+
@"row-resize", @"col-resize", @"ns-resize",
|
|
1806
|
+
@"nwse-resize", @"nesw-resize"
|
|
1807
|
+
]];
|
|
1808
|
+
});
|
|
1809
|
+
|
|
1810
|
+
if ([supportedTypes containsObject:cursorType]) {
|
|
1811
|
+
return cursorType;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
// Normalize edilmemiş tipleri en yakın desteklenen tipe eşle
|
|
1815
|
+
if ([cursorType isEqualToString:@"auto"] || [cursorType isEqualToString:@"none"] ||
|
|
1816
|
+
[cursorType isEqualToString:@"context-menu"]) {
|
|
1817
|
+
return @"default";
|
|
1818
|
+
}
|
|
1819
|
+
if ([cursorType isEqualToString:@"wait"]) {
|
|
1820
|
+
return @"progress";
|
|
1821
|
+
}
|
|
1822
|
+
if ([cursorType isEqualToString:@"cell"]) {
|
|
1823
|
+
return @"crosshair";
|
|
1824
|
+
}
|
|
1825
|
+
if ([cursorType isEqualToString:@"vertical-text"]) {
|
|
1826
|
+
return @"text";
|
|
1827
|
+
}
|
|
1828
|
+
if ([cursorType isEqualToString:@"move"]) {
|
|
1829
|
+
return @"all-scroll";
|
|
1830
|
+
}
|
|
1831
|
+
if ([cursorType isEqualToString:@"no-drop"]) {
|
|
1832
|
+
return @"not-allowed";
|
|
1833
|
+
}
|
|
1834
|
+
// Yönlü resize → iki yönlü resize
|
|
1835
|
+
if ([cursorType isEqualToString:@"ew-resize"] ||
|
|
1836
|
+
[cursorType isEqualToString:@"e-resize"] ||
|
|
1837
|
+
[cursorType isEqualToString:@"w-resize"]) {
|
|
1838
|
+
return @"col-resize";
|
|
1839
|
+
}
|
|
1840
|
+
if ([cursorType isEqualToString:@"n-resize"] ||
|
|
1841
|
+
[cursorType isEqualToString:@"s-resize"]) {
|
|
1842
|
+
return @"ns-resize";
|
|
1843
|
+
}
|
|
1844
|
+
if ([cursorType isEqualToString:@"ne-resize"] ||
|
|
1845
|
+
[cursorType isEqualToString:@"sw-resize"]) {
|
|
1846
|
+
return @"nesw-resize";
|
|
1847
|
+
}
|
|
1848
|
+
if ([cursorType isEqualToString:@"nw-resize"] ||
|
|
1849
|
+
[cursorType isEqualToString:@"se-resize"]) {
|
|
1850
|
+
return @"nwse-resize";
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
return @"default";
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1790
1856
|
NSString* getCursorType() {
|
|
1791
1857
|
@autoreleasepool {
|
|
1792
1858
|
g_cursorTypeCounter++;
|
|
@@ -1823,7 +1889,10 @@ NSString* getCursorType() {
|
|
|
1823
1889
|
// Use cursorTypeFromNSCursor for detection (pointer equality + image-based)
|
|
1824
1890
|
// DO NOT use accessibility detection as it's unreliable and causes false positives
|
|
1825
1891
|
NSString *systemCursorType = detectSystemCursorType();
|
|
1826
|
-
NSString *
|
|
1892
|
+
NSString *rawType = systemCursorType && [systemCursorType length] > 0 ? systemCursorType : @"default";
|
|
1893
|
+
|
|
1894
|
+
// Desktop SVG'lerine uyumlu tipe normalize et
|
|
1895
|
+
NSString *finalType = normalizeCursorTypeForDesktop(rawType);
|
|
1827
1896
|
|
|
1828
1897
|
// Only log when cursor type changes
|
|
1829
1898
|
static NSString *lastLoggedType = nil;
|
|
@@ -1967,12 +2036,43 @@ void cursorTimerCallback() {
|
|
|
1967
2036
|
if (!cursorType) {
|
|
1968
2037
|
cursorType = @"default";
|
|
1969
2038
|
}
|
|
2039
|
+
|
|
2040
|
+
// Mouse button state polling — event tap olmadığında click/drag tespiti
|
|
2041
|
+
bool currentLeftMouseDown = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonLeft);
|
|
2042
|
+
bool currentRightMouseDown = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonRight);
|
|
2043
|
+
|
|
1970
2044
|
NSString *eventType = @"move";
|
|
1971
2045
|
|
|
2046
|
+
if (currentLeftMouseDown && !g_leftMouseDown) {
|
|
2047
|
+
eventType = @"mousedown";
|
|
2048
|
+
g_lastEventType = @"mousedown";
|
|
2049
|
+
} else if (!currentLeftMouseDown && g_leftMouseDown) {
|
|
2050
|
+
eventType = @"mouseup";
|
|
2051
|
+
g_lastEventType = @"mouseup";
|
|
2052
|
+
} else if (currentRightMouseDown && !g_rightMouseDown) {
|
|
2053
|
+
eventType = @"rightmousedown";
|
|
2054
|
+
g_lastEventType = @"rightmousedown";
|
|
2055
|
+
} else if (!currentRightMouseDown && g_rightMouseDown) {
|
|
2056
|
+
eventType = @"rightmouseup";
|
|
2057
|
+
g_lastEventType = @"rightmouseup";
|
|
2058
|
+
} else if (currentLeftMouseDown) {
|
|
2059
|
+
eventType = @"drag";
|
|
2060
|
+
g_lastEventType = @"drag";
|
|
2061
|
+
} else if (currentRightMouseDown) {
|
|
2062
|
+
eventType = @"rightdrag";
|
|
2063
|
+
g_lastEventType = @"rightdrag";
|
|
2064
|
+
} else {
|
|
2065
|
+
eventType = @"move";
|
|
2066
|
+
g_lastEventType = @"move";
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
g_leftMouseDown = currentLeftMouseDown;
|
|
2070
|
+
g_rightMouseDown = currentRightMouseDown;
|
|
2071
|
+
|
|
1972
2072
|
if (!ShouldEmitCursorEvent(location, cursorType, eventType)) {
|
|
1973
2073
|
return;
|
|
1974
2074
|
}
|
|
1975
|
-
|
|
2075
|
+
|
|
1976
2076
|
// Cursor data oluştur
|
|
1977
2077
|
NSDictionary *cursorInfo = @{
|
|
1978
2078
|
@"x": @((int)location.x),
|
|
@@ -1982,7 +2082,7 @@ void cursorTimerCallback() {
|
|
|
1982
2082
|
@"cursorType": cursorType,
|
|
1983
2083
|
@"type": eventType
|
|
1984
2084
|
};
|
|
1985
|
-
|
|
2085
|
+
|
|
1986
2086
|
// Direkt dosyaya yaz
|
|
1987
2087
|
writeToFile(cursorInfo);
|
|
1988
2088
|
RememberCursorEvent(location, cursorType, eventType);
|
|
@@ -2237,20 +2337,32 @@ Napi::Value GetCursorPosition(const Napi::CallbackInfo& info) {
|
|
|
2237
2337
|
bool currentRightMouseDown = CGEventSourceButtonState(kCGEventSourceStateHIDSystemState, kCGMouseButtonRight);
|
|
2238
2338
|
|
|
2239
2339
|
NSString *eventType = @"move";
|
|
2240
|
-
|
|
2340
|
+
|
|
2241
2341
|
// Mouse button state değişikliklerini tespit et
|
|
2242
2342
|
if (currentLeftMouseDown && !g_leftMouseDown) {
|
|
2343
|
+
// Sol tuş basıldı (geçiş: up → down)
|
|
2243
2344
|
eventType = @"mousedown";
|
|
2244
2345
|
g_lastEventType = @"mousedown";
|
|
2245
2346
|
} else if (!currentLeftMouseDown && g_leftMouseDown) {
|
|
2347
|
+
// Sol tuş bırakıldı (geçiş: down → up)
|
|
2246
2348
|
eventType = @"mouseup";
|
|
2247
2349
|
g_lastEventType = @"mouseup";
|
|
2248
2350
|
} else if (currentRightMouseDown && !g_rightMouseDown) {
|
|
2351
|
+
// Sağ tuş basıldı
|
|
2249
2352
|
eventType = @"rightmousedown";
|
|
2250
2353
|
g_lastEventType = @"rightmousedown";
|
|
2251
2354
|
} else if (!currentRightMouseDown && g_rightMouseDown) {
|
|
2355
|
+
// Sağ tuş bırakıldı
|
|
2252
2356
|
eventType = @"rightmouseup";
|
|
2253
2357
|
g_lastEventType = @"rightmouseup";
|
|
2358
|
+
} else if (currentLeftMouseDown) {
|
|
2359
|
+
// Sol tuş basılı tutuluyor — sürükleme
|
|
2360
|
+
eventType = @"drag";
|
|
2361
|
+
g_lastEventType = @"drag";
|
|
2362
|
+
} else if (currentRightMouseDown) {
|
|
2363
|
+
// Sağ tuş basılı tutuluyor
|
|
2364
|
+
eventType = @"rightdrag";
|
|
2365
|
+
g_lastEventType = @"rightdrag";
|
|
2254
2366
|
} else {
|
|
2255
2367
|
eventType = @"move";
|
|
2256
2368
|
g_lastEventType = @"move";
|
|
@@ -50,6 +50,30 @@ static void initializeSafeQueue() {
|
|
|
50
50
|
initializeSafeQueue();
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
+ (BOOL)shouldAllowElectronWindows {
|
|
54
|
+
NSString *flag = [[[NSProcessInfo processInfo] environment] objectForKey:@"CREAVIT_ALLOW_ELECTRON_WINDOWS"];
|
|
55
|
+
if (!flag) return NO;
|
|
56
|
+
|
|
57
|
+
NSString *normalized = [[flag lowercaseString] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
58
|
+
return [normalized isEqualToString:@"1"] ||
|
|
59
|
+
[normalized isEqualToString:@"true"] ||
|
|
60
|
+
[normalized isEqualToString:@"yes"] ||
|
|
61
|
+
[normalized isEqualToString:@"on"];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
+ (BOOL)shouldSkipWindowOwner:(NSString *)appName {
|
|
65
|
+
if (!appName || appName.length == 0) return YES;
|
|
66
|
+
if ([appName containsString:@"WindowServer"] || [appName containsString:@"Dock"]) return YES;
|
|
67
|
+
|
|
68
|
+
if (![self shouldAllowElectronWindows]) {
|
|
69
|
+
if ([appName containsString:@"Electron"] || [appName containsString:@"node"]) {
|
|
70
|
+
return YES;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return NO;
|
|
75
|
+
}
|
|
76
|
+
|
|
53
77
|
+ (BOOL)startRecordingWithPath:(NSString *)outputPath options:(NSDictionary *)options {
|
|
54
78
|
if (@available(macOS 12.3, *)) {
|
|
55
79
|
return [self startRecordingModern:outputPath options:options];
|
|
@@ -432,8 +456,7 @@ static void initializeSafeQueue() {
|
|
|
432
456
|
|
|
433
457
|
NSString *appName = window.owningApplication.applicationName ?: @"Unknown";
|
|
434
458
|
|
|
435
|
-
|
|
436
|
-
if ([appName containsString:@"Electron"] || [appName containsString:@"node"]) continue;
|
|
459
|
+
if ([self shouldSkipWindowOwner:appName]) continue;
|
|
437
460
|
|
|
438
461
|
NSDictionary *windowInfo = @{
|
|
439
462
|
@"id": @(window.windowID),
|
|
@@ -12,6 +12,30 @@ static void initializeWindowQueue() {
|
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
static BOOL ShouldAllowElectronWindows(void) {
|
|
16
|
+
NSString *flag = [[[NSProcessInfo processInfo] environment] objectForKey:@"CREAVIT_ALLOW_ELECTRON_WINDOWS"];
|
|
17
|
+
if (!flag) return NO;
|
|
18
|
+
|
|
19
|
+
NSString *normalized = [[flag lowercaseString] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
20
|
+
return [normalized isEqualToString:@"1"] ||
|
|
21
|
+
[normalized isEqualToString:@"true"] ||
|
|
22
|
+
[normalized isEqualToString:@"yes"] ||
|
|
23
|
+
[normalized isEqualToString:@"on"];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static BOOL ShouldSkipWindowOwner(NSString *appName) {
|
|
27
|
+
if (!appName || appName.length == 0) return YES;
|
|
28
|
+
if ([appName containsString:@"WindowServer"] || [appName containsString:@"Dock"]) return YES;
|
|
29
|
+
|
|
30
|
+
if (!ShouldAllowElectronWindows()) {
|
|
31
|
+
if ([appName containsString:@"Electron"] || [appName containsString:@"node"]) {
|
|
32
|
+
return YES;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return NO;
|
|
37
|
+
}
|
|
38
|
+
|
|
15
39
|
// NAPI Function: Get Windows (Electron-safe)
|
|
16
40
|
Napi::Value GetWindowsElectronSafe(const Napi::CallbackInfo& info) {
|
|
17
41
|
Napi::Env env = info.Env();
|
|
@@ -38,11 +62,7 @@ Napi::Value GetWindowsElectronSafe(const Napi::CallbackInfo& info) {
|
|
|
38
62
|
|
|
39
63
|
NSString *appName = window.owningApplication.applicationName ?: @"Unknown";
|
|
40
64
|
|
|
41
|
-
|
|
42
|
-
if ([appName containsString:@"Electron"] ||
|
|
43
|
-
[appName containsString:@"node"] ||
|
|
44
|
-
[appName containsString:@"WindowServer"] ||
|
|
45
|
-
[appName containsString:@"Dock"]) continue;
|
|
65
|
+
if (ShouldSkipWindowOwner(appName)) continue;
|
|
46
66
|
|
|
47
67
|
NSDictionary *windowInfo = @{
|
|
48
68
|
@"id": @(window.windowID),
|
|
@@ -94,11 +114,7 @@ Napi::Value GetWindowsElectronSafe(const Napi::CallbackInfo& info) {
|
|
|
94
114
|
NSString *appName = (__bridge NSString*)ownerName;
|
|
95
115
|
NSString *windowTitle = windowName ? (__bridge NSString*)windowName : @"";
|
|
96
116
|
|
|
97
|
-
|
|
98
|
-
if ([appName containsString:@"Electron"] ||
|
|
99
|
-
[appName containsString:@"node"] ||
|
|
100
|
-
[appName containsString:@"WindowServer"] ||
|
|
101
|
-
[appName containsString:@"Dock"]) continue;
|
|
117
|
+
if (ShouldSkipWindowOwner(appName)) continue;
|
|
102
118
|
|
|
103
119
|
// Get window bounds
|
|
104
120
|
CGRect bounds = CGRectZero;
|
package/src/window_selector.mm
CHANGED
|
@@ -56,6 +56,31 @@ static id g_screenKeyEventMonitor = nil;
|
|
|
56
56
|
static NSTimer *g_screenTrackingTimer = nil;
|
|
57
57
|
static NSInteger g_currentActiveScreenIndex = -1;
|
|
58
58
|
|
|
59
|
+
static bool shouldAllowElectronWindows() {
|
|
60
|
+
NSString *flag = [[[NSProcessInfo processInfo] environment] objectForKey:@"CREAVIT_ALLOW_ELECTRON_WINDOWS"];
|
|
61
|
+
if (!flag) return false;
|
|
62
|
+
|
|
63
|
+
NSString *normalized = [[flag lowercaseString] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
64
|
+
return [normalized isEqualToString:@"1"] ||
|
|
65
|
+
[normalized isEqualToString:@"true"] ||
|
|
66
|
+
[normalized isEqualToString:@"yes"] ||
|
|
67
|
+
[normalized isEqualToString:@"on"];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static bool shouldSkipSelectableWindowOwner(NSString *windowOwner) {
|
|
71
|
+
if (!windowOwner || [windowOwner length] == 0) return true;
|
|
72
|
+
if ([windowOwner isEqualToString:@"WindowServer"]) return true;
|
|
73
|
+
if ([windowOwner isEqualToString:@"Dock"]) return true;
|
|
74
|
+
|
|
75
|
+
if (!shouldAllowElectronWindows()) {
|
|
76
|
+
if ([windowOwner containsString:@"Electron"] || [windowOwner containsString:@"node"]) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
59
84
|
// Record icon helpers
|
|
60
85
|
static NSImage *CreateRecordIconImage(CGFloat size) {
|
|
61
86
|
const CGFloat leadingInset = 24.0;
|
|
@@ -757,12 +782,7 @@ NSArray* getAllSelectableWindows() {
|
|
|
757
782
|
|
|
758
783
|
// Skip system windows, dock, menu bar, etc.
|
|
759
784
|
if ([windowLayer intValue] != 0) continue; // Only normal windows
|
|
760
|
-
if (
|
|
761
|
-
if ([windowOwner isEqualToString:@"WindowServer"]) continue;
|
|
762
|
-
if ([windowOwner isEqualToString:@"Dock"]) continue;
|
|
763
|
-
|
|
764
|
-
// Skip Electron windows (our own overlay)
|
|
765
|
-
if ([windowOwner containsString:@"Electron"] || [windowOwner containsString:@"node"]) continue;
|
|
785
|
+
if (shouldSkipSelectableWindowOwner(windowOwner)) continue;
|
|
766
786
|
|
|
767
787
|
// Extract bounds
|
|
768
788
|
int x = [[bounds objectForKey:@"X"] intValue];
|
|
@@ -802,8 +822,7 @@ NSDictionary* getWindowUnderCursor(CGPoint point) {
|
|
|
802
822
|
for (NSDictionary *window in g_allWindows) {
|
|
803
823
|
NSString *appName = [window objectForKey:@"appName"];
|
|
804
824
|
|
|
805
|
-
|
|
806
|
-
if (appName && ([appName containsString:@"Electron"] || [appName containsString:@"node"])) {
|
|
825
|
+
if (shouldSkipSelectableWindowOwner(appName)) {
|
|
807
826
|
continue;
|
|
808
827
|
}
|
|
809
828
|
|