Skip to content

Commit

Permalink
feat(window-state): add filter callback for excluding windows from tr…
Browse files Browse the repository at this point in the history
…acking (#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<Mutex<FilterCallbackFn>> to Box<FilterCallbackFn>

* 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
  • Loading branch information
thewh1teagle authored Jan 18, 2025
1 parent 406e6f4 commit 0ec895c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changes/window-state-filter-callback.md
Original file line number Diff line number Diff line change
@@ -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.
23 changes: 22 additions & 1 deletion plugins/window-state/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -320,6 +321,7 @@ impl<R: Runtime> WindowExtInternal for Window<R> {
#[derive(Default)]
pub struct Builder {
denylist: HashSet<String>,
filter_callback: Option<Box<FilterCallbackFn>>,
skip_initial_state: HashSet<String>,
state_flags: StateFlags,
map_label: Option<Box<LabelMapperFn>>,
Expand All @@ -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<F>(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());
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 0ec895c

Please sign in to comment.