]> Dogcows Code - chaz/openbox/blobdiff - openbox/config.c
Merge branch 'master' into chaz
[chaz/openbox] / openbox / config.c
index e34bc158be876d0d035bf934e50c319e9c667ad7..64bf981c1bf0371cd2718fb2b8b0f65b4f619976 100644 (file)
 #include "config.h"
 #include "keyboard.h"
 #include "mouse.h"
-#include "prop.h"
+#include "actions.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;
@@ -34,11 +34,22 @@ 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;
+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;
+guint    config_frame_flash_delay;
+guint    config_frame_flash_duration;
 
 gchar   *config_title_layout;
 
@@ -48,16 +59,18 @@ 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;
 
-gint    config_desktops_num;
+guint   config_desktops_num;
 GSList *config_desktops_names;
 guint   config_screen_firstdesk;
+guint   config_desktop_popup_time;
 
-gboolean config_resize_redraw;
-gboolean config_resize_four_corners;
-gint     config_resize_popup_show;
-gint     config_resize_popup_pos;
+gboolean         config_resize_redraw;
+gint             config_resize_popup_show;
+ObResizePopupPos config_resize_popup_pos;
+GravityPoint     config_resize_popup_fixed;
 
 ObStackingLayer config_dock_layer;
 gboolean        config_dock_floating;
@@ -75,13 +88,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_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;
 
@@ -90,11 +107,13 @@ gint     config_resist_edge;
 
 GSList *config_per_app_settings;
 
-ObAppSettings* config_create_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 = OB_PLACE_MONITOR_ANY;
     settings->monitor = -1;
     settings->focus = -1;
     settings->desktop = 0;
@@ -105,6 +124,7 @@ ObAppSettings* config_create_app_settings()
     settings->fullscreen = -1;
     settings->max_horz = -1;
     settings->max_vert = -1;
+    settings->opacity = -1;
     return settings;
 }
 
@@ -116,8 +136,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, OB_PLACE_MONITOR_ANY);
+    copy_if(monitor, -1);
     copy_if(focus, -1);
     copy_if(desktop, 0);
     copy_if(layer, -2);
@@ -127,17 +150,48 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
     copy_if(fullscreen, -1);
     copy_if(max_horz, -1);
     copy_if(max_vert, -1);
+    copy_if(opacity, -1);
 
     if (src->pos_given) {
         dst->pos_given = TRUE;
-        dst->center_x = src->center_x;
-        dst->center_y = src->center_y;
-        dst->position.x = src->position.x;
-        dst->position.y = src->position.y;
-        dst->monitor = src->monitor;
+        dst->pos_force = src->pos_force;
+        dst->position = src->position;
+        /* monitor is copied above */
+    }
+
+    dst->width_num = src->width_num;
+    dst->width_denom = src->width_denom;
+    dst->height_num = src->height_num;
+    dst->height_denom = src->height_denom;
+}
+
+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);
     }
 }
 
+void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
+{
+    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] == '+')
+            ps++;
+        config_parse_relative_number(ps, &c->pos, &c->denom);
+    }
+    g_free(s);
+}
+
 /*
   <applications>
     <application name="aterm">
@@ -155,10 +209,153 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
   </applications>
 */
 
