-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathhandler.rs
More file actions
91 lines (81 loc) · 3.03 KB
/
handler.rs
File metadata and controls
91 lines (81 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Shared shortcut event handling logic
//!
//! This module contains the common logic for handling shortcut events,
//! used by both the Tauri and handy-keys implementations.
use log::warn;
use std::sync::Arc;
use tauri::{AppHandle, Manager};
use crate::actions::ACTION_MAP;
use crate::managers::audio::AudioRecordingManager;
use crate::settings::get_settings;
use crate::ManagedToggleState;
/// Handle a shortcut event from either implementation.
///
/// This function contains the shared logic for:
/// - Looking up the action in ACTION_MAP
/// - Handling the cancel binding (only fires when recording)
/// - Handling push-to-talk mode (start on press, stop on release)
/// - Handling toggle mode (toggle state on press only)
///
/// # Arguments
/// * `app` - The Tauri app handle
/// * `binding_id` - The ID of the binding (e.g., "transcribe", "cancel")
/// * `hotkey_string` - The string representation of the hotkey
/// * `is_pressed` - Whether this is a key press (true) or release (false)
pub fn handle_shortcut_event(
app: &AppHandle,
binding_id: &str,
hotkey_string: &str,
is_pressed: bool,
) {
let settings = get_settings(app);
let Some(action) = ACTION_MAP.get(binding_id) else {
warn!(
"No action defined in ACTION_MAP for shortcut ID '{}'. Shortcut: '{}', Pressed: {}",
binding_id, hotkey_string, is_pressed
);
return;
};
// Cancel binding: only fires when recording and key is pressed
if binding_id == "cancel" {
let audio_manager = app.state::<Arc<AudioRecordingManager>>();
if audio_manager.is_recording() && is_pressed {
action.start(app, binding_id, hotkey_string);
}
return;
}
// Push-to-talk mode: start on press, stop on release
if settings.push_to_talk {
if is_pressed {
action.start(app, binding_id, hotkey_string);
} else {
action.stop(app, binding_id, hotkey_string);
}
return;
}
// Toggle mode: toggle state on press only
if is_pressed {
// Determine action and update state while holding the lock,
// but RELEASE the lock before calling the action to avoid deadlocks.
// (Actions may need to acquire the lock themselves, e.g., cancel_current_operation)
let should_start: bool;
{
let toggle_state_manager = app.state::<ManagedToggleState>();
let mut states = toggle_state_manager
.lock()
.expect("Failed to lock toggle state manager");
let is_currently_active = states
.active_toggles
.entry(binding_id.to_string())
.or_insert(false);
should_start = !*is_currently_active;
*is_currently_active = should_start;
} // Lock released here
// Now call the action without holding the lock
if should_start {
action.start(app, binding_id, hotkey_string);
} else {
action.stop(app, binding_id, hotkey_string);
}
}
}