node-mac-recorder 2.20.10 → 2.20.12
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/.claude/settings.local.json +2 -1
- package/index.js +6 -6
- package/package.json +1 -1
- package/src/cursor_tracker.mm +86 -119
- package/src/mac_recorder.mm +8 -8
package/index.js
CHANGED
|
@@ -217,7 +217,7 @@ class MacRecorder extends EventEmitter {
|
|
|
217
217
|
adjustedX = targetWindow.x - display.x;
|
|
218
218
|
adjustedY = targetWindow.y - display.y;
|
|
219
219
|
|
|
220
|
-
console.log(`🔧 macOS 14/13 coordinate fix: Global (${targetWindow.x},${targetWindow.y}) -> Display-relative (${adjustedX},${adjustedY})`);
|
|
220
|
+
// console.log(`🔧 macOS 14/13 coordinate fix: Global (${targetWindow.x},${targetWindow.y}) -> Display-relative (${adjustedX},${adjustedY})`);
|
|
221
221
|
break;
|
|
222
222
|
}
|
|
223
223
|
}
|
|
@@ -271,9 +271,9 @@ class MacRecorder extends EventEmitter {
|
|
|
271
271
|
height: targetWindow.height,
|
|
272
272
|
};
|
|
273
273
|
|
|
274
|
-
console.log(
|
|
275
|
-
|
|
276
|
-
);
|
|
274
|
+
// console.log(
|
|
275
|
+
// `Window ${targetWindow.appName}: display=${targetDisplayId}, coords=${targetWindow.x},${targetWindow.y} -> ${adjustedX},${adjustedY}`
|
|
276
|
+
// );
|
|
277
277
|
}
|
|
278
278
|
} catch (error) {
|
|
279
279
|
console.warn(
|
|
@@ -357,7 +357,7 @@ class MacRecorder extends EventEmitter {
|
|
|
357
357
|
recordingOptions
|
|
358
358
|
);
|
|
359
359
|
} catch (error) {
|
|
360
|
-
console.log('Native recording failed, trying alternative method');
|
|
360
|
+
// console.log('Native recording failed, trying alternative method');
|
|
361
361
|
success = false;
|
|
362
362
|
}
|
|
363
363
|
|
|
@@ -466,7 +466,7 @@ class MacRecorder extends EventEmitter {
|
|
|
466
466
|
try {
|
|
467
467
|
success = nativeBinding.stopRecording();
|
|
468
468
|
} catch (nativeError) {
|
|
469
|
-
console.log('Native stop failed:', nativeError.message);
|
|
469
|
+
// console.log('Native stop failed:', nativeError.message);
|
|
470
470
|
success = true; // Assume success to avoid throwing
|
|
471
471
|
}
|
|
472
472
|
|
package/package.json
CHANGED
package/src/cursor_tracker.mm
CHANGED
|
@@ -525,7 +525,7 @@ static NSString* cursorTypeFromNSCursor(NSCursor *cursor) {
|
|
|
525
525
|
return @"default";
|
|
526
526
|
}
|
|
527
527
|
|
|
528
|
-
// Standard macOS
|
|
528
|
+
// PRIORITY: Standard macOS cursor pointer equality (most reliable)
|
|
529
529
|
if (cursor == [NSCursor arrowCursor]) {
|
|
530
530
|
return @"default";
|
|
531
531
|
}
|
|
@@ -602,23 +602,28 @@ static NSString* cursorTypeFromNSCursor(NSCursor *cursor) {
|
|
|
602
602
|
NSString *className = NSStringFromClass([cursor class]);
|
|
603
603
|
NSString *description = [cursor description];
|
|
604
604
|
|
|
605
|
-
|
|
605
|
+
// Debug: Check for pointer cursor patterns
|
|
606
|
+
if (className && ([className containsString:@"pointing"] || [className containsString:@"Hand"])) {
|
|
607
|
+
NSLog(@"🔍 POINTER CLASS: %@", className);
|
|
608
|
+
return @"pointer";
|
|
609
|
+
}
|
|
610
|
+
if (description && ([description containsString:@"pointing"] || [description containsString:@"hand"])) {
|
|
611
|
+
NSLog(@"🔍 POINTER DESC: %@", description);
|
|
612
|
+
return @"pointer";
|
|
613
|
+
}
|
|
606
614
|
|
|
607
615
|
// Try name-based detection
|
|
608
616
|
NSString *derived = cursorTypeFromCursorName(className);
|
|
609
617
|
if (derived) {
|
|
610
|
-
MRLog(@"🎯 Cursor type from class name: %@", derived);
|
|
611
618
|
return derived;
|
|
612
619
|
}
|
|
613
620
|
|
|
614
621
|
derived = cursorTypeFromCursorName(description);
|
|
615
622
|
if (derived) {
|
|
616
|
-
MRLog(@"🎯 Cursor type from description: %@", derived);
|
|
617
623
|
return derived;
|
|
618
624
|
}
|
|
619
625
|
|
|
620
626
|
// Default fallback
|
|
621
|
-
MRLog(@"⚠️ Unknown cursor type, defaulting to 'default'");
|
|
622
627
|
return @"default";
|
|
623
628
|
}
|
|
624
629
|
|
|
@@ -631,61 +636,68 @@ static NSString* detectSystemCursorType(void) {
|
|
|
631
636
|
// Try different methods to get current cursor
|
|
632
637
|
if ([NSCursor respondsToSelector:@selector(currentSystemCursor)]) {
|
|
633
638
|
currentCursor = [NSCursor currentSystemCursor];
|
|
634
|
-
NSLog(@"🖱️ currentSystemCursor: %@", currentCursor ?: @"nil");
|
|
635
639
|
}
|
|
636
640
|
|
|
637
641
|
if (!currentCursor) {
|
|
638
642
|
currentCursor = [NSCursor currentCursor];
|
|
639
|
-
NSLog(@"🖱️ currentCursor: %@", currentCursor ?: @"nil");
|
|
640
643
|
}
|
|
641
644
|
|
|
642
645
|
if (currentCursor) {
|
|
643
646
|
NSString *className = NSStringFromClass([currentCursor class]);
|
|
644
647
|
NSString *description = [currentCursor description];
|
|
645
|
-
NSLog(@"🖱️ Cursor class: %@, description: %@", className ?: @"nil", description ?: @"nil");
|
|
646
|
-
|
|
647
648
|
// Use more direct cursor detection approach
|
|
648
649
|
NSImage *cursorImage = [currentCursor image];
|
|
649
650
|
NSPoint hotspot = [currentCursor hotSpot];
|
|
650
651
|
NSSize imageSize = [cursorImage size];
|
|
651
652
|
|
|
652
|
-
|
|
653
|
-
|
|
653
|
+
// ROBUST cursor detection - works with any cursor size
|
|
654
|
+
CGFloat aspectRatio = imageSize.width / imageSize.height;
|
|
655
|
+
CGFloat relativeHotspotX = hotspot.x / imageSize.width;
|
|
656
|
+
CGFloat relativeHotspotY = hotspot.y / imageSize.height;
|
|
657
|
+
|
|
654
658
|
|
|
655
|
-
//
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
659
|
+
// UPDATED with real cursor data:
|
|
660
|
+
// Arrow: 17x23 ratio=0.74 hotspot=(0.24,0.17)
|
|
661
|
+
// Text: 9x18 ratio=0.50 hotspot=(0.44,0.50)
|
|
662
|
+
// Pointer: 32x32 ratio=1.00 hotspot=(0.41,0.25)
|
|
663
|
+
|
|
664
|
+
// 1. TEXT/I-BEAM CURSOR - narrow ratio, center hotspot
|
|
665
|
+
if (aspectRatio >= 0.45 && aspectRatio <= 0.60 && // Narrow (0.50 typical)
|
|
666
|
+
relativeHotspotX >= 0.35 && relativeHotspotX <= 0.55 && // Center X (0.44 typical)
|
|
667
|
+
relativeHotspotY >= 0.40 && relativeHotspotY <= 0.60) { // Center Y (0.50 typical)
|
|
660
668
|
cursorType = @"text";
|
|
661
|
-
NSLog(@"🎯 DETECTED IBEAM CURSOR -> text");
|
|
662
669
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
670
|
+
// 2. ARROW CURSOR - medium ratio, top-left hotspot
|
|
671
|
+
else if (aspectRatio >= 0.65 && aspectRatio <= 0.85 && // Medium (0.74 typical)
|
|
672
|
+
relativeHotspotX >= 0.15 && relativeHotspotX <= 0.35 && // Left side (0.24 typical)
|
|
673
|
+
relativeHotspotY >= 0.10 && relativeHotspotY <= 0.25) { // Top area (0.17 typical)
|
|
666
674
|
cursorType = @"default";
|
|
667
|
-
NSLog(@"🎯 DETECTED ARROW CURSOR -> default");
|
|
668
675
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
676
|
+
// 3. POINTER CURSOR - square ratio, left-center hotspot
|
|
677
|
+
else if (aspectRatio >= 0.90 && aspectRatio <= 1.10 && // Square (1.00 typical)
|
|
678
|
+
relativeHotspotX >= 0.30 && relativeHotspotX <= 0.50 && // Left-center (0.41 typical)
|
|
679
|
+
relativeHotspotY >= 0.15 && relativeHotspotY <= 0.35) { // Upper area (0.25 typical)
|
|
673
680
|
cursorType = @"pointer";
|
|
674
|
-
|
|
681
|
+
}
|
|
682
|
+
// 4. GRAB CURSOR - square, center hotspot
|
|
683
|
+
else if (aspectRatio >= 0.90 && aspectRatio <= 1.10 && // Square
|
|
684
|
+
relativeHotspotX >= 0.40 && relativeHotspotX <= 0.60 && // Center X
|
|
685
|
+
relativeHotspotY >= 0.40 && relativeHotspotY <= 0.60) { // Center Y
|
|
686
|
+
cursorType = @"grab";
|
|
675
687
|
}
|
|
676
688
|
else {
|
|
677
689
|
// Try to use a different approach - cursor name introspection
|
|
678
690
|
NSString *derived = cursorTypeFromNSCursor(currentCursor);
|
|
679
691
|
if (derived && ![derived isEqualToString:@"default"]) {
|
|
680
692
|
cursorType = derived;
|
|
681
|
-
NSLog(@"🎯 DERIVED FROM ANALYSIS: %@", cursorType);
|
|
693
|
+
// NSLog(@"🎯 DERIVED FROM ANALYSIS: %@", cursorType);
|
|
682
694
|
} else {
|
|
683
695
|
cursorType = @"default";
|
|
684
|
-
NSLog(@"🎯 FALLBACK TO DEFAULT (will check AX)");
|
|
696
|
+
// NSLog(@"🎯 FALLBACK TO DEFAULT (will check AX)");
|
|
685
697
|
}
|
|
686
698
|
}
|
|
687
699
|
} else {
|
|
688
|
-
NSLog(@"🖱️ No current cursor found");
|
|
700
|
+
// NSLog(@"🖱️ No current cursor found");
|
|
689
701
|
cursorType = @"default";
|
|
690
702
|
}
|
|
691
703
|
};
|
|
@@ -738,35 +750,33 @@ NSString* getCursorType() {
|
|
|
738
750
|
|
|
739
751
|
NSString *finalType = @"default";
|
|
740
752
|
|
|
741
|
-
//
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
NSLog(@"🎯 Using AX cursor (specific over default): %@", finalType);
|
|
754
|
-
}
|
|
755
|
-
// Otherwise use system cursor (including default)
|
|
756
|
-
else if (systemCursorType && [systemCursorType length] > 0) {
|
|
757
|
-
finalType = systemCursorType;
|
|
758
|
-
NSLog(@"🎯 Using SYSTEM cursor: %@", finalType);
|
|
753
|
+
// SYSTEM CURSOR FIRST - more reliable for visual state
|
|
754
|
+
// Always trust system cursor first, only use AX for very specific cases
|
|
755
|
+
if (systemCursorType && [systemCursorType length] > 0) {
|
|
756
|
+
// Only override system cursor with AX if system is "default" AND AX gives us text/resize
|
|
757
|
+
if ([systemCursorType isEqualToString:@"default"] && axCursorType &&
|
|
758
|
+
([axCursorType isEqualToString:@"text"] ||
|
|
759
|
+
[axCursorType containsString:@"resize"] ||
|
|
760
|
+
[axCursorType isEqualToString:@"crosshair"])) {
|
|
761
|
+
finalType = axCursorType;
|
|
762
|
+
} else {
|
|
763
|
+
finalType = systemCursorType;
|
|
764
|
+
}
|
|
759
765
|
}
|
|
760
|
-
//
|
|
766
|
+
// Only if system completely fails, use AX
|
|
761
767
|
else if (axCursorType && [axCursorType length] > 0) {
|
|
762
768
|
finalType = axCursorType;
|
|
763
|
-
NSLog(@"🎯 Using AX cursor (final fallback): %@", finalType);
|
|
764
769
|
}
|
|
765
770
|
else {
|
|
766
|
-
|
|
771
|
+
finalType = @"default";
|
|
767
772
|
}
|
|
768
773
|
|
|
769
|
-
|
|
774
|
+
// Only log when cursor type changes
|
|
775
|
+
static NSString *lastLoggedType = nil;
|
|
776
|
+
if (![finalType isEqualToString:lastLoggedType]) {
|
|
777
|
+
NSLog(@"🎯 %@", finalType);
|
|
778
|
+
lastLoggedType = [finalType copy];
|
|
779
|
+
}
|
|
770
780
|
return finalType;
|
|
771
781
|
}
|
|
772
782
|
}
|
|
@@ -1065,80 +1075,58 @@ NSDictionary* getDisplayScalingInfo(CGPoint globalPoint) {
|
|
|
1065
1075
|
uint32_t displayCount;
|
|
1066
1076
|
CGDirectDisplayID displayIDs[32];
|
|
1067
1077
|
CGGetActiveDisplayList(32, displayIDs, &displayCount);
|
|
1068
|
-
|
|
1078
|
+
|
|
1069
1079
|
// Find which display contains this point
|
|
1070
1080
|
for (uint32_t i = 0; i < displayCount; i++) {
|
|
1071
1081
|
CGDirectDisplayID displayID = displayIDs[i];
|
|
1072
1082
|
CGRect displayBounds = CGDisplayBounds(displayID);
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
displayID, displayBounds.origin.x, displayBounds.origin.y,
|
|
1076
|
-
displayBounds.size.width, displayBounds.size.height,
|
|
1077
|
-
globalPoint.x, globalPoint.y);
|
|
1078
|
-
|
|
1079
|
-
// CRITICAL FIX: Manual bounds check for better coordinate system compatibility
|
|
1080
|
-
BOOL isInBounds = (globalPoint.x >= displayBounds.origin.x &&
|
|
1083
|
+
|
|
1084
|
+
BOOL isInBounds = (globalPoint.x >= displayBounds.origin.x &&
|
|
1081
1085
|
globalPoint.x < displayBounds.origin.x + displayBounds.size.width &&
|
|
1082
|
-
globalPoint.y >= displayBounds.origin.y &&
|
|
1086
|
+
globalPoint.y >= displayBounds.origin.y &&
|
|
1083
1087
|
globalPoint.y < displayBounds.origin.y + displayBounds.size.height);
|
|
1084
|
-
|
|
1085
|
-
NSLog(@"🔍 Manual bounds check: %s", isInBounds ? "INSIDE" : "OUTSIDE");
|
|
1086
|
-
|
|
1088
|
+
|
|
1087
1089
|
// Check if point is within this display
|
|
1088
1090
|
if (isInBounds) {
|
|
1089
|
-
//
|
|
1090
|
-
// Method 1: CGDisplayCreateImage (may be scaled on some systems)
|
|
1091
|
+
// Get physical dimensions
|
|
1091
1092
|
CGImageRef testImage = CGDisplayCreateImage(displayID);
|
|
1092
1093
|
CGSize imageSize = CGSizeMake(CGImageGetWidth(testImage), CGImageGetHeight(testImage));
|
|
1093
1094
|
CGImageRelease(testImage);
|
|
1094
|
-
|
|
1095
|
-
// Method 2: Native display mode detection for true physical resolution
|
|
1095
|
+
|
|
1096
1096
|
CGSize actualPhysicalSize = imageSize;
|
|
1097
1097
|
CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(displayID, NULL);
|
|
1098
1098
|
if (displayModes) {
|
|
1099
1099
|
CFIndex modeCount = CFArrayGetCount(displayModes);
|
|
1100
1100
|
CGSize maxResolution = CGSizeMake(0, 0);
|
|
1101
|
-
|
|
1102
|
-
// Find the highest resolution mode (native resolution)
|
|
1101
|
+
|
|
1103
1102
|
for (CFIndex i = 0; i < modeCount; i++) {
|
|
1104
1103
|
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
|
|
1105
1104
|
CGSize modeSize = CGSizeMake(CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode));
|
|
1106
|
-
|
|
1107
|
-
if (modeSize.width > maxResolution.width ||
|
|
1105
|
+
|
|
1106
|
+
if (modeSize.width > maxResolution.width ||
|
|
1108
1107
|
(modeSize.width == maxResolution.width && modeSize.height > maxResolution.height)) {
|
|
1109
1108
|
maxResolution = modeSize;
|
|
1110
1109
|
}
|
|
1111
1110
|
}
|
|
1112
|
-
|
|
1113
|
-
// Use the max resolution if it's significantly higher than image size
|
|
1111
|
+
|
|
1114
1112
|
if (maxResolution.width > imageSize.width * 1.5 || maxResolution.height > imageSize.height * 1.5) {
|
|
1115
1113
|
actualPhysicalSize = maxResolution;
|
|
1116
|
-
NSLog(@"🔍 Using display mode detection: %.0fx%.0f (was %.0fx%.0f)",
|
|
1117
|
-
maxResolution.width, maxResolution.height, imageSize.width, imageSize.height);
|
|
1118
1114
|
} else {
|
|
1119
1115
|
actualPhysicalSize = imageSize;
|
|
1120
|
-
NSLog(@"🔍 Using image size detection: %.0fx%.0f", imageSize.width, imageSize.height);
|
|
1121
1116
|
}
|
|
1122
|
-
|
|
1117
|
+
|
|
1123
1118
|
CFRelease(displayModes);
|
|
1124
1119
|
} else {
|
|
1125
1120
|
actualPhysicalSize = imageSize;
|
|
1126
1121
|
}
|
|
1127
|
-
|
|
1122
|
+
|
|
1128
1123
|
CGSize logicalSize = displayBounds.size;
|
|
1129
1124
|
CGSize reportedPhysicalSize = CGSizeMake(CGDisplayPixelsWide(displayID), CGDisplayPixelsHigh(displayID));
|
|
1130
|
-
|
|
1131
|
-
NSLog(@"🔍 REAL scaling info:");
|
|
1132
|
-
NSLog(@" Logical: %.0fx%.0f", logicalSize.width, logicalSize.height);
|
|
1133
|
-
NSLog(@" Reported physical: %.0fx%.0f", reportedPhysicalSize.width, reportedPhysicalSize.height);
|
|
1134
|
-
NSLog(@" ACTUAL physical: %.0fx%.0f", actualPhysicalSize.width, actualPhysicalSize.height);
|
|
1135
|
-
|
|
1125
|
+
|
|
1136
1126
|
CGFloat scaleX = actualPhysicalSize.width / logicalSize.width;
|
|
1137
1127
|
CGFloat scaleY = actualPhysicalSize.height / logicalSize.height;
|
|
1138
1128
|
CGFloat scaleFactor = MAX(scaleX, scaleY);
|
|
1139
1129
|
|
|
1140
|
-
NSLog(@"🔍 REAL scale factors: X=%.2f, Y=%.2f, Final=%.2f", scaleX, scaleY, scaleFactor);
|
|
1141
|
-
|
|
1142
1130
|
return @{
|
|
1143
1131
|
@"displayID": @(displayID),
|
|
1144
1132
|
@"logicalSize": [NSValue valueWithSize:NSMakeSize(logicalSize.width, logicalSize.height)],
|
|
@@ -1149,39 +1137,37 @@ NSDictionary* getDisplayScalingInfo(CGPoint globalPoint) {
|
|
|
1149
1137
|
}
|
|
1150
1138
|
}
|
|
1151
1139
|
|
|
1152
|
-
// Fallback to main display
|
|
1140
|
+
// Fallback to main display
|
|
1153
1141
|
CGDirectDisplayID mainDisplay = CGMainDisplayID();
|
|
1154
1142
|
CGRect displayBounds = CGDisplayBounds(mainDisplay);
|
|
1155
|
-
|
|
1156
|
-
// Get REAL physical dimensions using multiple detection methods
|
|
1143
|
+
|
|
1157
1144
|
CGImageRef testImage = CGDisplayCreateImage(mainDisplay);
|
|
1158
1145
|
CGSize imageSize = CGSizeMake(CGImageGetWidth(testImage), CGImageGetHeight(testImage));
|
|
1159
1146
|
CGImageRelease(testImage);
|
|
1160
|
-
|
|
1161
|
-
// Try display mode detection for true native resolution
|
|
1147
|
+
|
|
1162
1148
|
CGSize actualPhysicalSize = imageSize;
|
|
1163
1149
|
CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(mainDisplay, NULL);
|
|
1164
1150
|
if (displayModes) {
|
|
1165
1151
|
CFIndex modeCount = CFArrayGetCount(displayModes);
|
|
1166
1152
|
CGSize maxResolution = CGSizeMake(0, 0);
|
|
1167
|
-
|
|
1153
|
+
|
|
1168
1154
|
for (CFIndex i = 0; i < modeCount; i++) {
|
|
1169
1155
|
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
|
|
1170
1156
|
CGSize modeSize = CGSizeMake(CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode));
|
|
1171
|
-
|
|
1172
|
-
if (modeSize.width > maxResolution.width ||
|
|
1157
|
+
|
|
1158
|
+
if (modeSize.width > maxResolution.width ||
|
|
1173
1159
|
(modeSize.width == maxResolution.width && modeSize.height > maxResolution.height)) {
|
|
1174
1160
|
maxResolution = modeSize;
|
|
1175
1161
|
}
|
|
1176
1162
|
}
|
|
1177
|
-
|
|
1163
|
+
|
|
1178
1164
|
if (maxResolution.width > imageSize.width * 1.5 || maxResolution.height > imageSize.height * 1.5) {
|
|
1179
1165
|
actualPhysicalSize = maxResolution;
|
|
1180
1166
|
}
|
|
1181
|
-
|
|
1167
|
+
|
|
1182
1168
|
CFRelease(displayModes);
|
|
1183
1169
|
}
|
|
1184
|
-
|
|
1170
|
+
|
|
1185
1171
|
CGSize logicalSize = displayBounds.size;
|
|
1186
1172
|
CGFloat scaleFactor = MAX(actualPhysicalSize.width / logicalSize.width, actualPhysicalSize.height / logicalSize.height);
|
|
1187
1173
|
|
|
@@ -1209,10 +1195,7 @@ Napi::Value GetCursorPosition(const Napi::CallbackInfo& info) {
|
|
|
1209
1195
|
CFRelease(event);
|
|
1210
1196
|
}
|
|
1211
1197
|
|
|
1212
|
-
// Get display scaling information
|
|
1213
|
-
NSDictionary *scalingInfo = getDisplayScalingInfo(rawLocation);
|
|
1214
1198
|
CGPoint logicalLocation = rawLocation;
|
|
1215
|
-
// CGEventGetLocation already returns logical coordinates; additional scaling happens in JS layer.
|
|
1216
1199
|
|
|
1217
1200
|
NSString *cursorType = getCursorType();
|
|
1218
1201
|
|
|
@@ -1250,27 +1233,11 @@ Napi::Value GetCursorPosition(const Napi::CallbackInfo& info) {
|
|
|
1250
1233
|
result.Set("cursorType", Napi::String::New(env, [cursorType UTF8String]));
|
|
1251
1234
|
result.Set("eventType", Napi::String::New(env, [eventType UTF8String]));
|
|
1252
1235
|
|
|
1253
|
-
//
|
|
1236
|
+
// Basic display info
|
|
1237
|
+
NSDictionary *scalingInfo = getDisplayScalingInfo(rawLocation);
|
|
1254
1238
|
if (scalingInfo) {
|
|
1255
1239
|
CGFloat scaleFactor = [[scalingInfo objectForKey:@"scaleFactor"] doubleValue];
|
|
1256
|
-
NSSize logicalSize = [[scalingInfo objectForKey:@"logicalSize"] sizeValue];
|
|
1257
|
-
NSSize physicalSize = [[scalingInfo objectForKey:@"physicalSize"] sizeValue];
|
|
1258
|
-
NSRect displayBounds = [[scalingInfo objectForKey:@"displayBounds"] rectValue];
|
|
1259
|
-
|
|
1260
1240
|
result.Set("scaleFactor", Napi::Number::New(env, scaleFactor));
|
|
1261
|
-
result.Set("rawX", Napi::Number::New(env, (int)rawLocation.x));
|
|
1262
|
-
result.Set("rawY", Napi::Number::New(env, (int)rawLocation.y));
|
|
1263
|
-
|
|
1264
|
-
// Add display dimension info for JS coordinate transformation
|
|
1265
|
-
Napi::Object displayInfo = Napi::Object::New(env);
|
|
1266
|
-
displayInfo.Set("logicalWidth", Napi::Number::New(env, logicalSize.width));
|
|
1267
|
-
displayInfo.Set("logicalHeight", Napi::Number::New(env, logicalSize.height));
|
|
1268
|
-
displayInfo.Set("physicalWidth", Napi::Number::New(env, physicalSize.width));
|
|
1269
|
-
displayInfo.Set("physicalHeight", Napi::Number::New(env, physicalSize.height));
|
|
1270
|
-
displayInfo.Set("displayX", Napi::Number::New(env, displayBounds.origin.x));
|
|
1271
|
-
displayInfo.Set("displayY", Napi::Number::New(env, displayBounds.origin.y));
|
|
1272
|
-
|
|
1273
|
-
result.Set("displayInfo", displayInfo);
|
|
1274
1241
|
}
|
|
1275
1242
|
|
|
1276
1243
|
return result;
|
package/src/mac_recorder.mm
CHANGED
|
@@ -591,16 +591,16 @@ Napi::Value GetDisplays(const Napi::CallbackInfo& info) {
|
|
|
591
591
|
}
|
|
592
592
|
Napi::Array result = Napi::Array::New(env, displays.count);
|
|
593
593
|
|
|
594
|
-
NSLog(@"Found %lu displays", (unsigned long)displays.count);
|
|
595
|
-
|
|
594
|
+
// NSLog(@"Found %lu displays", (unsigned long)displays.count);
|
|
595
|
+
|
|
596
596
|
for (NSUInteger i = 0; i < displays.count; i++) {
|
|
597
597
|
NSDictionary *display = displays[i];
|
|
598
|
-
NSLog(@"Display %lu: ID=%u, Name=%@, Size=%@x%@",
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
598
|
+
// NSLog(@"Display %lu: ID=%u, Name=%@, Size=%@x%@",
|
|
599
|
+
// (unsigned long)i,
|
|
600
|
+
// [display[@"id"] unsignedIntValue],
|
|
601
|
+
// display[@"name"],
|
|
602
|
+
// display[@"width"],
|
|
603
|
+
// display[@"height"]);
|
|
604
604
|
|
|
605
605
|
Napi::Object displayObj = Napi::Object::New(env);
|
|
606
606
|
displayObj.Set("id", Napi::Number::New(env, [display[@"id"] unsignedIntValue]));
|