The daemon's fallback runtime directory `get_runtime_dir()` was hardcoded to `/run/pwsp`, creating a risk of shared, insecure access in multi-user systems.
This commit secures the fallback logic by:
1. Creating a user-specific temporary directory (`/tmp/pwsp-$UID`).
2. Ensuring directory creation happens atomically with `0o700` permissions using `std::fs::DirBuilder`.
3. Validating the fallback directory strictly (checking UID, 0o700 permissions, and symlink status) if it already exists to mitigate symlink attacks.
4. Using `libc::geteuid()` for robust cross-platform UID extraction.
5. Fixing `is_daemon_running` and locking logic to use `fs::OpenOptions` instead of `fs::File::create` to prevent accidental file truncation on active lock files.
Co-authored-by: arabianq <55220741+arabianq@users.noreply.github.com>
This optimization removes an unnecessary `.cloned()` call inside `draw_hotkeys_table`
which previously forced a clone of every filtered `HotkeySlot` on every frame render.
Instead, we now hold a `Vec<&HotkeySlot>` and only clone `slot.slot` exactly when
a user interaction requires ownership to dispatch a `HotkeyAction`.
This eliminates constant heap allocations of `String` and `Request` components
while scrolling or idling in the hotkeys view.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Break down the monolithic `draw_hotkeys` method into smaller,
focused component functions: `draw_hotkeys_header`,
`draw_hotkeys_search`, `draw_hotkeys_table`, and
`handle_hotkey_action`.
- Improve readability and maintainability of the `src/gui/draw.rs` file
while preserving identical behavior.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Extracted distinct UI sections (playback controls, position slider, volume controls, stop button) into their own well-scoped helper functions within `SoundpadGui`. This significantly improves the maintainability and readability of `draw_track_control` while preserving the existing layout structure and state mutation behavior.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* perf: optimize UI rendering loop by removing unnecessary Vec clone\n\n- Removed `clone()` on `self.audio_player_state.tracks` in `draw_header`\n- Iterated by reference instead of using an owned collection\n- Benchmarked and showed a significant performance improvement (7us -> 87ns)
Co-authored-by: arabianq <55220741+arabianq@users.noreply.github.com>
* build(flatpak): update cargo-sources.json to include criterion\n\nThe CI failed during the offline flatpak build because the newly added `criterion` dev-dependency was missing from `cargo-sources.json`. Regenerated `packages/flatpak/cargo-sources.json` to fix it.
Co-authored-by: arabianq <55220741+arabianq@users.noreply.github.com>
* Delete benches/ui_benchmark.rs
* refactor: remove garbage
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit addresses a security and stability vulnerability where failures in PipeWire context setup, connection, or registry acquisition would crash the entire thread (or daemon) via `.expect()` panics.
We now gracefully capture and propagate initialization errors up the call stack. A `sync_channel(0)` is used to signal the success or failure of the initial pipewire setup back to the calling functions (`get_all_devices`, `create_virtual_mic`, `create_link`). This prevents unexpected crashes and improves error resilience.
Also removed unneeded `pw_sender` panics on channel termination by simply dropping/ignoring the result.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* chore(ci): Add flatter to host Flatpak repo on GitHub Pages
- Update release.yml to not upload .flatpak file to releases
- Create flatter.yml to automate building and hosting of Flatpak via GitHub pages using andyholmes/flatter
- Add nightly branch for main pushes and stable branch for releases
- Update README.md with the new Flatpak installation instructions
Co-authored-by: arabianq <55220741+arabianq@users.noreply.github.com>
* Potential fix for pull request finding 'CodeQL / Workflow does not contain permissions'
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
* fix: truncate file button text in draw function so footer is no clipped
* fix(gui): fix hotkeys table clipping with egui_extras::TableBuilder
fully reworked hotkeys page
* deps: update flatpak cargo-sources.json
Add unit tests for parse_command in src/utils/commands.rs to ensure
robust handling of set_volume edge cases including missing or
invalid volume and id arguments.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Replaced `.chars().next().unwrap()` with `.chars().next().is_some_and(...)` in `chord_from_event` and `parse_chord` functions in `src/gui/input.rs`. This ensures that even if the string is empty, the application will not panic, adhering to the project's safety guidelines and resolving a potential security vulnerability.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Extract duplicated `pipewire::init()`, `MainLoopRc::new()`, and `ContextRc::new()` setup code from `pw_get_global_objects_thread`, `create_virtual_mic`, and `create_link` into a shared `setup_pipewire_context` helper in `src/utils/pipewire.rs`. Also ran codebase-wide linters to improve code quality.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>