+static void parse_single_per_app_settings(xmlNodePtr app,
+                                          ObAppSettings *settings)
+{
+    xmlNodePtr n, c;
+    gboolean x_pos_given = FALSE;
+
+    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 = 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 = 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;
+            }
+        }
+
+        /* monitor can be set without setting x or y */
+        if ((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_type = OB_PLACE_MONITOR_MOUSE;
+                else if (!g_ascii_strcasecmp(s, "active"))
+                    settings->monitor_type = OB_PLACE_MONITOR_ACTIVE;
+                else if (!g_ascii_strcasecmp(s, "primary"))
+                    settings->monitor_type = OB_PLACE_MONITOR_PRIMARY;
+                else
+                    settings->monitor = obt_xml_node_int(c);
+                g_free(s);
+            }
+        }
+
+        obt_xml_attr_bool(n, "force", &settings->pos_force);
+    }
+
+    if ((n = obt_xml_find_node(app->children, "size"))) {
+        if ((c = obt_xml_find_node(n->children, "width"))) {
+            if (!obt_xml_node_contains(c, "default")) {
+                gchar *s = obt_xml_node_string(c);
+                config_parse_relative_number(s,
+                                             &settings->width_num,
+                                             &settings->width_denom);
+                if (settings->width_num <= 0 || settings->width_denom < 0)
+                    settings->width_num = settings->width_denom = 0;
+                g_free(s);
+            }
+        }
+
+        if ((c = obt_xml_find_node(n->children, "height"))) {
+            if (!obt_xml_node_contains(c, "default")) {
+                gchar *s = obt_xml_node_string(c);
+                config_parse_relative_number(s,
+                                             &settings->height_num,
+                                             &settings->height_denom);
+                if (settings->height_num <= 0 || settings->height_denom < 0)
+                    settings->height_num = settings->height_denom = 0;
+                g_free(s);
+            }
+        }
+    }
+
+    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 = 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 = obt_xml_node_int(n);
+                if (i > 0)
+                    settings->desktop = i;
+            }
+            g_free(s);
+        }
+    }
+
+    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"))
+                settings->layer = -1;
+            else
+                settings->layer = 0;
+            g_free(s);
+        }
+    }
+
+    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 = 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 = 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 = obt_xml_find_node(app->children, "fullscreen")))
+        if (!obt_xml_node_contains(n, "default"))
+            settings->fullscreen = obt_xml_node_bool(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;
+            } else if (!g_ascii_strcasecmp(s, "vertical")) {
+                settings->max_horz = FALSE;
+                settings->max_vert = TRUE;
+            } else
+                settings->max_horz = settings->max_vert =
+                    obt_xml_node_bool(n);
+            g_free(s);
+        }
+    }
+
+    if ((n = obt_xml_find_node(app->children, "opacity")))
+        if (!obt_xml_node_contains(n, "default"))
+            settings->opacity = obt_xml_node_int(n);
+}
+
 /* 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
@@ -166,150 +363,81 @@ void config_app_settings_copy_non_defaults(const ObAppSettings *src,
    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 *i, xmlDocPtr doc,
-                                   xmlNodePtr node, gpointer d)
+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;
-    gboolean x_pos_given;
-
-    while (app) {
-        name_set = class_set = x_pos_given = FALSE;
-
-        class_set = parse_attr_string("class", app, &class);
-        name_set = parse_attr_string("name", app, &name);
-        if (class_set || name_set) {
-            xmlNodePtr n, c;
-            ObAppSettings *settings = config_create_app_settings();;
-            
-            if (name_set)
-                settings->name = g_pattern_spec_new(name);
-
-            if (class_set)
-                settings->class = g_pattern_spec_new(class);
-
-            if (parse_attr_string("role", app, &role))
-                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 ((n = parse_find_node("shade", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->shade = parse_bool(doc, n);
-
-            if ((n = parse_find_node("position", app->children))) {
-                if ((c = parse_find_node("x", n->children)))
-                    if (!parse_contains("default", doc, c)) {
-                        gchar *s = parse_string(doc, c);
-                        if (!strcmp(s, "center")) {
-                            settings->center_x = TRUE;
-                            x_pos_given = TRUE;
-                        } else {
-                            settings->position.x = parse_int(doc, c);
-                            x_pos_given = TRUE;
-                        }
-                        g_free(s);
-                    }
-
-                if (x_pos_given && (c = parse_find_node("y", n->children)))
-                    if (!parse_contains("default", doc, c)) {
-                        gchar *s = parse_string(doc, c);
-                        if (!strcmp(s, "center")) {
-                            settings->center_y = TRUE;
-                            settings->pos_given = TRUE;
-                        } else {
-                            settings->position.y = parse_int(doc, c);
-                            settings->pos_given = TRUE;
-                        }
-                        g_free(s);
-                    }
-
-                if (settings->pos_given &&
-                    (c = parse_find_node("monitor", n->children)))
-                    if (!parse_contains("default", doc, c)) {
-                        gchar *s = parse_string(doc, c);
-                        if (!strcmp(s, "mouse"))
-                            settings->monitor = 0;
-                        else
-                            settings->monitor = parse_int(doc, c) + 1;
-                        g_free(s);
-                    }
-            }
-
-            if ((n = parse_find_node("focus", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->focus = parse_bool(doc, n);
-
-            if ((n = parse_find_node("desktop", app->children))) {
-                if (!parse_contains("default", doc, n)) {
-                    gchar *s = parse_string(doc, n);
-                    if (!strcmp(s, "all"))
-                        settings->desktop = DESKTOP_ALL;
-                    else {
-                        gint i = parse_int(doc, n);
-                        if (i > 0)
-                            settings->desktop = i;
-                    }
-                    g_free(s);
-                }
-            }
+    xmlNodePtr app = obt_xml_find_node(node->children, "application");
+    for (; app; app = obt_xml_find_node(app->next, "application")) {
+        ObAppSettings *settings;
+
+        gboolean name_set, class_set, role_set, title_set,
+            type_set, group_name_set, group_class_set;
+        gchar *name = NULL, *class = NULL, *role = NULL, *title = NULL,
+            *type_str = NULL, *group_name = NULL, *group_class = NULL;
+        ObClientType type;
+
+        class_set = obt_xml_attr_string(app, "class", &class);
+        name_set = obt_xml_attr_string(app, "name", &name);
+        group_class_set = obt_xml_attr_string(app, "groupclass", &group_class);
+        group_name_set = obt_xml_attr_string(app, "groupname", &group_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! */
+        }
 
