How the Quickshell Desktop Is Launched and Restarted in Omarchy

Omarchy uses a dedicated wrapper script called omarchy-launch-shell to launch Quickshell as a supervised child process, handling automatic restarts, back-off limits, and signal-based shutdowns while logging all output to the systemd journal.

Managing a Wayland desktop shell requires careful process supervision to ensure the UI remains responsive even after crashes. In the Omarchy repository, the Quickshell desktop environment is not started directly via a systemd unit but through a custom Bash wrapper that manages the complete lifecycle from initial launch to graceful restart. This article examines the implementation details of how Omarchy initializes, monitors, and recovers the Quickshell process.

The omarchy-launch-shell Wrapper Architecture

The core of Omarchy's shell management resides in bin/omarchy-launch-shell, a Bash script that wraps the Quickshell binary to provide supervision capabilities unavailable when running the compositor directly. This wrapper handles environment preparation, process monitoring, and crash recovery without relying on external process managers.

Initial Launch Sequence

When starting the desktop, the wrapper invokes Quickshell with specific flags and environment overrides. According to the source code in bin/omarchy-launch-shell (lines 17-20), the script constructs a command that:

  • Sets QS_DISABLE_FILE_WATCHER=1 to disable Quickshell's built-in file watcher that would otherwise trigger reloads on configuration changes.
  • Sets QS_NO_RELOAD_POPUP=1 to suppress the "Reload?" confirmation dialog.
  • Uses the -n (no-restart) and -p (path-to-shell) flags pointing to $OMARCHY_PATH/shell.
  • Pipes all output through systemd-cat -t omarchy-shell to capture logs under the omarchy-shell journal tag.

This ensures the wrapper maintains exclusive control over the restart cycle rather than competing with Quickshell's native reloading mechanisms.

Running the Wrapper Manually

To start the Quickshell desktop manually from a terminal:


# Start the Omarchy shell (Quickshell will be launched under the hood)

$ omarchy-launch-shell

The command spawns Quickshell, redirects output to the journal, and enters the supervision loop.

Supervision and Automatic Restart Logic

Once started, the wrapper enters a supervision loop that determines whether to exit or relaunch based on the child's exit status and system state.

Exit Status Monitoring

The script distinguishes between clean shutdowns and crashes. If Quickshell exits with status 0, the wrapper terminates normally. Any non-zero exit triggers the restart sequence, subject to additional health checks defined in bin/omarchy-launch-shell (lines 35-45).

Compositor Health Validation

Before attempting any restart, the wrapper verifies that the Hyprland compositor is still alive. If the compositor has exited—indicating a full session teardown—the wrapper quits immediately rather than spawning orphaned shell processes. This guard prevents the shell from attempting to restart during logout or system shutdown.

Back-Off Protection and Rate Limiting

To prevent infinite restart loops, Omarchy implements a 5-attempt-per-minute budget. The script tracks a window_started timestamp; if fewer than 60 seconds have passed since the last successful start and the attempt count exceeds 5, the wrapper logs a warning and exits with status 1 (lines 79-87). The counter resets automatically after 60 seconds of continuous uptime.

Signal Handling for Graceful Restarts

The wrapper traps HUP, INT, and TERM signals to enable clean shutdowns when users or system utilities request a restart. Upon receiving a termination signal, the script sets a terminating flag and executes kill -TERM "$shell_pid" to stop the current Quickshell instance before the supervision loop starts a fresh one (lines 56-62).

To force a restart manually:


# Signal the wrapper to shut down the current shell and start a fresh one

$ kill -TERM "$(pidof omarchy-launch-shell)"

Because omarchy-launch-shell traps TERM, it will terminate the current Quickshell instance and immediately initiate a new launch sequence, subject to the 5-attempt-per-minute limit.

Logging and Observability

All launch events, crashes, and restart attempts are emitted to the systemd journal via systemd-cat, making the journal the single source of truth for shell health. Each line is tagged with omarchy-shell, allowing administrators to filter logs easily.

To inspect launch and crash history:


# Show the journal entries produced by the wrapper

$ journalctl -t omarchy-shell

You will see entries such as "Omarchy shell exited with status X; relaunching" and the final "Giving up ... after N relaunches" if the back-off limit is exceeded.

Testing the Launch Behavior

The Omarchy repository includes comprehensive tests for this supervision logic. The file test/shell.d/launch-shell-test.sh validates that the wrapper correctly relaunches after synthetic crashes and that the compositor-alive guard stops restarts when the session ends. A companion file, test/shell.d/restart-shell-test.sh, specifically verifies that signal handling triggers the expected restart workflow without violating rate limits.

Summary

  • Omarchy manages the Quickshell desktop through bin/omarchy-launch-shell rather than a direct systemd unit to enable custom supervision logic.
  • The wrapper disables Quickshell's internal file watcher via QS_DISABLE_FILE_WATCHER=1 and suppresses reload popups via QS_NO_RELOAD_POPUP=1 to maintain exclusive control over restarts.
  • Automatic restarts are limited to 5 attempts per minute to prevent resource exhaustion from rapid crash loops.
  • Before each restart, the wrapper verifies that Hyprland is running to avoid orphaned processes during session shutdown.
  • All output is captured via systemd-cat -t omarchy-shell, enabling centralized log inspection through journalctl.
  • Signal traps for HUP, INT, and TERM ensure clean shutdowns when manual restarts are requested.

Frequently Asked Questions

Why doesn't Omarchy use a systemd user unit to manage Quickshell?

Omarchy uses a wrapper script rather than a native systemd unit to implement custom back-off logic and compositor health checks that would be difficult to express in systemd unit directives alone. The omarchy-launch-shell script evaluates whether Hyprland is still alive before deciding to restart, preventing unnecessary process spawning during session teardown.

How can I manually restart the Quickshell desktop without logging out?

Send a TERM signal to the wrapper process using kill -TERM "$(pidof omarchy-launch-shell)". The script traps this signal, terminates the current Quickshell instance via kill -TERM "$shell_pid", and immediately initiates a fresh launch sequence subject to the standard 5-attempt-per-minute limit.

What happens if Quickshell crashes repeatedly?

If Quickshell exits non-zero more than 5 times within a 60-second window, the wrapper logs a warning message to the journal and exits with status 1. This prevents infinite crash loops and allows the system to fall back to a minimal state or display manager rather than consuming CPU with continuous restart attempts.

Where are the Quickshell logs stored when launched through Omarchy?

All stdout and stderr output is redirected through systemd-cat -t omarchy-shell, which writes to the systemd journal. Query these logs using journalctl -t omarchy-shell to view timestamped launch events, crash reports with exit codes, and restart notifications.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →