From 7a37355e177772cbddf24397d5a23280e00558af Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Mon, 16 Sep 2024 05:01:27 +0800 Subject: [PATCH] fix(window-state): deadlock when trying to restore window states on initial load (#1787) * Fix deadlock when trying to restore window the size on initial load * Typo --- .changes/fix-restore-window-state-deadlock.md | 5 +++++ plugins/window-state/src/lib.rs | 20 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 .changes/fix-restore-window-state-deadlock.md diff --git a/.changes/fix-restore-window-state-deadlock.md b/.changes/fix-restore-window-state-deadlock.md new file mode 100644 index 00000000..b9145064 --- /dev/null +++ b/.changes/fix-restore-window-state-deadlock.md @@ -0,0 +1,5 @@ +--- +"window-state": patch +--- + +Fix deadlock when trying to restore window states on initial load diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index 5d2b5bf4..15599da8 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -105,6 +105,8 @@ impl Default for WindowState { } struct WindowStateCache(Arc>>); +/// 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<()>; @@ -167,6 +169,8 @@ impl WindowExt for Window { .map(|map| map(self.label())) .unwrap_or_else(|| self.label()); + let restoring_window_state = self.state::(); + let _restoring_window_lock = restoring_window_state.0.lock().unwrap(); let cache = self.state::(); let mut c = cache.0.lock().unwrap(); @@ -396,6 +400,7 @@ impl Builder { Default::default() }; app.manage(WindowStateCache(cache)); + app.manage(RestoringWindowState(Mutex::new(()))); app.manage(PluginState { filename, map_label, @@ -443,7 +448,13 @@ impl Builder { } WindowEvent::Moved(position) if flags.contains(StateFlags::POSITION) => { - if !window_clone.is_minimized().unwrap_or_default() { + if window_clone + .state::() + .0 + .try_lock() + .is_ok() + && !window_clone.is_minimized().unwrap_or_default() + { let mut c = cache.lock().unwrap(); if let Some(state) = c.get_mut(&label) { state.prev_x = state.x; @@ -455,7 +466,12 @@ impl Builder { } } WindowEvent::Resized(size) if flags.contains(StateFlags::SIZE) => { - if !window_clone.is_minimized().unwrap_or_default() + if window_clone + .state::() + .0 + .try_lock() + .is_ok() + && !window_clone.is_minimized().unwrap_or_default() && !window_clone.is_maximized().unwrap_or_default() { let mut c = cache.lock().unwrap();