# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import os, re, subprocess
-from selector_window import PositionSelection
import gui
# for auto-config: common names of internal connectors
commonInternalConnectorNames = ['LVDS', 'LVDS0', 'LVDS1', 'LVDS-0', 'LVDS-1']
+# this is as close as one can get to an enum in Python
+class RelativeScreenPosition:
+ LEFT = 0
+ RIGHT = 1
+ EXTERNAL_ONLY = 2
+
# Load a section-less config file: maps parameter names to space-separated lists of strings (with shell quotation)
def loadConfigFile(file):
import shlex
def getXrandrInformation():
p = subprocess.Popen(["xrandr", "-q"], stdout=subprocess.PIPE)
connectors = {} # map of connector names to a list of resolutions
- try:
- connector = None # current connector
- for line in p.stdout:
- # screen?
- m = re.search(r'^Screen [0-9]+: ', line)
- if m is not None: # ignore this line
- connector = None
- continue
- # new connector?
- m = re.search(r'^([\w\-]+) (dis)?connected ', line)
- if m is not None:
- connector = m.groups()[0]
- assert connector not in connectors
- connectors[connector] = []
- continue
- # new resolution?
- m = re.search(r'^ ([\d]+)x([\d]+) +', line)
- if m is not None:
- assert connector is not None
- connectors[connector].append((int(m.groups()[0]), int(m.groups()[1])))
- continue
- # unknown line
- raise Exception("Unknown line in xrandr output:\n"+line)
- finally:
- # be sure to always proprly finish up with the xrandr
- p.communicate()
+ connector = None # current connector
+ for line in p.stdout:
+ # screen?
+ m = re.search(r'^Screen [0-9]+: ', line)
+ if m is not None: # ignore this line
+ connector = None
+ continue
+ # new connector?
+ m = re.search(r'^([\w\-]+) (dis)?connected ', line)
+ if m is not None:
+ connector = m.groups()[0]
+ assert connector not in connectors
+ connectors[connector] = []
+ continue
+ # new resolution?
+ m = re.search(r'^ ([\d]+)x([\d]+) +', line)
+ if m is not None:
+ assert connector is not None
+ connectors[connector].append((int(m.groups()[0]), int(m.groups()[1])))
+ continue
+ # unknown line
+ # not fatal as my xrandr shows strange stuff when a display is enabled, but not connected
+ #raise Exception("Unknown line in xrandr output:\n"+line)
+ print "Warning: Unknown xrandr line %s" % line
+ # be sure to always proprly finish up with the xrandr
+ p.communicate()
# if everything succeededso far, check return code
if p.returncode != 0: raise Exception("Querying xrandr for data failed.")
return connectors
externalConnectors = config['externalConnectors']
for connector in externalConnectors:
if not connector in connectors:
- raise Exception("Connector %s does not exist, there is an error in your config file." % internalConnector)
+ raise Exception("Connector %s does not exist, there is an error in your config file." % connector)
+ if connector == internalConnector:
+ raise Exception("%s is both internal and external, that doesn't make sense." % connector)
else:
externalConnectors = connectors.keys()
externalConnectors.remove(internalConnector)
if usedExternalConnector is not None: # there's an external screen connected, we need to ask what to do
internalResolutions = connectors[internalConnector]
externalResolutions = connectors[usedExternalConnector]
- extPosition = PositionSelection(usedExternalConnector, map(res2user, internalResolutions), map(res2user, externalResolutions))
- extPosition.exec_()
- if not extPosition.result(): sys.exit(1) # the user canceled
- extResolution = res2xrandr(externalResolutions[extPosition.extResolutions.currentIndex()])
- intResolution = res2xrandr(internalResolutions[extPosition.intResolutions.currentIndex()])
+ dialogue = gui.getDialogue(usedExternalConnector, map(res2user, internalResolutions), map(res2user, externalResolutions))
+ if not dialogue.run(): sys.exit(1) # the user canceled
+ extResolution = res2xrandr(externalResolutions[dialogue.getExtResolutionIndex()])
+ intResolution = res2xrandr(internalResolutions[dialogue.getIntResolutionIndex()])
+ relPosition = dialogue.getRelativeScreenPosition()
# build command-line
args[usedExternalConnector] = ["--mode", extResolution] # set external screen to desired resolution
- if extPosition.extOnly.isChecked():
+ if relPosition == RelativeScreenPosition.EXTERNAL_ONLY:
args[usedExternalConnector] += ["--primary"]
else:
# there are two screens
args[internalConnector] = ["--mode", intResolution] # set internal screen to desired resolution
# set position
- if extPosition.posLeft.isChecked():
+ if relPosition == RelativeScreenPosition.LEFT:
args[usedExternalConnector] += ["--left-of", internalConnector]
else:
args[usedExternalConnector] += ["--right-of", internalConnector]
# set primary screen
- if extPosition.primExt.isChecked():
+ if dialogue.externalIsPrimary():
args[usedExternalConnector] += ["--primary"]
else:
args[internalConnector] += ["--primary"]