Files
i3-dot/i3/scripts/dpms-inhibit
T
2026-09-25 17:03:27 +07:00

58 lines
1.8 KiB
Bash
Executable File

#!/bin/bash
# Suspends xset screensaver/DPMS blanking while any visible workspace has a
# fullscreen window (video, game, presentation), restores normal timeouts
# once nothing is fullscreen.
interval="${1:-5}"
# Single-instance lock: i3 restarts/reloads re-run our autostart exec, so
# without this, stray duplicate loops accumulate and race each other's state.
# Per session, so a loop lingering from a logged-out session can't block this one.
exec 9>"/tmp/.dpms-inhibit-$(id -u)-${XDG_SESSION_ID:-0}.lock"
flock -n 9 || exit 0
has_fullscreen() {
python3 - <<'EOF'
import json, subprocess, sys
def is_fullscreen(node):
if node.get('window') and node.get('fullscreen_mode', 0) > 0: return True
return any(is_fullscreen(c) for c in node.get('nodes', []) + node.get('floating_nodes', []))
def find_ws(node, name):
if node.get('type') == 'workspace' and node.get('name') == name: return node
for c in node.get('nodes', []) + node.get('floating_nodes', []):
r = find_ws(c, name)
if r: return r
try:
wss = json.loads(subprocess.check_output(['i3-msg', '-t', 'get_workspaces'], stderr=subprocess.DEVNULL))
tree = json.loads(subprocess.check_output(['i3-msg', '-t', 'get_tree'], stderr=subprocess.DEVNULL))
for ws in wss:
if ws.get('visible'):
node = find_ws(tree, ws['name'])
if node and is_fullscreen(node):
sys.exit(0)
except Exception:
pass
sys.exit(1)
EOF
}
inhibited=0
while true; do
# our i3 is gone (logged out): don't linger into the next session
i3-msg -t get_version >/dev/null 2>&1 || exit 0
if has_fullscreen; then
xset s off
xset -dpms
inhibited=1
else
if [ "$inhibited" -eq 1 ]; then
xset s 300 300
xset dpms 0 0 900
inhibited=0
fi
fi
sleep "$interval"
done