feat: implement Clipboard API

This commit is contained in:
ByteAtATime 2025-06-19 11:23:05 -07:00
parent a598ccf50b
commit 3c3566136a
No known key found for this signature in database
9 changed files with 461 additions and 97 deletions

View file

@ -1,6 +1,7 @@
mod app;
mod browser_extension;
mod cache;
mod clipboard;
mod desktop;
mod error;
mod extensions;
@ -16,122 +17,124 @@ use tauri::Manager;
#[tauri::command]
fn get_installed_apps() -> Vec<App> {
match AppCache::get_apps() {
Ok(apps) => apps,
Err(e) => {
eprintln!("Failed to get apps: {:?}", e);
Vec::new()
}
}
match AppCache::get_apps() {
Ok(apps) => apps,
Err(e) => {
eprintln!("Failed to get apps: {:?}", e);
Vec::new()
}
}
}
#[tauri::command]
fn launch_app(exec: String) -> Result<(), String> {
let exec_parts: Vec<&str> = exec.split_whitespace().collect();
if exec_parts.is_empty() {
return Err("Empty exec command".to_string());
}
let exec_parts: Vec<&str> = exec.split_whitespace().collect();
if exec_parts.is_empty() {
return Err("Empty exec command".to_string());
}
let mut command = Command::new(exec_parts[0]);
for arg in &exec_parts[1..] {
if !arg.starts_with('%') {
command.arg(arg);
}
}
let mut command = Command::new(exec_parts[0]);
for arg in &exec_parts[1..] {
if !arg.starts_with('%') {
command.arg(arg);
}
}
command
.spawn()
.map_err(|e| format!("Failed to launch app: {}", e))?;
command
.spawn()
.map_err(|e| format!("Failed to launch app: {}", e))?;
Ok(())
Ok(())
}
#[tauri::command]
fn get_selected_text() -> String {
get_text()
get_text()
}
fn setup_background_refresh() {
thread::spawn(|| {
thread::sleep(Duration::from_secs(60));
loop {
AppCache::refresh_background();
thread::sleep(Duration::from_secs(300));
}
});
thread::spawn(|| {
thread::sleep(Duration::from_secs(60));
loop {
AppCache::refresh_background();
thread::sleep(Duration::from_secs(300));
}
});
}
fn setup_global_shortcut(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
use tauri_plugin_global_shortcut::{
Code, GlobalShortcutExt, Modifiers, Shortcut, ShortcutState,
};
use tauri_plugin_global_shortcut::{
Code, GlobalShortcutExt, Modifiers, Shortcut, ShortcutState
};
let spotlight_shortcut = Shortcut::new(Some(Modifiers::ALT), Code::Space);
let handle = app.handle().clone();
let spotlight_shortcut = Shortcut::new(Some(Modifiers::ALT), Code::Space);
let handle = app.handle().clone();
println!("Spotlight shortcut: {:?}", spotlight_shortcut);
println!("Spotlight shortcut: {:?}", spotlight_shortcut);
app.handle().plugin(
tauri_plugin_global_shortcut::Builder::new()
.with_handler(move |_app, shortcut, event| {
println!("Shortcut: {:?}, Event: {:?}", shortcut, event);
if shortcut == &spotlight_shortcut
&& event.state() == ShortcutState::Pressed
{
let spotlight_window =
handle.get_webview_window("raycast-linux").unwrap();
println!("Spotlight window: {:?}", spotlight_window);
if spotlight_window.is_visible().unwrap_or(false) {
spotlight_window.hide().unwrap();
} else {
spotlight_window.show().unwrap();
spotlight_window.set_focus().unwrap();
}
}
})
.build(),
)?;
app.handle().plugin(
tauri_plugin_global_shortcut::Builder::new()
.with_handler(move |_app, shortcut, event| {
println!("Shortcut: {:?}, Event: {:?}", shortcut, event);
if shortcut == &spotlight_shortcut && event.state() == ShortcutState::Pressed {
let spotlight_window = handle.get_webview_window("raycast-linux").unwrap();
println!("Spotlight window: {:?}", spotlight_window);
if spotlight_window.is_visible().unwrap_or(false) {
spotlight_window.hide().unwrap();
} else {
spotlight_window.show().unwrap();
spotlight_window.set_focus().unwrap();
}
}
})
.build()
)?;
app.global_shortcut().register(spotlight_shortcut)?;
Ok(())
app.global_shortcut().register(spotlight_shortcut)?;
Ok(())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.manage(WsState::default())
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
if let Some(window) = app.get_webview_window("main") {
if let Ok(true) = window.is_visible() {
let _ = window.hide();
} else {
let _ = window.show();
let _ = window.set_focus();
}
}
}))
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![
get_installed_apps,
launch_app,
get_selected_text,
filesystem::get_selected_finder_items,
extensions::install_extension,
browser_extension::browser_extension_check_connection,
browser_extension::browser_extension_request
])
.setup(|app| {
let app_handle = app.handle().clone();
tauri::async_runtime::spawn(browser_extension::run_server(app_handle));
tauri::Builder::default()
.manage(WsState::default())
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
if let Some(window) = app.get_webview_window("main") {
if let Ok(true) = window.is_visible() {
let _ = window.hide();
} else {
let _ = window.show();
let _ = window.set_focus();
}
}
}))
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![
get_installed_apps,
launch_app,
get_selected_text,
filesystem::get_selected_finder_items,
extensions::install_extension,
browser_extension::browser_extension_check_connection,
browser_extension::browser_extension_request,
clipboard::clipboard_read_text,
clipboard::clipboard_read,
clipboard::clipboard_copy,
clipboard::clipboard_paste,
clipboard::clipboard_clear
])
.setup(|app| {
let app_handle = app.handle().clone();
tauri::async_runtime::spawn(browser_extension::run_server(app_handle));
setup_background_refresh();
setup_global_shortcut(app)?;
setup_background_refresh();
setup_global_shortcut(app)?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}