Compare commits
8 Commits
ff25e2d3e4
...
0940134d9e
Author | SHA1 | Date | |
---|---|---|---|
0940134d9e | |||
af24a8f6d4 | |||
446e8bb2ee | |||
6211945e3d | |||
9f215bb3d1 | |||
1a84e0d6c5 | |||
bd9d8b955a | |||
58f60bf053 |
175
frontend/src-tauri/src/shortcut.rs
Normal file
175
frontend/src-tauri/src/shortcut.rs
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
use tauri::App;
|
||||||
|
use tauri::AppHandle;
|
||||||
|
use tauri::Emitter;
|
||||||
|
use tauri::Manager;
|
||||||
|
use tauri::Runtime;
|
||||||
|
use tauri_plugin_global_shortcut::GlobalShortcutExt;
|
||||||
|
use tauri_plugin_global_shortcut::Shortcut;
|
||||||
|
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";
|
||||||
|
|
||||||
|
/// Key for storing global shortcuts
|
||||||
|
const HAYSTACK_GLOBAL_SHORTCUT: &str = "haystack_global_shortcut";
|
||||||
|
|
||||||
|
/// Default shortcut for macOS
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
const DEFAULT_SHORTCUT: &str = "command+shift+k";
|
||||||
|
|
||||||
|
/// Default shortcut for Windows and Linux
|
||||||
|
#[cfg(any(target_os = "windows", target_os = "linux"))]
|
||||||
|
const DEFAULT_SHORTCUT: &str = "ctrl+shift+k";
|
||||||
|
|
||||||
|
/// Set shortcut during application startup
|
||||||
|
pub fn enable_shortcut(app: &App) {
|
||||||
|
let store = app
|
||||||
|
.store(HAYSTACK_TAURI_STORE)
|
||||||
|
.expect("Creating the store should not fail");
|
||||||
|
|
||||||
|
// Use stored shortcut if it exists
|
||||||
|
if let Some(stored_shortcut) = store.get(HAYSTACK_GLOBAL_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
|
||||||
|
),
|
||||||
|
};
|
||||||
|
let stored_shortcut = stored_shortcut_str
|
||||||
|
.parse::<Shortcut>()
|
||||||
|
.expect("Stored shortcut string should be valid");
|
||||||
|
_register_shortcut_upon_start(app, stored_shortcut); // Register stored shortcut
|
||||||
|
} else {
|
||||||
|
// Use default shortcut if none is stored
|
||||||
|
store.set(
|
||||||
|
HAYSTACK_GLOBAL_SHORTCUT,
|
||||||
|
JsonValue::String(DEFAULT_SHORTCUT.to_string()),
|
||||||
|
);
|
||||||
|
let default_shortcut = DEFAULT_SHORTCUT
|
||||||
|
.parse::<Shortcut>()
|
||||||
|
.expect("Default shortcut should be valid");
|
||||||
|
_register_shortcut_upon_start(app, default_shortcut); // Register default shortcut
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the current stored shortcut as a string
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn get_current_shortcut<R: Runtime>(app: AppHandle<R>) -> Result<String, String> {
|
||||||
|
let shortcut = _get_shortcut(&app);
|
||||||
|
Ok(shortcut)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Unregister the current shortcut in Tauri
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn unregister_shortcut<R: Runtime>(app: AppHandle<R>) {
|
||||||
|
let shortcut_str = _get_shortcut(&app);
|
||||||
|
let shortcut = shortcut_str
|
||||||
|
.parse::<Shortcut>()
|
||||||
|
.expect("Stored shortcut string should be valid");
|
||||||
|
|
||||||
|
// Unregister the shortcut
|
||||||
|
app.global_shortcut()
|
||||||
|
.unregister(shortcut)
|
||||||
|
.expect("Failed to unregister shortcut")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the global shortcut
|
||||||
|
#[tauri::command]
|
||||||
|
pub fn change_shortcut<R: Runtime>(
|
||||||
|
app: AppHandle<R>,
|
||||||
|
_window: tauri::Window<R>,
|
||||||
|
key: String,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
println!("Key: {}", key);
|
||||||
|
let shortcut = match key.parse::<Shortcut>() {
|
||||||
|
Ok(shortcut) => shortcut,
|
||||||
|
Err(_) => return Err(format!("Invalid shortcut {}", key)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store the new shortcut
|
||||||
|
let store = app
|
||||||
|
.get_store(HAYSTACK_TAURI_STORE)
|
||||||
|
.expect("Store should already be loaded or created");
|
||||||
|
store.set(HAYSTACK_GLOBAL_SHORTCUT, JsonValue::String(key));
|
||||||
|
|
||||||
|
// Register the new shortcut
|
||||||
|
_register_shortcut(&app, shortcut);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to register a shortcut, primarily for updating shortcuts
|
||||||
|
fn _register_shortcut<R: Runtime>(app: &AppHandle<R>, shortcut: Shortcut) {
|
||||||
|
let main_window = app.get_webview_window("main").unwrap();
|
||||||
|
// Register global shortcut and define its behavior
|
||||||
|
app.global_shortcut()
|
||||||
|
.on_shortcut(shortcut, move |app, scut, event| {
|
||||||
|
if scut == &shortcut {
|
||||||
|
if let ShortcutState::Pressed = event.state() {
|
||||||
|
// Toggle window visibility
|
||||||
|
if main_window.is_visible().unwrap() {
|
||||||
|
main_window.hide().unwrap(); // Hide window
|
||||||
|
} else {
|
||||||
|
main_window.show().unwrap(); // Show window
|
||||||
|
main_window.set_focus().unwrap(); // Focus window
|
||||||
|
// Emit focus-search event
|
||||||
|
app.emit("focus-search", ()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map_err(|err| format!("Failed to register new shortcut '{}'", err))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Helper function to register shortcuts during application startup
|
||||||
|
fn _register_shortcut_upon_start(app: &App, shortcut: Shortcut) {
|
||||||
|
let window = app
|
||||||
|
.get_webview_window("main")
|
||||||
|
.expect("webview to be defined");
|
||||||
|
|
||||||
|
// Initialize global shortcut and set its handler
|
||||||
|
app.handle()
|
||||||
|
.plugin(
|
||||||
|
tauri_plugin_global_shortcut::Builder::new()
|
||||||
|
.with_handler(move |app, scut, event| {
|
||||||
|
if scut == &shortcut {
|
||||||
|
if let ShortcutState::Pressed = event.state() {
|
||||||
|
// Toggle window visibility
|
||||||
|
if window.is_visible().unwrap() {
|
||||||
|
window.hide().unwrap(); // Hide window
|
||||||
|
} else {
|
||||||
|
window.show().unwrap(); // Show window
|
||||||
|
window.set_focus().unwrap(); // Focus window
|
||||||
|
// Emit focus-search event
|
||||||
|
app.emit("focus-search", ()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
app.global_shortcut().register(shortcut).unwrap(); // Register global shortcut
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Retrieve the stored global shortcut as a string
|
||||||
|
pub fn _get_shortcut<R: Runtime>(app: &AppHandle<R>) -> String {
|
||||||
|
let store = app
|
||||||
|
.get_store(HAYSTACK_TAURI_STORE)
|
||||||
|
.expect("Store should already be loaded or created");
|
||||||
|
|
||||||
|
match store
|
||||||
|
.get(HAYSTACK_GLOBAL_SHORTCUT)
|
||||||
|
.expect("Shortcut should already be stored")
|
||||||
|
{
|
||||||
|
JsonValue::String(str) => str,
|
||||||
|
unexpected_type => panic!(
|
||||||
|
"Haystack shortcuts should be stored as strings, found type: {} ",
|
||||||
|
unexpected_type
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user