aboutsummaryrefslogtreecommitdiffstats
path: root/src/app.c
diff options
context:
space:
mode:
authoruser <user@clank>2026-08-15 23:18:00 +0200
committeruser <user@clank>2026-08-15 23:18:00 +0200
commit930f8f04f0b3b487031514615ca7ace7ad7bbe9c (patch)
treecaa887f2c5630e1c531254a75e374a2efebddf33 /src/app.c
parentsl0ppty: a config can be made of files (diff)
downloadslosh-930f8f04f0b3b487031514615ca7ace7ad7bbe9c.tar.gz
slosh-930f8f04f0b3b487031514615ca7ace7ad7bbe9c.tar.xz
slosh-930f8f04f0b3b487031514615ca7ace7ad7bbe9c.zip
sl0ppty: watch what the config was built from, not just what it was called
An included theme that does not reload when you save it is half a feature, and the half that is missing is the one the file headers in contrib/themes have been promising all along ("a running session re-reads it the moment you save"). That was true while a theme was something you pasted; the moment it became something you include, the watch was on the wrong file. So a config now remembers every file it was read from -- itself and everything it included -- and the watcher watches all of them. Recorded before each parse rather than after, because a file that is not there yet is exactly the file worth watching: writing it is the next thing that will happen, and that is the same reason the watch is on directories rather than on files. Deduplicated, so a cycle does not fill the list with two names twice. The set is rebuilt after every successful load, because it is a property of the config that just loaded: an include can be added, pointed somewhere else, or taken out, and the watch has to follow. One inotify watch per directory, deduplicated by the descriptor inotify hands back for a directory it is already watching; names are matched against the whole set rather than against the directory whose watch fired, which means two directories holding a file of the same name reload for each other's save. That costs a debounced re-read of a config that has not changed, and is not worth a second data structure to avoid. Only the main config's directory is created if missing. An include's is not: a mistyped path should not leave a directory behind. tests/test_reload.py drives a real session for this one -- the watcher is the thing under test and the headless driver has none. It writes a config that includes a theme, checks the theme applied at startup, then edits *only the included file* and waits for the session to change colour.
Diffstat (limited to '')
-rw-r--r--src/app.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/app.c b/src/app.c
index 48ec42d..9c33601 100644
--- a/src/app.c
+++ b/src/app.c
@@ -57,6 +57,15 @@ bool app_reload_config(char *err, size_t errcap) {
return true;
}
+/* Which files the config in force was read from. The server watches every one
+ * of them, so a theme that can be included is a theme that reloads when you
+ * save it — asked of the app rather than read from a config the front ends do
+ * not own. */
+size_t app_config_files(const char **out, size_t max) {
+ ensure_config();
+ return config_files(&CFG, out, max);
+}
+
#define WEIGHT_UNIT 1000
#define WEIGHT_MIN 150 /* a pane can be squeezed, not squeezed out */
#define WEIGHT_STEP 120 /* one keyboard nudge */