-            if ((n = parse_find_node("layer", app->children)))
-                if (!parse_contains("default", doc, n)) {
-                    gchar *s = parse_string(doc, n);
-                    if (!strcmp(s, "above"))
-                        settings->layer = 1;
-                    else if (!strcmp(s, "below"))
-                        settings->layer = -1;
-                    else
-                        settings->layer = 0;
-                    g_free(s);
-                }
+        if (!(class_set || name_set || role_set || title_set ||
+              type_set || group_class_set || group_name_set))
+            continue;
+
+        settings = config_create_app_settings();
+
+        if (name_set)
+            settings->name = g_pattern_spec_new(name);
+        if (class_set)
+            settings->class = g_pattern_spec_new(class);
+        if (group_name_set)
+            settings->group_name = g_pattern_spec_new(group_name);
+        if (group_class_set)
+            settings->group_class = g_pattern_spec_new(group_class);
+        if (role_set)
+            settings->role = g_pattern_spec_new(role);
+        if (title_set)
+            settings->title = g_pattern_spec_new(title);
+        if (type_set)
+            settings->type = type;
 
-            if ((n = parse_find_node("iconic", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->iconic = parse_bool(doc, 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 = parse_find_node("skip_taskbar", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->skip_taskbar = parse_bool(doc, n);
-
-            if ((n = parse_find_node("fullscreen", app->children)))
-                if (!parse_contains("default", doc, n))
-                    settings->fullscreen = parse_bool(doc, n);
-
-            if ((n = parse_find_node("maximized", app->children)))
-                if (!parse_contains("default", doc, n)) {
-                    gchar *s = parse_string(doc, n);
-                    if (!strcmp(s, "horizontal")) {
-                        settings->max_horz = TRUE;
-                        settings->max_vert = FALSE;
-                    } else if (!strcmp(s, "vertical")) {
-                        settings->max_horz = FALSE;
-                        settings->max_vert = TRUE;
-                    } else
-                        settings->max_horz = settings->max_vert =
-                            parse_bool(doc, n);
-                    g_free(s);
-                }
-
-            config_per_app_settings = g_slist_append(config_per_app_settings,
-                                              (gpointer) settings);
-        }
-        
-        app = parse_find_node("application", app->next);
+        g_free(name);
+        g_free(class);
+        g_free(group_name);
+        g_free(group_class);
+        g_free(role);
+        g_free(title);
+        g_free(type_str);
+
+        parse_single_per_app_settings(app, settings);
+        config_per_app_settings = g_slist_append(config_per_app_settings,
+                                                 (gpointer)settings);
     }
-
-    g_free(name);
-    g_free(class);
-    g_free(role);
 }
 
 /*
@@ -322,69 +450,72 @@ static void parse_per_app_settings(ObParseInst *i, 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) {
-            ObAction *action;
-            
-            action = action_parse(i, doc, n, OB_USER_ACTION_KEYBOARD_KEY);
-            if (action)
-                keyboard_bind(keylist, action);
-            n = parse_find_node("action", n->next);
+        else if ((n = obt_xml_find_node(node->children, "action"))) {
+            while (n) {
+                ObActionsAct *action;
+
+                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 d)
+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");
         }
 }
 
 /*
 
-<context name="Titlebar"> 
+<context name="Titlebar">
   <mousebind button="Left" action="Press">
     <action name="Raise"></action>
   </mousebind>
@@ -392,131 +523,199 @@ static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 
 */
 
-static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
-                        gpointer d)
+static void parse_mouse(xmlNodePtr node, gpointer d)
 {
     xmlNodePtr n, nbut, nact;
     gchar *buttonstr;
-    gchar *contextstr;
-    ObUserAction uact;
+    gchar *cxstr;
     ObMouseAction mact;
-    ObAction *action;
 
     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);
 
-    n = parse_find_node("context", node);
+    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 = 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")) {
-                uact = OB_USER_ACTION_MOUSE_PRESS;
-                mact = OB_MOUSE_ACTION_PRESS;
-            } else if (parse_attr_contains("release", nbut, "action")) {
-                uact = OB_USER_ACTION_MOUSE_RELEASE;
-                mact = OB_MOUSE_ACTION_RELEASE;
-            } else if (parse_attr_contains("click", nbut, "action")) {
-                uact = OB_USER_ACTION_MOUSE_CLICK;
-                mact = OB_MOUSE_ACTION_CLICK;
-            } else if (parse_attr_contains("doubleclick", nbut,"action")) {
-                uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK;
-                mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
-            } else if (parse_attr_contains("drag", nbut, "action")) {
-                uact = OB_USER_ACTION_MOUSE_MOTION;
-                mact = OB_MOUSE_ACTION_MOTION;
-            } else
-                goto next_nbut;
-            nact = parse_find_node("action", nbut->children);
-            while (nact) {
-                if ((action = action_parse(i, doc, nact, uact)))
-                    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 d)
+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) * 1000;
-    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 d)
+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 = 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(xmlNodePtr node, gpointer d)
+{
+    xmlNodePtr n;
+
+    node = node->children;
+
+    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 d)
+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;
+    }
+    if ((n = obt_xml_find_node(node, "flashFrameDelay")))
+        config_frame_flash_delay = obt_xml_node_int(n);
+    if ((n = obt_xml_find_node(node, "flashFrameDuration")))
+        config_frame_flash_duration = obt_xml_node_int(n);
 
