Skip to content

Commit 8eb6439

Browse files
committed
chore: refactor systemd and startup patterning for smoother boot
1 parent d956354 commit 8eb6439

File tree

4 files changed

+86
-11
lines changed

4 files changed

+86
-11
lines changed

config/systemd/hyprwhspr.service

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
[Unit]
22
Description=hyprwhspr stt
33
Documentation=https://github.com/goodroot/hyprwhspr
4-
After=graphical-session.target pipewire.service ydotool.service
5-
StartLimitIntervalSec=300
6-
StartLimitBurst=5
7-
Requires=ydotool.service
4+
5+
PartOf=graphical-session.target
6+
After=graphical-session.target
7+
8+
After=pipewire.service ydotool.service
89
Wants=pipewire.service
10+
Requires=ydotool.service
11+
12+
Wants=wireplumber.service
13+
After=wireplumber.service
914

1015
[Service]
1116
Type=simple
12-
# Wait for Wayland compositor - check for socket file directly since systemd
13-
# services don't inherit WAYLAND_DISPLAY from the graphical session
14-
ExecStartPre=/bin/bash -c 'for i in $(seq 1 30); do ls /run/user/$(id -u)/wayland-* >/dev/null 2>&1 && exit 0; sleep 0.5; done; echo "Warning: Wayland socket not found after 15s"'
17+
ExecStartPre=/bin/bash -lc 'for i in $(seq 1 60); do ls "$XDG_RUNTIME_DIR"/wayland-* >/dev/null 2>&1 && exit 0; sleep 0.25; done; echo "Wayland socket not found"; exit 1'
1518
ExecStart=/usr/lib/hyprwhspr/bin/hyprwhspr
16-
# Ensure virtual keyboard is killed even on crash/SIGKILL to release device grabs
1719
ExecStopPost=/bin/bash -c 'pkill -9 -f "hyprwhspr-virtual-keyboard" 2>/dev/null || true'
1820
Environment=HYPRWHSPR_ROOT=/usr/lib/hyprwhspr
1921
Environment=PYTHONUNBUFFERED=1
2022
Restart=on-failure
21-
# Give kernel time to release device grabs after stop
2223
RestartSec=2
2324
StandardOutput=journal
2425
StandardError=journal
2526

2627
[Install]
27-
WantedBy=default.target
28+
WantedBy=graphical-session.target

config/systemd/meeting-recorder.service

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
[Unit]
22
Description=meeting-recorder (hyprwhspr)
33
Documentation=https://github.com/goodroot/hyprwhspr
4+
5+
PartOf=graphical-session.target
6+
After=graphical-session.target
7+
48
After=pipewire.service
59
Wants=pipewire.service
610

@@ -14,4 +18,4 @@ StandardOutput=journal
1418
StandardError=journal
1519

1620
[Install]
17-
WantedBy=default.target
21+
WantedBy=graphical-session.target

docs/CONFIGURATION.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,45 @@ journalctl --user -u ydotool.service -f
743743

744744
If you are using the hyprland input method, do you have shortcuts?
745745

746+
#### Service starts but doesn't work until restarted
747+
748+
`hyprwhspr` must start within an active graphical session.
749+
750+
If the service appears active but hotkeys/transcription don't work until you manually restart, your session environment may not be set up correctly.
751+
752+
Check your session:
753+
754+
```bash
755+
# Verify graphical-session.target is active
756+
systemctl --user is-active graphical-session.target
757+
758+
# Verify Wayland env is available to systemd services
759+
systemctl --user show-environment | grep WAYLAND_DISPLAY
760+
```
761+
762+
If `WAYLAND_DISPLAY` is missing, add to `~/.config/hypr/hyprland.conf`:
763+
764+
```bash
765+
# Export session environment to systemd user services
766+
exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE
767+
```
768+
769+
**Hyprland:**
770+
771+
If `graphical-session.target` is inactive, you likely need a session manager to activate it. The recommended approach is to launch Hyprland via [uwsm](https://github.com/Vladimir-csp/uwsm) (it activates `graphical-session.target` and exports the session environment to systemd).
772+
773+
If you *aren't* using a session manager and your system allows it, you can try starting it manually:
774+
775+
```bash
776+
exec-once = systemctl --user start graphical-session.target
777+
```
778+
779+
> **Note:** Some distros set `graphical-session.target` with `RefuseManualStart=yes`, in which case the manual start will fail and you should use a session manager like `uwsm` instead.
780+
781+
Then restart Hyprland or log out and back in.
782+
783+
Run `hyprwhspr validate` to confirm the session is configured correctly.
784+
746785
#### Permission denied
747786

748787
```bash

lib/src/cli_commands.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3615,6 +3615,37 @@ def validate_command():
36153615
except Exception:
36163616
pass # Config validation is optional, don't fail if it errors
36173617

3618+
# Check graphical session readiness
3619+
try:
3620+
result = subprocess.run(
3621+
['systemctl', '--user', 'is-active', 'graphical-session.target'],
3622+
capture_output=True, text=True, timeout=5, check=False
3623+
)
3624+
if result.stdout.strip() == 'active':
3625+
log_success("✓ graphical-session.target is active")
3626+
else:
3627+
log_warning("⚠ graphical-session.target is not active")
3628+
print(" hyprwhspr starts with the graphical session.")
3629+
print(" A session manager like uwsm is needed to activate graphical-session.target.")
3630+
print(" See: https://github.com/Vladimir-csp/uwsm")
3631+
except Exception:
3632+
pass
3633+
3634+
# Check WAYLAND_DISPLAY in systemd user environment
3635+
try:
3636+
result = subprocess.run(
3637+
['systemctl', '--user', 'show-environment'],
3638+
capture_output=True, text=True, timeout=5, check=False
3639+
)
3640+
if result.returncode == 0 and 'WAYLAND_DISPLAY=' in result.stdout:
3641+
log_success("✓ WAYLAND_DISPLAY set in systemd user environment")
3642+
else:
3643+
log_warning("⚠ WAYLAND_DISPLAY not found in systemd user environment")
3644+
print(" Add to ~/.config/hypr/hyprland.conf:")
3645+
print(" exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE")
3646+
except Exception:
3647+
pass
3648+
36183649
if all_ok:
36193650
log_success("Validation passed")
36203651
else:

0 commit comments

Comments
 (0)