ActivityWatch (awatcher-bundle) doesn't start automatically after login on GNOME with Wayland. The desktop app shows "localhost refused the connection."
The XDG autostart method (.desktop files in ~/.config/autostart/) has timing issues:
- Watchers try to connect before GNOME is fully initialized
- D-Bus and Mutter/IdleMonitor are not yet available
- Database worker crashes with
RecvError
Create the file ~/.config/systemd/user/activitywatch.service:
[Unit]
Description=ActivityWatch (awatcher-bundle) - Activity tracking service
Documentation=https://docs.activitywatch.net/
After=graphical-session.target org.gnome.Shell.target
Wants=graphical-session.target
[Service]
Type=simple
ExecStartPre=/home/schmunk/.local/bin/prepare-activitywatch.sh
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.targetCreate the script ~/.local/bin/prepare-activitywatch.sh:
#!/bin/bash
# Prepare ActivityWatch: Wait for required dependencies
# - GNOME Shell Extension (focused-window-dbus)
# - ActivityWatch server (port 5600)
set -e
TIMEOUT=30
# Wait for D-Bus interface
wait_for_dbus() {
local interface="org.gnome.shell.extensions.FocusedWindow"
local path="/org/gnome/shell/extensions/FocusedWindow"
local elapsed=0
echo "Waiting for GNOME Extension D-Bus interface..."
while [ $elapsed -lt $TIMEOUT ]; do
if busctl --user introspect org.gnome.Shell "$path" 2>/dev/null | grep -q "$interface"; then
echo "✓ GNOME Extension available after ${elapsed}s"
return 0
fi
sleep 1
elapsed=$((elapsed + 1))
done
echo "ERROR: GNOME Extension not available after ${TIMEOUT}s" >&2
return 1
}
# Wait for ActivityWatch server
wait_for_server() {
local port=5600
local elapsed=0
echo "Waiting for ActivityWatch server on port $port..."
while [ $elapsed -lt $TIMEOUT ]; do
if curl -s "http://127.0.0.1:$port" >/dev/null 2>&1; then
echo "✓ ActivityWatch server available after ${elapsed}s"
return 0
fi
sleep 1
elapsed=$((elapsed + 1))
done
echo "WARNING: ActivityWatch server not available after ${TIMEOUT}s (will retry on start)" >&2
return 0 # Not critical, awatcher-bundle will retry
}
# Execute checks
wait_for_dbus || exit 1
wait_for_server
echo "✓ All dependencies ready"
exit 0Make the script executable:
chmod +x ~/.local/bin/prepare-activitywatch.sh# Reload systemd
systemctl --user daemon-reload
# Enable service for autostart
systemctl --user enable activitywatch.service
# Start service immediately
systemctl --user start activitywatch.service# If present, delete old XDG autostart entry
rm ~/.config/autostart/awatcher.desktop# Check service status
systemctl --user status activitywatch.service
# Test server connection
curl http://localhost:5600/api/0/info- Starts server and watchers without GUI tray icon
- Prevents issues with display access in systemd services
- Web app still works normally
- Intelligently waits for GNOME Shell Extension (focused-window-dbus) via D-Bus
- Checks availability of D-Bus interface
org.gnome.shell.extensions.FocusedWindow - Optionally waits for ActivityWatch server (port 5600)
- 30-second timeout for robust error handling
- Prevents the
RecvErrorcrash at startup by ensuring all dependencies are available
DISPLAY=:0- X11 DisplayWAYLAND_DISPLAY=wayland-0- Wayland Display SocketXDG_RUNTIME_DIR=/run/user/%U- User Runtime Directory
After=graphical-session.target org.gnome.Shell.target- Starts after graphical session AND GNOME ShellWants=graphical-session.target- Dependency without hard failureWantedBy=default.target- Started automatically at login
- Requires
focused-window-dbusextension for window tracking on Wayland - Prepare script explicitly waits for extension's D-Bus interface
- Without the extension, window watcher would not function
# Show service status
systemctl --user status activitywatch.service
# Restart service
systemctl --user restart activitywatch.service
# Stop service
systemctl --user stop activitywatch.service
# Disable service (no autostart)
systemctl --user disable activitywatch.service
# Show logs (live)
journalctl --user -u activitywatch.service -f
# Show logs from current boot
journalctl --user -u activitywatch.service -b 0After a reboot:
- ✓ ActivityWatch server runs automatically on http://127.0.0.1:5600
- ✓ Idle watcher active (Gnome idle/Mutter/IdleMonitor)
- ✓ Window watcher active (Gnome window extension)
- ✓ Chromium Web-Desktop App can connect
- ✓ Automatic restart on crashes
- Arch Linux
- GNOME with Wayland
- awatcher-bundle v0.13.1 (rust)
- systemd 256.7
Created: 2025-11-11