node-mac-recorder 2.11.0 → 2.12.0
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/mac_recorder.mm +13 -4
- package/src/screen_capture_kit.mm +20 -3
- package/src/window_selector.mm +17 -0
package/package.json
CHANGED
package/src/mac_recorder.mm
CHANGED
|
@@ -183,12 +183,12 @@ Napi::Value StartRecording(const Napi::CallbackInfo& info) {
|
|
|
183
183
|
};
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
// Use ScreenCaptureKit
|
|
186
|
+
// Use ScreenCaptureKit with window exclusion
|
|
187
187
|
NSError *sckError = nil;
|
|
188
188
|
if ([ScreenCaptureKitRecorder startRecordingWithConfiguration:sckConfig
|
|
189
189
|
delegate:g_delegate
|
|
190
190
|
error:&sckError]) {
|
|
191
|
-
NSLog(@"✅ ScreenCaptureKit recording started with
|
|
191
|
+
NSLog(@"✅ ScreenCaptureKit recording started with window exclusion");
|
|
192
192
|
g_isRecording = true;
|
|
193
193
|
return Napi::Boolean::New(env, true);
|
|
194
194
|
} else {
|
|
@@ -374,8 +374,17 @@ Napi::Value StopRecording(const Napi::CallbackInfo& info) {
|
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
@try {
|
|
377
|
-
|
|
378
|
-
|
|
377
|
+
if (g_movieFileOutput) {
|
|
378
|
+
[g_movieFileOutput stopRecording];
|
|
379
|
+
}
|
|
380
|
+
if (g_captureSession) {
|
|
381
|
+
[g_captureSession stopRunning];
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Try to stop ScreenCaptureKit if it's being used
|
|
385
|
+
if (@available(macOS 12.3, *)) {
|
|
386
|
+
[ScreenCaptureKitRecorder stopRecording];
|
|
387
|
+
}
|
|
379
388
|
|
|
380
389
|
g_isRecording = false;
|
|
381
390
|
return Napi::Boolean::New(env, true);
|
|
@@ -59,19 +59,36 @@ static BOOL g_isRecording = NO;
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
// Get current app windows to exclude
|
|
62
|
+
// Get current process and Electron app windows to exclude
|
|
63
63
|
NSMutableArray *excludedWindows = [NSMutableArray array];
|
|
64
|
+
NSMutableArray *excludedApps = [NSMutableArray array];
|
|
65
|
+
|
|
66
|
+
// Exclude current Node.js process windows (overlay selectors)
|
|
64
67
|
for (SCWindow *window in content.windows) {
|
|
65
68
|
if (window.owningApplication.processID == currentPID) {
|
|
66
69
|
[excludedWindows addObject:window];
|
|
67
|
-
NSLog(@"🚫 Excluding overlay window: %@ (PID: %d)", window.title, currentPID);
|
|
70
|
+
NSLog(@"🚫 Excluding Node.js overlay window: %@ (PID: %d)", window.title, currentPID);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
//
|
|
74
|
+
// Also try to exclude Electron app if running (common overlay use case)
|
|
75
|
+
for (SCWindow *window in content.windows) {
|
|
76
|
+
NSString *appName = window.owningApplication.applicationName;
|
|
77
|
+
if ([appName containsString:@"Electron"] ||
|
|
78
|
+
[appName isEqualToString:@"electron"] ||
|
|
79
|
+
[window.title containsString:@"Electron"]) {
|
|
80
|
+
[excludedWindows addObject:window];
|
|
81
|
+
NSLog(@"🚫 Excluding Electron window: %@ from %@", window.title, appName);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
NSLog(@"📊 Total windows to exclude: %lu", (unsigned long)excludedWindows.count);
|
|
86
|
+
|
|
87
|
+
// Create content filter - exclude overlay windows from recording
|
|
72
88
|
SCContentFilter *filter = [[SCContentFilter alloc]
|
|
73
89
|
initWithDisplay:targetDisplay
|
|
74
90
|
excludingWindows:excludedWindows];
|
|
91
|
+
NSLog(@"🎯 Using window-level exclusion for overlay prevention");
|
|
75
92
|
|
|
76
93
|
// Create stream configuration
|
|
77
94
|
SCStreamConfiguration *streamConfig = [[SCStreamConfiguration alloc] init];
|
package/src/window_selector.mm
CHANGED
|
@@ -15,6 +15,23 @@ static NSButton *g_selectButton = nil;
|
|
|
15
15
|
static NSTimer *g_trackingTimer = nil;
|
|
16
16
|
static NSDictionary *g_selectedWindowInfo = nil;
|
|
17
17
|
static NSMutableArray *g_allWindows = nil;
|
|
18
|
+
|
|
19
|
+
// Functions to hide/show main overlay window during recording
|
|
20
|
+
void hideAllOverlayWindows() {
|
|
21
|
+
if (g_overlayWindow && [g_overlayWindow isVisible]) {
|
|
22
|
+
[g_overlayWindow setAlphaValue:0.0];
|
|
23
|
+
[g_overlayWindow orderOut:nil];
|
|
24
|
+
NSLog(@"🫥 Hidden main overlay window for recording");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
void showAllOverlayWindows() {
|
|
29
|
+
if (g_overlayWindow) {
|
|
30
|
+
[g_overlayWindow setAlphaValue:1.0];
|
|
31
|
+
[g_overlayWindow orderFront:nil];
|
|
32
|
+
NSLog(@"👁️ Restored main overlay window after recording");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
18
35
|
static NSDictionary *g_currentWindowUnderCursor = nil;
|
|
19
36
|
static bool g_bringToFrontEnabled = false; // Default disabled for overlay-only highlighting
|
|
20
37
|
static bool g_hasToggledWindow = false; // Track if any window is currently toggled
|