node-mac-recorder 2.16.32 → 2.16.33

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.
@@ -0,0 +1,63 @@
1
+ const MacRecorder = require('./index.js');
2
+
3
+ async function testMacBookCursor() {
4
+ console.log('šŸ–„ļø Testing cursor on MacBook internal display...\n');
5
+
6
+ const recorder = new MacRecorder();
7
+
8
+ // Get displays
9
+ const displays = await recorder.getDisplays();
10
+ console.log('šŸ“ŗ Available displays:');
11
+ displays.forEach((display, index) => {
12
+ console.log(` Display ${index}: ${display.resolution} at (${display.x}, ${display.y}) - Primary: ${display.isPrimary}`);
13
+ });
14
+
15
+ console.log('\nšŸŽÆ Move your mouse to the PRIMARY MacBook display and press any key...');
16
+ console.log('(Make sure cursor is on the built-in MacBook screen, not external monitor)\n');
17
+
18
+ // Wait for keypress
19
+ await new Promise((resolve) => {
20
+ process.stdin.setRawMode(true);
21
+ process.stdin.resume();
22
+ process.stdin.once('data', () => {
23
+ process.stdin.setRawMode(false);
24
+ resolve();
25
+ });
26
+ });
27
+
28
+ console.log('šŸ” Testing cursor position on MacBook display:');
29
+ for (let i = 0; i < 3; i++) {
30
+ const position = recorder.getCursorPosition();
31
+ console.log(`\n Test ${i+1}:`);
32
+ console.log(` Cursor: (${position.x}, ${position.y})`);
33
+ console.log(` Cursor type: ${position.cursorType}`);
34
+
35
+ // Check which display cursor is on
36
+ const primaryDisplay = displays.find(d => d.isPrimary);
37
+ if (primaryDisplay) {
38
+ const isOnPrimary = position.x >= primaryDisplay.x &&
39
+ position.x < primaryDisplay.x + parseInt(primaryDisplay.resolution.split('x')[0]) &&
40
+ position.y >= primaryDisplay.y &&
41
+ position.y < primaryDisplay.y + parseInt(primaryDisplay.resolution.split('x')[1]);
42
+
43
+ console.log(` On primary display: ${isOnPrimary ? 'āœ… YES' : 'āŒ NO'}`);
44
+ }
45
+
46
+ if (position.scaleFactor) {
47
+ console.log(` Scale factor: ${position.scaleFactor}x`);
48
+ if (position.displayInfo) {
49
+ console.log(` Display logical: ${position.displayInfo.logicalWidth}x${position.displayInfo.logicalHeight}`);
50
+ console.log(` Display physical: ${position.displayInfo.physicalWidth}x${position.displayInfo.physicalHeight}`);
51
+ console.log(` Raw cursor: (${position.rawX}, ${position.rawY})`);
52
+ }
53
+ } else {
54
+ console.log(` āš ļø No scaling info detected`);
55
+ }
56
+
57
+ await new Promise(resolve => setTimeout(resolve, 1000));
58
+ }
59
+
60
+ process.exit(0);
61
+ }
62
+
63
+ testMacBookCursor().catch(console.error);
@@ -0,0 +1,26 @@
1
+ const MacRecorder = require('./index.js');
2
+
3
+ console.log('šŸŽÆ Simple cursor test - Move your mouse to MacBook screen...\n');
4
+
5
+ const recorder = new MacRecorder();
6
+
7
+ // Test 10 cursor positions
8
+ for (let i = 0; i < 10; i++) {
9
+ setTimeout(() => {
10
+ const position = recorder.getCursorPosition();
11
+ console.log(`${i+1}. Cursor: (${position.x}, ${position.y}), Scale: ${position.scaleFactor || 'none'}`);
12
+
13
+ if (position.displayInfo && position.scaleFactor > 1.1) {
14
+ console.log(` šŸŽ‰ SCALING DETECTED! ${position.scaleFactor}x`);
15
+ console.log(` Logical: ${position.displayInfo.logicalWidth}x${position.displayInfo.logicalHeight}`);
16
+ console.log(` Physical: ${position.displayInfo.physicalWidth}x${position.displayInfo.physicalHeight}`);
17
+ console.log(` Raw cursor: (${position.rawX}, ${position.rawY})`);
18
+ process.exit(0);
19
+ }
20
+
21
+ if (i === 9) {
22
+ console.log('\nāš ļø No scaling detected. Try moving mouse to MacBook internal display.');
23
+ process.exit(0);
24
+ }
25
+ }, i * 500);
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.16.32",
3
+ "version": "2.16.33",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -488,40 +488,110 @@ NSDictionary* getDisplayScalingInfo(CGPoint globalPoint) {
488
488
 
489
489
  // Check if point is within this display
490
490
  if (isInBounds) {
491
- // Get display scaling info
491
+ // CRITICAL FIX: Get REAL physical dimensions using multiple detection methods
492
+ // Method 1: CGDisplayCreateImage (may be scaled on some systems)
493
+ CGImageRef testImage = CGDisplayCreateImage(displayID);
494
+ CGSize imageSize = CGSizeMake(CGImageGetWidth(testImage), CGImageGetHeight(testImage));
495
+ CGImageRelease(testImage);
496
+
497
+ // Method 2: Native display mode detection for true physical resolution
498
+ CGSize actualPhysicalSize = imageSize;
499
+ CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(displayID, NULL);
500
+ if (displayModes) {
501
+ CFIndex modeCount = CFArrayGetCount(displayModes);
502
+ CGSize maxResolution = CGSizeMake(0, 0);
503
+
504
+ // Find the highest resolution mode (native resolution)
505
+ for (CFIndex i = 0; i < modeCount; i++) {
506
+ CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
507
+ CGSize modeSize = CGSizeMake(CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode));
508
+
509
+ if (modeSize.width > maxResolution.width ||
510
+ (modeSize.width == maxResolution.width && modeSize.height > maxResolution.height)) {
511
+ maxResolution = modeSize;
512
+ }
513
+ }
514
+
515
+ // Use the max resolution if it's significantly higher than image size
516
+ if (maxResolution.width > imageSize.width * 1.5 || maxResolution.height > imageSize.height * 1.5) {
517
+ actualPhysicalSize = maxResolution;
518
+ NSLog(@"šŸ” Using display mode detection: %.0fx%.0f (was %.0fx%.0f)",
519
+ maxResolution.width, maxResolution.height, imageSize.width, imageSize.height);
520
+ } else {
521
+ actualPhysicalSize = imageSize;
522
+ NSLog(@"šŸ” Using image size detection: %.0fx%.0f", imageSize.width, imageSize.height);
523
+ }
524
+
525
+ CFRelease(displayModes);
526
+ } else {
527
+ actualPhysicalSize = imageSize;
528
+ }
529
+
492
530
  CGSize logicalSize = displayBounds.size;
493
- CGSize physicalSize = CGSizeMake(CGDisplayPixelsWide(displayID), CGDisplayPixelsHigh(displayID));
531
+ CGSize reportedPhysicalSize = CGSizeMake(CGDisplayPixelsWide(displayID), CGDisplayPixelsHigh(displayID));
494
532
 
495
- NSLog(@"šŸ” Scaling info: logical(%.0fx%.0f) physical(%.0fx%.0f)",
496
- logicalSize.width, logicalSize.height, physicalSize.width, physicalSize.height);
533
+ NSLog(@"šŸ” REAL scaling info:");
534
+ NSLog(@" Logical: %.0fx%.0f", logicalSize.width, logicalSize.height);
535
+ NSLog(@" Reported physical: %.0fx%.0f", reportedPhysicalSize.width, reportedPhysicalSize.height);
536
+ NSLog(@" ACTUAL physical: %.0fx%.0f", actualPhysicalSize.width, actualPhysicalSize.height);
497
537
 
498
- CGFloat scaleX = physicalSize.width / logicalSize.width;
499
- CGFloat scaleY = physicalSize.height / logicalSize.height;
538
+ CGFloat scaleX = actualPhysicalSize.width / logicalSize.width;
539
+ CGFloat scaleY = actualPhysicalSize.height / logicalSize.height;
500
540
  CGFloat scaleFactor = MAX(scaleX, scaleY);
501
541
 
502
- NSLog(@"šŸ” Scale factors: X=%.2f, Y=%.2f, Final=%.2f", scaleX, scaleY, scaleFactor);
542
+ NSLog(@"šŸ” REAL scale factors: X=%.2f, Y=%.2f, Final=%.2f", scaleX, scaleY, scaleFactor);
503
543
 
504
544
  return @{
505
545
  @"displayID": @(displayID),
506
546
  @"logicalSize": [NSValue valueWithSize:NSMakeSize(logicalSize.width, logicalSize.height)],
507
- @"physicalSize": [NSValue valueWithSize:NSMakeSize(physicalSize.width, physicalSize.height)],
547
+ @"physicalSize": [NSValue valueWithSize:NSMakeSize(actualPhysicalSize.width, actualPhysicalSize.height)],
508
548
  @"scaleFactor": @(scaleFactor),
509
549
  @"displayBounds": [NSValue valueWithRect:NSMakeRect(displayBounds.origin.x, displayBounds.origin.y, displayBounds.size.width, displayBounds.size.height)]
510
550
  };
511
551
  }
512
552
  }
