all repos — openbox @ bcc31faf7ecd8b0ad3b66a75fc72145e93e6c35a

openbox fork - make it a bit more like ryudo

revamp the autostart functionality, so autostart apps launch after openbox.

add /usr/libexec/openbox-autostart which runs the global/user scripts and
  launches /usr/libexec/openbox-xdg-autostart (which runs .desktop autostart
  stuff)

make openbox-session call openbox with --startup option, to make openbox launch
  /usr/libexec/openbox-autostart *after* it is initialized.

add /etc/xdg/openbox/environment and ~/.config/openbox/environment files to let
  user change environment variables (locale) for their Openbox session, which
  openbox-session loads before running openbox.
Dana Jansens danakj@orodu.net
commit

bcc31faf7ecd8b0ad3b66a75fc72145e93e6c35a

parent

7d71fb8a77ba9e2ea4938e793410f029265507a8

M .gitignore.gitignore

@@ -97,5 +97,4 @@ tests/strut

tests/title tests/urgent tests/usertimewin -data/autostart.sh -<+ +data/autostart/openbox-autostart
M Makefile.amMakefile.am

@@ -12,7 +12,7 @@ obtpubincludedir= $(includedir)/openbox/@OBT_VERSION@/obt

rrpubincludedir = $(includedir)/openbox/@RR_VERSION@/obrender pixmapdir = $(datadir)/pixmaps xsddir = $(datadir)/openbox -secretbindir = $(libdir)/openbox +libexecdir = $(prefix)/libexec appsdir = $(datadir)/applications theme = Clearlooks

@@ -36,13 +36,19 @@ tools/gdm-control/gdm-control \

tools/gnome-panel-control/gnome-panel-control \ tools/obxprop/obxprop -dist_secretbin_SCRIPTS = \ - tools/xdg-autostart/xdg-autostart - nodist_bin_SCRIPTS = \ data/xsession/openbox-session \ data/xsession/openbox-gnome-session \ data/xsession/openbox-kde-session + +dist_rc_SCRIPTS = \ + data/environment \ + data/autostart/autostart + +dist_libexec_SCRIPTS = \ + data/autostart/openbox-xdg-autostart \ + data/autostart/openbox-autostart + ## obrender ##

@@ -446,9 +452,6 @@

dist_pixmap_DATA = \ data/openbox.png -nodist_rc_DATA = \ - data/autostart.sh - dist_rc_DATA = \ data/rc.xml \ data/menu.xml

@@ -456,10 +459,10 @@

edit = $(SED) \ -e 's!@version\@!$(VERSION)!' \ -e 's!@configdir\@!$(configdir)!' \ - -e 's!@secretbindir\@!$(secretbindir)!' \ + -e 's!@libexecdir\@!$(libexecdir)!' \ -e 's!@bindir\@!$(bindir)!' -data/autostart.sh: $(srcdir)/data/autostart.sh.in Makefile +data/autostart/openbox-autostart: $(srcdir)/data/autostart/openbox-autostart.in Makefile @echo make: creating $@ @$(edit) $< >$@

@@ -488,7 +491,6 @@ data/xsession/openbox-gnome.desktop \

data/xsession/openbox-kde.desktop dist_noinst_DATA = \ - data/autostart.sh.in \ data/rc.xsd \ data/menu.xsd \ data/xsession/openbox.desktop.in \
D data/autostart.sh.in

@@ -1,44 +0,0 @@

-# This shell script is run before Openbox launches. -# Environment variables set here are passed to the Openbox session. - -# Set a background color -BG="" -if which hsetroot >/dev/null; then - BG=hsetroot -else - if which esetroot >/dev/null; then - BG=esetroot - else - if which xsetroot >/dev/null; then - BG=xsetroot - fi - fi -fi -test -z $BG || $BG -solid "#303030" - -# D-bus -if which dbus-launch >/dev/null && test -z "$DBUS_SESSION_BUS_ADDRESS"; then - eval `dbus-launch --sh-syntax --exit-with-session` -fi - -# Make GTK apps look and behave how they were set up in the gnome config tools -if test -x /usr/libexec/gnome-settings-daemon >/dev/null; then - /usr/libexec/gnome-settings-daemon & -elif which gnome-settings-daemon >/dev/null; then - gnome-settings-daemon & -# Make GTK apps look and behave how they were set up in the XFCE config tools -elif which xfce-mcs-manager >/dev/null; then - xfce-mcs-manager n & -fi - -# Preload stuff for KDE apps -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="OPENBOX" -if which @secretbindir@/xdg-autostart >/dev/null; then - @secretbindir@/xdg-autostart $DESKTOP_ENV -fi
A data/autostart/Makefile

