You are not logged in.
Link23 on #gimptalk gave me the idea for this. It shows an icon in the systemtray and it sets a random wallpaper from a directory. Only feh is supported at the moment, because I don't know how Gnome/KDE etc. do this.
The dependencies are Python, PyGTK and xdg-utils.
The code:
#!/usr/bin/env python
"""
ChangeWP sets a random wallpaper.
Licensed under the MIT License.
"""
__author__ = 'Frank Smit <61924.nl>'
__version__ = '0.1'
import os
import sys
import subprocess
from random import randint
from ConfigParser import SafeConfigParser
import pygtk
pygtk.require('2.0')
import gtk
import gobject
_xdg_config_home = os.getenv('XDG_CONFIG_HOME',
os.path.join(os.path.expanduser('~'), '.config'))
_default_config_path = os.path.join(_xdg_config_home, 'changewp.conf')
class Config:
"""A class for loading writing and changing configuration files."""
def __init__(self, default_config):
self.parser = SafeConfigParser(default_config)
self.parser.read(_default_config_path)
def __getitem__(self, option):
return self.parser.get('DEFAULT', option)
def __setitem__(self, option, value):
self.parser.set('DEFAULT', option, str(value))
def getint(self, option):
"""A convenience method for retrieving an integer option."""
return int(self.parser.get('DEFAULT', option))
def getbool(self, option):
"""A convenience method for retrieving a boolean option."""
return self.parser.get('DEFAULT', option) == 'True'
def save(self):
"""Write all the settings to the config file."""
with open(_default_config_path, 'w') as f:
self.parser.write(f)
class ChangeWP(gtk.StatusIcon):
"""The main class."""
last_index = None
wallpapers = []
def __init__(self, arguments):
"""Load configuration, read wallpaper directory, restores the last
wallpaper create widgets and enter GTK the main loop."""
# Load config
self.cfg = Config({
'wallpaper_dir': os.path.expanduser('~/'),
'last_wallpaper': ''
})
# Read wallpaper directory
gobject.idle_add(self.read_directory)
# Restore last wallpaper
if self.cfg['last_wallpaper']:
self.set_wallpaper()
# Popup menu
self.menu = gtk.Menu()
menu_open = gtk.ImageMenuItem(gtk.STOCK_OPEN)
menu_about = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
menu_quit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
menu_open.connect('button-press-event', self._open)
menu_about.connect('button-press-event', self._about)
menu_quit.connect('button-press-event', self._quit)
self.menu.append(menu_open)
self.menu.append(menu_about)
self.menu.append(menu_quit)
# Systemtray icon
gtk.StatusIcon.__init__(self)
self.set_from_stock(gtk.STOCK_REFRESH)
self.set_tooltip('ChangeWP')
self.connect('activate', self._activate_icon)
self.connect('popup-menu', self._popup_menu)
self.set_visible(True)
gtk.main()
def read_directory(self):
"""Read all image files from the wallpaper directory."""
self.wallpapers = [filename for filename in os.listdir(
self.cfg['wallpaper_dir'])
if (filename.lower().endswith('jpg')
or filename.lower().endswith('png')
or filename.lower().endswith('gif'))]
def set_wallpaper(self):
"""Set a wallpaper."""
subprocess.call(['feh', '--bg-tile', self.cfg['last_wallpaper']])
def _activate_icon(self, widget):
"""Change the current wallpaper to a random wallpaper."""
if not self.wallpapers:
return
# Count wallpapers and choose an index
wallpaper_count = len(self.wallpapers)-1
index = randint(0, wallpaper_count)
# If the randint chooses the same index as the last one we run it again
if wallpaper_count > 0 and index == self.last_index:
index = randint(0, wallpaper_count)
# Save the index
self.last_index = index
# Set 'last_wallpaper'
self.cfg['last_wallpaper'] = os.path.join(
self.cfg['wallpaper_dir'],
self.wallpapers[self.last_index])
# Change current wallpaper
self.set_wallpaper()
def _popup_menu(self, widget, button, time):
"""Show a popup menu."""
# Only show the menu when the righ mouse button is clicked
if button == 3:
if self.menu:
self.menu.show_all()
self.menu.popup(None, None, None, 3, time)
def _open(self, widget, event):
"""Choose and set the wallpaper directory."""
dialog = gtk.FileChooserDialog(
title='Choose your wallpaper directory...',
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_current_folder(self.cfg['wallpaper_dir'])
dialog.set_default_response(gtk.RESPONSE_OK)
response = dialog.run()
if response == gtk.RESPONSE_OK:
self.cfg['wallpaper_dir'] = dialog.get_filename()
gobject.idle_add(self.read_directory)
dialog.destroy()
def _about(self, widget, event):
"""Show the about window."""
def _open_url(url):
subprocess.call(['xdg-open', url])
dialog = gtk.AboutDialog()
gtk.about_dialog_set_url_hook(_open_url)
dialog.set_name('ChangeWP')
dialog.set_version(__version__)
dialog.set_authors([__author__])
dialog.set_website('http://61924.nl/')
dialog.set_comments('ChangeWP sets a random wallpaper.')
dialog.run()
dialog.destroy()
def _quit(self, widget, event):
"""Save the configuration and quit the program."""
self.cfg.save()
gtk.main_quit()
if __name__ == '__main__':
# Create a changewp dir in ~/.config if it doesn't exist
if not os.path.isdir(_xdg_config_home):
os.makedirs(_xdg_config_home, mode=0700)
try:
ChangeWP(sys.argv[1:])
except KeyboardInterrupt:
print ' Exiting ChangeWP...'
sys.exit(0)
The README:
ChangeWP
========
ChangeWP sets a random wallpaper.
Installation
============
Install Python, PyGTK and xdg-utils.
Make the script executable and execute it. Then click with the right mouse button on
the icon that appeared in your systemtray and click on "Open" and choose a
directory that contains your wallpapers. Done.
To do
=====
- Support for more wallpaper setters, e.g. KDE, Gnome/Gconf, Xubuntu/Xfconf
and other commandline wallpaper setters.
Only feh is supported at the moment.
- "Change wallpaper each ?? minutes" option.
Resources
=========
- Changing a wallpaper with Gconf:
http://library.gnome.org/admin/system-admin-guide/stable/gconf-9.html.en#gconf-20
- Change wallpaper with Xfconf:
http://ubuntuforums.org/showpost.php?p=8046115&postcount=2
- Change wallpaper in KDE:
http://usalug.org/phpBB2/viewtopic.php?t=9821
License
=======
Copyright (c) 2010 Frank Smit
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
Offline
This can also be realized this way (.xinitrc):
while :; do
feh --bg-center "$(find /path/to/dir -type f | shuf -n1)"
sleep 15m
done &
Offline
Heh, nice. That's much simpler. I always directly try to make something in Python.
My script only changes the wallpaper when you click on the systray icon. I didn't add the interval stuff yet.
Offline