A lightweight Linux daemon that automatically boots the graphical interface (desktop/display manager) when a monitor or TV is plugged in / turned on, and stops it (isolates to headless CLI multi-user.target) when disconnected or powered off.
Conserves CPU, GPU, and RAM on home servers, media rigs, and hybrid workstations by remaining in headless mode until a physical display is actively detected.
flowchart TD
A["⚡ Monitor / TV Event"] --> B{"Hardware Check"}
B -->|"AMD / Intel / KMS"| C["libdrm.so.2 IOCTL & Sysfs"]
B -->|"NVIDIA"| D["nvidia-smi & Display Query"]
C --> E{"Physical Display Attached?"}
D --> E
E -->|"Yes (Connected)"| F["🚀 Switch to graphical.target\n(Boot Desktop Environment)"]
E -->|"No (Disconnected)"| G["💤 Isolate to multi-user.target\n(Conserve Resources in Headless CLI)"]
- Universal GPU & Driver Support:
- AMD & Intel & generic KMS: Direct hardware DDC/I2C probing via
libdrm.so.2ioctls and/sys/class/drm/sysfs fallback. - NVIDIA Proprietary Drivers: Hotplug detection via
nvidia-smiand active display querying. - Virtual / Passthrough GPUs: Works seamlessly with virtio-gpu and Nouveau.
- AMD & Intel & generic KMS: Direct hardware DDC/I2C probing via
- Display Manager Agnostic: Auto-detects and coordinates with
graphical.target,gdm,lightdm,sddm,ly,greetd, or custom start/stop commands. - Hardware DDC Probing: Detects displays even when HDMI/DisplayPort audio or power cycles fail to generate passive kernel interrupt events.
- Kernel Uevent + Async Polling: Listens to
NETLINK_KOBJECT_UEVENTkernel broadcast sockets for instant event reaction with zero CPU spin. - Configurable Debounce: Eliminates flapping when monitors cycle through power-save modes or switch inputs.
- Zero Third-Party Pip Dependencies: Pure Python 3 standard library with
ctypes.
Run with --dry-run to test hardware detection without modifying system targets:
python3 auto_gui_manager.py --dry-run --verbosesudo python3 auto_gui_manager.pyoptions:
-h, --help show this help message and exit
--debounce DEBOUNCE Debounce period in seconds before switching state (default: 2.5)
--poll-interval SEC Polling interval in seconds (default: 2.0)
--display-manager DM Specific DM service (e.g., gdm, lightdm, sddm, graphical.target)
--start-cmd CMD Custom shell command to execute when starting GUI
--stop-cmd CMD Custom shell command to execute when stopping GUI
--dry-run Log state transitions without modifying system targets
--verbose, -v Enable verbose debug logging
--version Show program's version number and exit
-
Copy the script to
/usr/local/bin:sudo cp auto_gui_manager.py /usr/local/bin/auto_gui_manager.py sudo chmod +x /usr/local/bin/auto_gui_manager.py
-
Copy and enable the systemd service:
sudo cp auto-gui-manager.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable --now auto-gui-manager.service -
View live hotplug logs:
journalctl -u auto-gui-manager.service -f
You can configure the service via environment variables in /etc/systemd/system/auto-gui-manager.service:
AUTO_GUI_DM: Force a specific display manager (gdm,lightdm,sddm,graphical.target).AUTO_GUI_DEBOUNCE: Debounce delay in seconds (default2.5).AUTO_GUI_POLL_INTERVAL: Polling interval in seconds (default2.0).AUTO_GUI_START_CMD: Custom start command.AUTO_GUI_STOP_CMD: Custom stop command.
MIT License. Open source and free for personal and commercial use.