diff --git a/packages/desktop/src-tauri/src/lib.rs b/packages/desktop/src-tauri/src/lib.rs index 2fe7c4aa176..a177e6ceedd 100644 --- a/packages/desktop/src-tauri/src/lib.rs +++ b/packages/desktop/src-tauri/src/lib.rs @@ -23,13 +23,18 @@ use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_dialog::{DialogExt, MessageDialogButtons, MessageDialogResult}; use tauri_plugin_shell::process::{CommandChild, CommandEvent}; use tauri_plugin_store::StoreExt; -use tokio::sync::oneshot; +use tauri_plugin_window_state::{AppHandleExt, StateFlags}; +use tokio::sync::{mpsc, oneshot}; use crate::window_customizer::PinchZoomDisablePlugin; const SETTINGS_STORE: &str = "opencode.settings.dat"; const DEFAULT_SERVER_URL_KEY: &str = "defaultServerUrl"; +fn window_state_flags() -> StateFlags { + StateFlags::all() - StateFlags::DECORATIONS +} + #[derive(Clone, serde::Serialize, specta::Type)] struct ServerReadyData { url: String, @@ -293,10 +298,7 @@ pub fn run() { .plugin(tauri_plugin_os::init()) .plugin( tauri_plugin_window_state::Builder::new() - .with_state_flags( - tauri_plugin_window_state::StateFlags::all() - - tauri_plugin_window_state::StateFlags::DECORATIONS, - ) + .with_state_flags(window_state_flags()) .build(), ) .plugin(tauri_plugin_store::Builder::new().build()) @@ -365,6 +367,8 @@ pub fn run() { let window = window_builder.build().expect("Failed to create window"); + setup_window_state_listener(&app, &window); + #[cfg(windows)] let _ = window.create_overlay_titlebar(); @@ -560,3 +564,34 @@ async fn spawn_local_server( } } } + +fn setup_window_state_listener(app: &tauri::AppHandle, window: &tauri::WebviewWindow) { + let (tx, mut rx) = mpsc::channel::<()>(1); + + window.on_window_event(move |event| { + if !matches!(event, WindowEvent::Moved(_) | WindowEvent::Resized(_)) { + return; + } + let _ = tx.try_send(()); + }); + + tauri::async_runtime::spawn({ + let app = app.clone(); + + async move { + let save = || { + let handle = app.clone(); + let app = app.clone(); + let _ = handle.run_on_main_thread(move || { + let _ = app.save_window_state(window_state_flags()); + }); + }; + + while rx.recv().await.is_some() { + tokio::time::sleep(Duration::from_millis(200)).await; + + save(); + } + } + }); +} diff --git a/packages/desktop/src-tauri/src/window_customizer.rs b/packages/desktop/src-tauri/src/window_customizer.rs index 682f57f2471..d73662120ac 100644 --- a/packages/desktop/src-tauri/src/window_customizer.rs +++ b/packages/desktop/src-tauri/src/window_customizer.rs @@ -1,4 +1,4 @@ -use tauri::{plugin::Plugin, Manager, Runtime, Window}; +use tauri::{Manager, Runtime, Window, plugin::Plugin}; pub struct PinchZoomDisablePlugin; @@ -21,8 +21,8 @@ impl Plugin for PinchZoomDisablePlugin { let _ = webview_window.with_webview(|_webview| { #[cfg(target_os = "linux")] unsafe { - use gtk::glib::ObjectExt; use gtk::GestureZoom; + use gtk::glib::ObjectExt; use webkit2gtk::glib::gobject_ffi; if let Some(data) = _webview.inner().data::("wk-view-zoom-gesture") {