fix: bread-theme per-output hot-reload watch reads rename source, not destination (ECO-14) #16
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/eco-14-output-theme-rename-watch"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bug
arm_dir_reload_watchinbread-theme/src/gtk.rs(behindensure_themes_watch()/ensure_palettes_watch(), which drive live per-monitor recolouring for every window bound viabind_window/bind_window_auto/*_with_app_css) never actually fired on a real write.atomic_write(bread-theme/src/output.rs) writes everythemes/<output>.css/palettes/<output>.jsonupdate as write-to-.{name}.tmp.{pid}-then-rename(). WithGFileMonitorFlags::WATCH_MOVESset (which this watch requests), that rename lands as a singleconnect_changedevent wherefileis the source (tmp) path andotheris the destination (final) path.The callback read:
file.path()isSomefor a valid tmp path, soother— the only field carrying the correct.css/.jsonextension — was never consulted.reload_stem_for_eventthen ran against the tmp filename (e.g..eDP-1.css.tmp.12345), failed its extension check, and the event was silently dropped.watch_theme_file(the shared-stylesheet watcher two functions above) already checks bothfileandothercorrectly, which is how this diverged.Confirmed against real GIO
FileMonitorEvent/WATCH_MOVESsemantics and the file's own doc comments.Fix
bread-theme/src/gtk.rs: extracted the file/other selection into a small pure function,reload_event_path, which prefersother(the rename destination) and falls back tofile(for a direct CREATE/CHANGED with no rename, e.g. a non-atomic editor write).arm_dir_reload_watchnow calls it instead of inlining the wrong precedence.Tests
Added
reload_event_path_prefers_the_rename_destination_over_the_tmp_source, a pure unit test mirroring the existingreload_stem_for_event_requires_the_right_extensionstyle.A full
FileMonitor+ real write-then-rename integration test was also tried (arming a real monitor, performing the literalatomic_writesequence, pumping the defaultglib::MainContext) — it passed in isolation but collided withshell::hotreload's own context-pumping tests under the default parallel test runner (the same runner CI uses:cargo test --workspace --locked --features gtk), aborting the whole test binary via glib's thread guard. Dropped in favor of the pure-function unit test, per the existing precedent in this file for keeping GTK/GIO-event-loop-dependent tests isolated (see the#[ignore]d widget-lifecycle tests' module note).cargo build --releaseandcargo test --release --workspace --locked --features gtkpass, run 3x with no flakiness.Fixes ECO-14.
Pull request closed