scythe/TODO_CHECKLIST.md

19 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

  • Sharp Dark Slate Window Architecture with Drop Shadows (Matching GSR Screenshots):

    • Issue: The UI previously had curved/rounded edges and embedded horizontal accent bars that felt uncharacteristic of native GPU screen recorder overlays.
    • Resolution: Redesigned all overlay windows in src/overlay_egui.rs to match the visual language of the provided GPU Screen Recorder screenshots:
      • Deep charcoal slate background (#15191E), crisp #1D2228 section cards, and #14181E inset boxes.
      • Zero roundness (CornerRadius::ZERO) across all windows, buttons, segmented pills, toggle switches, and inputs.
      • Added multi-layered deep drop shadow effects (draw_window_shadow) behind the floating settings window and dropdown menus.
      • Removed all top horizontal accent bars from the settings modal and card dropdowns.
  • Dedicated Screenshot Feature & Settings Panel:

    • Issue: Screenshot functionality lacked a dedicated settings panel and CLI access.
    • Resolution:
      • Added a dedicated Screenshot Settings menu (SettingsTab::Screenshot) with destination folder configuration (Browse & Open), format selection (PNG (Lossless) vs JPEG), cursor capture toggle, hotkey display, CLI command reference (scythe-ui --screenshot), and instant capture trigger.
      • Added scythe-ui --screenshot CLI command and registered global hotkey (Ctrl+Shift+S) across Hyprland and Windows/X11.
  • Comprehensive Customizability & Options Expansion:

    • Issue: Settings lacked granular capture and audio controls shown in GPU Screen Recorder.
    • Resolution: Expanded settings across all 5 menus:
      • Instant Replay: Replay duration (sec/formatted time), RAM vs Disk storage selection, low-power mode toggle, game-based naming, replay notification toggles, autostart rules (on startup, on game launch, power supply condition), and video bitrate in Kbps/Mbps.
      • Normal Recording: Capture source selection (Focused monitor, Monitor eDP-1, Window, Region), resolution change toggle, audio track management with output/input/application audio routing, audio codecs (Opus vs AAC), volume sliders with live meters, and color range (Full vs Limited).
      • Broadcast LIVE: Streaming services (Twitch, YouTube, Kick, Custom RTMP), URL, masked stream key with eye toggle, and streaming quality parameters.
      • General Settings: Interface accent palette chips, global keyboard shortcuts rebinding, and autostart toggles.
  • Four Dedicated Independent Settings Menus:

    • Issue: Settings options were previously mixed across different tabs rather than dedicated to the specific feature chosen.
    • Resolution: Refactored SettingsTab into 4 dedicated menus:
      1. Instant Replay: Buffer Duration (numeric box + RAM footprint badge), Replay FPS, Replay Bitrate, Codec, Cursor toggle, Save Directory, Audio Source.
      2. Normal Recording: Record FPS, Record Bitrate, Codec, Cursor toggle, Save Directory, Audio Source & Volume sliders with live VU meters.
      3. Broadcast LIVE: Service selector, Server URL, Stream Key (masked with unmask toggle), Stream FPS, Stream Bitrate, Audio Source.
      4. General Settings: Accent Color Theme chips, Keyboard Shortcuts (interactive listener cards), Startup integration, Software Updates.
  • Floating Frosted Glass Dropdowns on HUD Cards:

    • Issue: Dropdowns beneath HUD cards were harsh black rectangles flush against the cards.
    • Resolution: Rebuilt dropdowns with floating glass containers (CornerRadius::same(10), #10141A at 97% opacity, 1px soft stroke, 2.5px top accent line). Dropdown items feature smooth CornerRadius::same(6) hover pills, clean typography, right-aligned hotkey badges, and direct links to each feature's dedicated settings menu.
  • Silky Ease-In and Smooth Haste Exit Notification Animations:

    • Issue: Notifications felt sluggish on exit and lacked snappy responsiveness.
    • Resolution: Implemented silky cubic ease-out entrance (1.0 - (1.0 - t).powi(3)) over 280ms, a legible hold, and a swift smooth-haste exit slide over 200ms with smoothstep acceleration (t * t * (3.0 - 2.0 * t)). Styled notification cards with CornerRadius::same(10) and curved top accent bar.
  • 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 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.
  • 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, 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.
  • 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_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.
  • 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_CLOSE to the prior toast window before terminating; on Linux, issues SIGTERM with a 50ms graceful settling delay.
  • Windows Event-Driven Hotkey Message Pump (MsgWaitForMultipleObjectsEx):

    • Issue: In 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.
  • 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 AttachedToDesktop checks 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-portal restarts, 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.

2. Compiler & Linter Warnings

  • 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, 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).

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 with ffprobe). 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_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.
  • 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 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.
  • Manual Recording Start Error Propagation:

    • Issue: In 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.
  • Windows Multi-Monitor Detection for Overlay and Notifications:

    • Issue: In 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.
  • Windows DXGI Desktop Duplication Buffer Pool Memory Churn:

    • Issue: In 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.
  • Windows DXGI Invalid ReleaseFrame on Error Codes:

    • Issue: In 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.
  • 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_CLOSE message dispatch via EnumWindows and PostMessageW, using a 150ms timeout before falling back to TerminateProcess only if frozen.
  • Windows Native Folder Picker Latency:

    • Issue: In 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.
  • Windows WASAPI / CPAL Audio Format Expansion:

    • Issue: In 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.
  • Windows In-App Auto-Updater Missing DLL Synchronization:

    • Issue: In 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.
  • 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().

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/.
  • Direct DMA-BUF Import for AMD/Intel VAAPI Zero-Copy:

    • Issue: While AVDRMFrameDescriptor mapping is implemented in 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:

# 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