Order the migration notifier after graphical-session.target
omarchy-migrate-notify.service is a Type=oneshot wanted by graphical-session.target, and systemd complements a target's Wants= with an implicit After=, so the target waited for the notifier to exit. The notifier does not exit quickly: it sends the notification through systemd-run --scope, which is synchronous, and omarchy-notification-send -a blocks until the user clicks. The target stayed in activating for as long as the toast was up. wayland-wm-app-daemon.service is After=graphical-session.target and nothing wants it, so uwsm-app starts it on demand. Clicking the notification runs omarchy-launch-floating-terminal-with-presentation, which execs uwsm-app, which blocks on a systemctl --user restart of that daemon -- a job queued behind the very target the clicked notifier was holding open. The terminal never opened; uwsm-app gave up on its own pipe timeout instead. Declaring After= on the wanted unit suppresses the implicit dependency rather than forming a cycle, so the target is reached without waiting and the notifier runs behind it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2fb33a2a6a
commit
c7e327b05a
@@ -15,8 +15,8 @@ fi
|
|||||||
|
|
||||||
notify_command=$(printf 'if [[ -n $(omarchy-notification-send -u critical -g "Pending Omarchy Migrations" %q -a) ]]; then omarchy-launch-floating-terminal-with-presentation omarchy-migrate; fi' "$message")
|
notify_command=$(printf 'if [[ -n $(omarchy-notification-send -u critical -g "Pending Omarchy Migrations" %q -a) ]]; then omarchy-launch-floating-terminal-with-presentation omarchy-migrate; fi' "$message")
|
||||||
|
|
||||||
# This runs from omarchy-migrate-notify.service at graphical-session.target,
|
# This runs from omarchy-migrate-notify.service after graphical-session.target,
|
||||||
# which the session can reach before the shell has claimed
|
# but the target can be reached before the shell has claimed
|
||||||
# org.freedesktop.Notifications. Without the wait the toast is sent into the
|
# org.freedesktop.Notifications. Without the wait the toast is sent into the
|
||||||
# void and the user never learns about their pending migrations.
|
# void and the user never learns about their pending migrations.
|
||||||
omarchy-notification-wait || true
|
omarchy-notification-wait || true
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ Description=Notify about pending Omarchy migrations
|
|||||||
# already being applied in the visible update terminal. Checking once per login
|
# already being applied in the visible update terminal. Checking once per login
|
||||||
# is the only trigger that cannot collide with a running update.
|
# is the only trigger that cannot collide with a running update.
|
||||||
ConditionPathIsDirectory=/usr/share/omarchy/migrations
|
ConditionPathIsDirectory=/usr/share/omarchy/migrations
|
||||||
|
# The actionable notification launches its terminal through uwsm-app, whose
|
||||||
|
# daemon starts after graphical-session.target. Run after the target too so this
|
||||||
|
# oneshot cannot hold the target open while waiting for that daemon.
|
||||||
|
After=graphical-session.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
|
|||||||
+2
-1
@@ -198,7 +198,8 @@ appropriate helper or privilege prompt. Migrations must be idempotent;
|
|||||||
machine-wide repairs should no-op when another user already applied them.
|
machine-wide repairs should no-op when another user already applied them.
|
||||||
|
|
||||||
Each graphical user has `omarchy-migrate-notify.service`, started once per login
|
Each graphical user has `omarchy-migrate-notify.service`, started once per login
|
||||||
through `WantedBy=graphical-session.target`. The package also ships
|
through `WantedBy=graphical-session.target` and ordered after that target so
|
||||||
|
notification actions can safely launch through UWSM. The package also ships
|
||||||
`omarchy-update-user-notify.service` as a symlink onto it, so users enabled
|
`omarchy-update-user-notify.service` as a symlink onto it, so users enabled
|
||||||
under the old unit name keep working before they reach migration `1785095882`.
|
under the old unit name keep working before they reach migration `1785095882`.
|
||||||
It runs `omarchy-migrate-notify` as
|
It runs `omarchy-migrate-notify` as
|
||||||
|
|||||||
+2
-1
@@ -45,7 +45,8 @@ all pending migrations for the current user in the visible update terminal.
|
|||||||
|
|
||||||
### At login
|
### At login
|
||||||
|
|
||||||
Every graphical login starts `omarchy-migrate-notify.service`, which checks:
|
Every graphical login starts `omarchy-migrate-notify.service` after
|
||||||
|
`graphical-session.target`. The notifier checks:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
omarchy-migrate --pending
|
omarchy-migrate --pending
|
||||||
|
|||||||
@@ -150,7 +150,8 @@ sudo pacman -Syu
|
|||||||
├─ pre-transaction guard aborts and tells the user to run omarchy update
|
├─ pre-transaction guard aborts and tells the user to run omarchy update
|
||||||
└─ if explicitly bypassed, upgrades omarchy and related packages
|
└─ if explicitly bypassed, upgrades omarchy and related packages
|
||||||
└─ at that user's next login
|
└─ at that user's next login
|
||||||
├─ omarchy-migrate-notify.service starts with graphical-session.target
|
├─ graphical-session.target starts
|
||||||
|
├─ omarchy-migrate-notify.service starts after it
|
||||||
├─ omarchy-migrate-notify checks omarchy-migrate --pending
|
├─ omarchy-migrate-notify checks omarchy-migrate --pending
|
||||||
├─ if this user has missing migration state, show notification
|
├─ if this user has missing migration state, show notification
|
||||||
└─ click opens terminal: omarchy-migrate
|
└─ click opens terminal: omarchy-migrate
|
||||||
@@ -173,6 +174,9 @@ Fallbacks:
|
|||||||
migration that repoints it only runs for users who run an update — the
|
migration that repoints it only runs for users who run an update — the
|
||||||
opposite of who the notifier is for. The alias can be dropped once installs
|
opposite of who the notifier is for. The alias can be dropped once installs
|
||||||
have run migration `1785095882`.
|
have run migration `1785095882`.
|
||||||
|
- The notifier is ordered after `graphical-session.target`, so an action that
|
||||||
|
launches through `uwsm-app` cannot block the target that gates UWSM's app
|
||||||
|
daemon.
|
||||||
- The notifier waits for a live notification server before sending, because
|
- The notifier waits for a live notification server before sending, because
|
||||||
`graphical-session.target` can be reached before the shell claims
|
`graphical-session.target` can be reached before the shell claims
|
||||||
`org.freedesktop.Notifications`.
|
`org.freedesktop.Notifications`.
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ pass "no unit watches the migration directory, so package updates cannot trigger
|
|||||||
notify_service="$ROOT/default/systemd/user/omarchy-migrate-notify.service"
|
notify_service="$ROOT/default/systemd/user/omarchy-migrate-notify.service"
|
||||||
grep -Fx 'ExecStart=/usr/bin/omarchy-migrate-notify' "$notify_service" >/dev/null
|
grep -Fx 'ExecStart=/usr/bin/omarchy-migrate-notify' "$notify_service" >/dev/null
|
||||||
grep -Fx 'WantedBy=graphical-session.target' "$notify_service" >/dev/null
|
grep -Fx 'WantedBy=graphical-session.target' "$notify_service" >/dev/null
|
||||||
pass "migration notifier only checks once per login"
|
grep -Fx 'After=graphical-session.target' "$notify_service" >/dev/null ||
|
||||||
|
fail "migration notifier can deadlock UWSM by blocking graphical-session.target"
|
||||||
|
pass "migration notifier checks once per login after the graphical session is ready"
|
||||||
|
|
||||||
grep -F 'omarchy-migrate-notify.service' "$first_run_units" >/dev/null ||
|
grep -F 'omarchy-migrate-notify.service' "$first_run_units" >/dev/null ||
|
||||||
fail "first-run does not enable the login migration notifier"
|
fail "first-run does not enable the login migration notifier"
|
||||||
|
|||||||
Reference in New Issue
Block a user