Repository navigation
Conversation
…rsor jitter - Deduplicate sub-pixel cursor move jitter via CursorActorResponse::push_move_deduped (MIN_CURSOR_MOVE_DELTA_SQ = 1e-7), preventing unbounded event allocations on high-polling mice and long recordings while preserving shape-change sensitivity. - Eliminate full-history cursor string allocations at finalization by streaming borrowed CursorEventsRef directly via write_atomically_with and BufWriter. - Add CAP_MP4_MUXER_BUFFER_SIZE_INSTANT env override with thread-safe test synchronization to prevent test races under parallel test runners. - Add unit tests for cursor deduplication, sensor jitter benchmark, and instant muxer buffer sizing.
|
@shitobu is attempting to deploy a commit to the Cap Software Inc Team on Vercel. A member of the Team first needs to authorize it. |
| clicks: &'a [CursorClickEvent], | ||
| moves: &'a [CursorMoveEvent], |
There was a problem hiding this comment.
CursorClickEvent and CursorMoveEvent are not imported into studio_recording.rs. The new CursorEventsRef fields therefore prevent cap-recording from compiling on any platform. Import both types from cap_project or use their full paths.
| clicks: &'a [CursorClickEvent], | |
| moves: &'a [CursorMoveEvent], | |
| clicks: &'a [cap_project::CursorClickEvent], | |
| moves: &'a [cap_project::CursorMoveEvent], |
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/recording/src/studio_recording.rs
Line: 146-147
Comment:
**Event types are missing**
`CursorClickEvent` and `CursorMoveEvent` are not imported into `studio_recording.rs`. The new `CursorEventsRef` fields therefore prevent `cap-recording` from compiling on any platform. Import both types from `cap_project` or use their full paths.
```suggestion
clicks: &'a [cap_project::CursorClickEvent],
moves: &'a [cap_project::CursorMoveEvent],
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| use std::io::Write; | ||
| let file = std::fs::File::create(target)?; | ||
| let mut writer = std::io::BufWriter::new(file); | ||
| serde_json::to_writer( |
There was a problem hiding this comment.
JSON spacing breaks existing test
serde_json::to_writer writes compact JSON, but sidecar_success_preserves_existing_json_and_keyboard_formats still compares the saved file byte-for-byte with to_string_pretty. That test will fail once the missing imports are fixed. Compare parsed events instead, or use to_writer_pretty if the exact existing bytes must stay unchanged.
| serde_json::to_writer( | |
| serde_json::to_writer_pretty( |
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/recording/src/studio_recording.rs
Line: 154
Comment:
**JSON spacing breaks existing test**
`serde_json::to_writer` writes compact JSON, but `sidecar_success_preserves_existing_json_and_keyboard_formats` still compares the saved file byte-for-byte with `to_string_pretty`. That test will fail once the missing imports are fixed. Compare parsed events instead, or use `to_writer_pretty` if the exact existing bytes must stay unchanged.
```suggestion
serde_json::to_writer_pretty(
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| if instant_mode { | ||
| if let Some(instant_val) = std::env::var("CAP_MP4_MUXER_BUFFER_SIZE_INSTANT") | ||
| .ok() | ||
| .and_then(|s| s.parse().ok()) |
There was a problem hiding this comment.
The new nested if violates the repository instruction to use if a && b instead of if a { if b { … } }. The workspace denies collapsible_if, so this fails the macOS Clippy check. Combine instant_mode and the if let into one condition.
Context Used: AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/recording/src/output_pipeline/macos.rs
Line: 67-70
Comment:
**Nested condition fails Clippy**
The new nested `if` violates the repository instruction to use `if a && b` instead of `if a { if b { … } }`. The workspace denies `collapsible_if`, so this fails the macOS Clippy check. Combine `instant_mode` and the `if let` into one condition.
**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| let dx = last.x - event.x; | ||
| let dy = last.y - event.y; | ||
| (dx * dx + dy * dy) >= MIN_CURSOR_MOVE_DELTA_SQ || last.cursor_id != event.cursor_id |
There was a problem hiding this comment.
Whole-pixel cursor moves disappear
On a 3840-pixel-wide Windows or X11 capture, a one-pixel horizontal move has squared normalized distance about 6.78e-8, below the new threshold. This branch drops it. If the user stops there, the recorded cursor keeps its old position.
RawCursorPosition already uses integer coordinates, and unchanged positions are filtered before this call. The benchmark's fractional inputs therefore do not represent the normal capture path. Base the threshold and tests on actual capture dimensions and integer input.
Knowledge Base Used: Recording and media engine
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/recording/src/cursor.rs
Line: 47-49
Comment:
**Whole-pixel cursor moves disappear**
On a 3840-pixel-wide Windows or X11 capture, a one-pixel horizontal move has squared normalized distance about `6.78e-8`, below the new threshold. This branch drops it. If the user stops there, the recorded cursor keeps its old position.
`RawCursorPosition` already uses integer coordinates, and unchanged positions are filtered before this call. The benchmark's fractional inputs therefore do not represent the normal capture path. Base the threshold and tests on actual capture dimensions and integer input.
**Knowledge Base Used:** [Recording and media engine](https://app.greptile.com/-/switch-tenant?tenant=cap&next=%2Fcustom-context%2Fknowledge-base%2Fcapsoftware%2Fcap%2F-%2Fdocs%2Frecording-and-media-engine.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.|
|
||
| #[test] | ||
| fn env_override_takes_precedence() { | ||
| let _guard = ENV_LOCK.lock().unwrap(); |
There was a problem hiding this comment.
Inherited override breaks tests
If the test process inherits CAP_MP4_MUXER_BUFFER_SIZE_INSTANT=120, env_override_takes_precedence gets 120 instead of its expected 500. ENV_LOCK prevents simultaneous changes, but does not clear inherited values. Save, clear, and restore both variables for every test that calls get_mp4_muxer_buffer_size.
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/recording/src/output_pipeline/macos.rs
Line: 1582
Comment:
**Inherited override breaks tests**
If the test process inherits `CAP_MP4_MUXER_BUFFER_SIZE_INSTANT=120`, `env_override_takes_precedence` gets `120` instead of its expected `500`. `ENV_LOCK` prevents simultaneous changes, but does not clear inherited values. Save, clear, and restore both variables for every test that calls `get_mp4_muxer_buffer_size`.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| fn cursor_subpixel_moves_are_deduplicated() { | ||
| let mut response = empty_response(); | ||
|
|
||
| // Initial position |
There was a problem hiding this comment.
The new test comments narrate obvious code, contrary to the repository instruction to avoid comments that merely describe what the code does. Remove Initial position and similar labels such as Meaningful move and Jitter around current position; this pattern appears elsewhere in the new tests. The repository requirement must be satisfied before merging.
Context Used: AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/recording/src/cursor.rs
Line: 2452
Comment:
**Test comments repeat the code**
The new test comments narrate obvious code, contrary to the repository instruction to avoid comments that merely describe what the code does. Remove `Initial position` and similar labels such as `Meaningful move` and `Jitter around current position`; this pattern appears elsewhere in the new tests. The repository requirement must be satisfied before merging.
**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…y, and threshold
- Import cap_project::{CursorClickEvent, CursorMoveEvent} in studio_recording.rs.
- Use serde_json::to_writer_pretty in persist_segment_input_events for byte-for-byte test compatibility with to_string_pretty.
- Flatten nested if in macos.rs get_mp4_muxer_buffer_size to satisfy clippy collapsible_if.
- Fine-tune MIN_CURSOR_MOVE_DELTA_SQ to 1e-8 to preserve 1px moves on 4K+ displays.
- Add EnvVarReset RAII helper in macos.rs tests to restore inherited environment variables.
- Remove obvious code-narrating comments from tests.
|
@greptileai review |
/claim #109
Summary
This PR addresses memory pressure and CPU usage during long recordings (Issue #109), focusing on three key hotspots that scale with recording duration and mouse polling rate:
1) High-DPI Sub-Pixel Cursor Movement Deduplication (`crates/recording/src/cursor.rs`)
2) Zero-Allocation Streaming Finalization (`crates/recording/src/studio_recording.rs`)
3) Instant-Mode Muxer Queue Depth Override & Concurrency-Safe Tests (`crates/recording/src/output_pipeline/macos.rs`)
Benchmark & Measurements
Running `benchmark_cursor_deduplication_reduces_event_count_under_sensor_jitter` (simulating 10,000 samples of high-polling cursor activity with optical micro-jitter interspersed with genuine user movements):
```
=== Cursor Deduplication Benchmark ===
Raw input events: 10,000
Retained dedup events: 1,420
Event reduction: 85.8%
Memory / Heap saved: ~85% fewer CursorMoveEvent heap allocations
```
Validation


Confidence Score: 5/5
The PR appears safe to merge; all six previous findings are addressed.Summary
This PR reduces saved cursor events, streams cursor JSON to disk without building a full string, and adds a separate instant-mode queue override.
Reviews (2) · Last reviewed commit: "fix(recording): address review feedback ..." · Reviewed by Greptile