Split the long continuous block in `draw_footer` into smaller,
modular methods (`draw_mic_selection`, `draw_master_volume`,
`draw_hotkeys_button`, `draw_settings_button`) for better
readability and maintainability.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Extracted the main token processing loop body in `commands_loop` into `handle_connection` to resolve deep nesting and improve code readability.
- Improved request reading logic by using `(&mut stream).take(request_len as u64).read_to_end(&mut buffer)` to strictly bound allocation to `request_len` and prevent initialization overhead.
- Passed `cargo fmt` and `cargo clippy`.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Moved redundant struct initialization into `AudioDevice::new` and unified port mapping assignments in an `add_port` method. This removes nesting using early returns and eliminates an unnecessary clone on the hashmap conversion step.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
The `play` method in `src/types/audio_player.rs` previously used `.unwrap()`
directly on `self.stream_handle.as_ref()`. This posed a security/stability risk
where if `stream_handle` was uninitialized or became `None` unexpectedly
despite the prior `ensure_stream()` call, it would cause the thread to panic
and potentially crash the application.
This commit replaces the `.unwrap()` call with `.ok_or_else` to safely handle
the `None` case, returning an `anyhow` error instead of panicking, adhering to
the project's no-panic policy.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Replaced the monolithic `src/gui/draw.rs` with a new `src/gui/views` directory module.
The GUI drawing logic is now cleanly separated into distinct files:
- `body.rs`
- `footer.rs`
- `header.rs`
- `hotkey_capture.rs`
- `hotkeys.rs`
- `settings.rs`
- `waiting_for_daemon.rs`
This organization vastly improves readability and maintainability without altering functionality. All shared helpers are centralized in `src/gui/views/mod.rs` and imports are strictly managed.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
* 🔒 Fix insecure fallback directory and secure file creation
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>
* 🔒 Fix insecure fallback directory and secure file creation
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 safe `rustix::process::geteuid()` for robust cross-platform UID extraction, avoiding `unsafe` blocks.
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>
* small refactor
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
- Extracted search field rendering to `draw_files_search_field`
- Extracted list rendering to `draw_files_list`
- Split `draw_tree_node` file and directory branch logic to `draw_tree_node_file` and `draw_tree_node_dir`
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
This commit optimizes the GUI render loop in `src/gui/draw.rs` during the rendering of the drag and drop directory list. Previously, `self.app_state.dirs.clone()` was cloning the entire vector of `PathBuf`s on every frame, which caused unnecessary allocations.
Now, `std::mem::take` temporarily removes the list of directories from `app_state.dirs` inside `show_vec`, and items are passed by reference rather than being cloned (`let path = item;` instead of `item.clone()`). Finally, the original list is restored into `app_state.dirs`. To ensure the state doesn't mutate or invalidate when `self.open_dir(&path)` is clicked, this logic has been deferred to run after the `app_state` vector is restored.
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>