From: Dana Jansens Date: Fri, 25 May 2007 18:03:40 +0000 (+0000) Subject: first add of obconf stuff. probably missing a lot still X-Git-Tag: release-2.0.2~195 X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=9bc7f7a548b53d8d741cffd91afb8d3ec6884563;p=dana%2Fobconf.git first add of obconf stuff. probably missing a lot still --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..15bc113 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +ObConf is written by: + + - Dana Jansens (danakj@orodu.net) + - Initial code. + - Tim Riley (tr@slackzone.org) + - HIG adherence changes. + - Interface improvements. + - Maintainence. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..2f6445f --- /dev/null +++ b/Makefile.am @@ -0,0 +1,83 @@ +SUBDIRS = po + +localedir = $(datadir)/locale +gladedir = $(datadir)/obconf +pixmapdir = $(datadir)/pixmaps +themedir = $(datadir)/openbox/themes +desktopdir = $(datadir)/applications + +AUTOMAKE_OPTIONS = subdir-objects +ACLOCAL_AMFLAGS = -I m4 + +bin_PROGRAMS = \ + src/obconf + +src_obconf_CPPFLAGS = \ + $(OBLIBS_CFLAGS) \ + $(STARTUP_CFLAGS) \ + $(GTK_CFLAGS) \ + $(GLADE_CFLAGS) \ + $(GDK_PIXBUF_CFLAGS) \ + $(XML_CFLAGS) \ + -DLOCALEDIR=\"$(localedir)\" \ + -DPIXMAPDIR=\"$(pixmapdir)\" \ + -DGLADEDIR=\"$(gladedir)\" \ + -DTHEMEDIR=\"$(themedir)\" \ + -DG_LOG_DOMAIN=\"Obconf\" +src_obconf_LDADD = \ + $(OBLIBS_LIBS) \ + $(STARTUP_LIBS) \ + $(GTK_LIBS) \ + $(GLADE_LIBS) \ + $(GDK_PIXBUF_LIBS) \ + $(LIBINTL) +src_obconf_SOURCES = \ + src/gettext.h \ + src/main.c \ + src/main.h \ + src/handlers.c \ + src/handlers.h \ + src/tree.c \ + src/tree.h + +dist_glade_DATA = \ + src/obconf.glade + +dist_noinst_DATA = \ + src/obconf.gladep + +dist_desktop_DATA = \ + obconf.desktop + +EXTRA_DIST = \ + config.rpath \ + mkinstalldirs \ + README \ + COPYING \ + AUTHORS \ + m4/codeset.m4 \ + m4/gettext.m4 \ + m4/glibc21.m4 \ + m4/iconv.m4 \ + m4/intdiv0.m4 \ + m4/inttypes-pri.m4 \ + m4/inttypes.m4 \ + m4/inttypes_h.m4 \ + m4/isc-posix.m4 \ + m4/lcmessage.m4 \ + m4/lib-ld.m4 \ + m4/lib-link.m4 \ + m4/lib-prefix.m4 \ + m4/nls.m4 \ + m4/po.m4 \ + m4/progtest.m4 \ + m4/stdint_h.m4 \ + m4/uintmax_t.m4 \ + m4/ulonglong.m4 \ + debian/changelog.in \ + debian/compat \ + debian/control \ + debian/menu \ + debian/rules \ + config.rpath + diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..6a5b10f --- /dev/null +++ b/bootstrap @@ -0,0 +1,18 @@ +#! /bin/sh + +sh() { + /bin/sh -c "set -x; $*" +} + +export WANT_AUTOMAKE=1.9 + +sh autopoint --force || exit 1 # for GNU gettext +sh libtoolize --copy --force --automake || exit 1 +sh aclocal -I m4 $ACLOCAL_FLAGS || exit 1 +#sh autoheader || exit 1 +sh autoconf || exit 1 +sh automake --include-deps --add-missing --copy || exit 1 + +echo +echo You are now ready to run ./configure +echo enjoy! diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..895f400 --- /dev/null +++ b/configure.ac @@ -0,0 +1,49 @@ +AC_PREREQ([2.54]) +AC_INIT([obconf], [1.6.2], [http://bugzilla.icculus.org]) +AM_INIT_AUTOMAKE +AC_CONFIG_SRCDIR([src/main.c]) + +AC_PREFIX_DEFAULT([/usr/local]) +test "$prefix" = "NONE" && prefix=$ac_default_prefix + +# Pick compiler specific/build target flags, and set $CVS +AM_PROG_CC_C_O +AC_C_CONST +AC_C_INLINE + +AC_PROG_INSTALL + +LDFLAGS="$LDFLAGS -export-dynamic" + +ALL_LINGUAS="" +AM_GNU_GETTEXT_VERSION(0.15) +AM_GNU_GETTEXT([external]) + +PKG_CHECK_MODULES(OBLIBS, [obrender-3.0 obparser-3.0]) +AC_SUBST(OB_CFLAGS) +AC_SUBST(OB_LIBS) + +PKG_CHECK_MODULES(STARTUP, [libstartup-notification-1.0]) +AC_SUBST(STARTUP_CFLAGS) +AC_SUBST(STARTUP_LIBS) + +PKG_CHECK_MODULES(GTK, [gtk+-2.0]) +AC_SUBST(GTK_CFLAGS) +AC_SUBST(GTK_LIBS) + +PKG_CHECK_MODULES(GDK_PIXBUF, [gdk-pixbuf-2.0]) +AC_SUBST(GDK_PIXBUF_CFLAGS) +AC_SUBST(GDK_PIXBUF_LIBS) + +PKG_CHECK_MODULES(GLADE, [libglade-2.0]) +AC_SUBST(GLADE_CFLAGS) +AC_SUBST(GLADE_LIBS) + +AC_CONFIG_FILES([ + Makefile + po/Makefile.in +]) +AC_OUTPUT + +AC_MSG_RESULT +AC_MSG_RESULT([configure complete, now type \"make\"]) diff --git a/debian/changelog.in b/debian/changelog.in new file mode 100644 index 0000000..c943a77 --- /dev/null +++ b/debian/changelog.in @@ -0,0 +1,6 @@ +obconf (@version@) unstable; urgency=low + + * Upstream release + + -- Dana Jansens @time@ + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..2439a7c --- /dev/null +++ b/debian/control @@ -0,0 +1,11 @@ +Source: obconf +Section: x11 +Priority: optional +Maintainer: Dana Jansens +Standards-Version: 3.7.2 + +Package: obconf +Architecture: i386 +Depends: libc6, libgtk2.0-0, libglade2-0, openbox (>= 3.3.991), libstartup-notification0 +Recommends: obconf, ttf-bitstream-vera +Description: Openbox configuration tool diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/debian/copyright @@ -0,0 +1 @@ + diff --git a/debian/menu b/debian/menu new file mode 100644 index 0000000..fa3a412 --- /dev/null +++ b/debian/menu @@ -0,0 +1,6 @@ +?package(obconf):\ + needs="x11"\ + section="Apps/System"\ + title="ObConf"\ + command="/usr/bin/obconf"\ + icon="/usr/share/pixmaps/openbox.png" diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..65778f3 --- /dev/null +++ b/debian/rules @@ -0,0 +1,106 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + + +CFLAGS = -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +config.status: configure + dh_testdir + # Add here commands to configure the package. + ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --sysconfdir=/etc --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs" + + +build: build-stamp + +build-stamp: config.status + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) distclean +ifneq "$(wildcard /usr/share/misc/config.sub)" "" + cp -f /usr/share/misc/config.sub config.sub +endif +ifneq "$(wildcard /usr/share/misc/config.guess)" "" + cp -f /usr/share/misc/config.guess config.guess +endif + + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/obconf. + $(MAKE) DESTDIR=$(CURDIR)/debian/obconf install + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installchangelogs CHANGELOG +# dh_installdocs +# dh_installexamples +# dh_install + dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo +# dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/gettext.h b/gettext.h new file mode 100644 index 0000000..7bbc6a9 --- /dev/null +++ b/gettext.h @@ -0,0 +1,73 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +/* Custom macro to make life easier */ +#define _(str) gettext(str) + +#endif /* _LIBGETTEXT_H */ diff --git a/makedeb b/makedeb new file mode 100755 index 0000000..b4207f7 --- /dev/null +++ b/makedeb @@ -0,0 +1,33 @@ +#!/bin/sh + +if test "$1" = "ubuntu"; then + APPEND="ubuntu1"; +else + if test "$1" = "debian"; then + APPEND=""; + else + echo "Usage: makedeb [ubuntu|debian]"; + exit 1; + fi +fi + +# get the version from configure.ac +VERSION=$(grep AC_INIT\(\\\[obconf\\] configure.ac|cut -d [ -f 3-|cut -d ] -f 1) + +echo +echo "Building deb for obconf-$VERSION-0$APPEND" +echo + +TIME="$(date '+%a, %d %B %Y %T %z')" + +IN=debian/changelog.in +OUT=debian/changelog + +# make sure configure gets run with the right parameters +make distclean > /dev/null || rm -f config.status + +rm -f $OUT + +sed -e "s!@time@!$TIME!" -e "s!@version@!$VERSION-0$APPEND!" $IN >$OUT && \ +fakeroot debian/rules binary && \ +make distclean > /dev/null diff --git a/po/Makevars b/po/Makevars new file mode 100644 index 0000000..6335654 --- /dev/null +++ b/po/Makevars @@ -0,0 +1,41 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --from-code=iso-8859-1 + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Dana Jansens + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = http://bugzilla.icculus.org/ + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = diff --git a/po/POTFILES b/po/POTFILES new file mode 100644 index 0000000..3708239 --- /dev/null +++ b/po/POTFILES @@ -0,0 +1,4 @@ + ../src/strings.c \ + ../src/main.c \ + ../src/handlers.c \ + ../src/tree.c diff --git a/src/handlers.c b/src/handlers.c new file mode 100644 index 0000000..4306d27 --- /dev/null +++ b/src/handlers.c @@ -0,0 +1,1311 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + handlers.h for ObConf, the configuration tool for Openbox + Copyright (c) 2003 Dana Jansens + Copyright (c) 2003 Tim Riley + + 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. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include "main.h" +#include "tree.h" +#include "gettext.h" +#include "openbox/render.h" + +#include +#include +#include + +static gboolean mapping; +static GList *themes; +static GtkListStore *desktop_store; +static int num_desktops; +static GList *desktop_names; +static GtkListStore *theme_store; + +static void on_desktop_names_cell_edited(GtkCellRendererText *cell, + const gchar *path_string, + const gchar *new_text, + gpointer data); + +static void on_theme_names_selection_changed(GtkTreeSelection *sel, + gpointer data); + + +void setup_behavior_tab() +{ + GtkWidget *winresist = glade_xml_get_widget(glade, "resist_window"); + GtkWidget *edgeresist = glade_xml_get_widget(glade, "resist_edge"); + GtkSizeGroup *group1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + gtk_size_group_add_widget(group1, winresist); + gtk_size_group_add_widget(group1, edgeresist); + + GtkWidget *winresist_l = glade_xml_get_widget(glade, "resist_window_label"); + GtkWidget *edgeresist_l = glade_xml_get_widget(glade, "resist_edge_label"); + GtkSizeGroup *group2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + gtk_size_group_add_widget(group2, winresist_l); + gtk_size_group_add_widget(group2, edgeresist_l); +} + +void setup_dock_tab() +{ + GtkWidget *posi = glade_xml_get_widget(glade, "dock_position"); + GtkWidget *dir = glade_xml_get_widget(glade, "dock_direction"); + GtkSizeGroup *group1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + gtk_size_group_add_widget(group1, posi); + gtk_size_group_add_widget(group1, dir); + + GtkWidget *posi_l = glade_xml_get_widget(glade, "dock_position_label"); + GtkWidget *dir_l = glade_xml_get_widget(glade, "dock_direction_label"); + GtkSizeGroup *group2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + gtk_size_group_add_widget(group2, posi_l); + gtk_size_group_add_widget(group2, dir_l); +} + + + +gboolean on_main_window_delete_event(GtkWidget *w, GdkEvent *e, gpointer d) +{ + gtk_main_quit(); + return FALSE; +} + +void on_close_clicked() +{ + gtk_main_quit(); +} + +void on_about_clicked() +{ + GtkWidget *parent; + GtkWidget *about; + + parent = glade_xml_get_widget(glade, "main_window"); + about = glade_xml_get_widget(glade, "about_window"); + + gtk_window_set_transient_for(GTK_WINDOW(about), GTK_WINDOW(parent)); + gtk_widget_show(about); +} + +void on_about_close_clicked() +{ + GtkWidget *about; + + about = glade_xml_get_widget(glade, "about_window"); + + gtk_widget_hide(about); +} + +void on_about_window_delete_event() +{ + GtkWidget *about; + + about = glade_xml_get_widget(glade, "about_window"); + + gtk_widget_hide(about); +} + +void setup_focus_mouse(GtkWidget *w) +{ + gboolean b; + + mapping = TRUE; + + b = tree_get_bool("focus/followMouse", FALSE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), b); + + { + GtkWidget *delay = glade_xml_get_widget(glade, "focus_delay"); + GtkWidget *delay_l = glade_xml_get_widget(glade, "focus_delay_label"); + GtkWidget *delay_u = glade_xml_get_widget(glade, + "focus_delay_label_units"); + GtkWidget *raise = glade_xml_get_widget(glade, "focus_raise"); + gtk_widget_set_sensitive(delay, b); + gtk_widget_set_sensitive(delay_l, b); + gtk_widget_set_sensitive(delay_u, b); + gtk_widget_set_sensitive(raise, b); + } + + mapping = FALSE; +} + +void setup_focus_delay(GtkWidget *w) +{ + mapping = TRUE; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), + tree_get_int("focus/focusDelay", 0)); + mapping = FALSE; +} + +void setup_focus_raise(GtkWidget *w) +{ + mapping = TRUE; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), + tree_get_bool("focus/raiseOnFocus", FALSE)); + mapping = FALSE; +} + +void setup_focus_new(GtkWidget *w) +{ + mapping = TRUE; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), + tree_get_bool("focus/focusNew", TRUE)); + mapping = FALSE; +} + +void setup_place_mouse(GtkWidget *w) +{ + gchar *s; + + mapping = TRUE; + s = tree_get_string("placement/policy", "Smart"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), + !g_ascii_strcasecmp(s, "UnderMouse")); + g_free(s); + mapping = FALSE; +} + +void setup_resist_window(GtkWidget *w) +{ + mapping = TRUE; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), + tree_get_int("resistance/strength", 10)); + mapping = FALSE; +} + +void setup_resist_edge(GtkWidget *w) +{ + mapping = TRUE; + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), + tree_get_int("resistance/screen_edge_strength", + 20)); + mapping = FALSE; +} + +void setup_resize_contents(GtkWidget *w) +{ + mapping = TRUE; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), + tree_get_bool("resize/drawContents", TRUE)); + mapping = FALSE; +} + +void setup_dock_position(GtkWidget *w) +{ + gchar *s; + gboolean f; + + mapping = TRUE; + + s = tree_get_string("dock/position", "TopLeft"); + f = FALSE; + + if (!strcasecmp(s, "Top")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 1); + else if (!strcasecmp(s, "TopRight")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 2); + else if (!strcasecmp(s, "Left")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 3); + else if (!strcasecmp(s, "Right")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 4); + else if (!strcasecmp(s, "BottomLeft")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 5); + else if (!strcasecmp(s, "Bottom")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 6); + else if (!strcasecmp(s, "BottomRight")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 7); + else if (!strcasecmp(s, "Floating")) { + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 8); + f = TRUE; + } else + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 0); + g_free(s); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, f); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, f); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, f); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, f); + } + + mapping = FALSE; +} + +void setup_dock_float_x(GtkWidget *w) +{ + mapping = TRUE; + + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), + tree_get_int("dock/floatingX", 0)); + + mapping = FALSE; +} + +void setup_dock_float_y(GtkWidget *w) +{ + mapping = TRUE; + + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), + tree_get_int("dock/floatingY", 0)); + + mapping = FALSE; +} + +void setup_dock_stacking(GtkWidget *top, GtkWidget *normal, GtkWidget *bottom) +{ + gchar *s; + + mapping = TRUE; + + s = tree_get_string("dock/stacking", "Top"); + + if(!strcasecmp(s, "Normal")) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(normal), TRUE); + else if(!strcasecmp(s, "Bottom")) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bottom), TRUE); + else + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(top), TRUE); + g_free(s); + + mapping = FALSE; +} + +void setup_dock_direction(GtkWidget *w) +{ + gchar *s; + + mapping = TRUE; + + s = tree_get_string("dock/direction", "Vertical"); + + if (!strcasecmp(s, "Horizontal")) + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 1); + else + gtk_option_menu_set_history(GTK_OPTION_MENU(w), 0); + g_free(s); + + mapping = FALSE; +} + +void setup_dock_hide(GtkWidget *w) +{ + gboolean b; + + mapping = TRUE; + + b = tree_get_bool("dock/autoHide", FALSE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), b); + + { + GtkWidget *delay = glade_xml_get_widget(glade, "dock_hide_delay"); + GtkWidget *delay_l = glade_xml_get_widget(glade, "dock_hide_label"); + GtkWidget *delay_u = glade_xml_get_widget(glade, + "dock_hide_label_units"); + gtk_widget_set_sensitive(delay, b); + gtk_widget_set_sensitive(delay_l, b); + gtk_widget_set_sensitive(delay_u, b); + } + + mapping = FALSE; +} + +void setup_dock_hide_delay(GtkWidget *w) +{ + mapping = TRUE; + + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), + tree_get_int("dock/hideDelay", 300)); + + mapping = FALSE; +} + +static void add_theme_dir(const gchar *dirname) +{ + GDir *dir; + const gchar *n; + + if ((dir = g_dir_open(dirname, 0, NULL))) { + while ((n = g_dir_read_name(dir))) { + { + gchar *full; + full = g_build_filename(dirname, n, "openbox-3", + "themerc", NULL); + if (!g_file_test(full, + G_FILE_TEST_IS_REGULAR | + G_FILE_TEST_IS_SYMLINK)) + n = NULL; + g_free(full); + } + + if (n) { + themes = g_list_append(themes, g_strdup(n)); + } + } + g_dir_close(dir); + } +} + +void setup_theme_names(GtkWidget *w) +{ + GtkCellRenderer *render; + GtkTreeViewColumn *column; + gchar *name; + gchar *p; + GList *it, *next; + gint i; + GtkTreeSelection *select; + + mapping = TRUE; + + name = tree_get_string("theme/name", "TheBear"); + + for (it = themes; it; it = g_list_next(it)) + g_list_free(it->data); + g_list_free(themes); + themes = NULL; + + p = g_build_filename(g_get_home_dir(), ".themes", NULL); + add_theme_dir(p); + g_free(p); + + { + GSList *it; + for (it = parse_xdg_data_dir_paths(); it; it = g_slist_next(it)) { + p = g_build_filename(it->data, "themes", NULL); + add_theme_dir(p); + g_free(p); + } + } + + add_theme_dir(THEMEDIR); + + themes = g_list_sort(themes, (GCompareFunc) strcasecmp); + + /* widget setup */ + theme_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); + gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(theme_store)); + g_object_unref (theme_store); + + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)), + GTK_SELECTION_SINGLE); + + render = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes + ("Name", render, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(w), column); + + /* return to regular scheduled programming */ + i = 0; + for (it = themes; it; it = next) { + GtkTreeIter iter; + + next = g_list_next(it); + + /* remove duplicates */ + if (next && !strcmp(it->data, next->data)) { + g_free(it->data); + themes = g_list_delete_link(themes, it); + continue; + } + + gtk_list_store_append(theme_store, &iter); + gtk_list_store_set(theme_store, &iter, + 0, it->data, + 1, TRUE, + -1); + + if(!strcmp(name, it->data)) { + GtkTreePath *path; + path = gtk_tree_path_new_from_indices(i, -1); + gtk_tree_view_set_cursor(GTK_TREE_VIEW(w), path, NULL, FALSE); + } + + + ++i; + } + + /* setup the selection handler */ + select = gtk_tree_view_get_selection(GTK_TREE_VIEW (w)); + gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE); + g_signal_connect (G_OBJECT(select), "changed", + G_CALLBACK(on_theme_names_selection_changed), + NULL); + + g_free(name); + + mapping = FALSE; +} + +void setup_title_layout(GtkWidget *w) +{ + gchar *layout; + + mapping = TRUE; + + layout = tree_get_string("theme/titleLayout", "NLIMC"); + gtk_entry_set_text(GTK_ENTRY(w), layout); + g_free(layout); + + mapping = FALSE; +} + +void setup_desktop_num(GtkWidget *w) +{ + mapping = TRUE; + + num_desktops = tree_get_int("desktops/number", 4); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), num_desktops); + + mapping = FALSE; +} + +void setup_window_border(GtkWidget *w) +{ + gboolean border; + + mapping = TRUE; + + border = tree_get_bool("theme/keepBorder", TRUE); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), border); + + mapping = FALSE; +} + +void setup_font_active(GtkWidget *w) +{ + gchar *fontstring; + gchar *name, **names; + gchar *size; + gchar *weight; + gchar *slant; + + mapping = TRUE; + + name = tree_get_string("theme/font:place=ActiveWindow/name", "Sans"); + size = tree_get_string("theme/font:place=ActiveWindow/size", "8"); + weight = tree_get_string("theme/font:place=ActiveWindow/weight", ""); + slant = tree_get_string("theme/font:place=ActiveWindow/slant", ""); + + /* get only the first font in the string */ + names = g_strsplit(name, ",", 0); + g_free(name); + name = g_strdup(names[0]); + g_strfreev(names); + + fontstring = g_strdup_printf("%s %s %s %s", name, weight, slant, size); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontstring); + g_free(fontstring); + g_free(slant); + g_free(weight); + g_free(size); + g_free(name); + + mapping = FALSE; +} + +void setup_font_inactive(GtkWidget *w) +{ + gchar *fontstring; + gchar *name, **names; + gchar *size; + gchar *weight; + gchar *slant; + + mapping = TRUE; + + name = tree_get_string("theme/font:place=InactiveWindow/name", "Sans"); + size = tree_get_string("theme/font:place=InactiveWindow/size", "8"); + weight = tree_get_string("theme/font:place=InactiveWindow/weight", ""); + slant = tree_get_string("theme/font:place=InactiveWindow/slant", ""); + + /* get only the first font in the string */ + names = g_strsplit(name, ",", 0); + g_free(name); + name = g_strdup(names[0]); + g_strfreev(names); + + fontstring = g_strdup_printf("%s %s %s %s", name, weight, slant, size); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontstring); + g_free(fontstring); + g_free(slant); + g_free(weight); + g_free(size); + g_free(name); + + mapping = FALSE; +} + +void setup_font_menu_header(GtkWidget *w) +{ + gchar *fontstring; + gchar *name, **names; + gchar *size; + gchar *weight; + gchar *slant; + + mapping = TRUE; + + name = tree_get_string("theme/font:place=MenuHeader/name", "Sans"); + size = tree_get_string("theme/font:place=MenuHeader/size", "8"); + weight = tree_get_string("theme/font:place=MenuHeader/weight", ""); + slant = tree_get_string("theme/font:place=MenuHeader/slant", ""); + + /* get only the first font in the string */ + names = g_strsplit(name, ",", 0); + g_free(name); + name = g_strdup(names[0]); + g_strfreev(names); + + fontstring = g_strdup_printf("%s %s %s %s", name, weight, slant, size); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontstring); + g_free(fontstring); + g_free(slant); + g_free(weight); + g_free(size); + g_free(name); + + mapping = FALSE; +} + +void setup_font_menu_item(GtkWidget *w) +{ + gchar *fontstring; + gchar *name, **names; + gchar *size; + gchar *weight; + gchar *slant; + + mapping = TRUE; + + name = tree_get_string("theme/font:place=MenuItem/name", "Sans"); + size = tree_get_string("theme/font:place=MenuItem/size", "8"); + weight = tree_get_string("theme/font:place=MenuItem/weight", ""); + slant = tree_get_string("theme/font:place=MenuItem/slant", ""); + + /* get only the first font in the string */ + names = g_strsplit(name, ",", 0); + g_free(name); + name = g_strdup(names[0]); + g_strfreev(names); + + fontstring = g_strdup_printf("%s %s %s %s", name, weight, slant, size); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontstring); + g_free(fontstring); + g_free(slant); + g_free(weight); + g_free(size); + g_free(name); + + mapping = FALSE; +} + +void setup_font_display(GtkWidget *w) +{ + gchar *fontstring; + gchar *name, **names; + gchar *size; + gchar *weight; + gchar *slant; + + mapping = TRUE; + + name = tree_get_string("theme/font:place=OnScreenDisplay/name", "Sans"); + size = tree_get_string("theme/font:place=OnScreenDisplay/size", "8"); + weight = tree_get_string("theme/font:place=OnScreenDisplay/weight", ""); + slant = tree_get_string("theme/font:place=OnScreenDisplay/slant", ""); + + /* get only the first font in the string */ + names = g_strsplit(name, ",", 0); + g_free(name); + name = g_strdup(names[0]); + g_strfreev(names); + + fontstring = g_strdup_printf("%s %s %s %s", name, weight, slant, size); + gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), fontstring); + g_free(fontstring); + g_free(slant); + g_free(weight); + g_free(size); + g_free(name); + + mapping = FALSE; +} + +static void reset_desktop_names() +{ + GtkTreeIter it; + xmlNodePtr n; + gint i; + GList *lit; + + gtk_list_store_clear(desktop_store); + + for (lit = desktop_names; lit; lit = g_list_next(lit)) + g_free(lit->data); + g_list_free(desktop_names); + desktop_names = NULL; + + i = 0; + n = tree_get_node("desktops/names", NULL)->children; + while (n) { + gchar *name; + + if (!xmlStrcmp(n->name, (const xmlChar*)"name")) { + name = parse_string(doc, n); + + desktop_names = g_list_append(desktop_names, name); + + gtk_list_store_append(desktop_store, &it); + gtk_list_store_set(desktop_store, &it, + 0, (name[0] ? name : _("(Unnamed desktop)")), + 1, TRUE, + -1); + ++i; + } + + n = n->next; + } + + while (i < num_desktops) { + gchar *name = g_strdup(""); + + desktop_names = g_list_append(desktop_names, name); + + gtk_list_store_append(desktop_store, &it); + gtk_list_store_set(desktop_store, &it, + 0, _("(Unnamed desktop)"), + 1, TRUE, + -1); + ++i; + } +} + +void setup_desktop_names(GtkWidget *w) +{ + GtkCellRenderer *render; + GtkTreeViewColumn *column; + + mapping = TRUE; + + desktop_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN); + gtk_tree_view_set_model(GTK_TREE_VIEW(w), GTK_TREE_MODEL(desktop_store)); + g_object_unref (desktop_store); + + gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(w)), + GTK_SELECTION_SINGLE); + + render = gtk_cell_renderer_text_new(); + g_signal_connect(render, "edited", + G_CALLBACK (on_desktop_names_cell_edited), + NULL); + + column = gtk_tree_view_column_new_with_attributes + ("Name", render, "text", 0, "editable", 1, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(w), column); + + reset_desktop_names(); + + mapping = FALSE; +} + + +/***********************************************************************/ + +void on_window_border_toggled(GtkToggleButton *w, gpointer data) +{ + gboolean b; + + if (mapping) return; + + b = gtk_toggle_button_get_active(w); + tree_set_bool("theme/keepBorder", b); +} + +static void on_font_set(GtkFontButton *w, const gchar *place) +{ + gchar *c; + gchar *font, *node; + const gchar *size = NULL; + const gchar *bold = NULL; + const gchar *italic = NULL; + + if (mapping) return; + + font = g_strdup(gtk_font_button_get_font_name(w)); + while ((c = strrchr(font, ' '))) { + if (!bold && !italic && !size && atoi(c+1)) + size = c+1; + else if (!bold && !italic && !g_ascii_strcasecmp(c+1, "italic")) + italic = c+1; + else if (!bold && !g_ascii_strcasecmp(c+1, "bold")) + bold = c+1; + else + break; + *c = '\0'; + } + if (!bold) bold = "Normal"; + if (!italic) italic = "Normal"; + + node = g_strdup_printf("theme/font:place=%s/name", place); + tree_set_string(node, font); + g_free(node); + + node = g_strdup_printf("theme/font:place=%s/size", place); + tree_set_string(node, size); + g_free(node); + + node = g_strdup_printf("theme/font:place=%s/weight", place); + tree_set_string(node, bold); + g_free(node); + + node = g_strdup_printf("theme/font:place=%s/slant", place); + tree_set_string(node, italic); + g_free(node); + + g_free(font); +} + +void on_font_active_font_set(GtkFontButton *w, gpointer data) +{ + on_font_set(w, "ActiveWindow"); +} + +void on_font_inactive_font_set(GtkFontButton *w, gpointer data) +{ + on_font_set(w, "InactiveWindow"); +} + +void on_font_menu_header_font_set(GtkFontButton *w, gpointer data) +{ + on_font_set(w, "MenuHeader"); +} + +void on_font_menu_item_font_set(GtkFontButton *w, gpointer data) +{ + on_font_set(w, "MenuItem"); +} + +void on_font_display_font_set(GtkFontButton *w, gpointer data) +{ + on_font_set(w, "OnScreenDisplay"); +} + +void on_focus_mouse_toggled(GtkToggleButton *w, gpointer data) +{ + gboolean b; + + if (mapping) return; + + b = gtk_toggle_button_get_active(w); + tree_set_bool("focus/followMouse", b); + + { + GtkWidget *delay = glade_xml_get_widget(glade, "focus_delay"); + GtkWidget *delay_l = glade_xml_get_widget(glade, "focus_delay_label"); + GtkWidget *delay_u = glade_xml_get_widget(glade, + "focus_delay_label_units"); + GtkWidget *raise = glade_xml_get_widget(glade, "focus_raise"); + gtk_widget_set_sensitive(delay, b); + gtk_widget_set_sensitive(delay_l, b); + gtk_widget_set_sensitive(delay_u, b); + gtk_widget_set_sensitive(raise, b); + } +} + +void on_focus_delay_value_changed(GtkSpinButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_int("focus/focusDelay", + gtk_spin_button_get_value_as_int(w)); +} + +void on_focus_raise_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_bool("focus/raiseOnFocus", gtk_toggle_button_get_active(w)); +} + +void on_focus_new_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_bool("focus/focusNew", gtk_toggle_button_get_active(w)); +} + +void on_place_mouse_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("placement/policy", + (gtk_toggle_button_get_active(w) ? + "UnderMouse" : "Smart")); +} + +void on_resist_window_value_changed(GtkSpinButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_int("resistance/strength", gtk_spin_button_get_value_as_int(w)); +} + +void on_resist_edge_value_changed(GtkSpinButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_int("resistance/screen_edge_strength", + gtk_spin_button_get_value_as_int(w)); +} + +void on_resize_contents_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_bool("resize/drawContents", gtk_toggle_button_get_active(w)); +} + +void on_dock_top_left_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "TopLeft"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + } +} + +void on_dock_top_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "Top"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + } +} + +void on_dock_top_right_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "TopRight"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + } +} + +void on_dock_left_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "Left"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + } +} + +void on_dock_right_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "Right"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + + } +} + +void on_dock_bottom_left_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "BottomLeft"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + } +} + +void on_dock_bottom_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "Bottom"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + } +} + +void on_dock_bottom_right_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "BottomRight"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, FALSE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, FALSE); + } +} + +void on_dock_floating_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/position", "Floating"); + + { + GtkWidget *s; + s = glade_xml_get_widget(glade, "dock_float_x"); + gtk_widget_set_sensitive(s, TRUE); + s = glade_xml_get_widget(glade, "dock_float_y"); + gtk_widget_set_sensitive(s, TRUE); + s = glade_xml_get_widget(glade, "dock_float_label"); + gtk_widget_set_sensitive(s, TRUE); + s = glade_xml_get_widget(glade, "dock_float_label_x"); + gtk_widget_set_sensitive(s, TRUE); + } +} + +void on_dock_float_x_value_changed(GtkSpinButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_int("dock/floatingX", gtk_spin_button_get_value_as_int(w)); +} + +void on_dock_float_y_value_changed(GtkSpinButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_int("dock/floatingY", gtk_spin_button_get_value_as_int(w)); +} + +void on_dock_stacking_top_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + if(gtk_toggle_button_get_active(w)) + tree_set_string("dock/stacking", "Top"); +} + +void on_dock_stacking_normal_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + if(gtk_toggle_button_get_active(w)) + tree_set_string("dock/stacking", "Normal"); +} + +void on_dock_stacking_bottom_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + if(gtk_toggle_button_get_active(w)) + tree_set_string("dock/stacking", "Bottom"); +} + +void on_dock_horizontal_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/direction", "Horizontal"); +} + +void on_dock_vertical_activate(GtkMenuItem *w, gpointer data) +{ + if (mapping) return; + + tree_set_string("dock/direction", "Vertical"); +} + +void on_dock_hide_toggled(GtkToggleButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_bool("dock/autoHide", gtk_toggle_button_get_active(w)); + { + GtkWidget *delay = glade_xml_get_widget(glade, "dock_hide_delay"); + GtkWidget *delay_l = glade_xml_get_widget(glade, "dock_hide_label"); + GtkWidget *delay_u = glade_xml_get_widget(glade, + "dock_hide_label_units"); + gtk_widget_set_sensitive(delay, gtk_toggle_button_get_active(w)); + gtk_widget_set_sensitive(delay_l, gtk_toggle_button_get_active(w)); + gtk_widget_set_sensitive(delay_u, gtk_toggle_button_get_active(w)); + } +} + +void on_dock_hide_delay_value_changed(GtkSpinButton *w, gpointer data) +{ + if (mapping) return; + + tree_set_int("dock/hideDelay", + gtk_spin_button_get_value_as_int(w)); +} + +void on_theme_name_changed(GtkOptionMenu *w, gpointer data) +{ + const gchar *name; + + if (mapping) return; + + name = g_list_nth_data(themes, gtk_option_menu_get_history(w)); + + if (name) + tree_set_string("theme/name", name); +} + +void on_theme_names_selection_changed(GtkTreeSelection *sel, gpointer data) +{ + GtkTreeIter iter; + GtkTreeModel *model; + const gchar *name; + + if (mapping) return; + + if(gtk_tree_selection_get_selected(sel, &model, &iter)) { + gtk_tree_model_get(model, &iter, 0, &name, -1); + } + + if(name) + tree_set_string("theme/name", name); +} + +void on_title_layout_changed(GtkEntry *w, gpointer data) +{ + gchar *layout; + gchar *it, *it2; + gboolean n, d, s, l, i, m, c; + + if (mapping) return; + + layout = g_strdup(gtk_entry_get_text(w)); + + n = d = s = l = i = m = c = FALSE; + + for (it = layout; *it; ++it) { + gboolean *b; + + switch (*it) { + case 'N': + case 'n': + b = &n; + break; + case 'd': + case 'D': + b = &d; + break; + case 's': + case 'S': + b = &s; + break; + case 'l': + case 'L': + b = &l; + break; + case 'i': + case 'I': + b = &i; + break; + case 'm': + case 'M': + b = &m; + break; + case 'c': + case 'C': + b = &c; + break; + default: + b = NULL; + break; + } + + if (!b || *b) { + /* drop the letter */ + for (it2 = it; *it2; ++it2) + *it2 = *(it2+1); + } else { + *it = toupper(*it); + *b = TRUE; + } + } + + gtk_entry_set_text(w, layout); + tree_set_string("theme/titleLayout", layout); + g_free(layout); +} + +static void set_desktop_names() +{ + gchar **s; + GList *lit; + xmlNodePtr n, c; + + n = tree_get_node("desktops/names", NULL); + while ((c = n->children)) { + xmlUnlinkNode(c); + xmlFreeNode(c); + } + + for (lit = desktop_names; lit; lit = g_list_next(lit)) + xmlNewTextChild(n, NULL, "name", lit->data); + tree_apply(); + + /* make openbox re-set the property */ + XDeleteProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(), + XInternAtom(GDK_DISPLAY(), "_NET_DESKTOP_NAMES", FALSE)); +} + +static void set_desktop_number() +{ + XEvent ce; + + tree_set_int("desktops/number", num_desktops); + + ce.xclient.type = ClientMessage; + ce.xclient.message_type = XInternAtom(GDK_DISPLAY(), + "_NET_NUMBER_OF_DESKTOPS", + FALSE); + ce.xclient.display = GDK_DISPLAY(); + ce.xclient.window = GDK_ROOT_WINDOW(); + ce.xclient.format = 32; + ce.xclient.data.l[0] = num_desktops; + ce.xclient.data.l[1] = 0; + ce.xclient.data.l[2] = 0; + ce.xclient.data.l[3] = 0; + ce.xclient.data.l[4] = 0; + XSendEvent(GDK_DISPLAY(), GDK_ROOT_WINDOW(), FALSE, + SubstructureNotifyMask | SubstructureRedirectMask, + &ce); +} + +void on_desktop_num_value_changed(GtkSpinButton *w, gpointer data) +{ + if (mapping) return; + + num_desktops = gtk_spin_button_get_value(w); + + set_desktop_number(); + + reset_desktop_names(); +} + +static void on_desktop_names_cell_edited(GtkCellRendererText *cell, + const gchar *path_string, + const gchar *new_text, + gpointer data) +{ + if (mapping) return; + + GtkTreePath *path = gtk_tree_path_new_from_string (path_string); + GtkTreeIter it; + gchar *old_text; + GList *lit; + gint i; + + gtk_tree_model_get_iter(GTK_TREE_MODEL(desktop_store), &it, path); + + gtk_tree_model_get(GTK_TREE_MODEL(desktop_store), &it, 0, &old_text, -1); + g_free(old_text); + + i = gtk_tree_path_get_indices(path)[0]; + lit = g_list_nth(desktop_names, i); + + g_free(lit->data); + lit->data = g_strdup(new_text); + if (new_text[0]) /* not empty */ + gtk_list_store_set(desktop_store, &it, 0, lit->data, -1); + else + gtk_list_store_set(desktop_store, &it, 0, _("(Unnamed desktop)"), -1); + + set_desktop_names(); +} diff --git a/src/handlers.h b/src/handlers.h new file mode 100644 index 0000000..d945ef0 --- /dev/null +++ b/src/handlers.h @@ -0,0 +1,52 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + handlers.h for ObConf, the configuration tool for Openbox + Copyright (c) 2003 Dana Jansens + Copyright (c) 2003 Tim Riley + + 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. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#ifndef obconf__handlers_h +#define obconf__handlers_h + +void setup_behavior_tab(); +void setup_dock_tab(); +void setup_focus_mouse(GtkWidget *w); +void setup_focus_delay(GtkWidget *w); +void setup_focus_new(GtkWidget *w); +void setup_focus_raise(GtkWidget *w); +void setup_focus_desktop(GtkWidget *w); +void setup_place_mouse(GtkWidget *w); +void setup_resist_window(GtkWidget *w); +void setup_resist_edge(GtkWidget *w); +void setup_resize_contents(GtkWidget *w); +void setup_dock_position(GtkWidget *w); +void setup_dock_float_x(GtkWidget *w); +void setup_dock_float_y(GtkWidget *w); +void setup_dock_stacking(GtkWidget *top, GtkWidget *normal, GtkWidget *bottom); +void setup_dock_direction(GtkWidget *w); +void setup_dock_hide(GtkWidget *w); +void setup_dock_hide_delay(GtkWidget *w); +void setup_theme_names(GtkWidget *w); +void setup_title_layout(GtkWidget *w); +void setup_window_border(GtkWidget *w); +void setup_font_active(GtkWidget *w); +void setup_font_inactive(GtkWidget *w); +void setup_font_menu_header(GtkWidget *w); +void setup_font_menu_item(GtkWidget *w); +void setup_font_display(GtkWidget *w); +void setup_desktop_num(GtkWidget *w); +void setup_desktop_names(GtkWidget *w); + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..cc0b024 --- /dev/null +++ b/src/main.c @@ -0,0 +1,145 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + main.c for ObConf, the configuration tool for Openbox + Copyright (c) 2003-2007 Dana Jansens + Copyright (c) 2003 Tim Riley + + 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. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include "main.h" +#include "handlers.h" + +#include +#define SN_API_NOT_YET_FROZEN +#include +#undef SN_API_NOT_YET_FROZEN + +static GtkWidget *mainwin; + +GladeXML *glade; +xmlDocPtr doc; +xmlNodePtr root; + +void obconf_error(gchar *msg) +{ + GtkWidget *d; + + d = gtk_message_dialog_new(mainwin ? GTK_WINDOW(mainwin) : NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "%s", msg); + g_signal_connect_swapped(GTK_OBJECT(d), "response", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(d)); + gtk_widget_show(d); +} + +int main(int argc, char **argv) +{ + SnDisplay *sn_d; + SnLauncheeContext *sn_cx; + gchar *p; + + parse_paths_startup(); + + gtk_init(&argc, &argv); + + p = g_build_filename(GLADEDIR, "obconf.glade", NULL); + glade = glade_xml_new(p, NULL, NULL); + g_free(p); + + if (!glade) { + obconf_error("Failed to load the obconf.glade interface file. You " + "have probably failed to install ObConf properly."); + return 1; + } + + xmlIndentTreeOutput = 1; + if (!parse_load_rc(NULL, &doc, &root)) { + obconf_error("Failed to load an rc.xml. You have probably failed to " + "install Openbox properly."); + return 1; + } + + glade_xml_signal_autoconnect(glade); + + { + gchar *s = g_strdup_printf + ("ObConf %s", + PACKAGE_VERSION); + gtk_label_set_markup(GTK_LABEL + (glade_xml_get_widget(glade, "title_label")), s); + g_free(s); + } + + setup_behavior_tab(); + setup_dock_tab(); + setup_focus_mouse(glade_xml_get_widget(glade, "focus_mouse")); + setup_focus_raise(glade_xml_get_widget(glade, "focus_raise")); + setup_focus_delay(glade_xml_get_widget(glade, "focus_delay")); + setup_focus_new(glade_xml_get_widget(glade, "focus_new")); + setup_place_mouse(glade_xml_get_widget(glade, "place_mouse")); + setup_resist_window(glade_xml_get_widget(glade, "resist_window")); + setup_resist_edge(glade_xml_get_widget(glade, "resist_edge")); + setup_resize_contents(glade_xml_get_widget(glade, "resize_contents")); + setup_dock_position(glade_xml_get_widget(glade, "dock_position")); + setup_dock_float_x(glade_xml_get_widget(glade, "dock_float_x")); + setup_dock_float_y(glade_xml_get_widget(glade, "dock_float_y")); + setup_dock_stacking(glade_xml_get_widget(glade, "dock_stack_top"), + glade_xml_get_widget(glade, "dock_stack_normal"), + glade_xml_get_widget(glade, "dock_stack_bottom")); + setup_dock_direction(glade_xml_get_widget(glade, "dock_direction")); + setup_dock_hide(glade_xml_get_widget(glade, "dock_hide")); + setup_dock_hide_delay(glade_xml_get_widget(glade, "dock_hide_delay")); + setup_theme_names(glade_xml_get_widget(glade, "theme_names")); + setup_title_layout(glade_xml_get_widget(glade, "title_layout")); + setup_desktop_num(glade_xml_get_widget(glade, "desktop_num")); + setup_desktop_names(glade_xml_get_widget(glade, "desktop_names")); + setup_window_border(glade_xml_get_widget(glade, "window_border")); + setup_font_active(glade_xml_get_widget(glade, "font_active")); + setup_font_inactive(glade_xml_get_widget(glade, "font_inactive")); + setup_font_menu_header(glade_xml_get_widget(glade, "font_menu_header")); + setup_font_menu_item(glade_xml_get_widget(glade, "font_menu_item")); + setup_font_display(glade_xml_get_widget(glade, "font_display")); + + mainwin = glade_xml_get_widget(glade, "main_window"); + + sn_d = sn_display_new(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), + NULL, NULL); + + sn_cx = sn_launchee_context_new_from_environment + (sn_d, gdk_screen_get_number(gdk_display_get_default_screen + (gdk_display_get_default()))); + + if (sn_cx) + sn_launchee_context_setup_window + (sn_cx, GDK_WINDOW_XWINDOW(GDK_WINDOW(mainwin->window))); + + gtk_widget_show_all(mainwin); + + if (sn_cx) + sn_launchee_context_complete(sn_cx); + + if (sn_cx) + sn_launchee_context_unref(sn_cx); + sn_display_unref(sn_d); + + gtk_main(); + + parse_paths_shutdown(); + + xmlFreeDoc(doc); + return 0; +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..1514a85 --- /dev/null +++ b/src/main.h @@ -0,0 +1,33 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + main.h for ObConf, the configuration tool for Openbox + Copyright (c) 2003 Dana Jansens + + 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. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#ifndef obconf__main_h +#define obconf__main_h + +#include "openbox/parse.h" + +#include +#include + +extern GladeXML *glade; +extern xmlDocPtr doc; +extern xmlNodePtr root; + +void obconf_error(gchar *msg); + +#endif diff --git a/src/obconf.glade b/src/obconf.glade new file mode 100644 index 0000000..b70c6a1 --- /dev/null +++ b/src/obconf.glade @@ -0,0 +1,2831 @@ + + + + + + + 13 + True + Openbox Window Preferences + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + + True + False + 12 + + + + True + True + True + True + GTK_POS_TOP + False + False + + + + 12 + True + False + 18 + + + + True + False + 6 + + + + True + <span weight="bold">Theme</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + True + GTK_POLICY_NEVER + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + False + True + False + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + False + True + + + + + + True + Theme + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + True + False + 0 + + + + True + False + 0 + + + + True + <span weight="bold">Windows</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + True + Windows retain a border when undecorated + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + True + False + 6 + + + + True + <span weight="bold">Window Titles</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + Button _order: + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + N - The window's icon +D - The all-desktops (sticky) button +S - The shade (roll up) button +L - The label (window title) +I - The iconify (minimize) button +M - The maximize button +C - The close button + True + True + True + 0 + + True + * + False + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + True + False + 0 + + + + True + <span weight="bold">Fonts</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + 5 + 2 + False + 0 + 0 + + + + True + True + True + True + False + False + True + + + + 1 + 2 + 1 + 2 + fill + + + + + + + True + True + True + True + False + False + True + + + + 1 + 2 + 2 + 3 + fill + + + + + + + True + True + True + True + False + False + True + + + + 1 + 2 + 3 + 4 + fill + + + + + + + True + True + True + True + False + False + True + + + + 1 + 2 + 4 + 5 + fill + + + + + + + True + Active window title: + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 0 + 1 + fill + + + + + + + True + Inactive window title: + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 1 + 2 + fill + + + + + + + True + Menu header: + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + Menu Item: + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 3 + 4 + fill + + + + + + + True + On-screen display: + False + False + GTK_JUSTIFY_LEFT + False + False + 1 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + 1 + 4 + 5 + fill + + + + + + + True + True + True + True + False + False + True + + + + 1 + 2 + 0 + 1 + + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + False + True + + + + + + True + Appearance + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + 12 + True + False + 18 + + + + True + False + 6 + + + + True + <span weight="bold">Focusing Windows</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + True + Focus windows when the _mouse pointer moves over them + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + True + _Raise windows when the mouse pointer moves over them + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + True + False + 6 + + + + True + _Delay before focusing and raising windows: + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + focus_delay + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 0 0 100000 100 10 100000 + + + + 0 + False + True + + + + + + True + ms + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + False + False + + + + + + True + True + Focus _new windows when they appear + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + 0 + True + True + + + + + 0 + False + True + + + + + 0 + False + True + + + + + + True + False + 6 + + + + True + <span weight="bold">Placing Windows</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + True + _Place new windows under the mouse pointer + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + + True + False + 6 + + + + True + <span weight="bold">Moving and Resizing Windows</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + True + Update the window c_ontents while resizing + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + True + False + 6 + + + + True + Amount of resistance against other _windows: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + resist_window + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 20 0 10000 1 10 10 + + + + 0 + False + True + + + + + + True + px + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + 0 + False + True + + + + + + True + False + 6 + + + + True + Amount of resistance against screen _edges: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + resist_edge + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 100 1 10 10 + + + + 0 + False + True + + + + + + True + px + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + 0 + False + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + False + True + + + + + + True + Behavior + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + 12 + True + False + 6 + + + + True + <span weight="bold">Desktops</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + False + 6 + + + + True + Number of _desktops: + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + desktop_num + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 1 100 1 10 10 + + + + 0 + False + True + + + + + 0 + False + True + + + + + + True + Desktop _names: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + desktop_names + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + GTK_POLICY_NEVER + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT + + + + True + True + False + False + False + True + False + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + False + True + + + + + + True + Desktops + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + + 12 + True + False + 18 + + + + True + False + 6 + + + + True + <span weight="bold">Position</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + False + 12 + + + + True + _Position: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + dock_position + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 0 + + + + + + + True + Top Left + True + + + + + + + True + Top + True + + + + + + + True + Top Right + True + + + + + + + True + Left + True + + + + + + + True + Right + True + + + + + + + True + Bottom Left + True + + + + + + + True + Bottom + True + + + + + + + True + Bottom Right + True + + + + + + + True + Floating + True + + + + + + + + 0 + False + False + + + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + _Floating position: + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + dock_float_x + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 10000 1 10 10 + + + + 0 + False + True + + + + + + True + x + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 10000 1 10 10 + + + + 0 + False + True + + + + + 0 + True + True + + + + + 0 + False + False + + + + + + True + False + 12 + + + + True + _Orientation: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + dock_direction + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 0 + + + + + + + True + Vertical + True + + + + + + + True + Horizontal + True + + + + + + + + 0 + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + False + False + + + + + 0 + False + False + + + + + + True + False + 6 + + + + True + <span weight="bold">Stacking</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + True + Keep dock _above other windows + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + True + True + A_llow dock to be both above and below windows + True + GTK_RELIEF_NORMAL + True + False + False + True + dock_stack_top + + + + 0 + False + False + + + + + + True + True + Keep dock _below other windows + True + GTK_RELIEF_NORMAL + True + False + False + True + dock_stack_top + + + + 0 + False + False + + + + + 0 + False + False + + + + + 0 + False + False + + + + + 0 + False + False + + + + + + True + False + 6 + + + + True + <span weight="bold">Hiding</span> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + True + _Hide off screen + True + GTK_RELIEF_NORMAL + True + False + False + True + + + + 0 + False + False + + + + + + True + False + 0 + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + False + 6 + + + + True + _Delay before hiding: + True + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + dock_hide_delay + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 300 0 10000 1 10 10 + + + + 0 + False + True + + + + + + True + ms + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + True + True + + + + + 0 + False + False + + + + + False + True + + + + + + True + Dock + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + tab + + + + + 0 + True + True + + + + + + True + False + 0 + + + + True + GTK_BUTTONBOX_START + 0 + + + + True + True + True + About + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_END + 0 + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + 0 + False + False + + + + + + + + About ObConf + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_NONE + False + True + False + True + False + False + GDK_WINDOW_TYPE_HINT_NORMAL + GDK_GRAVITY_NORTH_WEST + True + False + + + + + 12 + True + False + 12 + + + + True + False + 6 + + + + True + True + <span weight="bold" size="xx-large">ObConf 3.0</span> + False + True + GTK_JUSTIFY_LEFT + False + True + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + A preferences manager for Openbox + False + False + GTK_JUSTIFY_LEFT + False + True + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + + True + True + Copyright (c) 2003-2006 +Dana Jansens <danakj@orodu.net> +Tim Riley <tr@slackzone.org> + False + False + GTK_JUSTIFY_CENTER + False + True + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + False + False + + + + + 0 + True + True + + + + + + True + GTK_BUTTONBOX_END + 0 + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + True + + + + + + 0 + True + True + + + + + + + diff --git a/src/tree.c b/src/tree.c new file mode 100644 index 0000000..5d15dbc --- /dev/null +++ b/src/tree.c @@ -0,0 +1,176 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + tree.c for ObConf, the configuration tool for Openbox + Copyright (c) 2003 Dana Jansens + + 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. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include "tree.h" +#include "main.h" +#include "openbox/parse.h" + +#include +#include + +xmlNodePtr tree_get_node(const gchar *path, const gchar *def) +{ + xmlNodePtr n, c; + gchar **nodes; + gchar **it, **next; + + n = root; + + nodes = g_strsplit(path, "/", 0); + for (it = nodes; *it; it = next) { + gchar **attrs; + gboolean ok = FALSE; + + attrs = g_strsplit(*it, ":", 0); + next = it + 1; + + /* match attributes */ + c = parse_find_node(attrs[0], n->children); + while (c && !ok) { + gint i; + + ok = TRUE; + for (i = 1; attrs[i]; ++i) { + gchar **eq = g_strsplit(attrs[i], "=", 2); + if (eq[1] && !parse_attr_contains(eq[1], c, eq[0])) + ok = FALSE; + g_strfreev(eq); + } + if (!ok) + c = parse_find_node(attrs[0], c->next); + } + + if (!c) { + gint i; + + c = xmlNewTextChild(n, NULL, *it, *next ? NULL : def); + + for (i = 1; attrs[i]; ++i) { + gchar **eq = g_strsplit(attrs[i], "=", 2); + if (eq[1]) + xmlNewProp(c, eq[0], eq[1]); + g_strfreev(eq); + } + } + n = c; + + g_strfreev(attrs); + } + + g_strfreev(nodes); + + return n; +} + +void tree_apply() +{ + gchar *p; + gboolean err; + + p = g_build_filename(parse_xdg_config_home_path(), "openbox", NULL); + parse_mkdir_path(p, 0700); + g_free(p); + + p = g_build_filename(parse_xdg_config_home_path(), "openbox", + "rc.xml", NULL); + err = xmlSaveFormatFile(p, doc, 1) == -1; + if (err) { + gchar *s; + s = g_strdup_printf("An error occured while saving the " + "config file '%s'", p); + obconf_error(s); + g_free(s); + } + g_free(p); + + if (!err) { + GdkAtom type; + gint format; + gint length; + guint *pid; + + if (gdk_property_get + (gdk_screen_get_root_window(gdk_screen_get_default()), + gdk_atom_intern("_OPENBOX_PID", FALSE), + gdk_atom_intern("CARDINAL", FALSE), + 0, 4, FALSE, &type, &format, &length, (guchar**)&pid)) { + kill(*pid, SIGUSR2); + g_free(pid); + } + } +} + +void tree_set_string(const gchar *node, const gchar *value) +{ + xmlNodePtr n; + + n = tree_get_node(node, NULL); + xmlNodeSetContent(n, (const xmlChar*) value); + + tree_apply(); +} + +void tree_set_int(const gchar *node, const gint value) +{ + xmlNodePtr n; + gchar *s; + + n = tree_get_node(node, NULL); + s = g_strdup_printf("%d", value); + xmlNodeSetContent(n, (const xmlChar*) s); + g_free(s); + + tree_apply(); +} + +void tree_set_bool(const gchar *node, const gboolean value) +{ + xmlNodePtr n; + + n = tree_get_node(node, NULL); + xmlNodeSetContent(n, (const xmlChar*) (value ? "yes" : "no")); + + tree_apply(); +} + +gchar* tree_get_string(const gchar *node, const gchar *def) +{ + xmlNodePtr n; + + n = tree_get_node(node, def); + return parse_string(doc, n); +} + +gint tree_get_int(const gchar *node, gint def) +{ + xmlNodePtr n; + gchar *d; + + d = g_strdup_printf("%d", def); + n = tree_get_node(node, d); + g_free(d); + return parse_int(doc, n); +} + +gboolean tree_get_bool(const gchar *node, gboolean def) +{ + xmlNodePtr n; + + n = tree_get_node(node, (def ? "yes" : "no")); + return parse_bool(doc, n); +} diff --git a/src/tree.h b/src/tree.h new file mode 100644 index 0000000..39c96b3 --- /dev/null +++ b/src/tree.h @@ -0,0 +1,36 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + tree.h for ObConf, the configuration tool for Openbox + Copyright (c) 2003 Dana Jansens + + 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. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#ifndef obconf__tree_h +#define obconf__tree_h + +#include "openbox/parse.h" + +xmlNodePtr tree_get_node(const gchar *path, const gchar *def); + +gchar* tree_get_string(const gchar *node, const gchar *def); +gint tree_get_int(const gchar *node, gint def); +gboolean tree_get_bool(const gchar *node, gboolean def); + +void tree_set_string(const gchar *node, const gchar *value); +void tree_set_int(const gchar *node, const gint value); +void tree_set_bool(const gchar *node, const gboolean value); + +void tree_apply(); /* save the rc.xml and force reconfigure from Openbox */ + +#endif