Fix hotkey binding replacement validation

This commit is contained in:
Leslie Leung committed 2026-05-04 22:02:21 +08:00
1 parent 13bfe26395
commit 61214aa8fb
3 files changed
+39 -7

No files matched your search

+24 -1
View File
@@ -97,7 +97,6 @@ impl ComboHotkeyMonitor {
return Ok(());
}
}
current.take();
let runtime = GlobalHotkeyRuntime::shared()
.map_err(|e| ComboHotkeyError::ManagerInitFailed(e.to_string()))?;
let (registered, rx) = runtime
@@ -202,4 +201,28 @@ mod tests {
Err(ComboHotkeyError::UnsupportedKey(_))
));
}
#[test]
fn bare_shift_is_rejected_for_combo_hotkey() {
let binding = ShortcutBinding {
primary: "Shift".into(),
modifiers: vec![],
};
assert!(matches!(
validate_binding(&binding),
Err(ComboHotkeyError::UnsupportedKey(_))
));
}
#[test]
fn legacy_modifier_only_is_rejected_for_combo_hotkey() {
let binding = ShortcutBinding {
primary: "RightOption".into(),
modifiers: vec![],
};
assert!(matches!(
validate_binding(&binding),
Err(ComboHotkeyError::UnsupportedKey(_))
));
}
}
+15 -5
View File
@@ -13,8 +13,7 @@ use crate::persistence::{CredentialAccount, CredentialsSnapshot, CredentialsVaul
use crate::polish::{LLMError, OpenAICompatibleConfig, OpenAICompatibleLLMProvider};
use crate::types::{
ComboBinding, CredentialsStatus, DictationSession, DictionaryEntry, HotkeyCapability,
HotkeyStatus, PolishMode, ShortcutBinding, UserPreferences, VocabPresetStore,
WindowsImeStatus,
HotkeyStatus, PolishMode, ShortcutBinding, UserPreferences, VocabPresetStore, WindowsImeStatus,
};
type CoordinatorState<'a> = State<'a, Arc<Coordinator>>;
@@ -707,10 +706,11 @@ fn reject_modifier_only_action_shortcut(binding: &ShortcutBinding) -> Result<(),
#[tauri::command]
pub fn validate_combo_hotkey(binding: ComboBinding) -> Result<(), String> {
validate_shortcut_binding(ShortcutBinding {
crate::combo_hotkey::validate_binding(&ShortcutBinding {
primary: binding.primary,
modifiers: binding.modifiers,
})
.map_err(|e| e.to_string())
}
/// 设置自定义录音组合键并热更新 monitor。
@@ -721,7 +721,7 @@ pub fn set_combo_hotkey(coord: CoordinatorState<'_>, binding: ComboBinding) -> R
primary: binding.primary.clone(),
modifiers: binding.modifiers.clone(),
};
crate::shortcut_binding::validate_binding(&shortcut).map_err(|e| e.to_string())?;
crate::combo_hotkey::validate_binding(&shortcut).map_err(|e| e.to_string())?;
prefs.custom_combo_hotkey = Some(binding);
prefs.dictation_hotkey = shortcut;
prefs.hotkey.trigger = crate::types::HotkeyTrigger::Custom;
@@ -743,7 +743,7 @@ mod tests {
SettingsWriter,
};
use crate::types::{
HotkeyBinding, HotkeyMode, HotkeyTrigger, ShortcutBinding, UserPreferences,
ComboBinding, HotkeyBinding, HotkeyMode, HotkeyTrigger, ShortcutBinding, UserPreferences,
};
use std::io::{Read, Write};
use std::net::TcpListener;
@@ -835,6 +835,16 @@ mod tests {
assert_eq!(*writer.combo_refreshes.lock().unwrap(), 1);
}
#[test]
fn validate_combo_hotkey_rejects_bare_shift() {
let result = super::validate_combo_hotkey(ComboBinding {
primary: "Shift".into(),
modifiers: vec![],
});
assert!(result.is_err());
}
#[tokio::test]
async fn fetch_provider_models_omits_authorization_when_api_key_is_empty() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
@@ -103,7 +103,6 @@ impl QaHotkeyMonitor {
return Ok(());
}
}
current.take();
let runtime = GlobalHotkeyRuntime::shared()
.map_err(|e| QaHotkeyError::ManagerInitFailed(e.to_string()))?;
let (registered, rx) = runtime