rendered paste body#!/usr/bin/env python
# needs python2.4, pygtk and PIL
import os
import urlparse
import urllib
import subprocess
import gtk
import gtk.gdk
import gtk.glade
import gconf
import Image
import dualpaper
TARGET_STRING = 0
DND_TARGETS = [ ('STRING', 0, TARGET_STRING), ]
def get_resolutions():
"""Return the sizes of the two monitors."""
screen = gtk.gdk.screen_get_default()
n = screen.get_n_monitors()
rect = screen.get_monitor_geometry(0)
w, h = rect.width, rect.height
if n == 1: # Single head
return (w, h), (w, h)
rect = screen.get_monitor_geometry(1)
return (w, h), (rect.width, rect.height)
def scale_maintaining_aspect(size, bbox):
w, h = size
bbox_w, bbox_h = bbox
w1, h1 = bbox_w, h * bbox_w / w
w2, h2 = w * bbox_h / h, bbox_h
if h1 <= bbox_h:
return w1, h1
else:
assert w2 <= bbox_w
return w2, h2
class GConfClient(object):
def __init__ (self):
self.client = gconf.client_get_default()
def get_background(self):
return self.client.get_string ("/desktop/gnome/background/picture_filename")
def set_background(self, background, options='wallpaper'):
self.client.set_string ("/desktop/gnome/background/picture_filename", background)
self.client.set_string ("/desktop/gnome/background/picture_options", options)
class DualPaper(object):
thumbnail_bbox = (128, 128)
def __init__(self):
self.resolutions = get_resolutions()
self.basedir = os.path.dirname(os.path.abspath(__file__))
self.emptyfile = os.path.join(self.basedir, 'empty.png')
self.outputfile = os.path.join(self.basedir, 'dualhead-wallpaper.jpg')
self.thumbnail_sizes = [scale_maintaining_aspect(size,
self.thumbnail_bbox)
for size in self.resolutions]
xml = gtk.glade.XML(os.path.join(self.basedir, 'dualpaper.glade'))
window = xml.get_widget('main_window')
window.show()
window.connect('destroy', lambda *a: gtk.main_quit())
self.images = [xml.get_widget('left_image'),
xml.get_widget('right_image')]
self.filenames = [self.emptyfile] * len(self.images)
for idx, image in enumerate(self.images):
image.set_from_file(self.emptyfile)
image.drag_dest_set(gtk.DEST_DEFAULT_ALL, DND_TARGETS,
gtk.gdk.ACTION_COPY)
image.connect('drag_data_received', self.drag_data_received, idx)
save_button = xml.get_widget('save_button')
save_button.connect('clicked', self.save_button_clicked)
set_as_wallpaper_button = xml.get_widget('set_as_wallpaper_button')
set_as_wallpaper_button.connect('clicked',
self.set_as_wallpaper_button_clicked)
def drag_data_received(self, img, context, x, y, data, info, time,
which):
print '%s: %r' % (which, data.data, )
url = data.data.strip()
filename = urllib.url2pathname(urlparse.urlsplit(url)[2])
img = dualpaper.load_and_resize(filename, self.thumbnail_sizes[which])
pixbuf = gtk.gdk.pixbuf_new_from_data(img.tostring(),
gtk.gdk.COLORSPACE_RGB, False, 8,
img.size[0], img.size[1],
3 * img.size[0])
self.images[which].set_from_pixbuf(pixbuf)
self.filenames[which] = filename
def save_button_clicked(self, widget):
print 'saving'
dualpaper.make_wallpaper(resolution=self.resolutions,
left_inputfile=self.filenames[0],
right_inputfile=self.filenames[1],
outputfile=self.outputfile)
def set_as_wallpaper_button_clicked(self, widget):
self.save_button_clicked(widget)
print 'wallpapering'
gconf = GConfClient()
if gconf.get_background() == self.outputfile:
# Stupid GNOME does not notice when I overwrite the file
otheroutputfile = self.outputfile.replace('.jpg', '-1.jpg')
try:
os.unlink(otheroutputfile)
except OSError:
pass
os.link(self.outputfile, otheroutputfile)
gconf.set_background(otheroutputfile)
else:
gconf.set_background(self.outputfile)
if __name__ == '__main__':
DualPaper()
gtk.main()