Linux: file watchers skip reads, so idle apps stop rereading theme, settings and repos (L1.2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-11 02:28:29 -04:00
1 parent c62d548688
commit b2e13230b5
12 files changed
+211 -9

No files matched your search

+8 -3
View File
@@ -29,9 +29,12 @@ pub fn load(current: &Path) -> Result<Option<OmarchyTheme>> {
Err(error) if error.kind() == io::ErrorKind::NotFound => return Ok(None),
Err(error) => return Err(error).with_context(|| format!("cannot read {}", file.display())),
};
let name = fs::read_to_string(current.join("theme.name"))
.ok()
.map(|name| name.trim().to_string());
let name_file = current.join("theme.name");
let name = match fs::read_to_string(&name_file) {
Ok(name) => Some(name.trim().to_string()),
Err(error) if error.kind() == io::ErrorKind::NotFound => None,
Err(error) => return Err(error).with_context(|| format!("cannot read {}", name_file.display())),
};
parse(&text, name, theme.join("light.mode").exists())
.with_context(|| format!("{} is not a usable theme", file.display()))
.map(Some)
@@ -53,6 +56,8 @@ pub fn changes(current: &Path) -> Result<(RecommendedWatcher, UnboundedReceiver<
let (sender, receiver) = mpsc::unbounded();
let mut watcher =
notify::recommended_watcher(move |event: notify::Result<notify::Event>| match event {
// Reads, ours included, are no change.
Ok(event) if crate::watching::only_read(&event.kind) => {}
Ok(_) => {
let _ = sender.unbounded_send(());
}
+26
View File
@@ -314,3 +314,29 @@ fn changes_sees_a_theme_swap_in_the_order_omarchy_does_it() {
"no event for a swapped theme"
);
}
#[test]
fn reading_the_theme_is_no_change() {
let current = tempfile::tempdir().unwrap();
let theme_dir = current.path().join("theme");
fs::create_dir(&theme_dir).unwrap();
fs::write(theme_dir.join("colors.toml"), LATTE).unwrap();
fs::write(current.path().join("theme.name"), "catppuccin-latte\n").unwrap();
let (_watcher, mut events) = changes(current.path()).unwrap();
load(current.path()).unwrap().expect("a theme");
assert!(!event_within(&mut events, 10), "a read counted as a change");
}
#[test]
fn an_unreadable_theme_name_is_an_error_and_a_missing_one_is_none() {
let current = tempfile::tempdir().unwrap();
let theme_dir = current.path().join("theme");
fs::create_dir(&theme_dir).unwrap();
fs::write(theme_dir.join("colors.toml"), LATTE).unwrap();
assert_eq!(load(current.path()).unwrap().unwrap().name, None);
fs::create_dir(current.path().join("theme.name")).unwrap();
let error = format!("{:#}", load(current.path()).unwrap_err());
assert!(error.contains("theme.name"), "{error}");
}