Created
October 29, 2011 04:17
-
-
Save adamnew123456/1324064 to your computer and use it in GitHub Desktop.
PyRandR GTK - A small program to manage screen resolutions and positions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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