node-mac-recorder 2.20.10 → 2.20.11
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 +89 -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,71 @@ 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
|
+
|
|
658
|
+
// Debug: Show proportional analysis
|
|
659
|
+
NSLog(@"🔍 CURSOR: %.1fx%.1f ratio=%.2f hotspot=(%.2f,%.2f)",
|
|
660
|
+
imageSize.width, imageSize.height, aspectRatio, relativeHotspotX, relativeHotspotY);
|
|
654
661
|
|
|
655
|
-
//
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
662
|
+
// UPDATED with real cursor data:
|
|
663
|
+
// Arrow: 17x23 ratio=0.74 hotspot=(0.24,0.17)
|
|
664
|
+
// Text: 9x18 ratio=0.50 hotspot=(0.44,0.50)
|
|
665
|
+
// Pointer: 32x32 ratio=1.00 hotspot=(0.41,0.25)
|
|
666
|
+
|
|
667
|
+
// 1. TEXT/I-BEAM CURSOR - narrow ratio, center hotspot
|
|
668
|
+
if (aspectRatio >= 0.45 && aspectRatio <= 0.60 && // Narrow (0.50 typical)
|
|
669
|
+
relativeHotspotX >= 0.35 && relativeHotspotX <= 0.55 && // Center X (0.44 typical)
|
|
670
|
+
relativeHotspotY >= 0.40 && relativeHotspotY <= 0.60) { // Center Y (0.50 typical)
|
|
660
671
|
cursorType = @"text";
|
|
661
|
-
NSLog(@"🎯 DETECTED IBEAM CURSOR -> text");
|
|
662
672
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
673
|
+
// 2. ARROW CURSOR - medium ratio, top-left hotspot
|
|
674
|
+
else if (aspectRatio >= 0.65 && aspectRatio <= 0.85 && // Medium (0.74 typical)
|
|
675
|
+
relativeHotspotX >= 0.15 && relativeHotspotX <= 0.35 && // Left side (0.24 typical)
|
|
676
|
+
relativeHotspotY >= 0.10 && relativeHotspotY <= 0.25) { // Top area (0.17 typical)
|
|
666
677
|
cursorType = @"default";
|
|
667
|
-
NSLog(@"🎯 DETECTED ARROW CURSOR -> default");
|
|
668
678
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
679
|
+
// 3. POINTER CURSOR - square ratio, left-center hotspot
|
|
680
|
+
else if (aspectRatio >= 0.90 && aspectRatio <= 1.10 && // Square (1.00 typical)
|
|
681
|
+
relativeHotspotX >= 0.30 && relativeHotspotX <= 0.50 && // Left-center (0.41 typical)
|
|
682
|
+
relativeHotspotY >= 0.15 && relativeHotspotY <= 0.35) { // Upper area (0.25 typical)
|
|
673
683
|
cursorType = @"pointer";
|
|
674
|
-
|
|
684
|
+
}
|
|
685
|
+
// 4. GRAB CURSOR - square, center hotspot
|
|
686
|
+
else if (aspectRatio >= 0.90 && aspectRatio <= 1.10 && // Square
|
|
687
|
+
relativeHotspotX >= 0.40 && relativeHotspotX <= 0.60 && // Center X
|
|
688
|
+
relativeHotspotY >= 0.40 && relativeHotspotY <= 0.60) { // Center Y
|
|
689
|
+
cursorType = @"grab";
|
|
675
690
|
}
|
|
676
691
|
else {
|
|
677
692
|
// Try to use a different approach - cursor name introspection
|
|
678
693
|
NSString *derived = cursorTypeFromNSCursor(currentCursor);
|
|
679
694
|
if (derived && ![derived isEqualToString:@"default"]) {
|
|
680
695
|
cursorType = derived;
|
|
681
|
-
NSLog(@"🎯 DERIVED FROM ANALYSIS: %@", cursorType);
|
|
696
|
+
// NSLog(@"🎯 DERIVED FROM ANALYSIS: %@", cursorType);
|
|
682
697
|
} else {
|
|
683
698
|
cursorType = @"default";
|
|
684
|
-
NSLog(@"🎯 FALLBACK TO DEFAULT (will check AX)");
|
|
699
|
+
// NSLog(@"🎯 FALLBACK TO DEFAULT (will check AX)");
|
|
685
700
|
}
|
|
686
701
|
}
|
|
687
702
|
} else {
|
|
688
|
-
NSLog(@"🖱️ No current cursor found");
|
|
703
|
+
// NSLog(@"🖱️ No current cursor found");
|
|
689
704
|
cursorType = @"default";
|
|
690
705
|
}
|
|
691
706
|
};
|
|
@@ -738,35 +753,33 @@ NSString* getCursorType() {
|
|
|
738
753
|
|
|
739
754
|
NSString *finalType = @"default";
|
|
740
755
|
|
|
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);
|
|
756
|
+
// SYSTEM CURSOR FIRST - more reliable for visual state
|
|
757
|
+
// Always trust system cursor first, only use AX for very specific cases
|
|
758
|
+
if (systemCursorType && [systemCursorType length] > 0) {
|
|
759
|
+
// Only override system cursor with AX if system is "default" AND AX gives us text/resize
|
|
760
|
+
if ([systemCursorType isEqualToString:@"default"] && axCursorType &&
|
|
761
|
+
([axCursorType isEqualToString:@"text"] ||
|
|
762
|
+
[axCursorType containsString:@"resize"] ||
|
|
763
|
+
[axCursorType isEqualToString:@"crosshair"])) {
|
|
764
|
+
finalType = axCursorType;
|
|
765
|
+
} else {
|
|
766
|
+
finalType = systemCursorType;
|
|
767
|
+
}
|
|
759
768
|
}
|
|
760
|
-
//
|
|
769
|
+
// Only if system completely fails, use AX
|
|
761
770
|
else if (axCursorType && [axCursorType length] > 0) {
|
|
762
771
|
finalType = axCursorType;
|
|
763
|
-
NSLog(@"🎯 Using AX cursor (final fallback): %@", finalType);
|
|
764
772
|
}
|
|
765
773
|
else {
|
|
766
|
-
|
|
774
|
+
finalType = @"default";
|
|
767
775
|
}
|
|
768
776
|
|
|
769
|
-
|
|
777
|
+
// Only log when cursor type changes
|
|
778
|
+
static NSString *lastLoggedType = nil;
|
|
779
|
+
if (![finalType isEqualToString:lastLoggedType]) {
|
|
780
|
+
NSLog(@"🎯 %@", finalType);
|
|
781
|
+
lastLoggedType = [finalType copy];
|
|
782
|
+
}
|
|
770
783
|
return finalType;
|
|
771
784
|
}
|
|
772
785
|
}
|
|
@@ -1065,80 +1078,58 @@ NSDictionary* getDisplayScalingInfo(CGPoint globalPoint) {
|
|
|
1065
1078
|
uint32_t displayCount;
|
|
1066
1079
|
CGDirectDisplayID displayIDs[32];
|
|
1067
1080
|
CGGetActiveDisplayList(32, displayIDs, &displayCount);
|
|
1068
|
-
|
|
1081
|
+
|
|
1069
1082
|
// Find which display contains this point
|
|
1070
1083
|
for (uint32_t i = 0; i < displayCount; i++) {
|
|
1071
1084
|
CGDirectDisplayID displayID = displayIDs[i];
|
|
1072
1085
|
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 &&
|
|
1086
|
+
|
|
1087
|
+
BOOL isInBounds = (globalPoint.x >= displayBounds.origin.x &&
|
|
1081
1088
|
globalPoint.x < displayBounds.origin.x + displayBounds.size.width &&
|
|
1082
|
-
globalPoint.y >= displayBounds.origin.y &&
|
|
1089
|
+
globalPoint.y >= displayBounds.origin.y &&
|
|
1083
1090
|
globalPoint.y < displayBounds.origin.y + displayBounds.size.height);
|
|
1084
|
-
|
|
1085
|
-
NSLog(@"🔍 Manual bounds check: %s", isInBounds ? "INSIDE" : "OUTSIDE");
|
|
1086
|
-
|
|
1091
|
+
|
|
1087
1092
|
// Check if point is within this display
|
|
1088
1093
|
if (isInBounds) {
|
|
1089
|
-
//
|
|
1090
|
-
// Method 1: CGDisplayCreateImage (may be scaled on some systems)
|
|
1094
|
+
// Get physical dimensions
|
|
1091
1095
|
CGImageRef testImage = CGDisplayCreateImage(displayID);
|
|
1092
1096
|
CGSize imageSize = CGSizeMake(CGImageGetWidth(testImage), CGImageGetHeight(testImage));
|
|
1093
1097
|
CGImageRelease(testImage);
|
|
1094
|
-
|
|
1095
|
-
// Method 2: Native display mode detection for true physical resolution
|
|
1098
|
+
|
|
1096
1099
|
CGSize actualPhysicalSize = imageSize;
|
|
1097
1100
|
CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(displayID, NULL);
|
|
1098
1101
|
if (displayModes) {
|
|
1099
1102
|
CFIndex modeCount = CFArrayGetCount(displayModes);
|
|
1100
1103
|
CGSize maxResolution = CGSizeMake(0, 0);
|
|
1101
|
-
|
|
1102
|
-
// Find the highest resolution mode (native resolution)
|
|
1104
|
+
|
|
1103
1105
|
for (CFIndex i = 0; i < modeCount; i++) {
|
|
1104
1106
|
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
|
|
1105
1107
|
CGSize modeSize = CGSizeMake(CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode));
|
|
1106
|
-
|
|
1107
|
-
if (modeSize.width > maxResolution.width ||
|
|
1108
|
+
|
|
1109
|
+
if (modeSize.width > maxResolution.width ||
|
|
1108
1110
|
(modeSize.width == maxResolution.width && modeSize.height > maxResolution.height)) {
|
|
1109
1111
|
maxResolution = modeSize;
|
|
1110
1112
|
}
|
|
1111
1113
|
}
|
|
1112
|
-
|
|
1113
|
-
// Use the max resolution if it's significantly higher than image size
|
|
1114
|
+
|
|
1114
1115
|
if (maxResolution.width > imageSize.width * 1.5 || maxResolution.height > imageSize.height * 1.5) {
|
|
1115
1116
|
actualPhysicalSize = maxResolution;
|
|
1116
|
-
NSLog(@"🔍 Using display mode detection: %.0fx%.0f (was %.0fx%.0f)",
|
|
1117
|
-
maxResolution.width, maxResolution.height, imageSize.width, imageSize.height);
|
|
1118
1117
|
} else {
|
|
1119
1118
|
actualPhysicalSize = imageSize;
|
|
1120
|
-
NSLog(@"🔍 Using image size detection: %.0fx%.0f", imageSize.width, imageSize.height);
|
|
1121
1119
|
}
|
|
1122
|
-
|
|
1120
|
+
|
|
1123
1121
|
CFRelease(displayModes);
|
|
1124
1122
|
} else {
|
|
1125
1123
|
actualPhysicalSize = imageSize;
|
|
1126
1124
|
}
|
|
1127
|
-
|
|
1125
|
+
|
|
1128
1126
|
CGSize logicalSize = displayBounds.size;
|
|
1129
1127
|
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
|
-
|
|
1128
|
+
|
|
1136
1129
|
CGFloat scaleX = actualPhysicalSize.width / logicalSize.width;
|
|
1137
1130
|
CGFloat scaleY = actualPhysicalSize.height / logicalSize.height;
|
|
1138
1131
|
CGFloat scaleFactor = MAX(scaleX, scaleY);
|
|
1139
1132
|
|
|
1140
|
-
NSLog(@"🔍 REAL scale factors: X=%.2f, Y=%.2f, Final=%.2f", scaleX, scaleY, scaleFactor);
|
|
1141
|
-
|
|
1142
1133
|
return @{
|
|
1143
1134
|
@"displayID": @(displayID),
|
|
1144
1135
|
@"logicalSize": [NSValue valueWithSize:NSMakeSize(logicalSize.width, logicalSize.height)],
|
|
@@ -1149,39 +1140,37 @@ NSDictionary* getDisplayScalingInfo(CGPoint globalPoint) {
|
|
|
1149
1140
|
}
|
|
1150
1141
|
}
|
|
1151
1142
|
|
|
1152
|
-
// Fallback to main display
|
|
1143
|
+
// Fallback to main display
|
|
1153
1144
|
CGDirectDisplayID mainDisplay = CGMainDisplayID();
|
|
1154
1145
|
CGRect displayBounds = CGDisplayBounds(mainDisplay);
|
|
1155
|
-
|
|
1156
|
-
// Get REAL physical dimensions using multiple detection methods
|
|
1146
|
+
|
|
1157
1147
|
CGImageRef testImage = CGDisplayCreateImage(mainDisplay);
|
|
1158
1148
|
CGSize imageSize = CGSizeMake(CGImageGetWidth(testImage), CGImageGetHeight(testImage));
|
|
1159
1149
|
CGImageRelease(testImage);
|
|
1160
|
-
|
|
1161
|
-
// Try display mode detection for true native resolution
|
|
1150
|
+
|
|
1162
1151
|
CGSize actualPhysicalSize = imageSize;
|
|
1163
1152
|
CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(mainDisplay, NULL);
|
|
1164
1153
|
if (displayModes) {
|
|
1165
1154
|
CFIndex modeCount = CFArrayGetCount(displayModes);
|
|
1166
1155
|
CGSize maxResolution = CGSizeMake(0, 0);
|
|
1167
|
-
|
|
1156
|
+
|
|
1168
1157
|
for (CFIndex i = 0; i < modeCount; i++) {
|
|
1169
1158
|
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
|
|
1170
1159
|
CGSize modeSize = CGSizeMake(CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode));
|
|
1171
|
-
|
|
1172
|
-
if (modeSize.width > maxResolution.width ||
|
|
1160
|
+
|
|
1161
|
+
if (modeSize.width > maxResolution.width ||
|
|
1173
1162
|
(modeSize.width == maxResolution.width && modeSize.height > maxResolution.height)) {
|
|
1174
1163
|
maxResolution = modeSize;
|
|
1175
1164
|
}
|
|
1176
1165
|
}
|
|
1177
|
-
|
|
1166
|
+
|
|
1178
1167
|
if (maxResolution.width > imageSize.width * 1.5 || maxResolution.height > imageSize.height * 1.5) {
|
|
1179
1168
|
actualPhysicalSize = maxResolution;
|
|
1180
1169
|
}
|
|
1181
|
-
|
|
1170
|
+
|
|
1182
1171
|
CFRelease(displayModes);
|
|
1183
1172
|
}
|
|
1184
|
-
|
|
1173
|
+
|
|
1185
1174
|
CGSize logicalSize = displayBounds.size;
|
|
1186
1175
|
CGFloat scaleFactor = MAX(actualPhysicalSize.width / logicalSize.width, actualPhysicalSize.height / logicalSize.height);
|
|
1187
1176
|
|
|
@@ -1209,10 +1198,7 @@ Napi::Value GetCursorPosition(const Napi::CallbackInfo& info) {
|
|
|
1209
1198
|
CFRelease(event);
|
|
1210
1199
|
}
|
|
1211
1200
|
|
|
1212
|
-
// Get display scaling information
|
|
1213
|
-
NSDictionary *scalingInfo = getDisplayScalingInfo(rawLocation);
|
|
1214
1201
|
CGPoint logicalLocation = rawLocation;
|
|
1215
|
-
// CGEventGetLocation already returns logical coordinates; additional scaling happens in JS layer.
|
|
1216
1202
|
|
|
1217
1203
|
NSString *cursorType = getCursorType();
|
|
1218
1204
|
|
|
@@ -1250,27 +1236,11 @@ Napi::Value GetCursorPosition(const Napi::CallbackInfo& info) {
|
|
|
1250
1236
|
result.Set("cursorType", Napi::String::New(env, [cursorType UTF8String]));
|
|
1251
1237
|
result.Set("eventType", Napi::String::New(env, [eventType UTF8String]));
|
|
1252
1238
|
|
|
1253
|
-
//
|
|
1239
|
+
// Basic display info
|
|
1240
|
+
NSDictionary *scalingInfo = getDisplayScalingInfo(rawLocation);
|
|
1254
1241
|
if (scalingInfo) {
|
|
1255
1242
|
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
1243
|
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
1244
|
}
|
|
1275
1245
|
|
|
1276
1246
|
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]));
|