node-mac-recorder 2.10.19 → 2.10.21
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 +58 -6
package/package.json
CHANGED
package/src/window_selector.mm
CHANGED
|
@@ -66,6 +66,10 @@ void updateScreenOverlays();
|
|
|
66
66
|
- (void)setupHoverTracking;
|
|
67
67
|
@end
|
|
68
68
|
|
|
69
|
+
// Window delegate to prevent focus
|
|
70
|
+
@interface OverlayWindowDelegate : NSObject <NSWindowDelegate>
|
|
71
|
+
@end
|
|
72
|
+
|
|
69
73
|
@implementation WindowSelectorOverlayView
|
|
70
74
|
|
|
71
75
|
- (instancetype)initWithFrame:(NSRect)frameRect {
|
|
@@ -79,6 +83,9 @@ void updateScreenOverlays();
|
|
|
79
83
|
// Transparent background for full-screen overlay
|
|
80
84
|
self.layer.backgroundColor = [[NSColor clearColor] CGColor];
|
|
81
85
|
|
|
86
|
+
// Disable focus ring completely
|
|
87
|
+
[self setFocusRingType:NSFocusRingTypeNone];
|
|
88
|
+
|
|
82
89
|
// Window selector overlay view created
|
|
83
90
|
}
|
|
84
91
|
return self;
|
|
@@ -131,6 +138,14 @@ void updateScreenOverlays();
|
|
|
131
138
|
[self setNeedsDisplay:YES];
|
|
132
139
|
}
|
|
133
140
|
|
|
141
|
+
- (BOOL)acceptsFirstResponder {
|
|
142
|
+
return NO; // Never accept focus to prevent blue ring
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
- (BOOL)canBecomeKeyView {
|
|
146
|
+
return NO; // Never become key view
|
|
147
|
+
}
|
|
148
|
+
|
|
134
149
|
- (void)setIsActiveWindow:(BOOL)isActiveWindow {
|
|
135
150
|
if (_isActiveWindow != isActiveWindow) {
|
|
136
151
|
_isActiveWindow = isActiveWindow;
|
|
@@ -211,6 +226,9 @@ void updateScreenOverlays();
|
|
|
211
226
|
}
|
|
212
227
|
|
|
213
228
|
- (void)animateScale:(CGFloat)scale duration:(NSTimeInterval)duration {
|
|
229
|
+
// Set anchor point to center for center-based scaling
|
|
230
|
+
self.layer.anchorPoint = CGPointMake(0.5, 0.5);
|
|
231
|
+
|
|
214
232
|
[NSAnimationContext beginGrouping];
|
|
215
233
|
[NSAnimationContext currentContext].duration = duration;
|
|
216
234
|
[NSAnimationContext currentContext].timingFunction =
|
|
@@ -236,6 +254,18 @@ void updateScreenOverlays();
|
|
|
236
254
|
|
|
237
255
|
@end
|
|
238
256
|
|
|
257
|
+
@implementation OverlayWindowDelegate
|
|
258
|
+
|
|
259
|
+
- (BOOL)windowShouldBecomeKey:(NSWindow *)window {
|
|
260
|
+
return NO; // Prevent window from becoming key to avoid focus ring
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
- (BOOL)windowShouldBecomeMain:(NSWindow *)window {
|
|
264
|
+
return NO; // Prevent window from becoming main
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@end
|
|
268
|
+
|
|
239
269
|
// Recording preview overlay view - full screen with cutout
|
|
240
270
|
@interface RecordingPreviewView : NSView
|
|
241
271
|
@property (nonatomic, strong) NSDictionary *recordingWindowInfo;
|
|
@@ -1024,7 +1054,7 @@ bool showRecordingPreview(NSDictionary *windowInfo) {
|
|
|
1024
1054
|
[g_recordingPreviewWindow setAcceptsMouseMovedEvents:NO];
|
|
1025
1055
|
[g_recordingPreviewWindow setHasShadow:NO];
|
|
1026
1056
|
[g_recordingPreviewWindow setAlphaValue:1.0];
|
|
1027
|
-
[g_recordingPreviewWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces];
|
|
1057
|
+
[g_recordingPreviewWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorIgnoresCycle];
|
|
1028
1058
|
|
|
1029
1059
|
// Remove any default window decorations and borders
|
|
1030
1060
|
[g_recordingPreviewWindow setTitlebarAppearsTransparent:YES];
|
|
@@ -1201,6 +1231,11 @@ bool startScreenSelection() {
|
|
|
1201
1231
|
@try {
|
|
1202
1232
|
if (g_isScreenSelecting) return false;
|
|
1203
1233
|
|
|
1234
|
+
// Clean up any existing window selector first
|
|
1235
|
+
if (g_isWindowSelecting) {
|
|
1236
|
+
cleanupWindowSelector();
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1204
1239
|
// Get all available screens
|
|
1205
1240
|
NSArray *screens = [NSScreen screens];
|
|
1206
1241
|
if (!screens || [screens count] == 0) return false;
|
|
@@ -1293,7 +1328,7 @@ bool startScreenSelection() {
|
|
|
1293
1328
|
[overlayWindow setHasShadow:NO];
|
|
1294
1329
|
[overlayWindow setAlphaValue:1.0];
|
|
1295
1330
|
// Ensure window appears on all spaces and stays put - match g_overlayWindow
|
|
1296
|
-
[overlayWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces];
|
|
1331
|
+
[overlayWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorIgnoresCycle];
|
|
1297
1332
|
|
|
1298
1333
|
// Remove any default window decorations and borders
|
|
1299
1334
|
[overlayWindow setTitlebarAppearsTransparent:YES];
|
|
@@ -1593,7 +1628,7 @@ bool showScreenRecordingPreview(NSDictionary *screenInfo) {
|
|
|
1593
1628
|
// no border
|
|
1594
1629
|
[overlayWindow setStyleMask:NSWindowStyleMaskBorderless];
|
|
1595
1630
|
[overlayWindow setAlphaValue:1.0];
|
|
1596
|
-
[overlayWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces];
|
|
1631
|
+
[overlayWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorIgnoresCycle];
|
|
1597
1632
|
|
|
1598
1633
|
|
|
1599
1634
|
// Force content view to have no borders
|
|
@@ -1650,7 +1685,7 @@ Napi::Value StartWindowSelection(const Napi::CallbackInfo& info) {
|
|
|
1650
1685
|
}
|
|
1651
1686
|
|
|
1652
1687
|
@try {
|
|
1653
|
-
// Clean up any existing
|
|
1688
|
+
// Clean up any existing overlays first
|
|
1654
1689
|
if (g_overlayWindow) {
|
|
1655
1690
|
[g_overlayWindow close];
|
|
1656
1691
|
g_overlayWindow = nil;
|
|
@@ -1658,6 +1693,11 @@ Napi::Value StartWindowSelection(const Napi::CallbackInfo& info) {
|
|
|
1658
1693
|
g_selectButton = nil;
|
|
1659
1694
|
}
|
|
1660
1695
|
|
|
1696
|
+
// Also cleanup screen selector if running
|
|
1697
|
+
if (g_isScreenSelecting) {
|
|
1698
|
+
cleanupScreenSelector();
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1661
1701
|
// Get all windows
|
|
1662
1702
|
g_allWindows = [getAllSelectableWindows() retain];
|
|
1663
1703
|
|
|
@@ -1684,7 +1724,7 @@ Napi::Value StartWindowSelection(const Napi::CallbackInfo& info) {
|
|
|
1684
1724
|
[g_overlayWindow setAcceptsMouseMovedEvents:YES];
|
|
1685
1725
|
[g_overlayWindow setHasShadow:NO];
|
|
1686
1726
|
[g_overlayWindow setAlphaValue:1.0];
|
|
1687
|
-
[g_overlayWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorFullScreenAuxiliary];
|
|
1727
|
+
[g_overlayWindow setCollectionBehavior:NSWindowCollectionBehaviorStationary | NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorFullScreenAuxiliary | NSWindowCollectionBehaviorIgnoresCycle];
|
|
1688
1728
|
|
|
1689
1729
|
// Remove any default window decorations and borders
|
|
1690
1730
|
[g_overlayWindow setTitlebarAppearsTransparent:YES];
|
|
@@ -1703,17 +1743,29 @@ Napi::Value StartWindowSelection(const Napi::CallbackInfo& info) {
|
|
|
1703
1743
|
|
|
1704
1744
|
// Note: NSWindow doesn't have setWantsLayer method, only NSView does
|
|
1705
1745
|
|
|
1706
|
-
// Force content view to have no borders
|
|
1746
|
+
// Force content view to have no borders and no focus ring
|
|
1707
1747
|
g_overlayWindow.contentView.wantsLayer = YES;
|
|
1708
1748
|
g_overlayWindow.contentView.layer.borderWidth = 0.0;
|
|
1709
1749
|
g_overlayWindow.contentView.layer.borderColor = [[NSColor clearColor] CGColor];
|
|
1710
1750
|
g_overlayWindow.contentView.layer.cornerRadius = 0.0;
|
|
1711
1751
|
g_overlayWindow.contentView.layer.masksToBounds = YES;
|
|
1712
1752
|
|
|
1753
|
+
// Disable focus ring on overlay view
|
|
1754
|
+
if ([g_overlayView respondsToSelector:@selector(setFocusRingType:)]) {
|
|
1755
|
+
[(NSView*)g_overlayView setFocusRingType:NSFocusRingTypeNone];
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1713
1758
|
// Additional window styling to ensure no borders or decorations
|
|
1714
1759
|
[g_overlayWindow setMovable:NO];
|
|
1715
1760
|
[g_overlayWindow setMovableByWindowBackground:NO];
|
|
1716
1761
|
|
|
1762
|
+
// Set delegate to prevent focus
|
|
1763
|
+
static OverlayWindowDelegate *windowDelegate = nil;
|
|
1764
|
+
if (!windowDelegate) {
|
|
1765
|
+
windowDelegate = [[OverlayWindowDelegate alloc] init];
|
|
1766
|
+
}
|
|
1767
|
+
[g_overlayWindow setDelegate:windowDelegate];
|
|
1768
|
+
|
|
1717
1769
|
// Create select button with purple theme and hover effects
|
|
1718
1770
|
g_selectButton = [[HoverButton alloc] initWithFrame:NSMakeRect(0, 0, 200, 60)];
|
|
1719
1771
|
[g_selectButton setTitle:@"Start Record"];
|