node-mac-recorder 2.10.25 → 2.10.27
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 +76 -29
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
|
+
// Custom window that never becomes key
|
|
70
|
+
@interface NoFocusWindow : NSWindow
|
|
71
|
+
@end
|
|
72
|
+
|
|
69
73
|
// Window delegate to prevent focus
|
|
70
74
|
@interface OverlayWindowDelegate : NSObject <NSWindowDelegate>
|
|
71
75
|
@end
|
|
@@ -113,21 +117,14 @@ void updateScreenOverlays();
|
|
|
113
117
|
NSColor *strokeColor;
|
|
114
118
|
|
|
115
119
|
if (self.isToggled) {
|
|
116
|
-
// Locked state: slightly different opacity
|
|
120
|
+
// Locked state: slightly different opacity with darker purple stroke
|
|
117
121
|
fillColor = [NSColor colorWithRed:0.6 green:0.4 blue:0.9 alpha:0.5];
|
|
118
122
|
strokeColor = [NSColor colorWithRed:0.45 green:0.25 blue:0.75 alpha:0.9];
|
|
119
|
-
}
|
|
120
|
-
// Normal state: standard fill
|
|
121
|
-
fillColor = [NSColor colorWithRed:0.6 green:0.4 blue:0.9 alpha:0.4];
|
|
122
|
-
strokeColor = [NSColor whiteColor];
|
|
123
|
-
}
|
|
123
|
+
}
|
|
124
124
|
|
|
125
125
|
[fillColor setFill];
|
|
126
126
|
[highlightPath fill];
|
|
127
|
-
|
|
128
|
-
[strokeColor setStroke];
|
|
129
|
-
[highlightPath setLineWidth:1.0];
|
|
130
|
-
[highlightPath stroke];
|
|
127
|
+
|
|
131
128
|
}
|
|
132
129
|
|
|
133
130
|
- (void)updateAppearance {
|
|
@@ -218,11 +215,34 @@ void updateScreenOverlays();
|
|
|
218
215
|
- (void)mouseEntered:(NSEvent *)event {
|
|
219
216
|
self.isHovered = YES;
|
|
220
217
|
[[NSCursor pointingHandCursor] set];
|
|
218
|
+
|
|
219
|
+
// Brighten background on hover
|
|
220
|
+
if (self.layer.backgroundColor) {
|
|
221
|
+
CGFloat red, green, blue, alpha;
|
|
222
|
+
NSColor *currentColor = [NSColor colorWithCGColor:self.layer.backgroundColor];
|
|
223
|
+
[currentColor getRed:&red green:&green blue:&blue alpha:&alpha];
|
|
224
|
+
|
|
225
|
+
// Increase brightness by 20%
|
|
226
|
+
red = MIN(1.0, red * 1.2);
|
|
227
|
+
green = MIN(1.0, green * 1.2);
|
|
228
|
+
blue = MIN(1.0, blue * 1.2);
|
|
229
|
+
|
|
230
|
+
NSColor *brighterColor = [NSColor colorWithRed:red green:green blue:blue alpha:alpha];
|
|
231
|
+
self.layer.backgroundColor = [brighterColor CGColor];
|
|
232
|
+
}
|
|
221
233
|
}
|
|
222
234
|
|
|
223
235
|
- (void)mouseExited:(NSEvent *)event {
|
|
224
236
|
self.isHovered = NO;
|
|
225
237
|
[[NSCursor arrowCursor] set];
|
|
238
|
+
|
|
239
|
+
// Restore original background color
|
|
240
|
+
NSString *title = [self title];
|
|
241
|
+
if ([title isEqualToString:@"Start Record"]) {
|
|
242
|
+
self.layer.backgroundColor = [[NSColor colorWithRed:90.0/255.0 green:50.0/255.0 blue:250.0/255.0 alpha:1.0] CGColor];
|
|
243
|
+
} else if ([title isEqualToString:@"Cancel"]) {
|
|
244
|
+
self.layer.backgroundColor = [[NSColor colorWithRed:0.4 green:0.4 blue:0.45 alpha:1.0] CGColor];
|
|
245
|
+
}
|
|
226
246
|
}
|
|
227
247
|
|
|
228
248
|
- (void)animateScale:(CGFloat)scale duration:(NSTimeInterval)duration {
|
|
@@ -251,6 +271,22 @@ void updateScreenOverlays();
|
|
|
251
271
|
|
|
252
272
|
@end
|
|
253
273
|
|
|
274
|
+
@implementation NoFocusWindow
|
|
275
|
+
|
|
276
|
+
- (BOOL)canBecomeKeyWindow {
|
|
277
|
+
return NO; // Never accept key status
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
- (BOOL)canBecomeMainWindow {
|
|
281
|
+
return NO; // Never accept main status
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
- (BOOL)acceptsFirstResponder {
|
|
285
|
+
return NO; // Never accept first responder
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
@end
|
|
289
|
+
|
|
254
290
|
@implementation OverlayWindowDelegate
|
|
255
291
|
|
|
256
292
|
- (BOOL)windowShouldBecomeKey:(NSWindow *)window {
|
|
@@ -261,6 +297,14 @@ void updateScreenOverlays();
|
|
|
261
297
|
return NO; // Prevent window from becoming main
|
|
262
298
|
}
|
|
263
299
|
|
|
300
|
+
- (BOOL)canBecomeKeyWindow {
|
|
301
|
+
return NO; // Never can become key
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
- (BOOL)canBecomeMainWindow {
|
|
305
|
+
return NO; // Never can become main
|
|
306
|
+
}
|
|
307
|
+
|
|
264
308
|
@end
|
|
265
309
|
|
|
266
310
|
// Recording preview overlay view - full screen with cutout
|
|
@@ -276,7 +320,7 @@ void updateScreenOverlays();
|
|
|
276
320
|
self.wantsLayer = YES;
|
|
277
321
|
self.layer.backgroundColor = [[NSColor clearColor] CGColor];
|
|
278
322
|
// Ensure no borders or decorations
|
|
279
|
-
self.layer.borderWidth =
|
|
323
|
+
self.layer.borderWidth = 1.0;
|
|
280
324
|
self.layer.cornerRadius = 8.0;
|
|
281
325
|
self.layer.masksToBounds = YES;
|
|
282
326
|
self.layer.shadowOpacity = 0.0;
|
|
@@ -336,7 +380,7 @@ void updateScreenOverlays();
|
|
|
336
380
|
self.wantsLayer = YES;
|
|
337
381
|
self.layer.backgroundColor = [[NSColor clearColor] CGColor];
|
|
338
382
|
// Ensure no borders or decorations
|
|
339
|
-
self.layer.borderWidth =
|
|
383
|
+
self.layer.borderWidth = 1.0;
|
|
340
384
|
self.layer.cornerRadius = 8.0;
|
|
341
385
|
self.layer.masksToBounds = YES;
|
|
342
386
|
self.layer.shadowOpacity = 0.0;
|
|
@@ -811,7 +855,7 @@ void updateOverlay() {
|
|
|
811
855
|
|
|
812
856
|
// Force no borders on info label
|
|
813
857
|
[infoLabel setWantsLayer:YES];
|
|
814
|
-
infoLabel.layer.borderWidth =
|
|
858
|
+
infoLabel.layer.borderWidth = 1.0;
|
|
815
859
|
infoLabel.layer.borderColor = [[NSColor clearColor] CGColor];
|
|
816
860
|
infoLabel.layer.cornerRadius = 0.0;
|
|
817
861
|
infoLabel.layer.masksToBounds = YES;
|
|
@@ -837,7 +881,7 @@ void updateOverlay() {
|
|
|
837
881
|
[appIconView.layer setBackgroundColor:[[NSColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.3] CGColor]]; // Debug background
|
|
838
882
|
|
|
839
883
|
// Force no borders on app icon view
|
|
840
|
-
appIconView.layer.borderWidth =
|
|
884
|
+
appIconView.layer.borderWidth = 1.0;
|
|
841
885
|
appIconView.layer.borderColor = [[NSColor clearColor] CGColor];
|
|
842
886
|
appIconView.layer.shadowOpacity = 0.0;
|
|
843
887
|
appIconView.layer.shadowRadius = 0.0;
|
|
@@ -878,20 +922,19 @@ void updateOverlay() {
|
|
|
878
922
|
NSString *labelAppName = [windowUnderCursor objectForKey:@"appName"] ?: @"Unknown App";
|
|
879
923
|
[infoLabel setStringValue:[NSString stringWithFormat:@"%@\n%@", labelAppName, labelWindowTitle]];
|
|
880
924
|
|
|
881
|
-
// Position buttons - Start Record in center of
|
|
925
|
+
// Position buttons - Start Record in center of screen
|
|
882
926
|
if (g_selectButton) {
|
|
883
927
|
NSSize buttonSize = [g_selectButton frame].size;
|
|
884
|
-
|
|
885
|
-
NSRect highlightFrame = NSMakeRect(x, [g_overlayView frame].size.height - y - height, width, height);
|
|
928
|
+
NSRect screenFrame = [g_overlayView frame];
|
|
886
929
|
NSPoint buttonCenter = NSMakePoint(
|
|
887
|
-
|
|
888
|
-
|
|
930
|
+
(screenFrame.size.width - buttonSize.width) / 2,
|
|
931
|
+
(screenFrame.size.height - buttonSize.height) / 2 + 30 // Slightly above center
|
|
889
932
|
);
|
|
890
933
|
[g_selectButton setFrameOrigin:buttonCenter];
|
|
891
934
|
|
|
892
|
-
// Position app icon above text label
|
|
935
|
+
// Position app icon above text label in screen center
|
|
893
936
|
NSPoint iconCenter = NSMakePoint(
|
|
894
|
-
|
|
937
|
+
(screenFrame.size.width - 96) / 2, // Center horizontally on screen
|
|
895
938
|
buttonCenter.y + buttonSize.height + 60 + 10 // Above label + text height + margin
|
|
896
939
|
);
|
|
897
940
|
[appIconView setFrameOrigin:iconCenter];
|
|
@@ -912,9 +955,9 @@ void updateOverlay() {
|
|
|
912
955
|
floatAnimationX.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
|
|
913
956
|
[appIconView.layer addAnimation:floatAnimationX forKey:@"floatAnimationX"];
|
|
914
957
|
|
|
915
|
-
// Position info label
|
|
958
|
+
// Position info label in screen center, above button
|
|
916
959
|
NSPoint labelCenter = NSMakePoint(
|
|
917
|
-
|
|
960
|
+
(screenFrame.size.width - [infoLabel frame].size.width) / 2, // Center horizontally on screen
|
|
918
961
|
buttonCenter.y + buttonSize.height + 10 // 10px above button, below icon
|
|
919
962
|
);
|
|
920
963
|
[infoLabel setFrameOrigin:labelCenter];
|
|
@@ -932,7 +975,7 @@ void updateOverlay() {
|
|
|
932
975
|
if (cancelButton) {
|
|
933
976
|
NSSize cancelButtonSize = [cancelButton frame].size;
|
|
934
977
|
NSPoint cancelButtonCenter = NSMakePoint(
|
|
935
|
-
|
|
978
|
+
(screenFrame.size.width - cancelButtonSize.width) / 2, // Center horizontally on screen
|
|
936
979
|
buttonCenter.y - buttonSize.height - 20 // 20px below main button
|
|
937
980
|
);
|
|
938
981
|
[cancelButton setFrameOrigin:cancelButtonCenter];
|
|
@@ -951,7 +994,7 @@ void updateOverlay() {
|
|
|
951
994
|
if ([subview respondsToSelector:@selector(setWantsLayer:)]) {
|
|
952
995
|
[subview setWantsLayer:YES];
|
|
953
996
|
if (subview.layer) {
|
|
954
|
-
subview.layer.borderWidth =
|
|
997
|
+
subview.layer.borderWidth = 1.0;
|
|
955
998
|
subview.layer.borderColor = [[NSColor clearColor] CGColor];
|
|
956
999
|
subview.layer.masksToBounds = YES;
|
|
957
1000
|
subview.layer.shadowOpacity = 0.0;
|
|
@@ -1717,10 +1760,10 @@ Napi::Value StartWindowSelection(const Napi::CallbackInfo& info) {
|
|
|
1717
1760
|
// Create full-screen overlay window to prevent window dragging
|
|
1718
1761
|
NSScreen *mainScreen = [NSScreen mainScreen];
|
|
1719
1762
|
NSRect fullScreenFrame = [mainScreen frame];
|
|
1720
|
-
g_overlayWindow = [[
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1763
|
+
g_overlayWindow = [[NoFocusWindow alloc] initWithContentRect:fullScreenFrame
|
|
1764
|
+
styleMask:NSWindowStyleMaskBorderless
|
|
1765
|
+
backing:NSBackingStoreBuffered
|
|
1766
|
+
defer:NO];
|
|
1724
1767
|
|
|
1725
1768
|
// Force completely borderless appearance
|
|
1726
1769
|
[g_overlayWindow setStyleMask:NSWindowStyleMaskBorderless];
|
|
@@ -1774,6 +1817,10 @@ Napi::Value StartWindowSelection(const Napi::CallbackInfo& info) {
|
|
|
1774
1817
|
}
|
|
1775
1818
|
[g_overlayWindow setDelegate:windowDelegate];
|
|
1776
1819
|
|
|
1820
|
+
// Additional focus prevention - override window methods
|
|
1821
|
+
[g_overlayWindow setAcceptsMouseMovedEvents:YES];
|
|
1822
|
+
[g_overlayWindow setIgnoresMouseEvents:NO];
|
|
1823
|
+
|
|
1777
1824
|
// Create select button with purple theme and hover effects
|
|
1778
1825
|
g_selectButton = [[HoverButton alloc] initWithFrame:NSMakeRect(0, 0, 200, 60)];
|
|
1779
1826
|
[g_selectButton setTitle:@"Start Record"];
|