mirror of
https://github.com/Screenly/Anthias.git
synced 2026-08-02 18:57:32 -04:00
* fix(viewer): re-assert linuxfb display mode after HDMI hotplug On the 32-bit Pi 1-3 (linuxfb/Qt5) viewer, a TV on a power schedule that switches itself off and on can leave the display stuck at 1024x768 instead of its native resolution (issue #3052). Root cause is kernel-side, not anything Anthias writes: under dtoverlay=vc4-kms-v3d the linuxfb boards never take DRM master, so the kernel's drm_fb_helper owns the display mode. When the HDMI sink wakes, the connector re-probe can win the race against the sink's EDID/DDC coming back; the connector momentarily reports no valid modes and drm_fb_helper latches its hard-coded 1024x768 default. Qt's linuxfb plugin reads the framebuffer geometry once at startup and can't follow the change, so the picture stays stuck until the Pi is power-cycled. eglfs boards (pi4 / pi5 / pi3-64 / arm64) are immune: Qt holds DRM master and keeps its own modeset committed across the hotplug. Verified on a Pi 3-64 testbed that a real ~10 s HDMI unplug never left 1920x1080. Fix: a linuxfb-only watchdog in start_viewer.sh watches the HDMI connector for a disconnect->reconnect and, once EDID is readable again, re-asserts the connector's *preferred* mode (read live from the connector, never hard-coded, so any panel resolution is honoured) onto the framebuffer via the fbdev sysfs `mode` attribute, then restarts the viewer so Qt re-initialises against the restored mode. All access is under /sys in the already-privileged viewer container; no DRM master is taken, so it never conflicts with Qt's fbdev use. The QT_QPA_PLATFORM guard makes it a no-op on eglfs/wayland boards. Validated on a real Pi 3: forcing the connector through a disconnect -> 1024x768 -> reconnect cycle, the watchdog re-asserted 1920x1080 and restarted the viewer. (The 1024x768 latch was simulated with fbset because the testbed monitor presents EDID instantly and can't reproduce the real no-EDID race; detection and recovery are identical regardless of how the mode was latched.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): restart to recover /dev/fb0 hotplugged after headless boot - exit wait_for_framebuffer when the host has fb0 but the container's stale /dev doesn't, so `restart: always` re-snapshots /dev - keep waiting quietly when genuinely headless (no sysfs fb0) to avoid the #2959 crash-loop - fixes the "self-heals on hotplug" case that a running container's devtmpfs snapshot silently broke Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): harden HDMI-hotplug resolution recovery (review follow-ups) - preserve interlaced scan type instead of forcing a progressive mode string (interlaced-native sinks were never matched) - log rejected /sys .../fb0/mode writes instead of returning silently, so a screen stuck at 1024x768 is diagnosable - watch every HDMI connector, seeded from current status, instead of binding one at startup (second micro-HDMI port / late connect) - normalize `pidof python` to a single PID so a multi-PID result can't disable the watchdog (also fixes the pre-existing kill -0 loop) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(viewer): address second-pass review nits on HDMI-hotplug recovery - wait_for_framebuffer: sleep+re-check before the stale-devtmpfs exit so a /dev/fb0 node that lags its sysfs entry on a fresh start can't cause restart churn - monitor: default an unseeded connector to 'connected' so an unreadable-status seed race can't look like a reconnect edge and spuriously restart a display that never dropped - PID: select the oldest pidof result (the viewer, launched before any gst_fbdev_player.py helper) instead of the newest Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>