Add "active" and "primary" options to the <monitor> placement option for per-app...
[dana/openbox.git] / openbox / config.c
index 56e625d..857255f 100644 (file)
 #include "keyboard.h"
 #include "mouse.h"
 #include "actions.h"
-#include "prop.h"
 #include "translate.h"
 #include "client.h"
 #include "screen.h"
-#include "parser/parse.h"
 #include "openbox.h"
 #include "gettext.h"
+#include "obt/paths.h"
 
 gboolean config_focus_new;
 gboolean config_focus_follow;
@@ -35,15 +34,20 @@ guint    config_focus_delay;
 gboolean config_focus_raise;
 gboolean config_focus_last;
 gboolean config_focus_under_mouse;
+gboolean config_unfocus_leave;
 
-ObPlacePolicy config_place_policy;
-gboolean      config_place_center;
-gboolean      config_place_active;
+ObPlacePolicy  config_place_policy;
+gboolean       config_place_center;
+ObPlaceMonitor config_place_monitor;
+
+guint          config_primary_monitor_index;
+ObPlaceMonitor config_primary_monitor;
 
 StrutPartial config_margins;
 
 gchar   *config_theme;
 gboolean config_theme_keepborder;
+guint    config_theme_window_list_icon_size;
 
 gchar   *config_title_layout;
 
@@ -53,7 +57,8 @@ RrFont *config_font_activewindow;
 RrFont *config_font_inactivewindow;
 RrFont *config_font_menuitem;
 RrFont *config_font_menutitle;
-RrFont *config_font_osd;
+RrFont *config_font_activeosd;
+RrFont *config_font_inactiveosd;
 
 guint   config_desktops_num;
 GSList *config_desktops_names;
@@ -81,14 +86,17 @@ guint           config_dock_app_move_modifiers;
 guint config_keyboard_reset_keycode;
 guint config_keyboard_reset_state;
 
-gint config_mouse_threshold;
-gint config_mouse_dclicktime;
-gint config_mouse_screenedgetime;
+gint     config_mouse_threshold;
+gint     config_mouse_dclicktime;
+gint     config_mouse_screenedgetime;
+gboolean config_mouse_screenedgewarp;
 
 guint    config_menu_hide_delay;
 gboolean config_menu_middle;
 guint    config_submenu_show_delay;
-gboolean config_menu_client_list_icons;
+guint    config_submenu_hide_delay;
+gboolean config_menu_manage_desktops;
+gboolean config_menu_show_icons;
 
 GSList *config_menu_files;
 
@@ -99,9 +107,11 @@ GSList *config_per_app_settings;
 
 ObAppSettings* config_create_app_settings(void)
 {
-    ObAppSettings *settings = g_new0(ObAppSettings, 1);
+    ObAppSettings *settings = g_slice_new0(ObAppSettings);
+    settings->type = -1;
     settings->decor = -1;
     settings->shade = -1;
+    settings->monitor_type = 0;
     settings->monitor = -1;
     settings->focus = -1;
     settings->desktop = 0;
@@ -123,8 +133,11 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
     g_assert(src != NULL);
     g_assert(dst != NULL);
 
+    copy_if(type, (ObClientType)-1);
     copy_if(decor, -1);
     copy_if(shade, -1);
+    copy_if(monitor_type, 0);
+    copy_if(monitor, -1);
     copy_if(focus, -1);
     copy_if(desktop, 0);
     copy_if(layer, -2);
@@ -137,24 +150,35 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
 
     if (src->pos_given) {
         dst->pos_given = TRUE;
+        dst->pos_force = src->pos_force;
         dst->position = src->position;
-        dst->monitor = src->monitor;
+        /* monitor is copied above */
+    }
+}
+
+void config_parse_relative_number(gchar *s, gint *num, gint *denom)
+{
+    *num = strtol(s, &s, 10);
+
+    if (*s == '%') {
+        *denom = 100;
+    } else if (*s == '/') {
+        *denom = atoi(s+1);
     }
 }
 
-static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node,
-                                       GravityCoord *c)
+void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
 {
-    gchar *s = parse_string(doc, node);
+    gchar *s = obt_xml_node_string(node);
     if (!g_ascii_strcasecmp(s, "center"))
         c->center = TRUE;
     else {
+        gchar *ps = s;
         if (s[0] == '-')
             c->opposite = TRUE;
         if (s[0] == '-' || s[0] == '+')
-            c->pos = atoi(s+1);
-        else
-            c->pos = atoi(s);
+            ps++;
+        config_parse_relative_number(ps, &c->pos, &c->denom);
     }
     g_free(s);
 }
@@ -178,8 +202,8 @@ static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node,
 
 /* Manages settings for individual applications.
    Some notes: monitor is the screen number in a multi monitor
-   (Xinerama) setup (starting from 0) or mouse, meaning the
-   monitor the pointer is on. Default: mouse.
+   (Xinerama) setup (starting from 0), or mouse: the monitor the pointer
+   is on, active: the active monitor, primary: the primary monitor.
    Layer can be three values, above (Always on top), below
    (Always on bottom) and everything else (normal behaviour).
    Positions can be an integer value or center, which will
@@ -187,22 +211,49 @@ static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node,
    the monitor, so <position><x>center</x></position><monitor>2</monitor>
    will center the window on the second monitor.
 */
