node-mac-recorder 1.8.0 → 1.10.0
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/index.js +77 -26
- package/package.json +1 -1
- package/src/screen_capture.mm +23 -2
- package/src/window_selector.mm +13 -0
package/index.js
CHANGED
|
@@ -139,19 +139,21 @@ class MacRecorder extends EventEmitter {
|
|
|
139
139
|
// WindowId varsa captureArea'yı otomatik ayarla
|
|
140
140
|
if (this.options.windowId && !this.options.captureArea) {
|
|
141
141
|
try {
|
|
142
|
-
|
|
143
|
-
const
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
|
|
142
|
+
// Window selector'dan seçilen pencere bilgisini al
|
|
143
|
+
const WindowSelector = require('./window-selector');
|
|
144
|
+
const selector = new WindowSelector();
|
|
145
|
+
const selectedWindow = selector.getSelectedWindow();
|
|
146
|
+
|
|
147
|
+
// Eğer window selector'dan overlay koordinatları varsa onları kullan
|
|
148
|
+
if (selectedWindow && selectedWindow.overlayX !== undefined) {
|
|
149
|
+
console.log('🎯 Using overlay coordinates for exact recording match');
|
|
150
|
+
console.log(`Overlay coords: (${selectedWindow.overlayX}, ${selectedWindow.overlayY}) ${selectedWindow.overlayWidth}x${selectedWindow.overlayHeight}`);
|
|
151
|
+
|
|
152
|
+
const displays = await this.getDisplays();
|
|
153
|
+
const targetWindow = selectedWindow;
|
|
154
|
+
|
|
155
|
+
// Display ID'yi bul
|
|
150
156
|
let targetDisplayId = null;
|
|
151
|
-
let adjustedX = targetWindow.x;
|
|
152
|
-
let adjustedY = targetWindow.y;
|
|
153
|
-
|
|
154
|
-
// Pencere hangi display'de?
|
|
155
157
|
for (let i = 0; i < displays.length; i++) {
|
|
156
158
|
const display = displays[i];
|
|
157
159
|
const displayWidth = parseInt(display.resolution.split("x")[0]);
|
|
@@ -159,24 +161,73 @@ class MacRecorder extends EventEmitter {
|
|
|
159
161
|
|
|
160
162
|
// Pencere bu display sınırları içinde mi?
|
|
161
163
|
if (
|
|
162
|
-
targetWindow.
|
|
163
|
-
targetWindow.
|
|
164
|
-
targetWindow.
|
|
165
|
-
targetWindow.
|
|
164
|
+
targetWindow.overlayX >= display.x &&
|
|
165
|
+
targetWindow.overlayX < display.x + displayWidth &&
|
|
166
|
+
targetWindow.overlayY >= display.y &&
|
|
167
|
+
targetWindow.overlayY < display.y + displayHeight
|
|
166
168
|
) {
|
|
167
|
-
targetDisplayId = display.id;
|
|
168
|
-
// Koordinatları display'e göre normalize et
|
|
169
|
-
adjustedX = targetWindow.x - display.x;
|
|
170
|
-
|
|
171
|
-
// Y coordinate fix: Window selector uses NSScreen.frame (excludes menu bar)
|
|
172
|
-
// but recording uses CGDisplayBounds (includes menu bar)
|
|
173
|
-
// For primary display, add menu bar height (~22-25px) to Y coordinate
|
|
174
|
-
const isMainDisplay = display.isPrimary;
|
|
175
|
-
const menuBarHeight = isMainDisplay ? 25 : 0; // Menu bar height adjustment
|
|
176
|
-
adjustedY = targetWindow.y - display.y + menuBarHeight;
|
|
169
|
+
targetDisplayId = display.id;
|
|
177
170
|
break;
|
|
178
171
|
}
|
|
179
172
|
}
|
|
173
|
+
|
|
174
|
+
// Display ID'yi ayarla
|
|
175
|
+
if (targetDisplayId !== null) {
|
|
176
|
+
this.options.displayId = targetDisplayId;
|
|
177
|
+
const targetDisplay = displays.find(d => d.id === targetDisplayId);
|
|
178
|
+
this.recordingDisplayInfo = {
|
|
179
|
+
displayId: targetDisplayId,
|
|
180
|
+
x: targetDisplay.x,
|
|
181
|
+
y: targetDisplay.y,
|
|
182
|
+
width: parseInt(targetDisplay.resolution.split("x")[0]),
|
|
183
|
+
height: parseInt(targetDisplay.resolution.split("x")[1]),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Overlay koordinatlarını direkt kullan - display offset'ini çıkar
|
|
188
|
+
const targetDisplay = displays.find(d => d.id === targetDisplayId);
|
|
189
|
+
this.options.captureArea = {
|
|
190
|
+
x: targetWindow.overlayX - (targetDisplay ? targetDisplay.x : 0),
|
|
191
|
+
y: targetWindow.overlayY - (targetDisplay ? targetDisplay.y : 0),
|
|
192
|
+
width: targetWindow.overlayWidth,
|
|
193
|
+
height: targetWindow.overlayHeight,
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
console.log(`🎬 Recording area: x=${this.options.captureArea.x}, y=${this.options.captureArea.y}, w=${this.options.captureArea.width}, h=${this.options.captureArea.height}`);
|
|
197
|
+
} else {
|
|
198
|
+
// Fallback: Eski yöntem
|
|
199
|
+
const windows = await this.getWindows();
|
|
200
|
+
const displays = await this.getDisplays();
|
|
201
|
+
const targetWindow = windows.find(
|
|
202
|
+
(w) => w.id === this.options.windowId
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
if (targetWindow) {
|
|
206
|
+
// Pencere hangi display'de olduğunu bul
|
|
207
|
+
let targetDisplayId = null;
|
|
208
|
+
let adjustedX = targetWindow.x;
|
|
209
|
+
let adjustedY = targetWindow.y;
|
|
210
|
+
|
|
211
|
+
// Pencere hangi display'de?
|
|
212
|
+
for (let i = 0; i < displays.length; i++) {
|
|
213
|
+
const display = displays[i];
|
|
214
|
+
const displayWidth = parseInt(display.resolution.split("x")[0]);
|
|
215
|
+
const displayHeight = parseInt(display.resolution.split("x")[1]);
|
|
216
|
+
|
|
217
|
+
// Pencere bu display sınırları içinde mi?
|
|
218
|
+
if (
|
|
219
|
+
targetWindow.x >= display.x &&
|
|
220
|
+
targetWindow.x < display.x + displayWidth &&
|
|
221
|
+
targetWindow.y >= display.y &&
|
|
222
|
+
targetWindow.y < display.y + displayHeight
|
|
223
|
+
) {
|
|
224
|
+
targetDisplayId = display.id; // Use actual display ID, not array index
|
|
225
|
+
// Koordinatları display'e göre normalize et
|
|
226
|
+
adjustedX = targetWindow.x - display.x;
|
|
227
|
+
adjustedY = targetWindow.y - display.y;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
180
231
|
|
|
181
232
|
// Eğer display bulunamadıysa ana display kullan
|
|
182
233
|
if (targetDisplayId === null) {
|
package/package.json
CHANGED
package/src/screen_capture.mm
CHANGED
|
@@ -25,11 +25,32 @@
|
|
|
25
25
|
CGDirectDisplayID *displayList = (CGDirectDisplayID *)malloc(displayCount * sizeof(CGDirectDisplayID));
|
|
26
26
|
CGGetActiveDisplayList(displayCount, displayList, &displayCount);
|
|
27
27
|
|
|
28
|
+
// Get NSScreen list for consistent coordinate system
|
|
29
|
+
NSArray<NSScreen *> *screens = [NSScreen screens];
|
|
30
|
+
|
|
28
31
|
for (uint32_t i = 0; i < displayCount; i++) {
|
|
29
32
|
CGDirectDisplayID displayID = displayList[i];
|
|
30
33
|
|
|
31
|
-
//
|
|
32
|
-
|
|
34
|
+
// Find corresponding NSScreen for this display ID
|
|
35
|
+
NSScreen *matchingScreen = nil;
|
|
36
|
+
for (NSScreen *screen in screens) {
|
|
37
|
+
// Match by display ID (requires screen.deviceDescription lookup)
|
|
38
|
+
NSDictionary *deviceDescription = [screen deviceDescription];
|
|
39
|
+
NSNumber *screenDisplayID = [deviceDescription objectForKey:@"NSScreenNumber"];
|
|
40
|
+
if (screenDisplayID && [screenDisplayID unsignedIntValue] == displayID) {
|
|
41
|
+
matchingScreen = screen;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Use NSScreen.frame if found, fallback to CGDisplayBounds
|
|
47
|
+
CGRect bounds;
|
|
48
|
+
if (matchingScreen) {
|
|
49
|
+
NSRect screenFrame = [matchingScreen frame];
|
|
50
|
+
bounds = CGRectMake(screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height);
|
|
51
|
+
} else {
|
|
52
|
+
bounds = CGDisplayBounds(displayID);
|
|
53
|
+
}
|
|
33
54
|
|
|
34
55
|
// Create display info dictionary
|
|
35
56
|
NSDictionary *displayInfo = @{
|
package/src/window_selector.mm
CHANGED
|
@@ -990,11 +990,24 @@ Napi::Value GetSelectedWindowInfo(const Napi::CallbackInfo& info) {
|
|
|
990
990
|
result.Set("id", Napi::Number::New(env, [[g_selectedWindowInfo objectForKey:@"id"] intValue]));
|
|
991
991
|
result.Set("title", Napi::String::New(env, [[g_selectedWindowInfo objectForKey:@"title"] UTF8String]));
|
|
992
992
|
result.Set("appName", Napi::String::New(env, [[g_selectedWindowInfo objectForKey:@"appName"] UTF8String]));
|
|
993
|
+
// Original CGWindow coordinates
|
|
993
994
|
result.Set("x", Napi::Number::New(env, [[g_selectedWindowInfo objectForKey:@"x"] intValue]));
|
|
994
995
|
result.Set("y", Napi::Number::New(env, [[g_selectedWindowInfo objectForKey:@"y"] intValue]));
|
|
995
996
|
result.Set("width", Napi::Number::New(env, [[g_selectedWindowInfo objectForKey:@"width"] intValue]));
|
|
996
997
|
result.Set("height", Napi::Number::New(env, [[g_selectedWindowInfo objectForKey:@"height"] intValue]));
|
|
997
998
|
|
|
999
|
+
// Add overlay coordinates for direct use in recording
|
|
1000
|
+
// These are the exact coordinates used by the recording preview overlay
|
|
1001
|
+
int windowX = [[g_selectedWindowInfo objectForKey:@"x"] intValue];
|
|
1002
|
+
int windowY = [[g_selectedWindowInfo objectForKey:@"y"] intValue];
|
|
1003
|
+
int windowWidth = [[g_selectedWindowInfo objectForKey:@"width"] intValue];
|
|
1004
|
+
int windowHeight = [[g_selectedWindowInfo objectForKey:@"height"] intValue];
|
|
1005
|
+
|
|
1006
|
+
result.Set("overlayX", Napi::Number::New(env, windowX));
|
|
1007
|
+
result.Set("overlayY", Napi::Number::New(env, windowY));
|
|
1008
|
+
result.Set("overlayWidth", Napi::Number::New(env, windowWidth));
|
|
1009
|
+
result.Set("overlayHeight", Napi::Number::New(env, windowHeight));
|
|
1010
|
+
|
|
998
1011
|
// Determine which screen this window is on
|
|
999
1012
|
int x = [[g_selectedWindowInfo objectForKey:@"x"] intValue];
|
|
1000
1013
|
int y = [[g_selectedWindowInfo objectForKey:@"y"] intValue];
|