diff --git a/Makefile.am b/Makefile.am index b7710247..9781ca84 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,6 +31,9 @@ bin_PROGRAMS = \ openbox/openbox \ tools/gnome-panel-control/gnome-panel-control +bin_SCRIPTS = \ + tools/xdg-autostart/xdg-autostart + nodist_bin_SCRIPTS = \ data/xsession/openbox-session \ data/xsession/openbox-gnome-session \ diff --git a/data/autostart.sh b/data/autostart.sh index 4c635202..ab542841 100644 --- a/data/autostart.sh +++ b/data/autostart.sh @@ -30,3 +30,10 @@ fi if which start_kdeinit >/dev/null; then LD_BIND_NOW=true start_kdeinit --new-startup +kcminit_startup & fi + +# Run XDG autostart things. By default don't run anything desktop-specific +# See xdg-autostart --help more info +DESKTOP_ENV="" +if which xdg-autostart; then + xdg-autostart $DESKTOP_ENV +fi diff --git a/tools/xdg-autostart/xdg-autostart b/tools/xdg-autostart/xdg-autostart new file mode 100755 index 00000000..6cee1342 --- /dev/null +++ b/tools/xdg-autostart/xdg-autostart @@ -0,0 +1,192 @@ +#!/usr/bin/env python + +# xdg-autostart runs things based on the XDG autostart specification +# Copyright (C) 2008 Dana Jansens +# +# XDG autostart specification can be found here: +# http://standards.freedesktop.org/autostart-spec/ +# +# +# +# LICENSE: +# 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 2 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. + +ME="xdg-autostart" +VERSION="1.0" + +from xdg import BaseDirectory +from xdg.DesktopEntry import DesktopEntry +from xdg.Exceptions import ParsingError +import os, glob, sys + +def main(argv=sys.argv): + if "--help" in argv[1:]: + show_help() + return 0 + if "--version" in argv[1:]: + show_version() + return 0 + + # get the autostart directories + autodirs = BaseDirectory.load_config_paths("autostart") + + # find all the autostart files + files = [] + for dir in autodirs: + for path in glob.glob(os.path.join(dir, '*.desktop')): + try: + autofile = AutostartFile(path) + except ParsingError: + print "Invalid .desktop file: " + path + else: + if not autofile in files: + files.append(autofile) + + list = False + if "--list" in argv[1:]: + list = True + argv.remove("--list") + + # run them ! + environments = argv[1:] + for autofile in files: + if list: autofile.list(environments) + else: autofile.run(environments) + +class AutostartFile(): + def __init__(self, path): + self.path = path + self.filename = os.path.basename(path) + self.dirname = os.path.dirname(path) + self.de = DesktopEntry(path) + + def __eq__(self, other): + return self.filename == other.filename + + def __str__(self): + return self.path + " : " + self.de.getName() + + def isexecfile(path): + return os.access(path, os.X_OK) + + def findFile(self, path, search, match_func): + # check empty path + if not path: return None + # check absolute path + if path[0] == '/': + if match_func(path): return path + else: return None + # check relative path + for dirname in search.split(os.pathsep): + if dirname != "": + candidate = os.path.join(dirname, path) + if (match_func(candidate)): return candidate + + def alert(self, str, info=False): + if info: + print "\t ", str + else: + print "\t*", str + + def showInEnvironment(self, envs, verbose=False): + default = not self.de.getOnlyShowIn() + noshow = False + force = False + for i in self.de.getOnlyShowIn(): + if i in envs: force = True + for i in self.de.getNotShowIn(): + if i in envs: noshow = True + + if verbose: + if not default and not force: + s = "" + for i in self.de.getOnlyShowIn(): + if s: s += ", " + s += i + self.alert("Excluded by: OnlyShowIn (" + s + ")") + if default and noshow and not force: + s = "" + for i in self.de.getOnlyShowIn(): + if s: s += ", " + s += i + self.alert("Excluded by: NotShowIn (" + s + ")") + return (default and not noshow) or force + + def shouldRun(self, envs, verbose=False): + if not self.de.getExec(): + if verbose: self.alert("Excluded by: Missing Exec field") + return False + if self.de.getHidden(): + if verbose: self.alert("Excluded by: Hidden") + return False + if self.de.getTryExec(): + if not self.findFile(self.de.getTryExec(), os.getenv("PATH"), + self.isexecfile): + if verbose: self.alert("Excluded by: TryExec (" + + self.de.getTryExec() + ")") + return False + if not self.showInEnvironment(envs, verbose): + return False + return True + + def list(self, envs): + running = False + if self.shouldRun(envs): + print "[*] " + self.de.getName() + else: + print "[ ] " + self.de.getName() + self.alert("File: " + self.path, info=True) + if self.de.getExec(): + self.alert("Executes: " + self.de.getExec(), info=True) + self.shouldRun(envs, True) + print + + def run(self, envs): + here = os.getcwd() + if self.de.getPath(): + os.chdir(self.de.getPath()) + if self.shouldRun(envs): + print "Running autostart file: " + self.path + os.system(self.de.getExec()); + os.chdir(here) + +def show_help(): + print "Usage:", ME, "[OPTION]... [ENVIRONMENT]..." + print + print "This tool will run xdg autostart .desktop files" + print + print "OPTIONS" + print " --list Show a list of the files which would be run" + print " Files which would be run are marked with an asterix" + print " symbol [*]. For files which would not be run," + print " information is given for why they are excluded" + print " --help Show this help and exit" + print " --version Show version and copyright information" + print + print "ENVIRONMENT specifies a list of environments for which to run autostart" + print "applications for. If none are specified, only applications which do not " + print "limit themselves to certain environments will be run." + print + print "ENVIRONMENT can be one or more of:" + print " GNOME Gnome Desktop" + print " KDE KDE Desktop" + print " ROX ROX Desktop" + print " XFCE XFCE Desktop" + print " Old Legacy systems" + print + +def show_version(): + print ME, VERSION + print "Copyright (c) 2008 Dana Jansens" + print + +if __name__ == "__main__": + sys.exit(main())