node-mac-recorder 2.17.20 → 2.17.21

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.
@@ -7,7 +7,9 @@
7
7
  "Bash(git checkout:*)",
8
8
  "WebSearch",
9
9
  "WebFetch(domain:stackoverflow.com)",
10
- "Bash(timeout:*)"
10
+ "Bash(timeout:*)",
11
+ "Bash(grep:*)",
12
+ "Bash(./test-cleanup.sh:*)"
11
13
  ],
12
14
  "deny": [],
13
15
  "ask": []
package/index.js CHANGED
@@ -647,11 +647,9 @@ class MacRecorder extends EventEmitter {
647
647
  */
648
648
  async startCursorCapture(intervalOrFilepath = 100, options = {}) {
649
649
  let filepath;
650
- let interval = 20; // Default 50 FPS
651
650
 
652
651
  // Parameter parsing: number = interval, string = filepath
653
652
  if (typeof intervalOrFilepath === "number") {
654
- interval = Math.max(10, intervalOrFilepath); // Min 10ms
655
653
  filepath = `cursor-data-${Date.now()}.json`;
656
654
  } else if (typeof intervalOrFilepath === "string") {
657
655
  filepath = intervalOrFilepath;
@@ -665,207 +663,28 @@ class MacRecorder extends EventEmitter {
665
663
  throw new Error("Cursor capture is already running");
666
664
  }
667
665
 
668
- // Koordinat sistemi belirle: window-relative, display-relative veya global
669
- if (options.windowRelative && options.windowInfo) {
670
- const windowInfo = options.windowInfo;
671
- const targetDisplay = windowInfo.targetDisplay || this.recordingDisplayInfo || null;
672
- const captureArea = windowInfo.captureArea || null;
673
- const hasNumber = (value) => typeof value === "number" && Number.isFinite(value);
674
-
675
- let globalX = hasNumber(windowInfo.x) ? windowInfo.x : null;
676
- let globalY = hasNumber(windowInfo.y) ? windowInfo.y : null;
677
-
678
- if (captureArea && targetDisplay) {
679
- if (!hasNumber(globalX) && hasNumber(captureArea.x) && hasNumber(targetDisplay.x)) {
680
- globalX = targetDisplay.x + captureArea.x;
681
- }
682
- if (!hasNumber(globalY) && hasNumber(captureArea.y) && hasNumber(targetDisplay.y)) {
683
- globalY = targetDisplay.y + captureArea.y;
684
- }
685
- }
686
-
687
- if (!hasNumber(globalX)) {
688
- if (captureArea && hasNumber(captureArea.x) && targetDisplay && hasNumber(targetDisplay.x)) {
689
- globalX = targetDisplay.x + captureArea.x;
690
- } else {
691
- globalX = hasNumber(captureArea?.x) ? captureArea.x : 0;
692
- }
693
- }
694
-
695
- if (!hasNumber(globalY)) {
696
- if (captureArea && hasNumber(captureArea.y) && targetDisplay && hasNumber(targetDisplay.y)) {
697
- globalY = targetDisplay.y + captureArea.y;
698
- } else {
699
- globalY = hasNumber(captureArea?.y) ? captureArea.y : 0;
700
- }
701
- }
702
-
703
- const displayOffsetX = captureArea && hasNumber(captureArea.x)
704
- ? captureArea.x
705
- : (targetDisplay && hasNumber(globalX) && hasNumber(targetDisplay.x)
706
- ? globalX - targetDisplay.x
707
- : globalX);
708
- const displayOffsetY = captureArea && hasNumber(captureArea.y)
709
- ? captureArea.y
710
- : (targetDisplay && hasNumber(globalY) && hasNumber(targetDisplay.y)
711
- ? globalY - targetDisplay.y
712
- : globalY);
713
-
714
- this.cursorDisplayInfo = {
715
- displayId:
716
- windowInfo.displayId ??
717
- targetDisplay?.displayId ??
718
- targetDisplay?.id ??
719
- null,
720
- x: globalX,
721
- y: globalY,
722
- width: windowInfo.width,
723
- height: windowInfo.height,
724
- windowRelative: true,
725
- windowInfo: {
726
- ...windowInfo,
727
- globalX,
728
- globalY,
729
- displayOffsetX,
730
- displayOffsetY
731
- },
732
- targetDisplay,
733
- captureArea
734
- };
735
- } else if (options.displayRelative && options.displayInfo) {
736
- // Display recording: Use display-relative coordinates
737
- this.cursorDisplayInfo = {
738
- displayId: options.displayInfo.displayId,
739
- x: options.displayInfo.x,
740
- y: options.displayInfo.y,
741
- width: options.displayInfo.width,
742
- height: options.displayInfo.height,
743
- displayRelative: true
744
- };
745
- } else if (this.recordingDisplayInfo) {
746
- // Fallback: Use recording display info if available
747
- this.cursorDisplayInfo = this.recordingDisplayInfo;
748
- } else {
749
- // Final fallback: Main display global coordinates
750
- try {
751
- const displays = await this.getDisplays();
752
- const mainDisplay = displays.find((d) => d.isPrimary) || displays[0];
753
- if (mainDisplay) {
754
- this.cursorDisplayInfo = {
755
- displayId: mainDisplay.id,
756
- x: mainDisplay.x,
757
- y: mainDisplay.y,
758
- width: parseInt(mainDisplay.resolution.split("x")[0]),
759
- height: parseInt(mainDisplay.resolution.split("x")[1]),
760
- };
761
- }
762
- } catch (error) {
763
- console.warn("Main display bilgisi alınamadı:", error.message);
764
- this.cursorDisplayInfo = null; // Fallback: global koordinatlar
765
- }
766
- }
767
-
768
666
  return new Promise((resolve, reject) => {
769
667
  try {
770
- // Dosyayı oluştur ve temizle
771
- const fs = require("fs");
772
- fs.writeFileSync(filepath, "[");
773
-
774
- this.cursorCaptureFile = filepath;
775
- this.cursorCaptureStartTime = Date.now();
776
- this.cursorCaptureFirstWrite = true;
777
- this.lastCapturedData = null;
778
-
779
- // JavaScript interval ile polling yap (daha sık - mouse event'leri yakalamak iƧin)
780
- this.cursorCaptureInterval = setInterval(() => {
781
- try {
782
- const position = nativeBinding.getCursorPosition();
783
- const timestamp = Date.now() - this.cursorCaptureStartTime;
784
-
785
- // Transform coordinates based on recording type
786
- let x = position.x;
787
- let y = position.y;
788
- let coordinateSystem = "global";
789
-
790
- if (this.cursorDisplayInfo) {
791
- if (this.cursorDisplayInfo.windowRelative) {
792
- // Window recording: Use direct global-to-window transformation
793
- // This works correctly for both primary and secondary displays
794
- x = position.x - this.cursorDisplayInfo.x;
795
- y = position.y - this.cursorDisplayInfo.y;
796
-
797
- coordinateSystem = "window-relative";
798
-
799
- // Window bounds check - skip if cursor is outside window
800
- if (x < 0 || y < 0 || x >= this.cursorDisplayInfo.width || y >= this.cursorDisplayInfo.height) {
801
- return; // Skip frame - cursor outside window
802
- }
803
- } else if (this.cursorDisplayInfo.displayRelative) {
804
- // Display recording: Transform global → display-relative coordinates
805
- x = position.x - this.cursorDisplayInfo.x;
806
- y = position.y - this.cursorDisplayInfo.y;
807
- coordinateSystem = "display-relative";
808
-
809
- // Display bounds check - skip if cursor is outside display
810
- if (x < 0 || y < 0 || x >= this.cursorDisplayInfo.width || y >= this.cursorDisplayInfo.height) {
811
- return; // Skip frame - cursor outside display
812
- }
813
- } else {
814
- // Legacy fallback: Use global coordinates with basic offset
815
- x = position.x - this.cursorDisplayInfo.x;
816
- y = position.y - this.cursorDisplayInfo.y;
817
- coordinateSystem = "display-relative";
818
- }
819
- }
820
-
821
- const cursorData = {
822
- x: x,
823
- y: y,
824
- timestamp: timestamp,
825
- unixTimeMs: Date.now(),
826
- cursorType: position.cursorType,
827
- type: position.eventType || "move",
828
- coordinateSystem: coordinateSystem,
829
- // Include recording context for window-relative coordinates
830
- ...(this.cursorDisplayInfo?.windowRelative && {
831
- windowInfo: {
832
- width: this.cursorDisplayInfo.width,
833
- height: this.cursorDisplayInfo.height,
834
- displayId: this.cursorDisplayInfo.displayId
835
- }
836
- }),
837
- // Include display context for display-relative coordinates
838
- ...(this.cursorDisplayInfo?.displayRelative && {
839
- displayInfo: {
840
- displayId: this.cursorDisplayInfo.displayId,
841
- width: this.cursorDisplayInfo.width,
842
- height: this.cursorDisplayInfo.height
843
- }
844
- })
845
- };
668
+ // Native cursor tracking kullan - hem screen hem window iƧin aynı yƶntem
669
+ const success = nativeBinding.startCursorTracking(filepath);
846
670
 
847
- // Sadece eventType değiştiğinde veya pozisyon değiştiğinde kaydet
848
- if (this.shouldCaptureEvent(cursorData)) {
849
- // Dosyaya ekle
850
- const jsonString = JSON.stringify(cursorData);
851
-
852
- if (this.cursorCaptureFirstWrite) {
853
- fs.appendFileSync(filepath, jsonString);
854
- this.cursorCaptureFirstWrite = false;
855
- } else {
856
- fs.appendFileSync(filepath, "," + jsonString);
857
- }
671
+ if (success) {
672
+ this.cursorCaptureFile = filepath;
673
+ this.cursorCaptureStartTime = Date.now();
674
+ this.cursorCaptureInterval = true; // Mark as active
858
675
 
859
- // Son pozisyonu sakla
860
- this.lastCapturedData = { ...cursorData };
861
- }
862
- } catch (error) {
863
- console.error("Cursor capture error:", error);
864
- }
865
- }, interval); // Configurable FPS
676
+ this.emit("cursorCaptureStarted", {
677
+ filepath: filepath,
678
+ timestamp: Date.now()
679
+ });
866
680
 
867
- this.emit("cursorCaptureStarted", filepath);
868
- resolve(true);
681
+ resolve({
682
+ filepath: filepath,
683
+ started: true
684
+ });
685
+ } else {
686
+ reject(new Error("Failed to start native cursor tracking"));
687
+ }
869
688
  } catch (error) {
870
689
  reject(error);
871
690
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.17.20",
3
+ "version": "2.17.21",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
package/publish.sh CHANGED
@@ -26,6 +26,24 @@ if ! git rev-parse --git-dir > /dev/null 2>&1; then
26
26
  exit 1
27
27
  fi
28
28
 
29
+ # Clean up test files and video files before publishing
30
+ echo "🧹 Cleaning up test files and video files..."
31
+
32
+ # Remove video files (MP4, MOV, AVI, etc.)
33
+ find . -maxdepth 1 -type f \( -name "*.mp4" -o -name "*.mov" -o -name "*.avi" -o -name "*.mkv" -o -name "*.webm" \) -delete
34
+
35
+ # Remove test output directories
36
+ rm -rf test-output debug-output
37
+
38
+ # Remove test files and temporary files
39
+ find . -maxdepth 1 -type f \( -name "*test*.json" -o -name "*debug*.json" -o -name "*cursor*.json" -o -name "temp-*" -o -name "*-temp.*" -o -name "*.tmp" \) -delete
40
+
41
+ # Remove test JavaScript files that shouldn't be published
42
+ find . -maxdepth 1 -type f -name "*test*.js" ! -name "test.js" -delete
43
+ find . -maxdepth 1 -type f -name "*debug*.js" -delete
44
+
45
+ echo "āœ… Cleanup completed"
46
+
29
47
  # Check if there are uncommitted changes
30
48
  if ! git diff --quiet || ! git diff --cached --quiet; then
31
49
  echo "šŸ“ Adding all changes to git..."
@@ -13,7 +13,7 @@ static CFMachPortRef g_eventTap = NULL;
13
13
  static CFRunLoopSourceRef g_runLoopSource = NULL;
14
14
  static NSDate *g_trackingStartTime = nil;
15
15
  static NSString *g_outputPath = nil;
16
- static NSTimer *g_cursorTimer = nil;
16
+ static dispatch_source_t g_cursorTimer = nil;
17
17
  static int g_debugCallbackCount = 0;
18
18
  static NSFileHandle *g_fileHandle = nil;
19
19
  static bool g_isFirstWrite = true;
@@ -623,8 +623,16 @@ CGEventRef eventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef eve
623
623
  void cursorTimerCallback() {
624
624
  @autoreleasepool {
625
625
  g_debugCallbackCount++; // Timer callback Ƨağrıldığını say
626
-
626
+
627
+ static int callCount = 0;
628
+ callCount++;
629
+ if (callCount <= 3) {
630
+ NSLog(@"šŸ”„ Timer callback #%d called", callCount);
631
+ }
632
+
627
633
  if (!g_isCursorTracking || !g_trackingStartTime || !g_fileHandle) {
634
+ NSLog(@"āŒ Timer callback stopped - tracking:%d, startTime:%@, fileHandle:%@",
635
+ g_isCursorTracking, g_trackingStartTime ? @"OK" : @"nil", g_fileHandle ? @"OK" : @"nil");
628
636
  return;
629
637
  }
630
638
 
@@ -673,16 +681,14 @@ void cursorTimerCallback() {
673
681
  void cleanupCursorTracking() {
674
682
  g_isCursorTracking = false;
675
683
 
676
- // Timer temizle
684
+ // GCD Timer temizle
677
685
  if (g_cursorTimer) {
678
- [g_cursorTimer invalidate];
686
+ dispatch_source_cancel(g_cursorTimer);
687
+ dispatch_release(g_cursorTimer);
679
688
  g_cursorTimer = nil;
680
689
  }
681
690
 
682
- if (g_timerTarget) {
683
- [g_timerTarget autorelease];
684
- g_timerTarget = nil;
685
- }
691
+ // Timer target artık kullanılmıyor (GCD kullanıyoruz)
686
692
 
687
693
  // Dosyayı ƶnce kapat (en ƶnemli işlem)
688
694
  if (g_fileHandle) {
@@ -788,19 +794,30 @@ Napi::Value StartCursorTracking(const Napi::CallbackInfo& info) {
788
794
  CGEventTapEnable(g_eventTap, true);
789
795
  }
790
796
 
791
- // NSTimer kullan (main thread'de çalışır)
792
- g_timerTarget = [[CursorTimerTarget alloc] init];
793
-
794
- g_cursorTimer = [NSTimer timerWithTimeInterval:0.05 // 50ms (20 FPS)
795
- target:g_timerTarget
796
- selector:@selector(timerCallback:)
797
- userInfo:nil
798
- repeats:YES];
799
-
800
- // Main run loop'a ekle
801
- [[NSRunLoop mainRunLoop] addTimer:g_cursorTimer forMode:NSRunLoopCommonModes];
802
-
797
+ // GCD Timer kullan (Node.js ile uyumlu)
798
+ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
799
+ g_cursorTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
800
+
801
+ if (g_cursorTimer) {
802
+ dispatch_source_set_timer(g_cursorTimer,
803
+ dispatch_time(DISPATCH_TIME_NOW, 50 * NSEC_PER_MSEC), // Start after 50ms
804
+ 50 * NSEC_PER_MSEC, // Repeat every 50ms (20 FPS)
805
+ 10 * NSEC_PER_MSEC); // Leeway of 10ms
806
+
807
+ dispatch_source_set_event_handler(g_cursorTimer, ^{
808
+ cursorTimerCallback();
809
+ });
810
+
811
+ dispatch_resume(g_cursorTimer);
812
+ }
813
+
803
814
  g_isCursorTracking = true;
815
+
816
+ NSLog(@"šŸŽÆ Native cursor tracking started with timer and event tap");
817
+ NSLog(@"šŸŽÆ File handle: %@", g_fileHandle ? @"OK" : @"FAILED");
818
+ NSLog(@"šŸŽÆ Timer: %@", g_cursorTimer ? @"OK" : @"FAILED");
819
+ NSLog(@"šŸŽÆ Event tap: %@", g_eventTap ? @"OK" : @"FAILED");
820
+
804
821
  return Napi::Boolean::New(env, true);
805
822
 
806
823
  } @catch (NSException *exception) {
@@ -1,60 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- console.log('šŸ” Debugging cursor coordinate scaling issue...\n');
4
-
5
- const recorder = new MacRecorder();
6
-
7
- async function testCursorScaling() {
8
- console.log('Getting display info...');
9
- const displays = await recorder.getDisplays();
10
-
11
- displays.forEach((display, index) => {
12
- console.log(`Display ${index}:`);
13
- console.log(` Resolution: ${display.resolution}`);
14
- console.log(` Position: (${display.x}, ${display.y})`);
15
- console.log(` Primary: ${display.isPrimary}`);
16
- console.log(` ID: ${display.id}`);
17
- });
18
-
19
- console.log('\nšŸŽÆ Please move your mouse to different corners and press Enter...');
20
- console.log('This will help us understand the coordinate mapping issue.\n');
21
-
22
- const readline = require('readline');
23
- const rl = readline.createInterface({
24
- input: process.stdin,
25
- output: process.stdout
26
- });
27
-
28
- let testCount = 0;
29
- const testPositions = [
30
- 'Top-Left corner of the display',
31
- 'Top-Right corner of the display',
32
- 'Bottom-Left corner of the display',
33
- 'Bottom-Right corner of the display',
34
- 'Center of the display'
35
- ];
36
-
37
- function nextTest() {
38
- if (testCount >= testPositions.length) {
39
- console.log('\nāœ… Test completed!');
40
- rl.close();
41
- process.exit(0);
42
- return;
43
- }
44
-
45
- console.log(`\nšŸ“ Test ${testCount + 1}: Move mouse to ${testPositions[testCount]} and press Enter:`);
46
- rl.question('', () => {
47
- const position = recorder.getCursorPosition();
48
- console.log(` Raw cursor position: (${position.rawX || 'N/A'}, ${position.rawY || 'N/A'})`);
49
- console.log(` Logical cursor position: (${position.x}, ${position.y})`);
50
- console.log(` Scale factor: ${position.scaleFactor || 'N/A'}x`);
51
-
52
- testCount++;
53
- nextTest();
54
- });
55
- }
56
-
57
- nextTest();
58
- }
59
-
60
- testCursorScaling().catch(console.error);
@@ -1,73 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- console.log('🧪 Testing cursor DPR scaling fixes...\n');
4
-
5
- const recorder = new MacRecorder();
6
-
7
- // Test basic cursor position
8
- console.log('1. Testing basic cursor position:');
9
- try {
10
- const position = recorder.getCursorPosition();
11
- console.log(` Position: (${position.x}, ${position.y})`);
12
-
13
- // If we have scaling debug info, show it
14
- if (position.scaleFactor) {
15
- console.log(` Scale factor: ${position.scaleFactor}x`);
16
- console.log(` Raw position: (${position.rawX}, ${position.rawY})`);
17
- console.log(` Logical position: (${position.x}, ${position.y})`);
18
- }
19
- } catch (error) {
20
- console.error(' Error:', error.message);
21
- }
22
-
23
- console.log('\n2. Testing display information:');
24
- recorder.getDisplays().then(displays => {
25
- displays.forEach((display, index) => {
26
- console.log(` Display ${index}: ${display.resolution} at (${display.x}, ${display.y})`);
27
- console.log(` Primary: ${display.isPrimary}, ID: ${display.id}`);
28
- });
29
-
30
- console.log('\n3. Testing cursor capture with DPR fix:');
31
- const outputFile = 'cursor-dpr-test.json';
32
-
33
- recorder.startCursorCapture(outputFile, 50).then(() => {
34
- console.log(` āœ… Cursor capture started, saving to ${outputFile}`);
35
- console.log(' Move your mouse around for 5 seconds...');
36
-
37
- setTimeout(() => {
38
- recorder.stopCursorCapture().then(() => {
39
- console.log(' āœ… Cursor capture stopped');
40
-
41
- // Read and analyze the captured data
42
- const fs = require('fs');
43
- try {
44
- const data = JSON.parse(fs.readFileSync(outputFile, 'utf8'));
45
- if (data.length > 0) {
46
- const first = data[0];
47
- const last = data[data.length - 1];
48
-
49
- console.log(` šŸ“Š Captured ${data.length} cursor events`);
50
- console.log(` šŸ“ First: (${first.x}, ${first.y}) ${first.coordinateSystem || 'unknown'}`);
51
- console.log(` šŸ“ Last: (${last.x}, ${last.y}) ${last.coordinateSystem || 'unknown'}`);
52
-
53
- // Check coordinate system
54
- const hasCoordinateSystem = data.some(d => d.coordinateSystem);
55
- console.log(` šŸŽÆ Coordinate system info: ${hasCoordinateSystem ? 'Present' : 'Missing'}`);
56
- } else {
57
- console.log(' āš ļø No cursor events captured');
58
- }
59
- } catch (readError) {
60
- console.error(' āŒ Error reading capture file:', readError.message);
61
- }
62
-
63
- process.exit(0);
64
- });
65
- }, 5000);
66
- }).catch(error => {
67
- console.error(' āŒ Cursor capture failed:', error.message);
68
- process.exit(1);
69
- });
70
- }).catch(error => {
71
- console.error(' Error getting displays:', error.message);
72
- process.exit(1);
73
- });
@@ -1 +0,0 @@
1
- []
@@ -1,63 +0,0 @@
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);
@@ -1,46 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- async function testCursorPermissions() {
4
- console.log('šŸ”’ Testing cursor tracking permissions...\n');
5
-
6
- const recorder = new MacRecorder();
7
-
8
- // Check permissions first
9
- console.log('1. Checking permissions:');
10
- const permissions = await recorder.checkPermissions();
11
- console.log(' Screen Recording:', permissions.screenRecording ? 'āœ…' : 'āŒ');
12
- console.log(' Accessibility:', permissions.accessibility ? 'āœ…' : 'āŒ');
13
- console.log(' Microphone:', permissions.microphone ? 'āœ…' : 'āŒ');
14
-
15
- if (permissions.error) {
16
- console.log(' Error:', permissions.error);
17
- }
18
-
19
- console.log('\n2. Testing direct cursor position (no capture):');
20
- for (let i = 0; i < 5; i++) {
21
- try {
22
- const position = recorder.getCursorPosition();
23
- console.log(` Position ${i+1}: (${position.x}, ${position.y}) - ${position.cursorType}`);
24
-
25
- if (position.scaleFactor) {
26
- console.log(` Scale: ${position.scaleFactor}x, Display: (${position.displayInfo?.displayX}, ${position.displayInfo?.displayY})`);
27
- console.log(` Logical: ${position.displayInfo?.logicalWidth}x${position.displayInfo?.logicalHeight}`);
28
- console.log(` Physical: ${position.displayInfo?.physicalWidth}x${position.displayInfo?.physicalHeight}`);
29
- }
30
-
31
- await new Promise(resolve => setTimeout(resolve, 500));
32
- } catch (error) {
33
- console.error(` Error getting position ${i+1}:`, error.message);
34
- }
35
- }
36
-
37
- console.log('\n3. Testing cursor capture status:');
38
- const status = recorder.getCursorCaptureStatus();
39
- console.log(' Is Capturing:', status.isCapturing);
40
- console.log(' Output File:', status.outputFile);
41
- console.log(' Display Info:', status.displayInfo);
42
-
43
- process.exit(0);
44
- }
45
-
46
- testCursorPermissions().catch(console.error);
@@ -1,53 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- async function debugCursorScaling() {
4
- console.log('šŸ” Debugging cursor scaling detection...\n');
5
-
6
- const recorder = new MacRecorder();
7
-
8
- // Get all displays
9
- const displays = await recorder.getDisplays();
10
- console.log('šŸ“ŗ Available displays:');
11
- displays.forEach((display, index) => {
12
- console.log(` Display ${index}: ID=${display.id}, ${display.resolution} at (${display.x}, ${display.y}), Primary: ${display.isPrimary}`);
13
- });
14
-
15
- console.log('\nšŸŽÆ Current cursor position analysis:');
16
- const position = recorder.getCursorPosition();
17
-
18
- console.log(` Logical position: (${position.x}, ${position.y})`);
19
- console.log(` Cursor type: ${position.cursorType}`);
20
- console.log(` Event type: ${position.eventType}`);
21
-
22
- if (position.scaleFactor) {
23
- console.log(` Scale factor detected: ${position.scaleFactor}x`);
24
- if (position.displayInfo) {
25
- const info = position.displayInfo;
26
- console.log(` Display bounds: (${info.displayX}, ${info.displayY})`);
27
- console.log(` Logical size: ${info.logicalWidth}x${info.logicalHeight}`);
28
- console.log(` Physical size: ${info.physicalWidth}x${info.physicalHeight}`);
29
- console.log(` Raw position: (${position.rawX}, ${position.rawY})`);
30
- }
31
- } else {
32
- console.log(` āŒ No scale factor detected`);
33
- console.log(` This could mean:`);
34
- console.log(` - getDisplayScalingInfo() didn't find the correct display`);
35
- console.log(` - Display detection logic needs debugging`);
36
- }
37
-
38
- // Find which display the cursor is on
39
- console.log('\nšŸ” Manual display detection:');
40
- displays.forEach((display, index) => {
41
- const inX = position.x >= display.x && position.x < display.x + parseInt(display.resolution.split('x')[0]);
42
- const inY = position.y >= display.y && position.y < display.y + parseInt(display.resolution.split('x')[1]);
43
- const isInside = inX && inY;
44
-
45
- console.log(` Display ${index} (${display.resolution}): ${isInside ? 'āœ… CURSOR IS HERE' : 'āŒ'}`);
46
- console.log(` Bounds: X(${display.x} - ${display.x + parseInt(display.resolution.split('x')[0])}), Y(${display.y} - ${display.y + parseInt(display.resolution.split('x')[1])})`);
47
- console.log(` Cursor: X(${position.x}), Y(${position.y})`);
48
- });
49
-
50
- process.exit(0);
51
- }
52
-
53
- debugCursorScaling().catch(console.error);