11 KiB
Settings UI and Notification Engine Redesign Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Rebuild the Scythe settings UI into a clean, centered NVIDIA ShadowPlay-style split-panel modal with smooth direct numeric input fields and implement a zero-latency in-overlay toast animation system with graceful standalone toast handoff.
Architecture: Replace the legacy 3-column freestanding page stack in src/overlay_egui.rs with a unified ShadowPlayView::Settings(SettingsTab) modal. Implement numeric inputs with bounds clamping and inline stepper buttons. Replace external toast process killing with in-overlay egui animation banners and graceful window messaging.
Tech Stack: Rust 2024 edition, egui / eframe 0.31, Win32 DWM / Windows COM, Wayland layer-shell.
Spec: docs/superpowers/specs/2026-10-04-settings-ui-and-notifications-redesign.md
Global Constraints
- Absolutely zero emojis across code, comments, logs, test outputs, and commits.
- Clickable markdown links formatted with the
file://scheme. - Complete conditional compilation safety across Linux and Windows.
- No blocking operations on UI rendering loops.
Review Focus
- Sub-1080p display clipping: Modal must adaptively scale below 850px viewport heights without overflowing the screen.
- Direct numeric string parsing: Typing non-numeric characters in FPS, Bitrate, or Duration fields must not crash or corrupt settings state.
- Rapid hotkey keycap binding: Entering key listener mode must capture multi-modifier shortcuts (
Ctrl+Shift+R,Alt+Z) cleanly and allow cancellation withEscape. - Simultaneous in-overlay notifications: Multiple sequential alerts must reset duration or smoothly update without graphical popping.
- Multi-monitor Windows geometry: Standalone toasts and modals must respect active monitor bounds when
monitor_xis negative or non-zero.
Task 1: Data Structures, Enums, and Numeric Input Component
Files:
- Modify:
src/overlay_egui.rs - Test:
src/overlay_egui.rs
Interfaces:
-
Produces:
pub enum SettingsTab { Video, Audio, Shortcuts, ReplayAndStorage, Livestream, AppearanceAndSystem }pub enum ShadowPlayView { MainHud, Settings(SettingsTab), Gallery }pub fn numeric_input_box(ui: &mut egui::Ui, value_str: &mut String, val: &mut u32, min: u32, max: u32, step: u32, unit: &str, accent: Color32) -> boolpub struct InOverlayToast { pub title: String, pub subtitle: String, pub icon: ToastIcon, pub created_at: Instant, pub duration: Duration }
-
Step 1: Write unit tests for numeric input bounds and Tab enums
In src/overlay_egui.rs tests module:
#[test]
fn test_numeric_input_clamping_and_validation() {
let mut val = 60u32;
let mut text = "60".to_string();
assert!((15..=360).contains(&val));
// Test text update
text = "144".to_string();
if let Ok(parsed) = text.trim().parse::<u32>() {
val = parsed.clamp(15, 360);
}
assert_eq!(val, 144);
// Test out of bounds clamping
text = "999".to_string();
if let Ok(parsed) = text.trim().parse::<u32>() {
val = parsed.clamp(15, 360);
}
assert_eq!(val, 360);
}
- Step 2: Run test to verify it passes or fails
Run: cargo test --lib test_numeric_input_clamping_and_validation
- Step 3: Define
SettingsTabandnumeric_input_boxinsrc/overlay_egui.rs
Implement:
-
SettingsTabenum withVideo,Audio,Shortcuts,ReplayAndStorage,Livestream,AppearanceAndSystem. -
numeric_input_boxrendering a dark input box with[-]and[+]stepper buttons and unit label. -
Add
active_tab: SettingsTabandin_overlay_toast: Option<InOverlayToast>toScytheOverlayApp. -
Step 4: Verify compilation
Run: cargo check --all-targets
- Step 5: Commit
git add src/overlay_egui.rs
git commit -m "feat(ui): add SettingsTab enum, InOverlayToast struct, and numeric input component"
Task 2: Unified Centered ShadowPlay Settings Modal Layout
Files:
- Modify:
src/overlay_egui.rs - Test:
src/overlay_egui.rs
Interfaces:
-
Consumes:
SettingsTab,ScytheOverlayApp,accent_color(). -
Produces:
render_settings_modal(&mut self, ctx: &egui::Context, ui: &mut egui::Ui). -
Step 1: Write layout geometry test for settings modal
In src/overlay_egui.rs tests module:
#[test]
fn test_settings_modal_geometry_bounds() {
for (screen_w, screen_h) in [(1280.0, 720.0), (1920.0, 1080.0), (2560.0, 1440.0), (3840.0, 2160.0)] {
let is_compact_h = screen_h < 850.0;
let modal_w = if screen_w < 1400.0 { 680.0 } else { 760.0 };
let modal_h = if is_compact_h { 450.0 } else { 520.0 };
let pos_x = (screen_w - modal_w) * 0.5;
let pos_y = (screen_h - modal_h) * 0.5;
assert!(pos_x >= 0.0);
assert!(pos_y >= 0.0);
assert!(pos_x + modal_w <= screen_w);
assert!(pos_y + modal_h <= screen_h);
}
}
- Step 2: Run test to verify it passes
Run: cargo test --lib test_settings_modal_geometry_bounds
-
Step 3: Implement
render_settings_modal -
Centered modal container (
modal_w x modal_h) with obsidian glass fill#101418and top accent line. -
Left sidebar (
190pxwidth) with vertical tab buttons forVideo,Audio,Shortcuts,Replay & Storage,Livestream,Appearance & System. -
Active tab highlight with accent pill border and crisp text.
-
Compact "Reset to Defaults" button and version tag at sidebar footer.
-
Close button (
X) and "Done" button at top-right. -
Clicking outside or pressing Escape returns to
ShadowPlayView::MainHud. -
Step 4: Run compiler check
Run: cargo check --all-targets
- Step 5: Commit
git add src/overlay_egui.rs
git commit -m "feat(ui): implement centered ShadowPlay settings modal with tab navigation"
Task 3: Category Settings Panels Implementation
Files:
- Modify:
src/overlay_egui.rs
Interfaces:
-
Produces:
render_tab_videorender_tab_audiorender_tab_shortcutsrender_tab_replay_storagerender_tab_livestreamrender_tab_appearance_system
-
Step 1: Implement
render_tab_video- Numeric input box for Target Framerate (
15to360FPS) with[-]and[+]steppers. - Numeric input box for Recording Bitrate (
5to150Mbps). - Codec selector (
H.264,HEVC,AV1). - Toggle switch for "Record mouse cursor".
- Numeric input box for Target Framerate (
-
Step 2: Implement
render_tab_audio- Source selector (
System Audio,Microphone,Both,Muted). - Sliders for System Volume (0-100%) and Mic Volume (0-100%).
- Live stereo VU meters with soft-limit indicators.
- Source selector (
-
Step 3: Implement
render_tab_shortcuts- Interactive cards for
Menu Overlay,Save Replay,Start/Stop Record,Toggle Cursor. - Click to listen for key combinations, with instant rebind and Esc to cancel.
- Interactive cards for
-
Step 4: Implement
render_tab_replay_storage- Numeric input box for Replay Buffer Duration (
5to1800seconds). - Calculated RAM footprint badge.
- Path input with "Browse" button (invoking native Windows COM
IFileOpenDialog/ Linux portal) and "Open Folder".
- Numeric input box for Replay Buffer Duration (
-
Step 5: Implement
render_tab_livestreamandrender_tab_appearance_system- Service dropdown (
Twitch,YouTube,Kick,Custom RTMP), URL, and masked stream key field. - 8 accent color chips with instant preview.
- Startup toggles ("Start replay on login", "Open overlay on login").
- In-app version checker with "Check for Updates" button.
- Service dropdown (
-
Step 6: Run verification and tests
Run: cargo check --all-targets && cargo test
- Step 7: Commit
git add src/overlay_egui.rs
git commit -m "feat(ui): implement clean settings tab panels with numeric input boxes"
Task 4: In-Overlay Notification Animation Engine & Standalone Toast Overhaul
Files:
- Modify:
src/overlay_egui.rs - Test:
src/overlay_egui.rs
Interfaces:
-
Produces:
ScytheOverlayApp::show_hud_notification(queues in-processInOverlayToast)render_in_overlay_toast(&mut self, ctx: &egui::Context, ui: &mut egui::Ui)- Overhauled
run_egui_toastwith cubic ease-out animation
-
Step 1: Write test for cubic ease-out calculation
#[test]
fn test_cubic_ease_out_progress() {
let ease_out = |t: f32| -> f32 {
let inv = 1.0 - t.clamp(0.0, 1.0);
1.0 - inv * inv * inv
};
assert_eq!(ease_out(0.0), 0.0);
assert_eq!(ease_out(1.0), 1.0);
assert!(ease_out(0.5) > 0.5); // Fast start, gentle deceleration
}
- Step 2: Run test to verify it passes
Run: cargo test --lib test_cubic_ease_out_progress
-
Step 3: Implement
render_in_overlay_toast- Paints floating notification banner in top-right corner of overlay.
0.0s – 0.22s: Slide in from right viewport margin using cubic ease-out.0.22s – 2.4s: Fully visible with icon, bold title, subtitle, and discharging accent progress line.2.4s – 2.7s: Smooth alpha fade-out to zero.- Renders directly in the egui viewport with zero process spawning overhead.
-
Step 4: Refactor
run_egui_toaststandalone window- Uses the same cubic ease-out curve and ShadowPlay aesthetic card.
- Positioned at
(active_mon_x + active_mon_w - 364, active_mon_y + 24). - Clean automatic exit after 2.7s duration.
-
Step 5: Verify compiler and tests
Run: cargo check --all-targets && cargo test
- Step 6: Commit
git add src/overlay_egui.rs
git commit -m "feat(ui): implement in-overlay toast animation engine and overhaul standalone toasts"
Task 5: Integration, End-to-End Verification, and Build Deployment
Files:
-
Modify:
TODO_CHECKLIST.md -
Test:
tests/e2e_test.sh -
Step 1: Run clippy and check across all targets
Run: cargo clippy --all-targets -- -D warnings
Expected: 0 warnings, 0 errors.
- Step 2: Run full unit test suite
Run: cargo test
Expected: All tests pass.
- Step 3: Run end-to-end integration test
Run: bash tests/e2e_test.sh
Expected: Recording and replay succeed without corruption.
- Step 4: Compile release binaries and install locally
Run: cargo build --release && bash install.sh
Expected: Fresh binaries deployed to ~/.local/bin/ and daemon restarted.
- Step 5: Commit final changes
git add TODO_CHECKLIST.md
git commit -m "chore: update maintainer checklist with settings modal and notification overhaul"