Files

4.6 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

The operator confirmed successful physical HDMI input switching and recovery with version 0.2.1 on 2026-09-23. The tested setup and the scope of that result are recorded in hardware validation.

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.

For a first normal input-switch test with the default timing, stay on the other input for about 40 seconds before returning. This allows the initial attempt and its 30-second cooldown to finish. Then test rapid switching separately; returns inside the cooldown can still be suppressed.