@@ -0,0 +1,4 @@

+all clean install: + $(MAKE) -C .. -$(MAKEFLAGS) $@ + +.PHONY: all clean install
A data/autostart/autostart

@@ -0,0 +1,17 @@

+# +# These things are run when an Openbox X Session is started. +# You may place a similar script in $HOME/.config/openbox/autostart +# to run user-specific things. +# + +# If you want to use GNOME config tools... +# +#if test -x /usr/libexec/gnome-settings-daemon >/dev/null; then +# /usr/libexec/gnome-settings-daemon & +#elif which gnome-settings-daemon >/dev/null; then +# gnome-settings-daemon & +#fi + +# If you want to use XFCE config tools... +# +#xfce-mcs-manager &
A data/autostart/openbox-autostart.in

@@ -0,0 +1,34 @@

+#!/bin/sh + +# Set a background color +BG="" +if which hsetroot >/dev/null; then + BG=hsetroot +elif which esetroot >/dev/null; then + BG=esetroot +elif which xsetroot >/dev/null; then + BG=xsetroot +fi +test -z $BG || $BG -solid "#303030" + +GLOBALAUTOSTART="@configdir@/autostart" +AUTOSTART="${XDG_CONFIG_HOME:-"$HOME/.config"}/openbox/autostart" + +# Run the global openbox autostart script +if test -f $GLOBALAUTOSTART; then + sh $GLOBALAUTOSTART +elif test -f $GLOBALAUTOSTART.sh; then + sh $GLOBALAUTOSTART.sh +fi + +# Run the user openbox autostart script +if test -f $AUTOSTART; then + sh $AUTOSTART +elif test -f $AUTOSTART.sh; then + sh $AUTOSTART.sh +fi + +# Run the XDG autostart stuff. These are found in /etc/xdg/autostart and +# in $HOME/.config/autostart. This requires PyXDG to be installed. +# See openbox-xdg-autostart --help for more details. +@libexecdir@/openbox-xdg-autostart OPENBOX
A data/autostart/openbox-xdg-autostart

@@ -0,0 +1,198 @@

+#!/usr/bin/env python + +# openbox-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="openbox-xdg-autostart" +VERSION="1.1" + +import os, glob, sys +try: + from xdg import BaseDirectory + from xdg.DesktopEntry import DesktopEntry + from xdg.Exceptions import ParsingError +except ImportError: + print + print "ERROR:", ME, "requires PyXDG to be installed" + print + sys.exit(1) + +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.display(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(self, 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 + else: + # 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.getNotShowIn(): + 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 display(self, envs): + 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): + args = ["/bin/sh", "-c", "exec " + self.de.getExec()] + os.spawnv(os.P_NOWAIT, args[0], args); + 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. 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())
A data/environment

@@ -0,0 +1,10 @@

+# +# Set system-wide environment variables here for Openbox +# User-specific variables should be placed in $HOME/.config/openbox/environment +# + +# To set your language for displaying messages and time/date formats, use the following: +#LANG=en_CA.UTF8 + +# To set your keyboard layout, you need to modify your X config: +# http://www.google.com/search?q=how+to+set+keyboard+layout+xorg
M data/xsession/openbox-session.indata/xsession/openbox-session.in

@@ -12,15 +12,11 @@ xprop -root -remove _NET_NUMBER_OF_DESKTOPS \

-remove _NET_DESKTOP_NAMES \ -remove _NET_CURRENT_DESKTOP 2> /dev/null -AUTOSTART="${XDG_CONFIG_HOME:-"$HOME/.config"}/openbox/autostart.sh" -GLOBALAUTOSTART="@configdir@/openbox/autostart.sh" - -if test -r $AUTOSTART; then - . $AUTOSTART -else - if test -r $GLOBALAUTOSTART; then - . $GLOBALAUTOSTART - fi -fi +# Set up the environment +A="@configdir@/openbox/environment" +test -r $A && . $A +A="${XDG_CONFIG_HOME:-"$HOME/.config"}/openbox/environment" +test -r $A && . $A -exec @bindir@/openbox "$@" +# Run Openbox, and have it run the autostart stuff +exec @bindir@/openbox --startup "@libexecdir@/openbox-autostart OPENBOX" "$@"
M openbox/openbox.copenbox/openbox.c

@@ -102,6 +102,7 @@ static gint exitcode = 0;

static guint remote_control = 0; static gboolean being_replaced = FALSE; static gchar *config_file = NULL; +static gchar *startup_cmd = NULL; static void signal_handler(gint signal, gpointer data); static void remove_args(gint *argc, gchar **argv, gint index, gint num);

@@ -342,6 +343,29 @@ reconfigure = FALSE;

ob_set_state(OB_STATE_RUNNING); + if (startup_cmd) { + gchar **argv = NULL; + GError *e = NULL; + gboolean ok; + + if (!g_shell_parse_argv(startup_cmd, NULL, &argv, &e)) { + g_message("Error parsing startup command: %s", + e->message); + g_error_free(e); + e = NULL; + } + ok = g_spawn_async(NULL, argv, NULL, + G_SPAWN_SEARCH_PATH | + G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, NULL, &e); + if (!g_shell_parse_argv(startup_cmd, NULL, &argv, &e)) { + g_message("Error launching startup command: %s", + e->message); + g_error_free(e); + e = NULL; + } + } + /* look for parsing errors */ { xmlErrorPtr e = xmlGetLastError();

@@ -519,6 +543,7 @@ g_print(_(" --restart Restart Openbox\n"));

g_print(_(" --exit Exit Openbox\n")); g_print(_("\nDebugging options:\n")); g_print(_(" --sync Run in synchronous mode\n")); + g_print(_(" --startup CMD Run CMD after starting\n")); g_print(_(" --debug Display debugging output\n")); g_print(_(" --debug-focus Display debugging output for focus handling\n")); g_print(_(" --debug-session Display debugging output for session management\n"));

@@ -579,6 +604,18 @@ --i; /* this arg was removed so go back */

} else if (!strcmp(argv[i], "--sync")) { xsync = TRUE; + } + else if (!strcmp(argv[i], "--startup")) { + if (i == *argc - 1) /* no args left */ + g_printerr(_("--startup requires an argument\n")); + else { + /* this will be in the current locale encoding, which is + what we want */ + startup_cmd = argv[i+1]; + remove_args(argc, argv, i, 2); + --i; /* this arg was removed so go back */ + ob_debug("--startup %s", startup_cmd); + } } else if (!strcmp(argv[i], "--debug")) { ob_debug_enable(OB_DEBUG_NORMAL, TRUE);
D tools/xdg-autostart/Makefile

@@ -1,4 +0,0 @@

-all clean install: - $(MAKE) -C ../.. -$(MAKEFLAGS) $@ - -.PHONY: all clean install
D tools/xdg-autostart/xdg-autostart

@@ -1,198 +0,0 @@

-#!/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" - -import os, glob, sys -try: - from xdg import BaseDirectory - from xdg.DesktopEntry import DesktopEntry - from xdg.Exceptions import ParsingError -except ImportError: - print - print "ERROR:", ME, "requires PyXDG to be installed" - print - sys.exit(1) - -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.display(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(self, 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 - else: - # 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.getNotShowIn(): - 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 display(self, envs): - 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): - args = ["/bin/sh", "-c", "exec " + self.de.getExec()] - os.spawnv(os.P_NOWAIT, args[0], args); - 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. 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())