node-mac-recorder 2.22.20 → 2.22.22
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/lib/cursorCapture/polling.js +61 -10
- package/package.json +1 -1
|
@@ -105,8 +105,39 @@ function transformInputFrameGlobal(ifr, d) {
|
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
// Electron: AX caret cache — deferred refresh ile crash-safe
|
|
109
|
+
const ELECTRON_AX_CACHE_MAX_AGE_MS = 500;
|
|
110
|
+
|
|
111
|
+
function deferredRefreshElectronAXCache(recorder, nativeBinding) {
|
|
112
|
+
if (recorder._axDeferredPending) return;
|
|
113
|
+
if (!nativeBinding || typeof nativeBinding.getTextInputSnapshot !== "function") return;
|
|
114
|
+
|
|
115
|
+
recorder._axDeferredPending = true;
|
|
116
|
+
setImmediate(() => {
|
|
117
|
+
recorder._axDeferredPending = false;
|
|
118
|
+
try {
|
|
119
|
+
const snap = nativeBinding.getTextInputSnapshot();
|
|
120
|
+
if (snap && Number.isFinite(snap.caretX) && Number.isFinite(snap.caretY)) {
|
|
121
|
+
const d = recorder.cursorDisplayInfo;
|
|
122
|
+
const caretT = transformGlobalToVideo(snap.caretX, snap.caretY, d);
|
|
123
|
+
recorder._axCaretCache = {
|
|
124
|
+
caretX: caretT.x,
|
|
125
|
+
caretY: caretT.y,
|
|
126
|
+
inputFrame: snap.inputFrame
|
|
127
|
+
? transformInputFrameGlobal(snap.inputFrame, d)
|
|
128
|
+
: null,
|
|
129
|
+
csys: d && d.videoRelative ? "video-relative" : "global",
|
|
130
|
+
wallMs: Date.now(),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
} catch {
|
|
134
|
+
// AX API hata verirse mevcut cache'i koru
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
108
139
|
/** @returns {boolean} Dosyaya textInput satırı yazıldı mı */
|
|
109
|
-
function tryAppendSyntheticTextInputRow(recorder, filepath, cursorData, timestamp) {
|
|
140
|
+
function tryAppendSyntheticTextInputRow(recorder, nativeBinding, filepath, cursorData, timestamp) {
|
|
110
141
|
if (!IS_ELECTRON) {
|
|
111
142
|
return false;
|
|
112
143
|
}
|
|
@@ -122,6 +153,8 @@ function tryAppendSyntheticTextInputRow(recorder, filepath, cursorData, timestam
|
|
|
122
153
|
wall - (recorder._electronSynthWallMs || 0) <
|
|
123
154
|
ELECTRON_SYNTH_THROTTLE_MS
|
|
124
155
|
) {
|
|
156
|
+
// Throttle aktif olsa bile AX cache yenilensin
|
|
157
|
+
deferredRefreshElectronAXCache(recorder, nativeBinding);
|
|
125
158
|
return false;
|
|
126
159
|
}
|
|
127
160
|
const vx = cursorData.x;
|
|
@@ -130,6 +163,28 @@ function tryAppendSyntheticTextInputRow(recorder, filepath, cursorData, timestam
|
|
|
130
163
|
return false;
|
|
131
164
|
}
|
|
132
165
|
|
|
166
|
+
// Cached AX caret varsa gerçek caret pozisyonunu kullan
|
|
167
|
+
let caretX = vx;
|
|
168
|
+
let caretY = vy;
|
|
169
|
+
let inputFrame = { x: vx - 1, y: vy - 9, width: 2, height: 18 };
|
|
170
|
+
let coordinateSystem = cursorData.coordinateSystem;
|
|
171
|
+
|
|
172
|
+
const cache = recorder._axCaretCache;
|
|
173
|
+
if (
|
|
174
|
+
cache &&
|
|
175
|
+
Number.isFinite(cache.caretX) &&
|
|
176
|
+
Number.isFinite(cache.caretY) &&
|
|
177
|
+
(wall - (cache.wallMs || 0)) < ELECTRON_AX_CACHE_MAX_AGE_MS
|
|
178
|
+
) {
|
|
179
|
+
caretX = cache.caretX;
|
|
180
|
+
caretY = cache.caretY;
|
|
181
|
+
if (cache.inputFrame) inputFrame = cache.inputFrame;
|
|
182
|
+
coordinateSystem = cache.csys || coordinateSystem;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Sonraki frame için AX cache'i yenile (deferred — crash-safe)
|
|
186
|
+
deferredRefreshElectronAXCache(recorder, nativeBinding);
|
|
187
|
+
|
|
133
188
|
const tiRow = {
|
|
134
189
|
x: vx,
|
|
135
190
|
y: vy,
|
|
@@ -137,15 +192,10 @@ function tryAppendSyntheticTextInputRow(recorder, filepath, cursorData, timestam
|
|
|
137
192
|
unixTimeMs: wall,
|
|
138
193
|
cursorType: "text",
|
|
139
194
|
type: "textInput",
|
|
140
|
-
caretX
|
|
141
|
-
caretY
|
|
142
|
-
inputFrame
|
|
143
|
-
|
|
144
|
-
y: vy - 9,
|
|
145
|
-
width: 2,
|
|
146
|
-
height: 18,
|
|
147
|
-
},
|
|
148
|
-
coordinateSystem: cursorData.coordinateSystem,
|
|
195
|
+
caretX,
|
|
196
|
+
caretY,
|
|
197
|
+
inputFrame,
|
|
198
|
+
coordinateSystem,
|
|
149
199
|
recordingType: cursorData.recordingType,
|
|
150
200
|
videoInfo: cursorData.videoInfo || {},
|
|
151
201
|
displayInfo: cursorData.displayInfo || {},
|
|
@@ -517,6 +567,7 @@ async function startCursorCapture(recorder, nativeBinding, intervalOrFilepath, o
|
|
|
517
567
|
if (IS_ELECTRON) {
|
|
518
568
|
const textInputWritten = tryAppendSyntheticTextInputRow(
|
|
519
569
|
recorder,
|
|
570
|
+
nativeBinding,
|
|
520
571
|
filepath,
|
|
521
572
|
cursorData,
|
|
522
573
|
timestamp,
|