--- /dev/null
+#!/usr/bin/python
+"""
+Parse xrandr current information
+
+TODO:
+* Cannot seem to undock notebook then recover displays without causing a logout
+ event. Could it be that i3 is finding there are no displays?
+"""
+
+import sys
+import subprocess
+import re
+
+dry_run = False
+
+class OutputInfo():
+ def __init__(self):
+ self.clear()
+
+ def clear(self):
+ self.name = None
+ self.connected = False
+ self.enabled = False
+ self.width = -1
+ self.height = -1
+ self.posx = -1
+ self.posy = -1
+
+ def complete(self):
+ if self.name and (self.connected == False or self.width != -1):
+ return True
+ else:
+ return False
+
+ def asDict(self):
+ if self.complete():
+ return {'name':self.name, 'enabled':self.enabled,
+ 'connected':self.connected, 'width':self.width,
+ 'height':self.height, 'posx':self.posx, 'posy':self.posy,
+ 'use':False, 'done':False}
+ else:
+ raise ValueError
+
+ def parse(self, line):
+ tokens = line.split()
+ if len(tokens):
+ if tokens[1] == 'connected' or tokens[1] == 'disconnected':
+ self.clear()
+ self.name = tokens[0]
+ if tokens[1] == 'connected':
+ self.connected = True
+ token = 2
+ size = []
+ while token < len(tokens) and len(size) != 4:
+ # skip other tokens like 'primary'
+ size = re.split('[x+]', tokens[token])
+ token += 1
+ if len(size) == 4:
+ self.enabled = True
+ #self.width = int(size[0])
+ #self.height = int(size[1])
+ #self.posx = int(size[2])
+ #self.posy = int(size[3])
+ elif self.connected and self.width < 0:
+ size = re.split('x', tokens[0])
+ if len(size) == 2:
+ self.width = int(size[0])
+ self.height = int(size[1])
+
+
+def parse():
+ outputs = []
+ output = OutputInfo()
+ p = subprocess.check_output('xrandr')
+ for line in p.split('\n'):
+ output.parse(line)
+ if output.complete():
+ outputs.append(output.asDict())
+ output.clear()
+ return outputs
+
+
+def xrandr_on(output):
+ command = ['xrandr', '--output', output['name'], '--auto', '--pos',
+ '%dx0' % output['posx']]
+ if output['posx'] == 0:
+ command += ['--primary']
+ if not dry_run:
+ print 'xrandr_on:', command
+ subprocess.call(command)
+ else:
+ print '(dry-run) xrandr_on:', command
+
+
+def xrandr_off(output):
+ command = ['xrandr', '--output', output['name'], '--off']
+ if not dry_run:
+ subprocess.call(command)
+ print 'xrandr_off:', command
+ else:
+ print '(dry-run) xrandr_off:', command
+
+
+def output_by_name(outputs, name):
+ for output in outputs:
+ if output['name'] == name:
+ return output
+ return None
+
+
+if __name__ == '__main__':
+ def print_output(output):
+ print 'name:%s connected:%r enabled:%r width:%d height:%d pos:%dx%d' % (
+ output['name'], output['connected'], output['enabled'],
+ output['width'], output['height'], output['posx'],
+ output['posy'])
+
+ def print_outputs(header, outputs):
+ print '%s:' % header
+ for output in outputs:
+ print_output(output)
+ print
+
+ def all_done(outputs):
+ for output in outputs:
+ if not output['done']:
+ return False
+ return True
+
+ def disable_an_entry(outputs):
+ for output in outputs:
+ if not output['done'] and not output['use'] and output['enabled']:
+ xrandr_off(output)
+ output['done'] = True
+ return 1
+ return 0
+
+ def enable_an_entry(outputs):
+ enables = 0
+ for output in reversed(outputs):
+ if not output['done'] and output['use']:
+ xrandr_on(output)
+ output['done'] = True
+ return 1
+ return 0
+
+ def main(argv):
+ global dry_run
+ if len(argv) >= 2 and argv[1] == '--dry-run':
+ dry_run = True
+
+ outputs = parse()
+ print_outputs('Outputs', outputs)
+
+ # Find the first two connected devices, in reverse list order. On the
+ # Thinkpad X201, the reversed list order is the preferred order of
+ # precedence, highest quality external display first, down to internal
+ # LVDS panel used as a last resort. Also find new posx values.
+ use_count = 0
+ posx = 0
+ for output in reversed(outputs):
+ if output['connected']:
+ print 'use', output['name']
+ output['use'] = True
+ output['posx'] = posx
+ posx += output['width']
+ use_count += 1
+ if use_count >= 2:
+ break
+
+ # How many outputs are currently enabled?
+ enabled_count = 0
+ for output in outputs:
+ if output['enabled']:
+ enabled_count += 1
+
+ # Mark outputs that receive no change as done
+ for output in outputs:
+ if not output['use'] and not output['enabled']:
+ # Nothing to do for this output, mark as done
+ output['done'] = True
+
+ while not all_done(outputs):
+ if enabled_count > 1:
+ enabled_count -= disable_an_entry(outputs)
+ if enabled_count < 2:
+ enabled_count += enable_an_entry(outputs)
+
+
+ main(sys.argv)
+++ /dev/null
-#!/usr/bin/python
-"""
-Parse xrandr current information
-
-TODO:
-* Cannot seem to undock notebook then recover displays without causing a logout
- event. Could it be that i3 is finding there are no displays?
-"""
-
-import sys
-import subprocess
-import re
-
-dry_run = False
-
-class OutputInfo():
- def __init__(self):
- self.clear()
-
- def clear(self):
- self.name = None
- self.connected = False
- self.enabled = False
- self.width = -1
- self.height = -1
- self.posx = -1
- self.posy = -1
-
- def complete(self):
- if self.name and (self.connected == False or self.width != -1):
- return True
- else:
- return False
-
- def asDict(self):
- if self.complete():
- return {'name':self.name, 'enabled':self.enabled,
- 'connected':self.connected, 'width':self.width,
- 'height':self.height, 'posx':self.posx, 'posy':self.posy,
- 'use':False, 'done':False}
- else:
- raise ValueError
-
- def parse(self, line):
- tokens = line.split()
- if len(tokens):
- if tokens[1] == 'connected' or tokens[1] == 'disconnected':
- self.clear()
- self.name = tokens[0]
- if tokens[1] == 'connected':
- self.connected = True
- token = 2
- size = []
- while token < len(tokens) and len(size) != 4:
- # skip other tokens like 'primary'
- size = re.split('[x+]', tokens[token])
- token += 1
- if len(size) == 4:
- self.enabled = True
- #self.width = int(size[0])
- #self.height = int(size[1])
- #self.posx = int(size[2])
- #self.posy = int(size[3])
- elif self.connected and self.width < 0:
- size = re.split('x', tokens[0])
- if len(size) == 2:
- self.width = int(size[0])
- self.height = int(size[1])
-
-
-def parse():
- outputs = []
- output = OutputInfo()
- p = subprocess.check_output('xrandr')
- for line in p.split('\n'):
- output.parse(line)
- if output.complete():
- outputs.append(output.asDict())
- output.clear()
- return outputs
-
-
-def xrandr_on(output):
- command = ['xrandr', '--output', output['name'], '--auto', '--pos',
- '%dx0' % output['posx']]
- if output['posx'] == 0:
- command += ['--primary']
- if not dry_run:
- print 'xrandr_on:', command
- subprocess.call(command)
- else:
- print '(dry-run) xrandr_on:', command
-
-
-def xrandr_off(output):
- command = ['xrandr', '--output', output['name'], '--off']
- if not dry_run:
- subprocess.call(command)
- print 'xrandr_off:', command
- else:
- print '(dry-run) xrandr_off:', command
-
-
-def output_by_name(outputs, name):
- for output in outputs:
- if output['name'] == name:
- return output
- return None
-
-
-if __name__ == '__main__':
- def print_output(output):
- print 'name:%s connected:%r enabled:%r width:%d height:%d pos:%dx%d' % (
- output['name'], output['connected'], output['enabled'],
- output['width'], output['height'], output['posx'],
- output['posy'])
-
- def print_outputs(header, outputs):
- print '%s:' % header
- for output in outputs:
- print_output(output)
- print
-
- def all_done(outputs):
- for output in outputs:
- if not output['done']:
- return False
- return True
-
- def disable_an_entry(outputs):
- for output in outputs:
- if not output['done'] and not output['use'] and output['enabled']:
- xrandr_off(output)
- output['done'] = True
- return 1
- return 0
-
- def enable_an_entry(outputs):
- enables = 0
- for output in reversed(outputs):
- if not output['done'] and output['use']:
- xrandr_on(output)
- output['done'] = True
- return 1
- return 0
-
- def main(argv):
- global dry_run
- if len(argv) >= 2 and argv[1] == '--dry-run':
- dry_run = True
-
- outputs = parse()
- print_outputs('Outputs', outputs)
-
- # Find the first two connected devices, in reverse list order. On the
- # Thinkpad X201, the reversed list order is the preferred order of
- # precedence, highest quality external display first, down to internal
- # LVDS panel used as a last resort. Also find new posx values.
- use_count = 0
- posx = 0
- for output in reversed(outputs):
- if output['connected']:
- print 'use', output['name']
- output['use'] = True
- output['posx'] = posx
- posx += output['width']
- use_count += 1
- if use_count >= 2:
- break
-
- # How many outputs are currently enabled?
- enabled_count = 0
- for output in outputs:
- if output['enabled']:
- enabled_count += 1
-
- # Mark outputs that receive no change as done
- for output in outputs:
- if not output['use'] and not output['enabled']:
- # Nothing to do for this output, mark as done
- output['done'] = True
-
- while not all_done(outputs):
- if enabled_count > 1:
- enabled_count -= disable_an_entry(outputs)
- if enabled_count < 2:
- enabled_count += enable_an_entry(outputs)
-
-
- main(sys.argv)