-    n = parse_find_node("font", node);
+    n = obt_xml_find_node(node, "font");
     while (n) {
         xmlNodePtr   fnode;
         RrFont     **font;
@@ -525,35 +724,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"))
@@ -564,28 +767,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 d)
+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 = d;
+            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;
 
@@ -594,153 +796,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 = 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 d)
+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))) {
-        config_resize_popup_pos = parse_int(doc, n);
-        if (parse_contains("Top", doc, n))
-            config_resize_popup_pos = 1;
-        else if (parse_contains("Center", doc, n))
-            config_resize_popup_pos = 0;
+    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 (obt_xml_node_contains(n, "Center"))
+            config_resize_popup_pos = OB_RESIZE_POS_CENTER;
+        else if (obt_xml_node_contains(n, "Fixed")) {
+            config_resize_popup_pos = OB_RESIZE_POS_FIXED;
+
+            if ((n = obt_xml_find_node(node, "popupFixedPosition"))) {
+                xmlNodePtr n2;
+
+                if ((n2 = obt_xml_find_node(n->children, "x")))
+                    config_parse_gravity_coord(n2,
+                                               &config_resize_popup_fixed.x);
+                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 d)
+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) * 1000;
-    if ((n = parse_find_node("showDelay", node)))
-        config_dock_show_delay = parse_int(doc, n) * 1000;
-    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 d)
+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;
+
+    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);
+#if !defined(USE_IMLIB2) && !defined(USE_LIBRSVG)
+        if (config_menu_show_icons)
+            g_message(_("Openbox was compiled without image loading support. Icons in menus will not be loaded."));
+#endif
+    }
 
-            c = parse_string(doc, node);
+    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 d)
+
+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
@@ -749,7 +977,7 @@ typedef struct
     const gchar *actname;
 } ObDefKeyBind;
 
-static void bind_default_keyboard()
+static void bind_default_keyboard(void)
 {
     ObDefKeyBind *it;
     ObDefKeyBind binds[] = {
@@ -758,11 +986,9 @@ static void bind_default_keyboard()
         { "A-F4", "Close" },
         { NULL, NULL }
     };
-
     for (it = binds; it->key; ++it) {
         GList *l = g_list_append(NULL, g_strdup(it->key));
-        keyboard_bind(l, action_from_string(it->actname,
-                                            OB_USER_ACTION_KEYBOARD_KEY));
+        keyboard_bind(l, actions_parse_string(it->actname));
     }
 }
 
