discardLatestPending() popped whichever batch happened to be at the
back of the queue. With a Stop → Record → Discard sequence, the
pending queue can have recording B's batch sitting in front of A's by
the time A's finalize callback resolves (because finalizeRecording
awaits fixWebmDuration), so the discard targets the wrong recording.
Tag each completed batch with the recording id supplied at
startSession() time and replace discardLatestPending() with
discardBatch(recordingId). takeNextBatch() now returns the full
{recordingId, samples} shape so prependBatch() can re-queue it on
write-failure without losing the id. The renderer already owns a
stable recordingId (Date.now() in useScreenRecorder) and the IPC
surface threads it through set-recording-state and
discard-cursor-telemetry.
Adds a regression test that mirrors FabLrc's scenario in PR #457:
two recordings finalize, A is discarded after B has already been
queued, and the buffer must drop A while keeping B intact.
Two follow-up fixes for CodeRabbit feedback on the docs commit:
- CursorTelemetryPoint JSDoc previously described cx/cy as 'device-pixel
positions'. The producer sampleCursorPoint() in electron/ipc/handlers.ts
clamps them to the [0, 1] range after dividing by the source display's
width/height, so they are normalised ratios, not pixel values. Correct
the doc comment accordingly.
- createCursorTelemetryBuffer now sanitizes maxActiveSamples and
maxPendingBatches: non-finite, zero, or negative values fall back to
safe positive-integer defaults. Without this, a caller passing Infinity
or NaN would hang the trim loops.
New test covers the sanitisation path for both options.
Add JSDoc to every public export in cursorTelemetryBuffer so the module
meets the 80% docstring-coverage threshold, and make two silent-drop
paths observable:
- endSession() now returns the number of pending batches evicted by the
maxPendingBatches cap and emits console.warn when any are dropped.
- prependBatch() defensively trims and warns if an unusual retry pattern
would push the queue past the cap (normal retry after takeNextBatch()
stays a no-op).
Tests cover both drop paths.
Address two issues raised during review:
P1 – When a recording is cancelled or restarted, setRecordingState(false)
enqueues its cursor batch but store-recorded-session is never called,
leaving a stale batch that contaminates the next recording's telemetry.
Add discardLatestPending() to the buffer and a discard-cursor-telemetry
IPC handler; the renderer now calls it on the discard path.
P2 – takeNextBatch() dequeued the batch before fs.writeFile, so a write
failure would permanently lose the telemetry. Wrap the write in
try/catch and re-insert the batch via prependBatch() on failure.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously, the main process kept two module-scope arrays —
activeCursorSamples and pendingCursorSamples — and set-recording-state
on a new recording wiped BOTH. When a user stopped recording and
immediately started a new one before store-recorded-session fired,
the previous recording's pending samples were discarded or later
overwritten with the new session's data, producing empty or mismatched
.cursor.json files.
Replace the two arrays with a small FIFO buffer
(createCursorTelemetryBuffer) that:
- Keeps pending batches per completed recording, never wiping them on
a new session start.
- Yields batches in arrival order to storeRecordedSessionFiles.
- Caps pending batches (default 8) so a never-stored sequence cannot
leak unbounded memory.
Unit-tested directly in src/lib/cursorTelemetryBuffer.test.ts, including
the rapid-restart race that motivated the change.
Both windows had alwaysOnTop but lacked setVisibleOnAllWorkspaces, so
they stayed pinned to the Space they were first opened on. Users moving
to a different virtual desktop would lose sight of the overlay.
Calls setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true })
on macOS only — no-op on Windows/Linux so cross-platform behaviour is
unchanged.
- Add complete Korean locale across all 7 i18n namespaces
- All translation keys match the English baseline 1:1
- Register ko-KR in SUPPORTED_LOCALES and i18n-check validation
Refs siddharthvaddem/openscreen#406
The zh-CN locale was missing the 'newRecording' section in editor.json,
which is present in the en locale. This commit adds the translation for:
- title: 返回录屏
- description: 当前会话已保存。
- cancel: 取消
- confirm: 确认