improv(cosmic-config): use notifier debouncer on inotify watchers

This commit is contained in:
Michael Aaron Murphy 2025-06-23 17:13:58 +02:00
parent 5be9611c8a
commit 90ad3e9e1b
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
3 changed files with 14 additions and 10 deletions

View file

@ -26,6 +26,7 @@ dirs.workspace = true
tokio = { version = "1.44", optional = true, features = ["time"] } tokio = { version = "1.44", optional = true, features = ["time"] }
async-std = { version = "1.13", optional = true } async-std = { version = "1.13", optional = true }
tracing = "0.1" tracing = "0.1"
notify-debouncer-full = "0.5.0"
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
xdg = "2.5" xdg = "2.5"

View file

@ -1,15 +1,15 @@
//! Integrations for cosmic-config — the cosmic configuration system. //! Integrations for cosmic-config — the cosmic configuration system.
use notify::{ use notify::{
event::{EventKind, ModifyKind}, event::{EventKind, ModifyKind}, RecommendedWatcher, Watcher
Watcher,
}; };
use notify_debouncer_full::{DebouncedEvent, Debouncer, RecommendedCache};
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Serialize};
use std::{ use std::{
fmt, fs, fmt, fs,
io::Write, io::Write,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::Mutex, sync::Mutex, time::Duration,
}; };
#[cfg(feature = "subscription")] #[cfg(feature = "subscription")]
@ -244,7 +244,7 @@ impl Config {
// This may end up being an mpsc channel instead of a function // This may end up being an mpsc channel instead of a function
// See EventHandler in the notify crate: https://docs.rs/notify/latest/notify/trait.EventHandler.html // See EventHandler in the notify crate: https://docs.rs/notify/latest/notify/trait.EventHandler.html
// Having a callback allows for any application abstraction to be used // Having a callback allows for any application abstraction to be used
pub fn watch<F>(&self, f: F) -> Result<notify::RecommendedWatcher, Error> pub fn watch<F>(&self, f: F) -> Result<Debouncer<RecommendedWatcher, RecommendedCache>, Error>
// Argument is an array of all keys that changed in that specific transaction // Argument is an array of all keys that changed in that specific transaction
//TODO: simplify F requirements //TODO: simplify F requirements
where where
@ -256,10 +256,11 @@ impl Config {
}; };
let user_path_clone = user_path.clone(); let user_path_clone = user_path.clone();
let mut watcher = let mut watcher =
notify::recommended_watcher(move |event_res: Result<notify::Event, notify::Error>| { notify_debouncer_full::new_debouncer(Duration::from_secs(1), None, move |event_res: Result<Vec<DebouncedEvent>, Vec<notify::Error>>| {
match &event_res { match event_res {
Ok(event) => { Ok(events) => {
match &event.kind { for event in events {
match &event.event.kind {
EventKind::Access(_) | EventKind::Modify(ModifyKind::Metadata(_)) => { EventKind::Access(_) | EventKind::Modify(ModifyKind::Metadata(_)) => {
// Data not mutated // Data not mutated
return; return;
@ -287,8 +288,9 @@ impl Config {
if !keys.is_empty() { if !keys.is_empty() {
f(&watch_config, &keys); f(&watch_config, &keys);
} }
}
} }
Err(_err) => { Err(_errs) => {
//TODO: handle errors //TODO: handle errors
} }
} }

View file

@ -1,13 +1,14 @@
use iced_futures::futures::{SinkExt, Stream}; use iced_futures::futures::{SinkExt, Stream};
use iced_futures::{futures::channel::mpsc, stream}; use iced_futures::{futures::channel::mpsc, stream};
use notify::RecommendedWatcher; use notify::RecommendedWatcher;
use notify_debouncer_full::{Debouncer, RecommendedCache};
use std::{borrow::Cow, hash::Hash}; use std::{borrow::Cow, hash::Hash};
use crate::{Config, CosmicConfigEntry}; use crate::{Config, CosmicConfigEntry};
pub enum ConfigState<T> { pub enum ConfigState<T> {
Init(Cow<'static, str>, u64, bool), Init(Cow<'static, str>, u64, bool),
Waiting(T, RecommendedWatcher, mpsc::Receiver<Vec<String>>, Config), Waiting(T, Debouncer<RecommendedWatcher, RecommendedCache>, mpsc::Receiver<Vec<String>>, Config),
Failed, Failed,
} }