~em-dash/x-daemons

x-daemons/auto-monitors.py -rwxr-xr-x 1.8 KiB
af585831Emily Ellis add auto-xrandr'ing thing 18 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/env python3
"""
Watch for an external monitor being connected or disconnected to a laptop, and enable/disable it.

Places the external monitor to the right of the internal monitor by default.
Set $EXTERNAL_MONITOR_DIRECTION to one of left/right/up/down to change this.
"""
import sys, os, subprocess
from Xlib import X, display as xdisplay
from Xlib.ext import randr as xrandr

display = xdisplay.Display()
screen = display.screen()
root_window = screen.root

last_event_timestamp = 0

root_window.xrandr_select_input(xrandr.RROutputChangeNotifyMask)

direction = os.environ.get('EXTERNAL_MONITOR_DIRECTION')
direction_arg = {
	'left': '--left-of',
	'right': '--right-of',
	'up': '--above',
	'above': '--above',
	'down': '--below',
	'below': '--below',
}.get(direction, '--right-of')

def do_the_thing():
	internal_output = None
	external_outputs = []
	
	resources = root_window.xrandr_get_screen_resources()._data
	for output in resources['outputs']:
		output_data = display.xrandr_get_output_info(output, resources['config_timestamp'])._data
		if output_data['name'].startswith("eDP-"):
			internal_output = output_data
		else:
			external_outputs.append(output_data)

	root_window.xrandr_select_input(0)
	for output in external_outputs:
		if output['connection'] == xrandr.Connected:
			subprocess.run([
				'/usr/bin/xrandr',
				'--output',
				output['name'],
				direction_arg,
				internal_output['name'],
				'--primary',
				'--auto',
			])
		else:
			subprocess.run([
				'/usr/bin/xrandr',
				'--output',
				output['name'],
				'--off',
			])
	root_window.xrandr_select_input(xrandr.RROutputChangeNotifyMask)

while True:
	ev = display.next_event()
	if ev.config_timestamp <= last_event_timestamp + 10:
		continue
	last_event_timestamp = ev.config_timestamp
	do_the_thing()