node-mac-recorder 2.20.8 → 2.20.10

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.
@@ -2,7 +2,8 @@
2
2
  "permissions": {
3
3
  "allow": [
4
4
  "Bash(node-gyp:*)",
5
- "Bash(node:*)"
5
+ "Bash(node:*)",
6
+ "Bash(timeout:*)"
6
7
  ],
7
8
  "deny": [],
8
9
  "ask": []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.20.8",
3
+ "version": "2.20.10",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -392,56 +392,100 @@ static NSString* cursorTypeFromCursorName(NSString *value) {
392
392
 
393
393
  NSString *normalized = [[value stringByReplacingOccurrencesOfString:@"_" withString:@"-"] lowercaseString];
394
394
 
395
- if ([normalized containsString:@"arrow"]) {
395
+ // Arrow cursor patterns
396
+ if ([normalized containsString:@"arrow"] || [normalized containsString:@"default"]) {
396
397
  return @"default";
397
398
  }
399
+
400
+ // Text cursor patterns
398
401
  if ([normalized containsString:@"ibeam"] ||
399
402
  [normalized containsString:@"insertion"] ||
400
- [normalized containsString:@"text"]) {
403
+ [normalized containsString:@"text"] ||
404
+ [normalized containsString:@"edit"]) {
401
405
  return @"text";
402
406
  }
403
- if ([normalized containsString:@"openhand"]) {
407
+
408
+ // Hand cursors
409
+ if ([normalized containsString:@"openhand"] || [normalized containsString:@"open-hand"]) {
404
410
  return @"grab";
405
411
  }
406
- if ([normalized containsString:@"closedhand"]) {
412
+ if ([normalized containsString:@"closedhand"] || [normalized containsString:@"closed-hand"]) {
407
413
  return @"grabbing";
408
414
  }
415
+
416
+ // Pointer cursor patterns
409
417
  if ([normalized containsString:@"pointing"] ||
410
- ([normalized containsString:@"hand"] && ![normalized containsString:@"closed"])) {
418
+ [normalized containsString:@"pointinghand"] ||
419
+ ([normalized containsString:@"hand"] && ![normalized containsString:@"closed"] && ![normalized containsString:@"open"]) ||
420
+ [normalized containsString:@"link"] ||
421
+ [normalized containsString:@"button"]) {
411
422
  return @"pointer";
412
423
  }
413
- if ([normalized containsString:@"crosshair"]) {
424
+
425
+ // Crosshair patterns
426
+ if ([normalized containsString:@"crosshair"] || [normalized containsString:@"cross-hair"]) {
414
427
  return @"crosshair";
415
428
  }
429
+
430
+ // Not allowed patterns
416
431
  if ([normalized containsString:@"not-allowed"] ||
417
432
  [normalized containsString:@"notallowed"] ||
418
- [normalized containsString:@"forbidden"]) {
433
+ [normalized containsString:@"forbidden"] ||
434
+ [normalized containsString:@"operation-not-allowed"]) {
419
435
  return @"not-allowed";
420
436
  }
421
- if ([normalized containsString:@"dragcopy"] || [normalized containsString:@"copy"]) {
437
+
438
+ // Copy cursor patterns
439
+ if ([normalized containsString:@"dragcopy"] ||
440
+ [normalized containsString:@"drag-copy"] ||
441
+ [normalized containsString:@"copy"]) {
422
442
  return @"copy";
423
443
  }
424
- if ([normalized containsString:@"draglink"] || [normalized containsString:@"alias"]) {
444
+
445
+ // Alias cursor patterns
446
+ if ([normalized containsString:@"draglink"] ||
447
+ [normalized containsString:@"drag-link"] ||
448
+ [normalized containsString:@"alias"]) {
425
449
  return @"alias";
426
450
  }
427
- if ([normalized containsString:@"context"] && [normalized containsString:@"menu"]) {
451
+
452
+ // Context menu patterns
453
+ if (([normalized containsString:@"context"] && [normalized containsString:@"menu"]) ||
454
+ [normalized containsString:@"contextual-menu"]) {
428
455
  return @"context-menu";
429
456
  }
457
+
458
+ // Zoom patterns
430
459
  if ([normalized containsString:@"zoom"]) {
431
460
  if ([normalized containsString:@"out"]) {
432
461
  return @"zoom-out";
433
462
  }
434
463
  return @"zoom-in";
435
464
  }
465
+
466
+ // Resize cursor patterns - more comprehensive
436
467
  if ([normalized containsString:@"resize"] || [normalized containsString:@"size"]) {
437
- BOOL diagonalUp = [normalized containsString:@"diagonalup"] || [normalized containsString:@"nesw"];
438
- BOOL diagonalDown = [normalized containsString:@"diagonaldown"] || [normalized containsString:@"nwse"];
468
+ // Diagonal resize cursors
469
+ BOOL diagonalUp = [normalized containsString:@"diagonalup"] ||
470
+ [normalized containsString:@"diagonal-up"] ||
471
+ [normalized containsString:@"nesw"];
472
+ BOOL diagonalDown = [normalized containsString:@"diagonaldown"] ||
473
+ [normalized containsString:@"diagonal-down"] ||
474
+ [normalized containsString:@"nwse"];
475
+
476
+ // Horizontal and vertical resize
439
477
  BOOL horizontal = [normalized containsString:@"leftright"] ||
478
+ [normalized containsString:@"left-right"] ||
440
479
  [normalized containsString:@"horizontal"] ||
441
- ([normalized containsString:@"left"] && [normalized containsString:@"right"]);
480
+ ([normalized containsString:@"left"] && [normalized containsString:@"right"]) ||
481
+ [normalized containsString:@"col"] ||
482
+ [normalized containsString:@"column"];
483
+
442
484
  BOOL vertical = [normalized containsString:@"updown"] ||
485
+ [normalized containsString:@"up-down"] ||
443
486
  [normalized containsString:@"vertical"] ||
444
- ([normalized containsString:@"up"] && [normalized containsString:@"down"]);
487
+ ([normalized containsString:@"up"] && [normalized containsString:@"down"]) ||
488
+ [normalized containsString:@"row"];
445
489
 
446
490
  if (diagonalUp) {
447
491
  return @"nesw-resize";
@@ -455,6 +499,22 @@ static NSString* cursorTypeFromCursorName(NSString *value) {
455
499
  if (horizontal) {
456
500
  return @"col-resize";
457
501
  }
502
+
503
+ // Generic resize fallback
504
+ return @"default"; // or could be a generic resize
505
+ }
506
+
507
+ // Additional specific patterns
508
+ if ([normalized containsString:@"wait"] || [normalized containsString:@"busy"]) {
509
+ return @"wait";
510
+ }
511
+
512
+ if ([normalized containsString:@"help"] || [normalized containsString:@"question"]) {
513
+ return @"help";
514
+ }
515
+
516
+ if ([normalized containsString:@"progress"]) {
517
+ return @"progress";
458
518
  }
459
519
 
460
520
  return nil;
@@ -462,9 +522,10 @@ static NSString* cursorTypeFromCursorName(NSString *value) {
462
522
 
463
523
  static NSString* cursorTypeFromNSCursor(NSCursor *cursor) {
464
524
  if (!cursor) {
465
- return nil;
525
+ return @"default";
466
526
  }
467
527
 
528
+ // Standard macOS cursors
468
529
  if (cursor == [NSCursor arrowCursor]) {
469
530
  return @"default";
470
531
  }
@@ -499,34 +560,66 @@ static NSString* cursorTypeFromNSCursor(NSCursor *cursor) {
499
560
  if (cursor == [NSCursor contextualMenuCursor]) {
500
561
  return @"context-menu";
501
562
  }
502
- if ([NSCursor respondsToSelector:@selector(resizeLeftRightCursor)] &&
503
- (cursor == [NSCursor resizeLeftRightCursor] ||
504
- cursor == [NSCursor resizeLeftCursor] ||
505
- cursor == [NSCursor resizeRightCursor])) {
506
- return @"col-resize";
563
+
564
+ // Resize cursors - improved detection
565
+ if ([NSCursor respondsToSelector:@selector(resizeLeftRightCursor)]) {
566
+ if (cursor == [NSCursor resizeLeftRightCursor]) {
567
+ return @"col-resize";
568
+ }
507
569
  }
508
- if ([NSCursor respondsToSelector:@selector(resizeUpDownCursor)] &&
509
- (cursor == [NSCursor resizeUpDownCursor] ||
510
- cursor == [NSCursor resizeUpCursor] ||
511
- cursor == [NSCursor resizeDownCursor])) {
512
- return @"ns-resize";
570
+ if ([NSCursor respondsToSelector:@selector(resizeLeftCursor)]) {
571
+ if (cursor == [NSCursor resizeLeftCursor]) {
572
+ return @"col-resize";
573
+ }
574
+ }
575
+ if ([NSCursor respondsToSelector:@selector(resizeRightCursor)]) {
576
+ if (cursor == [NSCursor resizeRightCursor]) {
577
+ return @"col-resize";
578
+ }
513
579
  }
580
+ if ([NSCursor respondsToSelector:@selector(resizeUpDownCursor)]) {
581
+ if (cursor == [NSCursor resizeUpDownCursor]) {
582
+ return @"ns-resize";
583
+ }
584
+ }
585
+ if ([NSCursor respondsToSelector:@selector(resizeUpCursor)]) {
586
+ if (cursor == [NSCursor resizeUpCursor]) {
587
+ return @"ns-resize";
588
+ }
589
+ }
590
+ if ([NSCursor respondsToSelector:@selector(resizeDownCursor)]) {
591
+ if (cursor == [NSCursor resizeDownCursor]) {
592
+ return @"ns-resize";
593
+ }
594
+ }
595
+
514
596
  if ([NSCursor respondsToSelector:@selector(disappearingItemCursor)] &&
515
597
  cursor == [NSCursor disappearingItemCursor]) {
516
598
  return @"default";
517
599
  }
518
600
 
519
- NSString *derived = cursorTypeFromCursorName(NSStringFromClass([cursor class]));
601
+ // Try to get class name and description for debugging
602
+ NSString *className = NSStringFromClass([cursor class]);
603
+ NSString *description = [cursor description];
604
+
605
+ MRLog(@"🔍 Unknown cursor class: %@, description: %@", className ?: @"nil", description ?: @"nil");
606
+
607
+ // Try name-based detection
608
+ NSString *derived = cursorTypeFromCursorName(className);
520
609
  if (derived) {
610
+ MRLog(@"🎯 Cursor type from class name: %@", derived);
521
611
  return derived;
522
612
  }
523
613
 
524
- derived = cursorTypeFromCursorName([cursor description]);
614
+ derived = cursorTypeFromCursorName(description);
525
615
  if (derived) {
616
+ MRLog(@"🎯 Cursor type from description: %@", derived);
526
617
  return derived;
527
618
  }
528
619
 
529
- return nil;
620
+ // Default fallback
621
+ MRLog(@"⚠️ Unknown cursor type, defaulting to 'default'");
622
+ return @"default";
530
623
  }
531
624
 
532
625
  static NSString* detectSystemCursorType(void) {
@@ -534,21 +627,67 @@ static NSString* detectSystemCursorType(void) {
534
627
 
535
628
  void (^fetchCursorBlock)(void) = ^{
536
629
  NSCursor *currentCursor = nil;
630
+
631
+ // Try different methods to get current cursor
537
632
  if ([NSCursor respondsToSelector:@selector(currentSystemCursor)]) {
538
633
  currentCursor = [NSCursor currentSystemCursor];
634
+ NSLog(@"🖱️ currentSystemCursor: %@", currentCursor ?: @"nil");
539
635
  }
636
+
540
637
  if (!currentCursor) {
541
638
  currentCursor = [NSCursor currentCursor];
639
+ NSLog(@"🖱️ currentCursor: %@", currentCursor ?: @"nil");
542
640
  }
543
641
 
544
- NSString *derivedType = cursorTypeFromNSCursor(currentCursor);
545
- if (derivedType) {
546
- cursorType = derivedType;
547
- } else if (currentCursor) {
642
+ if (currentCursor) {
643
+ NSString *className = NSStringFromClass([currentCursor class]);
644
+ NSString *description = [currentCursor description];
645
+ NSLog(@"🖱️ Cursor class: %@, description: %@", className ?: @"nil", description ?: @"nil");
646
+
647
+ // Use more direct cursor detection approach
648
+ NSImage *cursorImage = [currentCursor image];
649
+ NSPoint hotspot = [currentCursor hotSpot];
650
+ NSSize imageSize = [cursorImage size];
651
+
652
+ NSLog(@"🎯 Cursor analysis: size=%.1fx%.1f, hotspot=(%.1f,%.1f)",
653
+ imageSize.width, imageSize.height, hotspot.x, hotspot.y);
654
+
655
+ // Updated pattern recognition based on observed values
656
+ if (imageSize.width >= 8.0 && imageSize.width <= 12.0 &&
657
+ imageSize.height >= 16.0 && imageSize.height <= 20.0 &&
658
+ hotspot.x >= 3.0 && hotspot.x <= 5.0 && hotspot.y >= 8.0 && hotspot.y <= 10.0) {
659
+ // I-beam cursor: narrow and tall, hotspot in middle
660
+ cursorType = @"text";
661
+ NSLog(@"🎯 DETECTED IBEAM CURSOR -> text");
662
+ }
663
+ else if (imageSize.width <= 20.0 && imageSize.height <= 25.0 &&
664
+ hotspot.x <= 5.0 && hotspot.y <= 5.0) {
665
+ // Arrow cursor: small size, hotspot at top-left
666
+ cursorType = @"default";
667
+ NSLog(@"🎯 DETECTED ARROW CURSOR -> default");
668
+ }
669
+ else if (imageSize.width >= 15.0 && imageSize.width <= 25.0 &&
670
+ imageSize.height >= 15.0 && imageSize.height <= 25.0 &&
671
+ hotspot.x >= 5.0 && hotspot.x <= 10.0 && hotspot.y <= 8.0) {
672
+ // Hand cursor: squarish, hotspot at fingertip
673
+ cursorType = @"pointer";
674
+ NSLog(@"🎯 DETECTED HAND CURSOR -> pointer");
675
+ }
676
+ else {
677
+ // Try to use a different approach - cursor name introspection
678
+ NSString *derived = cursorTypeFromNSCursor(currentCursor);
679
+ if (derived && ![derived isEqualToString:@"default"]) {
680
+ cursorType = derived;
681
+ NSLog(@"🎯 DERIVED FROM ANALYSIS: %@", cursorType);
682
+ } else {
683
+ cursorType = @"default";
684
+ NSLog(@"🎯 FALLBACK TO DEFAULT (will check AX)");
685
+ }
686
+ }
687
+ } else {
688
+ NSLog(@"🖱️ No current cursor found");
548
689
  cursorType = @"default";
549
690
  }
550
-
551
- MRLog(@"🎯 SYSTEM CURSOR TYPE: %@", cursorType ? cursorType : @"(nil)");
552
691
  };
553
692
 
554
693
  if ([NSThread isMainThread]) {
@@ -564,7 +703,7 @@ NSString* getCursorType() {
564
703
  @autoreleasepool {
565
704
  g_cursorTypeCounter++;
566
705
 
567
- // Hybrid: AX (strict) first, then system cursor fallback.
706
+ // Get cursor position first
568
707
  BOOL hasCursorPosition = NO;
569
708
  CGPoint cursorPos = CGPointZero;
570
709
 
@@ -589,25 +728,45 @@ NSString* getCursorType() {
589
728
  }
590
729
  }
591
730
 
731
+ // Try multiple detection methods
732
+ NSString *systemCursorType = detectSystemCursorType();
592
733
  NSString *axCursorType = nil;
734
+
593
735
  if (hasCursorPosition) {
594
736
  axCursorType = detectCursorTypeUsingAccessibility(cursorPos);
595
737
  }
596
738
 
597
- NSString *systemCursorType = detectSystemCursorType();
739
+ NSString *finalType = @"default";
598
740
 
599
- NSString *finalType = nil;
600
- if (axCursorType && ![axCursorType isEqualToString:@"default"]) {
741
+ // Smart decision logic: AX for special cases, system for normal cases
742
+ NSLog(@"🎯 CURSOR DECISION: system='%@', ax='%@'", systemCursorType ?: @"nil", axCursorType ?: @"nil");
743
+
744
+ // If system cursor detected something specific (not default), use it
745
+ if (systemCursorType && [systemCursorType length] > 0 && ![systemCursorType isEqualToString:@"default"]) {
746
+ finalType = systemCursorType;
747
+ NSLog(@"🎯 Using SYSTEM cursor (specific): %@", finalType);
748
+ }
749
+ // If AX detected something specific and system is default, use AX
750
+ else if (axCursorType && [axCursorType length] > 0 && ![axCursorType isEqualToString:@"default"] &&
751
+ (!systemCursorType || [systemCursorType isEqualToString:@"default"])) {
601
752
  finalType = axCursorType;
602
- } else if (systemCursorType && [systemCursorType length] > 0) {
753
+ NSLog(@"🎯 Using AX cursor (specific over default): %@", finalType);
754
+ }
755
+ // Otherwise use system cursor (including default)
756
+ else if (systemCursorType && [systemCursorType length] > 0) {
603
757
  finalType = systemCursorType;
604
- } else if (axCursorType && [axCursorType length] > 0) {
758
+ NSLog(@"🎯 Using SYSTEM cursor: %@", finalType);
759
+ }
760
+ // Final fallback to AX or default
761
+ else if (axCursorType && [axCursorType length] > 0) {
605
762
  finalType = axCursorType;
606
- } else {
607
- finalType = @"default";
763
+ NSLog(@"🎯 Using AX cursor (final fallback): %@", finalType);
764
+ }
765
+ else {
766
+ NSLog(@"🎯 Ultimate fallback to default");
608
767
  }
609
768
 
610
- MRLog(@"🎯 FINAL CURSOR TYPE: %@", finalType);
769
+ NSLog(@"🎯 FINAL CURSOR TYPE: %@", finalType);
611
770
  return finalType;
612
771
  }
613
772
  }