@@ -774,7 +1000,7 @@ typedef struct
     const gchar *actname;
 } ObDefMouseBind;
 
-static void bind_default_mouse()
+static void bind_default_mouse(void)
 {
     ObDefMouseBind *it;
     ObDefMouseBind binds[] = {
@@ -810,7 +1036,7 @@ static void bind_default_mouse()
         { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "Raise" },
         { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "Raise" },
         { "Left", "Close", OB_MOUSE_ACTION_CLICK, "Close" },
-        { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximizeFull" },
+        { "Left", "Maximize", OB_MOUSE_ACTION_CLICK, "ToggleMaximize" },
         { "Left", "Iconify", OB_MOUSE_ACTION_CLICK, "Iconify" },
         { "Left", "AllDesktops", OB_MOUSE_ACTION_CLICK, "ToggleOmnipresent" },
         { "Left", "Shade", OB_MOUSE_ACTION_CLICK, "ToggleShade" },
@@ -818,34 +1044,22 @@ static void bind_default_mouse()
         { "Left", "TRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
         { "Left", "BLCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
         { "Left", "BRCorner", OB_MOUSE_ACTION_MOTION, "Resize" },
+        { "Left", "Top", OB_MOUSE_ACTION_MOTION, "Resize" },
+        { "Left", "Bottom", OB_MOUSE_ACTION_MOTION, "Resize" },
+        { "Left", "Left", OB_MOUSE_ACTION_MOTION, "Resize" },
+        { "Left", "Right", OB_MOUSE_ACTION_MOTION, "Resize" },
         { "Left", "Titlebar", OB_MOUSE_ACTION_MOTION, "Move" },
         { "A-Left", "Frame", OB_MOUSE_ACTION_MOTION, "Move" },
         { "A-Middle", "Frame", OB_MOUSE_ACTION_MOTION, "Resize" },
         { NULL, NULL, 0, NULL }
     };
 
-    for (it = binds; it->button; ++it) {
-        ObUserAction uact;
-        switch (it->mact) {
-        case OB_MOUSE_ACTION_PRESS:
-            uact = OB_USER_ACTION_MOUSE_PRESS; break;
-        case OB_MOUSE_ACTION_RELEASE:
-            uact = OB_USER_ACTION_MOUSE_RELEASE; break;
-        case OB_MOUSE_ACTION_CLICK:
-            uact = OB_USER_ACTION_MOUSE_CLICK; break;
-        case OB_MOUSE_ACTION_DOUBLE_CLICK:
-            uact = OB_USER_ACTION_MOUSE_DOUBLE_CLICK; break;
-        case OB_MOUSE_ACTION_MOTION:
-            uact = OB_USER_ACTION_MOUSE_MOTION; break;
-        default:
-            g_assert_not_reached();
-        }
-        mouse_bind(it->button, it->context, it->mact,
-                   action_from_string(it->actname, uact));
-    }
+    for (it = binds; it->button; ++it)
+        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;
@@ -853,38 +1067,55 @@ 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_monitor = OB_PLACE_MONITOR_PRIMARY;
+
+    config_primary_monitor_index = 1;
+    config_primary_monitor = OB_PLACE_MONITOR_ACTIVE;
 
-    parse_register(i, "placement", parse_placement, NULL);
+    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);
+
+    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_frame_flash_delay = 600;
+    config_frame_flash_duration = 5000;
 
     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_four_corners = FALSE;
     config_resize_popup_show = 1; /* nonpixel increments */
-    config_resize_popup_pos = 0;  /* center of client */
+    config_resize_popup_pos = OB_RESIZE_POS_CENTER;
+    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;
@@ -899,41 +1130,45 @@ 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 config_shutdown(void)
 {
     GSList *it;
 
@@ -945,6 +1180,8 @@ void config_shutdown()
     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);
@@ -956,10 +1193,13 @@ void config_shutdown()
 
     for (it = config_per_app_settings; it; it = g_slist_next(it)) {
         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->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);
+        if (itd->group_name) g_pattern_spec_free(itd->group_name);
+        if (itd->group_class) g_pattern_spec_free(itd->group_class);
+        g_slice_free(ObAppSettings, it->data);
     }
     g_slist_free(config_per_app_settings);
 }
This page took 0.055813 seconds and 4 git commands to generate.