Skip to content

Instantly share code, notes, and snippets.

@adamnew123456
Created October 29, 2011 04:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamnew123456/1324064 to your computer and use it in GitHub Desktop.
Save adamnew123456/1324064 to your computer and use it in GitHub Desktop.
PyRandR GTK - A small program to manage screen resolutions and positions
#!/usr/bin/python
#
# Copyright 2010 Adam Marchetti
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This exists because all other apps that claim to do the same thing
# (such as krandrtray) suck. This, by comparason, doesn't suck (too badly).
import gtk
import os
def button_create(name, func):
"Create and bind a button"
b = gtk.Button(name)
b.connect("clicked", func, None)
return b
class XRandRManager:
"Manages the interactions with XRandR and the main window"
def load_video_modes(self):
self.outputs = {}
lines = os.popen("xrandr -q").readlines()
curr = ""
for line in lines:
if " connected" in line:
# An activated monitor
curr = line.split()[0]
self.outputs[curr] = []
elif line.startswith(" " * 3):
# A mode
self.outputs[curr].append(line.split()[0])
def create_tabs(self):
self.load_video_modes()
nbook = gtk.Notebook()
for item in self.outputs:
tab = MonitorTab(item, self.outputs[item], self)
tab.show()
nbook.append_page(tab(), gtk.Label(item))
place = PlacementTab(self)
place.show()
nbook.append_page(place(), gtk.Label("Placement"))
nbook.show()
return nbook
def __call__(self):
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.set_title("GTK RandR")
win.add(self.create_tabs())
win.connect("destroy", lambda *data: gtk.main_quit(), None)
win.show()
gtk.main()
def setres(self, output, res):
"Set the resolution of a monitor"
os.system("xrandr --output {0} --mode {1}".format(output, res))
def off(self, scr):
"Turn a monitor off"
os.system("xrandr --output {0} --off".format(scr))
def setpos(self, output, typ, other):
"Set the position of a monitor relative to another"
os.system("xrandr --output {0} {1} {2}".format(output, typ, other))
class MonitorTab:
"A monitor snagged from xrandr"
def config(self, modes):
self.mview.append_column(gtk.TreeViewColumn("Modes", gtk.CellRendererText(), text=0))
for mode in modes:
self.mlist.append([mode])
self.mwind.add(self.mview)
self.vbox.pack_start(self.mwind, True, True, 0)
self.vbox.pack_start(self.hbox, False, False, 0)
self.hbox.pack_start(self.set, False, False, 0)
self.hbox.pack_start(self.off, False, False, 0)
def _getsel_(self):
_, sel = self.mview.get_selection().get_selected()
name = self.mlist.get_value(sel, 0)
return name
def __init__(self, name, modes, manager):
self.manager = manager
self.mlist = gtk.ListStore(str)
self.mview = gtk.TreeView(self.mlist)
self.mwind = gtk.ScrolledWindow()
self.set = button_create("Set Resoloution", self.setres)
self.off = button_create("Turn Off", self.off)
self.vbox = gtk.VBox()
self.hbox = gtk.HBox()
self.name = name
self.config(modes)
def setres(self, widget, data=None):
sel = self._getsel_()
self.manager.setres(self.name, sel)
def off(self, widget, data=None):
self.manager.off(self.name)
def __call__(self):
return self.vbox
def show(self):
self.vbox.show()
self.set.show()
self.off.show()
self.hbox.show()
self.mwind.show()
self.mview.show()
class PlacementTab:
"Place the various monitors"
def config(self):
self.mvcombo.set_popdown_strings(["Left Of", "Right Of", "Above", "Below"])
self.opcombo.set_popdown_strings([item for item in self.manager.outputs])
self.refcombo.set_popdown_strings([item for item in self.manager.outputs])
self.hbox.pack_start(self.opcombo, True, True, 0)
self.hbox.pack_start(self.mvcombo, True, True, 0)
self.hbox.pack_start(self.refcombo, True, True, 0)
self.vbox.pack_start(self.hbox, False, False, 0)
self.vbox.pack_start(self.set, False, False, 0)
def __init__(self, manager):
self.manager = manager
self.opcombo = gtk.Combo()
self.mvcombo = gtk.Combo()
self.refcombo = gtk.Combo()
self.set = button_create("Set Placement", self.setplace)
self.hbox = gtk.HBox()
self.vbox = gtk.VBox()
self.config()
def __call__(self):
return self.vbox
def setplace(self, widget, data=None):
op = self.opcombo.entry.get_text()
ref = self.refcombo.entry.get_text()
if op == ref:
return
mv = self.mvcombo.entry.get_text()
cmds = {'Right Of': "--right-of",
'Left Of': "--left-of",
'Above': "--above",
'Below': "--below"
}
self.manager.setpos(op, cmds[mv], ref)
def show(self):
self.vbox.show()
self.hbox.show()
self.set.show()
self.refcombo.show()
self.mvcombo.show()
self.opcombo.show()
XRandRManager()()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment