4.1 KiB
Troubleshooting
Status and logs
systemctl --user status revive-monitor-drm-watch.service
journalctl --user -u revive-monitor-drm-watch.service -b -f
Both scripts write to stderr; systemd captures their messages in the unit journal. Direct manual runs write to the terminal. There is no separate logger/syslog tag.
Missing Hyprland instance / IPC failure
From a Hyprland terminal, run ./scripts/install.sh --start and add the startup
hook from README so each new login updates HYPRLAND_INSTANCE_SIGNATURE.
hyprctl monitors must list the output configured in config.env. A stale
signature, failed IPC call or absent output aborts recovery without switching VTs.
No recovery after switching inputs
Observe events without starting another watcher:
udevadm monitor --kernel --property --subsystem-match=drm
Look for HOTPLUG=1. Then inspect the session:
loginctl list-sessions
loginctl show-session SESSION_ID -p User -p Type -p Active -p Seat -p VTNr -p Desktop
Expected: your numeric UID, Type=wayland, Active=yes, Seat=seat0, a VT from
1 to 63, and either a Hyprland desktop or an empty Desktop property. The helper
also checks these properties when invoked manually.
Hyprland refresh failed / Lua syntax error
Version 0.2.0 sent legacy dispatch commands even to Lua-configured sessions.
On Hyprland 0.56.2 this produced ')' expected near 'on' and aborted recovery
before the VT switch. Update to 0.2.1 with ./scripts/install.sh --start.
The helper now reads hyprctl -j status to choose the active config provider.
For Lua it sends hl.dsp.dpms({ action = "on", monitor = "HDMI-A-2" }) and
hl.dsp.focus({ monitor = "HDMI-A-2" }) through hyprctl dispatch. The configured
output replaces HDMI-A-2. Legacy hyprlang and older versions remain supported.
See the official hyprctl documentation
and dispatchers.
The journal identifies DPMS or focus, the command's exit status and its error
response. A zero exit status with an error response is also treated as failure.
Invalid runtime directory
XDG_RUNTIME_DIR must be your login-managed, user-owned directory with mode 0700
(normally /run/user/UID). Do not set it to /tmp or run the service with sudo.
The systemd unit sets it from %t.
sudo / VT return failures
Use visudo to verify the explicit VT permissions. Check authorization without
switching the display (replace the VTs to match your session):
sudo -n -l /usr/bin/chvt 2
sudo -n -l /usr/bin/chvt 1
A denied return permission aborts before the outward switch. Actual chvt errors are still possible; a return failure is retried once and logged. A failed emergency return requires manually returning to the graphical VT, e.g. Ctrl+Alt+F1 for VT1.
Debounce hides a rapid return / repeated recoveries
DEBOUNCE_SECONDS is a cooldown after each attempt, not an event queue. A genuine
rapid return can be ignored along with duplicate and self-generated events.
Reduce the interval if needed; increasing it can help noisy hardware. Setting it
to zero disables cooldown and can cause a recovery loop on some GPUs.
Manual recovery
From a terminal inside the active Hyprland session, pass its actual VT number:
~/.local/bin/revive-monitor-fix 1
This will visibly switch VTs. If the monitor needs more handshake time, increase
HDMI_SETTLE_SECONDS (default 5). Manual recovery still needs valid IPC, the
configured output, a private runtime directory and sudo permission.
Updating / uninstalling
Updates preserve config.env. Run ./scripts/install.sh --start inside Hyprland
to restart with the new scripts. Plain install.sh leaves the service stopped.
For uninstall, the systemd user manager must be reachable. Remove the startup
hook manually as documented in README.
Hardware acceptance
After installation, check a normal input change, a rapid away/back change and a logout/login cycle. Before Hyprland login there must be no chvt invocation from this service. Automated tests use mocks and do not replace this hardware check.