Skip to content

Reliable systemd autostart for awatcher-bundle on GNOME/Wayland (with fix for RecvError crashes) #1191

@schmunk42

Description

@schmunk42

This took me months to figure out, but I finally have a working solution for automatic ActivityWatch startup on GNOME with Wayland using systemd I want to share with you. Note: I had help from an AI.

The Problem

The commonly suggested approaches don't work reliably on GNOME/Wayland:

  1. XDG Autostart (.desktop files in ~/.config/autostart/) - Service starts too early, before GNOME's D-Bus services are ready
  2. Existing systemd solutions - Lack proper timing, causing crashes with ERROR aw_datastore::worker] DB worker quitting, error: RecvError

The root cause is that awatcher-bundle watchers need:

  • Mutter/IdleMonitor to be fully initialized
  • GNOME D-Bus services to be available
  • Proper display environment variables

When started too early at boot, the watchers fail to connect and the database worker crashes.

The Solution

Create ~/.config/systemd/user/activitywatch.service:

[Unit]
Description=ActivityWatch (awatcher-bundle) - Activity tracking service
Documentation=https://docs.activitywatch.net/
After=graphical-session.target
Wants=graphical-session.target

[Service]
Type=simple
ExecStartPre=/usr/bin/sleep 5
ExecStart=/usr/bin/awatcher-bundle -vv --no-tray
Restart=on-failure
RestartSec=10
KillMode=mixed
# Ensure the service has access to the display
Environment="DISPLAY=:0"
# For Wayland
Environment="WAYLAND_DISPLAY=wayland-0"
# XDG runtime directory
Environment="XDG_RUNTIME_DIR=/run/user/%U"

[Install]
WantedBy=default.target

Enable and start:

systemctl --user daemon-reload
systemctl --user enable activitywatch.service
systemctl --user start activitywatch.service

Key Differences from Other Solutions

Compared to existing solutions (like https://gist.github.com/guillermodotn/ec9ac40932b210d6216d17cc2d61c631):

  1. 5-second delay (ExecStartPre=/usr/bin/sleep 5) - This is crucial! It gives GNOME time to fully initialize D-Bus and Mutter/IdleMonitor before watchers try to connect. Without this, the service crashes on boot with RecvError.

  2. --no-tray flag - Runs server and watchers without the GUI tray icon. This avoids display initialization issues in systemd context and is more reliable for background operation. The web UI still works perfectly.

  3. KillMode=mixed - Ensures proper cleanup when stopping the service.

  4. Uses awatcher-bundle - Targets the modern Rust implementation instead of the older Python-based aw-qt.

Why This Matters

Without the 5-second delay, you get this error pattern on every boot:

[ERROR aw_datastore::worker] DB worker quitting, error: RecvError
systemd[3011]: activitywatch.service: Consumed 193ms CPU time

The service exits immediately and doesn't restart because it exits with status 0 (clean exit, not detected as failure).

Test Results

Tested successfully on:

  • OS: Arch Linux
  • Desktop: GNOME with Wayland
  • Version: awatcher-bundle v0.13.1 (rust)
  • systemd: 256.7

After reboot:

  • ✅ Server runs automatically on http://127.0.0.1:5600/
  • ✅ Idle watcher active (Gnome idle/Mutter/IdleMonitor)
  • ✅ Window watcher active (Gnome window extension)
  • ✅ Automatic restart on crashes
  • ✅ No manual intervention required

Relation to Existing Issues

This addresses concerns from:

While maintainers prefer .desktop autostart files, systemd provides more reliability with proper service management, logging, and automatic crash recovery - especially important for GNOME/Wayland environments.

Suggestion

Consider adding this to the documentation for GNOME/Wayland users, particularly those using awatcher-bundle. The timing issue is critical and not documented anywhere else.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions