Automatically reduce resolution to that of the smallest monitor upon connecting new monitor?
I have a monitor and a TV I use sometimes. The monitor is 4k, used at 2560x1440 resolution - except when the TV is connected I need to manually reduce the resolution to 1080, and then manually set it back to 1440 after disconnecting the TV.
xrandr output looks like:
DVI-I-1 connected (normal left inverted right x axis y axis)
1920x1080 60.00 + 59.94 23.98 60.05 60.00
1440x480 60.05
1280x720 60.00 59.94
720x480 59.94
640x480 59.93
HDMI-0 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 597mm x 336mm
3840x2160 60.00 + 59.94 29.97 25.00 23.98
2560x1440 59.95*
2048x1280 60.00
1920x1080 60.00 59.94 50.00 25.00 23.98 60.00 50.04
1600x1200 60.00
1600x900 60.00
1280x1024 75.02 60.02
1280x720 59.94
1152x864 75.00
1024x768 75.03 60.00
800x600 75.00 60.32
720x576 50.00
720x480 59.94
640x480 75.00 59.94 59.93
Solution 1:
Change resolution on signal
With the help of Gdk, we can act on several signals, a.o. on connecting/disconnecting monitors. If we connect both the monitor-added
and monitor-removed
-signal (Gdk.Display) to update the monitor resolution automatically, depending on the TV being attached, we're done.
In a script
#!/usr/bin/env python3
import gi
gi.require_version("Gdk", "3.0")
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
import subprocess
triggermon = "DVI-I-1" # if this one is connected, reduce resolution
tochange = "HDMI-0" # the monitor to lower resolution on
lowres = "1920x1080" # the low resolution
highres = "3840x2160" # the default resolution
class WatchOut:
def __init__(self):
self.gdkdsp = Gdk.Display.get_default()
# use connect/disconnect signales
self.gdkdsp.connect("monitor_added", self.act_onchange)
self.gdkdsp.connect("monitor_removed", self.act_onchange)
# make sure initial configuration is correct
self.act_onchange()
# we need a gtk thread to use the signals
Gtk.main()
def act_onchange(self, *args):
# let's default to highres
curr_res = highres
# get attached n-monitors, lower res if triggermon is connected
n_mons = self.gdkdsp.get_n_monitors()
for n in [n for n in range(self.gdkdsp.get_n_monitors())]:
mon_name = self.gdkdsp.get_monitor(n).get_model()
if mon_name == triggermon:
curr_res = lowres
# set resolution
subprocess.Popen([
"xrandr", "--output", tochange, "--mode", curr_res
])
WatchOut()
Set up
-
Copy the script into an empty file, save it as
actonmonitor.py
and make it executable (if you run it without calling the interpreter explicitely). -
The monitor names are in the head of the script, and so the resolutions you mentioned, change them if needed.
-
Test- run it in a terminal window.
/path/to/actonmonitor.py
-
See if all works as it should.
-
Add it to your startup applications if you like.
N.B.
The exact position of the secundary monitor in the monitor layout is not in the (your) output of xrandr. If the position matters, you probably need to add an additional xrandr
command to the script.