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.
- package/.claude/settings.local.json +3 -1
- package/index.js +17 -198
- package/package.json +1 -1
- package/publish.sh +18 -0
- package/src/cursor_tracker.mm +37 -20
- package/cursor-debug-test.js +0 -60
- package/cursor-dpr-test.js +0 -73
- package/cursor-dpr-test.json +0 -1
- package/cursor-macbook-test.js +0 -63
- package/cursor-permission-test.js +0 -46
- package/cursor-scaling-debug.js +0 -53
- package/cursor-simple-test.js +0 -26
- package/debug-audio.js +0 -79
- package/debug-coordinates.js +0 -69
- package/debug-macos14.js +0 -110
- package/debug-primary-window.js +0 -84
- package/debug-screen-selection.js +0 -81
- package/debug-window-selector.js +0 -178
- package/test-cursor-fix.js +0 -105
- package/test-cursor-types.js +0 -117
- package/test-display-coordinates.js +0 -72
- package/test-integrated-recording.js +0 -120
- package/test-menubar-offset.js +0 -110
- package/test-output/temp_cursor_1758313956591.json +0 -1
- package/test-primary-cursor.js +0 -154
- package/test-primary-fix.js +0 -120
- package/test-recording-with-cursor.js +0 -83
- package/test-unified-cursor.js +0 -75
- package/test-window-recording.js +0 -149
package/test-cursor-fix.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require('./index.js');
|
|
2
|
-
|
|
3
|
-
async function testCursorCoordinates() {
|
|
4
|
-
console.log('๐งช Testing cursor coordinate fixes for window recording...');
|
|
5
|
-
|
|
6
|
-
const recorder = new MacRecorder();
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
// Get available windows and displays
|
|
10
|
-
const windows = await recorder.getWindows();
|
|
11
|
-
const displays = await recorder.getDisplays();
|
|
12
|
-
|
|
13
|
-
console.log('\n๐ฑ Available displays:');
|
|
14
|
-
displays.forEach((display, i) => {
|
|
15
|
-
console.log(` ${i + 1}. Display ${display.id}: ${display.resolution} at (${display.x}, ${display.y}) ${display.isPrimary ? '(Primary)' : ''}`);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
console.log('\n๐ช Available windows:');
|
|
19
|
-
windows.slice(0, 5).forEach((window, i) => {
|
|
20
|
-
console.log(` ${i + 1}. ${window.title} (${window.app}) - ${window.width}x${window.height} at (${window.x}, ${window.y})`);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
if (windows.length === 0) {
|
|
24
|
-
console.log('โ No windows available for testing');
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Pick the first available window for testing
|
|
29
|
-
const testWindow = windows[0];
|
|
30
|
-
console.log(`\n๐ฏ Testing with window: ${testWindow.title}`);
|
|
31
|
-
console.log(` Window position: (${testWindow.x}, ${testWindow.y})`);
|
|
32
|
-
console.log(` Window size: ${testWindow.width}x${testWindow.height}`);
|
|
33
|
-
|
|
34
|
-
// Check current cursor position before recording
|
|
35
|
-
const cursorPos = recorder.getCursorPosition();
|
|
36
|
-
console.log(`\n๐ฑ๏ธ Current cursor position (global): (${cursorPos.x}, ${cursorPos.y})`);
|
|
37
|
-
|
|
38
|
-
// Setup recording options for window recording
|
|
39
|
-
recorder.options.windowId = testWindow.id;
|
|
40
|
-
recorder.options.captureCursor = true;
|
|
41
|
-
|
|
42
|
-
console.log('\n๐ง Starting cursor capture test for window recording...');
|
|
43
|
-
|
|
44
|
-
// Start cursor capture with window-relative coordinates
|
|
45
|
-
const outputFile = `./test-output/cursor-test-window-${Date.now()}.json`;
|
|
46
|
-
|
|
47
|
-
// Start cursor tracking first to see if coordinate transformation works
|
|
48
|
-
await recorder.startCursorCapture(outputFile, {
|
|
49
|
-
windowRelative: true,
|
|
50
|
-
windowInfo: {
|
|
51
|
-
x: testWindow.x,
|
|
52
|
-
y: testWindow.y,
|
|
53
|
-
width: testWindow.width,
|
|
54
|
-
height: testWindow.height,
|
|
55
|
-
displayId: null // Let it auto-detect
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
console.log('โ
Cursor capture started successfully!');
|
|
60
|
-
console.log('๐ฑ๏ธ Move your mouse around the window for 5 seconds...');
|
|
61
|
-
console.log(` Window bounds: (0, 0) to (${testWindow.width}, ${testWindow.height})`);
|
|
62
|
-
|
|
63
|
-
// Wait for 5 seconds to capture cursor movements
|
|
64
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
65
|
-
|
|
66
|
-
console.log('\n๐ Stopping cursor capture...');
|
|
67
|
-
await recorder.stopCursorCapture();
|
|
68
|
-
|
|
69
|
-
console.log(`โ
Test completed! Check cursor data in: ${outputFile}`);
|
|
70
|
-
|
|
71
|
-
// Read and analyze some cursor data
|
|
72
|
-
const fs = require('fs');
|
|
73
|
-
if (fs.existsSync(outputFile)) {
|
|
74
|
-
const cursorData = JSON.parse(fs.readFileSync(outputFile, 'utf8'));
|
|
75
|
-
console.log(`\n๐ Captured ${cursorData.length} cursor events`);
|
|
76
|
-
|
|
77
|
-
if (cursorData.length > 0) {
|
|
78
|
-
const first = cursorData[0];
|
|
79
|
-
const last = cursorData[cursorData.length - 1];
|
|
80
|
-
|
|
81
|
-
console.log(` First event: (${first.x}, ${first.y}) - ${first.coordinateSystem}`);
|
|
82
|
-
console.log(` Last event: (${last.x}, ${last.y}) - ${last.coordinateSystem}`);
|
|
83
|
-
|
|
84
|
-
// Check if coordinates are within window bounds
|
|
85
|
-
const inBounds = cursorData.filter(event =>
|
|
86
|
-
event.x >= 0 && event.x < testWindow.width &&
|
|
87
|
-
event.y >= 0 && event.y < testWindow.height
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
console.log(` Events within window bounds: ${inBounds.length}/${cursorData.length} (${Math.round(inBounds.length/cursorData.length*100)}%)`);
|
|
91
|
-
|
|
92
|
-
if (inBounds.length > 0) {
|
|
93
|
-
console.log('โ
Cursor coordinates appear to be correctly transformed to window-relative!');
|
|
94
|
-
} else {
|
|
95
|
-
console.log('โ No cursor coordinates are within window bounds - transformation may be incorrect');
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
} catch (error) {
|
|
101
|
-
console.error('โ Test failed:', error.message);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
testCursorCoordinates().catch(console.error);
|
package/test-cursor-types.js
DELETED
|
@@ -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
|
-
});
|
package/test-menubar-offset.js
DELETED
|
@@ -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":609,"y":795,"timestamp":184,"unixTimeMs":1758313956779,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":609,"y":795,"timestamp":205,"unixTimeMs":1758313956800,"cursorType":"default","type":"mousedown","coordinateSystem":"display-relative"},{"x":609,"y":795,"timestamp":224,"unixTimeMs":1758313956819,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":609,"y":795,"timestamp":286,"unixTimeMs":1758313956881,"cursorType":"default","type":"mouseup","coordinateSystem":"display-relative"},{"x":609,"y":795,"timestamp":306,"unixTimeMs":1758313956901,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":609,"y":802,"timestamp":824,"unixTimeMs":1758313957419,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":608,"y":812,"timestamp":842,"unixTimeMs":1758313957437,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":605,"y":828,"timestamp":863,"unixTimeMs":1758313957458,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":601,"y":851,"timestamp":883,"unixTimeMs":1758313957478,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":596,"y":877,"timestamp":905,"unixTimeMs":1758313957500,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":594,"y":887,"timestamp":923,"unixTimeMs":1758313957518,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":591,"y":900,"timestamp":942,"unixTimeMs":1758313957537,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":590,"y":905,"timestamp":965,"unixTimeMs":1758313957560,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":589,"y":908,"timestamp":984,"unixTimeMs":1758313957579,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":588,"y":910,"timestamp":1025,"unixTimeMs":1758313957620,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":588,"y":912,"timestamp":1065,"unixTimeMs":1758313957660,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":588,"y":914,"timestamp":1124,"unixTimeMs":1758313957719,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":587,"y":917,"timestamp":1145,"unixTimeMs":1758313957740,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":586,"y":920,"timestamp":1167,"unixTimeMs":1758313957762,"cursorType":"default","type":"move","coordinateSystem":"display-relative"},{"x":586,"y":922,"timestamp":1186,"unixTimeMs":1758313957781,"cursorType":"default","type":"move","coordinateSystem":"display-relative"}
|