Files
community-plugins/sharednd/README.md
T
wioletowaandClaude Fable 5 5e9027da1a fix(sharednd): address review — stop/start race, onExit cleanup, no busy loop off niri
- Debounce stop transitions by 1 s (host update tick): a stop/start pair
  from switching casts collapses into no transition, so the async
  `dnd-set off` can no longer race the `dnd-status` query and drop
  ownership mid-share. Also stops DND flapping.
- Add onExit: if the plugin owns DND when disabled/reloaded, turn it off
  via a detached runAsync (survives VM teardown).
- Gate detection on NIRI_SOCKET + commandExists("niri") instead of an
  unconditional retry loop: on other compositors (or niri installed but
  not running) the service now spawns nothing. If NIRI_SOCKET is set but
  the binary is missing from PATH, warn once.
- Make the stream retry loop self-terminating (parent gone or niri
  socket removed): hard host exits skip process-group cleanup and were
  leaking orphaned loops that respawned `niri msg` every 3 s across
  sessions (observed 11 such orphans over 4 days).
- Bump version to 1.1.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 18:30:29 +03:00

2.0 KiB

ShareDND

Automatic Do Not Disturb while the screen is being shared.

When the first screencast starts (any app sharing via the portal — Discord, OBS, browsers, niri msg action set-dynamic-cast-*, ...), notification DND is enabled. When the last screencast stops, notifications come back.

How it works

  • A headless service follows niri msg -j event-stream and reacts to CastsChanged / CastStartedOrChanged / CastStopped events — no polling.
  • On every cast event it re-queries niri msg -j casts as the authoritative state, so missed or reordered events cannot desync it. The stream is wrapped in a shell retry loop and resends full state on reconnect.
  • Stop transitions are debounced by ~1 second: switching what is being shared produces a stop/start event pair, which the debounce collapses — DND does not flap, and the stop/start race cannot drop ownership.
  • DND is toggled through the host IPC (noctalia msg notification-dnd-set), so the usual OSD feedback appears.

Ownership rules

  • If DND was already on before sharing started, the plugin leaves it on after sharing ends (it never took ownership). The "Always disable DND after sharing" setting overrides this.
  • If DND was enabled manually during sharing while the plugin owned it, it will still be turned off when sharing ends (the plugin cannot tell the difference).

Settings

  • Only active streams — count only casts with is_active: true. Off by default: any open screencast session (even paused or showing nothing) keeps DND on.
  • Always disable DND after sharing — force DND off when sharing ends, regardless of its state before sharing started.

Requirements & limitations

  • Requires niri (detection is niri IPC). Detection only starts inside a niri session (NIRI_SOCKET set and the niri binary in PATH); on other compositors the service is inert and spawns no processes.
  • Disabling or reloading the plugin mid-share while it owns DND turns DND back off (onExit cleanup).