From 391791f6165653ebe4c4f25af953841a3b0fc6c7 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 25 Nov 2023 19:23:41 +0100 Subject: Update setres MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- xmonad/xmonad-autofocus-output.c | 2 + xorg-xrandr/Makefile | 1 + xorg-xrandr/resolution-changed | 42 ++++- xorg-xrandr/setres/Makefile | 12 +- xorg-xrandr/setres/__main__.py | 153 ++++++++++++++---- xorg-xrandr/setres/__main__.py.gpp | 320 +++++++++++++++++++++++++++++++++++++ 6 files changed, 491 insertions(+), 39 deletions(-) create mode 100755 xorg-xrandr/setres/__main__.py.gpp diff --git a/xmonad/xmonad-autofocus-output.c b/xmonad/xmonad-autofocus-output.c index 853e18b..a36f76b 100644 --- a/xmonad/xmonad-autofocus-output.c +++ b/xmonad/xmonad-autofocus-output.c @@ -15,6 +15,8 @@ static KeyCode mod, key[2]; static inline int get_output(int x, int y) { + /* TODO use "resolution changed:$(printf -- ' %ix%i%+i%+i' "$@")" message broadcast on BUS_VIDEO + * at start up look in ${XDG_RUNTIME_DIR}/x-display/${DISPLAY}/resolution for $(printf -- '%ix%i%+i%+i\n' "$@") */ return x < 1920; } diff --git a/xorg-xrandr/Makefile b/xorg-xrandr/Makefile index 0968b2a..b5e442f 100644 --- a/xorg-xrandr/Makefile +++ b/xorg-xrandr/Makefile @@ -7,6 +7,7 @@ XINITRC_ORDER = 15 install: ../check-in-path xwallpaper ../check-in-path python3 + ../check-in-path bus ../check-installed-shebang resolution-changed mkdir -p -- ~/.config/X11/xinit/xinitrc.d test ! -e ~/.config/X11/xinit/xinitrc.d/$(XINITRC_ORDER)-xorg-xrandr || \ diff --git a/xorg-xrandr/resolution-changed b/xorg-xrandr/resolution-changed index a53c7b6..e1457ce 100755 --- a/xorg-xrandr/resolution-changed +++ b/xorg-xrandr/resolution-changed @@ -1,11 +1,23 @@ #!/bin/dash -# Reset rat size in case DPI change modified scaling -xsetroot -cursor_name left_ptr || : +reset_wallpaper_twice=0 -# Reset rat speed in case DPI changed -if test "${DESKTOP_SESSION}" = xmonad && test ! "${NO_MATE}" = y; then - (exec mate-settings-daemon --replace &) || : +if ! test "$(hostname | tr '[A-Z]' '[a-z]')" = zenith; then + # Reset rat size in case DPI change modified scaling + xsetroot -cursor_name left_ptr || : + + # Reset rat speed in case DPI changed + if test "${DESKTOP_SESSION}" = xmonad && test ! "${NO_MATE}" = y; then + msd=/usr/lib/mate-settings-daemon/mate-settings-daemon + if ! test -x "$msd"; then + msd=mate-settings-daemon + fi + (exec $msd --replace &) || : + # mate-settings-daemon will change the keyboard layout + (sleep 1; setkeys) & + # mate-settings-daemon may change the wallpaper + reset_wallpaper_twice=1 + fi fi # Reset background in case resolution change damaged it @@ -15,6 +27,24 @@ for file in ~/.config/background.${SESSION_} \ ~/.config/background; do if test -r "$file"; then xwallpaper --zoom "$file" - (sleep 2 ; xwallpaper --zoom "$file") & # Again, with delay, in case mate-settings-daemon changes it + if test ${reset_wallpaper_twice} = 1; then + # Again, with delay, in case mate-settings-daemon changes it + (sleep 2 ; xwallpaper --zoom "$file") & + fi fi done + +# Broadcast resolution change +if test -n "${XDG_RUNTIME_DIR}"; then + if test -n "${DISPLAY}"; then + mkdir -p -- "${XDG_RUNTIME_DIR}/x-display/${DISPLAY}/" + printf -- '%ix%i%+i%+i\n' "$@" > "${XDG_RUNTIME_DIR}/x-display/${DISPLAY}/resolution~" + mv -- "${XDG_RUNTIME_DIR}/x-display/${DISPLAY}/resolution~" "${XDG_RUNTIME_DIR}/x-display/${DISPLAY}/resolution" + fi + if test -z "${BUS_VIDEO}"; then + BUS_VIDEO="${XDG_RUNTIME_DIR}/@bus/video" + fi +fi +if test -n "${BUS_VIDEO}"; then + bus broadcast "${BUS_VIDEO}" "resolution changed:$(printf -- ' %ix%i%+i%+i' "$@")" +fi diff --git a/xorg-xrandr/setres/Makefile b/xorg-xrandr/setres/Makefile index 770d45d..c14aa8a 100644 --- a/xorg-xrandr/setres/Makefile +++ b/xorg-xrandr/setres/Makefile @@ -1,17 +1,21 @@ all: setres +__main__.py: __main__.py.gpp + gpp -s '%%' < $@.gpp > $@ + chmod -- a+x "$@" + setres.zip: __main__.py get.py set.py zip $@ $^ setres: setres.zip echo '#!/usr/bin/python3' > $@ - cat setres.zip >> $@ - chmod a+x $@ + cat -- setres.zip >> $@ + chmod -- a+x $@ clean: - -rm -r *.zip *.pyc __pycache__/ *~ + -rm -rf -- *.zip *.pyc __main__.py __pycache__/ *~ reallyclean: clean - -rm setres + -rm -f -- setres .PHONY: all clean reallyclean diff --git a/xorg-xrandr/setres/__main__.py b/xorg-xrandr/setres/__main__.py index 26f6f65..94a2db1 100755 --- a/xorg-xrandr/setres/__main__.py +++ b/xorg-xrandr/setres/__main__.py @@ -30,14 +30,15 @@ if pretend: print(repr(display.to_xrandr())) return True +phonies = [] -### Configurations +### Configurations if hostname == 'zenith': - prime = screen['DisplayPort-2' if not swap else 'DisplayPort-1'] - sec = screen['DisplayPort-1' if not swap else 'DisplayPort-2'] + prime = screen['DisplayPort-1' if not swap else 'DisplayPort-1'] + sec = screen['DisplayPort-0' if not swap else 'DisplayPort-0'] embed = None prime_alt = None @@ -45,15 +46,62 @@ if hostname == 'zenith': prime.want_mode = '1920x1200' sec.want_mode = '1920x1200' + + sec_position = 'left' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + else: - print('%s: no configurations found for this machine' % sys.argv[0], file = sys.stderr) + print('%s: no configurations found for this machine (%s)' % (sys.argv[0], hostname), + file = sys.stderr) sys.exit(1) -if not prime.connected and prime_alt is not None: +if prime is not None and not prime.connected and prime_alt is not None: prime, prime_alt = prime_alt, prime -if not sec.connected and sec_alt is not None: +if sec is not None and not sec.connected and sec_alt is not None: sec, sec_alt = sec_alt, sec @@ -102,7 +150,7 @@ if '-embed' in args: ### Apply -if prime.connected and sec.connected and not single: +if prime is not None and prime.connected and sec is not None and sec.connected and not single: display = Display() ok = True @@ -119,16 +167,24 @@ if prime.connected and sec.connected and not single: output.mode = sec.want_mode output.rate = sec.want_rate output.primary = False - output.relpos = 'left-of' if not mirror else 'same-as' + output.relpos = (sec_position + '-of') if not mirror else 'same-as' output.relto = prime.name if embed is not None: output = Output(embed.name) display.outputs.append(output) - output.off = True - - -elif prime.connected: + if embed.want_mode == prime.want_mode: + output.mode = embed.want_mode + output.rate = embed.want_rate + output.primary = False + output.off = False + output.relpos = 'same-as' + output.relto = prime.name + else: + output.off = True + + +elif prime is not None and prime.connected: display = Display() ok = True @@ -138,17 +194,26 @@ elif prime.connected: output.rate = prime.want_rate output.primary = True - output = Output(sec.name) - display.outputs.append(output) - output.off = True + if sec is not None: + output = Output(sec.name) + display.outputs.append(output) + output.off = True if embed is not None: output = Output(embed.name) display.outputs.append(output) - output.off = True - - -elif sec.connected: + if embed.want_mode == prime.want_mode: + output.mode = embed.want_mode + output.rate = embed.want_rate + output.primary = False + output.off = False + output.relpos = 'same-as' + output.relto = prime.name + else: + output.off = True + + +elif sec is not None and sec.connected: display = Display() ok = True @@ -158,14 +223,23 @@ elif sec.connected: output.rate = sec.want_rate output.primary = True - output = Output(prime.name) - display.outputs.append(output) - output.off = True + if prime is not None: + output = Output(prime.name) + display.outputs.append(output) + output.off = True if embed is not None: output = Output(embed.name) display.outputs.append(output) - output.off = True + if embed.want_mode == sec.want_mode: + output.mode = embed.want_mode + output.rate = embed.want_rate + output.primary = False + output.off = False + output.relpos = 'same-as' + output.relto = sec.name + else: + output.off = True elif embed is None or not embed.connected: @@ -182,13 +256,16 @@ else: output.rate = embed.want_rate output.primary = True - output = Output(prime.name) - display.outputs.append(output) - output.off = True + if prime is not None: + output = Output(prime.name) + display.outputs.append(output) + output.off = True + + if sec is not None: + output = Output(sec.name) + display.outputs.append(output) + output.off = True - output = Output(sec.name) - display.outputs.append(output) - output.off = True if ok: if prime_alt is not None: @@ -201,6 +278,11 @@ if ok: display.outputs.append(output) output.off = True + for phony in phonies: + output = Output(phony.name) + display.outputs.append(output) + output.off = True + ok = apply_setup(display) @@ -212,11 +294,24 @@ if not ok: if pretend: sys.exit(0) +reschargs = [] +for output in (prime, sec): + if output is not None: + output = screen[output.name] + reschargs.extend(output.size) + reschargs.extend(output.position) [screen] = get_setup() prime = screen[True] if prime.position[0] > 0: print(prime.position[0], flush = True) +file = '%s/.config/resolution-changed' % home +if os.path.exists(file): + try: + os.execlp(file, file, *reschargs) + except: + pass + for file in ('%s/.config/background.%s' % (home, session_), '%s/.config/background' % home): if os.path.exists(file): try: diff --git a/xorg-xrandr/setres/__main__.py.gpp b/xorg-xrandr/setres/__main__.py.gpp new file mode 100755 index 0000000..d34b85c --- /dev/null +++ b/xorg-xrandr/setres/__main__.py.gpp @@ -0,0 +1,320 @@ +#!/usr/bin/env python3 + +import sys, os, pwd +from subprocess import Popen, PIPE + +from get import * +from set import * + +args = sys.argv[1:] +home = os.environ['HOME'] if 'HOME' in os.environ else pwd.getpwuid(os.getuid()).pw_dir +session_ = os.environ['SESSION_'] if 'SESSION_' in os.environ else '' +hostname = os.uname().nodename.lower() + +t = lambda lopt, sopt : any(arg in args for arg in (lopt, '-' + lopt, '--' + lopt, sopt, '-' + sopt)) + +mirror = t('mirror', 'm') +swap = t('swap', 's') +tv = t('tv', 't') +wide = t('wide', 'w') +crt = t('crt', 'c') +large = t('large', 'l') +single = t('single', '1') +pretend = t('pretend', 'P') + +[screen] = get_setup() +ok = False + +if pretend: + def apply_setup(display): + print(repr(display.to_xrandr())) + return True + +phonies = [] + + + +### Configurations + +if hostname == 'zenith': + prime = screen['DisplayPort-1' if not swap else 'DisplayPort-1'] + sec = screen['DisplayPort-0' if not swap else 'DisplayPort-0'] + embed = None + + prime_alt = None + sec_alt = None + + prime.want_mode = '1920x1200' + sec.want_mode = '1920x1200' + + sec_position = 'left' + +%%>hostname="$(hostname | tr '[A-Z]' '[a-z]')" +%%>file="${HOME}/.dotfiles/xorg-xrandr/setres/${hostname}" +%%>if test -r "${file}"; then +elif hostname == '%%{hostname}': + connectors = {con.edid: con.name for con in screen.connectors if con.connected and con.edid and con.name} + +%%>cat -- "${file}" + + primes = [(home_prime, '1920x1200'), + (work_prime, '1920x1080')] + + secs = [(home_sec, '1920x1200', 'left'), + (work_sec, '1920x1080', 'right')] + + prime = None + prime_res = None + for edid, res in primes: + if edid in connectors: + prime, prime_res = screen[connectors[edid]], res + + sec = None + sec_res = None + sec_position = 'left' + for edid, res, pos in secs: + if edid in connectors: + sec, sec_res, sec_position = screen[connectors[edid]], res, pos + + embed = screen[connectors[embed]] if embed in connectors else screen['eDP-1'] + + phonies = [screen[name] for edid, name in connectors.items() if edid not in (prime, sec, embed)] + + if swap: + (prime, sec) = (sec, prime) + + prime_alt = None + sec_alt = None + + if prime is not None: + prime.want_mode = prime_res + if sec is not None: + sec.want_mode = sec_res + if embed is not None: + embed.want_mode = '1920x1200' +%%>fi + +else: + print('%s: no configurations found for this machine (%s)' % (sys.argv[0], hostname), + file = sys.stderr) + sys.exit(1) + +if prime is not None and not prime.connected and prime_alt is not None: + prime, prime_alt = prime_alt, prime +if sec is not None and not sec.connected and sec_alt is not None: + sec, sec_alt = sec_alt, sec + + +if large: + prime.want_mode = '1792x1344' + sec.want_mode = '1792x1344' + +if crt: + prime.want_mode = '800x600' + sec.want_mode = '800x600' + +if wide: + prime.want_mode = '1920x1080' + sec.want_mode = '1920x1080' + +if tv: + sec.want_mode = '1920x1080' + + +if prime is not None: + prime.want_rate = prime.best_rate(prime.want_mode) +if sec is not None: + sec.want_rate = sec.best_rate(sec.want_mode) +if embed is not None: + embed.want_rate = embed.best_rate(embed.want_mode) + + + + +if '+prime' in args: + prime.connected = True +if '+sec' in args: + sec.connected = True +if '+embed' in args: + embed.connected = True + +if '-prime' in args: + prime.connected = False +if '-sec' in args: + sec.connected = False +if '-embed' in args: + embed.connected = False + + + + +### Apply + +if prime is not None and prime.connected and sec is not None and sec.connected and not single: + display = Display() + ok = True + + output = Output(prime.name) + display.outputs.append(output) + output.mode = prime.want_mode + output.rate = prime.want_rate + output.primary = True + output.relpos = None + output.relto = None + + output = Output(sec.name) + display.outputs.append(output) + output.mode = sec.want_mode + output.rate = sec.want_rate + output.primary = False + output.relpos = (sec_position + '-of') if not mirror else 'same-as' + output.relto = prime.name + + if embed is not None: + output = Output(embed.name) + display.outputs.append(output) + if embed.want_mode == prime.want_mode: + output.mode = embed.want_mode + output.rate = embed.want_rate + output.primary = False + output.off = False + output.relpos = 'same-as' + output.relto = prime.name + else: + output.off = True + + +elif prime is not None and prime.connected: + display = Display() + ok = True + + output = Output(prime.name) + display.outputs.append(output) + output.mode = prime.want_mode + output.rate = prime.want_rate + output.primary = True + + if sec is not None: + output = Output(sec.name) + display.outputs.append(output) + output.off = True + + if embed is not None: + output = Output(embed.name) + display.outputs.append(output) + if embed.want_mode == prime.want_mode: + output.mode = embed.want_mode + output.rate = embed.want_rate + output.primary = False + output.off = False + output.relpos = 'same-as' + output.relto = prime.name + else: + output.off = True + + +elif sec is not None and sec.connected: + display = Display() + ok = True + + output = Output(sec.name) + display.outputs.append(output) + output.mode = sec.want_mode + output.rate = sec.want_rate + output.primary = True + + if prime is not None: + output = Output(prime.name) + display.outputs.append(output) + output.off = True + + if embed is not None: + output = Output(embed.name) + display.outputs.append(output) + if embed.want_mode == sec.want_mode: + output.mode = embed.want_mode + output.rate = embed.want_rate + output.primary = False + output.off = False + output.relpos = 'same-as' + output.relto = sec.name + else: + output.off = True + + +elif embed is None or not embed.connected: + print('%s: don\'t know how to configure' % sys.argv[0], file = sys.stderr) + + +else: + display = Display() + ok = True + + output = Output(embed.name) + display.outputs.append(output) + output.mode = embed.want_mode + output.rate = embed.want_rate + output.primary = True + + if prime is not None: + output = Output(prime.name) + display.outputs.append(output) + output.off = True + + if sec is not None: + output = Output(sec.name) + display.outputs.append(output) + output.off = True + + +if ok: + if prime_alt is not None: + output = Output(prime_alt.name) + display.outputs.append(output) + output.off = True + + if sec_alt is not None: + output = Output(sec_alt.name) + display.outputs.append(output) + output.off = True + + for phony in phonies: + output = Output(phony.name) + display.outputs.append(output) + output.off = True + + ok = apply_setup(display) + + + +### Epilogue + +if not ok: + sys.exit(1) +if pretend: + sys.exit(0) + +reschargs = [] +for output in (prime, sec): + if output is not None: + output = screen[output.name] + reschargs.extend(output.size) + reschargs.extend(output.position) +[screen] = get_setup() +prime = screen[True] +if prime.position[0] > 0: + print(prime.position[0], flush = True) + +file = '%s/.config/resolution-changed' % home +if os.path.exists(file): + try: + os.execlp(file, file, *reschargs) + except: + pass + +for file in ('%s/.config/background.%s' % (home, session_), '%s/.config/background' % home): + if os.path.exists(file): + try: + os.execlp('xwallpaper', 'xwallpaper', '--zoom', file) + except: + pass -- cgit v1.2.3-70-g09d2