Skip to content

Commit

Permalink
merge parts of the cglita branch
Browse files Browse the repository at this point in the history
closes the most common arandr issue
  • Loading branch information
chrysn committed Feb 28, 2013
2 parents 123355d + b5d1446 commit dad11f9
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 22 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
* Merged parts of the cglita branch
- solves ValueError / "1080p" issue
* New translations:
- Ukrainian (by R-a-x)
- Hungarian (by Tamás Nagy)
Expand Down
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Please send bug reports, suggestions, patches and git pull requests to me_.
About
-----

Copyright © chrysn_ <chrysn@fsfe.org> 2008–2012, published under GPLv3_ or any later version.
Copyright © chrysn_ <chrysn@fsfe.org> 2008–2013, Себастьян Gli ţa Κατινα 2011, published under GPLv3_ or any later version.

Inspired by the `dual head sketch`_ in the ThinkWiki_.

Expand Down
1 change: 0 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ ARandR TODO list

* integrate xvattr for mirror mode (cf http://wiki.debian.org/XStrikeForce/HowToRandR12 section "XV Overlay on only one display") -- but is this still alive at all?
* integrate --randr-display in gui configuration and add more options than "DISPLAY=${} xrandr" (for example "ssh some-server xrandr", maybe even with zeroconf detection of ssh hosts, but i digress)
* rewrite parser to --verbose
* use distutils translation build system instead of custom one (compare hotot package)
* debian packaging: use dh_python2 (/ dh_python3) instead of python-support
* optional "timeout" for applying setting ("does this work? click ok, otherwise it will revert in...")
23 changes: 23 additions & 0 deletions screenlayout/auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ def __new__(cls, arg):
def __str__(self):
return "%dx%d"%self

class NamedSize(object):
"""Object that behaves like a size, but has an additional name attribute"""
def __init__(self, size, name):
self._size = size
self.name = name

width = property(lambda self:self[0])
height = property(lambda self:self[1])
def __str__(self):
if "%dx%d"%(self.width, self.height) in self.name:
return self.name
else:
return "%s (%dx%d)"%(self.name, self.width, self.height)

def __iter__(self):
return self._size.__iter__()

def __getitem__(self, i):
return self._size[i]

def __len__(self):
return 2

class Position(tuple):
"""2-tuple of left and top that can be created from a '<left>x<top>' string"""
def __new__(cls, arg):
Expand Down
2 changes: 1 addition & 1 deletion screenlayout/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
## (ein weiteres GUI für XRandR)" so users get both the explanation of
## the acronym and a localized version.
PROGRAMDESCRIPTION = _(u'Another XRandR GUI')
COPYRIGHT = u'© chrysn 2008 – 2012'
COPYRIGHT = u'© chrysn 2008 – 2013, Себастьян Gli ţa Κατινα 2011'

TRANSLATORS = [
'chrysn <chrysn@fsfe.org>',
Expand Down
6 changes: 3 additions & 3 deletions screenlayout/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def _draw(self, xrandr, cr):
o = cfg.outputs[on]
if not o.active: continue

rect = (o.tentative_position if hasattr(o, 'tentative_position') else o.position) + o.size
rect = (o.tentative_position if hasattr(o, 'tentative_position') else o.position) + tuple(o.size)
center = rect[0]+rect[2]/2, rect[1]+rect[3]/2

# paint rectangle
Expand Down Expand Up @@ -309,9 +309,9 @@ def _contextmenu(self, on):
if oc.active:
res_m = gtk.Menu()
for r in os.modes:
i = gtk.CheckMenuItem("%sx%s"%r)
i = gtk.CheckMenuItem(str(r))
i.props.draw_as_radio = True
i.props.active = (oc.mode == r)
i.props.active = (oc.mode.name == r.name)
def _res_set(menuitem, on, r):
try:
self.set_resolution(on, r)
Expand Down
59 changes: 43 additions & 16 deletions screenlayout/xrandr.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import subprocess
import warnings

from .auxiliary import BetterList, Size, Position, Geometry, FileLoadError, FileSyntaxError, InadequateConfiguration, Rotation, ROTATIONS, NORMAL
from .auxiliary import BetterList, Size, Position, Geometry, FileLoadError, FileSyntaxError, InadequateConfiguration, Rotation, ROTATIONS, NORMAL, NamedSize

import gettext
gettext.install('arandr')
Expand Down Expand Up @@ -91,6 +91,7 @@ def _load_from_commandlineargs(self, commandline):

for on,oa in options.items():
o = self.configuration.outputs[on]
os = self.state.outputs[on]
if oa == ['--off']:
o.active = False
else:
Expand All @@ -99,7 +100,12 @@ def _load_from_commandlineargs(self, commandline):
parts = [(oa[2*i],oa[2*i+1]) for i in range(len(oa)//2)]
for p in parts:
if p[0] == '--mode':
o.mode = Size(p[1])
for namedmode in os.modes:
if namedmode.name == p[1]:
o.mode = namedmode
break
else:
raise FileLoadError("Not a known mode: %s"%p[1])
elif p[0] == '--pos':
o.position = Position(p[1])
elif p[0] == '--rotate':
Expand All @@ -110,7 +116,7 @@ def _load_from_commandlineargs(self, commandline):
raise FileSyntaxError()
o.active = True

def load_from_x(self): # FIXME -- use --verbose or, better, a library
def load_from_x(self): # FIXME -- use a library
self.configuration = self.Configuration()
self.state = self.State()

Expand All @@ -134,34 +140,55 @@ def load_from_x(self): # FIXME -- use --verbose or, better, a library

geometry = Geometry(hsplit[2])

if hsplit[3] in ROTATIONS: rotation = Rotation(hsplit[3])
modeid = hsplit[3].strip("()")

if hsplit[4] in ROTATIONS: rotation = Rotation(hsplit[4])
else: rotation = NORMAL
else:
active = False
geometry = None
modeid = None
rotation = None

o.rotations = set()
for r in ROTATIONS:
if r in headline:
o.rotations.add(r)

for d in details:
o.modes.append(Size(int(a) for a in d.strip().split(" ")[0].split("x")))
current = None
for d, w, h in details:
n, m = d[0:2]
k = m.strip("()")
try:
r = Size([int(w), int(h)])
except ValueError:
raise Exception("Output %s parse error: modename %s modeid %s."%(o.name, n,k))
if "*current" in d:
currentname = n
for x in [ "+preferred", "*current" ]:
if x in d: d.remove(x)
o.modes.append(NamedSize(r, name=n))

self.state.outputs[o.name] = o
self.configuration.outputs[o.name] = self.configuration.OutputConfiguration(active, geometry, rotation)
self.configuration.outputs[o.name] = self.configuration.OutputConfiguration(active, geometry, rotation, currentname)

def _load_raw_lines(self):
output = self._output("-q")
output = self._output("--verbose")
items = []
screenline = None
for l in output.split('\n'):
if l.startswith("Screen "):
assert screenline is None
screenline = l
elif l.startswith(" "): # mode
items[-1][1].append(l)
elif l.startswith('\t'):
continue
elif l.startswith(2*' '): # [mode, width, height]
l = l.strip()
if reduce(bool.__or__, [l.startswith(x+':') for x in "hv"]):
l = l[-len(l):l.index(" start")-len(l)]
items[-1][1][-1].append(l[l.rindex(' '):])
else: # mode
items[-1][1].append([l.split()])
else:
items.append([l, []])
return screenline, items
Expand Down Expand Up @@ -248,7 +275,7 @@ def __repr__(self):
return '<%s %r (%d modes)>'%(type(self).__name__, self.name, len(self.modes))

class Configuration(object):
"""Represents everything that can be set by xrand (and is therefore subject to saving and loading from files)"""
"""Represents everything that can be set by xrandr (and is therefore subject to saving and loading from files)"""
def __init__(self):
self.outputs = {}

Expand All @@ -264,21 +291,21 @@ def commandlineargs(self):
args.append("--off")
else:
args.append("--mode")
args.append(str(o.mode))
args.append(str(o.mode.name))
args.append("--pos")
args.append(str(o.position))
args.append("--rotate")
args.append(o.rotation)
return args

class OutputConfiguration(object):
def __init__(self, active, geometry, rotation):
def __init__(self, active, geometry, rotation, modename):
self.active = active
if active:
self.position = geometry.position
self.rotation = rotation
if rotation.is_odd:
self.mode = Size(reversed(geometry.size))
self.mode = NamedSize(Size(reversed(geometry.size)), name=modename)
else:
self.mode = geometry.size
size = property(lambda self: Size(reversed(self.mode)) if self.rotation.is_odd else self.mode)
self.mode = NamedSize(geometry.size, name=modename)
size = property(lambda self: NamedSize(Size(reversed(self.mode)), name=self.mode.name) if self.rotation.is_odd else self.mode)

0 comments on commit dad11f9

Please sign in to comment.