node-mac-recorder 2.17.19 โ†’ 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.
Files changed (41) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/index.js +21 -200
  3. package/package.json +1 -1
  4. package/publish.sh +18 -0
  5. package/src/cursor_tracker.mm +37 -20
  6. package/cursor-data-1751364226346.json +0 -1
  7. package/cursor-data-1751364314136.json +0 -1
  8. package/cursor-data.json +0 -1
  9. package/cursor-debug-test.js +0 -60
  10. package/cursor-dpr-test.js +0 -73
  11. package/cursor-dpr-test.json +0 -1
  12. package/cursor-macbook-test.js +0 -63
  13. package/cursor-permission-test.js +0 -46
  14. package/cursor-scaling-debug.js +0 -53
  15. package/cursor-simple-test.js +0 -26
  16. package/debug-audio.js +0 -79
  17. package/debug-coordinates.js +0 -69
  18. package/debug-cursor-output.json +0 -1
  19. package/debug-macos14.js +0 -110
  20. package/debug-primary-window.js +0 -84
  21. package/debug-screen-selection.js +0 -81
  22. package/debug-window-selector.js +0 -178
  23. package/examples/electron-integration-example.js +0 -230
  24. package/examples/electron-preload.js +0 -46
  25. package/examples/electron-renderer.html +0 -634
  26. package/examples/integration-example.js +0 -228
  27. package/examples/window-selector-example.js +0 -254
  28. package/quick-cursor-test.json +0 -1
  29. package/test-both-cursor.json +0 -1
  30. package/test-cursor-fix.js +0 -105
  31. package/test-cursor-types.js +0 -117
  32. package/test-display-coordinates.js +0 -72
  33. package/test-integrated-recording.js +0 -120
  34. package/test-menubar-offset.js +0 -110
  35. package/test-output/primary-fix-test-1758266910543.json +0 -1
  36. package/test-output/unified-cursor-1758313640878.json +0 -1
  37. package/test-output/unified-cursor-1758313689471.json +0 -1
  38. package/test-primary-cursor.js +0 -154
  39. package/test-primary-fix.js +0 -120
  40. package/test-unified-cursor.js +0 -75
  41. package/test-window-recording.js +0 -149
