From 9ae9671b591596508fa15fc87194923226924b12 Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Tue, 25 Jun 2024 15:02:24 -0300 Subject: [PATCH 1/6] feat(window-state): add `map_label` option --- .changes/window-state-map-label.md | 5 +++++ plugins/window-state/src/lib.rs | 34 ++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 .changes/window-state-map-label.md diff --git a/.changes/window-state-map-label.md b/.changes/window-state-map-label.md new file mode 100644 index 0000000000..fcba8313af --- /dev/null +++ b/.changes/window-state-map-label.md @@ -0,0 +1,5 @@ +--- +"window-state": patch +--- + +Add `map_label` option to transform the window label before using it internally, based on [amrbashir's suggestion](https://github.com/tauri-apps/plugins-workspace/pull/531#pullrequestreview-1566282300). \ No newline at end of file diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index c71458312f..164ab6e4a7 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -65,6 +65,7 @@ impl Default for StateFlags { struct PluginState { filename: String, + map_label: Option &str) + Send + Sync>>, } #[derive(Debug, Deserialize, Serialize, PartialEq)] @@ -148,13 +149,20 @@ impl WindowExt for WebviewWindow { } impl WindowExt for Window { fn restore_state(&self, flags: StateFlags) -> tauri::Result<()> { + let plugin_state = self.app_handle().state::(); + let label = plugin_state + .map_label + .as_ref() + .map(|map| map(self.label())) + .unwrap_or_else(|| self.label()); + let cache = self.state::(); let mut c = cache.0.lock().unwrap(); let mut should_show = true; if let Some(state) = c - .get(self.label()) + .get(label) .filter(|state| state != &&WindowState::default()) { if flags.contains(StateFlags::DECORATIONS) { @@ -235,7 +243,7 @@ impl WindowExt for Window { metadata.fullscreen = self.is_fullscreen()?; } - c.insert(self.label().into(), metadata); + c.insert(label.into(), metadata); } if flags.contains(StateFlags::VISIBLE) && should_show { @@ -309,6 +317,7 @@ pub struct Builder { denylist: HashSet, skip_initial_state: HashSet, state_flags: StateFlags, + map_label: Option &str) + Send + Sync>>, filename: Option, } @@ -342,9 +351,15 @@ impl Builder { self } + pub fn map_label(mut self, map_fn: fn(&str) -> &str) -> Self { + self.map_label = Some(Box::new(map_fn)); + self + } + pub fn build(self) -> TauriPlugin { let flags = self.state_flags; let filename = self.filename.unwrap_or_else(|| DEFAULT_FILENAME.into()); + let map_label = self.map_label; PluginBuilder::new("window-state") .invoke_handler(tauri::generate_handler![ @@ -372,21 +387,28 @@ impl Builder { Default::default() }; app.manage(WindowStateCache(cache)); - app.manage(PluginState { filename }); + app.manage(PluginState { filename, map_label }); Ok(()) }) .on_window_ready(move |window| { - if self.denylist.contains(window.label()) { + let plugin_state = window.app_handle().state::(); + let label = plugin_state + .map_label + .as_ref() + .map(|map| map(window.label())) + .unwrap_or_else(|| window.label()); + + if self.denylist.contains(label) { return; } - if !self.skip_initial_state.contains(window.label()) { + if !self.skip_initial_state.contains(label) { let _ = window.restore_state(self.state_flags); } let cache = window.state::(); let cache = cache.0.clone(); - let label = window.label().to_string(); + let label = label.to_string(); let window_clone = window.clone(); let flags = self.state_flags; From e8eca70e9f0124cbdd4d5ef77dc95917b99eeafb Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Tue, 25 Jun 2024 23:35:39 -0300 Subject: [PATCH 2/6] fix: update `save_window_state` function logic --- .changes/window-state-map-label.md | 2 +- plugins/window-state/src/lib.rs | 26 ++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.changes/window-state-map-label.md b/.changes/window-state-map-label.md index fcba8313af..23b4e9e9d3 100644 --- a/.changes/window-state-map-label.md +++ b/.changes/window-state-map-label.md @@ -2,4 +2,4 @@ "window-state": patch --- -Add `map_label` option to transform the window label before using it internally, based on [amrbashir's suggestion](https://github.com/tauri-apps/plugins-workspace/pull/531#pullrequestreview-1566282300). \ No newline at end of file +Add `Builder::map_label` option to transform the window label when saving the window state, this could be used to group different windows to use the same state. \ No newline at end of file diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index 164ab6e4a7..e86e6f1fc3 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -65,7 +65,7 @@ impl Default for StateFlags { struct PluginState { filename: String, - map_label: Option &str) + Send + Sync>>, + map_label: Option &str + Send + Sync>>, } #[derive(Debug, Deserialize, Serialize, PartialEq)] @@ -115,10 +115,22 @@ impl AppHandleExt for tauri::AppHandle { if let Ok(app_dir) = self.path().app_config_dir() { let plugin_state = self.state::(); let state_path = app_dir.join(&plugin_state.filename); + let windows = self.webview_windows(); let cache = self.state::(); let mut state = cache.0.lock().unwrap(); + for (label, s) in state.iter_mut() { - if let Some(window) = self.get_webview_window(label) { + let window = match &plugin_state.map_label { + Some(map) => { + windows + .iter() + .find(|(l, _)| map(l) == label) + .map(|(_, window)| window) + }, + None => windows.get(label) + }; + + if let Some(window) = window { window.update_state(s, flags)?; } } @@ -317,7 +329,7 @@ pub struct Builder { denylist: HashSet, skip_initial_state: HashSet, state_flags: StateFlags, - map_label: Option &str) + Send + Sync>>, + map_label: Option &str + Send + Sync>>, filename: Option, } @@ -351,7 +363,13 @@ impl Builder { self } - pub fn map_label(mut self, map_fn: fn(&str) -> &str) -> Self { + /// Transforms the window label when saving the window state. + /// + /// This can be used to group different windows to use the same state. + pub fn map_label(mut self, map_fn: F) -> Self + where + F: Fn(&str) -> &str + Sync + Send + 'static + { self.map_label = Some(Box::new(map_fn)); self } From 80b37f29d05cc1a8c32a18f939fff8c892c5c086 Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Tue, 25 Jun 2024 23:58:01 -0300 Subject: [PATCH 3/6] refactor: use `find_map` --- plugins/window-state/src/lib.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index e86e6f1fc3..f371ad9274 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -121,13 +121,10 @@ impl AppHandleExt for tauri::AppHandle { for (label, s) in state.iter_mut() { let window = match &plugin_state.map_label { - Some(map) => { - windows - .iter() - .find(|(l, _)| map(l) == label) - .map(|(_, window)| window) - }, - None => windows.get(label) + Some(map) => windows + .iter() + .find_map(|(l, window)| (map(l) == label).then_some(window)), + None => windows.get(label), }; if let Some(window) = window { @@ -364,11 +361,11 @@ impl Builder { } /// Transforms the window label when saving the window state. - /// + /// /// This can be used to group different windows to use the same state. pub fn map_label(mut self, map_fn: F) -> Self - where - F: Fn(&str) -> &str + Sync + Send + 'static + where + F: Fn(&str) -> &str + Sync + Send + 'static, { self.map_label = Some(Box::new(map_fn)); self @@ -405,7 +402,10 @@ impl Builder { Default::default() }; app.manage(WindowStateCache(cache)); - app.manage(PluginState { filename, map_label }); + app.manage(PluginState { + filename, + map_label, + }); Ok(()) }) .on_window_ready(move |window| { From f4f0aa833528b1d87e97856da3d26516e3007fae Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Wed, 26 Jun 2024 06:29:21 +0300 Subject: [PATCH 4/6] clippy --- plugins/window-state/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index f371ad9274..00e12f49f8 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -28,6 +28,8 @@ use std::{ mod cmd; +type LabelMapperFn = Fn(&str) -> &str + Send + Sync; + /// Default filename used to store window state. /// /// If using a custom filename, you should probably use [`AppHandleExt::filename`] instead. @@ -65,7 +67,7 @@ impl Default for StateFlags { struct PluginState { filename: String, - map_label: Option &str + Send + Sync>>, + map_label: Option, } #[derive(Debug, Deserialize, Serialize, PartialEq)] @@ -326,7 +328,7 @@ pub struct Builder { denylist: HashSet, skip_initial_state: HashSet, state_flags: StateFlags, - map_label: Option &str + Send + Sync>>, + map_label: Option>, filename: Option, } From 5c8447a5781a66ed10da1852f65de72617efb3c6 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Wed, 26 Jun 2024 06:32:01 +0300 Subject: [PATCH 5/6] Update plugins/window-state/src/lib.rs --- plugins/window-state/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index 00e12f49f8..5947586de3 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -67,7 +67,7 @@ impl Default for StateFlags { struct PluginState { filename: String, - map_label: Option, + map_label: Option>, } #[derive(Debug, Deserialize, Serialize, PartialEq)] From 400f0b24a925c96e0e9b56ef2cd6281f3b30d61c Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Wed, 26 Jun 2024 00:39:34 -0300 Subject: [PATCH 6/6] fix: fix lint errors --- plugins/window-state/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index 5947586de3..e577b45f34 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -28,7 +28,7 @@ use std::{ mod cmd; -type LabelMapperFn = Fn(&str) -> &str + Send + Sync; +type LabelMapperFn = dyn Fn(&str) -> &str + Send + Sync; /// Default filename used to store window state. /// @@ -67,7 +67,7 @@ impl Default for StateFlags { struct PluginState { filename: String, - map_label: Option>, + map_label: Option>, } #[derive(Debug, Deserialize, Serialize, PartialEq)] @@ -328,7 +328,7 @@ pub struct Builder { denylist: HashSet, skip_initial_state: HashSet, state_flags: StateFlags, - map_label: Option>, + map_label: Option>, filename: Option, }