refactor(window-state): simply some code (#2578)

pull/2581/head
Tony 2 months ago committed by GitHub
parent 6fa388d0b2
commit a77b1353e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -14,13 +14,14 @@ use bitflags::bitflags;
use serde::{Deserialize, Serialize};
use tauri::{
plugin::{Builder as PluginBuilder, TauriPlugin},
Manager, Monitor, PhysicalPosition, PhysicalSize, RunEvent, Runtime, WebviewWindow, Window,
WindowEvent,
AppHandle, Manager, Monitor, PhysicalPosition, PhysicalSize, RunEvent, Runtime, WebviewWindow,
Window, WindowEvent,
};
use std::{
collections::{HashMap, HashSet},
fs::{create_dir_all, File},
fs::create_dir_all,
io::BufReader,
sync::{Arc, Mutex},
};
@ -106,6 +107,7 @@ impl Default for WindowState {
struct WindowStateCache(Arc<Mutex<HashMap<String, WindowState>>>);
/// Used to prevent deadlocks from resize and position event listeners setting the cached state on restoring states
struct RestoringWindowState(Mutex<()>);
pub trait AppHandleExt {
/// Saves all open windows state to disk
fn save_window_state(&self, flags: StateFlags) -> Result<()>;
@ -115,33 +117,31 @@ pub trait AppHandleExt {
impl<R: Runtime> AppHandleExt for tauri::AppHandle<R> {
fn save_window_state(&self, flags: StateFlags) -> Result<()> {
if let Ok(app_dir) = self.path().app_config_dir() {
let plugin_state = self.state::<PluginState>();
let state_path = app_dir.join(&plugin_state.filename);
let windows = self.webview_windows();
let cache = self.state::<WindowStateCache>();
let mut state = cache.0.lock().unwrap();
for (label, s) in state.iter_mut() {
let window = match &plugin_state.map_label {
Some(map) => windows
.iter()
.find_map(|(l, window)| (map(l) == label).then_some(window)),
None => windows.get(label),
};
if let Some(window) = window {
window.update_state(s, flags)?;
}
let app_dir = self.path().app_config_dir()?;
let plugin_state = self.state::<PluginState>();
let state_path = app_dir.join(&plugin_state.filename);
let windows = self.webview_windows();
let cache = self.state::<WindowStateCache>();
let mut state = cache.0.lock().unwrap();
for (label, s) in state.iter_mut() {
let window = if let Some(map) = &plugin_state.map_label {
windows
.iter()
.find_map(|(l, window)| (map(l) == label).then_some(window))
} else {
windows.get(label)
};
if let Some(window) = window {
window.update_state(s, flags)?;
}
create_dir_all(&app_dir)
.map_err(Error::Io)
.and_then(|_| File::create(state_path).map_err(Into::into))
.and_then(|mut f| serde_json::to_writer_pretty(&mut f, &*state).map_err(Into::into))
} else {
Ok(())
}
create_dir_all(app_dir)?;
std::fs::write(state_path, serde_json::to_vec_pretty(&*state)?)?;
Ok(())
}
fn filename(&self) -> String {
@ -159,6 +159,7 @@ impl<R: Runtime> WindowExt for WebviewWindow<R> {
self.as_ref().window().restore_state(flags)
}
}
impl<R: Runtime> WindowExt for Window<R> {
fn restore_state(&self, flags: StateFlags) -> tauri::Result<()> {
let plugin_state = self.app_handle().state::<PluginState>();
@ -352,7 +353,7 @@ impl Builder {
self
}
/// Sets a filter callback to exclude specific windows from being tracked.
/// Sets a filter callback to exclude specific windows from being tracked.
/// Return `true` to save the state, or `false` to skip and not save it.
pub fn with_filter<F>(mut self, filter_callback: F) -> Self
where
@ -391,25 +392,8 @@ impl Builder {
cmd::filename
])
.setup(|app, _api| {
let cache: Arc<Mutex<HashMap<String, WindowState>>> =
if let Ok(app_dir) = app.path().app_config_dir() {
let state_path = app_dir.join(&filename);
if state_path.exists() {
Arc::new(Mutex::new(
std::fs::read(state_path)
.map_err(Error::from)
.and_then(|state| {
serde_json::from_slice(&state).map_err(Into::into)
})
.unwrap_or_default(),
))
} else {
Default::default()
}
} else {
Default::default()
};
app.manage(WindowStateCache(cache));
let cache = load_saved_window_states(app, &filename).unwrap_or_default();
app.manage(WindowStateCache(Arc::new(Mutex::new(cache))));
app.manage(RestoringWindowState(Mutex::new(())));
app.manage(PluginState {
filename,
@ -522,6 +506,18 @@ impl Builder {
}
}
fn load_saved_window_states<R: Runtime>(
app: &AppHandle<R>,
filename: &String,
) -> Result<HashMap<String, WindowState>> {
let app_dir = app.path().app_config_dir()?;
let state_path = app_dir.join(filename);
let file = std::fs::File::open(state_path)?;
let reader = BufReader::new(file);
let states = serde_json::from_reader(reader)?;
Ok(states)
}
trait MonitorExt {
fn intersects(&self, position: PhysicalPosition<i32>, size: PhysicalSize<u32>) -> bool;
}

Loading…
Cancel
Save