use tauri::{Emitter, Manager, WebviewUrl, WebviewWindowBuilder}; use crate::PreferencesScript; /// Open a floating always-on-top task window. #[tauri::command] pub async fn open_task_window(app: tauri::AppHandle) -> Result<(), String> { if let Some(window) = app.get_webview_window("tasks-float") { window.show().map_err(|e| e.to_string())?; window.set_focus().map_err(|e| e.to_string())?; app.emit("task-window-focus", ()) .map_err(|e| e.to_string())?; return Ok(()); } // On Linux we use native KWin/Mutter decorations so resize and drag // are handled by the compositor. Tauri's frameless path on Wayland // doesn't honour diagonal resize reliably and Tauri's own drag // region adds latency on webkit2gtk. macOS and Windows keep the // custom frameless chrome drawn by the Titlebar component. let use_native_decorations = cfg!(target_os = "linux"); let mut builder = WebviewWindowBuilder::new(&app, "tasks-float", WebviewUrl::App("/float".into())) .title("Kon Tasks") .inner_size(480.0, 520.0) .min_inner_size(360.0, 480.0) .always_on_top(true) .decorations(use_native_decorations) .resizable(true); // Inject preferences before Svelte mounts if let Some(script) = app.try_state::() { if !script.0.is_empty() { builder = builder.initialization_script(&script.0); } } builder.build().map_err(|e| e.to_string())?; Ok(()) } /// Open the transcript viewer window. #[tauri::command] pub async fn open_viewer_window(app: tauri::AppHandle) -> Result<(), String> { if let Some(window) = app.get_webview_window("transcript-viewer") { window.show().map_err(|e| e.to_string())?; window.set_focus().map_err(|e| e.to_string())?; return Ok(()); } // See note in open_task_window for the Linux-vs-other platform split. let use_native_decorations = cfg!(target_os = "linux"); let mut builder = WebviewWindowBuilder::new(&app, "transcript-viewer", WebviewUrl::App("/viewer".into())) .title("Kon - Transcription Editor") .inner_size(600.0, 700.0) .min_inner_size(560.0, 520.0) .decorations(use_native_decorations) .resizable(true); // Inject preferences before Svelte mounts if let Some(script) = app.try_state::() { if !script.0.is_empty() { builder = builder.initialization_script(&script.0); } } builder.build().map_err(|e| e.to_string())?; Ok(()) }