adaptive sync

This commit is contained in:
nnduc
2026-10-19 23:21:54 +07:00
parent 9b8320cead
commit 96467a1c56
15 changed files with 169 additions and 848 deletions
+10 -1
View File
@@ -20,6 +20,11 @@ font pango:NotoSans 12
# text rendering and scalability on retina/hidpi displays (thanks to pango).
#font pango:DejaVu Sans Mono 8
# Clear leftover Wayland env (e.g. from a previous Hyprland/sway session) out of
# systemd/dbus so dbus-activated apps like Thunar don't try to use a dead compositor.
# Must run before anything dbus-activated starts.
exec --no-startup-id sh -c "systemctl --user unset-environment WAYLAND_DISPLAY HYPRLAND_INSTANCE_SIGNATURE SWAYSOCK; dbus-update-activation-environment --systemd DISPLAY XAUTHORITY XDG_CURRENT_DESKTOP=i3 XDG_SESSION_TYPE=x11; pkill -x Thunar"
# Start XDG autostart .desktop files using dex. See also
# https://wiki.archlinux.org/index.php/XDG_Autostart
exec --no-startup-id dex --autostart --environment i3
@@ -58,6 +63,7 @@ exec --no-startup-id /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1
exec --no-startup-id ~/.config/i3/scripts/wallpaper-rotate $wallpaper_dir
exec --no-startup-id pasystray
exec --no-startup-id polybar
exec --no-startup-id ~/.config/i3/scripts/guide-freeze
set $refresh_i3status killall -SIGUSR1 i3status
@@ -99,7 +105,7 @@ floating_modifier $mod
#xrandr --output HDMI-2 --auto --right-of eDP1
# High refresh rates can flicker on AMD (VRAM clock switching), so run the
# desktop at 120Hz. See README "High refresh rate flicker".
exec --no-startup-id xrandr --output DisplayPort-0 --mode 1920x1080 --rate 120
exec --no-startup-id xrandr --output DisplayPort-0 --mode 1920x1080 --rate 240
# start a terminal
#bindsym $mod+Return exec i3-sensible-terminal
@@ -108,6 +114,9 @@ bindsym $mod+Return exec $terminal
# kill focused window
bindsym $mod+Shift+q kill
# freeze / resume focused window (SIGSTOP / SIGCONT)
bindsym $mod+m exec --no-startup-id ~/.config/i3/scripts/freeze-toggle
# start dmenu (a program launcher)
#bindsym $mod+d exec --no-startup-id j4-dmenu-desktop
#bindsym $mod+d exec --no-startup-id dmenu
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
# Freeze / resume the focused window's process tree (SIGSTOP / SIGCONT).
pid=$(xdotool getactivewindow getwindowpid 2>/dev/null) || exit 1
# collect pid plus all descendants (Wine/Proton games spawn several)
descendants() {
local p
for p in $(pgrep -P "$1"); do
echo "$p"
descendants "$p"
done
}
pids="$pid $(descendants "$pid")"
name=$(ps -o comm= -p "$pid")
case "$(ps -o state= -p "$pid")" in
T*) kill -CONT $pids && notify-send -t 1500 "Resumed" "$name ($pid)" ;;
*) kill -STOP $pids && notify-send -t 1500 "Frozen" "$name ($pid)" ;;
esac
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
# Freeze/resume the focused window on the controller's Home/guide button (BTN_MODE).
# Stdlib only: reads raw evdev events. Gamepads are readable by the seat user.
import glob, os, select, signal, struct, subprocess, time
EV_KEY, BTN_MODE = 1, 0x13c
EVENT = struct.Struct('llHHi') # struct input_event
LONG_BITS = struct.calcsize('l') * 8
CMD = [os.path.expanduser('~/.config/i3/scripts/freeze-toggle')]
signal.signal(signal.SIGCHLD, signal.SIG_IGN) # auto-reap child processes
def has_btn_mode(path):
try:
with open(f'/sys/class/input/{os.path.basename(path)}/device/capabilities/key') as f:
words = f.read().split()
except OSError:
return False
bits = 0
for w in words:
bits = bits << LONG_BITS | int(w, 16)
return bits >> BTN_MODE & 1
fds = {} # fd -> device path
last = 0.0
rescan = 0.0
while True:
if time.monotonic() >= rescan: # pick up hotplugged controllers
for path in glob.glob('/dev/input/event*'):
if path not in fds.values() and has_btn_mode(path):
try:
fds[os.open(path, os.O_RDONLY)] = path
except OSError:
pass
rescan = time.monotonic() + 2
ready, _, _ = select.select(list(fds), [], [], 2)
for fd in ready:
try:
data = os.read(fd, EVENT.size * 64)
except OSError: # controller unplugged
os.close(fd)
del fds[fd]
continue
for sec, usec, type_, code, value in EVENT.iter_unpack(data):
if type_ == EV_KEY and code == BTN_MODE and value == 1:
now = sec + usec / 1e6
if now - last < 0.4: # GuliKit's Home button double-fires ~10ms apart
continue
last = now
subprocess.Popen(CMD, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)