feat: SIGUSR2 handling for toggles (#354)
* feat: SIGUSR2 handling for toggles * run format --------- Co-authored-by: CJ Pais <cj@cjpais.com>
This commit is contained in:
parent
97f3018be0
commit
9c4b1e1f5c
5 changed files with 95 additions and 9 deletions
11
src-tauri/Cargo.lock
generated
11
src-tauri/Cargo.lock
generated
|
|
@ -2349,6 +2349,7 @@ dependencies = [
|
|||
"rustfft",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"signal-hook",
|
||||
"strsim",
|
||||
"tar",
|
||||
"tauri",
|
||||
|
|
@ -5560,6 +5561,16 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.6"
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ tauri-build = { version = "2", features = [] }
|
|||
[dependencies]
|
||||
once_cell = "1"
|
||||
tauri = { version = "2.9.1", features = [
|
||||
"protocol-asset",
|
||||
"macos-private-api",
|
||||
"tray-icon",
|
||||
'image-png',
|
||||
"protocol-asset",
|
||||
"macos-private-api",
|
||||
"tray-icon",
|
||||
'image-png',
|
||||
] }
|
||||
tauri-plugin-log = "2.7.1"
|
||||
tauri-plugin-opener = "2.5.2"
|
||||
|
|
@ -68,6 +68,9 @@ tar = "0.4.44"
|
|||
flate2 = "1.0"
|
||||
transcribe-rs = "0.1.4"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
signal-hook = "0.3"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
tauri-plugin-autostart = "2.5.1"
|
||||
tauri-plugin-global-shortcut = "2.3.1"
|
||||
|
|
@ -76,9 +79,9 @@ tauri-plugin-updater = "2.9.0"
|
|||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows = { version = "0.61.3", features = [
|
||||
"Win32_Media_Audio_Endpoints",
|
||||
"Win32_System_Com_StructuredStorage",
|
||||
"Win32_System_Variant",
|
||||
"Win32_Media_Audio_Endpoints",
|
||||
"Win32_System_Com_StructuredStorage",
|
||||
"Win32_System_Variant",
|
||||
] }
|
||||
|
||||
[profile.release]
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ pub fn is_laptop() -> Result<bool, String> {
|
|||
.arg("batt")
|
||||
.output()
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
|
||||
// Check if InternalBattery is present (laptops have batteries, desktops typically don't)
|
||||
Ok(stdout.contains("InternalBattery"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ mod managers;
|
|||
mod overlay;
|
||||
mod settings;
|
||||
mod shortcut;
|
||||
mod signal_handle;
|
||||
mod tray;
|
||||
mod utils;
|
||||
|
||||
|
|
@ -17,6 +18,8 @@ use managers::audio::AudioRecordingManager;
|
|||
use managers::history::HistoryManager;
|
||||
use managers::model::ModelManager;
|
||||
use managers::transcription::TranscriptionManager;
|
||||
use signal_hook::consts::SIGUSR2;
|
||||
use signal_hook::iterator::Signals;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::{AtomicU8, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
|
@ -119,6 +122,12 @@ fn initialize_core_logic(app_handle: &AppHandle) {
|
|||
// Initialize the shortcuts
|
||||
shortcut::init_shortcuts(app_handle);
|
||||
|
||||
#[cfg(unix)]
|
||||
let signals = Signals::new(&[SIGUSR2]).unwrap();
|
||||
// Set up SIGUSR2 signal handler for toggling transcription
|
||||
#[cfg(unix)]
|
||||
signal_handle::setup_signal_handler(app_handle.clone(), signals);
|
||||
|
||||
// Apply macOS Accessory policy if starting hidden
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
|
|
|
|||
63
src-tauri/src/signal_handle.rs
Normal file
63
src-tauri/src/signal_handle.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
use crate::actions::ACTION_MAP;
|
||||
use crate::ManagedToggleState;
|
||||
use log::{debug, info, warn};
|
||||
use std::thread;
|
||||
use tauri::{AppHandle, Manager};
|
||||
|
||||
#[cfg(unix)]
|
||||
use signal_hook::consts::SIGUSR2;
|
||||
#[cfg(unix)]
|
||||
use signal_hook::iterator::Signals;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn setup_signal_handler(app_handle: AppHandle, mut signals: Signals) {
|
||||
let app_handle_for_signal = app_handle.clone();
|
||||
|
||||
debug!("SIGUSR2 signal handler registered successfully");
|
||||
thread::spawn(move || {
|
||||
debug!("SIGUSR2 signal handler thread started");
|
||||
for sig in signals.forever() {
|
||||
match sig {
|
||||
SIGUSR2 => {
|
||||
debug!("Received SIGUSR2 signal (signal number: {sig})");
|
||||
|
||||
let binding_id = "transcribe";
|
||||
let shortcut_string = "SIGUSR2";
|
||||
|
||||
if let Some(action) = ACTION_MAP.get(binding_id) {
|
||||
let toggle_state_manager =
|
||||
app_handle_for_signal.state::<ManagedToggleState>();
|
||||
|
||||
let mut states = match toggle_state_manager.lock() {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
warn!("Failed to lock toggle state manager: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let is_currently_active = states
|
||||
.active_toggles
|
||||
.entry(binding_id.to_string())
|
||||
.or_insert(false);
|
||||
|
||||
if *is_currently_active {
|
||||
debug!("SIGUSR2: Stopping transcription (currently active)");
|
||||
action.stop(&app_handle_for_signal, binding_id, shortcut_string);
|
||||
*is_currently_active = false; // Update state to inactive
|
||||
debug!("SIGUSR2: Transcription stopped");
|
||||
} else {
|
||||
debug!("SIGUSR2: Starting transcription (currently inactive)");
|
||||
action.start(&app_handle_for_signal, binding_id, shortcut_string);
|
||||
*is_currently_active = true; // Update state to active
|
||||
info!("SIGUSR2: Transcription started");
|
||||
}
|
||||
} else {
|
||||
warn!("No action defined in ACTION_MAP for binding ID '{binding_id}'");
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
Loading…
Reference in a new issue