diff --git a/frontend/src-tauri/src/lib.rs b/frontend/src-tauri/src/lib.rs index 5de6bb4..37f3f80 100644 --- a/frontend/src-tauri/src/lib.rs +++ b/frontend/src-tauri/src/lib.rs @@ -22,6 +22,9 @@ pub fn run() { shortcut::change_shortcut, shortcut::unregister_shortcut, shortcut::get_current_shortcut, + shortcut::change_screenshot_shortcut, + shortcut::unregister_screenshot_shortcut, + shortcut::get_current_screenshot_shortcut, ]) .setup(|app| { setup_window(app)?; diff --git a/frontend/src-tauri/src/shortcut.rs b/frontend/src-tauri/src/shortcut.rs index 794b2b7..2808fc7 100644 --- a/frontend/src-tauri/src/shortcut.rs +++ b/frontend/src-tauri/src/shortcut.rs @@ -11,14 +11,19 @@ use tauri_plugin_store::StoreExt; /// 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 +const HAYSTACK_GLOBAL_SHORTCUT: &str = "haystack_global_shortcut"; // Key for storing the toggle window shortcut +const HAYSTACK_SCREENSHOT_SHORTCUT: &str = "haystack_screenshot_shortcut"; // Key for storing the screenshot shortcut /// Platform-specific default shortcuts #[cfg(target_os = "macos")] const DEFAULT_SHORTCUT: &str = "command+shift+k"; // macOS uses Command key +#[cfg(target_os = "macos")] +const DEFAULT_SCREENSHOT_SHORTCUT: &str = "command+shift+p"; // macOS screenshot shortcut #[cfg(any(target_os = "windows", target_os = "linux"))] const DEFAULT_SHORTCUT: &str = "ctrl+shift+k"; // Windows/Linux use Ctrl key +#[cfg(any(target_os = "windows", target_os = "linux"))] +const DEFAULT_SCREENSHOT_SHORTCUT: &str = "ctrl+shift+p"; // Windows/Linux screenshot shortcut /// Initializes the global shortcut during application startup. /// This function: @@ -32,9 +37,8 @@ pub fn enable_shortcut(app: &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 + // Initialize toggle window shortcut + let toggle_shortcut = if let Some(stored_shortcut) = store.get(HAYSTACK_GLOBAL_SHORTCUT) { let stored_shortcut_str = match stored_shortcut { JsonValue::String(str) => str, unexpected_type => panic!( @@ -46,7 +50,6 @@ pub fn enable_shortcut(app: &App) { .parse::() .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()), @@ -56,8 +59,31 @@ pub fn enable_shortcut(app: &App) { .expect("Default shortcut should be valid") }; - // Register the determined shortcut - register_shortcut_upon_start(app, shortcut); + // Initialize screenshot shortcut + let screenshot_shortcut = if let Some(stored_shortcut) = store.get(HAYSTACK_SCREENSHOT_SHORTCUT) + { + let stored_shortcut_str = match stored_shortcut { + JsonValue::String(str) => str, + unexpected_type => panic!( + "Haystack shortcuts should be stored as strings, found type: {} ", + unexpected_type + ), + }; + stored_shortcut_str + .parse::() + .expect("Stored shortcut string should be valid") + } else { + store.set( + HAYSTACK_SCREENSHOT_SHORTCUT, + JsonValue::String(DEFAULT_SCREENSHOT_SHORTCUT.to_string()), + ); + DEFAULT_SCREENSHOT_SHORTCUT + .parse::() + .expect("Default screenshot shortcut should be valid") + }; + + // Register both shortcuts + register_shortcut_upon_start(app, toggle_shortcut, screenshot_shortcut); } /// Returns the currently configured shortcut as a string. @@ -152,7 +178,11 @@ fn register_shortcut(app: &AppHandle, shortcut: Shortcut) { /// 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) { +fn register_shortcut_upon_start( + app: &App, + toggle_shortcut: Shortcut, + screenshot_shortcut: Shortcut, +) { let window = app .get_webview_window("main") .expect("webview to be defined"); @@ -161,16 +191,22 @@ fn register_shortcut_upon_start(app: &App, shortcut: Shortcut) { .plugin( tauri_plugin_global_shortcut::Builder::new() .with_handler(move |app, scut, event| { - if scut == &shortcut { + if scut == &toggle_shortcut { if let ShortcutState::Pressed = event.state() { handle_window_visibility(app, &window); } + } else if scut == &screenshot_shortcut { + if let ShortcutState::Pressed = event.state() { + // TODO: Implement screenshot functionality + println!("Screenshot shortcut pressed"); + } } }) .build(), ) .unwrap(); - app.global_shortcut().register(shortcut).unwrap(); + app.global_shortcut().register(toggle_shortcut).unwrap(); + app.global_shortcut().register(screenshot_shortcut).unwrap(); } /// Retrieves the currently stored shortcut from the persistent store. @@ -191,3 +227,72 @@ fn get_shortcut_from_store(app: &AppHandle) -> String { ), } } + +#[tauri::command] +pub fn get_current_screenshot_shortcut(app: AppHandle) -> Result { + Ok(get_screenshot_shortcut_from_store(&app)) +} + +#[tauri::command] +pub fn unregister_screenshot_shortcut(app: AppHandle) { + let shortcut_str = get_screenshot_shortcut_from_store(&app); + let shortcut = shortcut_str + .parse::() + .expect("Stored shortcut string should be valid"); + + app.global_shortcut() + .unregister(shortcut) + .expect("Failed to unregister screenshot shortcut") +} + +#[tauri::command] +pub fn change_screenshot_shortcut( + app: AppHandle, + _window: tauri::Window, + key: String, +) -> Result<(), String> { + let shortcut = match key.parse::() { + Ok(shortcut) => shortcut, + Err(_) => return Err(format!("Invalid screenshot shortcut {}", key)), + }; + + let store = app + .get_store(HAYSTACK_TAURI_STORE) + .expect("Store should already be loaded or created"); + store.set(HAYSTACK_SCREENSHOT_SHORTCUT, JsonValue::String(key)); + + register_screenshot_shortcut(&app, shortcut); + + Ok(()) +} + +fn register_screenshot_shortcut(app: &AppHandle, shortcut: Shortcut) { + app.global_shortcut() + .on_shortcut(shortcut, move |_app, scut, event| { + if scut == &shortcut { + if let ShortcutState::Pressed = event.state() { + // TODO: Implement screenshot functionality + println!("Screenshot shortcut pressed"); + } + } + }) + .map_err(|err| format!("Failed to register new screenshot shortcut '{}'", err)) + .unwrap(); +} + +fn get_screenshot_shortcut_from_store(app: &AppHandle) -> String { + let store = app + .get_store(HAYSTACK_TAURI_STORE) + .expect("Store should already be loaded or created"); + + match store + .get(HAYSTACK_SCREENSHOT_SHORTCUT) + .expect("Screenshot shortcut should already be stored") + { + JsonValue::String(str) => str, + unexpected_type => panic!( + "Haystack shortcuts should be stored as strings, found type: {} ", + unexpected_type + ), + } +}