From 0ec895c378d4700cf8d7a002c6d9829f3c015b9f Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Sat, 18 Jan 2025 03:31:20 +0200 Subject: [PATCH] feat(window-state): add filter callback for excluding windows from tracking (#2330) * feat(window-state): Add glob pattern support to denylist for flexible window management * changefile fix(window-state): Remove unnecessary reference in denylist pattern processing chore(changes): Update window-state and window-state-js versioning for glob pattern support docs(window-state): Update glob pattern denylist documentation for clarity * refactor(window-state): Simplify denylist handling and error management in with_denylist method * feat: add with_denylist_glob * feat(window-state): Add filter callback for excluding windows from tracking * refactor(window-state): Remove unused Glob error variant from Error enum * refactor(window-state): Change filter_callback from Arc> to Box * refactor(window-state): Remove glob dependency from Cargo.toml and Cargo.lock * feat(window-state): Introduce filter callback for dynamic window exclusion * Update .changes/window-state-filter-callback.md --- .changes/window-state-filter-callback.md | 6 ++++++ plugins/window-state/src/lib.rs | 23 ++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 .changes/window-state-filter-callback.md diff --git a/.changes/window-state-filter-callback.md b/.changes/window-state-filter-callback.md new file mode 100644 index 0000000000..e5846966b5 --- /dev/null +++ b/.changes/window-state-filter-callback.md @@ -0,0 +1,6 @@ +--- +window-state: patch +window-state-js: patch +--- + +Add `Builder::with_filter` callback to exclude specific windows from saving their state. This allows for more flexibility by enabling dynamic exclusion of windows based on custom logic. \ No newline at end of file diff --git a/plugins/window-state/src/lib.rs b/plugins/window-state/src/lib.rs index 8c675d4dab..1f4abdd633 100644 --- a/plugins/window-state/src/lib.rs +++ b/plugins/window-state/src/lib.rs @@ -27,6 +27,7 @@ use std::{ mod cmd; type LabelMapperFn = dyn Fn(&str) -> &str + Send + Sync; +type FilterCallbackFn = dyn Fn(&str) -> bool + Send + Sync; /// Default filename used to store window state. /// @@ -320,6 +321,7 @@ impl WindowExtInternal for Window { #[derive(Default)] pub struct Builder { denylist: HashSet, + filter_callback: Option>, skip_initial_state: HashSet, state_flags: StateFlags, map_label: Option>, @@ -344,12 +346,22 @@ impl Builder { } /// Sets a list of windows that shouldn't be tracked and managed by this plugin - /// for example splash screen windows. + /// For example, splash screen windows. pub fn with_denylist(mut self, denylist: &[&str]) -> Self { self.denylist = denylist.iter().map(|l| l.to_string()).collect(); self } + /// 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(mut self, filter_callback: F) -> Self + where + F: Fn(&str) -> bool + Send + Sync + 'static, + { + self.filter_callback = Some(Box::new(filter_callback)); + self + } + /// Adds the given window label to a list of windows to skip initial state restore. pub fn skip_initial_state(mut self, label: &str) -> Self { self.skip_initial_state.insert(label.into()); @@ -413,10 +425,19 @@ impl Builder { .map(|map| map(window.label())) .unwrap_or_else(|| window.label()); + // Check deny list names if self.denylist.contains(label) { return; } + // Check deny list callback + if let Some(filter_callback) = &self.filter_callback { + // Don't save the state if the callback returns false + if !filter_callback(label) { + return; + } + } + if !self.skip_initial_state.contains(label) { let _ = window.restore_state(self.state_flags); }