Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10f62fb1a6 | ||
|
|
5e58558dd3 |
2 changed files with 34 additions and 10 deletions
|
|
@ -26,6 +26,33 @@ fn reload_app() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Watch the shared stylesheet for changes and run `reload` when it's rewritten.
|
||||||
|
///
|
||||||
|
/// `bread-theme` writes the file with write-tmp-then-rename (atomic), which
|
||||||
|
/// *replaces the inode*. A monitor on the file itself dies after the first
|
||||||
|
/// replace (inotify reports DELETE_SELF and never re-arms), so we monitor the
|
||||||
|
/// parent *directory* and filter for the stylesheet's filename — that fires
|
||||||
|
/// reliably on every reload. Returns the monitor (keep it alive to stay armed).
|
||||||
|
fn watch_theme_file(reload: fn()) -> Option<gio::FileMonitor> {
|
||||||
|
let target = crate::shared_css_path();
|
||||||
|
let dir = target.parent()?;
|
||||||
|
// The dir must exist to be monitored; `bread-theme generate` makes it at
|
||||||
|
// login, but create it here too so a GUI started first still arms the watch.
|
||||||
|
let _ = std::fs::create_dir_all(dir);
|
||||||
|
let monitor = gio::File::for_path(dir)
|
||||||
|
.monitor_directory(gio::FileMonitorFlags::WATCH_MOVES, gio::Cancellable::NONE)
|
||||||
|
.ok()?;
|
||||||
|
monitor.connect_changed(move |_, file, other, _event| {
|
||||||
|
// The rename lands as an event whose file (or move destination) is the
|
||||||
|
// stylesheet. Match either to catch both CREATED/CHANGED and MOVED_IN.
|
||||||
|
let is_target = |f: &gio::File| f.path().as_deref() == Some(target.as_path());
|
||||||
|
if is_target(file) || other.is_some_and(is_target) {
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Some(monitor)
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply an app's *own* stylesheet and keep it live across palette changes.
|
/// Apply an app's *own* stylesheet and keep it live across palette changes.
|
||||||
///
|
///
|
||||||
/// `build` is called now to produce the app-specific CSS, and again every time
|
/// `build` is called now to produce the app-specific CSS, and again every time
|
||||||
|
|
@ -47,11 +74,7 @@ pub fn apply_app_css<F: Fn() -> String + 'static>(build: F) {
|
||||||
if cell.borrow().is_some() {
|
if cell.borrow().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let file = gio::File::for_path(crate::shared_css_path());
|
*cell.borrow_mut() = watch_theme_file(reload_app);
|
||||||
if let Ok(monitor) = file.monitor_file(gio::FileMonitorFlags::NONE, gio::Cancellable::NONE) {
|
|
||||||
monitor.connect_changed(|_, _, _, _| reload_app());
|
|
||||||
*cell.borrow_mut() = Some(monitor);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,11 +91,7 @@ pub fn apply_shared() {
|
||||||
if cell.borrow().is_some() {
|
if cell.borrow().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let file = gio::File::for_path(crate::shared_css_path());
|
*cell.borrow_mut() = watch_theme_file(reload_shared);
|
||||||
if let Ok(monitor) = file.monitor_file(gio::FileMonitorFlags::NONE, gio::Cancellable::NONE) {
|
|
||||||
monitor.connect_changed(|_, _, _, _| reload_shared());
|
|
||||||
*cell.borrow_mut() = Some(monitor);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,3 +36,8 @@ description = "Profile-aware Wi-Fi state machine with Tailscale integration"
|
||||||
name = "breadpad"
|
name = "breadpad"
|
||||||
repo = "Breadway/breadpad"
|
repo = "Breadway/breadpad"
|
||||||
description = "Quick-capture scratchpad and note viewer with AI classification"
|
description = "Quick-capture scratchpad and note viewer with AI classification"
|
||||||
|
|
||||||
|
[[products]]
|
||||||
|
name = "breadpaper"
|
||||||
|
repo = "Breadway/breadpaper"
|
||||||
|
description = "Wallpaper manager for the bread desktop"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue