]> Dogcows Code - chaz/openbox/commitdiff
Merge branch 'backport' into work
authorMikael Magnusson <mikachu@gmail.com>
Sun, 5 Jul 2009 20:27:25 +0000 (22:27 +0200)
committerMikael Magnusson <mikachu@gmail.com>
Sat, 19 Sep 2009 13:03:12 +0000 (15:03 +0200)
Conflicts:
openbox/actions/desktop.c
openbox/client.c
openbox/event.c
openbox/extensions.c
openbox/popup.c
openbox/screen.c
parser/parse.c

12 files changed:
1  2 
configure.ac
obt/paths.c
openbox/actions/desktop.c
openbox/actions/moveresizeto.c
openbox/client.c
openbox/event.c
openbox/frame.c
openbox/menu.c
openbox/popup.c
openbox/screen.c
openbox/startupnotify.c
render/theme.c

diff --combined configure.ac
index 9f8f26f6deffcb8e84336261c9ed7ffe502f3fb0,bba1b5c605674fbf10ad37b50e82ee7b14ad69c2..78d0753e172615d7088eee014f13b8d80d5396af
@@@ -4,65 -4,41 +4,65 @@@ AM_INIT_AUTOMAK
  AC_CONFIG_SRCDIR([openbox/openbox.c])
  
  dnl Making releases:
 -dnl   OB_MICRO_VERSION += 1;
 -dnl   OB_INTERFACE_AGE += 1;
 -dnl   OB_BINARY_AGE += 1;
 -dnl if any functions have been added, set OB_INTERFACE_AGE to 0.
 +dnl   RR_MICRO_VERSION += 1;
 +dnl   RR_INTERFACE_AGE += 1;
 +dnl   R_BINARY_AGE += 1;
 +dnl if any functions have been added, set RR_INTERFACE_AGE to 0.
  dnl if backwards compatibility has been broken,
 -dnl set OB_BINARY_AGE and OB_INTERFACE_AGE to 0.
 +dnl set RR_BINARY_AGE and RR_INTERFACE_AGE to 0.
  dnl
  dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
  dnl
 -OB_MAJOR_VERSION=3
 -OB_MINOR_VERSION=4
 -OB_MICRO_VERSION=16
 -OB_INTERFACE_AGE=0
 -OB_BINARY_AGE=0
 -OB_VERSION=$OB_MAJOR_VERSION.$OB_MINOR_VERSION
 -
 -AC_SUBST(OB_MAJOR_VERSION)
 -AC_SUBST(OB_MINOR_VERSION)
 -AC_SUBST(OB_MICRO_VERSION)
 -AC_SUBST(OB_INTERFACE_AGE)
 -AC_SUBST(OB_BINARY_AGE)
 -AC_SUBST(OB_VERSION)
 +RR_MAJOR_VERSION=4
 +RR_MINOR_VERSION=0
 +RR_MICRO_VERSION=17
 +RR_INTERFACE_AGE=0
 +RR_BINARY_AGE=0
 +RR_VERSION=$RR_MAJOR_VERSION.$RR_MINOR_VERSION
 +
 +OBT_MAJOR_VERSION=4
 +OBT_MINOR_VERSION=0
 +OBT_MICRO_VERSION=0
 +OBT_INTERFACE_AGE=0
 +OBT_BINARY_AGE=0
 +OBT_VERSION=$OBT_MAJOR_VERSION.$OBT_MINOR_VERSION
 +
 +AC_SUBST(RR_MAJOR_VERSION)
 +AC_SUBST(RR_MINOR_VERSION)
 +AC_SUBST(RR_MICRO_VERSION)
 +AC_SUBST(RR_INTERFACE_AGE)
 +AC_SUBST(RR_BINARY_AGE)
 +AC_SUBST(RR_VERSION)
 +AC_SUBST(OBT_MAJOR_VERSION)
 +AC_SUBST(OBT_MINOR_VERSION)
 +AC_SUBST(OBT_MICRO_VERSION)
 +AC_SUBST(OBT_INTERFACE_AGE)
 +AC_SUBST(OBT_BINARY_AGE)
 +AC_SUBST(OBT_VERSION)
  
  dnl Libtool versioning
 -LT_RELEASE=$OB_MAJOR_VERSION.$OB_MINOR_VERSION
 -LT_CURRENT=`expr $OB_MICRO_VERSION - $OB_INTERFACE_AGE`
 -LT_REVISION=$OB_INTERFACE_AGE
 -LT_AGE=`expr $OB_BINARY_AGE - $OB_INTERFACE_AGE`
 -LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
 -
 -AC_SUBST(LT_RELEASE)
 -AC_SUBST(LT_CURRENT)
 -AC_SUBST(LT_REVISION)
 -AC_SUBST(LT_AGE)
 -AC_SUBST(LT_CURRENT_MINUS_AGE)
 +RR_RELEASE=$RR_MAJOR_VERSION.$RR_MINOR_VERSION
 +RR_CURRENT=`expr $RR_MICRO_VERSION - $RR_INTERFACE_AGE`
 +RR_REVISION=$RR_INTERFACE_AGE
 +RR_AGE=`expr $RR_BINARY_AGE - $RR_INTERFACE_AGE`
 +RR_CURRENT_MINUS_AGE=`expr $RR_CURRENT - $RR_AGE`
 +
 +OBT_RELEASE=$OBT_MAJOR_VERSION.$OBT_MINOR_VERSION
 +OBT_CURRENT=`expr $OBT_MICRO_VERSION - $OBT_INTERFACE_AGE`
 +OBT_REVISION=$OBT_INTERFACE_AGE
 +OBT_AGE=`expr $OBT_BINARY_AGE - $OBT_INTERFACE_AGE`
 +OBT_CURRENT_MINUS_AGE=`expr $OBT_CURRENT - $OBT_AGE`
 +
 +AC_SUBST(RR_RELEASE)
 +AC_SUBST(RR_CURRENT)
 +AC_SUBST(RR_REVISION)
 +AC_SUBST(RR_AGE)
 +AC_SUBST(RR_CURRENT_MINUS_AGE)
 +AC_SUBST(OBT_RELEASE)
 +AC_SUBST(OBT_CURRENT)
 +AC_SUBST(OBT_REVISION)
 +AC_SUBST(OBT_AGE)
 +AC_SUBST(OBT_CURRENT_MINUS_AGE)
  
  AC_PREFIX_DEFAULT([/usr/local])
  test "$prefix" = "NONE" && prefix=$ac_default_prefix
@@@ -94,7 -70,7 +94,7 @@@ if test "$SED" = "no"; the
    AC_MSG_ERROR([The program "sed" is not available. This program is required to build Openbox.])
  fi
  
- PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.6.0])
+ PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.14.0])
  AC_SUBST(GLIB_CFLAGS)
  AC_SUBST(GLIB_LIBS)
  
@@@ -102,6 -78,10 +102,6 @@@ PKG_CHECK_MODULES(PANGO, [pango >= 1.8.
  AC_SUBST(PANGO_CFLAGS)
  AC_SUBST(PANGO_LIBS)
  
 -PKG_CHECK_MODULES(XFT, [xft])
 -AC_SUBST(XFT_CFLAGS)
 -AC_SUBST(XFT_LIBS)
 -
  PKG_CHECK_MODULES(XML, [libxml-2.0 >= 2.6.0])
  AC_SUBST(XML_CFLAGS)
  AC_SUBST(XML_LIBS)
@@@ -174,10 -154,9 +174,10 @@@ AC_CONFIG_FILES(
    Makefile
    m4/Makefile
    po/Makefile.in
 -  render/obrender-3.0.pc
 -  parser/obparser-3.0.pc
 -  version.h
 +  render/obrender-4.0.pc
 +  obt/obt-4.0.pc
 +  render/version.h
 +  obt/version.h
  ])
  AC_CONFIG_COMMANDS([doc],
                     [test -d doc || mkdir doc])
diff --combined obt/paths.c
index 6100499893e306a3dce92cd1fd041f49c20c85c2,0000000000000000000000000000000000000000..68615433e1d9426dc58cdf462050cbe89937cf6c
mode 100644,000000..100644
--- /dev/null
@@@ -1,247 -1,0 +1,249 @@@
-     gchar **spl;
 +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 +
 +   obt/paths.c for the Openbox window manager
 +   Copyright (c) 2003-2007   Dana Jansens
 +
 +   This program is free software; you can redistribute it and/or modify
 +   it under the terms of the GNU General Public License as published by
 +   the Free Software Foundation; either version 2 of the License, or
 +   (at your option) any later version.
 +
 +   This program is distributed in the hope that it will be useful,
 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +   GNU General Public License for more details.
 +
 +   See the COPYING file for a copy of the GNU General Public License.
 +*/
 +
 +#include "obt/paths.h"
 +#include "obt/util.h"
 +
 +#ifdef HAVE_SYS_STAT_H
 +#  include <sys/stat.h>
 +#endif
 +#ifdef HAVE_SYS_TYPES_H
 +#  include <sys/types.h>
 +#endif
 +#ifdef HAVE_STRING_H
 +#  include <string.h>
 +#endif
 +
 +struct _ObtPaths
 +{
 +    gint   ref;
 +    gchar  *config_home;
 +    gchar  *data_home;
 +    gchar  *cache_home;
 +    GSList *config_dirs;
 +    GSList *data_dirs;
 +};
 +
 +static gint slist_path_cmp(const gchar *a, const gchar *b)
 +{
 +    return strcmp(a, b);
 +}
 +
 +typedef GSList* (*GSListFunc) (gpointer list, gconstpointer data);
 +
 +static GSList* slist_path_add(GSList *list, gpointer data, GSListFunc func)
 +{
 +    g_assert(func);
 +
 +    if (!data)
 +        return list;
 +
 +    if (!g_slist_find_custom(list, data, (GCompareFunc) slist_path_cmp))
 +        list = func(list, data);
 +    else
 +        g_free(data);
 +
 +    return list;
 +}
 +
 +static GSList* split_paths(const gchar *paths)
 +{
 +    GSList *list = NULL;
 +    gchar **spl, **it;
 +
 +    if (!paths)
 +        return NULL;
 +    spl = g_strsplit(paths, ":", -1);
 +    for (it = spl; *it; ++it)
 +        list = slist_path_add(list, *it, (GSListFunc) g_slist_append);
 +    g_free(spl);
 +    return list;
 +}
 +
 +ObtPaths* obt_paths_new(void)
 +{
 +    ObtPaths *p;
 +    const gchar *path;
 +
 +    p = g_new0(ObtPaths, 1);
 +    p->ref = 1;
 +
 +    path = g_getenv("XDG_CONFIG_HOME");
 +    if (path && path[0] != '\0') /* not unset or empty */
 +        p->config_home = g_build_filename(path, NULL);
 +    else
 +        p->config_home = g_build_filename(g_get_home_dir(), ".config", NULL);
 +
 +    path = g_getenv("XDG_DATA_HOME");
 +    if (path && path[0] != '\0') /* not unset or empty */
 +        p->data_home = g_build_filename(path, NULL);
 +    else
 +        p->data_home = g_build_filename(g_get_home_dir(), ".local",
 +                                        "share", NULL);
 +
 +    path = g_getenv("XDG_CACHE_HOME");
 +    if (path && path[0] != '\0') /* not unset or empty */
 +        p->cache_home = g_build_filename(path, NULL);
 +    else
 +        p->cache_home = g_build_filename(g_get_home_dir(), ".cache", NULL);
 +
 +    path = g_getenv("XDG_CONFIG_DIRS");
 +    if (path && path[0] != '\0') /* not unset or empty */
 +        p->config_dirs = split_paths(path);
 +    else {
 +        p->config_dirs = slist_path_add(p->config_dirs,
 +                                        g_strdup(CONFIGDIR),
 +                                        (GSListFunc) g_slist_append);
 +        p->config_dirs = slist_path_add(p->config_dirs,
 +                                        g_build_filename
 +                                        (G_DIR_SEPARATOR_S,
 +                                         "etc", "xdg", NULL),
 +                                        (GSListFunc) g_slist_append);
 +    }
 +    p->config_dirs = slist_path_add(p->config_dirs,
 +                                    g_strdup(p->config_home),
 +                                    (GSListFunc) g_slist_prepend);
 +
 +    path = g_getenv("XDG_DATA_DIRS");
 +    if (path && path[0] != '\0') /* not unset or empty */
 +        p->data_dirs = split_paths(path);
 +    else {
 +        p->data_dirs = slist_path_add(p->data_dirs,
 +                                      g_strdup(DATADIR),
 +                                      (GSListFunc) g_slist_append);
 +        p->data_dirs = slist_path_add(p->data_dirs,
 +                                      g_build_filename
 +                                      (G_DIR_SEPARATOR_S,
 +                                       "usr", "local", "share", NULL),
 +                                      (GSListFunc) g_slist_append);
 +        p->data_dirs = slist_path_add(p->data_dirs,
 +                                      g_build_filename
 +                                      (G_DIR_SEPARATOR_S,
 +                                       "usr", "share", NULL),
 +                                      (GSListFunc) g_slist_append);
 +    }
 +    p->data_dirs = slist_path_add(p->data_dirs,
 +                                  g_strdup(p->data_home),
 +                                  (GSListFunc) g_slist_prepend);
 +    return p;
 +}
 +
 +void obt_paths_ref(ObtPaths *p)
 +{
 +    ++p->ref;
 +}
 +
 +void obt_paths_unref(ObtPaths *p)
 +{
 +    if (p && --p->ref == 0) {
 +        GSList *it;
 +
 +        for (it = p->config_dirs; it; it = g_slist_next(it))
 +            g_free(it->data);
 +        g_slist_free(p->config_dirs);
 +        for (it = p->data_dirs; it; it = g_slist_next(it))
 +            g_free(it->data);
 +        g_slist_free(p->data_dirs);
 +        g_free(p->config_home);
 +        g_free(p->data_home);
 +        g_free(p->cache_home);
 +
 +        obt_free0(p, ObtPaths, 1);
 +    }
 +}
 +
 +gchar *obt_paths_expand_tilde(const gchar *f)
 +{
-     spl = g_strsplit(f, "~", 0);
-     ret = g_strjoinv(g_get_home_dir(), spl);
-     g_strfreev(spl);
 +    gchar *ret;
++    GRegex *regex;
 +
 +    if (!f)
 +        return NULL;
++
++    regex = g_regex_new("(?:^|(?<=[ \\t]))~(?=[/ \\t$])", G_REGEX_MULTILINE | G_REGEX_RAW, 0, NULL);
++    ret = g_regex_replace_literal(regex, f, -1, 0, g_get_home_dir(), 0, NULL);
++    g_regex_unref(regex);
++
 +    return ret;
 +}
 +
 +gboolean obt_paths_mkdir(const gchar *path, gint mode)
 +{
 +    gboolean ret = TRUE;
 +
 +    g_return_val_if_fail(path != NULL, FALSE);
 +    g_return_val_if_fail(path[0] != '\0', FALSE);
 +
 +    if (!g_file_test(path, G_FILE_TEST_IS_DIR))
 +        if (mkdir(path, mode) == -1)
 +            ret = FALSE;
 +
 +    return ret;
 +}
 +
 +gboolean obt_paths_mkdir_path(const gchar *path, gint mode)
 +{
 +    gboolean ret = TRUE;
 +
 +    g_return_val_if_fail(path != NULL, FALSE);
 +    g_return_val_if_fail(path[0] == '/', FALSE);
 +
 +    if (!g_file_test(path, G_FILE_TEST_IS_DIR)) {
 +        gchar *c, *e;
 +
 +        c = g_strdup(path);
 +        e = c;
 +        while ((e = strchr(e + 1, '/'))) {
 +            *e = '\0';
 +            if (!(ret = obt_paths_mkdir(c, mode)))
 +                goto parse_mkdir_path_end;
 +            *e = '/';
 +        }
 +        ret = obt_paths_mkdir(c, mode);
 +
 +    parse_mkdir_path_end:
 +        g_free(c);
 +    }
 +
 +    return ret;
 +}
 +
 +const gchar* obt_paths_config_home(ObtPaths *p)
 +{
 +    return p->config_home;
 +}
 +
 +const gchar* obt_paths_data_home(ObtPaths *p)
 +{
 +    return p->data_home;
 +}
 +
 +const gchar* obt_paths_cache_home(ObtPaths *p)
 +{
 +    return p->cache_home;
 +}
 +
 +GSList* obt_paths_config_dirs(ObtPaths *p)
 +{
 +    return p->config_dirs;
 +}
 +
 +GSList* obt_paths_data_dirs(ObtPaths *p)
 +{
 +    return p->data_dirs;
 +}
index e352aa2e861d5fb042fc9368b474ddc1a8ce58e9,07416151cb7190b588b2272a0a4ad4ecc2060e69..edd22aa2bc7ac55bf632c56630c8f1669070bf8d
@@@ -21,13 -21,15 +21,13 @@@ typedef struct 
              gboolean wrap;
              ObDirection dir;
          } rel;
-     };
+     } u;
      gboolean send;
      gboolean follow;
  } Options;
  
 -static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc,
 -                                  xmlNodePtr node);
 -static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc,
 -                                xmlNodePtr node);
 +static gpointer setup_go_func(xmlNodePtr node);
 +static gpointer setup_send_func(xmlNodePtr node);
  static gboolean run_func(ObActionsData *data, gpointer options);
  
  void action_desktop_startup(void)
@@@ -38,7 -40,8 +38,7 @@@
                       NULL, NULL);
  }
  
 -static gpointer setup_go_func(ObParseInst *i, xmlDocPtr doc,
 -                                  xmlNodePtr node)
 +static gpointer setup_go_func(xmlNodePtr node)
  {
      xmlNodePtr n;
      Options *o;
      o = g_new0(Options, 1);
      /* don't go anywhere if theres no options given */
      o->type = ABSOLUTE;
-     o->abs.desktop = screen_desktop;
+     o->u.abs.desktop = screen_desktop;
      /* wrap by default - it's handy! */
-     o->rel.wrap = TRUE;
+     o->u.rel.wrap = TRUE;
  
 -    if ((n = parse_find_node("to", node))) {
 -        gchar *s = parse_string(doc, n);
 +    if ((n = obt_parse_find_node(node, "to"))) {
 +        gchar *s = obt_parse_node_string(n);
          if (!g_ascii_strcasecmp(s, "last"))
              o->type = LAST;
          else if (!g_ascii_strcasecmp(s, "next")) {
              o->type = RELATIVE;
-             o->rel.linear = TRUE;
-             o->rel.dir = OB_DIRECTION_EAST;
+             o->u.rel.linear = TRUE;
+             o->u.rel.dir = OB_DIRECTION_EAST;
          }
          else if (!g_ascii_strcasecmp(s, "previous")) {
              o->type = RELATIVE;
-             o->rel.linear = TRUE;
-             o->rel.dir = OB_DIRECTION_WEST;
+             o->u.rel.linear = TRUE;
+             o->u.rel.dir = OB_DIRECTION_WEST;
          }
          else if (!g_ascii_strcasecmp(s, "north") ||
                   !g_ascii_strcasecmp(s, "up")) {
              o->type = RELATIVE;
-             o->rel.dir = OB_DIRECTION_NORTH;
+             o->u.rel.dir = OB_DIRECTION_NORTH;
          }
          else if (!g_ascii_strcasecmp(s, "south") ||
                   !g_ascii_strcasecmp(s, "down")) {
              o->type = RELATIVE;
-             o->rel.dir = OB_DIRECTION_SOUTH;
+             o->u.rel.dir = OB_DIRECTION_SOUTH;
          }
          else if (!g_ascii_strcasecmp(s, "west") ||
                   !g_ascii_strcasecmp(s, "left")) {
              o->type = RELATIVE;
-             o->rel.dir = OB_DIRECTION_WEST;
+             o->u.rel.dir = OB_DIRECTION_WEST;
          }
          else if (!g_ascii_strcasecmp(s, "east") ||
                   !g_ascii_strcasecmp(s, "right")) {
              o->type = RELATIVE;
-             o->rel.dir = OB_DIRECTION_EAST;
+             o->u.rel.dir = OB_DIRECTION_EAST;
          }
          else {
              o->type = ABSOLUTE;
-             o->abs.desktop = atoi(s) - 1;
+             o->u.abs.desktop = atoi(s) - 1;
          }
          g_free(s);
      }
  
 -    if ((n = parse_find_node("wrap", node)))
 -        o->u.rel.wrap = parse_bool(doc, n);
 +    if ((n = obt_parse_find_node(node, "wrap")))
-         o->rel.wrap = obt_parse_node_bool(n);
++        o->u.rel.wrap = obt_parse_node_bool(n);
  
      return o;
  }
  
 -static gpointer setup_send_func(ObParseInst *i, xmlDocPtr doc,
 -                                xmlNodePtr node)
 +static gpointer setup_send_func(xmlNodePtr node)
  {
      xmlNodePtr n;
      Options *o;
  
 -    o = setup_go_func(i, doc, node);
 +    o = setup_go_func(node);
      o->send = TRUE;
      o->follow = TRUE;
  
 -    if ((n = parse_find_node("follow", node)))
 -        o->follow = parse_bool(doc, n);
 +    if ((n = obt_parse_find_node(node, "follow")))
 +        o->follow = obt_parse_node_bool(n);
  
      return o;
  }
@@@ -123,11 -127,11 +123,11 @@@ static gboolean run_func(ObActionsData 
          d = screen_last_desktop;
          break;
      case ABSOLUTE:
-         d = o->abs.desktop;
+         d = o->u.abs.desktop;
          break;
      case RELATIVE:
          d = screen_find_desktop(screen_desktop,
-                                 o->rel.dir, o->rel.wrap, o->rel.linear);
+                                 o->u.rel.dir, o->u.rel.wrap, o->u.rel.linear);
          break;
      }
  
index 357c7315d87b84c01e1de9b2a21197d4dcf4c933,acad73b50a578c91acad4d297936594868eb6f98..3ee3498a4cc3122c1c6dd054ff9ba918717ff6d9
@@@ -6,7 -6,9 +6,9 @@@
  
  enum {
      CURRENT_MONITOR = -1,
-     ALL_MONITORS = -2
+     ALL_MONITORS = -2,
+     NEXT_MONITOR = -3,
+     PREV_MONITOR = -4
  };
  
  typedef struct {
      gint monitor;
  } Options;
  
 -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 -static void     free_func(gpointer options);
 +static gpointer setup_func(xmlNodePtr node);
  static gboolean run_func(ObActionsData *data, gpointer options);
  
  void action_moveresizeto_startup(void)
  {
 -    actions_register("MoveResizeTo",
 -                     setup_func,
 -                     free_func,
 -                     run_func,
 -                     NULL, NULL);
 +    actions_register("MoveResizeTo", setup_func, g_free, run_func, NULL, NULL);
  }
  
 -static void parse_coord(xmlDocPtr doc, xmlNodePtr n, gint *pos,
 +static void parse_coord(xmlNodePtr n, gint *pos,
                          gboolean *opposite, gboolean *center)
  {
 -    gchar *s = parse_string(doc, n);
 +    gchar *s = obt_parse_node_string(n);
      if (g_ascii_strcasecmp(s, "current") != 0) {
          if (!g_ascii_strcasecmp(s, "center"))
              *center = TRUE;
@@@ -48,7 -55,7 +50,7 @@@
      g_free(s);
  }
  
 -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 +static gpointer setup_func(xmlNodePtr node)
  {
      xmlNodePtr n;
      Options *o;
      o->h = G_MININT;
      o->monitor = CURRENT_MONITOR;
  
 -    if ((n = parse_find_node("x", node)))
 -        parse_coord(doc, n, &o->x, &o->xopposite, &o->xcenter);
 +    if ((n = obt_parse_find_node(node, "x")))
 +        parse_coord(n, &o->x, &o->xopposite, &o->xcenter);
  
 -    if ((n = parse_find_node("y", node)))
 -        parse_coord(doc, n, &o->y, &o->yopposite, &o->ycenter);
 +    if ((n = obt_parse_find_node(node, "y")))
 +        parse_coord(n, &o->y, &o->yopposite, &o->ycenter);
  
 -    if ((n = parse_find_node("width", node))) {
 -        gchar *s = parse_string(doc, n);
 +    if ((n = obt_parse_find_node(node, "width"))) {
 +        gchar *s = obt_parse_node_string(n);
          if (g_ascii_strcasecmp(s, "current") != 0)
 -            o->w = parse_int(doc, n);
 +            o->w = obt_parse_node_int(n);
          g_free(s);
      }
 -    if ((n = parse_find_node("height", node))) {
 -        gchar *s = parse_string(doc, n);
 +    if ((n = obt_parse_find_node(node, "height"))) {
 +        gchar *s = obt_parse_node_string(n);
          if (g_ascii_strcasecmp(s, "current") != 0)
 -            o->h = parse_int(doc, n);
 +            o->h = obt_parse_node_int(n);
          g_free(s);
      }
  
 -    if ((n = parse_find_node("monitor", node))) {
 -        gchar *s = parse_string(doc, n);
 +    if ((n = obt_parse_find_node(node, "monitor"))) {
 +        gchar *s = obt_parse_node_string(n);
          if (g_ascii_strcasecmp(s, "current") != 0) {
              if (!g_ascii_strcasecmp(s, "all"))
                  o->monitor = ALL_MONITORS;
+             else if(!g_ascii_strcasecmp(s, "next"))
+                 o->monitor = NEXT_MONITOR;
+             else if(!g_ascii_strcasecmp(s, "prev"))
+                 o->monitor = PREV_MONITOR;
              else
 -                o->monitor = parse_int(doc, n) - 1;
 +                o->monitor = obt_parse_node_int(n) - 1;
          }
          g_free(s);
      }
      return o;
  }
  
 -static void free_func(gpointer options)
 -{
 -    Options *o = options;
 -
 -    g_free(o);
 -}
 -
  /* Always return FALSE because its not interactive */
  static gboolean run_func(ObActionsData *data, gpointer options)
  {
          cmon = client_monitor(c);
          if (mon == CURRENT_MONITOR) mon = cmon;
          else if (mon == ALL_MONITORS) mon = SCREEN_AREA_ALL_MONITORS;
+         else if (mon == NEXT_MONITOR) mon = (cmon + 1 > screen_num_monitors - 1) ? 0 : (cmon + 1);
+         else if (mon == PREV_MONITOR) mon = (cmon == 0) ? (screen_num_monitors - 1) : (cmon - 1);
          area = screen_area(c->desktop, mon, NULL);
          carea = screen_area(c->desktop, cmon, NULL);
  
diff --combined openbox/client.c
index d98ce642868ea112ad030ee76225ec172820cbe0,c1af196b5f08e90403cdd7c47fe0ba96a4515a18..38dc7c1ab81a1ed85d529d4a1fa339a2b62aa120
  #include "debug.h"
  #include "startupnotify.h"
  #include "dock.h"
 -#include "xerror.h"
  #include "screen.h"
  #include "moveresize.h"
  #include "ping.h"
  #include "place.h"
 -#include "prop.h"
 -#include "extensions.h"
  #include "frame.h"
  #include "session.h"
  #include "event.h"
@@@ -33,7 -36,6 +33,7 @@@
  #include "focus.h"
  #include "stacking.h"
  #include "openbox.h"
 +#include "hooks.h"
  #include "group.h"
  #include "config.h"
  #include "menuframe.h"
@@@ -41,8 -43,6 +41,8 @@@
  #include "mouse.h"
  #include "render/render.h"
  #include "gettext.h"
 +#include "obt/display.h"
 +#include "obt/prop.h"
  
  #ifdef HAVE_UNISTD_H
  #  include <unistd.h>
@@@ -184,8 -184,8 +184,8 @@@ void client_set_list(void
      } else
          windows = NULL;
  
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_client_list, window, (gulong*)windows, size);
 +    OBT_PROP_SETA32(obt_root(ob_screen), NET_CLIENT_LIST, WINDOW,
 +                    (gulong*)windows, size);
  
      if (windows)
          g_free(windows);
      stacking_set_list();
  }
  
 -void client_manage_all(void)
 -{
 -    guint i, j, nchild;
 -    Window w, *children;
 -    XWMHints *wmhints;
 -    XWindowAttributes attrib;
 -
 -    XQueryTree(ob_display, RootWindow(ob_display, ob_screen),
 -               &w, &w, &children, &nchild);
 -
 -    /* remove all icon windows from the list */
 -    for (i = 0; i < nchild; i++) {
 -        if (children[i] == None) continue;
 -        wmhints = XGetWMHints(ob_display, children[i]);
 -        if (wmhints) {
 -            if ((wmhints->flags & IconWindowHint) &&
 -                (wmhints->icon_window != children[i]))
 -                for (j = 0; j < nchild; j++)
 -                    if (children[j] == wmhints->icon_window) {
 -                        children[j] = None;
 -                        break;
 -                    }
 -            XFree(wmhints);
 -        }
 -    }
 -
 -    /* manage windows in reverse order from how they were originally mapped.
 -       this is an attempt to manage children windows before their parents, so
 -       that when the parent is mapped, it can find the child */
 -    for (i = 0; i < nchild; ++i) {
 -        if (children[i] == None)
 -            continue;
 -        if (XGetWindowAttributes(ob_display, children[i], &attrib)) {
 -            if (attrib.override_redirect) continue;
 -
 -            if (attrib.map_state != IsUnmapped)
 -                client_manage(children[i], NULL);
 -        }
 -    }
 -    XFree(children);
 -}
 -
  void client_manage(Window window, ObPrompt *prompt)
  {
      ObClient *self;
 -    XEvent e;
 -    XWindowAttributes attrib;
      XSetWindowAttributes attrib_set;
 -    XWMHints *wmhint;
      gboolean activate = FALSE;
      ObAppSettings *settings;
      gboolean transient = FALSE;
      Time launch_time, map_time;
      guint32 user_time;
  
 -    grab_server(TRUE);
 -
 -    /* check if it has already been unmapped by the time we started
 -       mapping. the grab does a sync so we don't have to here */
 -    if (XCheckTypedWindowEvent(ob_display, window, DestroyNotify, &e) ||
 -        XCheckTypedWindowEvent(ob_display, window, UnmapNotify, &e))
 -    {
 -        XPutBackEvent(ob_display, &e);
 -
 -        ob_debug("Trying to manage unmapped window. Aborting that.\n");
 -        grab_server(FALSE);
 -        return; /* don't manage it */
 -    }
 -
 -    /* make sure it isn't an override-redirect window */
 -    if (!XGetWindowAttributes(ob_display, window, &attrib) ||
 -        attrib.override_redirect)
 -    {
 -        grab_server(FALSE);
 -        return; /* don't manage it */
 -    }
 -
 -    /* is the window a docking app */
 -    if ((wmhint = XGetWMHints(ob_display, window))) {
 -        if ((wmhint->flags & StateHint) &&
 -            wmhint->initial_state == WithdrawnState)
 -        {
 -            dock_add(window, wmhint);
 -            grab_server(FALSE);
 -            XFree(wmhint);
 -            return;
 -        }
 -        XFree(wmhint);
 -    }
 -
 -    ob_debug("Managing window: 0x%lx\n", window);
 +    ob_debug("Managing window: 0x%lx", window);
  
      map_time = event_get_server_time();
  
      attrib_set.event_mask = CLIENT_EVENTMASK |
          (prompt ? prompt->event_mask : 0);
      attrib_set.do_not_propagate_mask = CLIENT_NOPROPAGATEMASK;
 -    XChangeWindowAttributes(ob_display, window,
 +    XChangeWindowAttributes(obt_display, window,
                              CWEventMask|CWDontPropagate, &attrib_set);
  
      /* create the ObClient struct, and populate it from the hints on the
         window */
      self = g_new0(ObClient, 1);
 -    self->obwin.type = Window_Client;
 +    self->obwin.type = OB_WINDOW_CLASS_CLIENT;
      self->window = window;
      self->prompt = prompt;
  
      /* get all the stuff off the window */
      client_get_all(self, TRUE);
  
 -    ob_debug("Window type: %d\n", self->type);
 -    ob_debug("Window group: 0x%x\n", self->group?self->group->leader:0);
 -    ob_debug("Window name: %s class: %s role: %s\n", self->name, self->class, self->role);
 +    ob_debug("Window type: %d", self->type);
 +    ob_debug("Window group: 0x%x", self->group?self->group->leader:0);
-     ob_debug("Window name: %s class: %s", self->name, self->class);
++    ob_debug("Window name: %s class: %s role: %s", self->name, self->class, self->role);
+     /* per-app settings override stuff from client_get_all, and return the
+        settings for other uses too. the returned settings is a shallow copy,
+        that needs to be freed with g_free(). */
+     settings = client_get_settings_state(self);
  
      /* now we have all of the window's information so we can set this up.
         do this before creating the frame, so it can tell that we are still
         should be reparented back to root automatically, unless we are managing
         an internal ObPrompt window  */
      if (!self->prompt)
 -        XChangeSaveSet(ob_display, window, SetModeInsert);
 +        XChangeSaveSet(obt_display, window, SetModeInsert);
  
      /* create the decoration frame for the client window */
      self->frame = frame_new(self);
         time now */
      grab_server(FALSE);
  
-     /* per-app settings override stuff from client_get_all, and return the
-        settings for other uses too. the returned settings is a shallow copy,
-        that needs to be freed with g_free(). */
-     settings = client_get_settings_state(self);
      /* the session should get the last say though */
      client_restore_session_state(self);
  
      /* tell startup notification that this app started */
      launch_time = sn_app_started(self->startup_id, self->class, self->name);
  
 -    if (!PROP_GET32(self->window, net_wm_user_time, cardinal, &user_time))
 +    if (!OBT_PROP_GET32(self->window, NET_WM_USER_TIME, CARDINAL, &user_time))
          user_time = map_time;
  
      /* do this after we have a frame.. it uses the frame to help determine the
      }
  
      /* remove the client's border */
 -    XSetWindowBorderWidth(ob_display, self->window, 0);
 +    XSetWindowBorderWidth(obt_display, self->window, 0);
  
      /* adjust the frame to the client's size before showing or placing
         the window */
  
      /* figure out placement for the window if the window is new */
      if (ob_state() == OB_STATE_RUNNING) {
 -        ob_debug("Positioned: %s @ %d %d\n",
 +        ob_debug("Positioned: %s @ %d %d",
                   (!self->positioned ? "no" :
                    (self->positioned == PPosition ? "program specified" :
                     (self->positioned == USPosition ? "user specified" :
                       "program + user specified" :
                       "BADNESS !?")))), place.x, place.y);
  
 -        ob_debug("Sized: %s @ %d %d\n",
 +        ob_debug("Sized: %s @ %d %d",
                   (!self->sized ? "no" :
                    (self->sized == PSize ? "program specified" :
                     (self->sized == USSize ? "user specified" :
          place.width = MIN(place.width, a->width);
          place.height = MIN(place.height, a->height);
  
 -        ob_debug("setting window size to %dx%d\n", place.width, place.height);
 +        ob_debug("setting window size to %dx%d", place.width, place.height);
  
          /* get the size of the client back */
          place.width -= self->frame->size.left + self->frame->size.right;
      }
  
      ob_debug("placing window 0x%x at %d, %d with size %d x %d. "
 -             "some restrictions may apply\n",
 +             "some restrictions may apply",
               self->window, place.x, place.y, place.width, place.height);
      if (self->session)
          ob_debug("  but session requested %d, %d  %d x %d instead, "
 -                 "overriding\n",
 +                 "overriding",
                   self->session->x, self->session->y,
                   self->session->w, self->session->h);
  
      g_free(monitor);
      monitor = NULL;
  
 -    ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s\n",
 +    ob_debug_type(OB_DEBUG_FOCUS, "Going to try activate new window? %s",
                    activate ? "yes" : "no");
      if (activate) {
          gboolean raise = FALSE;
          /* This is focus stealing prevention */
          ob_debug_type(OB_DEBUG_FOCUS,
                        "Want to focus new window 0x%x at time %u "
 -                      "launched at %u (last user interaction time %u)\n",
 +                      "launched at %u (last user interaction time %u)",
                        self->window, map_time, launch_time,
                        event_last_user_time);
 +        ob_debug_type(OB_DEBUG_FOCUS,
 +                      "Current focus_client: %s",
 +                      (focus_client ? focus_client->title : "(none)"));
 +        ob_debug_type(OB_DEBUG_FOCUS,
 +                      "parent focused: %d  relative focused: %d",
 +                      parent_focused, relative_focused);
  
          if (menu_frame_visible || moveresize_in_progress) {
              activate = FALSE;
              ob_debug_type(OB_DEBUG_FOCUS,
                            "Not focusing the window because the user is inside "
                            "an Openbox menu or is move/resizing a window and "
 -                          "we don't want to interrupt them\n");
 +                          "we don't want to interrupt them");
          }
  
          /* if it's on another desktop */
              raise = TRUE;
              ob_debug_type(OB_DEBUG_FOCUS,
                            "Not focusing the window because its on another "
 -                          "desktop\n");
 +                          "desktop");
          }
          /* If something is focused... */
          else if (focus_client) {
                  ob_debug_type(OB_DEBUG_FOCUS,
                                "Not focusing the window because the user is "
                                "working in another window that is not "
 -                              "its parent\n");
 +                              "its parent");
              }
              /* If the new window is a transient (and its relatives aren't
                 focused) */
                  activate = FALSE;
                  ob_debug_type(OB_DEBUG_FOCUS,
                                "Not focusing the window because it is a "
 -                              "transient, and its relatives aren't focused\n");
 +                              "transient, and its relatives aren't focused");
              }
              /* Don't steal focus from globally active clients.
                 I stole this idea from KWin. It seems nice.
                  activate = FALSE;
                  ob_debug_type(OB_DEBUG_FOCUS,
                                "Not focusing the window because a globally "
 -                              "active client has focus\n");
 +                              "active client has focus");
              }
              /* Don't move focus if it's not going to go to this window
                 anyway */
                  raise = TRUE;
                  ob_debug_type(OB_DEBUG_FOCUS,
                                "Not focusing the window because another window "
 -                              "would get the focus anyway\n");
 +                              "would get the focus anyway");
              }
              /* Don't move focus if the window is not visible on the current
                 desktop and none of its relatives are focused */
          if (!activate) {
              ob_debug_type(OB_DEBUG_FOCUS,
                            "Focus stealing prevention activated for %s at "
 -                          "time %u (last user interaction time %u)\n",
 +                          "time %u (last user interaction time %u)",
                            self->title, map_time, event_last_user_time);
              /* if the client isn't focused, then hilite it so the user
                 knows it is there */
  
      /* add to client list/map */
      client_list = g_list_append(client_list, self);
 -    g_hash_table_insert(window_map, &self->window, self);
 +    window_add(&self->window, CLIENT_AS_WINDOW(self));
  
      /* this has to happen after we're in the client_list */
      if (STRUT_EXISTS(self->strut))
      /* free the ObAppSettings shallow copy */
      g_free(settings);
  
 -    ob_debug("Managed window 0x%lx plate 0x%x (%s)\n",
 +    ob_debug("Managed window 0x%lx plate 0x%x (%s)",
               window, self->frame->window, self->class);
  
 -    return;
 +    hooks_queue(OB_HOOK_WIN_NEW, self);
  }
  
  ObClient *client_fake_manage(Window window)
      ObClient *self;
      ObAppSettings *settings;
  
 -    ob_debug("Pretend-managing window: %lx\n", window);
 +    ob_debug("Pretend-managing window: %lx", window);
  
      /* do this minimal stuff to figure out the client's decorations */
  
      self->frame = frame_new(self);
      frame_adjust_area(self->frame, FALSE, TRUE, TRUE);
  
 -    ob_debug("gave extents left %d right %d top %d bottom %d\n",
 +    ob_debug("gave extents left %d right %d top %d bottom %d",
               self->frame->size.left, self->frame->size.right,
               self->frame->size.top, self->frame->size.bottom);
  
@@@ -633,7 -708,7 +634,7 @@@ void client_unmanage(ObClient *self
      GSList *it;
      gulong ignore_start;
  
 -    ob_debug("Unmanaging window: 0x%x plate 0x%x (%s) (%s)\n",
 +    ob_debug("Unmanaging window: 0x%x plate 0x%x (%s) (%s)",
               self->window, self->frame->window,
               self->class, self->title ? self->title : "");
  
  
      /* we dont want events no more. do this before hiding the frame so we
         don't generate more events */
 -    XSelectInput(ob_display, self->window, NoEventMask);
 +    XSelectInput(obt_display, self->window, NoEventMask);
  
      /* ignore enter events from the unmap so it doesnt mess with the focus */
      if (!config_focus_under_mouse)
  
      frame_hide(self->frame);
      /* flush to send the hide to the server quickly */
 -    XFlush(ob_display);
 +    XFlush(obt_display);
  
      if (!config_focus_under_mouse)
          event_end_ignore_all_enters(ignore_start);
      /* remove the window from our save set, unless we are managing an internal
         ObPrompt window */
      if (!self->prompt)
 -        XChangeSaveSet(ob_display, self->window, SetModeDelete);
 +        XChangeSaveSet(obt_display, self->window, SetModeDelete);
 +
 +    /* this can't be queued to run later */
 +    hooks_run(OB_HOOK_WIN_CLOSE, self);
  
      /* update the focus lists */
      focus_order_remove(self);
  
      client_list = g_list_remove(client_list, self);
      stacking_remove(self);
 -    g_hash_table_remove(window_map, &self->window);
 +    window_remove(self->window);
  
      /* once the client is out of the list, update the struts to remove its
         influence */
          self->decorations = 0; /* unmanaged windows have no decor */
  
          /* give the client its border back */
 -        XSetWindowBorderWidth(ob_display, self->window, self->border_width);
 +        XSetWindowBorderWidth(obt_display, self->window, self->border_width);
  
          client_move_resize(self, a.x, a.y, a.width, a.height);
      }
      if (ob_state() != OB_STATE_EXITING) {
          /* these values should not be persisted across a window
             unmapping/mapping */
 -        PROP_ERASE(self->window, net_wm_desktop);
 -        PROP_ERASE(self->window, net_wm_state);
 -        PROP_ERASE(self->window, wm_state);
 +        OBT_PROP_ERASE(self->window, NET_WM_DESKTOP);
 +        OBT_PROP_ERASE(self->window, NET_WM_STATE);
 +        OBT_PROP_ERASE(self->window, WM_STATE);
      } else {
          /* if we're left in an unmapped state, the client wont be mapped.
             this is bad, since we will no longer be managing the window on
             restart */
 -        XMapWindow(ob_display, self->window);
 +        XMapWindow(obt_display, self->window);
      }
  
      /* these should not be left on the window ever.  other window managers
         don't necessarily use them and it will mess them up (like compiz) */
 -    PROP_ERASE(self->window, net_wm_visible_name);
 -    PROP_ERASE(self->window, net_wm_visible_icon_name);
 +    OBT_PROP_ERASE(self->window, NET_WM_VISIBLE_NAME);
 +    OBT_PROP_ERASE(self->window, NET_WM_VISIBLE_ICON_NAME);
  
      /* update the list hints */
      client_set_list();
  
 -    ob_debug("Unmanaged window 0x%lx\n", self->window);
 +    ob_debug("Unmanaged window 0x%lx", self->window);
  
      /* free all data allocated in the client struct */
      RrImageUnref(self->icon_set);
@@@ -819,7 -891,7 +820,7 @@@ static ObAppSettings *client_get_settin
              match = FALSE;
  
          if (match) {
 -            ob_debug("Window matching: %s\n", app->name);
 +            ob_debug("Window matching: %s", app->name);
  
              /* copy the settings to our struct, overriding the existing
                 settings if they are not defaults */
@@@ -874,17 -946,17 +875,17 @@@ static void client_restore_session_stat
      GList *it;
  
      ob_debug_type(OB_DEBUG_SM,
 -                  "Restore session for client %s\n", self->title);
 +                  "Restore session for client %s", self->title);
  
      if (!(it = session_state_find(self))) {
          ob_debug_type(OB_DEBUG_SM,
 -                      "Session data not found for client %s\n", self->title);
 +                      "Session data not found for client %s", self->title);
          return;
      }
  
      self->session = it->data;
  
 -    ob_debug_type(OB_DEBUG_SM, "Session data loaded for client %s\n",
 +    ob_debug_type(OB_DEBUG_SM, "Session data loaded for client %s",
                    self->title);
  
      RECT_SET_POINT(self->area, self->session->x, self->session->y);
          self->area.width = self->session->w;
      if (self->session->h > 0)
          self->area.height = self->session->h;
 -    XResizeWindow(ob_display, self->window,
 +    XResizeWindow(obt_display, self->window,
                    self->area.width, self->area.height);
  
      self->desktop = (self->session->desktop == DESKTOP_ALL ?
                       self->session->desktop :
                       MIN(screen_num_desktops - 1, self->session->desktop));
 -    PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
 +    OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, self->desktop);
  
      self->shaded = self->session->shaded;
      self->iconic = self->session->iconic;
@@@ -1127,11 -1199,10 +1128,11 @@@ static void client_get_all(ObClient *se
  
  static void client_get_startup_id(ObClient *self)
  {
 -    if (!(PROP_GETS(self->window, net_startup_id, utf8, &self->startup_id)))
 +    if (!(OBT_PROP_GETS(self->window, NET_STARTUP_ID, utf8,
 +                        &self->startup_id)))
          if (self->group)
 -            PROP_GETS(self->group->leader,
 -                      net_startup_id, utf8, &self->startup_id);
 +            OBT_PROP_GETS(self->group->leader,
 +                          NET_STARTUP_ID, utf8, &self->startup_id);
  }
  
  static void client_get_area(ObClient *self)
      XWindowAttributes wattrib;
      Status ret;
  
 -    ret = XGetWindowAttributes(ob_display, self->window, &wattrib);
 +    ret = XGetWindowAttributes(obt_display, self->window, &wattrib);
      g_assert(ret != BadWindow);
  
      RECT_SET(self->area, wattrib.x, wattrib.y, wattrib.width, wattrib.height);
      POINT_SET(self->root_pos, wattrib.x, wattrib.y);
      self->border_width = wattrib.border_width;
  
 -    ob_debug("client area: %d %d  %d %d  bw %d\n", wattrib.x, wattrib.y,
 +    ob_debug("client area: %d %d  %d %d  bw %d", wattrib.x, wattrib.y,
               wattrib.width, wattrib.height, wattrib.border_width);
  }
  
@@@ -1154,12 -1225,12 +1155,12 @@@ static void client_get_desktop(ObClien
  {
      guint32 d = screen_num_desktops; /* an always-invalid value */
  
 -    if (PROP_GET32(self->window, net_wm_desktop, cardinal, &d)) {
 +    if (OBT_PROP_GET32(self->window, NET_WM_DESKTOP, CARDINAL, &d)) {
          if (d >= screen_num_desktops && d != DESKTOP_ALL)
              self->desktop = screen_num_desktops - 1;
          else
              self->desktop = d;
 -        ob_debug("client requested desktop 0x%x\n", self->desktop);
 +        ob_debug("client requested desktop 0x%x", self->desktop);
      } else {
          GSList *it;
          gboolean first = TRUE;
          if (all != screen_num_desktops) {
              self->desktop = all;
  
 -            ob_debug("client desktop set from parents: 0x%x\n",
 +            ob_debug("client desktop set from parents: 0x%x",
                       self->desktop);
          }
          /* try get from the startup-notification protocol */
              if (self->desktop >= screen_num_desktops &&
                  self->desktop != DESKTOP_ALL)
                  self->desktop = screen_num_desktops - 1;
 -            ob_debug("client desktop set from startup-notification: 0x%x\n",
 +            ob_debug("client desktop set from startup-notification: 0x%x",
                       self->desktop);
          }
          /* defaults to the current desktop */
          else {
              self->desktop = screen_desktop;
 -            ob_debug("client desktop set to the current desktop: %d\n",
 +            ob_debug("client desktop set to the current desktop: %d",
                       self->desktop);
          }
      }
@@@ -1207,32 -1278,32 +1208,32 @@@ static void client_get_state(ObClient *
      guint32 *state;
      guint num;
  
 -    if (PROP_GETA32(self->window, net_wm_state, atom, &state, &num)) {
 +    if (OBT_PROP_GETA32(self->window, NET_WM_STATE, ATOM, &state, &num)) {
          gulong i;
          for (i = 0; i < num; ++i) {
 -            if (state[i] == prop_atoms.net_wm_state_modal)
 +            if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_MODAL))
                  self->modal = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_shaded)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_SHADED))
                  self->shaded = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_hidden)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_HIDDEN))
                  self->iconic = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_skip_taskbar)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR))
                  self->skip_taskbar = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_skip_pager)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER))
                  self->skip_pager = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_fullscreen)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN))
                  self->fullscreen = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_maximized_vert)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT))
                  self->max_vert = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_maximized_horz)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ))
                  self->max_horz = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_above)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_ABOVE))
                  self->above = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_below)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_BELOW))
                  self->below = TRUE;
 -            else if (state[i] == prop_atoms.net_wm_state_demands_attention)
 +            else if (state[i] == OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION))
                  self->demands_attention = TRUE;
 -            else if (state[i] == prop_atoms.ob_wm_state_undecorated)
 +            else if (state[i] == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
                  self->undecorated = TRUE;
          }
  
@@@ -1244,14 -1315,14 +1245,14 @@@ static void client_get_shaped(ObClient 
  {
      self->shaped = FALSE;
  #ifdef SHAPE
 -    if (extensions_shape) {
 +    if (obt_display_extension_shape) {
          gint foo;
          guint ufoo;
          gint s;
  
 -        XShapeSelectInput(ob_display, self->window, ShapeNotifyMask);
 +        XShapeSelectInput(obt_display, self->window, ShapeNotifyMask);
  
 -        XShapeQueryExtents(ob_display, self->window, &s, &foo,
 +        XShapeQueryExtents(obt_display, self->window, &s, &foo,
                             &foo, &ufoo, &ufoo, &foo, &foo, &foo, &ufoo,
                             &ufoo);
          self->shaped = !!s;
@@@ -1265,22 -1336,22 +1266,22 @@@ void client_update_transient_for(ObClie
      ObClient *target = NULL;
      gboolean trangroup = FALSE;
  
 -    if (XGetTransientForHint(ob_display, self->window, &t)) {
 +    if (XGetTransientForHint(obt_display, self->window, &t)) {
          if (t != self->window) { /* can't be transient to itself! */
 -            target = g_hash_table_lookup(window_map, &t);
 +            ObWindow *tw = window_find(t);
              /* if this happens then we need to check for it */
 -            g_assert(target != self);
 -            if (target && !WINDOW_IS_CLIENT(target)) {
 +            g_assert(tw != CLIENT_AS_WINDOW(self));
 +            if (tw && WINDOW_IS_CLIENT(tw)) {
                  /* watch out for windows with a parent that is something
                     different, like a dockapp for example */
 -                target = NULL;
 +                target = WINDOW_AS_CLIENT(tw);
              }
          }
  
          /* Setting the transient_for to Root is actually illegal, however
             applications from time have done this to specify transient for
             their group */
 -        if (!target && self->group && t == RootWindow(ob_display, ob_screen))
 +        if (!target && self->group && t == obt_root(ob_screen))
              trangroup = TRUE;
      } else if (self->group && self->transient)
          trangroup = TRUE;
@@@ -1415,8 -1486,8 +1416,8 @@@ static void client_get_mwm_hints(ObClie
  
      self->mwmhints.flags = 0; /* default to none */
  
 -    if (PROP_GETA32(self->window, motif_wm_hints, motif_wm_hints,
 -                    &hints, &num)) {
 +    if (OBT_PROP_GETA32(self->window, MOTIF_WM_HINTS, MOTIF_WM_HINTS,
 +                        &hints, &num)) {
          if (num >= OB_MWM_ELEMENTS) {
              self->mwmhints.flags = hints[0];
              self->mwmhints.functions = hints[1];
@@@ -1435,27 -1506,26 +1436,27 @@@ void client_get_type_and_transientness(
      self->type = -1;
      self->transient = FALSE;
  
 -    if (PROP_GETA32(self->window, net_wm_window_type, atom, &val, &num)) {
 +    if (OBT_PROP_GETA32(self->window, NET_WM_WINDOW_TYPE, ATOM, &val, &num)) {
          /* use the first value that we know about in the array */
          for (i = 0; i < num; ++i) {
 -            if (val[i] == prop_atoms.net_wm_window_type_desktop)
 +            if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DESKTOP))
                  self->type = OB_CLIENT_TYPE_DESKTOP;
 -            else if (val[i] == prop_atoms.net_wm_window_type_dock)
 +            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DOCK))
                  self->type = OB_CLIENT_TYPE_DOCK;
 -            else if (val[i] == prop_atoms.net_wm_window_type_toolbar)
 +            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_TOOLBAR))
                  self->type = OB_CLIENT_TYPE_TOOLBAR;
 -            else if (val[i] == prop_atoms.net_wm_window_type_menu)
 +            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_MENU))
                  self->type = OB_CLIENT_TYPE_MENU;
 -            else if (val[i] == prop_atoms.net_wm_window_type_utility)
 +            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_UTILITY))
                  self->type = OB_CLIENT_TYPE_UTILITY;
 -            else if (val[i] == prop_atoms.net_wm_window_type_splash)
 +            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_SPLASH))
                  self->type = OB_CLIENT_TYPE_SPLASH;
 -            else if (val[i] == prop_atoms.net_wm_window_type_dialog)
 +            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG))
                  self->type = OB_CLIENT_TYPE_DIALOG;
 -            else if (val[i] == prop_atoms.net_wm_window_type_normal)
 +            else if (val[i] == OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_NORMAL))
                  self->type = OB_CLIENT_TYPE_NORMAL;
 -            else if (val[i] == prop_atoms.kde_net_wm_window_type_override) {
 +            else if (val[i] == OBT_PROP_ATOM(KDE_NET_WM_WINDOW_TYPE_OVERRIDE))
 +            {
                  /* prevent this window from getting any decor or
                     functionality */
                  self->mwmhints.flags &= (OB_MWM_FLAG_FUNCTIONS |
          g_free(val);
      }
  
 -    if (XGetTransientForHint(ob_display, self->window, &t))
 +    if (XGetTransientForHint(obt_display, self->window, &t))
          self->transient = TRUE;
  
      if (self->type == (ObClientType) -1) {
  void client_update_protocols(ObClient *self)
  {
      guint32 *proto;
 -    guint num_return, i;
 +    guint num_ret, i;
  
      self->focus_notify = FALSE;
      self->delete_window = FALSE;
  
 -    if (PROP_GETA32(self->window, wm_protocols, atom, &proto, &num_return)) {
 -        for (i = 0; i < num_return; ++i) {
 -            if (proto[i] == prop_atoms.wm_delete_window)
 +    if (OBT_PROP_GETA32(self->window, WM_PROTOCOLS, ATOM, &proto, &num_ret)) {
 +        for (i = 0; i < num_ret; ++i) {
 +            if (proto[i] == OBT_PROP_ATOM(WM_DELETE_WINDOW))
                  /* this means we can request the window to close */
                  self->delete_window = TRUE;
 -            else if (proto[i] == prop_atoms.wm_take_focus)
 +            else if (proto[i] == OBT_PROP_ATOM(WM_TAKE_FOCUS))
                  /* if this protocol is requested, then the window will be
                     notified whenever we want it to receive focus */
                  self->focus_notify = TRUE;
 -            else if (proto[i] == prop_atoms.net_wm_ping)
 +            else if (proto[i] == OBT_PROP_ATOM(NET_WM_PING))
                  /* if this protocol is requested, then the window will allow
                     pings to determine if it is still alive */
                  self->ping = TRUE;
  #ifdef SYNC
 -            else if (proto[i] == prop_atoms.net_wm_sync_request)
 +            else if (proto[i] == OBT_PROP_ATOM(NET_WM_SYNC_REQUEST))
                  /* if this protocol is requested, then resizing the
                     window will be synchronized between the frame and the
                     client */
@@@ -1530,8 -1600,7 +1531,8 @@@ void client_update_sync_request_counter
  {
      guint32 i;
  
 -    if (PROP_GET32(self->window, net_wm_sync_request_counter, cardinal, &i)) {
 +    if (OBT_PROP_GET32(self->window, NET_WM_SYNC_REQUEST_COUNTER, CARDINAL,&i))
 +    {
          self->sync_counter = i;
      } else
          self->sync_counter = None;
@@@ -1542,7 -1611,7 +1543,7 @@@ static void client_get_colormap(ObClien
  {
      XWindowAttributes wa;
  
 -    if (XGetWindowAttributes(ob_display, self->window, &wa))
 +    if (XGetWindowAttributes(obt_display, self->window, &wa))
          client_update_colormap(self, wa.colormap);
  }
  
@@@ -1550,7 -1619,7 +1551,7 @@@ void client_update_colormap(ObClient *s
  {
      if (colormap == self->colormap) return;
  
 -    ob_debug("Setting client %s colormap: 0x%x\n", self->title, colormap);
 +    ob_debug("Setting client %s colormap: 0x%x", self->title, colormap);
  
      if (client_focused(self)) {
          screen_install_colormap(self, FALSE); /* uninstall old one */
@@@ -1574,7 -1643,7 +1575,7 @@@ void client_update_normal_hints(ObClien
      SIZE_SET(self->max_size, G_MAXINT, G_MAXINT);
  
      /* get the hints from the window */
 -    if (XGetWMNormalHints(ob_display, self->window, &size, &ret)) {
 +    if (XGetWMNormalHints(obt_display, self->window, &size, &ret)) {
          /* normal windows can't request placement! har har
          if (!client_normal(self))
          */
          if (size.flags & PResizeInc && size.width_inc && size.height_inc)
              SIZE_SET(self->size_inc, size.width_inc, size.height_inc);
  
 -        ob_debug("Normal hints: min size (%d %d) max size (%d %d)\n   "
 -                 "size inc (%d %d) base size (%d %d)\n",
 +        ob_debug("Normal hints: min size (%d %d) max size (%d %d)",
                   self->min_size.width, self->min_size.height,
 -                 self->max_size.width, self->max_size.height,
 +                 self->max_size.width, self->max_size.height);
 +        ob_debug("size inc (%d %d) base size (%d %d)",
                   self->size_inc.width, self->size_inc.height,
                   self->base_size.width, self->base_size.height);
      }
      else
 -        ob_debug("Normal hints: not set\n");
 +        ob_debug("Normal hints: not set");
  }
  
  void client_setup_decor_and_functions(ObClient *self, gboolean reconfig)
@@@ -1786,38 -1855,38 +1787,38 @@@ static void client_change_allowed_actio
  
      /* desktop windows are kept on all desktops */
      if (self->type != OB_CLIENT_TYPE_DESKTOP)
 -        actions[num++] = prop_atoms.net_wm_action_change_desktop;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_CHANGE_DESKTOP);
  
      if (self->functions & OB_CLIENT_FUNC_SHADE)
 -        actions[num++] = prop_atoms.net_wm_action_shade;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_SHADE);
      if (self->functions & OB_CLIENT_FUNC_CLOSE)
 -        actions[num++] = prop_atoms.net_wm_action_close;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_CLOSE);
      if (self->functions & OB_CLIENT_FUNC_MOVE)
 -        actions[num++] = prop_atoms.net_wm_action_move;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MOVE);
      if (self->functions & OB_CLIENT_FUNC_ICONIFY)
 -        actions[num++] = prop_atoms.net_wm_action_minimize;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MINIMIZE);
      if (self->functions & OB_CLIENT_FUNC_RESIZE)
 -        actions[num++] = prop_atoms.net_wm_action_resize;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_RESIZE);
      if (self->functions & OB_CLIENT_FUNC_FULLSCREEN)
 -        actions[num++] = prop_atoms.net_wm_action_fullscreen;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_FULLSCREEN);
      if (self->functions & OB_CLIENT_FUNC_MAXIMIZE) {
 -        actions[num++] = prop_atoms.net_wm_action_maximize_horz;
 -        actions[num++] = prop_atoms.net_wm_action_maximize_vert;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_HORZ);
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_VERT);
      }
      if (self->functions & OB_CLIENT_FUNC_ABOVE)
 -        actions[num++] = prop_atoms.net_wm_action_above;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_ABOVE);
      if (self->functions & OB_CLIENT_FUNC_BELOW)
 -        actions[num++] = prop_atoms.net_wm_action_below;
 +        actions[num++] = OBT_PROP_ATOM(NET_WM_ACTION_BELOW);
      if (self->functions & OB_CLIENT_FUNC_UNDECORATE)
 -        actions[num++] = prop_atoms.ob_wm_action_undecorate;
 +        actions[num++] = OBT_PROP_ATOM(OB_WM_ACTION_UNDECORATE);
  
 -    PROP_SETA32(self->window, net_wm_allowed_actions, atom, actions, num);
 +    OBT_PROP_SETA32(self->window, NET_WM_ALLOWED_ACTIONS, ATOM, actions, num);
  
 -   /* make sure the window isn't breaking any rules now
 +    /* make sure the window isn't breaking any rules now
  
 -   don't check ICONIFY here.  just cuz a window can't iconify doesnt mean
 -   it can't be iconified with its parent
 -   */
 +       don't check ICONIFY here.  just cuz a window can't iconify doesnt mean
 +       it can't be iconified with its parent
 +    */
  
      if (!(self->functions & OB_CLIENT_FUNC_SHADE) && self->shaded) {
          if (self->frame) client_shade(self, FALSE);
@@@ -1841,7 -1910,7 +1842,7 @@@ void client_update_wmhints(ObClient *se
      /* assume a window takes input if it doesn't specify */
      self->can_focus = TRUE;
  
 -    if ((hints = XGetWMHints(ob_display, self->window)) != NULL) {
 +    if ((hints = XGetWMHints(obt_display, self->window)) != NULL) {
          gboolean ur;
  
          if (hints->flags & InputHint)
@@@ -1930,10 -1999,10 +1931,10 @@@ void client_update_title(ObClient *self
      g_free(self->original_title);
  
      /* try netwm */
 -    if (!PROP_GETS(self->window, net_wm_name, utf8, &data)) {
 +    if (!OBT_PROP_GETS(self->window, NET_WM_NAME, utf8, &data)) {
          /* try old x stuff */
 -        if (!(PROP_GETS(self->window, wm_name, locale, &data)
 -              || PROP_GETS(self->window, wm_name, utf8, &data))) {
 +        if (!(OBT_PROP_GETS(self->window, WM_NAME, locale, &data)
 +              || OBT_PROP_GETS(self->window, WM_NAME, utf8, &data))) {
              if (self->transient) {
      /*
      GNOME alert windows are not given titles:
          g_free(data);
      }
  
 -    PROP_SETS(self->window, net_wm_visible_name, visible);
 +    OBT_PROP_SETS(self->window, NET_WM_VISIBLE_NAME, utf8, visible);
      self->title = visible;
  
      if (self->frame)
      g_free(self->icon_title);
  
      /* try netwm */
 -    if (!PROP_GETS(self->window, net_wm_icon_name, utf8, &data))
 +    if (!OBT_PROP_GETS(self->window, NET_WM_ICON_NAME, utf8, &data))
          /* try old x stuff */
 -        if (!(PROP_GETS(self->window, wm_icon_name, locale, &data) ||
 -              PROP_GETS(self->window, wm_icon_name, utf8, &data)))
 +        if (!(OBT_PROP_GETS(self->window, WM_ICON_NAME, locale, &data) ||
 +              OBT_PROP_GETS(self->window, WM_ICON_NAME, utf8, &data)))
              data = g_strdup(self->title);
  
      if (self->client_machine) {
          g_free(data);
      }
  
 -    PROP_SETS(self->window, net_wm_visible_icon_name, visible);
 +    OBT_PROP_SETS(self->window, NET_WM_VISIBLE_ICON_NAME, utf8, visible);
      self->icon_title = visible;
  }
  
@@@ -2004,9 -2073,8 +2005,9 @@@ void client_update_strut(ObClient *self
      gboolean got = FALSE;
      StrutPartial strut;
  
 -    if (PROP_GETA32(self->window, net_wm_strut_partial, cardinal,
 -                    &data, &num)) {
 +    if (OBT_PROP_GETA32(self->window, NET_WM_STRUT_PARTIAL, CARDINAL,
 +                        &data, &num))
 +    {
          if (num == 12) {
              got = TRUE;
              STRUT_PARTIAL_SET(strut,
      }
  
      if (!got &&
 -        PROP_GETA32(self->window, net_wm_strut, cardinal, &data, &num)) {
 +        OBT_PROP_GETA32(self->window, NET_WM_STRUT, CARDINAL, &data, &num)) {
          if (num == 4) {
              Rect *a;
  
@@@ -2067,7 -2135,7 +2068,7 @@@ void client_update_icons(ObClient *self
         icon */
      grab_server(TRUE);
  
 -    if (PROP_GETA32(self->window, net_wm_icon, cardinal, &data, &num)) {
 +    if (OBT_PROP_GETA32(self->window, NET_WM_ICON, CARDINAL, &data, &num)) {
          /* figure out how many valid icons are in here */
          i = 0;
          num_seen = 0;
      if (!img) {
          XWMHints *hints;
  
 -        if ((hints = XGetWMHints(ob_display, self->window))) {
 +        if ((hints = XGetWMHints(obt_display, self->window))) {
              if (hints->flags & IconPixmapHint) {
                  gboolean xicon;
 -                xerror_set_ignore(TRUE);
 +                obt_display_ignore_errors(TRUE);
                  xicon = RrPixmapToRGBA(ob_rr_inst,
                                         hints->icon_pixmap,
                                         (hints->flags & IconMaskHint ?
                                          hints->icon_mask : None),
                                         (gint*)&w, (gint*)&h, &data);
 -                xerror_set_ignore(FALSE);
 +                obt_display_ignore_errors(FALSE);
  
                  if (xicon) {
                      if (w > 0 && h > 0) {
                  (((icon[i] >> RrDefaultRedOffset) & 0xff) << 16) +
                  (((icon[i] >> RrDefaultGreenOffset) & 0xff) << 8) +
                  (((icon[i] >> RrDefaultBlueOffset) & 0xff) << 0);
 -        PROP_SETA32(self->window, net_wm_icon, cardinal, ldata, w*h+2);
 +        OBT_PROP_SETA32(self->window, NET_WM_ICON, CARDINAL, ldata, w*h+2);
          g_free(ldata);
      } else if (self->frame)
          /* don't draw the icon empty if we're just setting one now anyways,
@@@ -2188,8 -2256,7 +2189,8 @@@ void client_update_icon_geometry(ObClie
  
      RECT_SET(self->icon_geometry, 0, 0, 0, 0);
  
 -    if (PROP_GETA32(self->window, net_wm_icon_geometry, cardinal, &data, &num))
 +    if (OBT_PROP_GETA32(self->window, NET_WM_ICON_GEOMETRY, CARDINAL,
 +                        &data, &num))
      {
          if (num == 4)
              /* don't let them set it with an area < 0 */
@@@ -2206,23 -2273,23 +2207,23 @@@ static void client_get_session_ids(ObCl
      gchar *s;
      gchar **ss;
  
 -    if (!PROP_GET32(self->window, wm_client_leader, window, &leader))
 +    if (!OBT_PROP_GET32(self->window, WM_CLIENT_LEADER, WINDOW, &leader))
          leader = None;
  
      /* get the SM_CLIENT_ID */
      got = FALSE;
      if (leader)
 -        got = PROP_GETS(leader, sm_client_id, locale, &self->sm_client_id);
 +        got = OBT_PROP_GETS(leader, SM_CLIENT_ID, locale, &self->sm_client_id);
      if (!got)
 -        PROP_GETS(self->window, sm_client_id, locale, &self->sm_client_id);
 +        OBT_PROP_GETS(self->window, SM_CLIENT_ID, locale, &self->sm_client_id);
  
      /* get the WM_CLASS (name and class). make them "" if they are not
         provided */
      got = FALSE;
      if (leader)
 -        got = PROP_GETSS(leader, wm_class, locale, &ss);
 +        got = OBT_PROP_GETSS(leader, WM_CLASS, locale, &ss);
      if (!got)
 -        got = PROP_GETSS(self->window, wm_class, locale, &ss);
 +        got = OBT_PROP_GETSS(self->window, WM_CLASS, locale, &ss);
  
      if (got) {
          if (ss[0]) {
      /* get the WM_WINDOW_ROLE. make it "" if it is not provided */
      got = FALSE;
      if (leader)
 -        got = PROP_GETS(leader, wm_window_role, locale, &s);
 +        got = OBT_PROP_GETS(leader, WM_WINDOW_ROLE, locale, &s);
      if (!got)
 -        got = PROP_GETS(self->window, wm_window_role, locale, &s);
 +        got = OBT_PROP_GETS(self->window, WM_WINDOW_ROLE, locale, &s);
  
      if (got)
          self->role = s;
      got = FALSE;
  
      if (leader)
 -        got = PROP_GETSS(leader, wm_command, locale, &ss);
 +        got = OBT_PROP_GETSS(leader, WM_COMMAND, locale, &ss);
      if (!got)
 -        got = PROP_GETSS(self->window, wm_command, locale, &ss);
 +        got = OBT_PROP_GETSS(self->window, WM_COMMAND, locale, &ss);
  
      if (got) {
          /* merge/mash them all together */
      /* get the WM_CLIENT_MACHINE */
      got = FALSE;
      if (leader)
 -        got = PROP_GETS(leader, wm_client_machine, locale, &s);
 +        got = OBT_PROP_GETS(leader, WM_CLIENT_MACHINE, locale, &s);
      if (!got)
 -        got = PROP_GETS(self->window, wm_client_machine, locale, &s);
 +        got = OBT_PROP_GETS(self->window, WM_CLIENT_MACHINE, locale, &s);
  
      if (got) {
          gchar localhost[128];
  
          /* see if it has the PID set too (the PID requires that the
             WM_CLIENT_MACHINE be set) */
 -        if (PROP_GET32(self->window, net_wm_pid, cardinal, &pid))
 +        if (OBT_PROP_GET32(self->window, NET_WM_PID, CARDINAL, &pid))
              self->pid = pid;
      }
  }
@@@ -2314,12 -2381,12 +2315,12 @@@ static void client_change_wm_state(ObCl
          self->wmstate = NormalState;
  
      if (old != self->wmstate) {
 -        PROP_MSG(self->window, kde_wm_change_state,
 -                 self->wmstate, 1, 0, 0);
 +        OBT_PROP_MSG(ob_screen, self->window, KDE_WM_CHANGE_STATE,
 +                     self->wmstate, 1, 0, 0, 0);
  
          state[0] = self->wmstate;
          state[1] = None;
 -        PROP_SETA32(self->window, wm_state, wm_state, state, 2);
 +        OBT_PROP_SETA32(self->window, WM_STATE, WM_STATE, state, 2);
      }
  }
  
@@@ -2330,30 -2397,30 +2331,30 @@@ static void client_change_state(ObClien
  
      num = 0;
      if (self->modal)
 -        netstate[num++] = prop_atoms.net_wm_state_modal;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MODAL);
      if (self->shaded)
 -        netstate[num++] = prop_atoms.net_wm_state_shaded;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SHADED);
      if (self->iconic)
 -        netstate[num++] = prop_atoms.net_wm_state_hidden;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_HIDDEN);
      if (self->skip_taskbar)
 -        netstate[num++] = prop_atoms.net_wm_state_skip_taskbar;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR);
      if (self->skip_pager)
 -        netstate[num++] = prop_atoms.net_wm_state_skip_pager;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER);
      if (self->fullscreen)
 -        netstate[num++] = prop_atoms.net_wm_state_fullscreen;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN);
      if (self->max_vert)
 -        netstate[num++] = prop_atoms.net_wm_state_maximized_vert;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT);
      if (self->max_horz)
 -        netstate[num++] = prop_atoms.net_wm_state_maximized_horz;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ);
      if (self->above)
 -        netstate[num++] = prop_atoms.net_wm_state_above;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_ABOVE);
      if (self->below)
 -        netstate[num++] = prop_atoms.net_wm_state_below;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_BELOW);
      if (self->demands_attention)
 -        netstate[num++] = prop_atoms.net_wm_state_demands_attention;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
      if (self->undecorated)
 -        netstate[num++] = prop_atoms.ob_wm_state_undecorated;
 -    PROP_SETA32(self->window, net_wm_state, atom, netstate, num);
 +        netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
 +    OBT_PROP_SETA32(self->window, NET_WM_STATE, ATOM, netstate, num);
  
      if (self->frame)
          frame_adjust_state(self->frame);
@@@ -2546,8 -2613,6 +2547,8 @@@ gboolean client_show(ObClient *self
             desktop!
          */
          client_change_wm_state(self);
 +
 +        hooks_queue(OB_HOOK_WIN_VISIBLE, self);
      }
      return show;
  }
@@@ -2586,8 -2651,6 +2587,8 @@@ gboolean client_hide(ObClient *self
             desktop!
          */
          client_change_wm_state(self);
 +
 +        hooks_queue(OB_HOOK_WIN_INVISIBLE, self);
      }
      return hide;
  }
@@@ -2655,7 -2718,7 +2656,7 @@@ static void client_apply_startup_state(
         pre-max/pre-fullscreen values
      */
      client_try_configure(self, &x, &y, &w, &h, &l, &l, FALSE);
 -    ob_debug("placed window 0x%x at %d, %d with size %d x %d\n",
 +    ob_debug("placed window 0x%x at %d, %d with size %d x %d",
               self->window, x, y, w, h);
      /* save the area, and make it where it should be for the premax stuff */
      oldarea = self->area;
      client_configure(self, x, y, w, h, FALSE, TRUE, FALSE);
  
      /* set the desktop hint, to make sure that it always exists */
 -    PROP_SET32(self->window, net_wm_desktop, cardinal, self->desktop);
 +    OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, self->desktop);
  
      /* nothing to do for the other states:
         skip_taskbar
@@@ -2973,7 -3036,7 +2974,7 @@@ void client_configure(ObClient *self, g
  
      /* if the client is enlarging, then resize the client before the frame */
      if (send_resize_client && (w > oldw || h > oldh)) {
 -        XMoveResizeWindow(ob_display, self->window,
 +        XMoveResizeWindow(obt_display, self->window,
                            self->frame->size.left, self->frame->size.top,
                            MAX(w, oldw), MAX(h, oldh));
          frame_adjust_client_area(self->frame);
          XEvent event;
  
          event.type = ConfigureNotify;
 -        event.xconfigure.display = ob_display;
 +        event.xconfigure.display = obt_display;
          event.xconfigure.event = self->window;
          event.xconfigure.window = self->window;
  
 -        ob_debug("Sending ConfigureNotify to %s for %d,%d %dx%d\n",
 +        ob_debug("Sending ConfigureNotify to %s for %d,%d %dx%d",
                   self->title, self->root_pos.x, self->root_pos.y, w, h);
  
          /* root window real coords */
       */
      if (send_resize_client && (w <= oldw || h <= oldh)) {
          frame_adjust_client_area(self->frame);
 -        XMoveResizeWindow(ob_display, self->window,
 +        XMoveResizeWindow(obt_display, self->window,
                            self->frame->size.left, self->frame->size.top, w, h);
      }
  
 -    XFlush(ob_display);
 +    XFlush(obt_display);
  
      /* if it moved between monitors, then this can affect the stacking
         layer of this window or others - for fullscreen windows */
@@@ -3120,7 -3183,7 +3121,7 @@@ void client_fullscreen(ObClient *self, 
          RECT_SET(self->pre_fullscreen_area, 0, 0, 0, 0);
      }
  
 -    ob_debug("Window %s going fullscreen (%d)\n",
 +    ob_debug("Window %s going fullscreen (%d)",
               self->title, self->fullscreen);
  
      client_setup_decor_and_functions(self, FALSE);
@@@ -3145,7 -3208,7 +3146,7 @@@ static void client_iconify_recursive(Ob
      gboolean changed = FALSE;
  
      if (self->iconic != iconic) {
 -        ob_debug("%sconifying window: 0x%lx\n", (iconic ? "I" : "Uni"),
 +        ob_debug("%sconifying window: 0x%lx", (iconic ? "I" : "Uni"),
                   self->window);
  
          if (iconic) {
              frame_begin_iconify_animation(self->frame, iconic);
          /* do this after starting the animation so it doesn't flash */
          client_showhide(self);
 +
 +        hooks_queue((iconic ? OB_HOOK_WIN_ICONIC : OB_HOOK_WIN_UNICONIC),
 +                    self);
      }
  
      /* iconify all direct transients, and deiconify all transients
@@@ -3271,8 -3331,6 +3272,8 @@@ void client_maximize(ObClient *self, gb
  
      client_setup_decor_and_functions(self, FALSE);
      client_move_resize(self, x, y, w, h);
 +
 +    hooks_queue((max ? OB_HOOK_WIN_MAX : OB_HOOK_WIN_UNMAX), self);
  }
  
  void client_shade(ObClient *self, gboolean shade)
      client_change_wm_state(self); /* the window is being hidden/shown */
      /* resize the frame to just the titlebar */
      frame_adjust_area(self->frame, FALSE, TRUE, FALSE);
 +
 +    hooks_queue((shade ? OB_HOOK_WIN_SHADE : OB_HOOK_WIN_UNSHADE), self);
  }
  
  static void client_ping_event(ObClient *self, gboolean dead)
@@@ -3327,12 -3383,12 +3328,12 @@@ void client_close(ObClient *self
      if (!self->delete_window)
          /* don't use client_kill(), we should only kill based on PID in
             response to a lack of PING replies */
 -        XKillClient(ob_display, self->window);
 +        XKillClient(obt_display, self->window);
      else {
          /* request the client to close with WM_DELETE_WINDOW */
 -        PROP_MSG_TO(self->window, self->window, wm_protocols,
 -                    prop_atoms.wm_delete_window, event_curtime, 0, 0, 0,
 -                    NoEventMask);
 +        OBT_PROP_MSG_TO(self->window, self->window, WM_PROTOCOLS,
 +                        OBT_PROP_ATOM(WM_DELETE_WINDOW), event_curtime,
 +                        0, 0, 0, NoEventMask);
  
          /* we're trying to close the window, so see if it is responding. if it
             is not, then we will let them kill the window */
@@@ -3440,14 -3496,14 +3441,14 @@@ void client_kill(ObClient *self
              client_update_title(self);
          }
          else {
 -            ob_debug("killing window 0x%x with pid %lu, with SIGKILL\n",
 +            ob_debug("killing window 0x%x with pid %lu, with SIGKILL",
                       self->window, self->pid);
              kill(self->pid, SIGKILL); /* kill -9 */
          }
      }
      else {
          /* running on a remote host */
 -        XKillClient(ob_display, self->window);
 +        XKillClient(obt_display, self->window);
      }
  }
  
@@@ -3477,13 -3533,13 +3478,13 @@@ static void client_set_desktop_recursiv
  
      if (target != self->desktop && self->type != OB_CLIENT_TYPE_DESKTOP) {
  
 -        ob_debug("Setting desktop %u\n", target+1);
 +        ob_debug("Setting desktop %u", target+1);
  
          g_assert(target < screen_num_desktops || target == DESKTOP_ALL);
  
          old = self->desktop;
          self->desktop = target;
 -        PROP_SET32(self->window, net_wm_desktop, cardinal, target);
 +        OBT_PROP_SET32(self->window, NET_WM_DESKTOP, CARDINAL, target);
          /* the frame can display the current desktop state */
          frame_adjust_state(self->frame);
          /* 'move' the window to the new desktop */
              /* the new desktop's geometry may be different, so we may need to
                 resize, for example if we are maximized */
              client_reconfigure(self, FALSE);
 +
 +        if (old != self->desktop)
 +            hooks_queue(OB_HOOK_WIN_DESK_CHANGE, self);
      }
  
      /* move all transients */
@@@ -3538,19 -3591,38 +3539,38 @@@ ObClient *client_search_modal_child(ObC
      return NULL;
  }
  
 -    if (XCheckTypedWindowEvent(ob_display, self->window, UnmapNotify, &e)) {
+ static gboolean client_validate_unmap(ObClient *self, int n)
+ {
+     XEvent e;
+     gboolean ret = TRUE;
 -        XPutBackEvent(ob_display, &e);
++    if (XCheckTypedWindowEvent(obt_display, self->window, UnmapNotify, &e)) {
+         if (n < self->ignore_unmaps) // ignore this one, but look for more
+             ret = client_validate_unmap(self, n+1);
+         else
+             ret = FALSE; // the window is going to become unmanaged
+         /* put them back on the event stack so they end up in the same order */
++        XPutBackEvent(obt_display, &e);
+     }
+     return ret;
+ }
  gboolean client_validate(ObClient *self)
  {
      XEvent e;
  
 -    XSync(ob_display, FALSE); /* get all events on the server */
 +    XSync(obt_display, FALSE); /* get all events on the server */
  
-     if (XCheckTypedWindowEvent(obt_display, self->window, DestroyNotify, &e) ||
-         XCheckTypedWindowEvent(obt_display, self->window, UnmapNotify, &e))
-     {
 -    if (XCheckTypedWindowEvent(ob_display, self->window, DestroyNotify, &e)) {
 -        XPutBackEvent(ob_display, &e);
++    if (XCheckTypedWindowEvent(obt_display, self->window, DestroyNotify, &e)) {
 +        XPutBackEvent(obt_display, &e);
          return FALSE;
      }
  
+     if (!client_validate_unmap(self, 0))
+         return FALSE;
      return TRUE;
  }
  
@@@ -3581,11 -3653,10 +3601,11 @@@ void client_set_state(ObClient *self, A
      gboolean above = self->above;
      gboolean below = self->below;
      gint i;
 +    gboolean value;
  
 -    if (!(action == prop_atoms.net_wm_state_add ||
 -          action == prop_atoms.net_wm_state_remove ||
 -          action == prop_atoms.net_wm_state_toggle))
 +    if (!(action == OBT_PROP_ATOM(NET_WM_STATE_ADD) ||
 +          action == OBT_PROP_ATOM(NET_WM_STATE_REMOVE) ||
 +          action == OBT_PROP_ATOM(NET_WM_STATE_TOGGLE)))
          /* an invalid action was passed to the client message, ignore it */
          return;
  
          if (!state) continue;
  
          /* if toggling, then pick whether we're adding or removing */
 -        if (action == prop_atoms.net_wm_state_toggle) {
 -            if (state == prop_atoms.net_wm_state_modal)
 -                action = modal ? prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_maximized_vert)
 -                action = self->max_vert ? prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_maximized_horz)
 -                action = self->max_horz ? prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_shaded)
 -                action = shaded ? prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_skip_taskbar)
 -                action = self->skip_taskbar ?
 -                    prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_skip_pager)
 -                action = self->skip_pager ?
 -                    prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_hidden)
 -                action = self->iconic ?
 -                    prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_fullscreen)
 -                action = fullscreen ?
 -                    prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_above)
 -                action = self->above ? prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_below)
 -                action = self->below ? prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.net_wm_state_demands_attention)
 -                action = self->demands_attention ?
 -                    prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 -            else if (state == prop_atoms.ob_wm_state_undecorated)
 -                action = undecorated ? prop_atoms.net_wm_state_remove :
 -                    prop_atoms.net_wm_state_add;
 +        if (action == OBT_PROP_ATOM(NET_WM_STATE_TOGGLE)) {
 +            if (state == OBT_PROP_ATOM(NET_WM_STATE_MODAL))
 +                value = modal;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT))
 +                value = self->max_vert;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ))
 +                value = self->max_horz;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_SHADED))
 +                value = shaded;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR))
 +                value = self->skip_taskbar;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER))
 +                value = self->skip_pager;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_HIDDEN))
 +                value = self->iconic;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN))
 +                value = fullscreen;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_ABOVE))
 +                value = self->above;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_BELOW))
 +                value = self->below;
 +            else if (state == OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION))
 +                value = self->demands_attention;
 +            else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED))
 +                value = undecorated;
 +            action = value ? OBT_PROP_ATOM(NET_WM_STATE_REMOVE) :
 +                             OBT_PROP_ATOM(NET_WM_STATE_ADD);
          }
  
 -        if (action == prop_atoms.net_wm_state_add) {
 -            if (state == prop_atoms.net_wm_state_modal) {
 -                modal = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_maximized_vert) {
 -                max_vert = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_maximized_horz) {
 -                max_horz = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_shaded) {
 -                shaded = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_skip_taskbar) {
 -                self->skip_taskbar = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_skip_pager) {
 -                self->skip_pager = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_hidden) {
 -                iconic = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_fullscreen) {
 -                fullscreen = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_above) {
 -                above = TRUE;
 +        value = action == OBT_PROP_ATOM(NET_WM_STATE_ADD);
 +        if (state == OBT_PROP_ATOM(NET_WM_STATE_MODAL)) {
 +            modal = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT)) {
 +            max_vert = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ)) {
 +            max_horz = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_SHADED)) {
 +            shaded = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR)) {
 +            self->skip_taskbar = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER)) {
 +            self->skip_pager = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_HIDDEN)) {
 +            iconic = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN)) {
 +            fullscreen = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_ABOVE)) {
 +            above = value;
 +            /* only unset below when setting above, otherwise you can't get to
 +               the normal layer */
 +            if (value)
                  below = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_below) {
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_BELOW)) {
 +            /* and vice versa */
 +            if (value)
                  above = FALSE;
 -                below = TRUE;
 -            } else if (state == prop_atoms.net_wm_state_demands_attention) {
 -                demands_attention = TRUE;
 -            } else if (state == prop_atoms.ob_wm_state_undecorated) {
 -                undecorated = TRUE;
 -            }
 -
 -        } else { /* action == prop_atoms.net_wm_state_remove */
 -            if (state == prop_atoms.net_wm_state_modal) {
 -                modal = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_maximized_vert) {
 -                max_vert = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_maximized_horz) {
 -                max_horz = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_shaded) {
 -                shaded = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_skip_taskbar) {
 -                self->skip_taskbar = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_skip_pager) {
 -                self->skip_pager = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_hidden) {
 -                iconic = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_fullscreen) {
 -                fullscreen = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_above) {
 -                above = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_below) {
 -                below = FALSE;
 -            } else if (state == prop_atoms.net_wm_state_demands_attention) {
 -                demands_attention = FALSE;
 -            } else if (state == prop_atoms.ob_wm_state_undecorated) {
 -                undecorated = FALSE;
 -            }
 +            below = value;
 +        } else if (state == OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION)){
 +            demands_attention = value;
 +        } else if (state == OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED)) {
 +            undecorated = value;
          }
      }
  
@@@ -3745,12 -3854,12 +3765,12 @@@ gboolean client_focus(ObClient *self
  
      if (!client_can_focus(self)) {
          ob_debug_type(OB_DEBUG_FOCUS,
 -                      "Client %s can't be focused\n", self->title);
 +                      "Client %s can't be focused", self->title);
          return FALSE;
      }
  
      ob_debug_type(OB_DEBUG_FOCUS,
 -                  "Focusing client \"%s\" (0x%x) at time %u\n",
 +                  "Focusing client \"%s\" (0x%x) at time %u",
                    self->title, self->window, event_curtime);
  
      /* if using focus_delay, stop the timer now so that focus doesn't
  
      event_cancel_all_key_grabs();
  
 -    xerror_set_ignore(TRUE);
 -    xerror_occured = FALSE;
 +    obt_display_ignore_errors(TRUE);
  
      if (self->can_focus) {
          /* This can cause a BadMatch error with CurrentTime, or if an app
             passed in a bad time for _NET_WM_ACTIVE_WINDOW. */
 -        XSetInputFocus(ob_display, self->window, RevertToPointerRoot,
 +        XSetInputFocus(obt_display, self->window, RevertToPointerRoot,
                         event_curtime);
      }
  
      if (self->focus_notify) {
          XEvent ce;
          ce.xclient.type = ClientMessage;
 -        ce.xclient.message_type = prop_atoms.wm_protocols;
 -        ce.xclient.display = ob_display;
 +        ce.xclient.message_type = OBT_PROP_ATOM(WM_PROTOCOLS);
 +        ce.xclient.display = obt_display;
          ce.xclient.window = self->window;
          ce.xclient.format = 32;
 -        ce.xclient.data.l[0] = prop_atoms.wm_take_focus;
 +        ce.xclient.data.l[0] = OBT_PROP_ATOM(WM_TAKE_FOCUS);
          ce.xclient.data.l[1] = event_curtime;
          ce.xclient.data.l[2] = 0l;
          ce.xclient.data.l[3] = 0l;
          ce.xclient.data.l[4] = 0l;
 -        XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
 +        XSendEvent(obt_display, self->window, FALSE, NoEventMask, &ce);
      }
  
 -    xerror_set_ignore(FALSE);
 +    obt_display_ignore_errors(FALSE);
  
 -    ob_debug_type(OB_DEBUG_FOCUS, "Error focusing? %d\n", xerror_occured);
 -    return !xerror_occured;
 +    ob_debug_type(OB_DEBUG_FOCUS, "Error focusing? %d",
 +                  obt_display_error_occured);
 +    return !obt_display_error_occured;
  }
  
  static void client_present(ObClient *self, gboolean here, gboolean raise,
@@@ -3907,9 -4016,6 +3927,9 @@@ void client_set_undecorated(ObClient *s
          self->undecorated = undecorated;
          client_setup_decor_and_functions(self, TRUE);
          client_change_state(self); /* reflect this in the state hints */
 +
 +        hooks_queue((undecorated ?
 +                     OB_HOOK_WIN_UNDECORATED : OB_HOOK_WIN_DECORATED), self);
      }
  }
  
@@@ -4101,15 -4207,15 +4121,15 @@@ static void detect_edge(Rect area, ObDi
              g_assert_not_reached();
      }
  
 -    ob_debug("my head %d size %d\n", my_head, my_size);
 -    ob_debug("head %d tail %d dest %d\n", head, tail, *dest);
 +    ob_debug("my head %d size %d", my_head, my_size);
 +    ob_debug("head %d tail %d dest %d", head, tail, *dest);
      if (!skip_head) {
 -        ob_debug("using near edge %d\n", head);
 +        ob_debug("using near edge %d", head);
          *dest = head;
          *near_edge = TRUE;
      }
      else if (!skip_tail) {
 -        ob_debug("using far edge %d\n", tail);
 +        ob_debug("using far edge %d", tail);
          *dest = tail;
          *near_edge = FALSE;
      }
@@@ -4174,7 -4280,7 +4194,7 @@@ void client_find_edge_directional(ObCli
              cur->desktop != screen_desktop)
              continue;
  
 -        ob_debug("trying window %s\n", cur->title);
 +        ob_debug("trying window %s", cur->title);
  
          detect_edge(cur->frame->area, dir, my_head, my_size, my_edge_start,
                      my_edge_size, dest, near_edge);
@@@ -4295,10 -4401,10 +4315,10 @@@ void client_find_resize_directional(ObC
          g_assert_not_reached();
      }
  
 -    ob_debug("head %d dir %d\n", head, dir);
 +    ob_debug("head %d dir %d", head, dir);
      client_find_edge_directional(self, dir, head, 1,
                                   e_start, e_size, &e, &near);
 -    ob_debug("edge %d\n", e);
 +    ob_debug("edge %d", e);
      *x = self->frame->area.x;
      *y = self->frame->area.y;
      *w = self->frame->area.width;
diff --combined openbox/event.c
index f69267db60c63f1dcfed979fd567ad41a2345fed,ddd2e3263a81c9c015edebac2dccb483bbc0f9de..e2fd411f9f351ff830d9a35882bec13bd8a0bd2d
@@@ -24,6 -24,8 +24,6 @@@
  #include "dock.h"
  #include "actions.h"
  #include "client.h"
 -#include "xerror.h"
 -#include "prop.h"
  #include "config.h"
  #include "screen.h"
  #include "frame.h"
  #include "prompt.h"
  #include "menuframe.h"
  #include "keyboard.h"
 -#include "modkeys.h"
  #include "mouse.h"
 -#include "mainloop.h"
 +#include "hooks.h"
  #include "focus.h"
  #include "focus_cycle.h"
  #include "moveresize.h"
  #include "group.h"
  #include "stacking.h"
 -#include "extensions.h"
 -#include "translate.h"
  #include "ping.h"
 +#include "obt/display.h"
 +#include "obt/prop.h"
 +#include "obt/keyboard.h"
  
  #include <X11/Xlib.h>
  #include <X11/Xatom.h>
@@@ -85,8 -87,8 +85,8 @@@ typedef struc
  
  static void event_process(const XEvent *e, gpointer data);
  static void event_handle_root(XEvent *e);
 -static gboolean event_handle_menu_keyboard(XEvent *e);
 -static gboolean event_handle_menu(XEvent *e);
 +static gboolean event_handle_menu_input(XEvent *e);
 +static void event_handle_menu(ObMenuFrame *frame, XEvent *e);
  static gboolean event_handle_prompt(ObPrompt *p, XEvent *e);
  static void event_handle_dock(ObDock *s, XEvent *e);
  static void event_handle_dockapp(ObDockApp *app, XEvent *e);
@@@ -123,9 -125,9 +123,9 @@@ static void ice_watch(IceConn conn, Ice
  
      if (opening) {
          fd = IceConnectionNumber(conn);
 -        ob_main_loop_fd_add(ob_main_loop, fd, ice_handler, conn, NULL);
 +        obt_main_loop_fd_add(ob_main_loop, fd, ice_handler, conn, NULL);
      } else {
 -        ob_main_loop_fd_remove(ob_main_loop, fd);
 +        obt_main_loop_fd_remove(ob_main_loop, fd);
          fd = -1;
      }
  }
@@@ -135,7 -137,7 +135,7 @@@ void event_startup(gboolean reconfig
  {
      if (reconfig) return;
  
 -    ob_main_loop_x_add(ob_main_loop, event_process, NULL, NULL);
 +    obt_main_loop_x_add(ob_main_loop, event_process, NULL, NULL);
  
  #ifdef USE_SM
      IceAddConnectionWatch(ice_watch, NULL);
@@@ -162,15 -164,9 +162,15 @@@ static Window event_get_window(XEvent *
      /* pick a window */
      switch (e->type) {
      case SelectionClear:
 -        window = RootWindow(ob_display, ob_screen);
 +        window = obt_root(ob_screen);
 +        break;
 +    case CreateNotify:
 +        window = e->xcreatewindow.window;
          break;
      case MapRequest:
 +        window = e->xmaprequest.window;
 +        break;
 +    case MapNotify:
          window = e->xmap.window;
          break;
      case UnmapNotify:
          break;
      default:
  #ifdef XKB
 -        if (extensions_xkb && e->type == extensions_xkb_event_basep) {
 +        if (obt_display_extension_xkb &&
 +            e->type == obt_display_extension_xkb_basep)
 +        {
              switch (((XkbAnyEvent*)e)->xkb_type) {
              case XkbBellNotify:
                  window = ((XkbBellNotifyEvent*)e)->window;
          } else
  #endif
  #ifdef SYNC
 -        if (extensions_sync &&
 -            e->type == extensions_sync_event_basep + XSyncAlarmNotify)
 +        if (obt_display_extension_sync &&
 +            e->type == obt_display_extension_sync_basep + XSyncAlarmNotify)
          {
              window = None;
          } else
@@@ -238,8 -232,8 +238,8 @@@ static void event_set_curtime(XEvent *e
          break;
      default:
  #ifdef SYNC
 -        if (extensions_sync &&
 -            e->type == extensions_sync_event_basep + XSyncAlarmNotify)
 +        if (obt_display_extension_sync &&
 +            e->type == obt_display_extension_sync_basep + XSyncAlarmNotify)
          {
              t = ((XSyncAlarmNotifyEvent*)e)->time;
          }
@@@ -267,34 -261,34 +267,34 @@@ static void event_hack_mods(XEvent *e
      switch (e->type) {
      case ButtonPress:
      case ButtonRelease:
 -        e->xbutton.state = modkeys_only_modifier_masks(e->xbutton.state);
 +        e->xbutton.state = obt_keyboard_only_modmasks(e->xbutton.state);
          break;
      case KeyPress:
 -        e->xkey.state = modkeys_only_modifier_masks(e->xkey.state);
 +        e->xkey.state = obt_keyboard_only_modmasks(e->xkey.state);
          break;
      case KeyRelease:
  #ifdef XKB
          /* If XKB is present, then the modifiers are all strange from its
             magic.  Our X core protocol stuff won't work, so we use this to
             find what the modifier state is instead. */
 -        if (XkbGetState(ob_display, XkbUseCoreKbd, &xkb_state) == Success)
 +        if (XkbGetState(obt_display, XkbUseCoreKbd, &xkb_state) == Success)
              e->xkey.state =
 -                modkeys_only_modifier_masks(xkb_state.compat_state);
 +                obt_keyboard_only_modmasks(xkb_state.compat_state);
          else
  #endif
          {
 -            e->xkey.state = modkeys_only_modifier_masks(e->xkey.state);
 +            e->xkey.state = obt_keyboard_only_modmasks(e->xkey.state);
              /* remove from the state the mask of the modifier key being
                 released, if it is a modifier key being released that is */
 -            e->xkey.state &= ~modkeys_keycode_to_mask(e->xkey.keycode);
 +            e->xkey.state &= ~obt_keyboard_keycode_to_modmask(e->xkey.keycode);
          }
          break;
      case MotionNotify:
 -        e->xmotion.state = modkeys_only_modifier_masks(e->xmotion.state);
 +        e->xmotion.state = obt_keyboard_only_modmasks(e->xmotion.state);
          /* compress events */
          {
              XEvent ce;
 -            while (XCheckTypedWindowEvent(ob_display, e->xmotion.window,
 +            while (XCheckTypedWindowEvent(obt_display, e->xmotion.window,
                                            e->type, &ce)) {
                  e->xmotion.x = ce.xmotion.x;
                  e->xmotion.y = ce.xmotion.y;
@@@ -324,7 -318,7 +324,7 @@@ static gboolean wanted_focusevent(XEven
  
          /* These are the ones we want.. */
  
 -        if (win == RootWindow(ob_display, ob_screen)) {
 +        if (win == obt_root(ob_screen)) {
              /* If looking for a focus in on a client, then always return
                 FALSE for focus in's to the root window */
              if (in_client_only)
             but has disappeared.
          */
          if (in_client_only) {
 -            ObWindow *w = g_hash_table_lookup(window_map, &e->xfocus.window);
 +            ObWindow *w = window_find(e->xfocus.window);
              if (!w || !WINDOW_IS_CLIENT(w))
                  return FALSE;
          }
              return FALSE;
  
          /* Focus left the root window revertedto state */
 -        if (win == RootWindow(ob_display, ob_screen))
 +        if (win == obt_root(ob_screen))
              return FALSE;
  
          /* These are the ones we want.. */
@@@ -434,7 -428,7 +434,7 @@@ static void print_focusevent(XEvent *e
  
      g_assert(modestr);
      g_assert(detailstr);
 -    ob_debug_type(OB_DEBUG_FOCUS, "Focus%s 0x%x mode=%s detail=%s\n",
 +    ob_debug_type(OB_DEBUG_FOCUS, "Focus%s 0x%x mode=%s detail=%s",
                    (e->xfocus.type == FocusIn ? "In" : "Out"),
                    win,
                    modestr, detailstr);
@@@ -460,15 -454,13 +460,15 @@@ static gboolean event_ignore(XEvent *e
  
  static void event_process(const XEvent *ec, gpointer data)
  {
 +    XEvent ee, *e;
 +    ObEventData *ed = data;
 +
      Window window;
      ObClient *client = NULL;
      ObDock *dock = NULL;
      ObDockApp *dockapp = NULL;
      ObWindow *obwin = NULL;
 -    XEvent ee, *e;
 -    ObEventData *ed = data;
 +    ObMenuFrame *menu = NULL;
      ObPrompt *prompt = NULL;
  
      /* make a copy we can mangle */
      e = &ee;
  
      window = event_get_window(e);
 -    if ((obwin = g_hash_table_lookup(window_map, &window))) {
 +    if (window == obt_root(ob_screen))
 +        /* don't do any lookups, waste of cpu */;
 +    else if ((obwin = window_find(window))) {
          switch (obwin->type) {
 -        case Window_Dock:
 +        case OB_WINDOW_CLASS_DOCK:
              dock = WINDOW_AS_DOCK(obwin);
              break;
 -        case Window_DockApp:
 -            dockapp = WINDOW_AS_DOCKAPP(obwin);
 -            break;
 -        case Window_Client:
 +        case OB_WINDOW_CLASS_CLIENT:
              client = WINDOW_AS_CLIENT(obwin);
              /* events on clients can be events on prompt windows too */
              prompt = client->prompt;
              break;
 -        case Window_Menu:
 -            /* not to be used for events */
 -            g_assert_not_reached();
 +        case OB_WINDOW_CLASS_MENUFRAME:
 +            menu = WINDOW_AS_MENUFRAME(obwin);
              break;
 -        case Window_Internal:
 +        case OB_WINDOW_CLASS_INTERNAL:
              /* we don't do anything with events directly on these windows */
              break;
 -        case Window_Prompt:
 +        case OB_WINDOW_CLASS_PROMPT:
              prompt = WINDOW_AS_PROMPT(obwin);
              break;
          }
      }
 +    else
 +        dockapp = dock_find_dockapp(window);
  
      event_set_curtime(e);
      event_curserial = e->xany.serial;
  
      /* deal with it in the kernel */
  
 -    if (menu_frame_visible &&
 -        (e->type == EnterNotify || e->type == LeaveNotify))
 -    {
 -        /* crossing events for menu */
 -        event_handle_menu(e);
 -    } else if (e->type == FocusIn) {
 +    if (e->type == FocusIn) {
          if (client &&
              e->xfocus.detail == NotifyInferior)
          {
              XEvent ce;
  
              ob_debug_type(OB_DEBUG_FOCUS,
 -                          "Focus went to root or pointer root/none\n");
 +                          "Focus went to root or pointer root/none");
  
              if (e->xfocus.detail == NotifyInferior ||
                  e->xfocus.detail == NotifyNonlinear)
                 But if the other focus in is something like PointerRoot then we
                 still want to fall back.
              */
 -            if (XCheckIfEvent(ob_display, &ce, event_look_for_focusin_client,
 +            if (XCheckIfEvent(obt_display, &ce, event_look_for_focusin_client,
                                NULL))
              {
 -                XPutBackEvent(ob_display, &ce);
 +                XPutBackEvent(obt_display, &ce);
                  ob_debug_type(OB_DEBUG_FOCUS,
 -                              "  but another FocusIn is coming\n");
 +                              "  but another FocusIn is coming");
              } else {
                  /* Focus has been reverted.
  
          else if (!client)
          {
              ob_debug_type(OB_DEBUG_FOCUS,
 -                          "Focus went to a window that is already gone\n");
 +                          "Focus went to a window that is already gone");
  
              /* If you send focus to a window and then it disappears, you can
                 get the FocusIn for it, after it is unmanaged.
          XEvent ce;
  
          /* Look for the followup FocusIn */
 -        if (!XCheckIfEvent(ob_display, &ce, event_look_for_focusin, NULL)) {
 +        if (!XCheckIfEvent(obt_display, &ce, event_look_for_focusin, NULL)) {
              /* There is no FocusIn, this means focus went to a window that
                 is not being managed, or a window on another screen. */
              Window win, root;
              gint i;
              guint u;
 -            xerror_set_ignore(TRUE);
 -            if (XGetInputFocus(ob_display, &win, &i) != 0 &&
 -                XGetGeometry(ob_display, win, &root, &i,&i,&u,&u,&u,&u) != 0 &&
 -                root != RootWindow(ob_display, ob_screen))
 +            obt_display_ignore_errors(TRUE);
 +            if (XGetInputFocus(obt_display, &win, &i) &&
 +                XGetGeometry(obt_display, win, &root, &i,&i,&u,&u,&u,&u) &&
 +                root != obt_root(ob_screen))
              {
                  ob_debug_type(OB_DEBUG_FOCUS,
 -                              "Focus went to another screen !\n");
 +                              "Focus went to another screen !");
                  focus_left_screen = TRUE;
              }
              else
                  ob_debug_type(OB_DEBUG_FOCUS,
 -                              "Focus went to a black hole !\n");
 -            xerror_set_ignore(FALSE);
 +                              "Focus went to a black hole !");
 +            obt_display_ignore_errors(FALSE);
              /* nothing is focused */
              focus_set_client(NULL);
          } else {
                  /* The FocusIn was ignored, this means it was on a window
                     that isn't a client. */
                  ob_debug_type(OB_DEBUG_FOCUS,
 -                              "Focus went to an unmanaged window 0x%x !\n",
 +                              "Focus went to an unmanaged window 0x%x !",
                                ce.xfocus.window);
                  focus_fallback(TRUE, config_focus_under_mouse, TRUE, TRUE);
              }
          event_handle_dockapp(dockapp, e);
      else if (dock)
          event_handle_dock(dock, e);
 -    else if (window == RootWindow(ob_display, ob_screen))
 +    else if (menu)
 +        event_handle_menu(menu, e);
 +    else if (window == obt_root(ob_screen))
          event_handle_root(e);
      else if (e->type == MapRequest)
 -        client_manage(window, NULL);
 +        window_manage(window);
      else if (e->type == MappingNotify) {
          /* keyboard layout changes for modifier mapping changes. reload the
             modifier map, and rebind all the key bindings as appropriate */
-         ob_debug("Kepboard map changed. Reloading keyboard bindings.");
 -        ob_debug("Keyboard map changed. Reloading keyboard bindings.\n");
++        ob_debug("Keyboard map changed. Reloading keyboard bindings.");
          ob_set_state(OB_STATE_RECONFIGURING);
 -        modkeys_shutdown(TRUE);
 -        modkeys_startup(TRUE);
 +        obt_keyboard_reload();
          keyboard_rebind();
          ob_set_state(OB_STATE_RUNNING);
      }
      else if (e->type == ClientMessage) {
          /* This is for _NET_WM_REQUEST_FRAME_EXTENTS messages. They come for
             windows that are not managed yet. */
 -        if (e->xclient.message_type == prop_atoms.net_request_frame_extents) {
 +        if (e->xclient.message_type ==
 +            OBT_PROP_ATOM(NET_REQUEST_FRAME_EXTENTS))
 +        {
              /* Pretend to manage the client, getting information used to
                 determine its decorations */
              ObClient *c = client_fake_manage(e->xclient.window);
              vals[1] = c->frame->size.right;
              vals[2] = c->frame->size.top;
              vals[3] = c->frame->size.bottom;
 -            PROP_SETA32(e->xclient.window, net_frame_extents,
 -                        cardinal, vals, 4);
 +            OBT_PROP_SETA32(e->xclient.window, NET_FRAME_EXTENTS,
 +                            CARDINAL, vals, 4);
  
              /* Free the pretend client */
              client_fake_unmanage(c);
  
          /* we are not to be held responsible if someone sends us an
             invalid request! */
 -        xerror_set_ignore(TRUE);
 -        XConfigureWindow(ob_display, window,
 +        obt_display_ignore_errors(TRUE);
 +        XConfigureWindow(obt_display, window,
                           e->xconfigurerequest.value_mask, &xwc);
 -        xerror_set_ignore(FALSE);
 +        obt_display_ignore_errors(FALSE);
      }
  #ifdef SYNC
 -    else if (extensions_sync &&
 -        e->type == extensions_sync_event_basep + XSyncAlarmNotify)
 +    else if (obt_display_extension_sync &&
 +             e->type == obt_display_extension_sync_basep + XSyncAlarmNotify)
      {
          XSyncAlarmNotifyEvent *se = (XSyncAlarmNotifyEvent*)e;
          if (se->alarm == moveresize_alarm && moveresize_in_progress)
      else if (e->type == ButtonPress || e->type == ButtonRelease) {
          /* If the button press was on some non-root window, or was physically
             on the root window, then process it */
 -        if (window != RootWindow(ob_display, ob_screen) ||
 +        if (window != obt_root(ob_screen) ||
              e->xbutton.subwindow == None)
          {
              event_handle_user_input(client, e);
          else {
              ObWindow *w;
  
 -            if ((w = g_hash_table_lookup(window_map, &e->xbutton.subwindow)) &&
 +            if ((w = window_find(e->xbutton.subwindow)) &&
                  WINDOW_IS_INTERNAL(w))
              {
                  event_handle_user_input(client, e);
               e->type == MotionNotify)
          event_handle_user_input(client, e);
  
 +    XFlush(obt_display);
 +
 +    /* run all the hooks at once */
 +    hooks_run_queue();
 +
      /* if something happens and it's not from an XEvent, then we don't know
         the time */
      event_curtime = CurrentTime;
@@@ -758,7 -747,7 +758,7 @@@ static void event_handle_root(XEvent *e
  
      switch(e->type) {
      case SelectionClear:
 -        ob_debug("Another WM has requested to replace us. Exiting.\n");
 +        ob_debug("Another WM has requested to replace us. Exiting.");
          ob_exit_replace();
          break;
  
          if (e->xclient.format != 32) break;
  
          msgtype = e->xclient.message_type;
 -        if (msgtype == prop_atoms.net_current_desktop) {
 +        if (msgtype == OBT_PROP_ATOM(NET_CURRENT_DESKTOP)) {
              guint d = e->xclient.data.l[0];
              if (d < screen_num_desktops) {
                  event_curtime = e->xclient.data.l[1];
                  if (event_curtime == 0)
                      ob_debug_type(OB_DEBUG_APP_BUGS,
                                    "_NET_CURRENT_DESKTOP message is missing "
 -                                  "a timestamp\n");
 +                                  "a timestamp");
                  screen_set_desktop(d, TRUE);
              }
 -        } else if (msgtype == prop_atoms.net_number_of_desktops) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_NUMBER_OF_DESKTOPS)) {
              guint d = e->xclient.data.l[0];
              if (d > 0 && d <= 1000)
                  screen_set_num_desktops(d);
 -        } else if (msgtype == prop_atoms.net_showing_desktop) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_SHOWING_DESKTOP)) {
              screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
 -        } else if (msgtype == prop_atoms.ob_control) {
 -            ob_debug("OB_CONTROL: %d\n", e->xclient.data.l[0]);
 +        } else if (msgtype == OBT_PROP_ATOM(OB_CONTROL)) {
 +            ob_debug("OB_CONTROL: %d", e->xclient.data.l[0]);
              if (e->xclient.data.l[0] == 1)
                  ob_reconfigure();
              else if (e->xclient.data.l[0] == 2)
                  ob_restart();
              else if (e->xclient.data.l[0] == 3)
                  ob_exit(0);
 -        } else if (msgtype == prop_atoms.wm_protocols) {
 -            if ((Atom)e->xclient.data.l[0] == prop_atoms.net_wm_ping)
 +        } else if (msgtype == OBT_PROP_ATOM(WM_PROTOCOLS)) {
 +            if ((Atom)e->xclient.data.l[0] == OBT_PROP_ATOM(NET_WM_PING))
                  ping_got_pong(e->xclient.data.l[1]);
          }
          break;
      case PropertyNotify:
 -        if (e->xproperty.atom == prop_atoms.net_desktop_names) {
 -            ob_debug("UPDATE DESKTOP NAMES\n");
 +        if (e->xproperty.atom == OBT_PROP_ATOM(NET_DESKTOP_NAMES)) {
 +            ob_debug("UPDATE DESKTOP NAMES");
              screen_update_desktop_names();
          }
 -        else if (e->xproperty.atom == prop_atoms.net_desktop_layout)
 +        else if (e->xproperty.atom == OBT_PROP_ATOM(NET_DESKTOP_LAYOUT))
              screen_update_layout();
          break;
      case ConfigureNotify:
@@@ -828,17 -817,17 +828,17 @@@ void event_enter_client(ObClient *clien
          if (config_focus_delay) {
              ObFocusDelayData *data;
  
 -            ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
 +            obt_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
  
              data = g_new(ObFocusDelayData, 1);
              data->client = client;
              data->time = event_curtime;
              data->serial = event_curserial;
  
 -            ob_main_loop_timeout_add(ob_main_loop,
 -                                     config_focus_delay * 1000,
 -                                     focus_delay_func,
 -                                     data, focus_delay_cmp, focus_delay_dest);
 +            obt_main_loop_timeout_add(ob_main_loop,
 +                                      config_focus_delay * 1000,
 +                                      focus_delay_func,
 +                                      data, focus_delay_cmp, focus_delay_dest);
          } else {
              ObFocusDelayData data;
              data.client = client;
@@@ -888,12 -877,12 +888,12 @@@ static void compress_client_message_eve
                                            Atom msgtype)
  {
      /* compress changes into a single change */
 -    while (XCheckTypedWindowEvent(ob_display, window, e->type, ce)) {
 +    while (XCheckTypedWindowEvent(obt_display, window, e->type, ce)) {
          /* XXX: it would be nice to compress ALL messages of a
             type, not just messages in a row without other
             message types between. */
          if (ce->xclient.message_type != msgtype) {
 -            XPutBackEvent(ob_display, ce);
 +            XPutBackEvent(obt_display, ce);
              break;
          }
          e->xclient = ce->xclient;
@@@ -1012,7 -1001,7 +1012,7 @@@ static void event_handle_client(ObClien
                  event_end_ignore_all_enters(event_start_ignore_all_enters());
  
              ob_debug_type(OB_DEBUG_FOCUS,
 -                          "%sNotify mode %d detail %d on %lx\n",
 +                          "%sNotify mode %d detail %d on %lx",
                            (e->type == EnterNotify ? "Enter" : "Leave"),
                            e->xcrossing.mode,
                            e->xcrossing.detail, (client?client->window:0));
                     delay is up */
                  e->xcrossing.detail != NotifyInferior)
              {
 -                ob_main_loop_timeout_remove_data(ob_main_loop,
 -                                                 focus_delay_func,
 -                                                 client, FALSE);
 +                obt_main_loop_timeout_remove_data(ob_main_loop,
 +                                                  focus_delay_func,
 +                                                  client, FALSE);
              }
              break;
          default:
              {
                  ob_debug_type(OB_DEBUG_FOCUS,
                                "%sNotify mode %d detail %d serial %lu on %lx "
 -                              "IGNORED\n",
 +                              "IGNORED",
                                (e->type == EnterNotify ? "Enter" : "Leave"),
                                e->xcrossing.mode,
                                e->xcrossing.detail,
              else {
                  ob_debug_type(OB_DEBUG_FOCUS,
                                "%sNotify mode %d detail %d serial %lu on %lx, "
 -                              "focusing window\n",
 +                              "focusing window",
                                (e->type == EnterNotify ? "Enter" : "Leave"),
                                e->xcrossing.mode,
                                e->xcrossing.detail,
          RECT_TO_DIMS(client->area, x, y, w, h);
  
          ob_debug("ConfigureRequest for \"%s\" desktop %d wmstate %d "
 -                 "visible %d\n"
 -                 "                     x %d y %d w %d h %d b %d\n",
 +                 "visible %d",
                   client->title,
 -                 screen_desktop, client->wmstate, client->frame->visible,
 +                 screen_desktop, client->wmstate, client->frame->visible);
 +        ob_debug("                     x %d y %d w %d h %d b %d",
                   x, y, w, h, client->border_width);
  
          if (e->xconfigurerequest.value_mask & CWBorderWidth)
              /* get the sibling */
              if (e->xconfigurerequest.value_mask & CWSibling) {
                  ObWindow *win;
 -                win = g_hash_table_lookup(window_map,
 -                                          &e->xconfigurerequest.above);
 +                win = window_find(e->xconfigurerequest.above);
                  if (win && WINDOW_IS_CLIENT(win) &&
                      WINDOW_AS_CLIENT(win) != client)
                  {
          }
  
          ob_debug("ConfigureRequest x(%d) %d y(%d) %d w(%d) %d h(%d) %d "
 -                 "move %d resize %d\n",
 +                 "move %d resize %d",
                   e->xconfigurerequest.value_mask & CWX, x,
                   e->xconfigurerequest.value_mask & CWY, y,
                   e->xconfigurerequest.value_mask & CWWidth, w,
              ob_debug_type(OB_DEBUG_APP_BUGS,
                            "Application %s is trying to move via "
                            "ConfigureRequest to it's root window position "
 -                          "but it is not using StaticGravity\n",
 +                          "but it is not using StaticGravity",
                            client->title);
              /* don't move it */
              x = client->area.x;
  
              client_find_onscreen(client, &x, &y, w, h, FALSE);
  
 -            ob_debug("Granting ConfigureRequest x %d y %d w %d h %d\n",
 +            ob_debug("Granting ConfigureRequest x %d y %d w %d h %d",
                       x, y, w, h);
              client_configure(client, x, y, w, h, FALSE, TRUE, TRUE);
          }
          break;
      }
      case UnmapNotify:
 +        ob_debug("UnmapNotify for window 0x%x eventwin 0x%x sendevent %d "
 +                 "ignores left %d",
 +                 client->window, e->xunmap.event, e->xunmap.from_configure,
 +                 client->ignore_unmaps);
          if (client->ignore_unmaps) {
              client->ignore_unmaps--;
              break;
          }
 -        ob_debug("UnmapNotify for window 0x%x eventwin 0x%x sendevent %d "
 -                 "ignores left %d\n",
 -                 client->window, e->xunmap.event, e->xunmap.from_configure,
 -                 client->ignore_unmaps);
          client_unmanage(client);
          break;
      case DestroyNotify:
 -        ob_debug("DestroyNotify for window 0x%x\n", client->window);
 +        ob_debug("DestroyNotify for window 0x%x", client->window);
          client_unmanage(client);
          break;
      case ReparentNotify:
  
          /* we don't want the reparent event, put it back on the stack for the
             X server to deal with after we unmanage the window */
 -        XPutBackEvent(ob_display, e);
 +        XPutBackEvent(obt_display, e);
  
 -        ob_debug("ReparentNotify for window 0x%x\n", client->window);
 +        ob_debug("ReparentNotify for window 0x%x", client->window);
          client_unmanage(client);
          break;
      case MapRequest:
 -        ob_debug("MapRequest for 0x%lx\n", client->window);
 +        ob_debug("MapRequest for 0x%lx", client->window);
          if (!client->iconic) break; /* this normally doesn't happen, but if it
                                         does, we don't want it!
                                         it can happen now when the window is on
          if (e->xclient.format != 32) return;
  
          msgtype = e->xclient.message_type;
 -        if (msgtype == prop_atoms.wm_change_state) {
 +        if (msgtype == OBT_PROP_ATOM(WM_CHANGE_STATE)) {
              compress_client_message_event(e, &ce, client->window, msgtype);
              client_set_wm_state(client, e->xclient.data.l[0]);
 -        } else if (msgtype == prop_atoms.net_wm_desktop) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_WM_DESKTOP)) {
              compress_client_message_event(e, &ce, client->window, msgtype);
              if ((unsigned)e->xclient.data.l[0] < screen_num_desktops ||
                  (unsigned)e->xclient.data.l[0] == DESKTOP_ALL)
                  client_set_desktop(client, (unsigned)e->xclient.data.l[0],
                                     FALSE, FALSE);
 -        } else if (msgtype == prop_atoms.net_wm_state) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_WM_STATE)) {
              gulong ignore_start;
  
              /* can't compress these */
 -            ob_debug("net_wm_state %s %ld %ld for 0x%lx\n",
 +            ob_debug("net_wm_state %s %ld %ld for 0x%lx",
                       (e->xclient.data.l[0] == 0 ? "Remove" :
                        e->xclient.data.l[0] == 1 ? "Add" :
                        e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),
                               e->xclient.data.l[1], e->xclient.data.l[2]);
              if (!config_focus_under_mouse)
                  event_end_ignore_all_enters(ignore_start);
 -        } else if (msgtype == prop_atoms.net_close_window) {
 -            ob_debug("net_close_window for 0x%lx\n", client->window);
 +        } else if (msgtype == OBT_PROP_ATOM(NET_CLOSE_WINDOW)) {
 +            ob_debug("net_close_window for 0x%lx", client->window);
              client_close(client);
 -        } else if (msgtype == prop_atoms.net_active_window) {
 -            ob_debug("net_active_window for 0x%lx source=%s\n",
 +        } else if (msgtype == OBT_PROP_ATOM(NET_ACTIVE_WINDOW)) {
 +            ob_debug("net_active_window for 0x%lx source=%s",
                       client->window,
                       (e->xclient.data.l[0] == 0 ? "unknown" :
                        (e->xclient.data.l[0] == 1 ? "application" :
                  if (e->xclient.data.l[1] == 0)
                      ob_debug_type(OB_DEBUG_APP_BUGS,
                                    "_NET_ACTIVE_WINDOW message for window %s is"
 -                                  " missing a timestamp\n", client->title);
 +                                  " missing a timestamp", client->title);
              } else
                  ob_debug_type(OB_DEBUG_APP_BUGS,
                                "_NET_ACTIVE_WINDOW message for window %s is "
 -                              "missing source indication\n", client->title);
 +                              "missing source indication", client->title);
              client_activate(client, TRUE, TRUE, TRUE,
                              (e->xclient.data.l[0] == 0 ||
                               e->xclient.data.l[0] == 2));
 -        } else if (msgtype == prop_atoms.net_wm_moveresize) {
 -            ob_debug("net_wm_moveresize for 0x%lx direction %d\n",
 +        } else if (msgtype == OBT_PROP_ATOM(NET_WM_MOVERESIZE)) {
 +            ob_debug("net_wm_moveresize for 0x%lx direction %d",
                       client->window, e->xclient.data.l[2]);
              if ((Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_topleft ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_top ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOP) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_topright ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPRIGHT) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_right ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_RIGHT) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_right ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_RIGHT) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_bottomright ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_bottom ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOM) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_bottomleft ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_left ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_LEFT) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_move ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_size_keyboard ||
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD) ||
                  (Atom)e->xclient.data.l[2] ==
 -                prop_atoms.net_wm_moveresize_move_keyboard) {
 -
 +                OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD))
 +            {
                  moveresize_start(client, e->xclient.data.l[0],
                                   e->xclient.data.l[1], e->xclient.data.l[3],
                                   e->xclient.data.l[2]);
              }
              else if ((Atom)e->xclient.data.l[2] ==
 -                     prop_atoms.net_wm_moveresize_cancel)
 +                     OBT_PROP_ATOM(NET_WM_MOVERESIZE_CANCEL))
                  moveresize_end(TRUE);
 -        } else if (msgtype == prop_atoms.net_moveresize_window) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_MOVERESIZE_WINDOW)) {
              gint ograv, x, y, w, h;
  
              ograv = client->gravity;
              else
                  h = client->area.height;
  
 -            ob_debug("MOVERESIZE x %d %d y %d %d (gravity %d)\n",
 +            ob_debug("MOVERESIZE x %d %d y %d %d (gravity %d)",
                       e->xclient.data.l[0] & 1 << 8, x,
                       e->xclient.data.l[0] & 1 << 9, y,
                       client->gravity);
              client_configure(client, x, y, w, h, FALSE, TRUE, FALSE);
  
              client->gravity = ograv;
 -        } else if (msgtype == prop_atoms.net_restack_window) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_RESTACK_WINDOW)) {
              if (e->xclient.data.l[0] != 2) {
                  ob_debug_type(OB_DEBUG_APP_BUGS,
                                "_NET_RESTACK_WINDOW sent for window %s with "
 -                              "invalid source indication %ld\n",
 +                              "invalid source indication %ld",
                                client->title, e->xclient.data.l[0]);
              } else {
                  ObClient *sibling = NULL;
                  if (e->xclient.data.l[1]) {
 -                    ObWindow *win = g_hash_table_lookup
 -                        (window_map, &e->xclient.data.l[1]);
 +                    ObWindow *win = window_find(e->xclient.data.l[1]);
                      if (WINDOW_IS_CLIENT(win) &&
                          WINDOW_AS_CLIENT(win) != client)
                      {
                      if (sibling == NULL)
                          ob_debug_type(OB_DEBUG_APP_BUGS,
                                        "_NET_RESTACK_WINDOW sent for window %s "
 -                                      "with invalid sibling 0x%x\n",
 +                                      "with invalid sibling 0x%x",
                                   client->title, e->xclient.data.l[1]);
                  }
                  if (e->xclient.data.l[2] == Below ||
                  } else
                      ob_debug_type(OB_DEBUG_APP_BUGS,
                                    "_NET_RESTACK_WINDOW sent for window %s "
 -                                  "with invalid detail %d\n",
 +                                  "with invalid detail %d",
                                    client->title, e->xclient.data.l[2]);
              }
          }
          if (!client_validate(client)) break;
  
          /* compress changes to a single property into a single change */
 -        while (XCheckTypedWindowEvent(ob_display, client->window,
 +        while (XCheckTypedWindowEvent(obt_display, client->window,
                                        e->type, &ce)) {
              Atom a, b;
  
  
              if (a == b)
                  continue;
 -            if ((a == prop_atoms.net_wm_name ||
 -                 a == prop_atoms.wm_name ||
 -                 a == prop_atoms.net_wm_icon_name ||
 -                 a == prop_atoms.wm_icon_name)
 +            if ((a == OBT_PROP_ATOM(NET_WM_NAME) ||
 +                 a == OBT_PROP_ATOM(WM_NAME) ||
 +                 a == OBT_PROP_ATOM(NET_WM_ICON_NAME) ||
 +                 a == OBT_PROP_ATOM(WM_ICON_NAME))
                  &&
 -                (b == prop_atoms.net_wm_name ||
 -                 b == prop_atoms.wm_name ||
 -                 b == prop_atoms.net_wm_icon_name ||
 -                 b == prop_atoms.wm_icon_name)) {
 +                (b == OBT_PROP_ATOM(NET_WM_NAME) ||
 +                 b == OBT_PROP_ATOM(WM_NAME) ||
 +                 b == OBT_PROP_ATOM(NET_WM_ICON_NAME) ||
 +                 b == OBT_PROP_ATOM(WM_ICON_NAME))) {
                  continue;
              }
 -            if (a == prop_atoms.net_wm_icon &&
 -                b == prop_atoms.net_wm_icon)
 +            if (a == OBT_PROP_ATOM(NET_WM_ICON) &&
 +                b == OBT_PROP_ATOM(NET_WM_ICON))
                  continue;
  
 -            XPutBackEvent(ob_display, &ce);
 +            XPutBackEvent(obt_display, &ce);
              break;
          }
  
          msgtype = e->xproperty.atom;
          if (msgtype == XA_WM_NORMAL_HINTS) {
 -            ob_debug("Update NORMAL hints\n");
 +            ob_debug("Update NORMAL hints");
              client_update_normal_hints(client);
              /* normal hints can make a window non-resizable */
              client_setup_decor_and_functions(client, FALSE);
              /* type may have changed, so update the layer */
              client_calc_layer(client);
              client_setup_decor_and_functions(client, TRUE);
 -        } else if (msgtype == prop_atoms.net_wm_name ||
 -                   msgtype == prop_atoms.wm_name ||
 -                   msgtype == prop_atoms.net_wm_icon_name ||
 -                   msgtype == prop_atoms.wm_icon_name) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_WM_NAME) ||
 +                   msgtype == OBT_PROP_ATOM(WM_NAME) ||
 +                   msgtype == OBT_PROP_ATOM(NET_WM_ICON_NAME) ||
 +                   msgtype == OBT_PROP_ATOM(WM_ICON_NAME)) {
              client_update_title(client);
 -        } else if (msgtype == prop_atoms.wm_protocols) {
 +        } else if (msgtype == OBT_PROP_ATOM(WM_PROTOCOLS)) {
              client_update_protocols(client);
              client_setup_decor_and_functions(client, TRUE);
          }
 -        else if (msgtype == prop_atoms.net_wm_strut ||
 -                 msgtype == prop_atoms.net_wm_strut_partial) {
 +        else if (msgtype == OBT_PROP_ATOM(NET_WM_STRUT) ||
 +                 msgtype == OBT_PROP_ATOM(NET_WM_STRUT_PARTIAL)) {
              client_update_strut(client);
          }
 -        else if (msgtype == prop_atoms.net_wm_icon) {
 +        else if (msgtype == OBT_PROP_ATOM(NET_WM_ICON)) {
              client_update_icons(client);
          }
 -        else if (msgtype == prop_atoms.net_wm_icon_geometry) {
 +        else if (msgtype == OBT_PROP_ATOM(NET_WM_ICON_GEOMETRY)) {
              client_update_icon_geometry(client);
          }
 -        else if (msgtype == prop_atoms.net_wm_user_time) {
 +        else if (msgtype == OBT_PROP_ATOM(NET_WM_USER_TIME)) {
              guint32 t;
              if (client == focus_client &&
 -                PROP_GET32(client->window, net_wm_user_time, cardinal, &t) &&
 -                t && !event_time_after(t, e->xproperty.time) &&
 +                OBT_PROP_GET32(client->window, NET_WM_USER_TIME, CARDINAL, &t)
 +                && t && !event_time_after(t, e->xproperty.time) &&
                  (!event_last_user_time ||
                   event_time_after(t, event_last_user_time)))
              {
              }
          }
  #ifdef SYNC
 -        else if (msgtype == prop_atoms.net_wm_sync_request_counter) {
 +        else if (msgtype == OBT_PROP_ATOM(NET_WM_SYNC_REQUEST_COUNTER)) {
              client_update_sync_request_counter(client);
          }
  #endif
  #ifdef SHAPE
          {
              int kind;
 -            if (extensions_shape && e->type == extensions_shape_event_basep) {
 +            if (obt_display_extension_shape &&
 +                e->type == obt_display_extension_shape_basep)
 +            {
                  switch (((XShapeEvent*)e)->kind) {
                      case ShapeBounding:
                      case ShapeClip:
@@@ -1630,11 -1619,11 +1630,11 @@@ static void event_handle_dockapp(ObDock
              app->ignore_unmaps--;
              break;
          }
 -        dock_remove(app, TRUE);
 +        dock_unmanage(app, TRUE);
          break;
      case DestroyNotify:
      case ReparentNotify:
 -        dock_remove(app, FALSE);
 +        dock_unmanage(app, FALSE);
          break;
      case ConfigureNotify:
          dock_app_configure(app, e->xconfigure.width, e->xconfigure.height);
@@@ -1681,160 -1670,125 +1681,160 @@@ static gboolean event_handle_prompt(ObP
      return FALSE;
  }
  
 -static gboolean event_handle_menu_keyboard(XEvent *ev)
 +static gboolean event_handle_menu_input(XEvent *ev)
  {
 -    guint keycode, state;
 -    gunichar unikey;
 -    ObMenuFrame *frame;
      gboolean ret = FALSE;
  
 -    keycode = ev->xkey.keycode;
 -    state = ev->xkey.state;
 -    unikey = translate_unichar(keycode);
 +    if (ev->type == ButtonRelease || ev->type == ButtonPress) {
 +        ObMenuEntryFrame *e;
  
 -    frame = find_active_or_last_menu();
 -    if (frame == NULL)
 -        g_assert_not_reached(); /* there is no active menu */
 +        if (menu_hide_delay_reached() &&
 +            (ev->xbutton.button < 4 || ev->xbutton.button > 5))
 +        {
 +            if ((e = menu_entry_frame_under(ev->xbutton.x_root,
 +                                            ev->xbutton.y_root)))
 +            {
 +                if (ev->type == ButtonPress && e->frame->child)
 +                    menu_frame_select(e->frame->child, NULL, TRUE);
 +                menu_frame_select(e->frame, e, TRUE);
 +                if (ev->type == ButtonRelease)
 +                    menu_entry_frame_execute(e, ev->xbutton.state);
 +            }
 +            else if (ev->type == ButtonRelease)
 +                menu_frame_hide_all();
 +        }
 +        ret = TRUE;
 +    }
 +    else if (ev->type == MotionNotify) {
 +        ObMenuFrame *f;
 +        ObMenuEntryFrame *e;
  
 -    /* Allow control while going thru the menu */
 -    else if (ev->type == KeyPress && (state & ~ControlMask) == 0) {
 -        frame->got_press = TRUE;
 +        if ((e = menu_entry_frame_under(ev->xmotion.x_root,
 +                                        ev->xmotion.y_root)))
 +            if (!(f = find_active_menu()) ||
 +                f == e->frame ||
 +                f->parent == e->frame ||
 +                f->child == e->frame)
 +                menu_frame_select(e->frame, e, FALSE);
 +    }
 +    else if (ev->type == KeyPress || ev->type == KeyRelease) {
 +        guint keycode, state;
 +        gunichar unikey;
 +        ObMenuFrame *frame;
  
 -        if (keycode == ob_keycode(OB_KEY_ESCAPE)) {
 -            menu_frame_hide_all();
 -            ret = TRUE;
 -        }
 +        keycode = ev->xkey.keycode;
 +        state = ev->xkey.state;
 +        unikey = obt_keyboard_keycode_to_unichar(keycode);
  
 -        else if (keycode == ob_keycode(OB_KEY_LEFT)) {
 -            /* Left goes to the parent menu */
 -            if (frame->parent)
 -                menu_frame_select(frame, NULL, TRUE);
 -            ret = TRUE;
 -        }
 +        frame = find_active_or_last_menu();
 +        if (frame == NULL)
 +            g_assert_not_reached(); /* there is no active menu */
  
 -        else if (keycode == ob_keycode(OB_KEY_RIGHT)) {
 -            /* Right goes to the selected submenu */
 -            if (frame->child) menu_frame_select_next(frame->child);
 -            ret = TRUE;
 -        }
 +        /* Allow control while going thru the menu */
 +        else if (ev->type == KeyPress && (state & ~ControlMask) == 0) {
 +            frame->got_press = TRUE;
  
 -        else if (keycode == ob_keycode(OB_KEY_UP)) {
 -            menu_frame_select_previous(frame);
 -            ret = TRUE;
 -        }
 +            if (keycode == ob_keycode(OB_KEY_ESCAPE)) {
 +                menu_frame_hide_all();
 +                ret = TRUE;
 +            }
  
 -        else if (keycode == ob_keycode(OB_KEY_DOWN)) {
 -            menu_frame_select_next(frame);
 -            ret = TRUE;
 -        }
 -    }
 +            else if (keycode == ob_keycode(OB_KEY_LEFT)) {
 +                /* Left goes to the parent menu */
 +                if (frame->parent)
 +                    menu_frame_select(frame, NULL, TRUE);
 +                ret = TRUE;
 +            }
  
 -    /* Use KeyRelease events for running things so that the key release doesn't
 -       get sent to the focused application.
 +            else if (keycode == ob_keycode(OB_KEY_RIGHT)) {
 +                /* Right goes to the selected submenu */
 +                if (frame->child) menu_frame_select_next(frame->child);
 +                ret = TRUE;
 +            }
  
 -       Allow ControlMask only, and don't bother if the menu is empty */
 -    else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 &&
 -             frame->entries && frame->got_press)
 -    {
 -        if (keycode == ob_keycode(OB_KEY_RETURN)) {
 -            /* Enter runs the active item or goes into the submenu.
 -               Control-Enter runs it without closing the menu. */
 -            if (frame->child)
 -                menu_frame_select_next(frame->child);
 -            else if (frame->selected)
 -                menu_entry_frame_execute(frame->selected, state);
 -
 -            ret = TRUE;
 -        }
 +            else if (keycode == ob_keycode(OB_KEY_UP)) {
 +                menu_frame_select_previous(frame);
 +                ret = TRUE;
 +            }
  
 -        /* keyboard accelerator shortcuts. (if it was a valid key) */
 -        else if (unikey != 0) {
 -            GList *start;
 -            GList *it;
 -            ObMenuEntryFrame *found = NULL;
 -            guint num_found = 0;
 -
 -            /* start after the selected one */
 -            start = frame->entries;
 -            if (frame->selected) {
 -                for (it = start; frame->selected != it->data;
 -                     it = g_list_next(it))
 -                    g_assert(it != NULL); /* nothing was selected? */
 -                /* next with wraparound */
 -                start = g_list_next(it);
 -                if (start == NULL) start = frame->entries;
 +            else if (keycode == ob_keycode(OB_KEY_DOWN)) {
 +                menu_frame_select_next(frame);
 +                ret = TRUE;
              }
 +        }
 +
 +        /* Use KeyRelease events for running things so that the key release
 +           doesn't get sent to the focused application.
  
 -            it = start;
 -            do {
 -                ObMenuEntryFrame *e = it->data;
 -                gunichar entrykey = 0;
 +           Allow ControlMask only, and don't bother if the menu is empty */
 +        else if (ev->type == KeyRelease && (state & ~ControlMask) == 0 &&
 +                 frame->entries && frame->got_press)
 +        {
 +            if (keycode == ob_keycode(OB_KEY_RETURN)) {
 +                /* Enter runs the active item or goes into the submenu.
 +                   Control-Enter runs it without closing the menu. */
 +                if (frame->child)
 +                    menu_frame_select_next(frame->child);
 +                else if (frame->selected)
 +                    menu_entry_frame_execute(frame->selected, state);
  
 -                if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL)
 -                    entrykey = e->entry->data.normal.shortcut;
 -                else if (e->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
 -                    entrykey = e->entry->data.submenu.submenu->shortcut;
 +                ret = TRUE;
 +            }
  
 -                if (unikey == entrykey) {
 -                    if (found == NULL) found = e;
 -                    ++num_found;
 +            /* keyboard accelerator shortcuts. (if it was a valid key) */
 +            else if (unikey != 0) {
 +                GList *start;
 +                GList *it;
 +                ObMenuEntryFrame *found = NULL;
 +                guint num_found = 0;
 +
 +                /* start after the selected one */
 +                start = frame->entries;
 +                if (frame->selected) {
 +                    for (it = start; frame->selected != it->data;
 +                         it = g_list_next(it))
 +                        g_assert(it != NULL); /* nothing was selected? */
 +                    /* next with wraparound */
 +                    start = g_list_next(it);
 +                    if (start == NULL) start = frame->entries;
                  }
  
 -                /* next with wraparound */
 -                it = g_list_next(it);
 -                if (it == NULL) it = frame->entries;
 -            } while (it != start);
 +                it = start;
 +                do {
 +                    ObMenuEntryFrame *e = it->data;
 +                    gunichar entrykey = 0;
  
 -            if (found) {
 -                if (found->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
 -                    num_found == 1)
 -                {
 -                    menu_frame_select(frame, found, TRUE);
 -                    usleep(50000); /* highlight the item for a short bit so the
 -                                      user can see what happened */
 -                    menu_entry_frame_execute(found, state);
 -                } else {
 -                    menu_frame_select(frame, found, TRUE);
 -                    if (num_found == 1)
 -                        menu_frame_select_next(frame->child);
 -                }
 +                    if (e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL)
 +                        entrykey = e->entry->data.normal.shortcut;
 +                    else if (e->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
 +                        entrykey = e->entry->data.submenu.submenu->shortcut;
  
 -                ret = TRUE;
 +                    if (unikey == entrykey) {
 +                        if (found == NULL) found = e;
 +                        ++num_found;
 +                    }
 +
 +                    /* next with wraparound */
 +                    it = g_list_next(it);
 +                    if (it == NULL) it = frame->entries;
 +                } while (it != start);
 +
 +                if (found) {
 +                    if (found->entry->type == OB_MENU_ENTRY_TYPE_NORMAL &&
 +                        num_found == 1)
 +                    {
 +                        menu_frame_select(frame, found, TRUE);
 +                        usleep(50000); /* highlight the item for a short bit so
 +                                          the user can see what happened */
 +                        menu_entry_frame_execute(found, state);
 +                    } else {
 +                        menu_frame_select(frame, found, TRUE);
 +                        if (num_found == 1)
 +                            menu_frame_select_next(frame->child);
 +                    }
 +
 +                    ret = TRUE;
 +                }
              }
          }
      }
      return ret;
  }
  
 -static gboolean event_handle_menu(XEvent *ev)
 +static void event_handle_menu(ObMenuFrame *frame, XEvent *ev)
  {
      ObMenuFrame *f;
      ObMenuEntryFrame *e;
 -    gboolean ret = TRUE;
  
      switch (ev->type) {
 -    case ButtonRelease:
 -        if (menu_hide_delay_reached() &&
 -            (ev->xbutton.button < 4 || ev->xbutton.button > 5))
 -        {
 -            if ((e = menu_entry_frame_under(ev->xbutton.x_root,
 -                                            ev->xbutton.y_root)))
 -            {
 -                menu_frame_select(e->frame, e, TRUE);
 -                menu_entry_frame_execute(e, ev->xbutton.state);
 -            }
 -            else
 -                menu_frame_hide_all();
 -        }
 -        break;
      case EnterNotify:
          if ((e = g_hash_table_lookup(menu_frame_map, &ev->xcrossing.window))) {
              if (e->ignore_enters)
              menu_frame_select(e->frame, NULL, FALSE);
          }
          break;
 -    case MotionNotify:
 -        if ((e = menu_entry_frame_under(ev->xmotion.x_root,
 -                                        ev->xmotion.y_root)))
 -            if (!(f = find_active_menu()) ||
 -                f == e->frame ||
 -                f->parent == e->frame ||
 -                f->child == e->frame)
 -                menu_frame_select(e->frame, e, FALSE);
 -        break;
 -    case KeyPress:
 -    case KeyRelease:
 -        ret = event_handle_menu_keyboard(ev);
 -        break;
      }
 -    return ret;
  }
  
  static void event_handle_user_input(ObClient *client, XEvent *e)
               e->type == KeyRelease);
  
      if (menu_frame_visible) {
 -        if (event_handle_menu(e))
 +        if (event_handle_menu_input(e))
              /* don't use the event if the menu used it, but if the menu
                 didn't use it and it's a keypress that is bound, it will
                 close the menu and be used */
              if (!client || !frame_iconify_animating(client->frame))
                  mouse_event(client, e);
          } else
 -            keyboard_event((focus_cycle_target ? focus_cycle_target :
 -                            (client ? client : focus_client)), e);
 +            keyboard_event(event_target_client(client), e);
      }
  }
  
 +ObClient* event_target_client(ObClient *client)
 +{
 +    return (focus_cycle_target ? focus_cycle_target :
 +            (client ? client : focus_client));
 +}
 +
  static void focus_delay_dest(gpointer data)
  {
      g_free(data);
@@@ -1944,20 -1922,20 +1944,20 @@@ static gboolean focus_delay_func(gpoint
  
  static void focus_delay_client_dest(ObClient *client, gpointer data)
  {
 -    ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func,
 -                                     client, FALSE);
 +    obt_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func,
 +                                      client, FALSE);
  }
  
  void event_halt_focus_delay(void)
  {
      /* ignore all enter events up till the event which caused this to occur */
      if (event_curserial) event_ignore_enter_range(1, event_curserial);
 -    ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
 +    obt_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
  }
  
  gulong event_start_ignore_all_enters(void)
  {
 -    return NextRequest(ob_display);
 +    return NextRequest(obt_display);
  }
  
  static void event_ignore_enter_range(gulong start, gulong end)
      r->end = end;
      ignore_serials = g_slist_prepend(ignore_serials, r);
  
 -    ob_debug_type(OB_DEBUG_FOCUS, "ignoring enters from %lu until %lu\n",
 +    ob_debug_type(OB_DEBUG_FOCUS, "ignoring enters from %lu until %lu",
                    r->start, r->end);
  
      /* increment the serial so we don't ignore events we weren't meant to */
 -    PROP_ERASE(screen_support_win, motif_wm_hints);
 +    OBT_PROP_ERASE(screen_support_win, MOTIF_WM_HINTS);
  }
  
  void event_end_ignore_all_enters(gulong start)
         movement will be ignored until we create some further network traffic.
         Instead ignore up to NextRequest-1, then when we increment the serial,
         we will be *past* the range of ignored serials */
 -    event_ignore_enter_range(start, NextRequest(ob_display)-1);
 +    event_ignore_enter_range(start, NextRequest(obt_display)-1);
  }
  
  static gboolean is_enter_focus_event_ignored(gulong serial)
@@@ -2014,24 -1992,24 +2014,24 @@@ void event_cancel_all_key_grabs(void
  {
      if (actions_interactive_act_running()) {
          actions_interactive_cancel_act();
 -        ob_debug("KILLED interactive action\n");
 +        ob_debug("KILLED interactive action");
      }
      else if (menu_frame_visible) {
          menu_frame_hide_all();
 -        ob_debug("KILLED open menus\n");
 +        ob_debug("KILLED open menus");
      }
      else if (moveresize_in_progress) {
          moveresize_end(TRUE);
 -        ob_debug("KILLED interactive moveresize\n");
 +        ob_debug("KILLED interactive moveresize");
      }
      else if (grab_on_keyboard()) {
          ungrab_keyboard();
 -        ob_debug("KILLED active grab on keyboard\n");
 +        ob_debug("KILLED active grab on keyboard");
      }
      else
          ungrab_passive_key();
  
 -    XSync(ob_display, FALSE);
 +    XSync(obt_display, FALSE);
  }
  
  gboolean event_time_after(guint32 t1, guint32 t2)
@@@ -2066,9 -2044,9 +2066,9 @@@ Time event_get_server_time(void
      /* Generate a timestamp */
      XEvent event;
  
 -    XChangeProperty(ob_display, screen_support_win,
 -                    prop_atoms.wm_class, prop_atoms.string,
 +    XChangeProperty(obt_display, screen_support_win,
 +                    OBT_PROP_ATOM(WM_CLASS), OBT_PROP_ATOM(STRING),
                      8, PropModeAppend, NULL, 0);
 -    XWindowEvent(ob_display, screen_support_win, PropertyChangeMask, &event);
 +    XWindowEvent(obt_display, screen_support_win, PropertyChangeMask, &event);
      return event.xproperty.time;
  }
diff --combined openbox/frame.c
index c633fa6d1285b729781ba78e8fa1badfd657f33e,e4a64bd37ab2bc726d60e142b881a02fd8324313..ab5a14a868a4761023f52b02bbf3e651645c58d7
  #include "frame.h"
  #include "client.h"
  #include "openbox.h"
 -#include "extensions.h"
 -#include "prop.h"
  #include "grab.h"
  #include "config.h"
  #include "framerender.h"
 -#include "mainloop.h"
  #include "focus_cycle.h"
  #include "focus_cycle_indicator.h"
  #include "moveresize.h"
  #include "screen.h"
  #include "render/theme.h"
 +#include "obt/display.h"
 +#include "obt/prop.h"
  
  #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
                           ButtonPressMask | ButtonReleaseMask | \
@@@ -55,7 -56,7 +55,7 @@@ static void frame_adjust_cursors(ObFram
  static Window createWindow(Window parent, Visual *visual,
                             gulong mask, XSetWindowAttributes *attrib)
  {
 -    return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
 +    return XCreateWindow(obt_display, parent, 0, 0, 1, 1, 0,
                           (visual ? 32 : RrDepth(ob_rr_inst)), InputOutput,
                           (visual ? visual : RrVisual(ob_rr_inst)),
                           mask, attrib);
@@@ -72,7 -73,7 +72,7 @@@ static Visual *check_32bit_client(ObCli
      if (RrDepth(ob_rr_inst) == 32)
          return NULL;
  
 -    ret = XGetWindowAttributes(ob_display, c->window, &wattrib);
 +    ret = XGetWindowAttributes(obt_display, c->window, &wattrib);
      g_assert(ret != BadDrawable);
      g_assert(ret != BadWindow);
  
@@@ -101,12 -102,13 +101,12 @@@ ObFrame *frame_new(ObClient *client
          mask = CWColormap | CWBackPixel | CWBorderPixel;
          /* create a colormap with the visual */
          self->colormap = attrib.colormap =
 -            XCreateColormap(ob_display,
 -                            RootWindow(ob_display, ob_screen),
 +            XCreateColormap(obt_display, obt_root(ob_screen),
                              visual, AllocNone);
 -        attrib.background_pixel = BlackPixel(ob_display, ob_screen);
 -        attrib.border_pixel = BlackPixel(ob_display, ob_screen);
 +        attrib.background_pixel = BlackPixel(obt_display, ob_screen);
 +        attrib.border_pixel = BlackPixel(obt_display, ob_screen);
      }
 -    self->window = createWindow(RootWindow(ob_display, ob_screen), visual,
 +    self->window = createWindow(obt_root(ob_screen), visual,
                                  mask, &attrib);
  
      /* create the visible decor windows */
      self->focused = FALSE;
  
      /* the other stuff is shown based on decor settings */
 -    XMapWindow(ob_display, self->label);
 -    XMapWindow(ob_display, self->backback);
 -    XMapWindow(ob_display, self->backfront);
 +    XMapWindow(obt_display, self->label);
 +    XMapWindow(obt_display, self->backback);
 +    XMapWindow(obt_display, self->backfront);
  
      self->max_press = self->close_press = self->desk_press =
          self->iconify_press = self->shade_press = FALSE;
  static void set_theme_statics(ObFrame *self)
  {
      /* set colors/appearance/sizes for stuff that doesn't change */
 -    XResizeWindow(ob_display, self->max,
 +    XResizeWindow(obt_display, self->max,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->iconify,
 +    XResizeWindow(obt_display, self->iconify,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->icon,
 +    XResizeWindow(obt_display, self->icon,
                    ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
 -    XResizeWindow(ob_display, self->close,
 +    XResizeWindow(obt_display, self->close,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->desk,
 +    XResizeWindow(obt_display, self->desk,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->shade,
 +    XResizeWindow(obt_display, self->shade,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->tltresize,
 +    XResizeWindow(obt_display, self->tltresize,
                    ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
 -    XResizeWindow(ob_display, self->trtresize,
 +    XResizeWindow(obt_display, self->trtresize,
                    ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
 -    XResizeWindow(ob_display, self->tllresize,
 +    XResizeWindow(obt_display, self->tllresize,
                    ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
 -    XResizeWindow(ob_display, self->trrresize,
 +    XResizeWindow(obt_display, self->trrresize,
                    ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
  }
  
@@@ -224,9 -226,9 +224,9 @@@ void frame_free(ObFrame *self
  {
      free_theme_statics(self);
  
 -    XDestroyWindow(ob_display, self->window);
 +    XDestroyWindow(obt_display, self->window);
      if (self->colormap)
 -        XFreeColormap(ob_display, self->colormap);
 +        XFreeColormap(obt_display, self->colormap);
  
      g_free(self);
  }
@@@ -240,8 -242,8 +240,8 @@@ void frame_show(ObFrame *self
             the client gets its MapNotify, i.e. to make sure the client is
             _visible_ when it gets MapNotify. */
          grab_server(TRUE);
 -        XMapWindow(ob_display, self->client->window);
 -        XMapWindow(ob_display, self->window);
 +        XMapWindow(obt_display, self->client->window);
 +        XMapWindow(obt_display, self->window);
          grab_server(FALSE);
      }
  }
@@@ -251,10 -253,10 +251,10 @@@ void frame_hide(ObFrame *self
      if (self->visible) {
          self->visible = FALSE;
          if (!frame_iconify_animating(self))
 -            XUnmapWindow(ob_display, self->window);
 +            XUnmapWindow(obt_display, self->window);
          /* we unmap the client itself so that we can get MapRequest
             events, and because the ICCCM tells us to! */
 -        XUnmapWindow(ob_display, self->client->window);
 +        XUnmapWindow(obt_display, self->client->window);
          self->client->ignore_unmaps += 1;
      }
  }
@@@ -274,13 -276,13 +274,13 @@@ void frame_adjust_shape_kind(ObFrame *s
      if (!((kind == ShapeBounding && self->client->shaped) ||
            (kind == ShapeInput && self->client->shaped_input))) {
          /* clear the shape on the frame window */
 -        XShapeCombineMask(ob_display, self->window, kind,
 +        XShapeCombineMask(obt_display, self->window, kind,
                            self->size.left,
                            self->size.top,
                            None, ShapeSet);
      } else {
          /* make the frame's shape match the clients */
 -        XShapeCombineShape(ob_display, self->window, kind,
 +        XShapeCombineShape(obt_display, self->window, kind,
                             self->size.left,
                             self->size.top,
                             self->client->window,
              ++num;
          }
  
 -        XShapeCombineRectangles(ob_display, self->window,
 -                                kind, 0, 0, xrect, num,
 +        XShapeCombineRectangles(obt_display, self->window,
 +                                ShapeBounding, 0, 0, xrect, num,
                                  ShapeUnion, Unsorted);
      }
  }
@@@ -339,7 -341,8 +339,8 @@@ void frame_adjust_area(ObFrame *self, g
          self->shaded = self->client->shaded;
  
          if (self->decorations & OB_FRAME_DECOR_BORDER ||
-             (self->client->undecorated && config_theme_keepborder))
+             (self->client->undecorated && config_theme_keepborder
+              && !self->client->fullscreen))
              self->bwidth = ob_rr_theme->fbwidth;
          else
              self->bwidth = 0;
                  ob_rr_theme->grip_width - self->size.bottom;
  
              if (self->cbwidth_l) {
 -                XMoveResizeWindow(ob_display, self->innerleft,
 +                XMoveResizeWindow(obt_display, self->innerleft,
                                    self->size.left - self->cbwidth_l,
                                    self->size.top,
                                    self->cbwidth_l, self->client->area.height);
  
 -                XMapWindow(ob_display, self->innerleft);
 +                XMapWindow(obt_display, self->innerleft);
              } else
 -                XUnmapWindow(ob_display, self->innerleft);
 +                XUnmapWindow(obt_display, self->innerleft);
  
              if (self->cbwidth_l && innercornerheight > 0) {
 -                XMoveResizeWindow(ob_display, self->innerbll,
 +                XMoveResizeWindow(obt_display, self->innerbll,
                                    0,
                                    self->client->area.height - 
                                    (ob_rr_theme->grip_width -
                                    self->cbwidth_l,
                                    ob_rr_theme->grip_width - self->size.bottom);
  
 -                XMapWindow(ob_display, self->innerbll);
 +                XMapWindow(obt_display, self->innerbll);
              } else
 -                XUnmapWindow(ob_display, self->innerbll);
 +                XUnmapWindow(obt_display, self->innerbll);
  
              if (self->cbwidth_r) {
 -                XMoveResizeWindow(ob_display, self->innerright,
 +                XMoveResizeWindow(obt_display, self->innerright,
                                    self->size.left + self->client->area.width,
                                    self->size.top,
                                    self->cbwidth_r, self->client->area.height);
  
 -                XMapWindow(ob_display, self->innerright);
 +                XMapWindow(obt_display, self->innerright);
              } else
 -                XUnmapWindow(ob_display, self->innerright);
 +                XUnmapWindow(obt_display, self->innerright);
  
              if (self->cbwidth_r && innercornerheight > 0) {
 -                XMoveResizeWindow(ob_display, self->innerbrr,
 +                XMoveResizeWindow(obt_display, self->innerbrr,
                                    0,
                                    self->client->area.height - 
                                    (ob_rr_theme->grip_width -
                                    self->cbwidth_r,
                                    ob_rr_theme->grip_width - self->size.bottom);
  
 -                XMapWindow(ob_display, self->innerbrr);
 +                XMapWindow(obt_display, self->innerbrr);
              } else
 -                XUnmapWindow(ob_display, self->innerbrr);
 +                XUnmapWindow(obt_display, self->innerbrr);
  
              if (self->cbwidth_t) {
 -                XMoveResizeWindow(ob_display, self->innertop,
 +                XMoveResizeWindow(obt_display, self->innertop,
                                    self->size.left - self->cbwidth_l,
                                    self->size.top - self->cbwidth_t,
                                    self->client->area.width +
                                    self->cbwidth_l + self->cbwidth_r,
                                    self->cbwidth_t);
  
 -                XMapWindow(ob_display, self->innertop);
 +                XMapWindow(obt_display, self->innertop);
              } else
 -                XUnmapWindow(ob_display, self->innertop);
 +                XUnmapWindow(obt_display, self->innertop);
  
              if (self->cbwidth_b) {
 -                XMoveResizeWindow(ob_display, self->innerbottom,
 +                XMoveResizeWindow(obt_display, self->innerbottom,
                                    self->size.left - self->cbwidth_l,
                                    self->size.top + self->client->area.height,
                                    self->client->area.width +
                                    self->cbwidth_l + self->cbwidth_r,
                                    self->cbwidth_b);
  
 -                XMoveResizeWindow(ob_display, self->innerblb,
 +                XMoveResizeWindow(obt_display, self->innerblb,
                                    0, 0,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->cbwidth_b);
 -                XMoveResizeWindow(ob_display, self->innerbrb,
 +                XMoveResizeWindow(obt_display, self->innerbrb,
                                    self->client->area.width +
                                    self->cbwidth_l + self->cbwidth_r -
                                    (ob_rr_theme->grip_width + self->bwidth),
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->cbwidth_b);
  
 -                XMapWindow(ob_display, self->innerbottom);
 -                XMapWindow(ob_display, self->innerblb);
 -                XMapWindow(ob_display, self->innerbrb);
 +                XMapWindow(obt_display, self->innerbottom);
 +                XMapWindow(obt_display, self->innerblb);
 +                XMapWindow(obt_display, self->innerbrb);
              } else {
 -                XUnmapWindow(ob_display, self->innerbottom);
 -                XUnmapWindow(ob_display, self->innerblb);
 -                XUnmapWindow(ob_display, self->innerbrb);
 +                XUnmapWindow(obt_display, self->innerbottom);
 +                XUnmapWindow(obt_display, self->innerblb);
 +                XUnmapWindow(obt_display, self->innerbrb);
              }
  
              if (self->bwidth) {
                  /* height of titleleft and titleright */
                  titlesides = (!self->max_horz ? ob_rr_theme->grip_width : 0);
  
 -                XMoveResizeWindow(ob_display, self->titletop,
 +                XMoveResizeWindow(obt_display, self->titletop,
                                    ob_rr_theme->grip_width + self->bwidth, 0,
                                    /* width + bwidth*2 - bwidth*2 - grips*2 */
                                    self->width - ob_rr_theme->grip_width * 2,
                                    self->bwidth);
 -                XMoveResizeWindow(ob_display, self->titletopleft,
 +                XMoveResizeWindow(obt_display, self->titletopleft,
                                    0, 0,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->bwidth);
 -                XMoveResizeWindow(ob_display, self->titletopright,
 +                XMoveResizeWindow(obt_display, self->titletopright,
                                    self->client->area.width +
                                    self->size.left + self->size.right -
                                    ob_rr_theme->grip_width - self->bwidth,
                                    self->bwidth);
  
                  if (titlesides > 0) {
 -                    XMoveResizeWindow(ob_display, self->titleleft,
 +                    XMoveResizeWindow(obt_display, self->titleleft,
                                        0, self->bwidth,
                                        self->bwidth,
                                        titlesides);
 -                    XMoveResizeWindow(ob_display, self->titleright,
 +                    XMoveResizeWindow(obt_display, self->titleright,
                                        self->client->area.width +
                                        self->size.left + self->size.right -
                                        self->bwidth,
                                        self->bwidth,
                                        titlesides);
  
 -                    XMapWindow(ob_display, self->titleleft);
 -                    XMapWindow(ob_display, self->titleright);
 +                    XMapWindow(obt_display, self->titleleft);
 +                    XMapWindow(obt_display, self->titleright);
                  } else {
 -                    XUnmapWindow(ob_display, self->titleleft);
 -                    XUnmapWindow(ob_display, self->titleright);
 +                    XUnmapWindow(obt_display, self->titleleft);
 +                    XUnmapWindow(obt_display, self->titleright);
                  }
  
 -                XMapWindow(ob_display, self->titletop);
 -                XMapWindow(ob_display, self->titletopleft);
 -                XMapWindow(ob_display, self->titletopright);
 +                XMapWindow(obt_display, self->titletop);
 +                XMapWindow(obt_display, self->titletopleft);
 +                XMapWindow(obt_display, self->titletopright);
  
                  if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
 -                    XMoveResizeWindow(ob_display, self->titlebottom,
 +                    XMoveResizeWindow(obt_display, self->titlebottom,
                                        (self->max_horz ? 0 : self->bwidth),
                                        ob_rr_theme->title_height + self->bwidth,
                                        self->width,
                                        self->bwidth);
  
 -                    XMapWindow(ob_display, self->titlebottom);
 +                    XMapWindow(obt_display, self->titlebottom);
                  } else
 -                    XUnmapWindow(ob_display, self->titlebottom);
 +                    XUnmapWindow(obt_display, self->titlebottom);
              } else {
 -                XUnmapWindow(ob_display, self->titlebottom);
 +                XUnmapWindow(obt_display, self->titlebottom);
  
 -                XUnmapWindow(ob_display, self->titletop);
 -                XUnmapWindow(ob_display, self->titletopleft);
 -                XUnmapWindow(ob_display, self->titletopright);
 -                XUnmapWindow(ob_display, self->titleleft);
 -                XUnmapWindow(ob_display, self->titleright);
 +                XUnmapWindow(obt_display, self->titletop);
 +                XUnmapWindow(obt_display, self->titletopleft);
 +                XUnmapWindow(obt_display, self->titletopright);
 +                XUnmapWindow(obt_display, self->titleleft);
 +                XUnmapWindow(obt_display, self->titleright);
              }
  
              if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
 -                XMoveResizeWindow(ob_display, self->title,
 +                XMoveResizeWindow(obt_display, self->title,
                                    (self->max_horz ? 0 : self->bwidth),
                                    self->bwidth,
                                    self->width, ob_rr_theme->title_height);
  
 -                XMapWindow(ob_display, self->title);
 +                XMapWindow(obt_display, self->title);
  
                  if (self->decorations & OB_FRAME_DECOR_GRIPS) {
 -                    XMoveResizeWindow(ob_display, self->topresize,
 +                    XMoveResizeWindow(obt_display, self->topresize,
                                        ob_rr_theme->grip_width,
                                        0,
                                        self->width - ob_rr_theme->grip_width *2,
                                        ob_rr_theme->paddingy + 1);
  
 -                    XMoveWindow(ob_display, self->tltresize, 0, 0);
 -                    XMoveWindow(ob_display, self->tllresize, 0, 0);
 -                    XMoveWindow(ob_display, self->trtresize,
 +                    XMoveWindow(obt_display, self->tltresize, 0, 0);
 +                    XMoveWindow(obt_display, self->tllresize, 0, 0);
 +                    XMoveWindow(obt_display, self->trtresize,
                                  self->width - ob_rr_theme->grip_width, 0);
 -                    XMoveWindow(ob_display, self->trrresize,
 +                    XMoveWindow(obt_display, self->trrresize,
                                  self->width - ob_rr_theme->paddingx - 1, 0);
  
 -                    XMapWindow(ob_display, self->topresize);
 -                    XMapWindow(ob_display, self->tltresize);
 -                    XMapWindow(ob_display, self->tllresize);
 -                    XMapWindow(ob_display, self->trtresize);
 -                    XMapWindow(ob_display, self->trrresize);
 +                    XMapWindow(obt_display, self->topresize);
 +                    XMapWindow(obt_display, self->tltresize);
 +                    XMapWindow(obt_display, self->tllresize);
 +                    XMapWindow(obt_display, self->trtresize);
 +                    XMapWindow(obt_display, self->trrresize);
                  } else {
 -                    XUnmapWindow(ob_display, self->topresize);
 -                    XUnmapWindow(ob_display, self->tltresize);
 -                    XUnmapWindow(ob_display, self->tllresize);
 -                    XUnmapWindow(ob_display, self->trtresize);
 -                    XUnmapWindow(ob_display, self->trrresize);
 +                    XUnmapWindow(obt_display, self->topresize);
 +                    XUnmapWindow(obt_display, self->tltresize);
 +                    XUnmapWindow(obt_display, self->tllresize);
 +                    XUnmapWindow(obt_display, self->trtresize);
 +                    XUnmapWindow(obt_display, self->trrresize);
                  }
              } else
 -                XUnmapWindow(ob_display, self->title);
 +                XUnmapWindow(obt_display, self->title);
          }
  
          if ((self->decorations & OB_FRAME_DECOR_TITLEBAR))
              gint sidebwidth = self->max_horz ? 0 : self->bwidth;
  
              if (self->bwidth && self->size.bottom) {
 -                XMoveResizeWindow(ob_display, self->handlebottom,
 +                XMoveResizeWindow(obt_display, self->handlebottom,
                                    ob_rr_theme->grip_width +
                                    self->bwidth + sidebwidth,
                                    self->size.top + self->client->area.height +
                                                   sidebwidth) * 2,
                                    self->bwidth);
  
 +
                  if (sidebwidth) {
 -                    XMoveResizeWindow(ob_display, self->lgripleft,
 +                    XMoveResizeWindow(obt_display, self->lgripleft,
                                        0,
                                        self->size.top +
                                        self->client->area.height +
                                        (!self->max_horz ?
                                         ob_rr_theme->grip_width :
                                         self->size.bottom - self->cbwidth_b));
 -                    XMoveResizeWindow(ob_display, self->rgripright,
 +                    XMoveResizeWindow(obt_display, self->rgripright,
                                    self->size.left +
                                        self->client->area.width +
                                        self->size.right - self->bwidth,
                                         ob_rr_theme->grip_width :
                                         self->size.bottom - self->cbwidth_b));
  
 -                    XMapWindow(ob_display, self->lgripleft);
 -                    XMapWindow(ob_display, self->rgripright);
 +                    XMapWindow(obt_display, self->lgripleft);
 +                    XMapWindow(obt_display, self->rgripright);
                  } else {
 -                    XUnmapWindow(ob_display, self->lgripleft);
 -                    XUnmapWindow(ob_display, self->rgripright);
 +                    XUnmapWindow(obt_display, self->lgripleft);
 +                    XUnmapWindow(obt_display, self->rgripright);
                  }
  
 -                XMoveResizeWindow(ob_display, self->lgripbottom,
 +                XMoveResizeWindow(obt_display, self->lgripbottom,
                                    sidebwidth,
                                    self->size.top + self->client->area.height +
                                    self->size.bottom - self->bwidth,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->bwidth);
 -                XMoveResizeWindow(ob_display, self->rgripbottom,
 +                XMoveResizeWindow(obt_display, self->rgripbottom,
                                    self->size.left + self->client->area.width +
                                    self->size.right - self->bwidth - sidebwidth-
                                    ob_rr_theme->grip_width,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->bwidth);
  
 -                XMapWindow(ob_display, self->handlebottom);
 -                XMapWindow(ob_display, self->lgripbottom);
 -                XMapWindow(ob_display, self->rgripbottom);
 +                XMapWindow(obt_display, self->handlebottom);
 +                XMapWindow(obt_display, self->lgripbottom);
 +                XMapWindow(obt_display, self->rgripbottom);
  
                  if (self->decorations & OB_FRAME_DECOR_HANDLE &&
                      ob_rr_theme->handle_height > 0)
                  {
 -                    XMoveResizeWindow(ob_display, self->handletop,
 +                    XMoveResizeWindow(obt_display, self->handletop,
                                        ob_rr_theme->grip_width +
                                        self->bwidth + sidebwidth,
                                        FRAME_HANDLE_Y(self),
                                        self->width - (ob_rr_theme->grip_width +
                                                       sidebwidth) * 2,
                                        self->bwidth);
 -                    XMapWindow(ob_display, self->handletop);
 +                    XMapWindow(obt_display, self->handletop);
  
                      if (self->decorations & OB_FRAME_DECOR_GRIPS) {
 -                        XMoveResizeWindow(ob_display, self->handleleft,
 +                        XMoveResizeWindow(obt_display, self->handleleft,
                                            ob_rr_theme->grip_width,
                                            0,
                                            self->bwidth,
                                            ob_rr_theme->handle_height);
 -                        XMoveResizeWindow(ob_display, self->handleright,
 +                        XMoveResizeWindow(obt_display, self->handleright,
                                            self->width -
                                            ob_rr_theme->grip_width -
                                            self->bwidth,
                                            self->bwidth,
                                            ob_rr_theme->handle_height);
  
 -                        XMoveResizeWindow(ob_display, self->lgriptop,
 +                        XMoveResizeWindow(obt_display, self->lgriptop,
                                            sidebwidth,
                                            FRAME_HANDLE_Y(self),
                                            ob_rr_theme->grip_width +
                                            self->bwidth,
                                            self->bwidth);
 -                        XMoveResizeWindow(ob_display, self->rgriptop,
 +                        XMoveResizeWindow(obt_display, self->rgriptop,
                                            self->size.left +
                                            self->client->area.width +
                                            self->size.right - self->bwidth -
                                            self->bwidth,
                                            self->bwidth);
  
 -                        XMapWindow(ob_display, self->handleleft);
 -                        XMapWindow(ob_display, self->handleright);
 -                        XMapWindow(ob_display, self->lgriptop);
 -                        XMapWindow(ob_display, self->rgriptop);
 +                        XMapWindow(obt_display, self->handleleft);
 +                        XMapWindow(obt_display, self->handleright);
 +                        XMapWindow(obt_display, self->lgriptop);
 +                        XMapWindow(obt_display, self->rgriptop);
                      } else {
 -                        XUnmapWindow(ob_display, self->handleleft);
 -                        XUnmapWindow(ob_display, self->handleright);
 -                        XUnmapWindow(ob_display, self->lgriptop);
 -                        XUnmapWindow(ob_display, self->rgriptop);
 +                        XUnmapWindow(obt_display, self->handleleft);
 +                        XUnmapWindow(obt_display, self->handleright);
 +                        XUnmapWindow(obt_display, self->lgriptop);
 +                        XUnmapWindow(obt_display, self->rgriptop);
                      }
                  } else {
 -                    XUnmapWindow(ob_display, self->handleleft);
 -                    XUnmapWindow(ob_display, self->handleright);
 -                    XUnmapWindow(ob_display, self->lgriptop);
 -                    XUnmapWindow(ob_display, self->rgriptop);
 +                    XUnmapWindow(obt_display, self->handleleft);
 +                    XUnmapWindow(obt_display, self->handleright);
 +                    XUnmapWindow(obt_display, self->lgriptop);
 +                    XUnmapWindow(obt_display, self->rgriptop);
  
 -                    XUnmapWindow(ob_display, self->handletop);
 +                    XUnmapWindow(obt_display, self->handletop);
                  }
              } else {
 -                XUnmapWindow(ob_display, self->handleleft);
 -                XUnmapWindow(ob_display, self->handleright);
 -                XUnmapWindow(ob_display, self->lgriptop);
 -                XUnmapWindow(ob_display, self->rgriptop);
 -
 -                XUnmapWindow(ob_display, self->handletop);
 -
 -                XUnmapWindow(ob_display, self->handlebottom);
 -                XUnmapWindow(ob_display, self->lgripleft);
 -                XUnmapWindow(ob_display, self->rgripright);
 -                XUnmapWindow(ob_display, self->lgripbottom);
 -                XUnmapWindow(ob_display, self->rgripbottom);
 +                XUnmapWindow(obt_display, self->handleleft);
 +                XUnmapWindow(obt_display, self->handleright);
 +                XUnmapWindow(obt_display, self->lgriptop);
 +                XUnmapWindow(obt_display, self->rgriptop);
 +
 +                XUnmapWindow(obt_display, self->handletop);
 +
 +                XUnmapWindow(obt_display, self->handlebottom);
 +                XUnmapWindow(obt_display, self->lgripleft);
 +                XUnmapWindow(obt_display, self->rgripright);
 +                XUnmapWindow(obt_display, self->lgripbottom);
 +                XUnmapWindow(obt_display, self->rgripbottom);
              }
  
              if (self->decorations & OB_FRAME_DECOR_HANDLE &&
                  ob_rr_theme->handle_height > 0)
              {
 -                XMoveResizeWindow(ob_display, self->handle,
 +                XMoveResizeWindow(obt_display, self->handle,
                                    sidebwidth,
                                    FRAME_HANDLE_Y(self) + self->bwidth,
                                    self->width, ob_rr_theme->handle_height);
 -                XMapWindow(ob_display, self->handle);
 +                XMapWindow(obt_display, self->handle);
  
                  if (self->decorations & OB_FRAME_DECOR_GRIPS) {
 -                    XMoveResizeWindow(ob_display, self->lgrip,
 +                    XMoveResizeWindow(obt_display, self->lgrip,
                                        0, 0,
                                        ob_rr_theme->grip_width,
                                        ob_rr_theme->handle_height);
 -                    XMoveResizeWindow(ob_display, self->rgrip,
 +                    XMoveResizeWindow(obt_display, self->rgrip,
                                        self->width - ob_rr_theme->grip_width,
                                        0,
                                        ob_rr_theme->grip_width,
                                        ob_rr_theme->handle_height);
  
 -                    XMapWindow(ob_display, self->lgrip);
 -                    XMapWindow(ob_display, self->rgrip);
 +                    XMapWindow(obt_display, self->lgrip);
 +                    XMapWindow(obt_display, self->rgrip);
                  } else {
 -                    XUnmapWindow(ob_display, self->lgrip);
 -                    XUnmapWindow(ob_display, self->rgrip);
 +                    XUnmapWindow(obt_display, self->lgrip);
 +                    XUnmapWindow(obt_display, self->rgrip);
                  }
              } else {
 -                XUnmapWindow(ob_display, self->lgrip);
 -                XUnmapWindow(ob_display, self->rgrip);
 +                XUnmapWindow(obt_display, self->lgrip);
 +                XUnmapWindow(obt_display, self->rgrip);
  
 -                XUnmapWindow(ob_display, self->handle);
 +                XUnmapWindow(obt_display, self->handle);
              }
  
              if (self->bwidth && !self->max_horz &&
                  (self->client->area.height + self->size.top +
                   self->size.bottom) > ob_rr_theme->grip_width * 2)
              {
 -                XMoveResizeWindow(ob_display, self->left,
 +                XMoveResizeWindow(obt_display, self->left,
                                    0,
                                    self->bwidth + ob_rr_theme->grip_width,
                                    self->bwidth,
                                    self->size.top + self->size.bottom -
                                    ob_rr_theme->grip_width * 2);
  
 -                XMapWindow(ob_display, self->left);
 +                XMapWindow(obt_display, self->left);
              } else
 -                XUnmapWindow(ob_display, self->left);
 +                XUnmapWindow(obt_display, self->left);
  
              if (self->bwidth && !self->max_horz &&
                  (self->client->area.height + self->size.top +
                   self->size.bottom) > ob_rr_theme->grip_width * 2)
              {
 -                XMoveResizeWindow(ob_display, self->right,
 +                XMoveResizeWindow(obt_display, self->right,
                                    self->client->area.width + self->cbwidth_l +
                                    self->cbwidth_r + self->bwidth,
                                    self->bwidth + ob_rr_theme->grip_width,
                                    self->size.top + self->size.bottom -
                                    ob_rr_theme->grip_width * 2);
  
 -                XMapWindow(ob_display, self->right);
 +                XMapWindow(obt_display, self->right);
              } else
 -                XUnmapWindow(ob_display, self->right);
 +                XUnmapWindow(obt_display, self->right);
  
 -            XMoveResizeWindow(ob_display, self->backback,
 +            XMoveResizeWindow(obt_display, self->backback,
                                self->size.left, self->size.top,
                                self->client->area.width,
                                self->client->area.height);
                 but don't do this during an iconify animation. it will be
                 reflected afterwards.
              */
 -            XMoveResizeWindow(ob_display, self->window,
 +            XMoveResizeWindow(obt_display, self->window,
                                self->area.x,
                                self->area.y,
                                self->area.width,
             also this correctly positions the client when it maps.
             this also needs to be run when the frame's decorations sizes change!
          */
 -        XMoveWindow(ob_display, self->client->window,
 +        XMoveWindow(obt_display, self->client->window,
                      self->size.left, self->size.top);
  
          if (resized) {
              vals[1] = self->size.right;
              vals[2] = self->size.top;
              vals[3] = self->size.bottom;
 -            PROP_SETA32(self->client->window, net_frame_extents,
 -                        cardinal, vals, 4);
 -            PROP_SETA32(self->client->window, kde_net_wm_frame_strut,
 -                        cardinal, vals, 4);
 +            OBT_PROP_SETA32(self->client->window, NET_FRAME_EXTENTS,
 +                            CARDINAL, vals, 4);
 +            OBT_PROP_SETA32(self->client->window, KDE_NET_WM_FRAME_STRUT,
 +                            CARDINAL, vals, 4);
          }
  
          /* if this occurs while we are focus cycling, the indicator needs to
              focus_cycle_update_indicator(self->client);
      }
      if (resized && (self->decorations & OB_FRAME_DECOR_TITLEBAR))
 -        XResizeWindow(ob_display, self->label, self->label_width,
 +        XResizeWindow(obt_display, self->label, self->label_width,
                        ob_rr_theme->label_height);
  
  }
@@@ -884,58 -886,58 +885,58 @@@ static void frame_adjust_cursors(ObFram
          /* these ones turn off when max vert, and some when shaded */
          a.cursor = ob_cursor(r && topbot && !sh ?
                               OB_CURSOR_NORTH : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->topresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->titletop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->topresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titletop, CWCursor, &a);
          a.cursor = ob_cursor(r && topbot ? OB_CURSOR_SOUTH : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->handle, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handletop, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handlebottom, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handle, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handletop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handlebottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbottom, CWCursor, &a);
  
          /* these ones change when shaded */
          a.cursor = ob_cursor(r ? (sh ? OB_CURSOR_WEST : OB_CURSOR_NORTHWEST) :
                               OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->titleleft, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->tltresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->tllresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->titletopleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titleleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->tltresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->tllresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titletopleft, CWCursor, &a);
          a.cursor = ob_cursor(r ? (sh ? OB_CURSOR_EAST : OB_CURSOR_NORTHEAST) :
                               OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->titleright, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->trtresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->trrresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->titletopright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titleright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->trtresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->trrresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titletopright, CWCursor,&a);
  
          /* these ones are pretty static */
          a.cursor = ob_cursor(r ? OB_CURSOR_WEST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->left, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->left, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerleft, CWCursor, &a);
          a.cursor = ob_cursor(r ? OB_CURSOR_EAST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->right, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->right, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerright, CWCursor, &a);
          a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHWEST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->lgrip, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handleleft, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->lgripleft, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->lgriptop, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->lgripbottom, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbll, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerblb, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgrip, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handleleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgripleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgriptop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgripbottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbll, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerblb, CWCursor, &a);
          a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHEAST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->rgrip, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handleright, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->rgripright, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->rgriptop, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->rgripbottom, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbrr, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbrb, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgrip, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handleright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgripright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgriptop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgripbottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbrr, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbrb, CWCursor, &a);
      }
  }
  
  void frame_adjust_client_area(ObFrame *self)
  {
      /* adjust the window which is there to prevent flashing on unmap */
 -    XMoveResizeWindow(ob_display, self->backfront, 0, 0,
 +    XMoveResizeWindow(obt_display, self->backfront, 0, 0,
                        self->client->area.width,
                        self->client->area.height);
  }
@@@ -951,7 -953,7 +952,7 @@@ void frame_adjust_focus(ObFrame *self, 
      self->focused = hilite;
      self->need_render = TRUE;
      framerender_frame(self);
 -    XFlush(ob_display);
 +    XFlush(obt_display);
  }
  
  void frame_adjust_title(ObFrame *self)
@@@ -974,7 -976,7 +975,7 @@@ void frame_grab_client(ObFrame *self
      */
  
      /* reparent the client to the frame */
 -    XReparentWindow(ob_display, self->client->window, self->window, 0, 0);
 +    XReparentWindow(obt_display, self->client->window, self->window, 0, 0);
  
      /*
        When reparenting the client window, it is usually not mapped yet, since
  
      /* select the event mask on the client's parent (to receive config/map
         req's) the ButtonPress is to catch clicks on the client border */
 -    XSelectInput(ob_display, self->window, FRAME_EVENTMASK);
 +    XSelectInput(obt_display, self->window, FRAME_EVENTMASK);
  
      /* set all the windows for the frame in the window_map */
 -    g_hash_table_insert(window_map, &self->window, self->client);
 -    g_hash_table_insert(window_map, &self->backback, self->client);
 -    g_hash_table_insert(window_map, &self->backfront, self->client);
 -    g_hash_table_insert(window_map, &self->innerleft, self->client);
 -    g_hash_table_insert(window_map, &self->innertop, self->client);
 -    g_hash_table_insert(window_map, &self->innerright, self->client);
 -    g_hash_table_insert(window_map, &self->innerbottom, self->client);
 -    g_hash_table_insert(window_map, &self->innerblb, self->client);
 -    g_hash_table_insert(window_map, &self->innerbll, self->client);
 -    g_hash_table_insert(window_map, &self->innerbrb, self->client);
 -    g_hash_table_insert(window_map, &self->innerbrr, self->client);
 -    g_hash_table_insert(window_map, &self->title, self->client);
 -    g_hash_table_insert(window_map, &self->label, self->client);
 -    g_hash_table_insert(window_map, &self->max, self->client);
 -    g_hash_table_insert(window_map, &self->close, self->client);
 -    g_hash_table_insert(window_map, &self->desk, self->client);
 -    g_hash_table_insert(window_map, &self->shade, self->client);
 -    g_hash_table_insert(window_map, &self->icon, self->client);
 -    g_hash_table_insert(window_map, &self->iconify, self->client);
 -    g_hash_table_insert(window_map, &self->handle, self->client);
 -    g_hash_table_insert(window_map, &self->lgrip, self->client);
 -    g_hash_table_insert(window_map, &self->rgrip, self->client);
 -    g_hash_table_insert(window_map, &self->topresize, self->client);
 -    g_hash_table_insert(window_map, &self->tltresize, self->client);
 -    g_hash_table_insert(window_map, &self->tllresize, self->client);
 -    g_hash_table_insert(window_map, &self->trtresize, self->client);
 -    g_hash_table_insert(window_map, &self->trrresize, self->client);
 -    g_hash_table_insert(window_map, &self->left, self->client);
 -    g_hash_table_insert(window_map, &self->right, self->client);
 -    g_hash_table_insert(window_map, &self->titleleft, self->client);
 -    g_hash_table_insert(window_map, &self->titletop, self->client);
 -    g_hash_table_insert(window_map, &self->titletopleft, self->client);
 -    g_hash_table_insert(window_map, &self->titletopright, self->client);
 -    g_hash_table_insert(window_map, &self->titleright, self->client);
 -    g_hash_table_insert(window_map, &self->titlebottom, self->client);
 -    g_hash_table_insert(window_map, &self->handleleft, self->client);
 -    g_hash_table_insert(window_map, &self->handletop, self->client);
 -    g_hash_table_insert(window_map, &self->handleright, self->client);
 -    g_hash_table_insert(window_map, &self->handlebottom, self->client);
 -    g_hash_table_insert(window_map, &self->lgripleft, self->client);
 -    g_hash_table_insert(window_map, &self->lgriptop, self->client);
 -    g_hash_table_insert(window_map, &self->lgripbottom, self->client);
 -    g_hash_table_insert(window_map, &self->rgripright, self->client);
 -    g_hash_table_insert(window_map, &self->rgriptop, self->client);
 -    g_hash_table_insert(window_map, &self->rgripbottom, self->client);
 +    window_add(&self->window, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->backback, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->backfront, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innertop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerblb, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbll, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbrb, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbrr, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->title, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->label, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->max, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->close, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->desk, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->shade, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->icon, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->iconify, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handle, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgrip, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgrip, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->topresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->tltresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->tllresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->trtresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->trrresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->left, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->right, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titleleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titletop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titletopleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titletopright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titleright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titlebottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handleleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handletop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handleright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handlebottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgripleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgriptop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgripbottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgripright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgriptop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgripbottom, CLIENT_AS_WINDOW(self->client));
  }
  
  void frame_release_client(ObFrame *self)
      gboolean reparent = TRUE;
  
      /* if there was any animation going on, kill it */
 -    ob_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 -                                     self, FALSE);
 +    obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 +                                      self, FALSE);
  
      /* check if the app has already reparented its window away */
 -    while (XCheckTypedWindowEvent(ob_display, self->client->window,
 +    while (XCheckTypedWindowEvent(obt_display, self->client->window,
                                    ReparentNotify, &ev))
      {
          /* This check makes sure we don't catch our own reparent action to
          */
          if (ev.xreparent.parent != self->window) {
              reparent = FALSE;
 -            XPutBackEvent(ob_display, &ev);
 +            XPutBackEvent(obt_display, &ev);
              break;
          }
      }
      if (reparent) {
          /* according to the ICCCM - if the client doesn't reparent itself,
             then we will reparent the window to root for them */
 -        XReparentWindow(ob_display, self->client->window,
 -                        RootWindow(ob_display, ob_screen),
 -                        self->client->area.x,
 -                        self->client->area.y);
 +        XReparentWindow(obt_display, self->client->window, obt_root(ob_screen),
 +                        self->client->area.x, self->client->area.y);
      }
  
      /* remove all the windows for the frame from the window_map */
 -    g_hash_table_remove(window_map, &self->window);
 -    g_hash_table_remove(window_map, &self->backback);
 -    g_hash_table_remove(window_map, &self->backfront);
 -    g_hash_table_remove(window_map, &self->innerleft);
 -    g_hash_table_remove(window_map, &self->innertop);
 -    g_hash_table_remove(window_map, &self->innerright);
 -    g_hash_table_remove(window_map, &self->innerbottom);
 -    g_hash_table_remove(window_map, &self->innerblb);
 -    g_hash_table_remove(window_map, &self->innerbll);
 -    g_hash_table_remove(window_map, &self->innerbrb);
 -    g_hash_table_remove(window_map, &self->innerbrr);
 -    g_hash_table_remove(window_map, &self->title);
 -    g_hash_table_remove(window_map, &self->label);
 -    g_hash_table_remove(window_map, &self->max);
 -    g_hash_table_remove(window_map, &self->close);
 -    g_hash_table_remove(window_map, &self->desk);
 -    g_hash_table_remove(window_map, &self->shade);
 -    g_hash_table_remove(window_map, &self->icon);
 -    g_hash_table_remove(window_map, &self->iconify);
 -    g_hash_table_remove(window_map, &self->handle);
 -    g_hash_table_remove(window_map, &self->lgrip);
 -    g_hash_table_remove(window_map, &self->rgrip);
 -    g_hash_table_remove(window_map, &self->topresize);
 -    g_hash_table_remove(window_map, &self->tltresize);
 -    g_hash_table_remove(window_map, &self->tllresize);
 -    g_hash_table_remove(window_map, &self->trtresize);
 -    g_hash_table_remove(window_map, &self->trrresize);
 -    g_hash_table_remove(window_map, &self->left);
 -    g_hash_table_remove(window_map, &self->right);
 -    g_hash_table_remove(window_map, &self->titleleft);
 -    g_hash_table_remove(window_map, &self->titletop);
 -    g_hash_table_remove(window_map, &self->titletopleft);
 -    g_hash_table_remove(window_map, &self->titletopright);
 -    g_hash_table_remove(window_map, &self->titleright);
 -    g_hash_table_remove(window_map, &self->titlebottom);
 -    g_hash_table_remove(window_map, &self->handleleft);
 -    g_hash_table_remove(window_map, &self->handletop);
 -    g_hash_table_remove(window_map, &self->handleright);
 -    g_hash_table_remove(window_map, &self->handlebottom);
 -    g_hash_table_remove(window_map, &self->lgripleft);
 -    g_hash_table_remove(window_map, &self->lgriptop);
 -    g_hash_table_remove(window_map, &self->lgripbottom);
 -    g_hash_table_remove(window_map, &self->rgripright);
 -    g_hash_table_remove(window_map, &self->rgriptop);
 -    g_hash_table_remove(window_map, &self->rgripbottom);
 -
 -    ob_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
 +    window_remove(self->window);
 +    window_remove(self->backback);
 +    window_remove(self->backfront);
 +    window_remove(self->innerleft);
 +    window_remove(self->innertop);
 +    window_remove(self->innerright);
 +    window_remove(self->innerbottom);
 +    window_remove(self->innerblb);
 +    window_remove(self->innerbll);
 +    window_remove(self->innerbrb);
 +    window_remove(self->innerbrr);
 +    window_remove(self->title);
 +    window_remove(self->label);
 +    window_remove(self->max);
 +    window_remove(self->close);
 +    window_remove(self->desk);
 +    window_remove(self->shade);
 +    window_remove(self->icon);
 +    window_remove(self->iconify);
 +    window_remove(self->handle);
 +    window_remove(self->lgrip);
 +    window_remove(self->rgrip);
 +    window_remove(self->topresize);
 +    window_remove(self->tltresize);
 +    window_remove(self->tllresize);
 +    window_remove(self->trtresize);
 +    window_remove(self->trrresize);
 +    window_remove(self->left);
 +    window_remove(self->right);
 +    window_remove(self->titleleft);
 +    window_remove(self->titletop);
 +    window_remove(self->titletopleft);
 +    window_remove(self->titletopright);
 +    window_remove(self->titleright);
 +    window_remove(self->titlebottom);
 +    window_remove(self->handleleft);
 +    window_remove(self->handletop);
 +    window_remove(self->handleright);
 +    window_remove(self->handlebottom);
 +    window_remove(self->lgripleft);
 +    window_remove(self->lgriptop);
 +    window_remove(self->lgripbottom);
 +    window_remove(self->rgripright);
 +    window_remove(self->rgriptop);
 +    window_remove(self->rgripbottom);
 +
 +    obt_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
  }
  
  /* is there anything present between us and the label? */
@@@ -1236,53 -1240,53 +1237,53 @@@ static void layout_title(ObFrame *self
  
      /* position and map the elements */
      if (self->icon_on) {
 -        XMapWindow(ob_display, self->icon);
 -        XMoveWindow(ob_display, self->icon, self->icon_x,
 +        XMapWindow(obt_display, self->icon);
 +        XMoveWindow(obt_display, self->icon, self->icon_x,
                      ob_rr_theme->paddingy);
      } else
 -        XUnmapWindow(ob_display, self->icon);
 +        XUnmapWindow(obt_display, self->icon);
  
      if (self->desk_on) {
 -        XMapWindow(ob_display, self->desk);
 -        XMoveWindow(ob_display, self->desk, self->desk_x,
 +        XMapWindow(obt_display, self->desk);
 +        XMoveWindow(obt_display, self->desk, self->desk_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->desk);
 +        XUnmapWindow(obt_display, self->desk);
  
      if (self->shade_on) {
 -        XMapWindow(ob_display, self->shade);
 -        XMoveWindow(ob_display, self->shade, self->shade_x,
 +        XMapWindow(obt_display, self->shade);
 +        XMoveWindow(obt_display, self->shade, self->shade_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->shade);
 +        XUnmapWindow(obt_display, self->shade);
  
      if (self->iconify_on) {
 -        XMapWindow(ob_display, self->iconify);
 -        XMoveWindow(ob_display, self->iconify, self->iconify_x,
 +        XMapWindow(obt_display, self->iconify);
 +        XMoveWindow(obt_display, self->iconify, self->iconify_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->iconify);
 +        XUnmapWindow(obt_display, self->iconify);
  
      if (self->max_on) {
 -        XMapWindow(ob_display, self->max);
 -        XMoveWindow(ob_display, self->max, self->max_x,
 +        XMapWindow(obt_display, self->max);
 +        XMoveWindow(obt_display, self->max, self->max_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->max);
 +        XUnmapWindow(obt_display, self->max);
  
      if (self->close_on) {
 -        XMapWindow(ob_display, self->close);
 -        XMoveWindow(ob_display, self->close, self->close_x,
 +        XMapWindow(obt_display, self->close);
 +        XMoveWindow(obt_display, self->close, self->close_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->close);
 +        XUnmapWindow(obt_display, self->close);
  
      if (self->label_on && self->label_width > 0) {
 -        XMapWindow(ob_display, self->label);
 -        XMoveWindow(ob_display, self->label, self->label_x,
 +        XMapWindow(obt_display, self->label);
 +        XMoveWindow(obt_display, self->label, self->label_x,
                      ob_rr_theme->paddingy);
      } else
 -        XUnmapWindow(ob_display, self->label);
 +        XUnmapWindow(obt_display, self->label);
  }
  
  ObFrameContext frame_context_from_string(const gchar *name)
@@@ -1337,7 -1341,7 +1338,7 @@@ ObFrameContext frame_context(ObClient *
      if (moveresize_in_progress)
          return OB_FRAME_CONTEXT_MOVE_RESIZE;
  
 -    if (win == RootWindow(ob_display, ob_screen))
 +    if (win == obt_root(ob_screen))
          return OB_FRAME_CONTEXT_ROOT ;
      if (client == NULL) return OB_FRAME_CONTEXT_NONE;
      if (win == client->window) {
@@@ -1630,12 -1634,12 +1631,12 @@@ void frame_flash_start(ObFrame *self
      self->flash_on = self->focused;
  
      if (!self->flashing)
 -        ob_main_loop_timeout_add(ob_main_loop,
 -                                 G_USEC_PER_SEC * 0.6,
 -                                 flash_timeout,
 -                                 self,
 -                                 g_direct_equal,
 -                                 flash_done);
 +        obt_main_loop_timeout_add(ob_main_loop,
 +                                  G_USEC_PER_SEC * 0.6,
 +                                  flash_timeout,
 +                                  self,
 +                                  g_direct_equal,
 +                                  flash_done);
      g_get_current_time(&self->flash_end);
      g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5);
  
@@@ -1721,8 -1725,8 +1722,8 @@@ static gboolean frame_animate_iconify(g
          h = self->size.top; /* just the titlebar */
      }
  
 -    XMoveResizeWindow(ob_display, self->window, x, y, w, h);
 -    XFlush(ob_display);
 +    XMoveResizeWindow(obt_display, self->window, x, y, w, h);
 +    XFlush(obt_display);
  
      if (time == 0)
          frame_end_iconify_animation(self);
@@@ -1736,7 -1740,7 +1737,7 @@@ void frame_end_iconify_animation(ObFram
      if (self->iconify_animation_going == 0) return;
  
      if (!self->visible)
 -        XUnmapWindow(ob_display, self->window);
 +        XUnmapWindow(obt_display, self->window);
      else {
          /* Send a ConfigureNotify when the animation is done, this fixes
             KDE's pager showing the window in the wrong place.  since the
      /* we're not animating any more ! */
      self->iconify_animation_going = 0;
  
 -    XMoveResizeWindow(ob_display, self->window,
 +    XMoveResizeWindow(obt_display, self->window,
                        self->area.x, self->area.y,
                        self->area.width, self->area.height);
      /* we delay re-rendering until after we're done animating */
      framerender_frame(self);
 -    XFlush(ob_display);
 +    XFlush(obt_display);
  }
  
  void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying)
      }
  
      if (new_anim) {
 -        ob_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 -                                         self, FALSE);
 -        ob_main_loop_timeout_add(ob_main_loop,
 -                                 FRAME_ANIMATE_ICONIFY_STEP_TIME,
 -                                 frame_animate_iconify, self,
 -                                 g_direct_equal, NULL);
 +        obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 +                                          self, FALSE);
 +        obt_main_loop_timeout_add(ob_main_loop,
 +                                  FRAME_ANIMATE_ICONIFY_STEP_TIME,
 +                                  frame_animate_iconify, self,
 +                                  g_direct_equal, NULL);
  
          /* do the first step */
          frame_animate_iconify(self);
  
          /* show it during the animation even if it is not "visible" */
          if (!self->visible)
 -            XMapWindow(ob_display, self->window);
 +            XMapWindow(obt_display, self->window);
      }
  }
diff --combined openbox/menu.c
index f7d50e39f0f59f8e05b7c1b1e805827beb2bab33,58b6280e5d6c4939a775d6bfcc08bb39d806c176..3e45fb93ca9961a7e253f41af995507155783161
@@@ -20,6 -20,7 +20,6 @@@
  #include "debug.h"
  #include "menu.h"
  #include "openbox.h"
 -#include "mainloop.h"
  #include "stacking.h"
  #include "grab.h"
  #include "client.h"
@@@ -34,8 -35,7 +34,8 @@@
  #include "client_list_menu.h"
  #include "client_list_combined_menu.h"
  #include "gettext.h"
 -#include "parser/parse.h"
 +#include "obt/parse.h"
 +#include "obt/paths.h"
  
  typedef struct _ObMenuParseState ObMenuParseState;
  
@@@ -46,14 -46,18 +46,14 @@@ struct _ObMenuParseStat
  };
  
  static GHashTable *menu_hash = NULL;
 -static ObParseInst *menu_parse_inst;
 +static ObtParseInst *menu_parse_inst;
  static ObMenuParseState menu_parse_state;
  static gboolean menu_can_hide = FALSE;
  
  static void menu_destroy_hash_value(ObMenu *self);
 -static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                            gpointer data);
 -static void parse_menu_separator(ObParseInst *i,
 -                                 xmlDocPtr doc, xmlNodePtr node,
 -                                 gpointer data);
 -static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                       gpointer data);
 +static void parse_menu_item(xmlNodePtr node, gpointer data);
 +static void parse_menu_separator(xmlNodePtr node, gpointer data);
 +static void parse_menu(xmlNodePtr node, gpointer data);
  static gunichar parse_shortcut(const gchar *label, gboolean allow_shortcut,
                                 gchar **strippedlabel, guint *position,
                                 gboolean *always_show);
@@@ -67,6 -71,8 +67,6 @@@ static void client_dest(ObClient *clien
  
  void menu_startup(gboolean reconfig)
  {
 -    xmlDocPtr doc;
 -    xmlNodePtr node;
      gboolean loaded = FALSE;
      GSList *it;
  
      client_list_combined_menu_startup(reconfig);
      client_menu_startup();
  
 -    menu_parse_inst = parse_startup();
 +    menu_parse_inst = obt_parse_instance_new();
  
      menu_parse_state.parent = NULL;
      menu_parse_state.pipe_creator = NULL;
 -    parse_register(menu_parse_inst, "menu", parse_menu, &menu_parse_state);
 -    parse_register(menu_parse_inst, "item", parse_menu_item,
 -                   &menu_parse_state);
 -    parse_register(menu_parse_inst, "separator",
 -                   parse_menu_separator, &menu_parse_state);
 +    obt_parse_register(menu_parse_inst, "menu", parse_menu, &menu_parse_state);
 +    obt_parse_register(menu_parse_inst, "item", parse_menu_item,
 +                       &menu_parse_state);
 +    obt_parse_register(menu_parse_inst, "separator",
 +                       parse_menu_separator, &menu_parse_state);
  
      for (it = config_menu_files; it; it = g_slist_next(it)) {
 -        if (parse_load_menu(it->data, &doc, &node)) {
 +        if (obt_parse_load_config_file(menu_parse_inst,
 +                                       "openbox",
 +                                       it->data,
 +                                       "openbox_menu"))
 +        {
              loaded = TRUE;
 -            parse_tree(menu_parse_inst, doc, node->children);
 -            xmlFreeDoc(doc);
 +            obt_parse_tree_from_root(menu_parse_inst);
 +            obt_parse_close(menu_parse_inst);
          } else
              g_message(_("Unable to find a valid menu file \"%s\""),
                        (const gchar*)it->data);
      }
      if (!loaded) {
 -        if (parse_load_menu("menu.xml", &doc, &node)) {
 -            parse_tree(menu_parse_inst, doc, node->children);
 -            xmlFreeDoc(doc);
 +        if (obt_parse_load_config_file(menu_parse_inst,
 +                                       "openbox",
 +                                       "menu.xml",
 +                                       "openbox_menu"))
 +        {
 +            obt_parse_tree_from_root(menu_parse_inst);
 +            obt_parse_close(menu_parse_inst);
          } else
              g_message(_("Unable to find a valid menu file \"%s\""),
                        "menu.xml");
@@@ -124,7 -122,7 +124,7 @@@ void menu_shutdown(gboolean reconfig
      if (!reconfig)
          client_remove_destroy_notify(client_dest);
  
 -    parse_shutdown(menu_parse_inst);
 +    obt_parse_instance_unref(menu_parse_inst);
      menu_parse_inst = NULL;
  
      client_list_menu_shutdown(reconfig);
@@@ -158,6 -156,8 +158,6 @@@ void menu_clear_pipe_caches(void
  
  void menu_pipe_execute(ObMenu *self)
  {
 -    xmlDocPtr doc;
 -    xmlNodePtr node;
      gchar *output;
      GError *err = NULL;
  
          return;
      }
  
 -    if (parse_load_mem(output, strlen(output),
 -                       "openbox_pipe_menu", &doc, &node))
 +    if (obt_parse_load_mem(menu_parse_inst, output, strlen(output),
 +                           "openbox_pipe_menu"))
      {
          menu_parse_state.pipe_creator = self;
          menu_parse_state.parent = self;
 -        parse_tree(menu_parse_inst, doc, node->children);
 -        xmlFreeDoc(doc);
 +        obt_parse_tree_from_root(menu_parse_inst);
 +        obt_parse_close(menu_parse_inst);
      } else {
          g_message(_("Invalid output from pipe-menu \"%s\""), self->execute);
      }
@@@ -232,10 -232,13 +232,13 @@@ static gunichar parse_shortcut(const gc
              /* you have to use a printable ascii character for shortcuts
                 don't allow space either, so you can have like "a _ b"
              */
-             if (VALID_SHORTCUT(*(i+1))) {
-                 shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
-                 *position = i - *strippedlabel;
-                 *always_show = TRUE;
+             if (VALID_SHORTCUT(*(i+1)) || *(i+1) == '_') {
+                 /* Allow you to escape the first _ by putting __ */
+                 if (*(i+1) != '_') {
+                     shortcut = g_unichar_tolower(g_utf8_get_char(i+1));
+                     *position = i - *strippedlabel;
+                     *always_show = TRUE;
+                 }
  
                  /* remove the '_' from the string */
                  for (; *i != '\0'; ++i)
      return shortcut;
  }
  
 -static void parse_menu_item(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                            gpointer data)
 +static void parse_menu_item(xmlNodePtr node,  gpointer data)
  {
      ObMenuParseState *state = data;
      gchar *label;
  
      if (state->parent) {
 -        if (parse_attr_string("label", node, &label)) {
 +        if (obt_parse_attr_string(node, "label", &label)) {
              GSList *acts = NULL;
  
              for (node = node->children; node; node = node->next)
                  if (!xmlStrcasecmp(node->name, (const xmlChar*) "action")) {
 -                    ObActionsAct *a = actions_parse(i, doc, node);
 +                    ObActionsAct *a = actions_parse(node);
                      if (a)
                          acts = g_slist_append(acts, a);
                  }
      }
  }
  
 -static void parse_menu_separator(ObParseInst *i,
 -                                 xmlDocPtr doc, xmlNodePtr node,
 -                                 gpointer data)
 +static void parse_menu_separator(xmlNodePtr node, gpointer data)
  {
      ObMenuParseState *state = data;
  
      if (state->parent) {
          gchar *label;
  
 -        if (!parse_attr_string("label", node, &label))
 +        if (!obt_parse_attr_string(node, "label", &label))
              label = NULL;
  
          menu_add_separator(state->parent, -1, label);
      }
  }
  
 -static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                       gpointer data)
 +static void parse_menu(xmlNodePtr node, gpointer data)
  {
      ObMenuParseState *state = data;
      gchar *name = NULL, *title = NULL, *script = NULL;
      ObMenu *menu;
  
 -    if (!parse_attr_string("id", node, &name))
 +    if (!obt_parse_attr_string(node, "id", &name))
          goto parse_menu_fail;
  
      if (!g_hash_table_lookup(menu_hash, name)) {
 -        if (!parse_attr_string("label", node, &title))
 +        if (!obt_parse_attr_string(node, "label", &title))
              goto parse_menu_fail;
  
          if ((menu = menu_new(name, title, TRUE, NULL))) {
              menu->pipe_creator = state->pipe_creator;
 -            if (parse_attr_string("execute", node, &script)) {
 -                menu->execute = parse_expand_tilde(script);
 +            if (obt_parse_attr_string(node, "execute", &script)) {
 +                menu->execute = obt_paths_expand_tilde(script);
              } else {
                  ObMenu *old;
  
                  old = state->parent;
                  state->parent = menu;
 -                parse_tree(i, doc, node->children);
 +                obt_parse_tree(menu_parse_inst, node->children);
                  state->parent = old;
              }
          }
@@@ -452,10 -459,10 +455,10 @@@ void menu_show(gchar *name, gint x, gin
              menu_can_hide = TRUE;
          else {
              menu_can_hide = FALSE;
 -            ob_main_loop_timeout_add(ob_main_loop,
 -                                     config_menu_hide_delay * 1000,
 -                                     menu_hide_delay_func,
 -                                     NULL, g_direct_equal, NULL);
 +            obt_main_loop_timeout_add(ob_main_loop,
 +                                      config_menu_hide_delay * 1000,
 +                                      menu_hide_delay_func,
 +                                      NULL, g_direct_equal, NULL);
          }
      }
  }
diff --combined openbox/popup.c
index fd31846eb8c309b65f3ef2939a54472cad794761,2a0d5960d67d11b6f6dc35091ae0078946ad9bb5..bddf137db29d555c930b750062cfc255a27517bf
@@@ -25,6 -25,7 +25,6 @@@
  #include "stacking.h"
  #include "event.h"
  #include "screen.h"
 -#include "mainloop.h"
  #include "render/render.h"
  #include "render/theme.h"
  
@@@ -33,7 -34,7 +33,7 @@@ ObPopup *popup_new(void
      XSetWindowAttributes attrib;
      ObPopup *self = g_new0(ObPopup, 1);
  
 -    self->obwin.type = Window_Internal;
 +    self->obwin.type = OB_WINDOW_CLASS_INTERNAL;
      self->gravity = NorthWestGravity;
      self->x = self->y = self->textw = self->h = 0;
      self->a_bg = RrAppearanceCopy(ob_rr_theme->osd_hilite_bg);
      self->iconwm = self->iconhm = 1;
  
      attrib.override_redirect = True;
 -    self->bg = XCreateWindow(ob_display, RootWindow(ob_display, ob_screen),
 +    self->bg = XCreateWindow(obt_display, obt_root(ob_screen),
                               0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
                               InputOutput, RrVisual(ob_rr_inst),
                               CWOverrideRedirect, &attrib);
  
 -    self->text = XCreateWindow(ob_display, self->bg,
 +    self->text = XCreateWindow(obt_display, self->bg,
                                 0, 0, 1, 1, 0, RrDepth(ob_rr_inst),
                                 InputOutput, RrVisual(ob_rr_inst), 0, NULL);
  
 -    XSetWindowBorderWidth(ob_display, self->bg, ob_rr_theme->obwidth);
 -    XSetWindowBorder(ob_display, self->bg,
 +    XSetWindowBorderWidth(obt_display, self->bg, ob_rr_theme->obwidth);
 +    XSetWindowBorder(obt_display, self->bg,
                       RrColorPixel(ob_rr_theme->osd_border_color));
  
 -    XMapWindow(ob_display, self->text);
 +    XMapWindow(obt_display, self->text);
  
      stacking_add(INTERNAL_AS_WINDOW(self));
 -    g_hash_table_insert(window_map, &self->bg, self);
 +    window_add(&self->bg, INTERNAL_AS_WINDOW(self));
      return self;
  }
  
  void popup_free(ObPopup *self)
  {
      if (self) {
 -        XDestroyWindow(ob_display, self->bg);
 -        XDestroyWindow(ob_display, self->text);
 +        XDestroyWindow(obt_display, self->bg);
 +        XDestroyWindow(obt_display, self->text);
          RrAppearanceFree(self->a_bg);
          RrAppearanceFree(self->a_text);
 -        g_hash_table_remove(window_map, &self->bg);
 +        window_remove(self->bg);
          stacking_remove(self);
          g_free(self);
      }
@@@ -140,7 -141,7 +140,7 @@@ static gboolean popup_show_timeout(gpoi
  {
      ObPopup *self = data;
  
 -    XMapWindow(ob_display, self->bg);
 +    XMapWindow(obt_display, self->bg);
      stacking_raise(INTERNAL_AS_WINDOW(self));
      self->mapped = TRUE;
      self->delay_mapped = FALSE;
@@@ -272,7 -273,7 +272,7 @@@ void popup_delay_show(ObPopup *self, gu
      }
  
      /* set the windows/appearances up */
 -    XMoveResizeWindow(ob_display, self->bg, x, y, w, h);
 +    XMoveResizeWindow(obt_display, self->bg, x, y, w, h);
      /* when there is no icon and the text is not parent relative, then
         fill the whole dialog with the text appearance, don't use the bg at all
      */
          self->a_text->surface.parent = self->a_bg;
          self->a_text->surface.parentx = textx;
          self->a_text->surface.parenty = texty;
 -        XMoveResizeWindow(ob_display, self->text, textx, texty, textw, texth);
 +        XMoveResizeWindow(obt_display, self->text, textx, texty, textw, texth);
          RrPaint(self->a_text, self->text, textw, texth);
      }
  
          if (usec) {
              /* don't kill previous show timers */
              if (!self->delay_mapped) {
 -                ob_main_loop_timeout_add(ob_main_loop, usec,
 -                                         popup_show_timeout, self,
 -                                         g_direct_equal, NULL);
 +                obt_main_loop_timeout_add(ob_main_loop, usec,
 +                                          popup_show_timeout, self,
 +                                          g_direct_equal, NULL);
                  self->delay_mapped = TRUE;
              }
          } else {
@@@ -314,12 -315,12 +314,12 @@@ void popup_hide(ObPopup *self
          /* kill enter events cause by this unmapping */
          ignore_start = event_start_ignore_all_enters();
  
 -        XUnmapWindow(ob_display, self->bg);
 +        XUnmapWindow(obt_display, self->bg);
          self->mapped = FALSE;
  
          event_end_ignore_all_enters(ignore_start);
      } else if (self->delay_mapped) {
-         obt_main_loop_timeout_remove(ob_main_loop, popup_show_timeout);
 -        ob_main_loop_timeout_remove_data(ob_main_loop, popup_show_timeout, self, FALSE);
++        obt_main_loop_timeout_remove_data(ob_main_loop, popup_show_timeout, self, FALSE);
          self->delay_mapped = FALSE;
      }
  }
@@@ -331,7 -332,7 +331,7 @@@ static void icon_popup_draw_icon(gint x
      self->a_icon->surface.parent = self->popup->a_bg;
      self->a_icon->surface.parentx = x;
      self->a_icon->surface.parenty = y;
 -    XMoveResizeWindow(ob_display, self->icon, x, y, w, h);
 +    XMoveResizeWindow(obt_display, self->icon, x, y, w, h);
      RrPaint(self->a_icon, self->icon, w, h);
  }
  
@@@ -342,11 -343,11 +342,11 @@@ ObIconPopup *icon_popup_new(void
      self = g_new0(ObIconPopup, 1);
      self->popup = popup_new();
      self->a_icon = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
 -    self->icon = XCreateWindow(ob_display, self->popup->bg,
 +    self->icon = XCreateWindow(obt_display, self->popup->bg,
                                 0, 0, 1, 1, 0,
                                 RrDepth(ob_rr_inst), InputOutput,
                                 RrVisual(ob_rr_inst), 0, NULL);
 -    XMapWindow(ob_display, self->icon);
 +    XMapWindow(obt_display, self->icon);
  
      self->popup->hasicon = TRUE;
      self->popup->draw_icon = icon_popup_draw_icon;
  void icon_popup_free(ObIconPopup *self)
  {
      if (self) {
 -        XDestroyWindow(ob_display, self->icon);
 +        XDestroyWindow(obt_display, self->icon);
          RrAppearanceFree(self->a_icon);
          popup_free(self->popup);
          g_free(self);
@@@ -484,7 -485,7 +484,7 @@@ static void pager_popup_draw_icon(gint 
                  a->surface.parent = self->popup->a_bg;
                  a->surface.parentx = x + px;
                  a->surface.parenty = y + py;
 -                XMoveResizeWindow(ob_display, self->wins[n],
 +                XMoveResizeWindow(obt_display, self->wins[n],
                                    x + px, y + py, eachw, eachh);
                  RrPaint(a, self->wins[n], eachw, eachh);
              }
@@@ -519,7 -520,7 +519,7 @@@ void pager_popup_free(ObPagerPopup *sel
          guint i;
  
          for (i = 0; i < self->desks; ++i)
 -            XDestroyWindow(ob_display, self->wins[i]);
 +            XDestroyWindow(obt_display, self->wins[i]);
          g_free(self->wins);
          RrAppearanceFree(self->hilight);
          RrAppearanceFree(self->unhilight);
@@@ -535,7 -536,7 +535,7 @@@ void pager_popup_delay_show(ObPagerPopu
  
      if (screen_num_desktops < self->desks)
          for (i = screen_num_desktops; i < self->desks; ++i)
 -            XDestroyWindow(ob_display, self->wins[i]);
 +            XDestroyWindow(obt_display, self->wins[i]);
  
      if (screen_num_desktops != self->desks)
          self->wins = g_renew(Window, self->wins, screen_num_desktops);
  
              attr.border_pixel =
                  RrColorPixel(ob_rr_theme->osd_border_color);
 -            self->wins[i] = XCreateWindow(ob_display, self->popup->bg,
 +            self->wins[i] = XCreateWindow(obt_display, self->popup->bg,
                                            0, 0, 1, 1, ob_rr_theme->obwidth,
                                            RrDepth(ob_rr_inst), InputOutput,
                                            RrVisual(ob_rr_inst), CWBorderPixel,
                                            &attr);
 -            XMapWindow(ob_display, self->wins[i]);
 +            XMapWindow(obt_display, self->wins[i]);
          }
  
      self->desks = screen_num_desktops;
diff --combined openbox/screen.c
index 74d073c475ab82c8c0266db29f437e3eb5524689,1bcda980d2a87776b486238d0955d5f580febb67..09d5003c4eeaba5d52964ec6e672fa713563606a
  #include "debug.h"
  #include "openbox.h"
  #include "dock.h"
 -#include "xerror.h"
 -#include "prop.h"
  #include "grab.h"
  #include "startupnotify.h"
  #include "moveresize.h"
  #include "config.h"
 -#include "mainloop.h"
  #include "screen.h"
  #include "client.h"
  #include "session.h"
  #include "event.h"
  #include "focus.h"
  #include "popup.h"
 -#include "extensions.h"
 +#include "hooks.h"
  #include "render/render.h"
  #include "gettext.h"
 +#include "obt/display.h"
 +#include "obt/prop.h"
 +#include "obt/mainloop.h"
  
  #include <X11/Xlib.h>
  #ifdef HAVE_UNISTD_H
@@@ -77,7 -77,7 +77,7 @@@ static GSList *struts_left = NULL
  static GSList *struts_right = NULL;
  static GSList *struts_bottom = NULL;
  
- static ObPagerPopup *desktop_popup;
+ static ObPagerPopup **desktop_popup;
  
  /*! The number of microseconds that you need to be on a desktop before it will
    replace the remembered "last desktop" */
@@@ -91,10 -91,10 +91,10 @@@ static gboolean replace_wm(void
      Time timestamp;
  
      wm_sn = g_strdup_printf("WM_S%d", ob_screen);
 -    wm_sn_atom = XInternAtom(ob_display, wm_sn, FALSE);
 +    wm_sn_atom = XInternAtom(obt_display, wm_sn, FALSE);
      g_free(wm_sn);
  
 -    current_wm_sn_owner = XGetSelectionOwner(ob_display, wm_sn_atom);
 +    current_wm_sn_owner = XGetSelectionOwner(obt_display, wm_sn_atom);
      if (current_wm_sn_owner == screen_support_win)
          current_wm_sn_owner = None;
      if (current_wm_sn_owner) {
                        ob_screen);
              return FALSE;
          }
 -        xerror_set_ignore(TRUE);
 -        xerror_occured = FALSE;
 +        obt_display_ignore_errors(TRUE);
  
          /* We want to find out when the current selection owner dies */
 -        XSelectInput(ob_display, current_wm_sn_owner, StructureNotifyMask);
 -        XSync(ob_display, FALSE);
 +        XSelectInput(obt_display, current_wm_sn_owner, StructureNotifyMask);
 +        XSync(obt_display, FALSE);
  
 -        xerror_set_ignore(FALSE);
 -        if (xerror_occured)
 +        obt_display_ignore_errors(FALSE);
 +        if (obt_display_error_occured)
              current_wm_sn_owner = None;
      }
  
      timestamp = event_get_server_time();
  
 -    XSetSelectionOwner(ob_display, wm_sn_atom, screen_support_win,
 +    XSetSelectionOwner(obt_display, wm_sn_atom, screen_support_win,
                         timestamp);
  
 -    if (XGetSelectionOwner(ob_display, wm_sn_atom) != screen_support_win) {
 +    if (XGetSelectionOwner(obt_display, wm_sn_atom) != screen_support_win) {
          g_message(_("Could not acquire window manager selection on screen %d"),
                    ob_screen);
          return FALSE;
        const gulong timeout = G_USEC_PER_SEC * 15; /* wait for 15s max */
  
        while (wait < timeout) {
 -          if (XCheckWindowEvent(ob_display, current_wm_sn_owner,
 +          if (XCheckWindowEvent(obt_display, current_wm_sn_owner,
                                  StructureNotifyMask, &event) &&
                event.type == DestroyNotify)
                break;
      }
  
      /* Send client message indicating that we are now the WM */
 -    prop_message(RootWindow(ob_display, ob_screen), prop_atoms.manager,
 -                 timestamp, wm_sn_atom, screen_support_win, 0,
 -                 SubstructureNotifyMask);
 +    obt_prop_message(ob_screen, obt_root(ob_screen), OBT_PROP_ATOM(MANAGER),
 +                     timestamp, wm_sn_atom, screen_support_win, 0, 0,
 +                     SubstructureNotifyMask);
  
      return TRUE;
  }
@@@ -159,33 -160,37 +159,33 @@@ gboolean screen_annex(void
      XSetWindowAttributes attrib;
      pid_t pid;
      gint i, num_support;
 -    Atom *prop_atoms_start, *wm_supported_pos;
      gulong *supported;
  
      /* create the netwm support window */
      attrib.override_redirect = TRUE;
      attrib.event_mask = PropertyChangeMask;
 -    screen_support_win = XCreateWindow(ob_display,
 -                                       RootWindow(ob_display, ob_screen),
 +    screen_support_win = XCreateWindow(obt_display, obt_root(ob_screen),
                                         -100, -100, 1, 1, 0,
                                         CopyFromParent, InputOutput,
                                         CopyFromParent,
                                         CWEventMask | CWOverrideRedirect,
                                         &attrib);
 -    XMapWindow(ob_display, screen_support_win);
 -    XLowerWindow(ob_display, screen_support_win);
 +    XMapWindow(obt_display, screen_support_win);
 +    XLowerWindow(obt_display, screen_support_win);
  
      if (!replace_wm()) {
 -        XDestroyWindow(ob_display, screen_support_win);
 +        XDestroyWindow(obt_display, screen_support_win);
          return FALSE;
      }
  
 -    xerror_set_ignore(TRUE);
 -    xerror_occured = FALSE;
 -    XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
 -                 ROOT_EVENTMASK);
 -    xerror_set_ignore(FALSE);
 -    if (xerror_occured) {
 +    obt_display_ignore_errors(TRUE);
 +    XSelectInput(obt_display, obt_root(ob_screen), ROOT_EVENTMASK);
 +    obt_display_ignore_errors(FALSE);
 +    if (obt_display_error_occured) {
          g_message(_("A window manager is already running on screen %d"),
                    ob_screen);
  
 -        XDestroyWindow(ob_display, screen_support_win);
 +        XDestroyWindow(obt_display, screen_support_win);
          return FALSE;
      }
  
  
      /* set the OPENBOX_PID hint */
      pid = getpid();
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               openbox_pid, cardinal, pid);
 +    OBT_PROP_SET32(obt_root(ob_screen), OPENBOX_PID, CARDINAL, pid);
  
      /* set supporting window */
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_supporting_wm_check, window, screen_support_win);
 +    OBT_PROP_SET32(obt_root(ob_screen),
 +                   NET_SUPPORTING_WM_CHECK, WINDOW, screen_support_win);
  
      /* set properties on the supporting window */
 -    PROP_SETS(screen_support_win, net_wm_name, "Openbox");
 -    PROP_SET32(screen_support_win, net_supporting_wm_check,
 -               window, screen_support_win);
 +    OBT_PROP_SETS(screen_support_win, NET_WM_NAME, utf8, "Openbox");
 +    OBT_PROP_SET32(screen_support_win, NET_SUPPORTING_WM_CHECK,
 +                   WINDOW, screen_support_win);
  
      /* set the _NET_SUPPORTED_ATOMS hint */
  
 -    /* this is all the atoms after net_supported in the prop_atoms struct */
 -    prop_atoms_start = (Atom*)&prop_atoms;
 -    wm_supported_pos = (Atom*)&(prop_atoms.net_supported);
 -    num_support = sizeof(prop_atoms) / sizeof(Atom) -
 -        (wm_supported_pos - prop_atoms_start) - 1;
 +    /* this is all the atoms after NET_SUPPORTED in the ObtPropAtoms enum */
 +    num_support = OBT_PROP_NUM_ATOMS - OBT_PROP_NET_SUPPORTED - 1;
      i = 0;
      supported = g_new(gulong, num_support);
 -    supported[i++] = prop_atoms.net_supporting_wm_check;
 -    supported[i++] = prop_atoms.net_wm_full_placement;
 -    supported[i++] = prop_atoms.net_current_desktop;
 -    supported[i++] = prop_atoms.net_number_of_desktops;
 -    supported[i++] = prop_atoms.net_desktop_geometry;
 -    supported[i++] = prop_atoms.net_desktop_viewport;
 -    supported[i++] = prop_atoms.net_active_window;
 -    supported[i++] = prop_atoms.net_workarea;
 -    supported[i++] = prop_atoms.net_client_list;
 -    supported[i++] = prop_atoms.net_client_list_stacking;
 -    supported[i++] = prop_atoms.net_desktop_names;
 -    supported[i++] = prop_atoms.net_close_window;
 -    supported[i++] = prop_atoms.net_desktop_layout;
 -    supported[i++] = prop_atoms.net_showing_desktop;
 -    supported[i++] = prop_atoms.net_wm_name;
 -    supported[i++] = prop_atoms.net_wm_visible_name;
 -    supported[i++] = prop_atoms.net_wm_icon_name;
 -    supported[i++] = prop_atoms.net_wm_visible_icon_name;
 -    supported[i++] = prop_atoms.net_wm_desktop;
 -    supported[i++] = prop_atoms.net_wm_strut;
 -    supported[i++] = prop_atoms.net_wm_strut_partial;
 -    supported[i++] = prop_atoms.net_wm_icon;
 -    supported[i++] = prop_atoms.net_wm_icon_geometry;
 -    supported[i++] = prop_atoms.net_wm_window_type;
 -    supported[i++] = prop_atoms.net_wm_window_type_desktop;
 -    supported[i++] = prop_atoms.net_wm_window_type_dock;
 -    supported[i++] = prop_atoms.net_wm_window_type_toolbar;
 -    supported[i++] = prop_atoms.net_wm_window_type_menu;
 -    supported[i++] = prop_atoms.net_wm_window_type_utility;
 -    supported[i++] = prop_atoms.net_wm_window_type_splash;
 -    supported[i++] = prop_atoms.net_wm_window_type_dialog;
 -    supported[i++] = prop_atoms.net_wm_window_type_normal;
 -    supported[i++] = prop_atoms.net_wm_allowed_actions;
 -    supported[i++] = prop_atoms.net_wm_action_move;
 -    supported[i++] = prop_atoms.net_wm_action_resize;
 -    supported[i++] = prop_atoms.net_wm_action_minimize;
 -    supported[i++] = prop_atoms.net_wm_action_shade;
 -    supported[i++] = prop_atoms.net_wm_action_maximize_horz;
 -    supported[i++] = prop_atoms.net_wm_action_maximize_vert;
 -    supported[i++] = prop_atoms.net_wm_action_fullscreen;
 -    supported[i++] = prop_atoms.net_wm_action_change_desktop;
 -    supported[i++] = prop_atoms.net_wm_action_close;
 -    supported[i++] = prop_atoms.net_wm_action_above;
 -    supported[i++] = prop_atoms.net_wm_action_below;
 -    supported[i++] = prop_atoms.net_wm_state;
 -    supported[i++] = prop_atoms.net_wm_state_modal;
 -    supported[i++] = prop_atoms.net_wm_state_maximized_vert;
 -    supported[i++] = prop_atoms.net_wm_state_maximized_horz;
 -    supported[i++] = prop_atoms.net_wm_state_shaded;
 -    supported[i++] = prop_atoms.net_wm_state_skip_taskbar;
 -    supported[i++] = prop_atoms.net_wm_state_skip_pager;
 -    supported[i++] = prop_atoms.net_wm_state_hidden;
 -    supported[i++] = prop_atoms.net_wm_state_fullscreen;
 -    supported[i++] = prop_atoms.net_wm_state_above;
 -    supported[i++] = prop_atoms.net_wm_state_below;
 -    supported[i++] = prop_atoms.net_wm_state_demands_attention;
 -    supported[i++] = prop_atoms.net_moveresize_window;
 -    supported[i++] = prop_atoms.net_wm_moveresize;
 -    supported[i++] = prop_atoms.net_wm_user_time;
 +    supported[i++] = OBT_PROP_ATOM(NET_SUPPORTING_WM_CHECK);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_FULL_PLACEMENT);
 +    supported[i++] = OBT_PROP_ATOM(NET_CURRENT_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_NUMBER_OF_DESKTOPS);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_GEOMETRY);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_VIEWPORT);
 +    supported[i++] = OBT_PROP_ATOM(NET_ACTIVE_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WORKAREA);
 +    supported[i++] = OBT_PROP_ATOM(NET_CLIENT_LIST);
 +    supported[i++] = OBT_PROP_ATOM(NET_CLIENT_LIST_STACKING);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_NAMES);
 +    supported[i++] = OBT_PROP_ATOM(NET_CLOSE_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_LAYOUT);
 +    supported[i++] = OBT_PROP_ATOM(NET_SHOWING_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_VISIBLE_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ICON_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_VISIBLE_ICON_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STRUT);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STRUT_PARTIAL);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ICON);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ICON_GEOMETRY);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DOCK);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_TOOLBAR);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_MENU);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_UTILITY);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_SPLASH);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_NORMAL);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ALLOWED_ACTIONS);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MOVE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_RESIZE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MINIMIZE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_SHADE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_HORZ);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_VERT);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_FULLSCREEN);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_CHANGE_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_CLOSE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_ABOVE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_BELOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_MODAL);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_SHADED);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_HIDDEN);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_ABOVE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_BELOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
 +    supported[i++] = OBT_PROP_ATOM(NET_MOVERESIZE_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_MOVERESIZE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_USER_TIME);
  /*
 -    supported[i++] = prop_atoms.net_wm_user_time_window;
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_USER_TIME_WINDOW);
  */
 -    supported[i++] = prop_atoms.net_frame_extents;
 -    supported[i++] = prop_atoms.net_request_frame_extents;
 -    supported[i++] = prop_atoms.net_restack_window;
 -    supported[i++] = prop_atoms.net_startup_id;
 +    supported[i++] = OBT_PROP_ATOM(NET_FRAME_EXTENTS);
 +    supported[i++] = OBT_PROP_ATOM(NET_REQUEST_FRAME_EXTENTS);
 +    supported[i++] = OBT_PROP_ATOM(NET_RESTACK_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_STARTUP_ID);
  #ifdef SYNC
 -    supported[i++] = prop_atoms.net_wm_sync_request;
 -    supported[i++] = prop_atoms.net_wm_sync_request_counter;
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST_COUNTER);
  #endif
 -    supported[i++] = prop_atoms.net_wm_pid;
 -    supported[i++] = prop_atoms.net_wm_ping;
 -
 -    supported[i++] = prop_atoms.kde_wm_change_state;
 -    supported[i++] = prop_atoms.kde_net_wm_frame_strut;
 -    supported[i++] = prop_atoms.kde_net_wm_window_type_override;
 -
 -    supported[i++] = prop_atoms.ob_wm_action_undecorate;
 -    supported[i++] = prop_atoms.ob_wm_state_undecorated;
 -    supported[i++] = prop_atoms.openbox_pid;
 -    supported[i++] = prop_atoms.ob_theme;
 -    supported[i++] = prop_atoms.ob_config_file;
 -    supported[i++] = prop_atoms.ob_control;
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_PID);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_PING);
 +
 +    supported[i++] = OBT_PROP_ATOM(KDE_WM_CHANGE_STATE);
 +    supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_FRAME_STRUT);
 +    supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
 +
 +    supported[i++] = OBT_PROP_ATOM(OB_WM_ACTION_UNDECORATE);
 +    supported[i++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
 +    supported[i++] = OBT_PROP_ATOM(OPENBOX_PID);
 +    supported[i++] = OBT_PROP_ATOM(OB_THEME);
 +    supported[i++] = OBT_PROP_ATOM(OB_CONFIG_FILE);
 +    supported[i++] = OBT_PROP_ATOM(OB_CONTROL);
      g_assert(i == num_support);
  
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_supported, atom, supported, num_support);
 +    OBT_PROP_SETA32(obt_root(ob_screen),
 +                    NET_SUPPORTED, ATOM, supported, num_support);
      g_free(supported);
  
      screen_tell_ksplash();
@@@ -328,14 -337,14 +328,14 @@@ static void screen_tell_ksplash(void
         hear it anyways. perhaps it is for old ksplash. or new ksplash. or
         something. oh well. */
      e.xclient.type = ClientMessage;
 -    e.xclient.display = ob_display;
 -    e.xclient.window = RootWindow(ob_display, ob_screen);
 +    e.xclient.display = obt_display;
 +    e.xclient.window = obt_root(ob_screen);
      e.xclient.message_type =
 -        XInternAtom(ob_display, "_KDE_SPLASH_PROGRESS", False);
 +        XInternAtom(obt_display, "_KDE_SPLASH_PROGRESS", False);
      e.xclient.format = 8;
      strcpy(e.xclient.data.b, "wm started");
 -    XSendEvent(ob_display, RootWindow(ob_display, ob_screen),
 -               False, SubstructureNotifyMask, &e );
 +    XSendEvent(obt_display, obt_root(ob_screen),
 +               False, SubstructureNotifyMask, &e);
  }
  
  void screen_startup(gboolean reconfig)
      guint32 d;
      gboolean namesexist = FALSE;
  
-     desktop_popup = pager_popup_new();
-     pager_popup_height(desktop_popup, POPUP_HEIGHT);
      if (reconfig) {
-         /* update the pager popup's width */
-         pager_popup_text_width_to_strings(desktop_popup,
-                                           screen_desktop_names,
-                                           screen_num_desktops);
+         guint i;
+         desktop_popup = g_new(ObPagerPopup*, screen_num_monitors);
+         for (i = 0; i < screen_num_monitors; i++) {
+             desktop_popup[i] = pager_popup_new();
+             pager_popup_height(desktop_popup[i], POPUP_HEIGHT);
+             /* update the pager popup's width */
+             pager_popup_text_width_to_strings(desktop_popup[i],
+                                               screen_desktop_names,
+                                               screen_num_desktops);
+         }
          return;
+     } else {
+         desktop_popup = NULL;
      }
  
      /* get the initial size */
      screen_resize();
  
      /* have names already been set for the desktops? */
 -    if (PROP_GETSS(RootWindow(ob_display, ob_screen),
 -                   net_desktop_names, utf8, &names))
 -    {
 +    if (OBT_PROP_GETSS(obt_root(ob_screen), NET_DESKTOP_NAMES, utf8, &names)) {
          g_strfreev(names);
          namesexist = TRUE;
      }
              names[i] = g_strdup(it->data);
  
          /* set the root window property */
 -        PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names,names);
 +        OBT_PROP_SETSS(obt_root(ob_screen),
 +                       NET_DESKTOP_NAMES, utf8, (const gchar**)names);
  
          g_strfreev(names);
      }
         this will also set the default names from the config file up for
         desktops that don't have names yet */
      screen_num_desktops = 0;
 -    if (PROP_GET32(RootWindow(ob_display, ob_screen),
 -                   net_number_of_desktops, cardinal, &d))
 +    if (OBT_PROP_GET32(obt_root(ob_screen),
 +                       NET_NUMBER_OF_DESKTOPS, CARDINAL, &d))
      {
          if (d != config_desktops_num) {
              /* TRANSLATORS: If you need to specify a different order of the
  
      screen_desktop = screen_num_desktops;  /* something invalid */
      /* start on the current desktop when a wm was already running */
 -    if (PROP_GET32(RootWindow(ob_display, ob_screen),
 -                   net_current_desktop, cardinal, &d) &&
 +    if (OBT_PROP_GET32(obt_root(ob_screen),
 +                       NET_CURRENT_DESKTOP, CARDINAL, &d) &&
          d < screen_num_desktops)
      {
          screen_set_desktop(d, FALSE);
  
      /* don't start in showing-desktop mode */
      screen_showing_desktop = FALSE;
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_showing_desktop, cardinal, screen_showing_desktop);
 +    OBT_PROP_SET32(obt_root(ob_screen),
 +                   NET_SHOWING_DESKTOP, CARDINAL, screen_showing_desktop);
  
      if (session_desktop_layout_present &&
          screen_validate_layout(&session_desktop_layout))
  
  void screen_shutdown(gboolean reconfig)
  {
-     pager_popup_free(desktop_popup);
+     guint i;
+     for (i = 0; i < screen_num_monitors; i++) {
+         pager_popup_free(desktop_popup[i]);
+     }
+     g_free(desktop_popup);
  
      if (reconfig)
          return;
  
 -    XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
 -                 NoEventMask);
 +    XSelectInput(obt_display, obt_root(ob_screen), NoEventMask);
  
      /* we're not running here no more! */
 -    PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid);
 +    OBT_PROP_ERASE(obt_root(ob_screen), OPENBOX_PID);
      /* not without us */
 -    PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported);
 +    OBT_PROP_ERASE(obt_root(ob_screen), NET_SUPPORTED);
      /* don't keep this mode */
 -    PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop);
 +    OBT_PROP_ERASE(obt_root(ob_screen), NET_SHOWING_DESKTOP);
  
 -    XDestroyWindow(ob_display, screen_support_win);
 +    XDestroyWindow(obt_display, screen_support_win);
  
      g_strfreev(screen_desktop_names);
      screen_desktop_names = NULL;
@@@ -468,8 -491,8 +480,8 @@@ void screen_resize(void
      GList *it;
      gulong geometry[2];
  
 -    w = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen));
 -    h = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen));
 +    w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +    h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));
  
      if (w == oldw && h == oldh) return;
  
      /* Set the _NET_DESKTOP_GEOMETRY hint */
      screen_physical_size.width = geometry[0] = w;
      screen_physical_size.height = geometry[1] = h;
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_desktop_geometry, cardinal, geometry, 2);
 +    OBT_PROP_SETA32(obt_root(ob_screen),
 +                    NET_DESKTOP_GEOMETRY, CARDINAL, geometry, 2);
  
      if (ob_state() != OB_STATE_RUNNING)
          return;
@@@ -503,12 -526,13 +515,12 @@@ void screen_set_num_desktops(guint num
  
      old = screen_num_desktops;
      screen_num_desktops = num;
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_number_of_desktops, cardinal, num);
 +    OBT_PROP_SET32(obt_root(ob_screen), NET_NUMBER_OF_DESKTOPS, CARDINAL, num);
  
      /* set the viewport hint */
      viewport = g_new0(gulong, num * 2);
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_desktop_viewport, cardinal, viewport, num * 2);
 +    OBT_PROP_SETA32(obt_root(ob_screen),
 +                    NET_DESKTOP_VIEWPORT, CARDINAL, viewport, num * 2);
      g_free(viewport);
  
      /* the number of rows/columns will differ */
@@@ -604,7 -628,8 +616,7 @@@ void screen_set_desktop(guint num, gboo
  
      if (previous == num) return;
  
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_current_desktop, cardinal, num);
 +    OBT_PROP_SET32(obt_root(ob_screen), NET_CURRENT_DESKTOP, CARDINAL, num);
  
      /* This whole thing decides when/how to save the screen_last_desktop so
         that it can be restored later if you want */
          }
      }
      screen_desktop_timeout = FALSE;
 -    ob_main_loop_timeout_remove(ob_main_loop, last_desktop_func);
 -    ob_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME,
 -                             last_desktop_func, NULL, NULL, NULL);
 +    obt_main_loop_timeout_remove(ob_main_loop, last_desktop_func);
 +    obt_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME,
 +                              last_desktop_func, NULL, NULL, NULL);
  
 -    ob_debug("Moving to desktop %d\n", num+1);
 +    ob_debug("Moving to desktop %d", num+1);
  
      if (ob_state() == OB_STATE_RUNNING)
          screen_show_desktop_popup(screen_desktop);
  
      if (event_curtime != CurrentTime)
          screen_desktop_user_time = event_curtime;
 +
 +    hooks_queue(OB_HOOK_SCREEN_DESK_CHANGE, NULL);
  }
  
  void screen_add_desktop(gboolean current)
                     parent - which will have to be on the same desktop */
                  !client_direct_parent(c))
              {
 -                ob_debug("moving window %s\n", c->title);
 +                ob_debug("moving window %s", c->title);
                  client_set_desktop(c, c->desktop+1, FALSE, TRUE);
              }
          }
@@@ -774,7 -797,7 +786,7 @@@ void screen_remove_desktop(gboolean cur
                     parent - which will have to be on the same desktop */
                  !client_direct_parent(c))
              {
 -                ob_debug("moving window %s\n", c->title);
 +                ob_debug("moving window %s", c->title);
                  client_set_desktop(c, c->desktop - 1, TRUE, TRUE);
              }
              /* raise all the windows that are on the current desktop which
                  (d == DESKTOP_ALL || d == screen_desktop))
              {
                  stacking_raise(CLIENT_AS_WINDOW(c));
 -                ob_debug("raising window %s\n", c->title);
 +                ob_debug("raising window %s", c->title);
              }
          }
      }
      /* fallback focus like we're changing desktops */
      if (screen_desktop < screen_num_desktops - 1) {
          screen_fallback_focus();
 -        ob_debug("fake desktop change\n");
 +        ob_debug("fake desktop change");
      }
  
      screen_set_num_desktops(screen_num_desktops-1);
@@@ -911,39 -934,52 +923,52 @@@ static guint translate_row_col(guint r
  
  static gboolean hide_desktop_popup_func(gpointer data)
  {
-     pager_popup_hide(desktop_popup);
+     guint i;
+     for (i = 0; i < screen_num_monitors; i++) {
+         pager_popup_hide(desktop_popup[i]);
+     }
      return FALSE; /* don't repeat */
  }
  
  void screen_show_desktop_popup(guint d)
  {
      Rect *a;
+     guint i;
  
      /* 0 means don't show the popup */
      if (!config_desktop_popup_time) return;
  
-     a = screen_physical_area_active();
-     pager_popup_position(desktop_popup, CenterGravity,
-                          a->x + a->width / 2, a->y + a->height / 2);
-     pager_popup_icon_size_multiplier(desktop_popup,
-                                      (screen_desktop_layout.columns /
-                                       screen_desktop_layout.rows) / 2,
-                                      (screen_desktop_layout.rows/
-                                       screen_desktop_layout.columns) / 2);
-     pager_popup_max_width(desktop_popup,
-                           MAX(a->width/3, POPUP_WIDTH));
-     pager_popup_show(desktop_popup, screen_desktop_names[d], d);
-     obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
-     obt_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000,
-                               hide_desktop_popup_func, NULL, NULL, NULL);
-     g_free(a);
+     for (i = 0; i < screen_num_monitors; i++) {
+         a = screen_physical_area_monitor(i);
+         pager_popup_position(desktop_popup[i], CenterGravity,
+                              a->x + a->width / 2, a->y + a->height / 2);
+         pager_popup_icon_size_multiplier(desktop_popup[i],
+                                          (screen_desktop_layout.columns /
+                                           screen_desktop_layout.rows) / 2,
+                                          (screen_desktop_layout.rows/
+                                           screen_desktop_layout.columns) / 2);
+         pager_popup_max_width(desktop_popup[i],
+                               MAX(a->width/3, POPUP_WIDTH));
+         pager_popup_show(desktop_popup[i], screen_desktop_names[d], d);
 -        ob_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
 -        ob_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000,
 -                                 hide_desktop_popup_func, desktop_popup[i],
 -                                 g_direct_equal, NULL);
++        obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
++        obt_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000,
++                                  hide_desktop_popup_func, desktop_popup[i],
++                                  g_direct_equal, NULL);
+         g_free(a);
+     }
  }
  
  void screen_hide_desktop_popup(void)
  {
-     obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
-     pager_popup_hide(desktop_popup);
+     guint i;
+     for (i = 0; i < screen_num_monitors; i++) {
 -        ob_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func,
 -                                         desktop_popup[i], FALSE);
++        obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func,
++                                          desktop_popup[i], FALSE);
+         pager_popup_hide(desktop_popup[i]);
+     }
  }
  
  guint screen_find_desktop(guint from, ObDirection dir,
@@@ -1101,13 -1137,13 +1126,13 @@@ void screen_update_layout(void
      screen_desktop_layout.rows = 1;
      screen_desktop_layout.columns = screen_num_desktops;
  
 -    if (PROP_GETA32(RootWindow(ob_display, ob_screen),
 -                    net_desktop_layout, cardinal, &data, &num)) {
 +    if (OBT_PROP_GETA32(obt_root(ob_screen),
 +                        NET_DESKTOP_LAYOUT, CARDINAL, &data, &num)) {
          if (num == 3 || num == 4) {
  
 -            if (data[0] == prop_atoms.net_wm_orientation_vert)
 +            if (data[0] == OBT_PROP_ATOM(NET_WM_ORIENTATION_VERT))
                  l.orientation = OB_ORIENTATION_VERT;
 -            else if (data[0] == prop_atoms.net_wm_orientation_horz)
 +            else if (data[0] == OBT_PROP_ATOM(NET_WM_ORIENTATION_HORZ))
                  l.orientation = OB_ORIENTATION_HORZ;
              else
                  return;
              if (num < 4)
                  l.start_corner = OB_CORNER_TOPLEFT;
              else {
 -                if (data[3] == prop_atoms.net_wm_topleft)
 +                if (data[3] == OBT_PROP_ATOM(NET_WM_TOPLEFT))
                      l.start_corner = OB_CORNER_TOPLEFT;
 -                else if (data[3] == prop_atoms.net_wm_topright)
 +                else if (data[3] == OBT_PROP_ATOM(NET_WM_TOPRIGHT))
                      l.start_corner = OB_CORNER_TOPRIGHT;
 -                else if (data[3] == prop_atoms.net_wm_bottomright)
 +                else if (data[3] == OBT_PROP_ATOM(NET_WM_BOTTOMRIGHT))
                      l.start_corner = OB_CORNER_BOTTOMRIGHT;
 -                else if (data[3] == prop_atoms.net_wm_bottomleft)
 +                else if (data[3] == OBT_PROP_ATOM(NET_WM_BOTTOMLEFT))
                      l.start_corner = OB_CORNER_BOTTOMLEFT;
                  else
                      return;
@@@ -1146,8 -1182,8 +1171,8 @@@ void screen_update_desktop_names(void
      g_strfreev(screen_desktop_names);
      screen_desktop_names = NULL;
  
 -    if (PROP_GETSS(RootWindow(ob_display, ob_screen),
 -                   net_desktop_names, utf8, &screen_desktop_names))
 +    if (OBT_PROP_GETSS(obt_root(ob_screen),
 +                       NET_DESKTOP_NAMES, utf8, &screen_desktop_names))
          for (i = 0; screen_desktop_names[i] && i < screen_num_desktops; ++i);
      else
          i = 0;
  
          /* if we changed any names, then set the root property so we can
             all agree on the names */
 -        PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names,
 -                   screen_desktop_names);
 +        OBT_PROP_SETSS(obt_root(ob_screen), NET_DESKTOP_NAMES,
 +                       utf8, (const gchar**)screen_desktop_names);
      }
  
      /* resize the pager for these names */
-     pager_popup_text_width_to_strings(desktop_popup,
-                                       screen_desktop_names,
-                                       screen_num_desktops);
+     for (i = 0; i < screen_num_monitors; i++) {
+         pager_popup_text_width_to_strings(desktop_popup[i],
+                                           screen_desktop_names,
+                                           screen_num_desktops);
+     }
  }
  
  void screen_show_desktop(gboolean show, ObClient *show_only)
      }
  
      show = !!show; /* make it boolean */
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_showing_desktop, cardinal, show);
 +    OBT_PROP_SET32(obt_root(ob_screen), NET_SHOWING_DESKTOP, CARDINAL, show);
  }
  
  void screen_install_colormap(ObClient *client, gboolean install)
  {
      if (client == NULL || client->colormap == None) {
          if (install)
 -            XInstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst));
 +            XInstallColormap(obt_display, RrColormap(ob_rr_inst));
          else
 -            XUninstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst));
 +            XUninstallColormap(obt_display, RrColormap(ob_rr_inst));
      } else {
 -        xerror_set_ignore(TRUE);
 +        obt_display_ignore_errors(TRUE);
          if (install)
 -            XInstallColormap(RrDisplay(ob_rr_inst), client->colormap);
 +            XInstallColormap(obt_display, client->colormap);
          else
 -            XUninstallColormap(RrDisplay(ob_rr_inst), client->colormap);
 -        xerror_set_ignore(FALSE);
 +            XUninstallColormap(obt_display, client->colormap);
 +        obt_display_ignore_errors(FALSE);
      }
  }
  
@@@ -1299,54 -1338,6 +1326,55 @@@ typedef struct 
      } \
  }
  
-     gint l, r, t, b;
 +static void get_xinerama_screens(Rect **xin_areas, guint *nxin)
 +{
 +    guint i;
-     else if (obt_display_extension_xinerama) {
-         guint i;
-         gint n;
-         XineramaScreenInfo *info = XineramaQueryScreens(obt_display, &n);
++    gint n, l, r, t, b;
++#ifdef XINERAMA
++    XineramaScreenInfo *info;
++#endif
 +
 +    if (ob_debug_xinerama) {
 +        gint w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +        gint h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +        *nxin = 2;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        RECT_SET((*xin_areas)[0], 0, 0, w/2, h);
 +        RECT_SET((*xin_areas)[1], w/2, 0, w-(w/2), h);
 +    }
 +#ifdef XINERAMA
++    else if (obt_display_extension_xinerama &&
++             (info = XineramaQueryScreens(obt_display, &n))) {
 +        *nxin = n;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        for (i = 0; i < *nxin; ++i)
 +            RECT_SET((*xin_areas)[i], info[i].x_org, info[i].y_org,
 +                     info[i].width, info[i].height);
 +        XFree(info);
 +    }
 +#endif
 +    else {
 +        *nxin = 1;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        RECT_SET((*xin_areas)[0], 0, 0,
 +                 WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)),
 +                 HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)));
 +    }
 +
 +    /* returns one extra with the total area in it */
 +    l = (*xin_areas)[0].x;
 +    t = (*xin_areas)[0].y;
 +    r = (*xin_areas)[0].x + (*xin_areas)[0].width - 1;
 +    b = (*xin_areas)[0].y + (*xin_areas)[0].height - 1;
 +    for (i = 1; i < *nxin; ++i) {
 +        l = MIN(l, (*xin_areas)[i].x);
 +        t = MIN(l, (*xin_areas)[i].y);
 +        r = MAX(r, (*xin_areas)[i].x + (*xin_areas)[i].width - 1);
 +        b = MAX(b, (*xin_areas)[i].y + (*xin_areas)[i].height - 1);
 +    }
 +    RECT_SET((*xin_areas)[*nxin], l, t, r - l + 1, b - t + 1);
 +}
 +
  void screen_update_areas(void)
  {
      guint i, j;
      GSList *sit;
  
      g_free(monitor_area);
 -    extensions_xinerama_screens(&monitor_area, &screen_num_monitors);
 +    get_xinerama_screens(&monitor_area, &screen_num_monitors);
  
+     if (!desktop_popup) {
+         desktop_popup = g_new(ObPagerPopup*, screen_num_monitors);
+         for (i = 0; i < screen_num_monitors; i++) {
+             desktop_popup[i] = pager_popup_new();
+             pager_popup_height(desktop_popup[i], POPUP_HEIGHT);
+             if (screen_desktop_names)
+                 /* update the pager popup's width */
+                 pager_popup_text_width_to_strings(desktop_popup[i],
+                                                   screen_desktop_names,
+                                                   screen_num_desktops);
+         }
+     }
      /* set up the user-specified margins */
      config_margins.top_start = RECT_LEFT(monitor_area[screen_num_monitors]);
      config_margins.top_end = RECT_RIGHT(monitor_area[screen_num_monitors]);
                      b = MAX(b, s->strut->bottom);
              }
  
+             if (l) l += RECT_LEFT  (monitor_area[screen_num_monitors])
+                         - RECT_LEFT  (monitor_area[i]);
+             if (t) t += RECT_TOP   (monitor_area[screen_num_monitors])
+                         - RECT_TOP   (monitor_area[i]);
+             if (r) r -= RECT_RIGHT (monitor_area[screen_num_monitors])
+                         - RECT_RIGHT (monitor_area[i]);
+             if (b) b -= RECT_BOTTOM(monitor_area[screen_num_monitors])
+                         - RECT_BOTTOM(monitor_area[i]);
              /* based on these margins, set the work area for the
                 monitor/desktop */
              dims[(i * screen_num_desktops + j) * 4 + 0] += l;
  
      /* all the work areas are not used here, only the ones for the first
         monitor are */
 -    PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal,
 -                dims, 4 * screen_num_desktops);
 +    OBT_PROP_SETA32(obt_root(ob_screen), NET_WORKAREA, CARDINAL,
 +                    dims, 4 * screen_num_desktops);
  
      /* the area has changed, adjust all the windows if they need it */
      for (it = client_list; it; it = g_list_next(it))
@@@ -1594,28 -1608,32 +1645,32 @@@ Rect* screen_area(guint desktop, guint 
                  if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
                      STRUT_LEFT_IN_SEARCH(s->strut, search) &&
                      !STRUT_LEFT_IGNORE(s->strut, us, search))
-                     l = MAX(l, al + s->strut->left);
+                     l = MAX(l, RECT_LEFT(monitor_area[screen_num_monitors])
+                                + s->strut->left);
              }
              for (it = struts_top; it; it = g_slist_next(it)) {
                  ObScreenStrut *s = it->data;
                  if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
                      STRUT_TOP_IN_SEARCH(s->strut, search) &&
                      !STRUT_TOP_IGNORE(s->strut, us, search))
-                     t = MAX(t, at + s->strut->top);
+                     t = MAX(t, RECT_TOP(monitor_area[screen_num_monitors])
+                                + s->strut->top);
              }
              for (it = struts_right; it; it = g_slist_next(it)) {
                  ObScreenStrut *s = it->data;
                  if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
                      STRUT_RIGHT_IN_SEARCH(s->strut, search) &&
                      !STRUT_RIGHT_IGNORE(s->strut, us, search))
-                     r = MIN(r, ar - s->strut->right);
+                     r = MIN(r, RECT_RIGHT(monitor_area[screen_num_monitors])
+                                - s->strut->right);
              }
              for (it = struts_bottom; it; it = g_slist_next(it)) {
                  ObScreenStrut *s = it->data;
                  if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
                      STRUT_BOTTOM_IN_SEARCH(s->strut, search) &&
                      !STRUT_BOTTOM_IGNORE(s->strut, us, search))
-                     b = MIN(b, ab - s->strut->bottom);
+                     b = MIN(b, RECT_BOTTOM(monitor_area[screen_num_monitors])
+                                - s->strut->bottom);
              }
  
              /* limit to this monitor */
@@@ -1706,10 -1724,10 +1761,10 @@@ Rect* screen_physical_area_active(void
  void screen_set_root_cursor(void)
  {
      if (sn_app_starting())
 -        XDefineCursor(ob_display, RootWindow(ob_display, ob_screen),
 +        XDefineCursor(obt_display, obt_root(ob_screen),
                        ob_cursor(OB_CURSOR_BUSYPOINTER));
      else
 -        XDefineCursor(ob_display, RootWindow(ob_display, ob_screen),
 +        XDefineCursor(obt_display, obt_root(ob_screen),
                        ob_cursor(OB_CURSOR_POINTER));
  }
  
@@@ -1720,12 -1738,12 +1775,12 @@@ gboolean screen_pointer_pos(gint *x, gi
      guint u;
      gboolean ret;
  
 -    ret = !!XQueryPointer(ob_display, RootWindow(ob_display, ob_screen),
 +    ret = !!XQueryPointer(obt_display, obt_root(ob_screen),
                            &w, &w, x, y, &i, &i, &u);
      if (!ret) {
 -        for (i = 0; i < ScreenCount(ob_display); ++i)
 +        for (i = 0; i < ScreenCount(obt_display); ++i)
              if (i != ob_screen)
 -                if (XQueryPointer(ob_display, RootWindow(ob_display, i),
 +                if (XQueryPointer(obt_display, obt_root(i),
                                    &w, &w, x, y, &i, &i, &u))
                      break;
      }
diff --combined openbox/startupnotify.c
index 3e8799f8dd9ea7f4a9bc4b0e5d6fda66cdca2e3e,47c95da12b5afd66b02172a567a5cade2dc57d1d..aa6db7e6ce29f01c11a60a131f27f29814956863
@@@ -43,6 -43,7 +43,6 @@@ void sn_spawn_cancel() {
  #else
  
  #include "openbox.h"
 -#include "mainloop.h"
  #include "screen.h"
  
  #define SN_API_NOT_YET_FROZEN
@@@ -62,12 -63,12 +62,12 @@@ void sn_startup(gboolean reconfig
  {
      if (reconfig) return;
  
 -    sn_display = sn_display_new(ob_display, NULL, NULL);
 +    sn_display = sn_display_new(obt_display, NULL, NULL);
      sn_context = sn_monitor_context_new(sn_display, ob_screen,
                                          sn_event_func, NULL, NULL);
      sn_launcher = sn_launcher_context_new(sn_display, ob_screen);
  
 -    ob_main_loop_x_add(ob_main_loop, sn_handler, NULL, NULL);
 +    obt_main_loop_x_add(ob_main_loop, sn_handler, NULL, NULL);
  }
  
  void sn_shutdown(gboolean reconfig)
@@@ -76,7 -77,7 +76,7 @@@
  
      if (reconfig) return;
  
 -    ob_main_loop_x_remove(ob_main_loop, sn_handler);
 +    obt_main_loop_x_remove(ob_main_loop, sn_handler);
  
      for (it = sn_waits; it; it = g_slist_next(it))
          sn_startup_sequence_unref((SnStartupSequence*)it->data);
@@@ -139,10 -140,10 +139,10 @@@ static void sn_event_func(SnMonitorEven
          sn_waits = g_slist_prepend(sn_waits, seq);
          /* 20 second timeout for apps to start if the launcher doesn't
             have a timeout */
 -        ob_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
 -                                 sn_wait_timeout, seq,
 -                                 g_direct_equal,
 -                                 (GDestroyNotify)sn_startup_sequence_unref);
 +        obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
 +                                  sn_wait_timeout, seq,
 +                                  g_direct_equal,
 +                                  (GDestroyNotify)sn_startup_sequence_unref);
          change = TRUE;
          break;
      case SN_MONITOR_EVENT_CHANGED:
      case SN_MONITOR_EVENT_CANCELED:
          if ((seq = sequence_find(sn_startup_sequence_get_id(seq)))) {
              sn_waits = g_slist_remove(sn_waits, seq);
 -            ob_main_loop_timeout_remove_data(ob_main_loop, sn_wait_timeout,
 -                                             seq, FALSE);
 +            obt_main_loop_timeout_remove_data(ob_main_loop, sn_wait_timeout,
 +                                              seq, FALSE);
              change = TRUE;
          }
          break;
@@@ -239,7 -240,7 +239,7 @@@ void sn_setup_spawn_environment(const g
      gchar *desc;
      const char *id;
  
-     desc = g_strdup_printf(_("Running %s\n"), program);
+     desc = g_strdup_printf(_("Running %s"), program);
  
      if (sn_launcher_context_get_initiated(sn_launcher)) {
          sn_launcher_context_unref(sn_launcher);
  
      /* 20 second timeout for apps to start */
      sn_launcher_context_ref(sn_launcher);
 -    ob_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
 -                             sn_launch_wait_timeout, sn_launcher,
 -                             g_direct_equal,
 -                             (GDestroyNotify)sn_launcher_context_unref);
 +    obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
 +                              sn_launch_wait_timeout, sn_launcher,
 +                              g_direct_equal,
 +                              (GDestroyNotify)sn_launcher_context_unref);
  
      setenv("DESKTOP_STARTUP_ID", id, TRUE);
  
diff --combined render/theme.c
index 47c8a9c9cbfb77b4add7862268b868d96e199bc3,0882637a70df257f26b44ea99f4d5bec72bee456..8ead9673929921e45c0981cf9bf79d4c761f1c9f
@@@ -23,7 -23,7 +23,7 @@@
  #include "mask.h"
  #include "theme.h"
  #include "icon.h"
 -#include "parser/parse.h"
 +#include "obt/paths.h"
  
  #include <X11/Xlib.h>
  #include <X11/Xresource.h>
@@@ -46,6 -46,22 +46,22 @@@ static int parse_inline_number(const ch
  static RrPixel32* read_c_image(gint width, gint height, const guint8 *data);
  static void set_default_appearance(RrAppearance *a);
  
+ static RrFont *get_font(RrFont *target, RrFont **default_font, const RrInstance *inst)
+ {
+     if (target) {
+         RrFontRef(target);
+         return target;
+     } else {
+         /* Only load the default font once */
+         if (*default_font) {
+             RrFontRef(*default_font);
+         } else {
+             *default_font = RrFontOpenDefault(inst);
+         }
+         return *default_font;
+     }
+ }
  RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name,
                      gboolean allow_fallback,
                      RrFont *active_window_font, RrFont *inactive_window_font,
@@@ -56,6 -72,7 +72,7 @@@
      RrJustify winjust, mtitlejust;
      gchar *str;
      RrTheme *theme;
+     RrFont *default_font = NULL;
      gchar *path;
      gboolean userdef;
  
      theme->osd_unhilite_fg = RrAppearanceNew(inst, 0);
  
      /* load the font stuff */
-     if (active_window_font) {
-         theme->win_font_focused = active_window_font;
-         RrFontRef(active_window_font);
-     } else
-         theme->win_font_focused = RrFontOpenDefault(inst);
-     if (inactive_window_font) {
-         theme->win_font_unfocused = inactive_window_font;
-         RrFontRef(inactive_window_font);
-     } else
-         theme->win_font_unfocused = RrFontOpenDefault(inst);
+     theme->win_font_focused = get_font(active_window_font, &default_font, inst);
+     theme->win_font_unfocused = get_font(inactive_window_font, &default_font, inst);
  
      winjust = RR_JUSTIFY_LEFT;
      if (read_string(db, "window.label.text.justify", &str)) {
              winjust = RR_JUSTIFY_CENTER;
      }
  
-     if (menu_title_font) {
-         theme->menu_title_font = menu_title_font;
-         RrFontRef(menu_title_font);
-     } else
-         theme->menu_title_font = RrFontOpenDefault(inst);
+     theme->menu_title_font = get_font(menu_title_font, &default_font, inst);
  
      mtitlejust = RR_JUSTIFY_LEFT;
      if (read_string(db, "menu.title.text.justify", &str)) {
              mtitlejust = RR_JUSTIFY_CENTER;
      }
  
-     if (menu_item_font) {
-         theme->menu_font = menu_item_font;
-         RrFontRef(menu_item_font);
-     } else
-         theme->menu_font = RrFontOpenDefault(inst);
-     if (osd_font) {
-         theme->osd_font = osd_font;
-         RrFontRef(osd_font);
-     } else
-         theme->osd_font = RrFontOpenDefault(inst);
+     theme->menu_font = get_font(menu_item_font, &default_font, inst);
+     theme->osd_font = get_font(osd_font, &default_font, inst);
  
      /* load direct dimensions */
      if ((!read_int(db, "menu.overlap.x", &theme->menu_overlap_x) &&
          theme->menu_bullet_mask = RrPixmapMaskNew(inst, 4, 7, (gchar*)data);
      }
  
 +    /* up and down arrows */
 +    {
 +        guchar data[] = { 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, 0x10, 0x00 };
 +        theme->down_arrow_mask = RrPixmapMaskNew(inst, 9, 4, (gchar*)data);
 +    }
 +    {
 +        guchar data[] = { 0x10, 0x00, 0x38, 0x00, 0x7c, 0x00, 0xfe, 0x00 };
 +        theme->up_arrow_mask = RrPixmapMaskNew(inst, 9, 4, (gchar*)data);
 +    }
 +
      /* setup the default window icon */
      theme->def_win_icon = read_c_image(OB_DEFAULT_ICON_WIDTH,
                                         OB_DEFAULT_ICON_HEIGHT,
@@@ -1481,8 -1467,6 +1477,8 @@@ void RrThemeFree(RrTheme *theme
          RrPixmapMaskFree(theme->close_hover_mask);
          RrPixmapMaskFree(theme->close_pressed_mask);
          RrPixmapMaskFree(theme->menu_bullet_mask);
 +        RrPixmapMaskFree(theme->down_arrow_mask);
 +        RrPixmapMaskFree(theme->up_arrow_mask);
  
          RrFontClose(theme->win_font_focused);
          RrFontClose(theme->win_font_unfocused);
@@@ -1593,10 -1577,6 +1589,10 @@@ static XrmDatabase loaddb(const gchar *
              *path = g_path_get_dirname(s);
          g_free(s);
      } else {
 +        ObtPaths *p;
 +
 +        p = obt_paths_new();
 +
          /* XXX backwards compatibility, remove me sometime later */
          s = g_build_filename(g_get_home_dir(), ".themes", name,
                               "openbox-3", "themerc", NULL);
              *path = g_path_get_dirname(s);
          g_free(s);
  
 -        for (it = parse_xdg_data_dir_paths(); !db && it;
 -             it = g_slist_next(it))
 +        for (it = obt_paths_data_dirs(p); !db && it; it = g_slist_next(it))
          {
              s = g_build_filename(it->data, "themes", name,
                                   "openbox-3", "themerc", NULL);
                  *path = g_path_get_dirname(s);
              g_free(s);
          }
 +
 +        obt_paths_unref(p);
      }
  
      if (db == NULL) {
This page took 0.268765 seconds and 4 git commands to generate.