diff options
| author | Adam Malczewski <[email protected]> | 2026-06-13 23:48:14 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-13 23:48:14 +0900 |
| commit | c4939d736ff55fa48cff31a26333f4922430c3d8 (patch) | |
| tree | 66ce055e9b88e1c519bd55038faec7220d04a726 /packages/kernel/src/file_watcher.cpp | |
| parent | 81b40bd6ee8dc2c151f318352a7f68cb7525ef3a (diff) | |
| download | unbox-c4939d736ff55fa48cff31a26333f4922430c3d8.tar.gz unbox-c4939d736ff55fa48cff31a26333f4922430c3d8.zip | |
kernel: fix asset hot-reload regression (watch the whole asset dir, not the .rml basename)
The watch_file refactor (35e5d32) moved the substrate's UI-asset hot-reload onto
the shared FileWatcher but armed a BASENAME watch on the document's .rml file only.
The dock's styling lives in a separately-<link>ed dock.rcss, so editing it (the
common case) never matched the watch — asset hot-reload silently stopped working on
the real seat (no "dev hot-reload ON" line, no reload on save), while config
watching kept working. The ui_reload_surface() seam test passed because it bypassed
the real inotify->reload path.
Fix: FileWatcher::add_dir watches the document's whole DIRECTORY (so any .rml/.rcss
in it triggers the surface reload); the substrate uses it and restores the
"dev hot-reload ON (inotify watching asset dir '...')" log. Added an END-TO-END
test mirroring the dock (a doc that <link>s a separate .rcss, real inotify event,
wl_event_loop pumped, assert the document actually reloaded) — fails on the buggy
code, passes now; no more relying on the seam.
Real-seat verified: editing dock.rcss now reloads the live dock (border-radius +
background-color changes apply on save). kernel 59 cases/260 assertions green on
build + build-asan, no new suppressions. Edits confined to packages/kernel/.
Diffstat (limited to 'packages/kernel/src/file_watcher.cpp')
| -rw-r--r-- | packages/kernel/src/file_watcher.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/packages/kernel/src/file_watcher.cpp b/packages/kernel/src/file_watcher.cpp index ae292c2..c747fe4 100644 --- a/packages/kernel/src/file_watcher.cpp +++ b/packages/kernel/src/file_watcher.cpp @@ -109,6 +109,19 @@ auto FileWatcher::add(const std::string& path, std::function<void()> on_change, return FileWatch(this, token); } +auto FileWatcher::add_dir(const std::string& dir, std::function<void()> on_change, ExtensionId who) + -> FileWatch { + if (!ensure_started()) { + return FileWatch{}; + } + std::string d = dir.empty() ? std::string(".") : dir; + const Token token = ++next_token_; + // Empty basename => match ANY file change in `d`. + entries_.emplace(token, Entry{std::move(d), std::string{}, std::move(on_change), who}); + arm_dir(entries_.at(token).dir); + return FileWatch(this, token); +} + void FileWatcher::remove_watch(Token token) noexcept { auto it = entries_.find(token); if (it == entries_.end()) { @@ -164,7 +177,9 @@ void FileWatcher::on_readable() { std::vector<Token> to_fire; for (const auto& [token, e] : entries_) { for (const auto& [dir, name] : changed) { - if (e.dir == dir && e.basename == name) { + // A file-specific entry matches its basename; a directory entry + // (empty basename) matches ANY file change in its dir. + if (e.dir == dir && (e.basename.empty() || e.basename == name)) { to_fire.push_back(token); break; } |
