node-mac-recorder 2.17.17 → 2.17.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
const MacRecorder = require('./index.js');
|
|
2
|
+
|
|
3
|
+
async function debugPrimaryCursor() {
|
|
4
|
+
console.log('🔍 Detailed debugging of primary display cursor coordinates...');
|
|
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
|
+
console.log('\n📱 Primary Display:');
|
|
14
|
+
console.log(` Bounds: (${primaryDisplay.x}, ${primaryDisplay.y}) ${primaryDisplay.width}x${primaryDisplay.height}`);
|
|
15
|
+
|
|
16
|
+
// Find a window on primary display
|
|
17
|
+
const primaryWindows = windows.filter(window => {
|
|
18
|
+
const windowCenterX = window.x + window.width / 2;
|
|
19
|
+
const windowCenterY = window.y + window.height / 2;
|
|
20
|
+
return (windowCenterX >= primaryDisplay.x &&
|
|
21
|
+
windowCenterX < primaryDisplay.x + primaryDisplay.width &&
|
|
22
|
+
windowCenterY >= primaryDisplay.y &&
|
|
23
|
+
windowCenterY < primaryDisplay.y + primaryDisplay.height);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (primaryWindows.length === 0) {
|
|
27
|
+
console.log('❌ No windows found on primary display');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const testWindow = primaryWindows[0];
|
|
32
|
+
console.log('\n🪟 Test Window:');
|
|
33
|
+
console.log(` Title: "${testWindow.title}"`);
|
|
34
|
+
console.log(` Global position: (${testWindow.x}, ${testWindow.y})`);
|
|
35
|
+
console.log(` Size: ${testWindow.width}x${testWindow.height}`);
|
|
36
|
+
console.log(` Global bounds: (${testWindow.x}, ${testWindow.y}) to (${testWindow.x + testWindow.width}, ${testWindow.y + testWindow.height})`);
|
|
37
|
+
|
|
38
|
+
// Manual cursor position check
|
|
39
|
+
console.log('\n🖱️ Current cursor position:');
|
|
40
|
+
const currentPos = recorder.getCursorPosition();
|
|
41
|
+
console.log(` Global cursor: (${currentPos.x}, ${currentPos.y})`);
|
|
42
|
+
|
|
43
|
+
// Manual transformation calculation
|
|
44
|
+
console.log('\n🧮 Manual transformation calculation:');
|
|
45
|
+
const manualWindowRelativeX = currentPos.x - testWindow.x;
|
|
46
|
+
const manualWindowRelativeY = currentPos.y - testWindow.y;
|
|
47
|
+
console.log(` Manual window-relative: (${manualWindowRelativeX}, ${manualWindowRelativeY})`);
|
|
48
|
+
|
|
49
|
+
const isInWindow = (manualWindowRelativeX >= 0 && manualWindowRelativeX < testWindow.width &&
|
|
50
|
+
manualWindowRelativeY >= 0 && manualWindowRelativeY < testWindow.height);
|
|
51
|
+
console.log(` Is cursor in window? ${isInWindow ? '✅ YES' : '❌ NO'}`);
|
|
52
|
+
|
|
53
|
+
if (!isInWindow) {
|
|
54
|
+
console.log('\n⚠️ Move cursor to the test window for accurate testing...');
|
|
55
|
+
console.log(' Waiting 3 seconds for you to move cursor to the window...');
|
|
56
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
57
|
+
|
|
58
|
+
const newPos = recorder.getCursorPosition();
|
|
59
|
+
console.log(`\n🖱️ New cursor position: (${newPos.x}, ${newPos.y})`);
|
|
60
|
+
const newManualX = newPos.x - testWindow.x;
|
|
61
|
+
const newManualY = newPos.y - testWindow.y;
|
|
62
|
+
console.log(` New manual window-relative: (${newManualX}, ${newManualY})`);
|
|
63
|
+
|
|
64
|
+
const newIsInWindow = (newManualX >= 0 && newManualX < testWindow.width &&
|
|
65
|
+
newManualY >= 0 && newManualY < testWindow.height);
|
|
66
|
+
console.log(` Is cursor in window now? ${newIsInWindow ? '✅ YES' : '❌ NO'}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Now test with cursor capture to see what actually gets recorded
|
|
70
|
+
console.log('\n🎬 Testing actual cursor capture...');
|
|
71
|
+
|
|
72
|
+
// Create a custom logger to see what coordinates are being processed
|
|
73
|
+
const originalLog = console.log;
|
|
74
|
+
const capturedLogs = [];
|
|
75
|
+
|
|
76
|
+
// Temporarily override console.log to capture coordinate logs
|
|
77
|
+
console.log = (...args) => {
|
|
78
|
+
const message = args.join(' ');
|
|
79
|
+
if (message.includes('cursor') || message.includes('position') || message.includes('coordinate')) {
|
|
80
|
+
capturedLogs.push(message);
|
|
81
|
+
}
|
|
82
|
+
originalLog(...args);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const outputFile = `./test-output/debug-primary-${Date.now()}.json`;
|
|
86
|
+
|
|
87
|
+
// Start capture with detailed logging
|
|
88
|
+
await recorder.startCursorCapture(outputFile, {
|
|
89
|
+
windowRelative: true,
|
|
90
|
+
windowInfo: {
|
|
91
|
+
x: testWindow.x,
|
|
92
|
+
y: testWindow.y,
|
|
93
|
+
width: testWindow.width,
|
|
94
|
+
height: testWindow.height,
|
|
95
|
+
displayId: primaryDisplay.id
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
console.log('\n📍 Cursor capture started. Move mouse in the window for 3 seconds...');
|
|
100
|
+
console.log(` Expected window bounds: (0, 0) to (${testWindow.width}, ${testWindow.height})`);
|
|
101
|
+
|
|
102
|
+
// Capture for 3 seconds with manual checking
|
|
103
|
+
for (let i = 0; i < 6; i++) {
|
|
104
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
105
|
+
const pos = recorder.getCursorPosition();
|
|
106
|
+
const windowRelX = pos.x - testWindow.x;
|
|
107
|
+
const windowRelY = pos.y - testWindow.y;
|
|
108
|
+
|
|
109
|
+
console.log(` Sample ${i+1}: Global(${pos.x}, ${pos.y}) → Window-rel(${windowRelX}, ${windowRelY})`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
await recorder.stopCursorCapture();
|
|
113
|
+
|
|
114
|
+
// Restore console.log
|
|
115
|
+
console.log = originalLog;
|
|
116
|
+
|
|
117
|
+
// Analyze results
|
|
118
|
+
const fs = require('fs');
|
|
119
|
+
if (fs.existsSync(outputFile)) {
|
|
120
|
+
const cursorData = JSON.parse(fs.readFileSync(outputFile, 'utf8'));
|
|
121
|
+
|
|
122
|
+
console.log('\n📊 Analysis Results:');
|
|
123
|
+
console.log(` Captured events: ${cursorData.length}`);
|
|
124
|
+
|
|
125
|
+
if (cursorData.length > 0) {
|
|
126
|
+
console.log('\n📍 Sample recorded coordinates:');
|
|
127
|
+
cursorData.slice(0, 5).forEach((event, i) => {
|
|
128
|
+
console.log(` Event ${i+1}: (${event.x}, ${event.y}) - ${event.coordinateSystem}`);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
// Check bounds
|
|
132
|
+
const inBounds = cursorData.filter(event =>
|
|
133
|
+
event.x >= 0 && event.x < testWindow.width &&
|
|
134
|
+
event.y >= 0 && event.y < testWindow.height
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const outOfBounds = cursorData.filter(event =>
|
|
138
|
+
event.x < 0 || event.x >= testWindow.width ||
|
|
139
|
+
event.y < 0 || event.y >= testWindow.height
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
console.log(`\n✅ Events in bounds: ${inBounds.length}/${cursorData.length} (${Math.round(inBounds.length/cursorData.length*100)}%)`);
|
|
143
|
+
|
|
144
|
+
if (outOfBounds.length > 0) {
|
|
145
|
+
console.log(`❌ Events out of bounds: ${outOfBounds.length}`);
|
|
146
|
+
console.log(' Problem coordinates:');
|
|
147
|
+
outOfBounds.slice(0, 3).forEach(event => {
|
|
148
|
+
console.log(` (${event.x}, ${event.y}) - Expected: 0-${testWindow.width}, 0-${testWindow.height}`);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Calculate offset pattern
|
|
152
|
+
const xOffsets = outOfBounds.map(e => e.x - (e.x >= 0 ? 0 : testWindow.width));
|
|
153
|
+
const yOffsets = outOfBounds.map(e => e.y - (e.y >= 0 ? 0 : testWindow.height));
|
|
154
|
+
|
|
155
|
+
console.log(`\n🔍 Offset analysis:`);
|
|
156
|
+
console.log(` X offset pattern: ${xOffsets.slice(0, 3).join(', ')}`);
|
|
157
|
+
console.log(` Y offset pattern: ${yOffsets.slice(0, 3).join(', ')}`);
|
|
158
|
+
} else {
|
|
159
|
+
console.log('✅ All coordinates are within bounds!');
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
console.log('❌ No events captured - cursor might not be in window or transformation is dropping events');
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
console.log('❌ No output file created');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log('\n🔍 Captured system logs:');
|
|
169
|
+
if (capturedLogs.length > 0) {
|
|
170
|
+
capturedLogs.forEach(log => console.log(` ${log}`));
|
|
171
|
+
} else {
|
|
172
|
+
console.log(' No relevant coordinate logs captured');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error('❌ Debug failed:', error.message);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
debugPrimaryCursor().catch(console.error);
|
package/package.json
CHANGED
package/src/cursor_tracker.mm
CHANGED
|
@@ -636,20 +636,27 @@ void cursorTimerCallback() {
|
|
|
636
636
|
// Apply DPR scaling correction for Retina displays
|
|
637
637
|
NSDictionary *scalingInfo = getDisplayScalingInfo(rawLocation);
|
|
638
638
|
CGPoint location = rawLocation;
|
|
639
|
-
|
|
639
|
+
|
|
640
640
|
if (scalingInfo) {
|
|
641
641
|
CGFloat scaleFactor = [[scalingInfo objectForKey:@"scaleFactor"] doubleValue];
|
|
642
642
|
NSRect displayBounds = [[scalingInfo objectForKey:@"displayBounds"] rectValue];
|
|
643
|
-
|
|
643
|
+
|
|
644
644
|
// Keep logical coordinates - no scaling needed here
|
|
645
645
|
location = rawLocation;
|
|
646
646
|
}
|
|
647
|
-
|
|
647
|
+
|
|
648
648
|
NSDate *currentDate = [NSDate date];
|
|
649
649
|
NSTimeInterval timestamp = [currentDate timeIntervalSinceDate:g_trackingStartTime] * 1000; // milliseconds
|
|
650
650
|
NSTimeInterval unixTimeMs = [currentDate timeIntervalSince1970] * 1000; // unix timestamp in milliseconds
|
|
651
651
|
NSString *cursorType = getCursorType();
|
|
652
|
-
|
|
652
|
+
|
|
653
|
+
// CRITICAL: Apply coordinate transformation if needed
|
|
654
|
+
// This should match the transformation logic in index.js cursorTimerCallback
|
|
655
|
+
|
|
656
|
+
// Use transformed coordinates from the JavaScript layer if available
|
|
657
|
+
// The transformation is handled in index.js, so we need to get the transformed position
|
|
658
|
+
// For now, we'll write the raw coordinates and let the JS layer handle transformation
|
|
659
|
+
|
|
653
660
|
// Cursor data oluştur
|
|
654
661
|
NSDictionary *cursorInfo = @{
|
|
655
662
|
@"x": @((int)location.x),
|
|
@@ -659,7 +666,7 @@ void cursorTimerCallback() {
|
|
|
659
666
|
@"cursorType": cursorType,
|
|
660
667
|
@"type": @"move"
|
|
661
668
|
};
|
|
662
|
-
|
|
669
|
+
|
|
663
670
|
// Direkt dosyaya yaz
|
|
664
671
|
writeToFile(cursorInfo);
|
|
665
672
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[]
|