135 lines
14 KiB
Markdown
135 lines
14 KiB
Markdown
# 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
|
|
|
|
- [x] **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](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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.
|
|
|
|
- [x] **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 `InOverlayToast` rendering 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.
|
|
|
|
- [x] **Settings Page Reset to Defaults Button Over-sizing**:
|
|
- **Issue**: In [src/overlay_egui.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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, width `side_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_rect` height from `btn_h` down 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.
|
|
|
|
- [x] **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](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/overlay_egui.rs) in both `render_section_card` and `render_settings_view`. On displays with height under 850px, inner padding adjusts from 16px to 12px horizontal and 12px to 8px vertical, section gaps compress, and `max_content_h` expands to 78% of viewport height.
|
|
|
|
- [x] **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](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/overlay_egui.rs). On Windows, dispatches `WM_CLOSE` to the prior toast window before terminating; on Linux, issues `SIGTERM` with a 50ms graceful settling delay.
|
|
|
|
- [x] **Windows Event-Driven Hotkey Message Pump (`MsgWaitForMultipleObjectsEx`)**:
|
|
- **Issue**: In [src/bin/scythe-ui.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/bin/scythe-ui.rs), the hotkey loop previously polled `PeekMessageW` with 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.
|
|
|
|
- [x] **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](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/capture/windows.rs), added `AttachedToDesktop` checks and filtering for software rasterizers (`DXGI_ADAPTER_FLAG_SOFTWARE`), ensuring the active physical display is dynamically prioritized and re-enumerated.
|
|
|
|
- [x] **Linux PipeWire Portal Stream Reconnect on Compositor Crash**:
|
|
- **Issue**: If Hyprland, Sway, or `xdg-desktop-portal` restarts, the existing PipeWire stream FD disconnects, causing capture to stall.
|
|
- **Resolution**: In [src/capture/wayland.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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.
|
|
|
|
---
|
|
|
|
## 2. Compiler & Linter Warnings
|
|
|
|
- [x] **Clippy `chunks_exact_to_as_chunks` Lints**:
|
|
- **Issue**: Newer Rust toolchains (Rust 1.88+) flag `chunks_exact` and `chunks_exact_mut` on 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](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/lib.rs), [src/bin/scythe-daemon.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/bin/scythe-daemon.rs), and [src/bin/scythe-ui.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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).
|
|
|
|
---
|
|
|
|
## 3. Reliability & Bug Fixes
|
|
|
|
- [x] **Video Timestamp Pacing Judder (Lag & Micro-Stutter Fix)**:
|
|
- **Issue**: In [src/bin/scythe-daemon.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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 with `ffprobe`). Video players and web browsers now play back smoothly without frame pacing judder.
|
|
|
|
- [x] **Hardware Video Encoder Rate Control & Quality Bottleneck**:
|
|
- **Issue**: In [src/encoder.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/encoder.rs), `rc_buffer_size` was restricted to `rate / 2` (only 0.5 seconds), `rc_mode` was unconfigured, and quantizer was capped with `qmin = 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_size` and `rc_max_rate` to `rate * 2` (2 full seconds of headroom), unlocked `qmin = 1` for crystal-clear fine details, set explicit `rc_mode = VBR`, and enabled `async_depth = 4` for hardware pipelining. Matches GPU Screen Recorder quality standards.
|
|
|
|
- [x] **Daemon Config Reload Process Deadlock**:
|
|
- **Issue**: In [src/bin/scythe-daemon.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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 holding `flock` on `scythe.lock`, the child process failed with "Another instance is already running" and aborted, while systemd saw `exit(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_enabled` and bitrates from restart triggers (they are now dynamically resized in RAM), and delegated service restarts to systemd (`systemctl --user restart`) when running under systemd.
|
|
|
|
- [x] **Manual Recording Start Error Propagation**:
|
|
- **Issue**: In [src/bin/scythe-daemon.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/bin/scythe-daemon.rs), `Muxer::new` for manual recording previously discarded errors with `.ok()`. If opening the file failed (e.g., read-only filesystem or invalid path), the daemon remained in `is_recording = true` state 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.
|
|
|
|
- [x] **Windows Multi-Monitor Detection for Overlay and Notifications**:
|
|
- **Issue**: In [src/overlay_egui.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/overlay_egui.rs), `run_egui_overlay()` and `run_egui_toast()` previously hardcoded `(0.0, 0.0)` with `SM_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()` using `GetForegroundWindow()` -> `MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)` -> `GetMonitorInfoW()`. Seamlessly falls back to `MonitorFromPoint` via cursor coordinates and primary metrics. Both overlay and toast now target the active monitor.
|
|
|
|
- [x] **Windows DXGI Desktop Duplication Buffer Pool Memory Churn**:
|
|
- **Issue**: In [src/capture/windows.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/capture/windows.rs), `buffer_pool` checked `Arc::strong_count(buf) == 1` and took entries with `slot.take()`, but never pushed reused entries back once `len == 4`. Within 4 frames of launch, the pool was permanently emptied, causing fresh 8.3 MB `Arc::new(vec![0u8; total_bytes])` allocations every frame (~500 MB/s allocation thrashing at 1080p60).
|
|
- **Resolution**: Refactored `buffer_pool` to a true reusable `Vec<Arc<Vec<u8>>>` with capacity 8. Entries are borrowed when `strong_count == 1`, mutated in place, cloned for dispatch, and maintained in the pool. Allocation churn drops to zero after startup.
|
|
|
|
- [x] **Windows DXGI Invalid `ReleaseFrame` on Error Codes**:
|
|
- **Issue**: In [src/capture/windows.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/capture/windows.rs), `ReleaseFrame()` was called on error paths (`ACCESS_LOST`, `ACCESS_DENIED`, etc.). Per Microsoft DXGI specification, calling `ReleaseFrame` when `AcquireNextFrame` failed returns `DXGI_ERROR_INVALID_CALL` and corrupts state.
|
|
- **Resolution**: Removed invalid `ReleaseFrame()` invocations from error branches.
|
|
|
|
- [x] **Windows Overlay Ungraceful Process Hard-Kill**:
|
|
- **Issue**: In [src/bin/scythe-ui.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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_CLOSE` message dispatch via `EnumWindows` and `PostMessageW`, using a 150ms timeout before falling back to `TerminateProcess` only if frozen.
|
|
|
|
- [x] **Windows Native Folder Picker Latency**:
|
|
- **Issue**: In [src/overlay_egui.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/overlay_egui.rs), clicking "Change" directory previously spawned `powershell.exe` with 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.
|
|
|
|
- [x] **Windows WASAPI / CPAL Audio Format Expansion**:
|
|
- **Issue**: In [src/capture/audio.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/capture/audio.rs), CPAL only handled `F32` and `I16` sample formats. Systems with DACs or audio drivers defaulting to `I32` (32-bit signed integer) failed with "Unsupported audio format", resulting in no audio.
|
|
- **Resolution**: Added normalization handlers for `cpal::SampleFormat::I32` and `cpal::SampleFormat::U16`.
|
|
|
|
- [x] **Windows In-App Auto-Updater Missing DLL Synchronization**:
|
|
- **Issue**: In [src/updater.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/updater.rs), portable zip extraction only copied `scythe-ui.exe` and `scythe-daemon.exe`, leaving updated FFmpeg/MinGW DLLs uncopied and causing potential version mismatches.
|
|
- **Resolution**: Expanded extraction to scan all `.exe` and `.dll` binaries recursively and swap them atomically using the `.old` staging pattern.
|
|
|
|
- [x] **Windows IPC Candidate Port Deduplication**:
|
|
- **Issue**: In [src/ipc.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/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()`.
|
|
|
|
---
|
|
|
|
## 4. Performance & Memory Optimizations
|
|
|
|
- [x] **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/](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/tests/manual_ipc).
|
|
|
|
- [ ] **Direct DMA-BUF Import for AMD/Intel VAAPI Zero-Copy**:
|
|
- **Issue**: While `AVDRMFrameDescriptor` mapping is implemented in [src/encoder.rs](file:///home/oiupoyt/my%20stuff%20yea/projects/scythe/src/encoder.rs), certain driver configurations fallback to cached `mmap` + `sws_scale`.
|
|
- **Proposed Enhancement**: Benchmark and expand DRM modifier negotiation in `WaylandStream` to maximize direct hardware surface import without host CPU touches.
|
|
|
|
- [ ] **Audio Resampling Fast Path for 48,000 Hz Sources**:
|
|
- **Status**: Already implemented in `convert_to_stereo_48k` via early return passthrough, avoiding interpolation when input matches 48 kHz.
|
|
|
|
---
|
|
|
|
## 5. Verification Commands
|
|
|
|
Run these commands before any commit or release to verify project health:
|
|
|
|
```bash
|
|
# 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
|
|
```
|