mirror of
https://github.com/arabianq/pipewire-soundpad.git
synced 2026-06-19 20:23:33 +00:00
a156df346b
* feat: add hotkey system for playing individual sounds Slot-based hotkey mappings stored in ~/.config/pwsp/hotkeys.json. Daemon serves hotkey IPC commands for CLI/compositor bindings. GUI supports focused hotkey triggers, a dedicated Hotkeys panel with search and conflict detection, file badges, and a key chord capture dialog. CLI gains play-hotkey, get hotkeys, set hotkey, set hotkey-key, and clear-hotkey subcommands. * feat: add global hotkey support via evdev Listen for keyboard events directly from /dev/input using evdev, enabling hotkeys to work system-wide regardless of window focus or display server (X11, GNOME, KDE Plasma, Hyprland). The daemon spawns async listeners for each keyboard device at startup, tracks modifier state, and triggers playback when a configured chord matches. Requires the user to be in the 'input' group; logs a warning and continues without global hotkeys if devices are inaccessible. * various changes * refactor: route hotkey mutations through daemon IPC GUI no longer writes hotkey config directly to disk. Instead, all mutations (set slot, set key chord, clear chord, remove slot) are sent to the daemon via IPC, which persists the changes. The state thread periodically syncs the hotkey config back from the daemon, so CLI-made changes are reflected in the GUI. New IPC commands: set_hotkey_action (arbitrary action per slot), clear_hotkey_key (remove key chord without removing the slot). Also removes unreachable capture overlay from draw_hotkeys(). * small refactor --------- Co-authored-by: arabian <a.tevg@ya.ru>
74 lines
1.6 KiB
Rust
74 lines
1.6 KiB
Rust
use crate::types::{
|
|
audio_player::{PlayerState, TrackInfo},
|
|
config::HotkeyConfig,
|
|
};
|
|
|
|
use egui::Id;
|
|
|
|
use std::{
|
|
collections::{HashMap, HashSet},
|
|
path::PathBuf,
|
|
time::Instant,
|
|
};
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct TrackUiState {
|
|
pub position_slider_value: f32,
|
|
pub volume_slider_value: f32,
|
|
|
|
pub position_dragged: bool,
|
|
pub volume_dragged: bool,
|
|
|
|
pub ignore_position_update_until: Option<Instant>,
|
|
pub ignore_volume_update_until: Option<Instant>,
|
|
}
|
|
|
|
#[derive(Default, Debug)]
|
|
pub struct AppState {
|
|
pub search_query: String,
|
|
|
|
pub track_ui_states: HashMap<u32, TrackUiState>,
|
|
|
|
pub show_settings: bool,
|
|
pub volume_dragged: bool,
|
|
pub force_focus_search: bool,
|
|
|
|
pub volume_slider_value: f32,
|
|
|
|
pub search_field_id: Option<Id>,
|
|
|
|
pub ignore_volume_update_until: Option<Instant>,
|
|
|
|
pub current_dir: Option<PathBuf>,
|
|
pub dirs: Vec<PathBuf>,
|
|
pub dirs_to_remove: HashSet<PathBuf>,
|
|
|
|
pub selected_file: Option<PathBuf>,
|
|
pub files: HashSet<PathBuf>,
|
|
|
|
pub show_hotkeys: bool,
|
|
pub hotkey_config: HotkeyConfig,
|
|
pub hotkey_search_query: String,
|
|
pub assigning_hotkey_slot: Option<String>,
|
|
pub assigning_hotkey_for_file: Option<PathBuf>,
|
|
pub hotkey_capture_active: bool,
|
|
}
|
|
|
|
#[derive(Default, Debug, Clone)]
|
|
pub struct AudioPlayerState {
|
|
pub state: PlayerState,
|
|
pub new_state: Option<PlayerState>,
|
|
|
|
pub tracks: Vec<TrackInfo>,
|
|
|
|
pub volume: f32, // Master volume
|
|
|
|
pub current_input: String,
|
|
pub all_inputs: HashMap<String, String>,
|
|
pub all_inputs_sorted: Vec<(String, String)>,
|
|
|
|
pub is_daemon_running: bool,
|
|
|
|
pub hotkey_config: Option<HotkeyConfig>,
|
|
}
|