feat(image-viewer): enhance window focus and visibility handling in ImageViewer component

This commit is contained in:
2025-04-22 20:56:08 +02:00
parent c3f4403145
commit 2b022c31cb
6 changed files with 82 additions and 41 deletions

Binary file not shown.

View File

@@ -13,6 +13,8 @@
"global-shortcut:allow-unregister",
"global-shortcut:allow-unregister-all",
"http:default",
"core:window:allow-show",
"core:window:allow-set-focus",
{
"identifier": "http:default",
"allow": [

View File

@@ -29,8 +29,7 @@ pub fn enable_shortcut(app: &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 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!(
@@ -38,39 +37,36 @@ pub fn enable_shortcut(app: &App) {
unexpected_type
),
};
let stored_shortcut = stored_shortcut_str
stored_shortcut_str
.parse::<Shortcut>()
.expect("Stored shortcut string should be valid");
_register_shortcut_upon_start(app, stored_shortcut); // Register stored shortcut
.expect("Stored shortcut string should be valid")
} else {
// Use default shortcut if none is stored
store.set(
HAYSTACK_GLOBAL_SHORTCUT,
JsonValue::String(DEFAULT_SHORTCUT.to_string()),
);
let default_shortcut = DEFAULT_SHORTCUT
DEFAULT_SHORTCUT
.parse::<Shortcut>()
.expect("Default shortcut should be valid");
_register_shortcut_upon_start(app, default_shortcut); // Register default shortcut
}
.expect("Default shortcut should be valid")
};
register_shortcut_upon_start(app, 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)
Ok(get_shortcut_from_store(&app))
}
/// 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_str = get_shortcut_from_store(&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")
@@ -96,28 +92,31 @@ pub fn change_shortcut<R: Runtime>(
store.set(HAYSTACK_GLOBAL_SHORTCUT, JsonValue::String(key));
// Register the new shortcut
_register_shortcut(&app, shortcut);
register_shortcut(&app, shortcut);
Ok(())
}
/// Helper function to handle window visibility toggle
fn handle_window_visibility<R: Runtime>(app: &AppHandle<R>, window: &tauri::WebviewWindow<R>) {
if window.is_visible().unwrap() {
window.hide().unwrap();
} else {
window.show().unwrap();
window.set_focus().unwrap();
app.emit("focus-search", ()).unwrap();
}
}
/// Helper function to register a shortcut, primarily for updating shortcuts
fn _register_shortcut<R: Runtime>(app: &AppHandle<R>, shortcut: Shortcut) {
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();
}
handle_window_visibility(app, &main_window);
}
}
})
@@ -126,38 +125,29 @@ fn _register_shortcut<R: Runtime>(app: &AppHandle<R>, shortcut: Shortcut) {
}
/// Helper function to register shortcuts during application startup
fn _register_shortcut_upon_start(app: &App, shortcut: Shortcut) {
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();
}
handle_window_visibility(app, &window);
}
}
})
.build(),
)
.unwrap();
app.global_shortcut().register(shortcut).unwrap(); // Register global shortcut
app.global_shortcut().register(shortcut).unwrap();
}
/// Retrieve the stored global shortcut as a string
pub fn _get_shortcut<R: Runtime>(app: &AppHandle<R>) -> String {
fn get_shortcut_from_store<R: Runtime>(app: &AppHandle<R>) -> String {
let store = app
.get_store(HAYSTACK_TAURI_STORE)
.expect("Store should already be loaded or created");

View File

@@ -1,7 +1,13 @@
import { listen } from "@tauri-apps/api/event";
import { createEffect } from "solid-js";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { createEffect, createSignal } from "solid-js";
import { sendImage } from "../network";
// TODO: This component should focus the window and show preview of screenshot,
// before we send it to backend, potentially we could draw and annotate
// OR we kill this and do stuff siltently
// anyhow keeping it like this for now
export function ImageViewer() {
// const [latestImage, setLatestImage] = createSignal<string | null>(null);
@@ -11,10 +17,15 @@ export function ImageViewer() {
console.log("Received processed PNG", event);
const base64Data = event.payload as string;
const appWindow = getCurrentWindow();
appWindow.show();
appWindow.setFocus();
// setLatestImage(`data:image/png;base64,${base64Data}`);
const result = await sendImage("test-image.png", base64Data);
window.location.reload();
console.log("DBG: ", result);
});