node-mac-recorder 2.7.2 → 2.7.4
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/window_selector.mm +93 -37
package/package.json
CHANGED
package/src/window_selector.mm
CHANGED
|
@@ -68,7 +68,7 @@ void updateScreenOverlays();
|
|
|
68
68
|
if (self) {
|
|
69
69
|
// Use layer for background instead of custom drawing
|
|
70
70
|
self.wantsLayer = YES;
|
|
71
|
-
self.isActiveWindow = NO; // Default to inactive (
|
|
71
|
+
self.isActiveWindow = NO; // Default to inactive (will be set by updateOverlay)
|
|
72
72
|
self.isSelectedWindow = NO; // Default to not selected
|
|
73
73
|
|
|
74
74
|
// Set initial appearance
|
|
@@ -81,19 +81,19 @@ void updateScreenOverlays();
|
|
|
81
81
|
|
|
82
82
|
- (void)updateAppearance {
|
|
83
83
|
if (self.isSelectedWindow) {
|
|
84
|
-
// Selected window: bright background with thick border
|
|
84
|
+
// Selected window: bright background with thick border (2-3px)
|
|
85
85
|
self.layer.backgroundColor = [[NSColor colorWithRed:0.6 green:0.4 blue:0.9 alpha:0.6] CGColor];
|
|
86
86
|
self.layer.borderColor = [[NSColor colorWithRed:0.6 green:0.4 blue:0.9 alpha:1.0] CGColor];
|
|
87
|
-
self.layer.borderWidth =
|
|
87
|
+
self.layer.borderWidth = 2.5; // Thick border for selected window
|
|
88
88
|
// Selected window appearance set
|
|
89
89
|
} else if (self.isActiveWindow) {
|
|
90
|
-
// Active window:
|
|
90
|
+
// Active window (highlighted): thin border (1px)
|
|
91
91
|
self.layer.backgroundColor = [[NSColor colorWithRed:0.6 green:0.4 blue:0.9 alpha:0.4] CGColor];
|
|
92
92
|
self.layer.borderColor = [[NSColor colorWithRed:0.6 green:0.4 blue:0.9 alpha:0.8] CGColor];
|
|
93
|
-
self.layer.borderWidth = 1.0; // Thin border for
|
|
93
|
+
self.layer.borderWidth = 1.0; // Thin border for highlighted window
|
|
94
94
|
// Active window appearance set
|
|
95
95
|
} else {
|
|
96
|
-
// Inactive window:
|
|
96
|
+
// Inactive window: no border
|
|
97
97
|
self.layer.backgroundColor = [[NSColor colorWithRed:0.4 green:0.2 blue:0.6 alpha:0.25] CGColor];
|
|
98
98
|
self.layer.borderColor = [[NSColor clearColor] CGColor];
|
|
99
99
|
self.layer.borderWidth = 0.0; // No border for inactive window
|
|
@@ -123,26 +123,57 @@ void updateScreenOverlays();
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
- (void)mouseDown:(NSEvent *)event {
|
|
126
|
-
// Handle mouse click to
|
|
126
|
+
// Handle mouse click to toggle window selection (ONLY selection, no recording start)
|
|
127
127
|
if (self.windowInfo) {
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (
|
|
133
|
-
|
|
128
|
+
// Check if this window is already selected
|
|
129
|
+
BOOL wasSelected = (g_selectedWindowInfo &&
|
|
130
|
+
[g_selectedWindowInfo isEqualToDictionary:self.windowInfo]);
|
|
131
|
+
|
|
132
|
+
if (wasSelected) {
|
|
133
|
+
// Deselect this window - return to normal highlight behavior
|
|
134
|
+
if (g_selectedOverlayView) {
|
|
135
|
+
g_selectedOverlayView.isSelectedWindow = NO;
|
|
136
|
+
[g_selectedOverlayView updateAppearance];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Clear global selection
|
|
140
|
+
if (g_selectedWindowInfo) {
|
|
141
|
+
[g_selectedWindowInfo release];
|
|
142
|
+
g_selectedWindowInfo = nil;
|
|
143
|
+
}
|
|
144
|
+
g_selectedOverlayView = nil;
|
|
145
|
+
|
|
146
|
+
NSLog(@"🚫 WINDOW DESELECTED - Back to normal highlight mode: %@ - \"%@\"",
|
|
147
|
+
[self.windowInfo objectForKey:@"appName"] ?: @"Unknown",
|
|
148
|
+
[self.windowInfo objectForKey:@"title"] ?: @"Untitled");
|
|
149
|
+
} else {
|
|
150
|
+
// Deselect previous window if any
|
|
151
|
+
if (g_selectedOverlayView && g_selectedOverlayView != self) {
|
|
152
|
+
g_selectedOverlayView.isSelectedWindow = NO;
|
|
153
|
+
[g_selectedOverlayView updateAppearance];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Select this window
|
|
157
|
+
self.isSelectedWindow = YES;
|
|
158
|
+
|
|
159
|
+
// Update global selected window info
|
|
160
|
+
if (g_selectedWindowInfo) {
|
|
161
|
+
[g_selectedWindowInfo release];
|
|
162
|
+
}
|
|
163
|
+
g_selectedWindowInfo = [self.windowInfo retain];
|
|
164
|
+
|
|
165
|
+
// Update global selected overlay reference
|
|
166
|
+
g_selectedOverlayView = self;
|
|
167
|
+
|
|
168
|
+
NSLog(@"🎯 WINDOW SELECTED - Highlight blocked on this window: %@ - \"%@\"",
|
|
169
|
+
[self.windowInfo objectForKey:@"appName"] ?: @"Unknown",
|
|
170
|
+
[self.windowInfo objectForKey:@"title"] ?: @"Untitled");
|
|
134
171
|
}
|
|
135
|
-
g_selectedWindowInfo = [self.windowInfo retain];
|
|
136
172
|
|
|
137
|
-
// Update
|
|
138
|
-
g_selectedOverlayView = self;
|
|
139
|
-
|
|
140
|
-
// Update overlay appearance
|
|
173
|
+
// Update appearance for this overlay
|
|
141
174
|
[self updateAppearance];
|
|
142
175
|
|
|
143
|
-
|
|
144
|
-
[self.windowInfo objectForKey:@"appName"] ?: @"Unknown",
|
|
145
|
-
[self.windowInfo objectForKey:@"title"] ?: @"Untitled");
|
|
176
|
+
// DON'T start recording here - that's only for the "Start Record" button
|
|
146
177
|
}
|
|
147
178
|
}
|
|
148
179
|
|
|
@@ -494,23 +525,33 @@ NSDictionary* getWindowUnderCursor(CGPoint point) {
|
|
|
494
525
|
}
|
|
495
526
|
}
|
|
496
527
|
|
|
497
|
-
// Update overlay to show
|
|
528
|
+
// Update overlay to show window under cursor with highlighting (but no auto-bring-to-front)
|
|
498
529
|
void updateOverlay() {
|
|
499
530
|
@autoreleasepool {
|
|
500
531
|
if (!g_isWindowSelecting || !g_overlayWindow) return;
|
|
501
532
|
|
|
502
|
-
//
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
533
|
+
// Get current cursor position for highlighting
|
|
534
|
+
NSPoint mouseLocation = [NSEvent mouseLocation];
|
|
535
|
+
NSScreen *mainScreen = [NSScreen mainScreen];
|
|
536
|
+
CGFloat screenHeight = [mainScreen frame].size.height;
|
|
537
|
+
CGPoint globalPoint = CGPointMake(mouseLocation.x, screenHeight - mouseLocation.y);
|
|
538
|
+
|
|
539
|
+
// Find window under cursor for highlighting
|
|
540
|
+
NSDictionary *windowUnderCursor = getWindowUnderCursor(globalPoint);
|
|
541
|
+
|
|
542
|
+
// Update current window under cursor for highlighting
|
|
543
|
+
if (windowUnderCursor && ![windowUnderCursor isEqualToDictionary:g_currentWindowUnderCursor]) {
|
|
544
|
+
[g_currentWindowUnderCursor release];
|
|
545
|
+
g_currentWindowUnderCursor = [windowUnderCursor retain];
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// If no window under cursor, show first available window
|
|
549
|
+
if (!windowUnderCursor) {
|
|
506
550
|
if (g_allWindows && [g_allWindows count] > 0) {
|
|
507
551
|
windowUnderCursor = [g_allWindows objectAtIndex:0];
|
|
508
552
|
} else {
|
|
509
553
|
return; // No windows available
|
|
510
554
|
}
|
|
511
|
-
} else {
|
|
512
|
-
// Use selected window info
|
|
513
|
-
windowUnderCursor = g_selectedWindowInfo;
|
|
514
555
|
}
|
|
515
556
|
|
|
516
557
|
// Update overlay position and size
|
|
@@ -545,8 +586,8 @@ void updateOverlay() {
|
|
|
545
586
|
|
|
546
587
|
// Convert coordinates from CGWindow (top-left) to NSWindow (bottom-left) for the specific screen
|
|
547
588
|
NSRect screenFrame = [windowScreen frame];
|
|
548
|
-
CGFloat
|
|
549
|
-
CGFloat adjustedY =
|
|
589
|
+
CGFloat windowScreenHeight = screenFrame.size.height;
|
|
590
|
+
CGFloat adjustedY = windowScreenHeight - y - height;
|
|
550
591
|
|
|
551
592
|
// Window coordinates are in global space, overlay frame should be screen-relative
|
|
552
593
|
// Keep X coordinate as-is (already in global space which is what we want)
|
|
@@ -754,18 +795,28 @@ void updateOverlay() {
|
|
|
754
795
|
[g_overlayWindow level], [g_overlayWindow alphaValue],
|
|
755
796
|
[g_overlayWindow isVisible] ? "YES" : "NO");
|
|
756
797
|
|
|
757
|
-
// Update overlay view states -
|
|
798
|
+
// Update overlay view states - highlight window under cursor and check selection
|
|
758
799
|
if (g_overlayView && [g_overlayView isKindOfClass:[WindowSelectorOverlayView class]]) {
|
|
759
800
|
WindowSelectorOverlayView *overlayView = (WindowSelectorOverlayView *)g_overlayView;
|
|
760
801
|
|
|
761
|
-
// Check if this is
|
|
762
|
-
BOOL
|
|
802
|
+
// Check if this window is under cursor (highlight)
|
|
803
|
+
BOOL isUnderCursor = (windowUnderCursor &&
|
|
804
|
+
[g_currentWindowUnderCursor isEqualToDictionary:windowUnderCursor]);
|
|
763
805
|
|
|
764
|
-
//
|
|
765
|
-
|
|
806
|
+
// Check if this is the selected window
|
|
807
|
+
BOOL isSelected = (g_selectedWindowInfo &&
|
|
808
|
+
[g_selectedWindowInfo isEqualToDictionary:windowUnderCursor]);
|
|
809
|
+
|
|
810
|
+
// If window is selected, don't allow highlighting on it
|
|
811
|
+
if (isSelected) {
|
|
812
|
+
overlayView.isActiveWindow = NO; // No highlight on selected window
|
|
813
|
+
} else {
|
|
814
|
+
overlayView.isActiveWindow = isUnderCursor; // Highlight if under cursor and not selected
|
|
815
|
+
}
|
|
766
816
|
overlayView.isSelectedWindow = isSelected;
|
|
767
817
|
|
|
768
|
-
NSLog(@"🎯 Overlay State Updated: Active
|
|
818
|
+
NSLog(@"🎯 Overlay State Updated: Active=%s, Selected=%s",
|
|
819
|
+
overlayView.isActiveWindow ? "YES" : "NO", isSelected ? "YES" : "NO");
|
|
769
820
|
}
|
|
770
821
|
}
|
|
771
822
|
}
|
|
@@ -1540,6 +1591,11 @@ Napi::Value StartWindowSelection(const Napi::CallbackInfo& info) {
|
|
|
1540
1591
|
[(WindowSelectorOverlayView *)g_overlayView setIsActiveWindow:NO];
|
|
1541
1592
|
[(WindowSelectorOverlayView *)g_overlayView setIsSelectedWindow:NO];
|
|
1542
1593
|
|
|
1594
|
+
// Set initial window under cursor for highlighting
|
|
1595
|
+
if (g_allWindows && [g_allWindows count] > 0) {
|
|
1596
|
+
g_currentWindowUnderCursor = [[g_allWindows objectAtIndex:0] retain];
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1543
1599
|
// Note: NSWindow doesn't have setWantsLayer method, only NSView does
|
|
1544
1600
|
|
|
1545
1601
|
// Force content view to have no borders
|