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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -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 (no mouse highlighting)
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 = 3.0; // Thick border for selected window
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: brighter background with thin border
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 active window
93
+ self.layer.borderWidth = 1.0; // Thin border for highlighted window
94
94
  // Active window appearance set
95
95
  } else {
96
- // Inactive window: dimmer background with no border
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 select this window
126
+ // Handle mouse click to toggle window selection (ONLY selection, no recording start)
127
127
  if (self.windowInfo) {
128
- // Set this overlay as selected
129
- self.isSelectedWindow = YES;
130
-
131
- // Update global selected window info
132
- if (g_selectedWindowInfo) {
133
- [g_selectedWindowInfo release];
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 global selected overlay reference
138
- g_selectedOverlayView = self;
139
-
140
- // Update overlay appearance
173
+ // Update appearance for this overlay
141
174
  [self updateAppearance];
142
175
 
143
- NSLog(@"🎯 WINDOW SELECTED VIA CLICK: %@ - \"%@\"",
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 selected window (no more mouse-based highlighting)
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
- // Check if we have a selected window or if we should show overlay for selection
503
- NSDictionary *windowUnderCursor = nil;
504
- if (!g_selectedWindowInfo) {
505
- // No window selected yet - show overlay for the first available window
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 screenHeight = screenFrame.size.height;
549
- CGFloat adjustedY = screenHeight - y - height;
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 - check if this window is selected
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 the selected window (true if we have selected window info)
762
- BOOL isSelected = (g_selectedWindowInfo != nil);
802
+ // Check if this window is under cursor (highlight)
803
+ BOOL isUnderCursor = (windowUnderCursor &&
804
+ [g_currentWindowUnderCursor isEqualToDictionary:windowUnderCursor]);
763
805
 
764
- // Update states
765
- overlayView.isActiveWindow = NO; // No more mouse-based highlighting
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=NO, Selected=%s", isSelected ? "YES" : "NO");
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