summaryrefslogtreecommitdiffstats
path: root/desktop/modules/status/statusctl
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/status/statusctl')
-rwxr-xr-xdesktop/modules/status/statusctl11
1 files changed, 9 insertions, 2 deletions
diff --git a/desktop/modules/status/statusctl b/desktop/modules/status/statusctl
index 839377e..87c2cac 100755
--- a/desktop/modules/status/statusctl
+++ b/desktop/modules/status/statusctl
@@ -59,7 +59,8 @@ read_mode() {
# Write through a temporary file and rename, so no reader ever sees a
# half-written value. This is also what FileView does on the QML side, and it
-# is why a watcher has to listen for moved_to as well as close_write.
+# is why a watcher has to listen for moved_to as well as close_write, and
+# create for FileView's first write (see watch below).
write_mode() {
local want="$1" tmp
tmp="$(mktemp "$DIR/.status.$mode.XXXXXX")" || exit 1
@@ -142,13 +143,19 @@ case "$action" in
# the file, so a watch held on the old inode dies with it. This is the
# same trap the mail watcher hit with Xapian.
#
+ # create is needed as well: Qt's atomic write builds the file as an
+ # unnamed O_TMPFILE, and when the target does not exist yet it links
+ # that straight into place. The only event naming the file is then
+ # IN_CREATE, so without it the first write of every session, the one
+ # that matters most, goes unseen until some later write.
+ #
# inotifywait must die with us. Piped straight into the while loop it
# would be a pipeline sibling, not a child, so a plain kill on this
# process (which is exactly how waybar stops and respawns its exec
# children on every reload) leaves it running, watching a directory
# nobody reads anymore. Process substitution makes it a real child
# whose PID we can hold and kill from a trap.
- exec 3< <(inotifywait -q -m -e close_write,moved_to,delete --format '%f' "$DIR" 2>/dev/null)
+ exec 3< <(inotifywait -q -m -e create,close_write,moved_to,delete --format '%f' "$DIR" 2>/dev/null)
watcher=$!
trap 'kill "$watcher" 2>/dev/null' EXIT TERM INT
# Presentation also follows status.gaming, so a game starting or