513
553
 
514
- // Fallback to main display
554
+ // Fallback to main display with REAL physical dimensions
515
555
  CGDirectDisplayID mainDisplay = CGMainDisplayID();
516
556
  CGRect displayBounds = CGDisplayBounds(mainDisplay);
557
+
558
+ // Get REAL physical dimensions using multiple detection methods
559
+ CGImageRef testImage = CGDisplayCreateImage(mainDisplay);
560
+ CGSize imageSize = CGSizeMake(CGImageGetWidth(testImage), CGImageGetHeight(testImage));
561
+ CGImageRelease(testImage);
562
+
563
+ // Try display mode detection for true native resolution
564
+ CGSize actualPhysicalSize = imageSize;
565
+ CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(mainDisplay, NULL);
566
+ if (displayModes) {
567
+ CFIndex modeCount = CFArrayGetCount(displayModes);
568
+ CGSize maxResolution = CGSizeMake(0, 0);
569
+
570
+ for (CFIndex i = 0; i < modeCount; i++) {
571
+ CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i);
572
+ CGSize modeSize = CGSizeMake(CGDisplayModeGetWidth(mode), CGDisplayModeGetHeight(mode));
573
+
574
+ if (modeSize.width > maxResolution.width ||
575
+ (modeSize.width == maxResolution.width && modeSize.height > maxResolution.height)) {
576
+ maxResolution = modeSize;
577
+ }
578
+ }
579
+
580
+ if (maxResolution.width > imageSize.width * 1.5 || maxResolution.height > imageSize.height * 1.5) {
581
+ actualPhysicalSize = maxResolution;
582
+ }
583
+
584
+ CFRelease(displayModes);
585
+ }
586
+
517
587
  CGSize logicalSize = displayBounds.size;
518
- CGSize physicalSize = CGSizeMake(CGDisplayPixelsWide(mainDisplay), CGDisplayPixelsHigh(mainDisplay));
588
+ CGFloat scaleFactor = MAX(actualPhysicalSize.width / logicalSize.width, actualPhysicalSize.height / logicalSize.height);
519
589
 
520
590
  return @{
521
591
  @"displayID": @(mainDisplay),
522
592
  @"logicalSize": [NSValue valueWithSize:NSMakeSize(logicalSize.width, logicalSize.height)],
523
- @"physicalSize": [NSValue valueWithSize:NSMakeSize(physicalSize.width, physicalSize.height)],
524
- @"scaleFactor": @(MAX(physicalSize.width / logicalSize.width, physicalSize.height / logicalSize.height)),
593
+ @"physicalSize": [NSValue valueWithSize:NSMakeSize(actualPhysicalSize.width, actualPhysicalSize.height)],
594
+ @"scaleFactor": @(scaleFactor),
525
595
  @"displayBounds": [NSValue valueWithRect:NSMakeRect(displayBounds.origin.x, displayBounds.origin.y, displayBounds.size.width, displayBounds.size.height)]
526
596
  };
527
597
  } @catch (NSException *exception) {