-static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
-                                   xmlNodePtr node, gpointer data)
+static void parse_per_app_settings(xmlNodePtr node, gpointer d)
 {
-    xmlNodePtr app = parse_find_node("application", node->children);
-    gchar *name = NULL, *class = NULL, *role = NULL;
-    gboolean name_set, class_set;
+    xmlNodePtr app = obt_xml_find_node(node->children, "application");
+    gchar *name = NULL, *class = NULL, *role = NULL, *title = NULL,
+        *type_str = NULL;
+    gboolean name_set, class_set, type_set, role_set, title_set;
+    ObClientType type;
     gboolean x_pos_given;
 
     while (app) {
-        name_set = class_set = x_pos_given = FALSE;
+        x_pos_given = FALSE;
+
+        class_set = obt_xml_attr_string(app, "class", &class);
+        name_set = obt_xml_attr_string(app, "name", &name);
+        type_set = obt_xml_attr_string(app, "type", &type_str);
+        role_set = obt_xml_attr_string(app, "role", &role);
+        title_set = obt_xml_attr_string(app, "title", &title);
+
+        /* validate the type tho */
+        if (type_set) {
+            if (!g_ascii_strcasecmp(type_str, "normal"))
+                type = OB_CLIENT_TYPE_NORMAL;
+            else if (!g_ascii_strcasecmp(type_str, "dialog"))
+                type = OB_CLIENT_TYPE_DIALOG;
+            else if (!g_ascii_strcasecmp(type_str, "splash"))
+                type = OB_CLIENT_TYPE_SPLASH;
+            else if (!g_ascii_strcasecmp(type_str, "utility"))
+                type = OB_CLIENT_TYPE_UTILITY;
+            else if (!g_ascii_strcasecmp(type_str, "menu"))
+                type = OB_CLIENT_TYPE_MENU;
+            else if (!g_ascii_strcasecmp(type_str, "toolbar"))
+                type = OB_CLIENT_TYPE_TOOLBAR;
+            else if (!g_ascii_strcasecmp(type_str, "dock"))
+                type = OB_CLIENT_TYPE_DOCK;
+            else if (!g_ascii_strcasecmp(type_str, "desktop"))
+                type = OB_CLIENT_TYPE_DESKTOP;
+            else
+                type_set = FALSE; /* not valid! */
+        }
 
-        class_set = parse_attr_string("class", app, &class);
-        name_set = parse_attr_string("name", app, &name);
-        if (class_set || name_set) {
+        if (class_set || name_set || role_set || title_set || type_set) {
             xmlNodePtr n, c;
-            ObAppSettings *settings = config_create_app_settings();;
+            ObAppSettings *settings = config_create_app_settings();
 
             if (name_set)
                 settings->name = g_pattern_spec_new(name);
@@ -210,55 +261,68 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
             if (class_set)
                 settings->class = g_pattern_spec_new(class);
 
-            if (parse_attr_string("role", app, &role))
+            if (role_set)
                 settings->role = g_pattern_spec_new(role);
 
-            if ((n = parse_find_node("decor", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->decor = parse_bool(doc, n);
+            if (title_set)
+                settings->title = g_pattern_spec_new(title);
+
+            if (type_set)
+                settings->type = type;
 
-            if ((n = parse_find_node("shade", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->shade = parse_bool(doc, n);
+            if ((n = obt_xml_find_node(app->children, "decor")))
+                if (!obt_xml_node_contains(n, "default"))
+                    settings->decor = obt_xml_node_bool(n);
 
-            if ((n = parse_find_node("position", app->children))) {
-                if ((c = parse_find_node("x", n->children)))
-                    if (!parse_contains("default", doc, c)) {
-                        config_parse_gravity_coord(doc, c,
-                                                   &settings->position.x);
+            if ((n = obt_xml_find_node(app->children, "shade")))
+                if (!obt_xml_node_contains(n, "default"))
+                    settings->shade = obt_xml_node_bool(n);
+
+            if ((n = obt_xml_find_node(app->children, "position"))) {
+                if ((c = obt_xml_find_node(n->children, "x")))
+                    if (!obt_xml_node_contains(c, "default")) {
+                        config_parse_gravity_coord(c, &settings->position.x);
                         x_pos_given = TRUE;
                     }
 
-                if (x_pos_given && (c = parse_find_node("y", n->children)))
-                    if (!parse_contains("default", doc, c)) {
-                        config_parse_gravity_coord(doc, c,
-                                                   &settings->position.y);
+                if (x_pos_given && (c = obt_xml_find_node(n->children, "y")))
+                    if (!obt_xml_node_contains(c, "default")) {
+                        config_parse_gravity_coord(c, &settings->position.y);
                         settings->pos_given = TRUE;
                     }
 
                 if (settings->pos_given &&
-                    (c = parse_find_node("monitor", n->children)))
-                    if (!parse_contains("default", doc, c)) {
-                        gchar *s = parse_string(doc, c);
+                    (c = obt_xml_find_node(n->children, "monitor")))
+                    if (!obt_xml_node_contains(c, "default")) {
+                        gchar *s = obt_xml_node_string(c);
                         if (!g_ascii_strcasecmp(s, "mouse"))
-                            settings->monitor = 0;
+                            settings->monitor_type =
+                                    OB_APP_SETTINGS_MONITOR_MOUSE;
+                        else if (!g_ascii_strcasecmp(s, "active"))
+                            settings->monitor_type =
+                                    OB_APP_SETTINGS_MONITOR_ACTIVE;
+                        else if (!g_ascii_strcasecmp(s, "primary"))
+                            settings->monitor_type =
+                                    OB_APP_SETTINGS_MONITOR_PRIMARY;
                         else
-                            settings->monitor = parse_int(doc, c) + 1;
+                            settings->monitor = obt_xml_node_int(c);
                         g_free(s);
                     }
+
+                obt_xml_attr_bool(n, "force", &settings->pos_force);
             }
 
-            if ((n = parse_find_node("focus", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->focus = parse_bool(doc, n);
+            if ((n = obt_xml_find_node(app->children, "focus")))
+                if (!obt_xml_node_contains(n, "default"))
+                    settings->focus = obt_xml_node_bool(n);
 
-            if ((n = parse_find_node("desktop", app->children))) {
-                if (!parse_contains("default", doc, n)) {
-                    gchar *s = parse_string(doc, n);
+            if ((n = obt_xml_find_node(app->children, "desktop"))) {
+                if (!obt_xml_node_contains(n, "default")) {
+                    gchar *s = obt_xml_node_string(n);
                     if (!g_ascii_strcasecmp(s, "all"))
                         settings->desktop = DESKTOP_ALL;
                     else {
-                        gint i = parse_int(doc, n);
+                        gint i = obt_xml_node_int(n);
                         if (i > 0)
                             settings->desktop = i;
                     }
@@ -266,9 +330,9 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
                 }
             }
 
-            if ((n = parse_find_node("layer", app->children)))
-                if (!parse_contains("default", doc, n)) {
-                    gchar *s = parse_string(doc, n);
+            if ((n = obt_xml_find_node(app->children, "layer")))
+                if (!obt_xml_node_contains(n, "default")) {
+                    gchar *s = obt_xml_node_string(n);
                     if (!g_ascii_strcasecmp(s, "above"))
                         settings->layer = 1;
                     else if (!g_ascii_strcasecmp(s, "below"))
@@ -278,25 +342,25 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
                     g_free(s);
                 }
 
-            if ((n = parse_find_node("iconic", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->iconic = parse_bool(doc, n);
+            if ((n = obt_xml_find_node(app->children, "iconic")))
+                if (!obt_xml_node_contains(n, "default"))
+                    settings->iconic = obt_xml_node_bool(n);
 
-            if ((n = parse_find_node("skip_pager", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->skip_pager = parse_bool(doc, n);
+            if ((n = obt_xml_find_node(app->children, "skip_pager")))
+                if (!obt_xml_node_contains(n, "default"))
+                    settings->skip_pager = obt_xml_node_bool(n);
 
-            if ((n = parse_find_node("skip_taskbar", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->skip_taskbar = parse_bool(doc, n);
+            if ((n = obt_xml_find_node(app->children, "skip_taskbar")))
+                if (!obt_xml_node_contains(n, "default"))
+                    settings->skip_taskbar = obt_xml_node_bool(n);
 
-            if ((n = parse_find_node("fullscreen", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->fullscreen = parse_bool(doc, n);
+            if ((n = obt_xml_find_node(app->children, "fullscreen")))
+                if (!obt_xml_node_contains(n, "default"))
+                    settings->fullscreen = obt_xml_node_bool(n);
 
-            if ((n = parse_find_node("maximized", app->children)))
-                if (!parse_contains("default", doc, n)) {
-                    gchar *s = parse_string(doc, n);
+            if ((n = obt_xml_find_node(app->children, "maximized")))
+                if (!obt_xml_node_contains(n, "default")) {
+                    gchar *s = obt_xml_node_string(n);
                     if (!g_ascii_strcasecmp(s, "horizontal")) {
                         settings->max_horz = TRUE;
                         settings->max_vert = FALSE;
@@ -305,19 +369,21 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
                         settings->max_vert = TRUE;
                     } else
                         settings->max_horz = settings->max_vert =
-                            parse_bool(doc, n);
+                            obt_xml_node_bool(n);
                     g_free(s);
                 }
 
             config_per_app_settings = g_slist_append(config_per_app_settings,
-                                              (gpointer) settings);
+                                                     (gpointer) settings);
             g_free(name);
             g_free(class);
             g_free(role);
-            name = class = role = NULL;
+            g_free(title);
+            g_free(type_str);
+            name = class = role = title = type_str = NULL;
         }
 
-        app = parse_find_node("application", app->next);
+        app = obt_xml_find_node(app->next, "application");
     }
 }
 
@@ -331,63 +397,66 @@ static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
 
 */
 
-static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                      GList *keylist)
+static void parse_key(xmlNodePtr node, GList *keylist)
 {
-    gchar *key;
+    gchar *keystring, **keys, **key;
     xmlNodePtr n;
     gboolean is_chroot = FALSE;
 
-    if (!parse_attr_string("key", node, &key))
+    if (!obt_xml_attr_string(node, "key", &keystring))
         return;
 
-    parse_attr_bool("chroot", node, &is_chroot);
+    obt_xml_attr_bool(node, "chroot", &is_chroot);
 
-    keylist = g_list_append(keylist, key);
+    keys = g_strsplit(keystring, " ", 0);
+    for (key = keys; *key; ++key) {
+        keylist = g_list_append(keylist, *key);
 
-    if ((n = parse_find_node("keybind", node->children))) {
-        while (n) {
-            parse_key(i, doc, n, keylist);
-            n = parse_find_node("keybind", n->next);
+        if ((n = obt_xml_find_node(node->children, "keybind"))) {
+            while (n) {
+                parse_key(n, keylist);
+                n = obt_xml_find_node(n->next, "keybind");
+            }
         }
-    }
-    else if ((n = parse_find_node("action", node->children))) {
-        while (n) {
-            ObActionsAct *action;
+        else if ((n = obt_xml_find_node(node->children, "action"))) {
+            while (n) {
+                ObActionsAct *action;
 
-            action = actions_parse(i, doc, n);
-            if (action)
-                keyboard_bind(keylist, action);
-            n = parse_find_node("action", n->next);
+                action = actions_parse(n);
+                if (action)
+                    keyboard_bind(keylist, action);
+                n = obt_xml_find_node(n->next, "action");
+            }
         }
-    }
 
-    if (is_chroot)
-        keyboard_chroot(keylist);
 
-    g_free(key);
-    keylist = g_list_delete_link(keylist, g_list_last(keylist));
+        if (is_chroot)
+            keyboard_chroot(keylist);
+        keylist = g_list_delete_link(keylist, g_list_last(keylist));
+    }
+
+    g_strfreev(keys);
+    g_free(keystring);
 }
 
-static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                           gpointer data)
+static void parse_keyboard(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
     gchar *key;
 
     keyboard_unbind_all();
 
-    if ((n = parse_find_node("chainQuitKey", node->children))) {
-        key = parse_string(doc, n);
+    if ((n = obt_xml_find_node(node->children, "chainQuitKey"))) {
+        key = obt_xml_node_string(n);
         translate_key(key, &config_keyboard_reset_state,
                       &config_keyboard_reset_keycode);
         g_free(key);
     }
 
-    if ((n = parse_find_node("keybind", node->children)))
+    if ((n = obt_xml_find_node(node->children, "keybind")))
         while (n) {
-            parse_key(i, doc, n, NULL);
-            n = parse_find_node("keybind", n->next);
+            parse_key(n, NULL);
+            n = obt_xml_find_node(n->next, "keybind");
         }
 }
 
@@ -401,149 +470,193 @@ static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 
 */
 
-static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                        gpointer data)
+static void parse_mouse(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n, nbut, nact;
     gchar *buttonstr;
-    gchar *contextstr;
+    gchar *cxstr;
     ObMouseAction mact;
 
     mouse_unbind_all();
 
     node = node->children;
 
-    if ((n = parse_find_node("dragThreshold", node)))
-        config_mouse_threshold = parse_int(doc, n);
-    if ((n = parse_find_node("doubleClickTime", node)))
-        config_mouse_dclicktime = parse_int(doc, n);
-    if ((n = parse_find_node("screenEdgeWarpTime", node)))
-        config_mouse_screenedgetime = parse_int(doc, n);
+    if ((n = obt_xml_find_node(node, "dragThreshold")))
+        config_mouse_threshold = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "doubleClickTime")))
+        config_mouse_dclicktime = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "screenEdgeWarpTime"))) {
+        config_mouse_screenedgetime = obt_xml_node_int(n);
+        /* minimum value of 25 for this property, when it is 1 and you hit the
+           edge it basically never stops */
+        if (config_mouse_screenedgetime && config_mouse_screenedgetime < 25)
+            config_mouse_screenedgetime = 25;
+    }
+    if ((n = obt_xml_find_node(node, "screenEdgeWarpMouse")))
+        config_mouse_screenedgewarp = obt_xml_node_bool(n);
 
-    n = parse_find_node("context", node);
+    n = obt_xml_find_node(node, "context");
     while (n) {
-        if (!parse_attr_string("name", n, &contextstr))
+        gchar *modcxstr;
+        ObFrameContext cx;
+
+        if (!obt_xml_attr_string(n, "name", &cxstr))
             goto next_n;
-        nbut = parse_find_node("mousebind", n->children);
-        while (nbut) {
-            if (!parse_attr_string("button", nbut, &buttonstr))
-                goto next_nbut;
-            if (parse_attr_contains("press", nbut, "action")) {
-                mact = OB_MOUSE_ACTION_PRESS;
-            } else if (parse_attr_contains("release", nbut, "action")) {
-                mact = OB_MOUSE_ACTION_RELEASE;
-            } else if (parse_attr_contains("click", nbut, "action")) {
-                mact = OB_MOUSE_ACTION_CLICK;
-            } else if (parse_attr_contains("doubleclick", nbut,"action")) {
-                mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
-            } else if (parse_attr_contains("drag", nbut, "action")) {
-                mact = OB_MOUSE_ACTION_MOTION;
-            } else
-                goto next_nbut;
-            nact = parse_find_node("action", nbut->children);
-            while (nact) {
-                ObActionsAct *action;
 
-                if ((action = actions_parse(i, doc, nact)))
-                    mouse_bind(buttonstr, contextstr, mact, action);
-                nact = parse_find_node("action", nact->next);
+        modcxstr = g_strdup(cxstr); /* make a copy to mutilate */
+        while (frame_next_context_from_string(modcxstr, &cx)) {
+            if (!cx) {
+                gchar *s = strchr(modcxstr, ' ');
+                if (s) {
+                    *s = '\0';
+                    g_message(_("Invalid context \"%s\" in mouse binding"),
+                              modcxstr);
+                    *s = ' ';
+                }
+                continue;
             }
+
+            nbut = obt_xml_find_node(n->children, "mousebind");
+            while (nbut) {
+                if (!obt_xml_attr_string(nbut, "button", &buttonstr))
+                    goto next_nbut;
+                if (obt_xml_attr_contains(nbut, "action", "press"))
+                    mact = OB_MOUSE_ACTION_PRESS;
+                else if (obt_xml_attr_contains(nbut, "action", "release"))
+                    mact = OB_MOUSE_ACTION_RELEASE;
+                else if (obt_xml_attr_contains(nbut, "action", "click"))
+                    mact = OB_MOUSE_ACTION_CLICK;
+                else if (obt_xml_attr_contains(nbut, "action","doubleclick"))
+                    mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
+                else if (obt_xml_attr_contains(nbut, "action", "drag"))
+                    mact = OB_MOUSE_ACTION_MOTION;
+                else
+                    goto next_nbut;
+
+                nact = obt_xml_find_node(nbut->children, "action");
+                while (nact) {
+                    ObActionsAct *action;
+
+                    if ((action = actions_parse(nact)))
+                        mouse_bind(buttonstr, cx, mact, action);
+                    nact = obt_xml_find_node(nact->next, "action");
+                }
             g_free(buttonstr);
-        next_nbut:
-            nbut = parse_find_node("mousebind", nbut->next);
+            next_nbut:
+            nbut = obt_xml_find_node(nbut->next, "mousebind");
+            }
         }
-        g_free(contextstr);
+        g_free(modcxstr);
+        g_free(cxstr);
     next_n:
-        n = parse_find_node("context", n->next);
+        n = obt_xml_find_node(n->next, "context");
     }
 }
 
-static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                        gpointer data)
+static void parse_focus(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
 
-    if ((n = parse_find_node("focusNew", node)))
-        config_focus_new = parse_bool(doc, n);
-    if ((n = parse_find_node("followMouse", node)))
-        config_focus_follow = parse_bool(doc, n);
-    if ((n = parse_find_node("focusDelay", node)))
-        config_focus_delay = parse_int(doc, n);
-    if ((n = parse_find_node("raiseOnFocus", node)))
-        config_focus_raise = parse_bool(doc, n);
-    if ((n = parse_find_node("focusLast", node)))
-        config_focus_last = parse_bool(doc, n);
-    if ((n = parse_find_node("underMouse", node)))
-        config_focus_under_mouse = parse_bool(doc, n);
+    if ((n = obt_xml_find_node(node, "focusNew")))
+        config_focus_new = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "followMouse")))
+        config_focus_follow = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "focusDelay")))
+        config_focus_delay = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "raiseOnFocus")))
+        config_focus_raise = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "focusLast")))
+        config_focus_last = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "underMouse")))
+        config_focus_under_mouse = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "unfocusOnLeave")))
+        config_unfocus_leave = obt_xml_node_bool(n);
 }
 
-static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                            gpointer data)
+static void parse_placement(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
 
-    if ((n = parse_find_node("policy", node)))
-        if (parse_contains("UnderMouse", doc, n))
+    if ((n = obt_xml_find_node(node, "policy")))
+        if (obt_xml_node_contains(n, "UnderMouse"))
             config_place_policy = OB_PLACE_POLICY_MOUSE;
-    if ((n = parse_find_node("center", node)))
-        config_place_center = parse_bool(doc, n);
-    if ((n = parse_find_node("active", node)))
-        config_place_active = parse_bool(doc, n);
+    if ((n = obt_xml_find_node(node, "center")))
+        config_place_center = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "monitor"))) {
+        if (obt_xml_node_contains(n, "active"))
+            config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
+        else if (obt_xml_node_contains(n, "mouse"))
+            config_place_monitor = OB_PLACE_MONITOR_MOUSE;
+        else if (obt_xml_node_contains(n, "any"))
+            config_place_monitor = OB_PLACE_MONITOR_ANY;
+    }
+    if ((n = obt_xml_find_node(node, "primaryMonitor"))) {
+        config_primary_monitor_index = obt_xml_node_int(n);
+        if (!config_primary_monitor_index) {
+            if (obt_xml_node_contains(n, "mouse"))
+                config_primary_monitor = OB_PLACE_MONITOR_MOUSE;
+        }
+    }
 }
 
-static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                          gpointer data)
+static void parse_margins(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
 
-    if ((n = parse_find_node("top", node)))
-        config_margins.top = MAX(0, parse_int(doc, n));
-    if ((n = parse_find_node("left", node)))
-        config_margins.left = MAX(0, parse_int(doc, n));
-    if ((n = parse_find_node("right", node)))
-        config_margins.right = MAX(0, parse_int(doc, n));
-    if ((n = parse_find_node("bottom", node)))
-        config_margins.bottom = MAX(0, parse_int(doc, n));
+    if ((n = obt_xml_find_node(node, "top")))
+        config_margins.top = MAX(0, obt_xml_node_int(n));
+    if ((n = obt_xml_find_node(node, "left")))
+        config_margins.left = MAX(0, obt_xml_node_int(n));
+    if ((n = obt_xml_find_node(node, "right")))
+        config_margins.right = MAX(0, obt_xml_node_int(n));
+    if ((n = obt_xml_find_node(node, "bottom")))
+        config_margins.bottom = MAX(0, obt_xml_node_int(n));
 }
 
-static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                        gpointer data)
+static void parse_theme(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
 
-    if ((n = parse_find_node("name", node))) {
+    if ((n = obt_xml_find_node(node, "name"))) {
         gchar *c;
 
         g_free(config_theme);
-        c = parse_string(doc, n);
-        config_theme = parse_expand_tilde(c);
+        c = obt_xml_node_string(n);
+        config_theme = obt_paths_expand_tilde(c);
         g_free(c);
     }
-    if ((n = parse_find_node("titleLayout", node))) {
+    if ((n = obt_xml_find_node(node, "titleLayout"))) {
         gchar *c, *d;
 
         g_free(config_title_layout);
-        config_title_layout = parse_string(doc, n);
+        config_title_layout = obt_xml_node_string(n);
 
         /* replace duplicates with spaces */
         for (c = config_title_layout; *c != '\0'; ++c)
             for (d = c+1; *d != '\0'; ++d)
                 if (*c == *d) *d = ' ';
     }
-    if ((n = parse_find_node("keepBorder", node)))
-        config_theme_keepborder = parse_bool(doc, n);
-    if ((n = parse_find_node("animateIconify", node)))
-        config_animate_iconify = parse_bool(doc, n);
+    if ((n = obt_xml_find_node(node, "keepBorder")))
+        config_theme_keepborder = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "animateIconify")))
+        config_animate_iconify = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "windowListIconSize"))) {
+        config_theme_window_list_icon_size = obt_xml_node_int(n);
+        if (config_theme_window_list_icon_size < 16)
+            config_theme_window_list_icon_size = 16;
+        else if (config_theme_window_list_icon_size > 96)
+            config_theme_window_list_icon_size = 96;
+    }
 
