feat(shortcuts): improve global shortcut management and documentation

This commit is contained in:
Dmytro Kondakov
2025-04-22 21:00:48 +02:00
parent c3fc915e60
commit e0fadb2c66

View File

@ -9,27 +9,32 @@ use tauri_plugin_global_shortcut::ShortcutState;
use tauri_plugin_store::JsonValue;
use tauri_plugin_store::StoreExt;
/// Name of the Tauri storage
const HAYSTACK_TAURI_STORE: &str = "haystack_tauri_store";
/// Constants for Tauri store configuration
const HAYSTACK_TAURI_STORE: &str = "haystack_tauri_store"; // Name of the persistent store
const HAYSTACK_GLOBAL_SHORTCUT: &str = "haystack_global_shortcut"; // Key for storing the shortcut
/// Key for storing global shortcuts
const HAYSTACK_GLOBAL_SHORTCUT: &str = "haystack_global_shortcut";
/// Default shortcut for macOS
/// Platform-specific default shortcuts
#[cfg(target_os = "macos")]
const DEFAULT_SHORTCUT: &str = "command+shift+k";
const DEFAULT_SHORTCUT: &str = "command+shift+k"; // macOS uses Command key
/// Default shortcut for Windows and Linux
#[cfg(any(target_os = "windows", target_os = "linux"))]
const DEFAULT_SHORTCUT: &str = "ctrl+shift+k";
const DEFAULT_SHORTCUT: &str = "ctrl+shift+k"; // Windows/Linux use Ctrl key
/// Set shortcut during application startup
/// Initializes the global shortcut during application startup.
/// This function:
/// 1. Checks if a shortcut is already stored
/// 2. Uses the stored shortcut if it exists
/// 3. Falls back to the platform-specific default if no shortcut is stored
/// 4. Registers the shortcut with the system
pub fn enable_shortcut(app: &App) {
// Get or create the persistent store
let store = app
.store(HAYSTACK_TAURI_STORE)
.expect("Creating the store should not fail");
// Determine which shortcut to use (stored or default)
let shortcut = if let Some(stored_shortcut) = store.get(HAYSTACK_GLOBAL_SHORTCUT) {
// Parse the stored shortcut string
let stored_shortcut_str = match stored_shortcut {
JsonValue::String(str) => str,
unexpected_type => panic!(
@ -41,6 +46,7 @@ pub fn enable_shortcut(app: &App) {
.parse::<Shortcut>()
.expect("Stored shortcut string should be valid")
} else {
// Store and use the default shortcut
store.set(
HAYSTACK_GLOBAL_SHORTCUT,
JsonValue::String(DEFAULT_SHORTCUT.to_string()),
@ -50,16 +56,19 @@ pub fn enable_shortcut(app: &App) {
.expect("Default shortcut should be valid")
};
// Register the determined shortcut
register_shortcut_upon_start(app, shortcut);
}
/// Get the current stored shortcut as a string
/// Returns the currently configured shortcut as a string.
/// This is exposed as a Tauri command for the frontend to query.
#[tauri::command]
pub fn get_current_shortcut<R: Runtime>(app: AppHandle<R>) -> Result<String, String> {
Ok(get_shortcut_from_store(&app))
}
/// Unregister the current shortcut in Tauri
/// Unregisters the current global shortcut from the system.
/// This is exposed as a Tauri command for the frontend to trigger.
#[tauri::command]
pub fn unregister_shortcut<R: Runtime>(app: AppHandle<R>) {
let shortcut_str = get_shortcut_from_store(&app);
@ -72,7 +81,11 @@ pub fn unregister_shortcut<R: Runtime>(app: AppHandle<R>) {
.expect("Failed to unregister shortcut")
}
/// Change the global shortcut
/// Changes the global shortcut to a new key combination.
/// This function:
/// 1. Validates the new shortcut
/// 2. Stores it in the persistent store
/// 3. Registers it with the system
#[tauri::command]
pub fn change_shortcut<R: Runtime>(
app: AppHandle<R>,
@ -97,7 +110,11 @@ pub fn change_shortcut<R: Runtime>(
Ok(())
}
/// Helper function to handle window visibility toggle
/// Handles the window visibility toggle logic when the shortcut is pressed.
/// This function:
/// 1. Hides the window if it's visible
/// 2. Shows and focuses the window if it's hidden
/// 3. Emits a 'focus-search' event when showing the window
fn handle_window_visibility<R: Runtime>(app: &AppHandle<R>, window: &tauri::WebviewWindow<R>) {
if window.is_visible().unwrap() {
window.hide().unwrap();
@ -108,7 +125,12 @@ fn handle_window_visibility<R: Runtime>(app: &AppHandle<R>, window: &tauri::Webv
}
}
/// Helper function to register a shortcut, primarily for updating shortcuts
/// Registers a new shortcut with the system.
/// This is used when changing shortcuts during runtime.
/// The function:
/// 1. Gets the main window
/// 2. Sets up the shortcut handler
/// 3. Registers the shortcut with the system
fn register_shortcut<R: Runtime>(app: &AppHandle<R>, shortcut: Shortcut) {
let main_window = app.get_webview_window("main").unwrap();
@ -124,7 +146,12 @@ fn register_shortcut<R: Runtime>(app: &AppHandle<R>, shortcut: Shortcut) {
.unwrap();
}
/// Helper function to register shortcuts during application startup
/// Registers a shortcut during application startup.
/// This is similar to register_shortcut but handles the initial plugin setup.
/// The function:
/// 1. Gets the main window
/// 2. Sets up the global shortcut plugin
/// 3. Registers the shortcut with the system
fn register_shortcut_upon_start(app: &App, shortcut: Shortcut) {
let window = app
.get_webview_window("main")
@ -146,7 +173,8 @@ fn register_shortcut_upon_start(app: &App, shortcut: Shortcut) {
app.global_shortcut().register(shortcut).unwrap();
}
/// Retrieve the stored global shortcut as a string
/// Retrieves the currently stored shortcut from the persistent store.
/// This is a helper function used by other functions to access the stored shortcut.
fn get_shortcut_from_store<R: Runtime>(app: &AppHandle<R>) -> String {
let store = app
.get_store(HAYSTACK_TAURI_STORE)