Add Wayland display server support for power management
Added support for both X11 and Wayland environments: Display Server Detection: - Auto-detects Wayland via WAYLAND_DISPLAY environment variable - Falls back to X11 commands if not Wayland - Works seamlessly on both display servers Wayland-specific tools: - wlopm - Wayland output power management (keeps display on) - wlr-randr - Output management for wlroots compositors - ydotool - Mouse movement for Wayland (alternative to xdotool) - systemd-inhibit integration for idle prevention Enhanced display keep-alive script: - Detects display server type on startup - Uses appropriate commands based on environment - Wayland: wlopm, wlr-randr, ydotool - X11: xset, xdotool, xrandr - Both: tvservice for HDMI power control App-level improvements (main.py): - Detects Wayland via os.environ check - Executes Wayland-specific commands when detected - Maintains X11 compatibility for older systems Installation improvements: - Auto-installs Wayland tools if Wayland is detected - Attempts to install: wlopm, wlr-randr, ydotool - Graceful fallback if packages unavailable This ensures HDMI power management works correctly on: - Raspberry Pi OS with X11 (older versions) - Raspberry Pi OS with Wayland (Bookworm and newer) - Any Linux system using either display server
This commit is contained in:
33
.display-keepalive.sh
Executable file
33
.display-keepalive.sh
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Aggressive display keep-alive for Raspberry Pi
|
||||||
|
# Prevents HDMI from powering down
|
||||||
|
|
||||||
|
DISPLAY_TIMEOUT=30
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
# Keep HDMI powered on (tvservice command)
|
||||||
|
if command -v tvservice &> /dev/null; then
|
||||||
|
/usr/bin/tvservice -p 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disable screensaver
|
||||||
|
if command -v xset &> /dev/null; then
|
||||||
|
DISPLAY=:0 xset s off 2>/dev/null
|
||||||
|
DISPLAY=:0 xset -dpms 2>/dev/null
|
||||||
|
DISPLAY=:0 xset dpms force on 2>/dev/null
|
||||||
|
DISPLAY=:0 xset s reset 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move mouse to trigger activity
|
||||||
|
if command -v xdotool &> /dev/null; then
|
||||||
|
DISPLAY=:0 xdotool mousemove_relative 1 1 2>/dev/null
|
||||||
|
DISPLAY=:0 xdotool mousemove_relative -1 -1 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disable monitor power saving
|
||||||
|
if command -v xrandr &> /dev/null; then
|
||||||
|
DISPLAY=:0 xrandr --output HDMI-1 --power-profile performance 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep $DISPLAY_TIMEOUT
|
||||||
|
done
|
||||||
@@ -1 +1 @@
|
|||||||
1768672780.5973904
|
1768673747.1927276
|
||||||
113
install.sh
113
install.sh
@@ -349,33 +349,79 @@ EOF
|
|||||||
cat > "$DISPLAY_KEEPALIVE" << 'EOF'
|
cat > "$DISPLAY_KEEPALIVE" << 'EOF'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Aggressive display keep-alive for Raspberry Pi
|
# Aggressive display keep-alive for Raspberry Pi
|
||||||
# Prevents HDMI from powering down
|
# Supports both X11 and Wayland environments
|
||||||
|
|
||||||
DISPLAY_TIMEOUT=30
|
DISPLAY_TIMEOUT=30
|
||||||
|
|
||||||
|
# Detect display server type
|
||||||
|
detect_display_server() {
|
||||||
|
if [ -n "$WAYLAND_DISPLAY" ]; then
|
||||||
|
echo "wayland"
|
||||||
|
elif [ -n "$DISPLAY" ]; then
|
||||||
|
echo "x11"
|
||||||
|
else
|
||||||
|
echo "unknown"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY_SERVER=$(detect_display_server)
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
# Keep HDMI powered on (tvservice command)
|
# Keep HDMI powered on (works for both X11 and Wayland)
|
||||||
if command -v tvservice &> /dev/null; then
|
if command -v tvservice &> /dev/null; then
|
||||||
/usr/bin/tvservice -p 2>/dev/null
|
/usr/bin/tvservice -p 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Disable screensaver
|
if [ "$DISPLAY_SERVER" = "wayland" ]; then
|
||||||
if command -v xset &> /dev/null; then
|
# Wayland-specific power management
|
||||||
DISPLAY=:0 xset s off 2>/dev/null
|
|
||||||
DISPLAY=:0 xset -dpms 2>/dev/null
|
# Method 1: Use wlr-randr for Wayland compositors (if available)
|
||||||
DISPLAY=:0 xset dpms force on 2>/dev/null
|
if command -v wlr-randr &> /dev/null; then
|
||||||
DISPLAY=:0 xset s reset 2>/dev/null
|
wlr-randr --output HDMI-A-1 --on 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Move mouse to trigger activity
|
# Method 2: Prevent idle using systemd-inhibit
|
||||||
if command -v xdotool &> /dev/null; then
|
if command -v systemd-inhibit &> /dev/null; then
|
||||||
DISPLAY=:0 xdotool mousemove_relative 1 1 2>/dev/null
|
# This is already running, but refresh the lock
|
||||||
DISPLAY=:0 xdotool mousemove_relative -1 -1 2>/dev/null
|
systemctl --user restart plasma-ksmserver.service 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Disable monitor power saving
|
# Method 3: Use wlopm (Wayland output power management)
|
||||||
if command -v xrandr &> /dev/null; then
|
if command -v wlopm &> /dev/null; then
|
||||||
DISPLAY=:0 xrandr --output HDMI-1 --power-profile performance 2>/dev/null || true
|
wlopm --on \* 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Method 4: Simulate activity via input (works on Wayland)
|
||||||
|
if command -v ydotool &> /dev/null; then
|
||||||
|
ydotool mousemove -x 1 -y 1 2>/dev/null || true
|
||||||
|
ydotool mousemove -x -1 -y -1 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Method 5: GNOME/KDE Wayland idle inhibit
|
||||||
|
if command -v gnome-session-inhibit &> /dev/null; then
|
||||||
|
# Already inhibited by running process
|
||||||
|
true
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
# X11-specific power management (original code)
|
||||||
|
if command -v xset &> /dev/null; then
|
||||||
|
DISPLAY=:0 xset s off 2>/dev/null
|
||||||
|
DISPLAY=:0 xset -dpms 2>/dev/null
|
||||||
|
DISPLAY=:0 xset dpms force on 2>/dev/null
|
||||||
|
DISPLAY=:0 xset s reset 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move mouse to trigger activity
|
||||||
|
if command -v xdotool &> /dev/null; then
|
||||||
|
DISPLAY=:0 xdotool mousemove_relative 1 1 2>/dev/null
|
||||||
|
DISPLAY=:0 xdotool mousemove_relative -1 -1 2>/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disable monitor power saving
|
||||||
|
if command -v xrandr &> /dev/null; then
|
||||||
|
DISPLAY=:0 xrandr --output HDMI-1 --power-profile performance 2>/dev/null || true
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
sleep $DISPLAY_TIMEOUT
|
sleep $DISPLAY_TIMEOUT
|
||||||
@@ -385,6 +431,35 @@ EOF
|
|||||||
chmod +x "$DISPLAY_KEEPALIVE"
|
chmod +x "$DISPLAY_KEEPALIVE"
|
||||||
echo "✓ Display keep-alive script created"
|
echo "✓ Display keep-alive script created"
|
||||||
|
|
||||||
|
# Install Wayland tools if using Wayland
|
||||||
|
echo "Checking for Wayland and installing necessary tools..."
|
||||||
|
if [ -n "$WAYLAND_DISPLAY" ] || pgrep -x "wayfire\|sway\|weston\|mutter" > /dev/null; then
|
||||||
|
echo "Wayland detected - installing Wayland power management tools..."
|
||||||
|
|
||||||
|
# Install wlopm for Wayland output power management
|
||||||
|
if ! command -v wlopm &> /dev/null; then
|
||||||
|
echo "Installing wlopm..."
|
||||||
|
# wlopm might need to be compiled from source or installed via package manager
|
||||||
|
sudo apt-get install -y wlopm 2>/dev/null || echo "Note: wlopm not available in package manager"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install wlr-randr for wlroots compositors
|
||||||
|
if ! command -v wlr-randr &> /dev/null; then
|
||||||
|
echo "Installing wlr-randr..."
|
||||||
|
sudo apt-get install -y wlr-randr 2>/dev/null || echo "Note: wlr-randr not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install ydotool (Wayland's xdotool alternative)
|
||||||
|
if ! command -v ydotool &> /dev/null; then
|
||||||
|
echo "Installing ydotool..."
|
||||||
|
sudo apt-get install -y ydotool 2>/dev/null || echo "Note: ydotool not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Wayland tools installation attempted"
|
||||||
|
else
|
||||||
|
echo "X11 detected - using xset/xdotool/xrandr tools"
|
||||||
|
fi
|
||||||
|
|
||||||
# Update systemd screen keep-alive service to use this script
|
# Update systemd screen keep-alive service to use this script
|
||||||
sudo tee /etc/systemd/system/screen-keepalive.service > /dev/null << EOF
|
sudo tee /etc/systemd/system/screen-keepalive.service > /dev/null << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
|
|||||||
69
src/main.py
69
src/main.py
@@ -930,34 +930,55 @@ class SignagePlayer(Widget):
|
|||||||
def signal_screen_activity(self, dt):
|
def signal_screen_activity(self, dt):
|
||||||
"""Signal screen activity to prevent power saving/sleep
|
"""Signal screen activity to prevent power saving/sleep
|
||||||
|
|
||||||
Uses multiple methods to keep display awake:
|
Supports both X11 and Wayland display servers.
|
||||||
1. xset s reset - Reset screensaver timeout
|
Uses multiple methods to keep display awake.
|
||||||
2. xset dpms force on - Force display on
|
|
||||||
3. xdotool - Move mouse to trigger activity
|
|
||||||
4. tvservice - Keep HDMI powered on (Raspberry Pi)
|
|
||||||
5. xrandr - Disable monitor power saving
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Method 1: Reset screensaver timer using xset
|
# Detect display server type
|
||||||
os.system('DISPLAY=:0 xset s reset 2>/dev/null')
|
is_wayland = os.environ.get('WAYLAND_DISPLAY') is not None
|
||||||
|
|
||||||
# Method 2: Force display on
|
if is_wayland:
|
||||||
os.system('DISPLAY=:0 xset dpms force on 2>/dev/null')
|
# Wayland-specific commands
|
||||||
|
|
||||||
# Method 3: Disable DPMS
|
|
||||||
os.system('DISPLAY=:0 xset -dpms 2>/dev/null')
|
|
||||||
|
|
||||||
# Method 4: Move mouse slightly (subtle, user won't notice)
|
|
||||||
if os.system('DISPLAY=:0 xdotool mousemove_relative 1 1 2>/dev/null') == 0:
|
|
||||||
os.system('DISPLAY=:0 xdotool mousemove_relative -1 -1 2>/dev/null')
|
|
||||||
|
|
||||||
# Method 5: Keep HDMI powered on (Raspberry Pi specific)
|
|
||||||
os.system('/usr/bin/tvservice -p 2>/dev/null')
|
|
||||||
|
|
||||||
# Method 6: Disable monitor power saving via xrandr
|
|
||||||
os.system('DISPLAY=:0 xrandr --output HDMI-1 --power-profile performance 2>/dev/null || true')
|
|
||||||
|
|
||||||
Logger.debug("SignagePlayer: Screen activity signal sent (display kept awake)")
|
# Method 1: Use wlopm (Wayland output power management)
|
||||||
|
os.system('wlopm --on \* 2>/dev/null || true')
|
||||||
|
|
||||||
|
# Method 2: Use wlr-randr for wlroots compositors
|
||||||
|
os.system('wlr-randr --output HDMI-A-1 --on 2>/dev/null || true')
|
||||||
|
|
||||||
|
# Method 3: Simulate activity via ydotool (Wayland's xdotool alternative)
|
||||||
|
if os.system('which ydotool 2>/dev/null') == 0:
|
||||||
|
os.system('ydotool mousemove -x 1 -y 1 2>/dev/null || true')
|
||||||
|
os.system('ydotool mousemove -x -1 -y -1 2>/dev/null || true')
|
||||||
|
|
||||||
|
# Method 4: Keep HDMI powered on (works on both)
|
||||||
|
os.system('/usr/bin/tvservice -p 2>/dev/null')
|
||||||
|
|
||||||
|
Logger.debug("SignagePlayer: Wayland screen activity signal sent")
|
||||||
|
|
||||||
|
else:
|
||||||
|
# X11-specific commands (original code)
|
||||||
|
|
||||||
|
# Method 1: Reset screensaver timer using xset
|
||||||
|
os.system('DISPLAY=:0 xset s reset 2>/dev/null')
|
||||||
|
|
||||||
|
# Method 2: Force display on
|
||||||
|
os.system('DISPLAY=:0 xset dpms force on 2>/dev/null')
|
||||||
|
|
||||||
|
# Method 3: Disable DPMS
|
||||||
|
os.system('DISPLAY=:0 xset -dpms 2>/dev/null')
|
||||||
|
|
||||||
|
# Method 4: Move mouse slightly (subtle, user won't notice)
|
||||||
|
if os.system('DISPLAY=:0 xdotool mousemove_relative 1 1 2>/dev/null') == 0:
|
||||||
|
os.system('DISPLAY=:0 xdotool mousemove_relative -1 -1 2>/dev/null')
|
||||||
|
|
||||||
|
# Method 5: Keep HDMI powered on (Raspberry Pi specific)
|
||||||
|
os.system('/usr/bin/tvservice -p 2>/dev/null')
|
||||||
|
|
||||||
|
# Method 6: Disable monitor power saving via xrandr
|
||||||
|
os.system('DISPLAY=:0 xrandr --output HDMI-1 --power-profile performance 2>/dev/null || true')
|
||||||
|
|
||||||
|
Logger.debug("SignagePlayer: X11 screen activity signal sent")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Logger.debug(f"SignagePlayer: Screen activity signal failed (non-critical): {e}")
|
Logger.debug(f"SignagePlayer: Screen activity signal failed (non-critical): {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user