-    n = parse_find_node("font", node);
+    n = obt_xml_find_node(node, "font");
     while (n) {
         xmlNodePtr   fnode;
         RrFont     **font;
@@ -552,35 +665,39 @@ static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
         RrFontWeight weight = RrDefaultFontWeight;
         RrFontSlant  slant = RrDefaultFontSlant;
 
-        if (parse_attr_contains("ActiveWindow", n, "place"))
+        if (obt_xml_attr_contains(n, "place", "ActiveWindow"))
             font = &config_font_activewindow;
-        else if (parse_attr_contains("InactiveWindow", n, "place"))
+        else if (obt_xml_attr_contains(n, "place", "InactiveWindow"))
             font = &config_font_inactivewindow;
-        else if (parse_attr_contains("MenuHeader", n, "place"))
+        else if (obt_xml_attr_contains(n, "place", "MenuHeader"))
             font = &config_font_menutitle;
-        else if (parse_attr_contains("MenuItem", n, "place"))
+        else if (obt_xml_attr_contains(n, "place", "MenuItem"))
             font = &config_font_menuitem;
-        else if (parse_attr_contains("OnScreenDisplay", n, "place"))
-            font = &config_font_osd;
+        else if (obt_xml_attr_contains(n, "place", "ActiveOnScreenDisplay"))
+            font = &config_font_activeosd;
+        else if (obt_xml_attr_contains(n, "place", "OnScreenDisplay"))
+            font = &config_font_activeosd;
+        else if (obt_xml_attr_contains(n, "place","InactiveOnScreenDisplay"))
+            font = &config_font_inactiveosd;
         else
             goto next_font;
 
-        if ((fnode = parse_find_node("name", n->children))) {
+        if ((fnode = obt_xml_find_node(n->children, "name"))) {
             g_free(name);
-            name = parse_string(doc, fnode);
+            name = obt_xml_node_string(fnode);
         }
-        if ((fnode = parse_find_node("size", n->children))) {
-            int s = parse_int(doc, fnode);
+        if ((fnode = obt_xml_find_node(n->children, "size"))) {
+            int s = obt_xml_node_int(fnode);
             if (s > 0) size = s;
         }
-        if ((fnode = parse_find_node("weight", n->children))) {
-            gchar *w = parse_string(doc, fnode);
+        if ((fnode = obt_xml_find_node(n->children, "weight"))) {
+            gchar *w = obt_xml_node_string(fnode);
             if (!g_ascii_strcasecmp(w, "Bold"))
                 weight = RR_FONTWEIGHT_BOLD;
             g_free(w);
         }
-        if ((fnode = parse_find_node("slant", n->children))) {
-            gchar *s = parse_string(doc, fnode);
+        if ((fnode = obt_xml_find_node(n->children, "slant"))) {
+            gchar *s = obt_xml_node_string(fnode);
             if (!g_ascii_strcasecmp(s, "Italic"))
                 slant = RR_FONTSLANT_ITALIC;
             if (!g_ascii_strcasecmp(s, "Oblique"))
@@ -591,28 +708,27 @@ static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
         *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
         g_free(name);
     next_font:
-        n = parse_find_node("font", n->next);
+        n = obt_xml_find_node(n->next, "font");
     }
 }
 
-static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                           gpointer data)
+static void parse_desktops(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
 
-    if ((n = parse_find_node("number", node))) {
-        gint d = parse_int(doc, n);
+    if ((n = obt_xml_find_node(node, "number"))) {
+        gint d = obt_xml_node_int(n);
         if (d > 0)
             config_desktops_num = (unsigned) d;
     }
-    if ((n = parse_find_node("firstdesk", node))) {
-        gint d = parse_int(doc, n);
+    if ((n = obt_xml_find_node(node, "firstdesk"))) {
+        gint d = obt_xml_node_int(n);
         if (d > 0)
             config_screen_firstdesk = (unsigned) d;
     }
-    if ((n = parse_find_node("names", node))) {
+    if ((n = obt_xml_find_node(node, "names"))) {
         GSList *it;
         xmlNodePtr nname;
 
@@ -621,168 +737,179 @@ static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
         g_slist_free(config_desktops_names);
         config_desktops_names = NULL;
 
-        nname = parse_find_node("name", n->children);
+        nname = obt_xml_find_node(n->children, "name");
         while (nname) {
-            config_desktops_names = g_slist_append(config_desktops_names,
-                                                   parse_string(doc, nname));
-            nname = parse_find_node("name", nname->next);
+            config_desktops_names =
+                g_slist_append(config_desktops_names,
+                               obt_xml_node_string(nname));
+            nname = obt_xml_find_node(nname->next, "name");
         }
     }
-    if ((n = parse_find_node("popupTime", node)))
-        config_desktop_popup_time = parse_int(doc, n);
+    if ((n = obt_xml_find_node(node, "popupTime")))
+        config_desktop_popup_time = obt_xml_node_int(n);
 }
 
-static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                         gpointer data)
+static void parse_resize(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
 
-    if ((n = parse_find_node("drawContents", node)))
-        config_resize_redraw = parse_bool(doc, n);
-    if ((n = parse_find_node("popupShow", node))) {
-        config_resize_popup_show = parse_int(doc, n);
-        if (parse_contains("Always", doc, n))
+    if ((n = obt_xml_find_node(node, "drawContents")))
+        config_resize_redraw = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "popupShow"))) {
+        config_resize_popup_show = obt_xml_node_int(n);
+        if (obt_xml_node_contains(n, "Always"))
             config_resize_popup_show = 2;
-        else if (parse_contains("Never", doc, n))
+        else if (obt_xml_node_contains(n, "Never"))
             config_resize_popup_show = 0;
-        else if (parse_contains("Nonpixel", doc, n))
+        else if (obt_xml_node_contains(n, "Nonpixel"))
             config_resize_popup_show = 1;
     }
-    if ((n = parse_find_node("popupPosition", node))) {
-        if (parse_contains("Top", doc, n))
+    if ((n = obt_xml_find_node(node, "popupPosition"))) {
+        if (obt_xml_node_contains(n, "Top"))
             config_resize_popup_pos = OB_RESIZE_POS_TOP;
-        else if (parse_contains("Center", doc, n))
+        else if (obt_xml_node_contains(n, "Center"))
             config_resize_popup_pos = OB_RESIZE_POS_CENTER;
-        else if (parse_contains("Fixed", doc, n)) {
+        else if (obt_xml_node_contains(n, "Fixed")) {
             config_resize_popup_pos = OB_RESIZE_POS_FIXED;
 
-            if ((n = parse_find_node("popupFixedPosition", node))) {
+            if ((n = obt_xml_find_node(node, "popupFixedPosition"))) {
                 xmlNodePtr n2;
 
-                if ((n2 = parse_find_node("x", n->children)))
-                    config_parse_gravity_coord(doc, n2,
+                if ((n2 = obt_xml_find_node(n->children, "x")))
+                    config_parse_gravity_coord(n2,
                                                &config_resize_popup_fixed.x);
-                if ((n2 = parse_find_node("y", n->children)))
-                    config_parse_gravity_coord(doc, n2,
+                if ((n2 = obt_xml_find_node(n->children, "y")))
+                    config_parse_gravity_coord(n2,
                                                &config_resize_popup_fixed.y);
+
+                config_resize_popup_fixed.x.pos =
+                    MAX(config_resize_popup_fixed.x.pos, 0);
+                config_resize_popup_fixed.y.pos =
+                    MAX(config_resize_popup_fixed.y.pos, 0);
             }
         }
     }
 }
 
-static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                       gpointer data)
+static void parse_dock(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
 
-    if ((n = parse_find_node("position", node))) {
-        if (parse_contains("TopLeft", doc, n))
+    if ((n = obt_xml_find_node(node, "position"))) {
+        if (obt_xml_node_contains(n, "TopLeft"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_NORTHWEST;
-        else if (parse_contains("Top", doc, n))
+        else if (obt_xml_node_contains(n, "Top"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_NORTH;
-        else if (parse_contains("TopRight", doc, n))
+        else if (obt_xml_node_contains(n, "TopRight"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_NORTHEAST;
-        else if (parse_contains("Right", doc, n))
+        else if (obt_xml_node_contains(n, "Right"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_EAST;
-        else if (parse_contains("BottomRight", doc, n))
+        else if (obt_xml_node_contains(n, "BottomRight"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_SOUTHEAST;
-        else if (parse_contains("Bottom", doc, n))
+        else if (obt_xml_node_contains(n, "Bottom"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_SOUTH;
-        else if (parse_contains("BottomLeft", doc, n))
+        else if (obt_xml_node_contains(n, "BottomLeft"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_SOUTHWEST;
-        else if (parse_contains("Left", doc, n))
+        else if (obt_xml_node_contains(n, "Left"))
             config_dock_floating = FALSE,
             config_dock_pos = OB_DIRECTION_WEST;
-        else if (parse_contains("Floating", doc, n))
+        else if (obt_xml_node_contains(n, "Floating"))
             config_dock_floating = TRUE;
     }
     if (config_dock_floating) {
-        if ((n = parse_find_node("floatingX", node)))
-            config_dock_x = parse_int(doc, n);
-        if ((n = parse_find_node("floatingY", node)))
-            config_dock_y = parse_int(doc, n);
+        if ((n = obt_xml_find_node(node, "floatingX")))
+            config_dock_x = obt_xml_node_int(n);
+        if ((n = obt_xml_find_node(node, "floatingY")))
+            config_dock_y = obt_xml_node_int(n);
     } else {
-        if ((n = parse_find_node("noStrut", node)))
-            config_dock_nostrut = parse_bool(doc, n);
+        if ((n = obt_xml_find_node(node, "noStrut")))
+            config_dock_nostrut = obt_xml_node_bool(n);
     }
-    if ((n = parse_find_node("stacking", node))) {
-        if (parse_contains("above", doc, n))
-            config_dock_layer = OB_STACKING_LAYER_ABOVE;
-        else if (parse_contains("normal", doc, n))
+    if ((n = obt_xml_find_node(node, "stacking"))) {
+        if (obt_xml_node_contains(n, "normal"))
             config_dock_layer = OB_STACKING_LAYER_NORMAL;
-        else if (parse_contains("below", doc, n))
+        else if (obt_xml_node_contains(n, "below"))
             config_dock_layer = OB_STACKING_LAYER_BELOW;
+        else if (obt_xml_node_contains(n, "above"))
+            config_dock_layer = OB_STACKING_LAYER_ABOVE;
     }
-    if ((n = parse_find_node("direction", node))) {
-        if (parse_contains("horizontal", doc, n))
+    if ((n = obt_xml_find_node(node, "direction"))) {
+        if (obt_xml_node_contains(n, "horizontal"))
             config_dock_orient = OB_ORIENTATION_HORZ;
-        else if (parse_contains("vertical", doc, n))
+        else if (obt_xml_node_contains(n, "vertical"))
             config_dock_orient = OB_ORIENTATION_VERT;
     }
-    if ((n = parse_find_node("autoHide", node)))
-        config_dock_hide = parse_bool(doc, n);
-    if ((n = parse_find_node("hideDelay", node)))
-        config_dock_hide_delay = parse_int(doc, n);
-    if ((n = parse_find_node("showDelay", node)))
-        config_dock_show_delay = parse_int(doc, n);
-    if ((n = parse_find_node("moveButton", node))) {
-        gchar *str = parse_string(doc, n);
+    if ((n = obt_xml_find_node(node, "autoHide")))
+        config_dock_hide = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "hideDelay")))
+        config_dock_hide_delay = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "showDelay")))
+        config_dock_show_delay = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "moveButton"))) {
+        gchar *str = obt_xml_node_string(n);
         guint b, s;
         if (translate_button(str, &s, &b)) {
             config_dock_app_move_button = b;
             config_dock_app_move_modifiers = s;
         } else {
-            g_message(_("Invalid button '%s' specified in config file"), str);
+            g_message(_("Invalid button \"%s\" specified in config file"), str);
         }
         g_free(str);
     }
 }
 
-static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                       gpointer data)
+static void parse_menu(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
-    for (node = node->children; node; node = node->next) {
-        if (!xmlStrcasecmp(node->name, (const xmlChar*) "file")) {
-            gchar *c;
+    node = node->children;
 
-            c = parse_string(doc, node);
+    if ((n = obt_xml_find_node(node, "hideDelay")))
+        config_menu_hide_delay = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "middle")))
+        config_menu_middle = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "submenuShowDelay")))
+        config_submenu_show_delay = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "submenuHideDelay")))
+        config_submenu_hide_delay = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "manageDesktops")))
+        config_menu_manage_desktops = obt_xml_node_bool(n);
+    if ((n = obt_xml_find_node(node, "showIcons"))) {
+        config_menu_show_icons = obt_xml_node_bool(n);
+#ifndef USE_IMLIB2
+        if (config_menu_show_icons)
+            g_message(_("Openbox was compiled without Imlib2 image loading support. Icons in menus will not be loaded."));
+#endif
+    }
+
+    while ((node = obt_xml_find_node(node, "file"))) {
+            gchar *c = obt_xml_node_string(node);
             config_menu_files = g_slist_append(config_menu_files,
-                                               parse_expand_tilde(c));
+                                               obt_paths_expand_tilde(c));
             g_free(c);
-        }
-        if ((n = parse_find_node("hideDelay", node)))
-            config_menu_hide_delay = parse_int(doc, n);
-        if ((n = parse_find_node("middle", node)))
-            config_menu_middle = parse_bool(doc, n);
-        if ((n = parse_find_node("submenuShowDelay", node)))
-            config_submenu_show_delay = parse_int(doc, n);
-        if ((n = parse_find_node("applicationIcons", node)))
-            config_menu_client_list_icons = parse_bool(doc, n);
+            node = node->next;
     }
 }
 
-static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                             gpointer data)
+static void parse_resistance(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n;
 
     node = node->children;
-    if ((n = parse_find_node("strength", node)))
-        config_resist_win = parse_int(doc, n);
-    if ((n = parse_find_node("screen_edge_strength", node)))
-        config_resist_edge = parse_int(doc, n);
+    if ((n = obt_xml_find_node(node, "strength")))
+        config_resist_win = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "screen_edge_strength")))
+        config_resist_edge = obt_xml_node_int(n);
 }
 
 typedef struct