@@ -1,117 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- async function testCursorTypes() {
4
- console.log('๐Ÿงช Testing improved cursor type detection...');
5
-
6
- const recorder = new MacRecorder();
7
-
8
- try {
9
- // Test basic cursor position and type detection
10
- console.log('\n๐Ÿ“ Current cursor state:');
11
- const cursorPos = recorder.getCursorPosition();
12
- console.log(` Position: (${cursorPos.x}, ${cursorPos.y})`);
13
- console.log(` Type: ${cursorPos.cursorType}`);
14
- console.log(` Event: ${cursorPos.eventType}`);
15
-
16
- console.log('\n๐Ÿ–ฑ๏ธ Starting continuous cursor type monitoring...');
17
- console.log('๐Ÿ“‹ Instructions:');
18
- console.log(' 1. Move mouse over different UI elements');
19
- console.log(' 2. Hover over buttons, text fields, links, window borders');
20
- console.log(' 3. Try resize handles on windows');
21
- console.log(' 4. Move over different applications');
22
- console.log(' 5. Test will run for 15 seconds');
23
-
24
- const cursorData = [];
25
- let lastReportedType = null;
26
- let typeChangeCount = 0;
27
-
28
- const startTime = Date.now();
29
- const testDuration = 15000; // 15 seconds
30
-
31
- // Continuous monitoring
32
- const monitor = setInterval(() => {
33
- const pos = recorder.getCursorPosition();
34
- const currentType = pos.cursorType;
35
-
36
- // Record all data for analysis
37
- cursorData.push({
38
- timestamp: Date.now() - startTime,
39
- x: pos.x,
40
- y: pos.y,
41
- type: currentType,
42
- event: pos.eventType
43
- });
44
-
45
- // Report type changes immediately
46
- if (currentType !== lastReportedType) {
47
- const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
48
- console.log(` [${elapsed}s] Cursor changed: ${lastReportedType || 'unknown'} โ†’ ${currentType} at (${pos.x}, ${pos.y})`);
49
- lastReportedType = currentType;
50
- typeChangeCount++;
51
- }
52
- }, 50); // Check every 50ms for high responsiveness
53
-
54
- // Stop after test duration
55
- setTimeout(() => {
56
- clearInterval(monitor);
57
-
58
- console.log('\n๐Ÿ“Š Test Results:');
59
- console.log(` Total cursor events: ${cursorData.length}`);
60
- console.log(` Cursor type changes: ${typeChangeCount}`);
61
- console.log(` Test duration: ${testDuration/1000} seconds`);
62
-
63
- // Analyze cursor types detected
64
- const typeDistribution = {};
65
- cursorData.forEach(data => {
66
- typeDistribution[data.type] = (typeDistribution[data.type] || 0) + 1;
67
- });
68
-
69
- console.log('\n๐ŸŽฏ Cursor types detected:');
70
- Object.entries(typeDistribution)
71
- .sort(([,a], [,b]) => b - a)
72
- .forEach(([type, count]) => {
73
- const percentage = ((count / cursorData.length) * 100).toFixed(1);
74
- console.log(` ${type}: ${count} times (${percentage}%)`);
75
- });
76
-
77
- // Responsiveness analysis
78
- const typeChanges = cursorData.filter((data, i) =>
79
- i === 0 || data.type !== cursorData[i-1].type
80
- );
81
-
82
- if (typeChanges.length > 1) {
83
- console.log('\nโšก Responsiveness Analysis:');
84
- console.log(` First type change at: ${typeChanges[1].timestamp}ms`);
85
- console.log(` Last type change at: ${typeChanges[typeChanges.length-1].timestamp}ms`);
86
- console.log(` Average detection frequency: ${(cursorData.length / (testDuration/1000)).toFixed(1)} checks/sec`);
87
-
88
- if (typeChangeCount > 0) {
89
- console.log('โœ… Cursor type detection is working and responsive!');
90
- } else {
91
- console.log('โš ๏ธ No cursor type changes detected - try moving over different UI elements');
92
- }
93
- }
94
-
95
- // Save detailed log for analysis
96
- const fs = require('fs');
97
- const logFile = `./test-output/cursor-types-test-${Date.now()}.json`;
98
- fs.writeFileSync(logFile, JSON.stringify({
99
- summary: {
100
- totalEvents: cursorData.length,
101
- typeChanges: typeChangeCount,
102
- duration: testDuration,
103
- typeDistribution
104
- },
105
- events: cursorData
106
- }, null, 2));
107
-
108
- console.log(`\n๐Ÿ’พ Detailed log saved to: ${logFile}`);
109
-
110
- }, testDuration);
111
-
112
- } catch (error) {
113
- console.error('โŒ Test failed:', error.message);
114
- }
115
- }
116
-
117
- testCursorTypes().catch(console.error);
@@ -1,72 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- async function testDisplayCoordinates() {
4
- console.log('๐Ÿงช Testing cursor coordinate behavior across displays...');
5
-
6
- const recorder = new MacRecorder();
7
-
8
- try {
9
- const displays = await recorder.getDisplays();
10
-
11
- console.log('\n๐Ÿ“ฑ Display information:');
12
- displays.forEach((display, i) => {
13
- const type = display.isPrimary ? 'PRIMARY' : 'SECONDARY';
14
- console.log(` ${type} Display ${display.id}: ${display.resolution} at (${display.x}, ${display.y})`);
15
- });
16
-
17
- console.log('\n๐Ÿ–ฑ๏ธ Real-time cursor position test:');
18
- console.log('Move your mouse to different displays and observe coordinates...');
19
- console.log('Press Ctrl+C to stop\n');
20
-
21
- let lastDisplay = null;
22
- const interval = setInterval(() => {
23
- const pos = recorder.getCursorPosition();
24
-
25
- // Determine which display cursor is on
26
- let currentDisplay = null;
27
- for (const display of displays) {
28
- if (pos.x >= display.x &&
29
- pos.x < display.x + display.width &&
30
- pos.y >= display.y &&
31
- pos.y < display.y + display.height) {
32
- currentDisplay = display;
33
- break;
34
- }
35
- }
36
-
37
- if (currentDisplay && currentDisplay.id !== lastDisplay?.id) {
38
- const type = currentDisplay.isPrimary ? 'PRIMARY' : 'SECONDARY';
39
- console.log(`\n๐Ÿ“ Moved to ${type} Display ${currentDisplay.id}:`);
40
- console.log(` Display bounds: (${currentDisplay.x}, ${currentDisplay.y}) to (${currentDisplay.x + currentDisplay.width}, ${currentDisplay.y + currentDisplay.height})`);
41
- lastDisplay = currentDisplay;
42
- }
43
-
44
- if (currentDisplay) {
45
- // Calculate display-relative coordinates
46
- const displayRelativeX = pos.x - currentDisplay.x;
47
- const displayRelativeY = pos.y - currentDisplay.y;
48
-
49
- const type = currentDisplay.isPrimary ? 'PRI' : 'SEC';
50
- console.log(`${type} | Global: (${pos.x}, ${pos.y}) | Display-rel: (${displayRelativeX}, ${displayRelativeY})`);
51
- } else {
52
- console.log(`??? | Global: (${pos.x}, ${pos.y}) | Not on any display`);
53
- }
54
- }, 200); // Every 200ms
55
-
56
- // Handle Ctrl+C
57
- process.on('SIGINT', () => {
58
- clearInterval(interval);
59
- console.log('\n\n๐Ÿ” Test completed. Look for any unusual patterns in the coordinates.');
60
- console.log('\nKey things to check:');
61
- console.log('1. Do global coordinates look correct on both displays?');
62
- console.log('2. Do display-relative coordinates start from (0,0) on each display?');
63
- console.log('3. Are there any unexpected offsets on the primary display?');
64
- process.exit(0);
65
- });
66
-
67
- } catch (error) {
68
- console.error('โŒ Test failed:', error.message);
69
- }
70
- }
71
-
72
- testDisplayCoordinates().catch(console.error);
@@ -1,120 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const MacRecorder = require('./index.js');
4
- const path = require('path');
5
- const fs = require('fs');
6
-
7
- // Test output directory
8
- const outputDir = './test-output';
9
- if (!fs.existsSync(outputDir)) {
10
- fs.mkdirSync(outputDir, { recursive: true });
11
- }
12
-
13
- const recorder = new MacRecorder();
14
-
15
- async function testIntegratedRecording() {
16
- console.log('๐ŸŽฌ Testing integrated screen recording with automatic cursor tracking...');
17
-
18
- try {
19
- // Test permissions first
20
- const permissions = await recorder.checkPermissions();
21
- console.log('๐Ÿ“‹ Permissions:', permissions);
22
-
23
- if (!permissions.screenRecording) {
24
- console.log('โŒ Screen recording permission required');
25
- return;
26
- }
27
-
28
- // Get displays and windows
29
- const displays = await recorder.getDisplays();
30
- const windows = await recorder.getWindows();
31
-
32
- console.log(`๐Ÿ“บ Found ${displays.length} displays and ${windows.length} windows`);
33
-
34
- // Setup recording options
35
- const timestamp = Date.now();
36
- const videoPath = path.join(outputDir, `integrated-test-${timestamp}.mov`);
37
-
38
- console.log(`๐ŸŽฅ Starting recording to: ${videoPath}`);
39
- console.log('๐Ÿ“ Cursor tracking will start automatically and create a JSON file in the same directory');
40
-
41
- // Start recording (cursor tracking will start automatically)
42
- // Use the primary display (displayId: 1) where cursor is located
43
- await recorder.startRecording(videoPath, {
44
- includeMicrophone: false,
45
- includeSystemAudio: false,
46
- captureCursor: true,
47
- displayId: 1 // Use primary display where cursor is located
48
- });
49
-
50
- console.log('โœ… Recording started successfully!');
51
- console.log('๐Ÿ–ฑ๏ธ Cursor tracking started automatically');
52
- console.log('โฐ Recording for 5 seconds...');
53
- console.log('๐Ÿ’ก Move your mouse around to generate cursor data');
54
-
55
- // Wait for 5 seconds
56
- await new Promise(resolve => setTimeout(resolve, 5000));
57
-
58
- console.log('๐Ÿ›‘ Stopping recording...');
59
-
60
- // Stop recording (cursor tracking will stop automatically)
61
- const result = await recorder.stopRecording();
62
-
63
- console.log('โœ… Recording stopped:', result);
64
- console.log('๐Ÿ“ Checking output files...');
65
-
66
- // Wait a moment for files to be written
67
- await new Promise(resolve => setTimeout(resolve, 1000));
68
-
69
- // Check for video file
70
- if (fs.existsSync(videoPath)) {
71
- const videoStats = fs.statSync(videoPath);
72
- console.log(`๐Ÿ“น Video file created: ${videoPath} (${videoStats.size} bytes)`);
73
- } else {
74
- console.log('โŒ Video file not found');
75
- }
76
-
77
- // Check for cursor file
78
- const files = fs.readdirSync(outputDir);
79
- const cursorFile = files.find(f => f.startsWith('temp_cursor_') && f.endsWith('.json'));
80
-
81
- if (cursorFile) {
82
- const cursorPath = path.join(outputDir, cursorFile);
83
- const cursorStats = fs.statSync(cursorPath);
84
- console.log(`๐Ÿ–ฑ๏ธ Cursor file created: ${cursorFile} (${cursorStats.size} bytes)`);
85
-
86
- // Read and validate cursor data
87
- try {
88
- const cursorData = JSON.parse(fs.readFileSync(cursorPath, 'utf8'));
89
- console.log(`๐Ÿ“Š Cursor data points: ${cursorData.length}`);
90
-
91
- if (cursorData.length > 0) {
92
- const first = cursorData[0];
93
- const last = cursorData[cursorData.length - 1];
94
- console.log(`๐Ÿ“ First cursor position: (${first.x}, ${first.y}) at ${first.timestamp}ms`);
95
- console.log(`๐Ÿ“ Last cursor position: (${last.x}, ${last.y}) at ${last.timestamp}ms`);
96
- console.log(`๐Ÿ“ Coordinate system: ${first.coordinateSystem || 'global'}`);
97
- }
98
- } catch (parseError) {
99
- console.log('โš ๏ธ Could not parse cursor data:', parseError.message);
100
- }
101
- } else {
102
- console.log('โŒ Cursor file not found');
103
- }
104
-
105
- console.log('โœ… Test completed successfully!');
106
-
107
- } catch (error) {
108
- console.error('โŒ Test failed:', error.message);
109
- console.error(error.stack);
110
- }
111
- }
112
-
113
- // Run the test
114
- testIntegratedRecording().then(() => {
115
- console.log('๐Ÿ All tests finished');
116
- process.exit(0);
117
- }).catch(error => {
118
- console.error('๐Ÿ’ฅ Fatal error:', error);
119
- process.exit(1);
120
- });
@@ -1,110 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- async function testMenuBarOffset() {
4
- console.log('๐Ÿงช Testing macOS menu bar coordinate offset...');
5
-
6
- const recorder = new MacRecorder();
7
-
8
- try {
9
- const displays = await recorder.getDisplays();
10
- const windows = await recorder.getWindows();
11
-
12
- const primaryDisplay = displays.find(d => d.isPrimary);
13
-
14
- console.log('\n๐Ÿ“ฑ Primary Display Info:');
15
- console.log(` Bounds: (${primaryDisplay.x}, ${primaryDisplay.y}) ${primaryDisplay.width}x${primaryDisplay.height}`);
16
-
17
- // Get menu bar height by checking screen bounds vs usable bounds
18
- const { screen } = require('electron').screen || {};
19
-
20
- // Alternative way to get menu bar info using native macOS APIs
21
- console.log('\n๐Ÿ” Coordinate System Analysis:');
22
-
23
- // Find windows on primary display
24
- const primaryWindows = windows.filter(window => {
25
- const windowCenterX = window.x + window.width / 2;
26
- const windowCenterY = window.y + window.height / 2;
27
- return (windowCenterX >= primaryDisplay.x &&
28
- windowCenterX < primaryDisplay.x + primaryDisplay.width &&
29
- windowCenterY >= primaryDisplay.y &&
30
- windowCenterY < primaryDisplay.y + primaryDisplay.height);
31
- });
32
-
33
- console.log('\n๐ŸชŸ Windows on Primary Display:');
34
- primaryWindows.slice(0, 3).forEach((window, i) => {
35
- console.log(` ${i+1}. "${window.title}" at (${window.x}, ${window.y}) ${window.width}x${window.height}`);
36
-
37
- // Check if window Y starts suspiciously high (indicating menu bar offset)
38
- if (window.y > 20 && window.y < 100) {
39
- console.log(` โš ๏ธ Window Y=${window.y} suggests menu bar offset of ~${window.y}px`);
40
- }
41
- });
42
-
43
- // Test cursor coordinates at the very top of the screen
44
- console.log('\n๐Ÿ–ฑ๏ธ Move mouse to the very TOP of the primary screen and observe:');
45
- console.log('(This will help identify if menu bar affects coordinates)');
46
-
47
- for (let i = 0; i < 10; i++) {
48
- await new Promise(resolve => setTimeout(resolve, 500));
49
- const pos = recorder.getCursorPosition();
50
-
51
- if (pos.x >= primaryDisplay.x &&
52
- pos.x < primaryDisplay.x + primaryDisplay.width &&
53
- pos.y >= primaryDisplay.y &&
54
- pos.y < primaryDisplay.y + primaryDisplay.height) {
55
-
56
- console.log(` Test ${i+1}: Global (${pos.x}, ${pos.y}) | Y from top: ${pos.y - primaryDisplay.y}`);
57
-
58
- // If cursor Y is very close to 0 but not exactly 0, there might be menu bar offset
59
- if (pos.y >= primaryDisplay.y && pos.y <= primaryDisplay.y + 50) {
60
- const yFromTop = pos.y - primaryDisplay.y;
61
- if (yFromTop > 0 && yFromTop < 40) {
62
- console.log(` ๐ŸŽฏ Potential menu bar detected: ${yFromTop}px from top`);
63
- }
64
- }
65
- }
66
- }
67
-
68
- // Test with a specific window on primary display
69
- if (primaryWindows.length > 0) {
70
- const testWindow = primaryWindows[0];
71
-
72
- console.log(`\n๐Ÿงช Testing window coordinate transformation:`);
73
- console.log(` Window: "${testWindow.title}"`);
74
- console.log(` Global position: (${testWindow.x}, ${testWindow.y})`);
75
- console.log(` Display offset: (${testWindow.x - primaryDisplay.x}, ${testWindow.y - primaryDisplay.y})`);
76
-
77
- // Calculate what window-relative coordinates should be
78
- console.log(`\n๐Ÿ“Š Expected coordinate transformation:`);
79
- console.log(` If cursor at window's top-left (${testWindow.x}, ${testWindow.y}):`);
80
- console.log(` Should become window-relative: (0, 0)`);
81
- console.log(` Current transformation would give: (${testWindow.x - testWindow.x}, ${testWindow.y - testWindow.y})`);
82
-
83
- // Check if there's a Y offset issue
84
- const expectedZeroY = testWindow.y - testWindow.y; // Should be 0
85
- if (expectedZeroY !== 0) {
86
- console.log(` โŒ Y transformation issue detected!`);
87
- }
88
-
89
- // Now check what happens with display transformation
90
- const globalToDisplayX = testWindow.x - primaryDisplay.x;
91
- const globalToDisplayY = testWindow.y - primaryDisplay.y;
92
- const displayToWindowX = globalToDisplayX - (testWindow.x - primaryDisplay.x);
93
- const displayToWindowY = globalToDisplayY - (testWindow.y - primaryDisplay.y);
94
-
95
- console.log(`\n๐Ÿ”ง Two-step transformation analysis:`);
96
- console.log(` Step 1 - Global to display-relative: (${globalToDisplayX}, ${globalToDisplayY})`);
97
- console.log(` Step 2 - Display-relative to window-relative: (${displayToWindowX}, ${displayToWindowY})`);
98
-
99
- if (displayToWindowX !== 0 || displayToWindowY !== 0) {
100
- console.log(` โŒ Two-step transformation creates offset!`);
101
- console.log(` โœ… Should use direct transformation: global - window_global`);
102
- }
103
- }
104
-
105
- } catch (error) {
106
- console.error('โŒ Test failed:', error.message);
107
- }
108
- }
109
-
110
- testMenuBarOffset().catch(console.error);
@@ -1 +0,0 @@
1
- [{"x":702,"y":607,"timestamp":119,"unixTimeMs":1758313640997,"cursorType":"text","type":"move","coordinateSystem":"display-relative"}
@@ -1 +0,0 @@
1
- [{"x":702,"y":607,"timestamp":132,"unixTimeMs":1758313689604,"cursorType":"text","type":"move","coordinateSystem":"display-relative"}
@@ -1,154 +0,0 @@
1
- const MacRecorder = require('./index.js');
2
-
3
- async function testPrimaryCursor() {
4
- console.log('๐Ÿงช Testing cursor coordinates on primary vs secondary displays...');
5
-
6
- const recorder = new MacRecorder();
7
-
8
- try {
9
- // Get available displays and windows
10
- const displays = await recorder.getDisplays();
11
- const windows = await recorder.getWindows();
12
-
13
- console.log('\n๐Ÿ“ฑ Available displays:');
14
- displays.forEach((display, i) => {
15
- const type = display.isPrimary ? 'PRIMARY' : 'SECONDARY';
16
- console.log(` ${i + 1}. ${type} Display ${display.id}: ${display.resolution} at (${display.x}, ${display.y})`);
17
- });
18
-
19
- // Find windows on each display
20
- const primaryDisplay = displays.find(d => d.isPrimary);
21
- const secondaryDisplay = displays.find(d => !d.isPrimary);
22
-
23
- console.log('\n๐ŸชŸ Finding windows on each display:');
24
-
25
- const primaryWindows = windows.filter(window => {
26
- const windowCenterX = window.x + window.width / 2;
27
- const windowCenterY = window.y + window.height / 2;
28
- return (windowCenterX >= primaryDisplay.x &&
29
- windowCenterX < primaryDisplay.x + primaryDisplay.width &&
30
- windowCenterY >= primaryDisplay.y &&
31
- windowCenterY < primaryDisplay.y + primaryDisplay.height);
32
- });
33
-
34
- const secondaryWindows = secondaryDisplay ? windows.filter(window => {
35
- const windowCenterX = window.x + window.width / 2;
36
- const windowCenterY = window.y + window.height / 2;
37
- return (windowCenterX >= secondaryDisplay.x &&
38
- windowCenterX < secondaryDisplay.x + secondaryDisplay.width &&
39
- windowCenterY >= secondaryDisplay.y &&
40
- windowCenterY < secondaryDisplay.y + secondaryDisplay.height);
41
- }) : [];
42
-
43
- console.log(`\n๐Ÿ“Š Window distribution:`);
44
- console.log(` Primary display: ${primaryWindows.length} windows`);
45
- console.log(` Secondary display: ${secondaryWindows.length} windows`);
46
-
47
- // Test each display type
48
- for (const displayType of ['primary', 'secondary']) {
49
- const display = displayType === 'primary' ? primaryDisplay : secondaryDisplay;
50
- const windowList = displayType === 'primary' ? primaryWindows : secondaryWindows;
51
-
52
- if (!display) {
53
- console.log(`\nโš ๏ธ No ${displayType} display found, skipping...`);
54
- continue;
55
- }
56
-
57
- if (windowList.length === 0) {
58
- console.log(`\nโš ๏ธ No windows found on ${displayType} display, skipping...`);
59
- continue;
60
- }
61
-
62
- const testWindow = windowList[0];
63
- console.log(`\n๐ŸŽฏ Testing ${displayType.toUpperCase()} display (${display.id}):`);
64
- console.log(` Display bounds: (${display.x}, ${display.y}) ${display.width}x${display.height}`);
65
- console.log(` Test window: "${testWindow.title}" at (${testWindow.x}, ${testWindow.y}) ${testWindow.width}x${testWindow.height}`);
66
-
67
- // Calculate window position relative to display
68
- const windowRelativeX = testWindow.x - display.x;
69
- const windowRelativeY = testWindow.y - display.y;
70
- console.log(` Window relative to display: (${windowRelativeX}, ${windowRelativeY})`);
71
-
72
- // Test cursor capture
73
- const outputFile = `./test-output/cursor-${displayType}-${Date.now()}.json`;
74
-
75
- console.log(`\n๐Ÿ–ฑ๏ธ Starting cursor test for ${displayType} display...`);
76
- console.log(' Move mouse over the test window for 3 seconds');
77
-
78
- await recorder.startCursorCapture(outputFile, {
79
- windowRelative: true,
80
- windowInfo: {
81
- x: testWindow.x,
82
- y: testWindow.y,
83
- width: testWindow.width,
84
- height: testWindow.height,
85
- displayId: display.id,
86
- targetDisplay: display
87
- }
88
- });
89
-
90
- // Capture for 3 seconds
91
- await new Promise(resolve => setTimeout(resolve, 3000));
92
-
93
- await recorder.stopCursorCapture();
94
-
95
- // Analyze results
96
- const fs = require('fs');
97
- if (fs.existsSync(outputFile)) {
98
- const cursorData = JSON.parse(fs.readFileSync(outputFile, 'utf8'));
99
-
100
- console.log(`\n๐Ÿ“Š ${displayType.toUpperCase()} Display Results:`);
101
- console.log(` Captured events: ${cursorData.length}`);
102
-
103
- if (cursorData.length > 0) {
104
- const inBounds = cursorData.filter(event =>
105
- event.x >= 0 && event.x < testWindow.width &&
106
- event.y >= 0 && event.y < testWindow.height
107
- );
108
-
109
- const outOfBounds = cursorData.filter(event =>
110
- event.x < 0 || event.x >= testWindow.width ||
111
- event.y < 0 || event.y >= testWindow.height
112
- );
113
-
114
- console.log(` Events in bounds: ${inBounds.length}/${cursorData.length} (${Math.round(inBounds.length/cursorData.length*100)}%)`);
115
- console.log(` Events out of bounds: ${outOfBounds.length}`);
116
-
117
- if (outOfBounds.length > 0) {
118
- console.log(` โŒ ISSUE DETECTED on ${displayType} display!`);
119
- console.log(` Sample out-of-bounds coordinates:`);
120
- outOfBounds.slice(0, 5).forEach(event => {
121
- console.log(` (${event.x}, ${event.y}) - should be 0-${testWindow.width}, 0-${testWindow.height}`);
122
- });
123
-
124
- // Analyze the offset pattern
125
- const xOffsets = outOfBounds.map(e => e.x);
126
- const yOffsets = outOfBounds.map(e => e.y);
127
- const avgXOffset = xOffsets.reduce((a, b) => a + b, 0) / xOffsets.length;
128
- const avgYOffset = yOffsets.reduce((a, b) => a + b, 0) / yOffsets.length;
129
-
130
- console.log(` ๐Ÿ“Š Average coordinate offsets: X=${avgXOffset.toFixed(1)}, Y=${avgYOffset.toFixed(1)}`);
131
- } else {
132
- console.log(` โœ… All coordinates within bounds on ${displayType} display`);
133
- }
134
-
135
- // Show coordinate samples
136
- console.log(` Sample coordinates (first 3):`);
137
- cursorData.slice(0, 3).forEach((event, i) => {
138
- console.log(` ${i+1}. (${event.x}, ${event.y}) - ${event.coordinateSystem}`);
139
- });
140
- }
141
- }
142
- }
143
-
144
- console.log('\n๐Ÿ” Analysis Summary:');
145
- console.log(' If primary display shows out-of-bounds coordinates,');
146
- console.log(' but secondary display works correctly, this indicates');
147
- console.log(' a coordinate transformation issue specific to primary displays.');
148
-
149
- } catch (error) {
150
- console.error('โŒ Test failed:', error.message);
151
- }
152
- }
153
-
154
- testPrimaryCursor().catch(console.error);