fix(quick-pane): preserve lifecycle and answer history

This commit is contained in:
2026-08-25 23:08:45 +02:00
parent 1b0b34fad8
commit 4fc9c60ade
8 changed files with 506 additions and 65 deletions
+76 -13
View File
@@ -3,7 +3,10 @@ mod ui_state;
use serde_json::{json, Value};
use std::{env, path::Path, sync::{Arc, Mutex}, time::Duration};
use tauri::{async_runtime::JoinHandle, AppHandle, Emitter, Manager, State};
use tauri::{
async_runtime::JoinHandle, AppHandle, Emitter, Manager, State, WebviewWindow,
WebviewWindowBuilder, WindowEvent,
};
struct LegacySubscription(Mutex<Option<JoinHandle<()>>>);
struct WorkspaceSubscription {
@@ -57,20 +60,46 @@ fn quick_pane_action(is_visible: bool) -> WindowAction {
}
}
fn toggle_quick_pane(app: &AppHandle) {
fn should_hide_close_request(label: &str) -> bool {
label == "quick-pane"
}
fn get_or_create_quick_pane(app: &AppHandle) -> Result<WebviewWindow, String> {
if let Some(window) = app.get_webview_window("quick-pane") {
match quick_pane_action(window.is_visible().unwrap_or(false)) {
WindowAction::Hide => {
let _ = window.hide();
}
WindowAction::ShowAndFocus => {
if let Some(main) = app.get_webview_window("main") {
let _ = main.hide();
}
let _ = window.show();
let _ = window.unminimize();
let _ = window.set_focus();
return Ok(window);
}
let config = app
.config()
.app
.windows
.iter()
.find(|window| window.label == "quick-pane")
.ok_or_else(|| "Quick Pane window configuration is missing".to_owned())?;
WebviewWindowBuilder::from_config(app, config)
.map_err(|error| error.to_string())?
.build()
.map_err(|error| error.to_string())
}
fn toggle_quick_pane(app: &AppHandle) {
let window = match get_or_create_quick_pane(app) {
Ok(window) => window,
Err(error) => {
eprintln!("Could not create Quick Pane window: {error}");
return;
}
};
match quick_pane_action(window.is_visible().unwrap_or(false)) {
WindowAction::Hide => {
let _ = window.hide();
}
WindowAction::ShowAndFocus => {
if let Some(main) = app.get_webview_window("main") {
let _ = main.hide();
}
let _ = window.show();
let _ = window.unminimize();
let _ = window.set_focus();
}
}
}
@@ -419,6 +448,14 @@ pub fn run() {
}
}
}))
.on_window_event(|window, event| {
if should_hide_close_request(window.label()) {
if let WindowEvent::CloseRequested { api, .. } = event {
api.prevent_close();
let _ = window.hide();
}
}
})
.setup(move |app| {
if requested_quick_pane(&launch_args) {
toggle_quick_pane(app.handle());
@@ -504,6 +541,32 @@ mod tests {
assert_eq!(quick_pane_action(true), WindowAction::Hide);
}
#[test]
fn only_quick_pane_native_close_requests_are_hidden() {
assert!(should_hide_close_request("quick-pane"));
assert!(!should_hide_close_request("main"));
}
#[test]
fn quick_pane_recreation_uses_the_complete_configured_window() {
let context: tauri::Context<tauri::Wry> = tauri::generate_context!();
let quick_pane = context
.config()
.app
.windows
.iter()
.find(|window| window.label == "quick-pane")
.unwrap();
assert_eq!(quick_pane.width, 640.0);
assert_eq!(quick_pane.height, 440.0);
assert_eq!(quick_pane.url.to_string(), "index.html");
assert!(!quick_pane.visible);
assert!(quick_pane.transparent);
assert!(quick_pane.always_on_top);
assert!(quick_pane.skip_taskbar);
}
#[test]
fn toggle_hides_a_visible_window_and_shows_a_hidden_window() {
let toggle = vec!["--toggle".to_owned()];