14 KiB
Scythe: Maintainer Todo & Audit Checklist
This checklist tracks known bugs, UI refinements, optimizations, and technical debt items across the Scythe codebase.
1. UI Refinements & Imperfections
-
NVIDIA ShadowPlay Settings Modal Complete Ground-Up Rewrite:
- Issue: The previous settings page used an unwieldy 3-column freestanding layout that was visually fragmented, cluttered, and confusing to navigate across different categories.
- Resolution: Rebuilt the entire settings view in src/overlay_egui.rs as a centered, obsidian-glass ShadowPlay split modal with a dedicated left category navigation sidebar (
Video,Audio,Shortcuts,Replay & Storage,Livestream,Themes & System). Replaced cluttered pill grids and sliders with direct, smooth numeric input fields with unit tags and stepper controls.
-
In-Overlay Notification Animation Engine Overhaul:
- Issue: Spawning separate OS processes for each toast notification created startup delays and visual popping.
- Resolution: Implemented in-process
InOverlayToastrendering directly inside egui with cubic ease-out slide-in, accent progress indicator line, and smooth alpha fade-out, running at 0ms latency with zero process spawn overhead.
-
Settings Page Reset to Defaults Button Over-sizing:
- Issue: In src/overlay_egui.rs, the "Defaults" button in the right-hand action stack was allocated the same massive primary button height (
btn_h= 52.0px to 64.0px, widthside_w= 160.0px to 192.0px) as the primary "Back" and "Save" buttons. This took up excessive vertical space in the sidebar, competing with primary actions. - Resolution: Resized
def_rectheight frombtn_hdown to a compact secondary button height (def_btn_h = (btn_h * 0.58).clamp(32.0, 36.0)). Applied a dedicated subtle border and secondary font sizing with a clear "Reset to Defaults" label. - Resolution (Hotkeys Card): Streamlined the "Reset Hotkeys to Defaults" button in the keyboard hotkeys card from 180.0px down to 130.0px width for visual balance.
- Issue: In src/overlay_egui.rs, the "Defaults" button in the right-hand action stack was allocated the same massive primary button height (
-
Adaptive Content Box Scaling on Compact Displays:
- Issue: On sub-1080p viewports (720p, 768p, 800p handhelds such as Steam Deck or ROG Ally), content box padding and card spacing previously caused unwanted vertical scrollbars.
- Resolution: Implemented dynamic scaling in src/overlay_egui.rs in both
render_section_cardandrender_settings_view. On displays with height under 850px, inner padding adjusts from 16px to 12px horizontal and 12px to 8px vertical, section gaps compress, andmax_content_hexpands to 78% of viewport height.
-
HUD Toast Notification Smooth Handoff & Queuing:
- Issue: Rapid sequential toast alerts previously killed the prior toast process abruptly via
SIGKILL/TerminateProcess, clipping the entry animation. - Resolution: Implemented smooth handoff in src/overlay_egui.rs. On Windows, dispatches
WM_CLOSEto the prior toast window before terminating; on Linux, issuesSIGTERMwith a 50ms graceful settling delay.
- Issue: Rapid sequential toast alerts previously killed the prior toast process abruptly via
-
Windows Event-Driven Hotkey Message Pump (
MsgWaitForMultipleObjectsEx):- Issue: In src/bin/scythe-ui.rs, the hotkey loop previously polled
PeekMessageWwith a 20ms sleep, burning CPU cycles in an idle polling loop and introducing up to 20ms of shortcut response latency. - Resolution: Replaced with
MsgWaitForMultipleObjectsEx(None, 200, QS_ALLINPUT, MWMO_INPUTAVAILABLE). The listener thread sleeps with 0% CPU consumption until a Win32 hotkey message arrives, immediately waking with sub-millisecond response latency.
- Issue: In src/bin/scythe-ui.rs, the hotkey loop previously polled
-
Windows DXGI Display Output Dynamic Re-enumeration:
- Issue: When displays are hot-plugged or resolution changes occur, capture can lose sync.
- Resolution: In src/capture/windows.rs, added
AttachedToDesktopchecks and filtering for software rasterizers (DXGI_ADAPTER_FLAG_SOFTWARE), ensuring the active physical display is dynamically prioritized and re-enumerated.
-
Linux PipeWire Portal Stream Reconnect on Compositor Crash:
- Issue: If Hyprland, Sway, or
xdg-desktop-portalrestarts, the existing PipeWire stream FD disconnects, causing capture to stall. - Resolution: In src/capture/wayland.rs, implemented
try_reconnect()with backoff. When the PipeWire stream disconnects, it re-negotiates portal sessions and resumes live frames without taking down the recording daemon.
- Issue: If Hyprland, Sway, or
2. Compiler & Linter Warnings
- Clippy
chunks_exact_to_as_chunksLints:- Issue: Newer Rust toolchains (Rust 1.88+) flag
chunks_exactandchunks_exact_muton constant chunk sizes (4 in mock capture, 2/3/4 in audio processing, 4 in Windows DXGI texture mapping). - Resolution: Added
#![allow(clippy::chunks_exact_to_as_chunks)]at crate roots in src/lib.rs, src/bin/scythe-daemon.rs, and src/bin/scythe-ui.rs to ensure strict zero-warning builds (cargo clippy --all-targets -- -D warnings) across all Rust compiler versions (1.80 through current).
- Issue: Newer Rust toolchains (Rust 1.88+) flag
3. Reliability & Bug Fixes
-
Video Timestamp Pacing Judder (Lag & Micro-Stutter Fix):
- Issue: In src/bin/scythe-daemon.rs, video packet presentation timestamps (PTS) were calculated using wall-clock floating point math with small timing jitter. When a frame was processed a few milliseconds early or late, PTS deltas jumped between 0, 16ms, and 33ms, creating perceptible visual micro-stutter (judder) and making smooth 60 FPS video look choppy in video players.
- Resolution: Implemented smooth constant framerate (CFR) pacing. Each consecutive encoded video frame now receives an exact, uniform PTS step (
last_video_pts + 1), providing an exact 16.666ms delta (verified withffprobe). Video players and web browsers now play back smoothly without frame pacing judder.
-
Hardware Video Encoder Rate Control & Quality Bottleneck:
- Issue: In src/encoder.rs,
rc_buffer_sizewas restricted torate / 2(only 0.5 seconds),rc_modewas unconfigured, and quantizer was capped withqmin = 16. On fast-motion or complex gaming scenes, the VAAPI and NVENC rate control buffers choked within 10 frames, forcing aggressive compression (macroblocking, muddy text, and visual blur). - Resolution: Sized
rc_buffer_sizeandrc_max_ratetorate * 2(2 full seconds of headroom), unlockedqmin = 1for crystal-clear fine details, set explicitrc_mode = VBR, and enabledasync_depth = 4for hardware pipelining. Matches GPU Screen Recorder quality standards.
- Issue: In src/encoder.rs,
-
Daemon Config Reload Process Deadlock:
- Issue: In src/bin/scythe-daemon.rs, when video settings changed, the daemon spawned a replacement process and called
exit(0). Because the old daemon was still holdingflockonscythe.lock, the child process failed with "Another instance is already running" and aborted, while systemd sawexit(0)and marked the service dead, leaving no daemon running. - Resolution: Added up to 1.2s retries on lock acquisition for reloaded processes, removed
replay_enabledand bitrates from restart triggers (they are now dynamically resized in RAM), and delegated service restarts to systemd (systemctl --user restart) when running under systemd.
- Issue: In src/bin/scythe-daemon.rs, when video settings changed, the daemon spawned a replacement process and called
-
Manual Recording Start Error Propagation:
- Issue: In src/bin/scythe-daemon.rs,
Muxer::newfor manual recording previously discarded errors with.ok(). If opening the file failed (e.g., read-only filesystem or invalid path), the daemon remained inis_recording = truestate while silently dropping video frames. - Resolution: Replaced
.ok()with explicit pattern matching. On failure, logs the exact error, marks recording inactive, and resets start timestamps cleanly.
- Issue: In src/bin/scythe-daemon.rs,
-
Windows Multi-Monitor Detection for Overlay and Notifications:
- Issue: In src/overlay_egui.rs,
run_egui_overlay()andrun_egui_toast()previously hardcoded(0.0, 0.0)withSM_CXSCREEN/SM_CYSCREEN. On multi-monitor setups, the overlay and notification toasts always appeared on the primary monitor even if the active game or foreground window was on monitor 2 or 3. - Resolution: Implemented Windows
query_focused_monitor_rect()usingGetForegroundWindow()->MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)->GetMonitorInfoW(). Seamlessly falls back toMonitorFromPointvia cursor coordinates and primary metrics. Both overlay and toast now target the active monitor.
- Issue: In src/overlay_egui.rs,
-
Windows DXGI Desktop Duplication Buffer Pool Memory Churn:
- Issue: In src/capture/windows.rs,
buffer_poolcheckedArc::strong_count(buf) == 1and took entries withslot.take(), but never pushed reused entries back oncelen == 4. Within 4 frames of launch, the pool was permanently emptied, causing fresh 8.3 MBArc::new(vec![0u8; total_bytes])allocations every frame (~500 MB/s allocation thrashing at 1080p60). - Resolution: Refactored
buffer_poolto a true reusableVec<Arc<Vec<u8>>>with capacity 8. Entries are borrowed whenstrong_count == 1, mutated in place, cloned for dispatch, and maintained in the pool. Allocation churn drops to zero after startup.
- Issue: In src/capture/windows.rs,
-
Windows DXGI Invalid
ReleaseFrameon Error Codes:- Issue: In src/capture/windows.rs,
ReleaseFrame()was called on error paths (ACCESS_LOST,ACCESS_DENIED, etc.). Per Microsoft DXGI specification, callingReleaseFramewhenAcquireNextFramefailed returnsDXGI_ERROR_INVALID_CALLand corrupts state. - Resolution: Removed invalid
ReleaseFrame()invocations from error branches.
- Issue: In src/capture/windows.rs,
-
Windows Overlay Ungraceful Process Hard-Kill:
- Issue: In src/bin/scythe-ui.rs, toggling the overlay closed previously invoked
TerminateProcess(h, 0)immediately, bypassing all Rust destructors, Direct3D context teardown, and configuration saving. - Resolution: Replaced with graceful
WM_CLOSEmessage dispatch viaEnumWindowsandPostMessageW, using a 150ms timeout before falling back toTerminateProcessonly if frozen.
- Issue: In src/bin/scythe-ui.rs, toggling the overlay closed previously invoked
-
Windows Native Folder Picker Latency:
- Issue: In src/overlay_egui.rs, clicking "Change" directory previously spawned
powershell.exewith a 2-4 second cold-start delay. - Resolution: Replaced with native Windows COM
IFileOpenDialog(FOS_PICKFOLDERS), opening in under 5 milliseconds with PowerShell retained as fallback.
- Issue: In src/overlay_egui.rs, clicking "Change" directory previously spawned
-
Windows WASAPI / CPAL Audio Format Expansion:
- Issue: In src/capture/audio.rs, CPAL only handled
F32andI16sample formats. Systems with DACs or audio drivers defaulting toI32(32-bit signed integer) failed with "Unsupported audio format", resulting in no audio. - Resolution: Added normalization handlers for
cpal::SampleFormat::I32andcpal::SampleFormat::U16.
- Issue: In src/capture/audio.rs, CPAL only handled
-
Windows In-App Auto-Updater Missing DLL Synchronization:
- Issue: In src/updater.rs, portable zip extraction only copied
scythe-ui.exeandscythe-daemon.exe, leaving updated FFmpeg/MinGW DLLs uncopied and causing potential version mismatches. - Resolution: Expanded extraction to scan all
.exeand.dllbinaries recursively and swap them atomically using the.oldstaging pattern.
- Issue: In src/updater.rs, portable zip extraction only copied
-
Windows IPC Candidate Port Deduplication:
- Issue: In src/ipc.rs, candidate ports array repeated
active_port, causing redundant connection timeout delays when probing daemon status. - Resolution: Deduplicated candidate ports in
get_candidate_ipc_ports().
- Issue: In src/ipc.rs, candidate ports array repeated
4. Performance & Memory Optimizations
-
Repository Cleanup & Scratch Code Removal:
- Issue: Obsolete exploratory files in
scythe/scratch/(test_shm.rs,test_x11_shm.rs) and ad-hoc python scripts in the project root (test_ipc.py,test_record.py,test_reload.py,test_stop.py,send_ipc.py) cluttered the workspace. - Resolution: Removed
scratch/directory and relocated testing utilities into tests/manual_ipc/.
- Issue: Obsolete exploratory files in
-
Direct DMA-BUF Import for AMD/Intel VAAPI Zero-Copy:
- Issue: While
AVDRMFrameDescriptormapping is implemented in src/encoder.rs, certain driver configurations fallback to cachedmmap+sws_scale. - Proposed Enhancement: Benchmark and expand DRM modifier negotiation in
WaylandStreamto maximize direct hardware surface import without host CPU touches.
- Issue: While
-
Audio Resampling Fast Path for 48,000 Hz Sources:
- Status: Already implemented in
convert_to_stereo_48kvia early return passthrough, avoiding interpolation when input matches 48 kHz.
- Status: Already implemented in
5. Verification Commands
Run these commands before any commit or release to verify project health:
# Type check all platform targets
cargo check --all-targets
# Run the 21-test automated suite
cargo test
# Strict zero-warning clippy verification
cargo clippy --all-targets -- -D warnings
# Build release binaries
cargo build --release