#!/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()