@@ -869,11 +996,11 @@ static void bind_default_mouse(void)
     };
 
     for (it = binds; it->button; ++it)
-        mouse_bind(it->button, it->context, it->mact,
-                   actions_parse_string(it->actname));
+        mouse_bind(it->button, frame_context_from_string(it->context),
+                   it->mact, actions_parse_string(it->actname));
 }
 
-void config_startup(ObParseInst *i)
+void config_startup(ObtXmlInst *i)
 {
     config_focus_new = TRUE;
     config_focus_follow = FALSE;
@@ -881,38 +1008,45 @@ void config_startup(ObParseInst *i)
     config_focus_raise = FALSE;
     config_focus_last = TRUE;
     config_focus_under_mouse = FALSE;
+    config_unfocus_leave = FALSE;
 
-    parse_register(i, "focus", parse_focus, NULL);
+    obt_xml_register(i, "focus", parse_focus, NULL);
 
     config_place_policy = OB_PLACE_POLICY_SMART;
     config_place_center = TRUE;
-    config_place_active = FALSE;
+    config_place_monitor = OB_PLACE_MONITOR_PRIMARY;
 
-    parse_register(i, "placement", parse_placement, NULL);
+    config_primary_monitor_index = 1;
+    config_primary_monitor = OB_PLACE_MONITOR_ACTIVE;
+
+    obt_xml_register(i, "placement", parse_placement, NULL);
 
     STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 
-    parse_register(i, "margins", parse_margins, NULL);
+    obt_xml_register(i, "margins", parse_margins, NULL);
 
     config_theme = NULL;
 
     config_animate_iconify = TRUE;
     config_title_layout = g_strdup("NLIMC");
     config_theme_keepborder = TRUE;
+    config_theme_window_list_icon_size = 36;
 
     config_font_activewindow = NULL;
     config_font_inactivewindow = NULL;
     config_font_menuitem = NULL;
     config_font_menutitle = NULL;
+    config_font_activeosd = NULL;
+    config_font_inactiveosd = NULL;
 
-    parse_register(i, "theme", parse_theme, NULL);
+    obt_xml_register(i, "theme", parse_theme, NULL);
 
     config_desktops_num = 4;
     config_screen_firstdesk = 1;
     config_desktops_names = NULL;
     config_desktop_popup_time = 875;
 
-    parse_register(i, "desktops", parse_desktops, NULL);
+    obt_xml_register(i, "desktops", parse_desktops, NULL);
 
     config_resize_redraw = TRUE;
     config_resize_popup_show = 1; /* nonpixel increments */
@@ -920,7 +1054,7 @@ void config_startup(ObParseInst *i)
     GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
     GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
 
-    parse_register(i, "resize", parse_resize, NULL);
+    obt_xml_register(i, "resize", parse_resize, NULL);
 
     config_dock_layer = OB_STACKING_LAYER_ABOVE;
     config_dock_pos = OB_DIRECTION_NORTHEAST;
@@ -935,39 +1069,42 @@ void config_startup(ObParseInst *i)
     config_dock_app_move_button = 2; /* middle */
     config_dock_app_move_modifiers = 0;
 
-    parse_register(i, "dock", parse_dock, NULL);
+    obt_xml_register(i, "dock", parse_dock, NULL);
 
     translate_key("C-g", &config_keyboard_reset_state,
                   &config_keyboard_reset_keycode);
 
     bind_default_keyboard();
 
-    parse_register(i, "keyboard", parse_keyboard, NULL);
+    obt_xml_register(i, "keyboard", parse_keyboard, NULL);
 
     config_mouse_threshold = 8;
-    config_mouse_dclicktime = 200;
+    config_mouse_dclicktime = 500;
     config_mouse_screenedgetime = 400;
+    config_mouse_screenedgewarp = FALSE;
 
     bind_default_mouse();
 
-    parse_register(i, "mouse", parse_mouse, NULL);
+    obt_xml_register(i, "mouse", parse_mouse, NULL);
 
     config_resist_win = 10;
     config_resist_edge = 20;
 
-    parse_register(i, "resistance", parse_resistance, NULL);
+    obt_xml_register(i, "resistance", parse_resistance, NULL);
 
     config_menu_hide_delay = 250;
     config_menu_middle = FALSE;
-    config_submenu_show_delay = 0;
-    config_menu_client_list_icons = TRUE;
+    config_submenu_show_delay = 100;
+    config_submenu_hide_delay = 400;
+    config_menu_manage_desktops = TRUE;
     config_menu_files = NULL;
+    config_menu_show_icons = TRUE;
 
-    parse_register(i, "menu", parse_menu, NULL);
+    obt_xml_register(i, "menu", parse_menu, NULL);
 
     config_per_app_settings = NULL;
 
-    parse_register(i, "applications", parse_per_app_settings, NULL);
+    obt_xml_register(i, "applications", parse_per_app_settings, NULL);
 }
 
 void config_shutdown(void)
@@ -982,6 +1119,8 @@ void config_shutdown(void)
     RrFontClose(config_font_inactivewindow);
     RrFontClose(config_font_menuitem);
     RrFontClose(config_font_menutitle);
+    RrFontClose(config_font_activeosd);
+    RrFontClose(config_font_inactiveosd);
 
     for (it = config_desktops_names; it; it = g_slist_next(it))
         g_free(it->data);
@@ -995,8 +1134,9 @@ void config_shutdown(void)
         ObAppSettings *itd = (ObAppSettings *)it->data;
         if (itd->name)  g_pattern_spec_free(itd->name);
         if (itd->role)  g_pattern_spec_free(itd->role);
+        if (itd->title) g_pattern_spec_free(itd->title);
         if (itd->class) g_pattern_spec_free(itd->class);
-        g_free(it->data);
+        g_slice_free(ObAppSettings, it->data);
     }
     g_slist_free(config_per_app_settings);
 }