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();