Merge branch 'backport' into work
authorDana Jansens <danakj@orodu.net>
Tue, 8 Dec 2009 19:19:04 +0000 (14:19 -0500)
committerDana Jansens <danakj@orodu.net>
Tue, 8 Dec 2009 19:19:04 +0000 (14:19 -0500)
Conflicts:

openbox/actions/all.h
openbox/actions/session.c
openbox/client.c
openbox/event.c
openbox/grab.c

1  2 
Makefile.am
openbox/actions/all.c
openbox/actions/all.h
openbox/actions/exit.c
openbox/client.c
openbox/client.h
openbox/event.c
openbox/focus.c
openbox/session.c

diff --combined Makefile.am
@@@ -8,8 -8,7 +8,8 @@@ rcdir           = $(configdir)/openbo
  xsessionsdir    = $(datadir)/xsessions
  gnomewmfilesdir = $(datadir)/gnome/wm-properties
  pkgconfigdir    = $(libdir)/pkgconfig
 -pubincludedir   = $(includedir)/openbox/@OB_VERSION@/openbox
 +obtpubincludedir= $(includedir)/openbox/@OBT_VERSION@/obt
 +rrpubincludedir = $(includedir)/openbox/@RR_VERSION@/render
  pixmapdir       = $(datadir)/pixmaps
  xsddir          = $(datadir)/openbox
  secretbindir    = $(libdir)/openbox
@@@ -26,7 -25,7 +26,7 @@@ check_PROGRAMS = 
        render/rendertest
  
  lib_LTLIBRARIES = \
 -      parser/libobparser.la \
 +      obt/libobt.la \
        render/libobrender.la
  
  bin_PROGRAMS = \
@@@ -46,13 -45,15 +46,13 @@@ nodist_bin_SCRIPTS = 
  
  render_rendertest_CPPFLAGS = \
        $(PANGO_CFLAGS) \
 -      $(XFT_CFLAGS) \
        $(GLIB_CFLAGS) \
        -DG_LOG_DOMAIN=\"RenderTest\"
  render_rendertest_LDADD = \
 -      parser/libobparser.la \
 +      obt/libobt.la \
        render/libobrender.la \
        $(GLIB_LIBS) \
        $(PANGO_LIBS) \
 -      $(XFT_LIBS) \
        $(XML_LIBS) \
        $(X_LIBS)
  render_rendertest_SOURCES = render/test.c
@@@ -62,14 -63,16 +62,14 @@@ render_libobrender_la_CPPFLAGS = 
        $(GLIB_CFLAGS) \
        $(XML_CFLAGS) \
        $(PANGO_CFLAGS) \
 -      $(XFT_CFLAGS) \
        -DG_LOG_DOMAIN=\"ObRender\" \
        -DDEFAULT_THEME=\"$(theme)\"
  render_libobrender_la_LDFLAGS = \
 -      -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
 +      -version-info $(RR_CURRENT):$(RR_REVISION):$(RR_AGE)
  render_libobrender_la_LIBADD = \
 -      parser/libobparser.la \
 +      obt/libobt.la \
        $(X_LIBS) \
        $(PANGO_LIBS) \
 -      $(XFT_LIBS) \
        $(GLIB_LIBS) \
        $(XML_LIBS)
  render_libobrender_la_SOURCES = \
        render/theme.h \
        render/theme.c
  
 -## parser ##
 +## obt ##
  
 -parser_libobparser_la_CPPFLAGS = \
 +obt_libobt_la_CPPFLAGS = \
 +      $(XINERAMA_CFLAGS) \
 +      $(XKB_CFLAGS) \
 +      $(XRANDR_CFLAGS) \
 +      $(XSHAPE_CFLAGS) \
 +      $(XSYNC_CFLAGS) \
        $(GLIB_CFLAGS) \
        $(XML_CFLAGS) \
 -      -DG_LOG_DOMAIN=\"ObParser\" \
 +      -DG_LOG_DOMAIN=\"Obt\" \
        -DLOCALEDIR=\"$(localedir)\" \
        -DDATADIR=\"$(datadir)\" \
        -DCONFIGDIR=\"$(configdir)\"
 -parser_libobparser_la_LDFLAGS = \
 -      -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
 -parser_libobparser_la_LIBADD = \
 +obt_libobt_la_LDFLAGS = \
 +      -version-info $(OBT_CURRENT):$(OBT_REVISION):$(OBT_AGE)
 +obt_libobt_la_LIBADD = \
 +      $(XINERAMA_LIBS) \
 +      $(XKB_LIBS) \
 +      $(XRANDR_LIBS) \
 +      $(XSHAPE_LIBS) \
 +      $(XSYNC_LIBS) \
        $(GLIB_LIBS) \
 -      $(XML_LIBS) 
 -parser_libobparser_la_SOURCES = \
 -      parser/parse.h \
 -      parser/parse.c
 +      $(XML_LIBS)
 +obt_libobt_la_SOURCES = \
 +      obt/display.h \
 +      obt/display.c \
 +      obt/internal.h \
 +      obt/keyboard.h \
 +      obt/keyboard.c \
 +      obt/mainloop.h \
 +      obt/mainloop.c \
 +      obt/parse.h \
 +      obt/parse.c \
 +      obt/paths.h \
 +      obt/paths.c \
 +      obt/prop.h \
 +      obt/prop.c \
 +      obt/util.h \
 +      obt/xevent.h \
 +      obt/xevent.c
  
  ## openbox ##
  
  openbox_openbox_CPPFLAGS = \
        $(SM_CFLAGS) \
 -      $(XINERAMA_CFLAGS) \
 -      $(XKB_CFLAGS) \
 -      $(XRANDR_CFLAGS) \
 -      $(XSHAPE_CFLAGS) \
 -      $(XSYNC_CFLAGS) \
        $(X_CFLAGS) \
        $(XCURSOR_CFLAGS) \
        $(SM_CFLAGS) \
        -DG_LOG_DOMAIN=\"Openbox\"
  openbox_openbox_LDADD = \
        $(SM_LIBS) \
 -      $(XINERAMA_LIBS) \
 -      $(XKB_LIBS) \
 -      $(XRANDR_LIBS) \
 -      $(XSHAPE_LIBS) \
 -      $(XSYNC_LIBS) \
        $(GLIB_LIBS) \
        $(X_LIBS) \
        $(XCURSOR_LIBS) \
        $(EFENCE_LIBS) \
        $(LIBINTL) \
        render/libobrender.la \
 -      parser/libobparser.la
 +      obt/libobt.la
  openbox_openbox_LDFLAGS = -export-dynamic
  openbox_openbox_SOURCES = \
        gettext.h \
        openbox/actions/if.c \
        openbox/actions/kill.c \
        openbox/actions/layer.c \
-       openbox/actions/session.c \
        openbox/actions/lower.c \
        openbox/actions/maximize.c \
        openbox/actions/move.c \
        openbox/actions/resizerelative.c \
        openbox/actions/restart.c \
        openbox/actions/shade.c \
 +      openbox/actions/shadelowerraise.c \
        openbox/actions/showdesktop.c \
        openbox/actions/showmenu.c \
        openbox/actions/unfocus.c \
        openbox/dock.h \
        openbox/event.c \
        openbox/event.h \
 -      openbox/extensions.c \
 -      openbox/extensions.h \
        openbox/focus.c \
        openbox/focus.h \
        openbox/focus_cycle.c \
        openbox/keyboard.h \
        openbox/keytree.c \
        openbox/keytree.h \
 -      openbox/mainloop.c \
 -      openbox/mainloop.h \
        openbox/menuframe.c \
        openbox/menuframe.h \
        openbox/menu.c \
        openbox/menu.h \
        openbox/misc.h \
 -      openbox/modkeys.c \
 -      openbox/modkeys.h \
        openbox/mouse.c \
        openbox/mouse.h \
        openbox/moveresize.c \
        openbox/prompt.h \
        openbox/popup.c \
        openbox/popup.h \
 -      openbox/prop.c \
 -      openbox/prop.h \
        openbox/resist.c \
        openbox/resist.h \
        openbox/screen.c \
        openbox/translate.c \
        openbox/translate.h \
        openbox/window.c \
 -      openbox/window.h \
 -      openbox/xerror.c \
 -      openbox/xerror.h
 -
 +      openbox/window.h
  
  ## gnome-panel-control ##
  
@@@ -395,7 -393,7 +394,7 @@@ dist_syscrash_theme_DATA= 
  
  ## public headers ##
  
 -pubinclude_HEADERS = \
 +rrpubinclude_HEADERS = \
        render/color.h \
        render/font.h \
        render/geom.h \
        render/mask.h \
        render/render.h \
        render/theme.h \
 -      parser/parse.h
 -
 -nodist_pubinclude_HEADERS = \
 -      version.h
 +      render/version.h
 +
 +obtpubinclude_HEADERS = \
 +      obt/display.h \
 +      obt/keyboard.h \
 +      obt/mainloop.h \
 +      obt/parse.h \
 +      obt/paths.h \
 +      obt/prop.h \
 +      obt/util.h \
 +      obt/version.h \
 +      obt/xevent.h
  
  nodist_pkgconfig_DATA = \
 -      render/obrender-3.0.pc \
 -      parser/obparser-3.0.pc
 +      render/obrender-4.0.pc \
 +      obt/obt-4.0.pc
  
  ## data ##
  
@@@ -469,6 -459,7 +468,6 @@@ nodist_xsessions_DATA = 
        data/xsession/openbox-kde.desktop
  
  dist_noinst_DATA = \
 -      version.h.in \
        data/autostart.sh.in \
        data/rc.xsd \
        data/menu.xsd \
        doc/openbox-gnome-session.1.in \
        doc/openbox-kde-session.1.sgml \
        doc/openbox-kde-session.1.in \
 -      render/obrender-3.0.pc.in \
 -      parser/obparser-3.0.pc.in \
 +      render/version.h.in \
 +      render/obrender-4.0.pc.in \
 +      obt/obt-4.0.pc.in \
 +      obt/version.h.in \
        tools/themeupdate/themeupdate.py \
        tests/hideshow.py \
        tests/Makefile \
@@@ -545,7 -534,7 +544,7 @@@ CLEANFILES = 
  #       $(MAKE) -$(MAKEFLAGS) -C doc/doxygen doc
  
  distclean-local:
 -      for d in . m4 po render; do \
 +      for d in . m4 po render parser obt openbox; do \
                for p in core core.* gmon.out *\~ *.orig *.rej .\#*; do \
                        rm -f "$$d/$$p"; \
                done \
diff --combined openbox/actions/all.c
@@@ -9,7 -9,6 +9,6 @@@ void action_all_startup(void
      action_reconfigure_startup();
      action_exit_startup();
      action_restart_startup();
-     action_session_startup();
      action_cyclewindows_startup();
      action_breakchroot_startup();
      action_close_startup();
@@@ -39,6 -38,4 +38,6 @@@
      action_growtoedge_startup();
      action_if_startup();
      action_focustobottom_startup();
 +    /* 3.4-compatibility */
 +    action_shadelowerraise_startup();
  }
diff --combined openbox/actions/all.h
@@@ -1,46 -1,43 +1,45 @@@
  #ifndef __actions_all_h
  #define __actions_all_h
  
 -void action_all_startup();
 +void action_all_startup(void);
  
 -void action_execute_startup();
 -void action_debug_startup();
 -void action_showmenu_startup();
 -void action_showdesktop_startup();
 -void action_reconfigure_startup();
 -void action_exit_startup();
 -void action_restart_startup();
 -void action_cyclewindows_startup();
 -void action_breakchroot_startup();
 -void action_close_startup();
 -void action_move_startup();
 -void action_focus_startup();
 -void action_raise_startup();
 -void action_lower_startup();
 -void action_raiselower_startup();
 -void action_unfocus_startup();
 -void action_iconify_startup();
 -void action_fullscreen_startup();
 -void action_maximize_startup();
 -void action_moveresizeto_startup();
 -void action_moverelative_startup();
 -void action_shade_startup();
 -void action_kill_startup();
 -void action_omnipresent_startup();
 -void action_directionalwindows_startup();
 -void action_resize_startup();
 -void action_decorations_startup();
 -void action_desktop_startup();
 -void action_resizerelative_startup();
 -void action_addremovedesktop_startup();
 -void action_dockautohide_startup();
 -void action_layer_startup();
 -void action_movetoedge_startup();
 -void action_growtoedge_startup();
 -void action_if_startup();
 -void action_focustobottom_startup();
 +void action_execute_startup(void);
 +void action_debug_startup(void);
 +void action_showmenu_startup(void);
 +void action_showdesktop_startup(void);
 +void action_reconfigure_startup(void);
 +void action_exit_startup(void);
 +void action_restart_startup(void);
- void action_session_startup(void);
 +void action_cyclewindows_startup(void);
 +void action_breakchroot_startup(void);
 +void action_close_startup(void);
 +void action_move_startup(void);
 +void action_focus_startup(void);
 +void action_raise_startup(void);
 +void action_lower_startup(void);
 +void action_raiselower_startup(void);
 +void action_unfocus_startup(void);
 +void action_iconify_startup(void);
 +void action_fullscreen_startup(void);
 +void action_maximize_startup(void);
 +void action_moveresizeto_startup(void);
 +void action_moverelative_startup(void);
 +void action_shade_startup(void);
 +void action_kill_startup(void);
 +void action_omnipresent_startup(void);
 +void action_directionalwindows_startup(void);
 +void action_resize_startup(void);
 +void action_decorations_startup(void);
 +void action_desktop_startup(void);
 +void action_resizerelative_startup(void);
 +void action_addremovedesktop_startup(void);
 +void action_dockautohide_startup(void);
 +void action_layer_startup(void);
 +void action_movetoedge_startup(void);
 +void action_growtoedge_startup(void);
 +void action_if_startup(void);
 +void action_focustobottom_startup(void);
 +/* 3.4-compatibility */
 +void action_shadelowerraise_startup(void);
  
  #endif
diff --combined openbox/actions/exit.c
@@@ -1,21 -1,23 +1,23 @@@
  #include "openbox/actions.h"
  #include "openbox/openbox.h"
  #include "openbox/prompt.h"
+ #include "openbox/session.h"
  #include "gettext.h"
  
  typedef struct {
      gboolean prompt;
  } Options;
  
 -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 +static gpointer setup_func(xmlNodePtr node);
  static gboolean run_func(ObActionsData *data, gpointer options);
  
  void action_exit_startup(void)
  {
      actions_register("Exit", setup_func, NULL, run_func, NULL, NULL);
+     actions_register("SessionLogout", setup_func, NULL, run_func, NULL, NULL);
  }
  
 -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node)
 +static gpointer setup_func(xmlNodePtr node)
  {
      xmlNodePtr n;
      Options *o;
      o = g_new0(Options, 1);
      o->prompt = TRUE;
  
 -    if ((n = parse_find_node("prompt", node)))
 -        o->prompt = parse_bool(doc, n);
 +    if ((n = obt_parse_find_node(node, "prompt")))
 +        o->prompt = obt_parse_node_bool(n);
  
      return o;
  }
  
+ static void do_exit(void)
+ {
+     if (session_connected())
+         session_request_logout(FALSE);
+     else
+         ob_exit(0);
+ }
  static gboolean prompt_cb(ObPrompt *p, gint result, gpointer data)
  {
      if (result)
-         ob_exit(0);
+         do_exit();
      return TRUE; /* call the cleanup func */
  }
  
@@@ -53,13 -63,19 +63,19 @@@ static gboolean run_func(ObActionsData 
              { _("Exit"), 1 }
          };
  
-         p = prompt_new(_("Are you sure you want to exit Openbox?"),
-                        _("Exit Openbox"),
-                        answers, 2, 0, 0, prompt_cb, prompt_cleanup, NULL);
+         if (session_connected())
+             p = prompt_new(_("Are you sure you want to log out?"),
+                            _("Log Out"),
+                            answers, 2, 0, 0, prompt_cb, prompt_cleanup, NULL);
+         else
+             p = prompt_new(_("Are you sure you want to exit Openbox?"),
+                            _("Exit Openbox"),
+                            answers, 2, 0, 0, prompt_cb, prompt_cleanup, NULL);
          prompt_show(p, NULL, FALSE);
      }
      else
-         ob_exit(0);
+         do_exit();
  
      return FALSE;
  }
diff --combined openbox/client.c
  #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"
@@@ -40,8 -43,6 +40,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>
@@@ -105,6 -106,8 +105,8 @@@ static GSList *client_search_all_top_pa
  static void client_call_notifies(ObClient *self, GSList *list);
  static void client_ping_event(ObClient *self, gboolean dead);
  static void client_prompt_kill(ObClient *self);
+ static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
+                                        Time launch_time);
  
  void client_startup(gboolean reconfig)
  {
@@@ -182,8 -185,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 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,
         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);
      /* 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;
-         gboolean relative_focused;
-         gboolean parent_focused;
-         parent_focused = (focus_client != NULL &&
-                           client_search_focus_parent(self));
-         relative_focused = (focus_client != NULL &&
-                             (client_search_focus_tree_full(self) != NULL ||
-                              client_search_focus_group_full(self) != NULL));
-         /* 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)",
-                       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;
-             raise = TRUE;
-             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");
-         }
-         /* if it's on another desktop */
-         else if (!(self->desktop == screen_desktop ||
-                    self->desktop == DESKTOP_ALL) &&
-                  /* the timestamp is from before you changed desktops */
-                  launch_time && screen_desktop_user_time &&
-                  !event_time_after(launch_time, screen_desktop_user_time))
-         {
-             activate = FALSE;
-             raise = TRUE;
-             ob_debug_type(OB_DEBUG_FOCUS,
-                           "Not focusing the window because its on another "
-                           "desktop");
-         }
-         /* If something is focused... */
-         else if (focus_client) {
-             /* If the user is working in another window right now, then don't
-                steal focus */
-             if (!parent_focused &&
-                 event_last_user_time && launch_time &&
-                 event_time_after(event_last_user_time, launch_time) &&
-                 event_last_user_time != launch_time &&
-                 event_time_after(event_last_user_time,
-                                  map_time - OB_EVENT_USER_TIME_DELAY))
-             {
-                 activate = FALSE;
-                 ob_debug_type(OB_DEBUG_FOCUS,
-                               "Not focusing the window because the user is "
-                               "working in another window that is not "
-                               "its parent");
-             }
-             /* If the new window is a transient (and its relatives aren't
-                focused) */
-             else if (client_has_parent(self) && !relative_focused) {
-                 activate = FALSE;
-                 ob_debug_type(OB_DEBUG_FOCUS,
-                               "Not focusing the window because it is a "
-                               "transient, and its relatives aren't focused");
-             }
-             /* Don't steal focus from globally active clients.
-                I stole this idea from KWin. It seems nice.
-              */
-             else if (!(focus_client->can_focus ||
-                        focus_client->focus_notify))
-             {
-                 activate = FALSE;
-                 ob_debug_type(OB_DEBUG_FOCUS,
-                               "Not focusing the window because a globally "
-                               "active client has focus");
-             }
-             /* Don't move focus if it's not going to go to this window
-                anyway */
-             else if (client_focus_target(self) != self) {
-                 activate = FALSE;
-                 raise = TRUE;
-                 ob_debug_type(OB_DEBUG_FOCUS,
-                               "Not focusing the window because another window "
-                               "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 */
-             else if (!(self->desktop == screen_desktop ||
-                        self->desktop == DESKTOP_ALL) &&
-                      !relative_focused)
-             {
-                 activate = FALSE;
-                 raise = TRUE;
-                 ob_debug_type(OB_DEBUG_FOCUS,
-                               "Not focusing the window because it is on "
-                               "another desktop and no relatives are focused ");
-             }
-         }
+         activate = client_can_steal_focus(self, map_time, launch_time);
  
          if (!activate) {
-             ob_debug_type(OB_DEBUG_FOCUS,
-                           "Focus stealing prevention activated for %s at "
-                           "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 */
-             client_hilite(self, TRUE);
-             /* we may want to raise it even tho we're not activating it */
-             if (raise && !client_restore_session_stacking(self))
-                 stacking_raise(CLIENT_AS_WINDOW(self));
+             /* if the client isn't stealing focus, then hilite it so the user
+                knows it is there, but don't do this if we're restoring from a
+                session */
+             if (!client_restore_session_stacking(self))
+                 client_hilite(self, TRUE);
          }
      }
      else {
  
      /* 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;
  }
  
  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);
  
@@@ -630,7 -608,7 +525,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);
  
      /* 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);
@@@ -781,6 -759,105 +676,105 @@@ void client_fake_unmanage(ObClient *sel
      g_free(self);
  }
  
 -                  "launched at %u (last user interaction time %u)\n",
+ static gboolean client_can_steal_focus(ObClient *self, Time steal_time,
+                                        Time launch_time)
+ {
+     gboolean steal;
+     gboolean relative_focused;
+     gboolean parent_focused;
+     steal = TRUE;
+     parent_focused = (focus_client != NULL &&
+                       client_search_focus_parent(self));
+     relative_focused = (focus_client != NULL &&
+                         (client_search_focus_tree_full(self) != NULL ||
+                          client_search_focus_group_full(self) != NULL));
+     /* This is focus stealing prevention */
+     ob_debug_type(OB_DEBUG_FOCUS,
+                   "Want to focus new window 0x%x at time %u "
 -                          "its parent\n");
++                  "launched at %u (last user interaction time %u)",
+                   self->window, steal_time, launch_time,
+                   event_last_user_time);
+     /* if it's on another desktop */
+     if (!(self->desktop == screen_desktop ||
+           self->desktop == DESKTOP_ALL) &&
+         /* the timestamp is from before you changed desktops */
+         launch_time && screen_desktop_user_time &&
+         !event_time_after(launch_time, screen_desktop_user_time))
+     {
+         steal = FALSE;
+         ob_debug_type(OB_DEBUG_FOCUS,
+                       "Not focusing the window because its on another "
+                       "desktop\n");
+     }
+     /* If something is focused... */
+     else if (focus_client) {
+         /* If the user is working in another window right now, then don't
+            steal focus */
+         if (!parent_focused &&
+             event_last_user_time && launch_time &&
+             event_time_after(event_last_user_time, launch_time) &&
+             event_last_user_time != launch_time &&
+             event_time_after(event_last_user_time,
+                              steal_time - OB_EVENT_USER_TIME_DELAY))
+         {
+             steal = FALSE;
+             ob_debug_type(OB_DEBUG_FOCUS,
+                           "Not focusing the window because the user is "
+                           "working in another window that is not "
 -                          "transient, and its relatives aren't focused\n");
++                          "its parent");
+         }
+         /* If the new window is a transient (and its relatives aren't
+            focused) */
+         else if (client_has_parent(self) && !relative_focused) {
+             steal = FALSE;
+             ob_debug_type(OB_DEBUG_FOCUS,
+                           "Not focusing the window because it is a "
 -                          "active client has focus\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.
+         */
+         else if (!(focus_client->can_focus ||
+                    focus_client->focus_notify))
+         {
+             steal = FALSE;
+             ob_debug_type(OB_DEBUG_FOCUS,
+                           "Not focusing the window because a globally "
 -                          "would get the focus anyway\n");
++                          "active client has focus");
+         }
+         /* Don't move focus if it's not going to go to this window
+            anyway */
+         else if (client_focus_target(self) != self) {
+             steal = FALSE;
+             ob_debug_type(OB_DEBUG_FOCUS,
+                           "Not focusing the window because another window "
 -                      "time %u (last user interaction time %u)\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 */
+         else if (!(self->desktop == screen_desktop ||
+                    self->desktop == DESKTOP_ALL) &&
+                  !relative_focused)
+         {
+             steal = FALSE;
+             ob_debug_type(OB_DEBUG_FOCUS,
+                           "Not focusing the window because it is on "
+                           "another desktop and no relatives are focused ");
+         }
+     }
+     if (!steal)
+         ob_debug_type(OB_DEBUG_FOCUS,
+                       "Focus stealing prevention activated for %s at "
++                      "time %u (last user interaction time %u)",
+                       self->title, steal_time, event_last_user_time);
+     return steal;
+ }
  /*! Returns a new structure containing the per-app settings for this client.
    The returned structure needs to be freed with g_free. */
  static ObAppSettings *client_get_settings_state(ObClient *self)
              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 */
@@@ -868,17 -945,17 +862,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;
@@@ -1121,11 -1198,10 +1115,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);
  }
  
@@@ -1148,12 -1224,12 +1142,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);
          }
      }
@@@ -1201,32 -1277,32 +1195,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;
          }
  
@@@ -1238,14 -1314,14 +1232,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;
@@@ -1259,22 -1335,22 +1253,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;
@@@ -1409,8 -1485,8 +1403,8 @@@ void client_get_mwm_hints(ObClient *sel
  
      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];
@@@ -1429,27 -1505,26 +1423,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 */
@@@ -1524,8 -1599,7 +1518,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;
@@@ -1536,7 -1610,7 +1530,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);
  }
  
@@@ -1544,7 -1618,7 +1538,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 */
@@@ -1568,7 -1642,7 +1562,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)
@@@ -1781,38 -1855,38 +1775,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);
@@@ -1836,7 -1910,7 +1830,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)
@@@ -1925,10 -1999,10 +1919,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;
  }
  
@@@ -1999,9 -2073,8 +1993,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;
  
@@@ -2062,7 -2135,7 +2056,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,
@@@ -2183,8 -2256,7 +2177,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 */
@@@ -2201,23 -2273,23 +2195,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;
      }
  }
@@@ -2309,12 -2381,12 +2303,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);
      }
  }
  
@@@ -2325,30 -2397,30 +2319,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);
@@@ -2373,7 -2445,7 +2367,7 @@@ ObClient *client_search_focus_tree_full
  
          for (it = self->parents; it; it = g_slist_next(it)) {
              ObClient *c = it->data;
 -            if ((c = client_search_focus_tree_full(it->data))) return c;
 +            if ((c = client_search_focus_tree_full(c))) return c;
          }
  
          return NULL;
@@@ -2550,10 -2622,6 +2544,6 @@@ gboolean client_hide(ObClient *self
      gboolean hide = FALSE;
  
      if (!client_should_show(self)) {
-         if (self == focus_client) {
-             event_cancel_all_key_grabs();
-         }
          /* We don't need to ignore enter events here.
             The window can hide/iconify in 3 different ways:
             1 - through an x message. in this case we ignore all enter events
@@@ -2646,7 -2714,7 +2636,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
@@@ -2964,7 -3032,7 +2954,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 */
@@@ -3111,7 -3179,7 +3101,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);
@@@ -3136,7 -3204,7 +3126,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) {
@@@ -3311,12 -3379,12 +3301,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 */
@@@ -3424,14 -3492,14 +3414,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);
      }
  }
  
@@@ -3443,8 -3511,18 +3433,18 @@@ void client_hilite(ObClient *self, gboo
      /* don't allow focused windows to hilite */
      self->demands_attention = hilite && !client_focused(self);
      if (self->frame != NULL) { /* if we're mapping, just set the state */
-         if (self->demands_attention)
+         if (self->demands_attention) {
              frame_flash_start(self->frame);
+             /* if the window is on another desktop then raise it and make it
+                the most recently used window */
+             if (self->desktop != screen_desktop &&
+                 self->desktop != DESKTOP_ALL)
+             {
+                 stacking_raise(CLIENT_AS_WINDOW(self));
+                 focus_order_to_top(self);
+             }
+         }
          else
              frame_flash_stop(self->frame);
          client_change_state(self);
@@@ -3461,13 -3539,13 +3461,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 */
@@@ -3524,14 -3602,14 +3524,14 @@@ static gboolean client_validate_unmap(O
      XEvent e;
      gboolean ret = TRUE;
  
 -    if (XCheckTypedWindowEvent(ob_display, self->window, UnmapNotify, &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(ob_display, &e);
 +        XPutBackEvent(obt_display, &e);
      }
  
      return ret;
@@@ -3541,10 -3619,10 +3541,10 @@@ 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(ob_display, self->window, DestroyNotify, &e)) {
 -        XPutBackEvent(ob_display, &e);
 +    if (XCheckTypedWindowEvent(obt_display, self->window, DestroyNotify, &e)) {
 +        XPutBackEvent(obt_display, &e);
          return FALSE;
      }
  
@@@ -3581,11 -3659,10 +3581,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;
 +            else
 +                g_assert_not_reached();
 +            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;
          }
      }
  
@@@ -3747,49 -3860,47 +3747,47 @@@ 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
         go moving on us */
      event_halt_focus_delay();
  
-     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,
  }
  
  /* this function exists to map to the net_active_window message in the ewmh */
- void client_activate(ObClient *self, gboolean here, gboolean raise,
+ void client_activate(ObClient *self, gboolean desktop, gboolean raise,
                       gboolean unshade, gboolean user)
  {
-     if (user || (self->desktop == DESKTOP_ALL ||
-                  self->desktop == screen_desktop))
-         client_present(self, here, raise, unshade);
+     if ((user && (desktop ||
+                   self->desktop == DESKTOP_ALL ||
+                   self->desktop == screen_desktop)) ||
+         client_can_steal_focus(self, event_curtime, CurrentTime))
+     {
+         client_present(self, FALSE, raise, unshade);
+     }
      else
          client_hilite(self, TRUE);
  }
@@@ -4100,15 -4215,15 +4102,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;
      }
@@@ -4173,7 -4288,7 +4175,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);
@@@ -4294,10 -4409,10 +4296,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/client.h
@@@ -323,13 -323,15 +323,13 @@@ typedef void (*ObClientCallback)(ObClie
  void client_add_destroy_notify(ObClientCallback func, gpointer data);
  void client_remove_destroy_notify(ObClientCallback func);
  
 -/*! Manages all existing windows */
 -void client_manage_all();
  /*! Manages a given window
    @param prompt This specifies an ObPrompt which is being managed.  It is
                  possible to manage Openbox-owned windows through this.
  */
  void client_manage(Window win, struct _ObPrompt *prompt);
  /*! Unmanages all managed windows */
 -void client_unmanage_all();
 +void client_unmanage_all(void);
  /*! Unmanages a given client */
  void client_unmanage(ObClient *client);
  
@@@ -342,7 -344,7 +342,7 @@@ ObClient *client_fake_manage(Window win
  void client_fake_unmanage(ObClient *self);
  
  /*! Sets the client list on the root window from the client_list */
 -void client_set_list();
 +void client_set_list(void);
  
  /*! Determines if the client should be shown or hidden currently.
    @return TRUE if it should be visible; otherwise, FALSE.
@@@ -573,14 -575,14 +573,14 @@@ gboolean client_focus(ObClient *self)
  
  /*! Activates the client for use, focusing, uniconifying it, etc. To be used
    when the user deliberately selects a window for use.
-   @param here If true, then the client is brought to the current desktop;
-               otherwise, the desktop is changed to where the client lives.
+   @param desktop If true, and the window is on another desktop, it will still
+                  be activated.
    @param raise If true, the client is brought to the front.
    @param unshade If true, the client is unshaded (if it is shaded)
    @param user If true, then a user action is what requested the activation;
                otherwise, it means an application requested it on its own
  */
- void client_activate(ObClient *self, gboolean here, gboolean raise,
+ void client_activate(ObClient *self, gboolean desktop, gboolean raise,
                       gboolean unshade, gboolean user);
  
  /*! Bring all of its helper windows to its desktop. These are the utility and
@@@ -725,7 -727,7 +725,7 @@@ void client_set_layer(ObClient *self, g
  
  guint client_monitor(ObClient *self);
  
 -ObClient* client_under_pointer();
 +ObClient* client_under_pointer(void);
  
  gboolean client_has_group_siblings(ObClient *self);
  
diff --combined openbox/event.c
@@@ -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 "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>
@@@ -84,8 -87,8 +84,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);
@@@ -122,9 -125,9 +122,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;
      }
  }
@@@ -134,7 -137,7 +134,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);
@@@ -161,15 -164,9 +161,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
@@@ -237,8 -232,8 +237,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;
          }
@@@ -266,34 -261,34 +266,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;
@@@ -323,7 -318,7 +323,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.. */
@@@ -416,7 -411,6 +416,7 @@@ static void print_focusevent(XEvent *e
      case NotifyGrab:         modestr="NotifyGrab";         break;
      case NotifyUngrab:       modestr="NotifyUngrab";       break;
      case NotifyWhileGrabbed: modestr="NotifyWhileGrabbed"; break;
 +    default:                 g_assert_not_reached();
      }
      switch (detail) {
      case NotifyAncestor:    detailstr="NotifyAncestor";    break;
      case NotifyPointer:     detailstr="NotifyPointer";     break;
      case NotifyPointerRoot: detailstr="NotifyPointerRoot"; break;
      case NotifyDetailNone:  detailstr="NotifyDetailNone";  break;
 +    default:                g_assert_not_reached();
      }
  
      if (mode == NotifyGrab || mode == NotifyUngrab)
  
      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);
@@@ -461,15 -454,13 +461,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("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);
@@@ -754,7 -747,7 +754,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:
@@@ -824,17 -817,17 +824,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;
@@@ -884,12 -877,12 +884,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;
@@@ -1008,7 -1001,7 +1008,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" :
                         (e->xclient.data.l[0] == 2 ? "user" : "INVALID"))));
              /* XXX make use of data.l[2] !? */
              if (e->xclient.data.l[0] == 1 || e->xclient.data.l[0] == 2) {
-                 /* don't use the user's timestamp for client_focus, cuz if it's
-                    an old broken timestamp (happens all the time) then focus
-                    won't move even though we're trying to move it
-                   event_curtime = e->xclient.data.l[1];*/
+                 event_curtime = e->xclient.data.l[1];
                  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,
+             client_activate(client, FALSE, 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");
 +            int x, y, w, h, lw, lh;
 +
 +            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);
  
 -            /* make sure the client's sizes are within its bounds, but only
 -               reconfigure the window if it needs to. emacs will update its
 -               normal hints every time it receives a conigurenotify */
 -            client_reconfigure(client, FALSE);
 -        } else if (msgtype == prop_atoms.motif_wm_hints) {
 +            x = client->area.x;
 +            y = client->area.y;
 +            w = client->area.width;
 +            h = client->area.height;
 +
 +            /* apply the new normal hints */
 +            client_try_configure(client, &x, &y, &w, &h, &lw, &lh, FALSE);
 +            /* make sure the window is visible, and if the window is resized
 +               off-screen due to the normal hints changing then this will push
 +               it back onto the screen. */
 +            client_find_onscreen(client, &x, &y, w, h, FALSE);
 +
 +            /* make sure the client's sizes are within its bounds, but don't
 +               make it reply with a configurenotify unless something changed.
 +               emacs will update its normal hints every time it receives a
 +               configurenotify */
 +            client_configure(client, x, y, w, h, FALSE, TRUE, FALSE);
 +        } else if (msgtype == OBT_PROP_ATOM(MOTIF_WM_HINTS)) {
              client_get_mwm_hints(client);
              /* This can override some mwm hints */
              client_get_type_and_transientness(client);
              /* 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:
                          client->shaped_input = ((XShapeEvent*)e)->shaped;
                          kind = ShapeInput;
                          break;
 +                    default:
 +                        g_assert_not_reached();
                  }
                  frame_adjust_shape_kind(client->frame, kind);
              }
@@@ -1650,11 -1623,11 +1647,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);
@@@ -1701,160 -1674,125 +1698,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;
              }
 +        }
  
 -            it = start;
 -            do {
 -                ObMenuEntryFrame *e = it->data;
 -                gunichar entrykey = 0;
 +        /* Use KeyRelease events for running things so that the key release
 +           doesn't get sent to the focused application.
  
 -                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;
 +           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;
 +            }
  
 -                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 */
@@@ -1959,20 -1926,20 +1956,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)
@@@ -2029,24 -1996,24 +2026,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)
@@@ -2081,9 -2048,9 +2078,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/focus.c
  #include "group.h"
  #include "focus_cycle.h"
  #include "screen.h"
 -#include "prop.h"
  #include "keyboard.h"
  #include "focus.h"
  #include "stacking.h"
 +#include "obt/prop.h"
  
  #include <X11/Xlib.h>
  #include <glib.h>
@@@ -52,7 -52,7 +52,7 @@@ void focus_shutdown(gboolean reconfig
      if (reconfig) return;
  
      /* reset focus to root */
 -    XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime);
 +    XSetInputFocus(obt_display, PointerRoot, RevertToNone, CurrentTime);
  }
  
  static void push_to_top(ObClient *client)
@@@ -74,7 -74,7 +74,7 @@@ void focus_set_client(ObClient *client
      Window active;
  
      ob_debug_type(OB_DEBUG_FOCUS,
 -                  "focus_set_client 0x%lx\n", client ? client->window : 0);
 +                  "focus_set_client 0x%lx", client ? client->window : 0);
  
      if (focus_client == client)
          return;
      screen_install_colormap(focus_client, FALSE);
      screen_install_colormap(client, TRUE);
  
-     /* in the middle of cycling..? kill it. */
-     focus_cycle_stop(focus_client);
-     focus_cycle_stop(client);
      focus_client = client;
  
      if (client != NULL) {
@@@ -99,7 -95,8 +95,7 @@@
      /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */
      if (ob_state() != OB_STATE_EXITING) {
          active = client ? client->window : None;
 -        PROP_SET32(RootWindow(ob_display, ob_screen),
 -                   net_active_window, window, active);
 +        OBT_PROP_SET32(obt_root(ob_screen), NET_ACTIVE_WINDOW, WINDOW, active);
      }
  }
  
@@@ -111,18 -108,18 +107,18 @@@ static ObClient* focus_fallback_target(
      GList *it;
      ObClient *c;
  
 -    ob_debug_type(OB_DEBUG_FOCUS, "trying pointer stuff\n");
 +    ob_debug_type(OB_DEBUG_FOCUS, "trying pointer stuff");
      if (allow_pointer && config_focus_follow)
          if ((c = client_under_pointer()) &&
              (allow_refocus || client_focus_target(c) != old) &&
              (client_normal(c) &&
               client_focus(c)))
          {
 -            ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
 +            ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff");
              return c;
          }
  
 -    ob_debug_type(OB_DEBUG_FOCUS, "trying the focus order\n");
 +    ob_debug_type(OB_DEBUG_FOCUS, "trying the focus order");
      for (it = focus_order; it; it = g_list_next(it)) {
          c = it->data;
          /* fallback focus to a window if:
              (allow_refocus || client_focus_target(c) != old) &&
              client_focus(c))
          {
 -            ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
 +            ob_debug_type(OB_DEBUG_FOCUS, "found in focus order");
              return c;
          }
      }
  
 -    ob_debug_type(OB_DEBUG_FOCUS, "trying a desktop window\n");
 +    ob_debug_type(OB_DEBUG_FOCUS, "trying a desktop window");
      for (it = focus_order; it; it = g_list_next(it)) {
          c = it->data;
          /* fallback focus to a window if:
              (allow_refocus || client_focus_target(c) != old) &&
              client_focus(c))
          {
 -            ob_debug_type(OB_DEBUG_FOCUS, "found a desktop window\n");
 +            ob_debug_type(OB_DEBUG_FOCUS, "found a desktop window");
              return c;
          }
      }
@@@ -196,10 -193,8 +192,8 @@@ void focus_nothing(void
      /* nothing is focused, update the colormap and _the root property_ */
      focus_set_client(NULL);
  
-     event_cancel_all_key_grabs();
      /* when nothing will be focused, send focus to the backup target */
 -    XSetInputFocus(ob_display, screen_support_win, RevertToPointerRoot,
 +    XSetInputFocus(obt_display, screen_support_win, RevertToPointerRoot,
                     event_curtime);
  }
  
diff --combined openbox/session.c
@@@ -34,15 -34,16 +34,16 @@@ void session_startup(gint argc, gchar *
  void session_shutdown(gboolean permanent) {}
  GList* session_state_find(struct _ObClient *c) { return NULL; }
  void session_request_logout(gboolean silent) {}
+ gboolean session_connected(void) { return FALSE; }
  #else
  
  #include "debug.h"
  #include "openbox.h"
  #include "client.h"
 -#include "prop.h"
  #include "focus.h"
  #include "gettext.h"
 -#include "parser/parse.h"
 +#include "obt/parse.h"
 +#include "obt/paths.h"
  
  #include <time.h>
  #include <errno.h>
@@@ -92,26 -93,22 +93,26 @@@ static void session_state_free(ObSessio
  void session_startup(gint argc, gchar **argv)
  {
      gchar *dir;
 +    ObtPaths *p;
  
      if (!ob_sm_use) return;
  
      sm_argc = argc;
      sm_argv = argv;
  
 -    dir = g_build_filename(parse_xdg_data_home_path(),
 +    p = obt_paths_new();
 +    dir = g_build_filename(obt_paths_cache_home(p),
                             "openbox", "sessions", NULL);
 -    if (!parse_mkdir_path(dir, 0700)) {
 +    obt_paths_unref(p), p = NULL;
 +
 +    if (!obt_paths_mkdir_path(dir, 0700)) {
          g_message(_("Unable to make directory \"%s\": %s"),
                    dir, g_strerror(errno));
      }
  
      if (ob_sm_save_file != NULL) {
          if (ob_sm_restore) {
 -            ob_debug_type(OB_DEBUG_SM, "Loading from session file %s\n",
 +            ob_debug_type(OB_DEBUG_SM, "Loading from session file %s",
                            ob_sm_save_file);
              session_load_file(ob_sm_save_file);
          }
@@@ -159,8 -156,13 +160,13 @@@ void session_shutdown(gboolean permanen
      }
  }
  
+ gboolean session_connected(void)
+ {
+     return !!sm_conn;
+ }
  /*! Connect to the session manager and set up our callback functions */
 -static gboolean session_connect()
 +static gboolean session_connect(void)
  {
      SmcCallbacks cb;
      gchar *oldid;
  
      /* connect to the server */
      oldid = ob_sm_id;
 -    ob_debug_type(OB_DEBUG_SM, "Connecting to SM with id: %s\n",
 +    ob_debug_type(OB_DEBUG_SM, "Connecting to SM with id: %s",
                    oldid ? oldid : "(null)");
      sm_conn = SmcOpenConnection(NULL, NULL, 1, 0,
                                  SmcSaveYourselfProcMask |
                                  &cb, oldid, &ob_sm_id,
                                  SM_ERR_LEN-1, sm_err);
      g_free(oldid);
 -    ob_debug_type(OB_DEBUG_SM, "Connected to SM with id: %s\n", ob_sm_id);
 +    ob_debug_type(OB_DEBUG_SM, "Connected to SM with id: %s", ob_sm_id);
      if (sm_conn == NULL)
 -        ob_debug("Failed to connect to session manager: %s\n", sm_err);
 +        ob_debug("Failed to connect to session manager: %s", sm_err);
      return sm_conn != NULL;
  }
  
 -static void session_setup_program()
 +static void session_setup_program(void)
  {
      SmPropValue vals = {
          .value = sm_argv[0],
          .vals = &vals
      };
      SmProp *list = &prop;
 -    ob_debug_type(OB_DEBUG_SM, "Setting program: %s\n", sm_argv[0]);
 +    ob_debug_type(OB_DEBUG_SM, "Setting program: %s", sm_argv[0]);
      SmcSetProperties(sm_conn, 1, &list);
      g_free(prop.name);
      g_free(prop.type);
  }
  
 -static void session_setup_user()
 +static void session_setup_user(void)
  {
      char *user = g_strdup(g_get_user_name());
  
          .vals = &vals
      };
      SmProp *list = &prop;
 -    ob_debug_type(OB_DEBUG_SM, "Setting user: %s\n", user);
 +    ob_debug_type(OB_DEBUG_SM, "Setting user: %s", user);
      SmcSetProperties(sm_conn, 1, &list);
      g_free(prop.name);
      g_free(prop.type);
@@@ -250,13 -252,13 +256,13 @@@ static void session_setup_restart_style
          .vals = &vals
      };
      SmProp *list = &prop;
 -    ob_debug_type(OB_DEBUG_SM, "Setting restart: %d\n", restart);
 +    ob_debug_type(OB_DEBUG_SM, "Setting restart: %d", restart);
      SmcSetProperties(sm_conn, 1, &list);
      g_free(prop.name);
      g_free(prop.type);
  }
  
 -static void session_setup_pid()
 +static void session_setup_pid(void)
  {
      gchar *pid = g_strdup_printf("%ld", (glong) getpid());
  
          .vals = &vals
      };
      SmProp *list = &prop;
 -    ob_debug_type(OB_DEBUG_SM, "Setting pid: %s\n", pid);
 +    ob_debug_type(OB_DEBUG_SM, "Setting pid: %s", pid);
      SmcSetProperties(sm_conn, 1, &list);
      g_free(prop.name);
      g_free(prop.type);
  }
  
  /*! This is a gnome-session-manager extension */
 -static void session_setup_priority()
 +static void session_setup_priority(void)
  {
      gchar priority = 20; /* 20 is a lower prioity to run before other apps */
  
          .vals = &vals
      };
      SmProp *list = &prop;
 -    ob_debug_type(OB_DEBUG_SM, "Setting priority: %d\n", priority);
 +    ob_debug_type(OB_DEBUG_SM, "Setting priority: %d", priority);
      SmcSetProperties(sm_conn, 1, &list);
      g_free(prop.name);
      g_free(prop.type);
  }
  
 -static void session_setup_clone_command()
 +static void session_setup_clone_command(void)
  {
      gint i;
  
      };
      SmProp *list = &prop;
  
 -    ob_debug_type(OB_DEBUG_SM, "Setting clone command: (%d)\n", sm_argc);
 +    ob_debug_type(OB_DEBUG_SM, "Setting clone command: (%d)", sm_argc);
      for (i = 0; i < sm_argc; ++i) {
          vals[i].value = sm_argv[i];
          vals[i].length = strlen(sm_argv[i]) + 1;
 -        ob_debug_type(OB_DEBUG_SM, "    %s\n", vals[i].value);
 +        ob_debug_type(OB_DEBUG_SM, "    %s", vals[i].value);
      }
  
      SmcSetProperties(sm_conn, 1, &list);
      g_free(vals);
  }
  
 -static void session_setup_restart_command()
 +static void session_setup_restart_command(void)
  {
      gint i;
  
      };
      SmProp *list = &prop;
  
 -    ob_debug_type(OB_DEBUG_SM, "Setting restart command: (%d)\n", sm_argc+4);
 +    ob_debug_type(OB_DEBUG_SM, "Setting restart command: (%d)", sm_argc+4);
      for (i = 0; i < sm_argc; ++i) {
          vals[i].value = sm_argv[i];
          vals[i].length = strlen(sm_argv[i]) + 1;
 -        ob_debug_type(OB_DEBUG_SM, "    %s\n", vals[i].value);
 +        ob_debug_type(OB_DEBUG_SM, "    %s", vals[i].value);
      }
  
      vals[i].value = g_strdup("--sm-client-id");
      vals[i].length = strlen("--sm-client-id") + 1;
      vals[i+1].value = ob_sm_id;
      vals[i+1].length = strlen(ob_sm_id) + 1;
 -    ob_debug_type(OB_DEBUG_SM, "    %s\n", vals[i].value);
 -    ob_debug_type(OB_DEBUG_SM, "    %s\n", vals[i+1].value);
 +    ob_debug_type(OB_DEBUG_SM, "    %s", vals[i].value);
 +    ob_debug_type(OB_DEBUG_SM, "    %s", vals[i+1].value);
  
      vals[i+2].value = g_strdup("--sm-save-file");
      vals[i+2].length = strlen("--sm-save-file") + 1;
      vals[i+3].value = ob_sm_save_file;
      vals[i+3].length = strlen(ob_sm_save_file) + 1;
 -    ob_debug_type(OB_DEBUG_SM, "    %s\n", vals[i+2].value);
 -    ob_debug_type(OB_DEBUG_SM, "    %s\n", vals[i+3].value);
 +    ob_debug_type(OB_DEBUG_SM, "    %s", vals[i+2].value);
 +    ob_debug_type(OB_DEBUG_SM, "    %s", vals[i+3].value);
  
      SmcSetProperties(sm_conn, 1, &list);
      g_free(prop.name);
      g_free(vals);
  }
  
 -static ObSMSaveData *sm_save_get_data()
 +static ObSMSaveData *sm_save_get_data(void)
  {
      ObSMSaveData *savedata = g_new0(ObSMSaveData, 1);
      /* save the active desktop and client.
@@@ -386,9 -388,9 +392,9 @@@ static void sm_save_yourself_2(SmcConn 
      ObSMSaveData *savedata = data;
  
      /* save the current state */
 -    ob_debug_type(OB_DEBUG_SM, "Session save phase 2 requested\n");
 +    ob_debug_type(OB_DEBUG_SM, "Session save phase 2 requested");
      ob_debug_type(OB_DEBUG_SM,
 -                  "  Saving session to file '%s'\n", ob_sm_save_file);
 +                  "  Saving session to file '%s'", ob_sm_save_file);
      if (savedata == NULL)
          savedata = sm_save_get_data();
      success = session_save_to_file(savedata);
      /* tell the session manager how to restore this state */
      if (success) session_setup_restart_command();
  
 -    ob_debug_type(OB_DEBUG_SM, "Saving is done (success = %d)\n", success);
 +    ob_debug_type(OB_DEBUG_SM, "Saving is done (success = %d)", success);
      SmcSaveYourselfDone(conn, success);
  }
  
@@@ -413,7 -415,7 +419,7 @@@ static void sm_save_yourself(SmcConn co
              (save_type == SmSaveLocal ? "SmSaveLocal" :
               (save_type == SmSaveGlobal ? "SmSaveGlobal" :
                (save_type == SmSaveBoth ? "SmSaveBoth" : "INVALID!!")));
 -        ob_debug_type(OB_DEBUG_SM, "Session save requested, type %s\n", sname);
 +        ob_debug_type(OB_DEBUG_SM, "Session save requested, type %s", sname);
      }
  #endif
  
      }
  
      vendor = SmcVendor(sm_conn);
 -    ob_debug_type(OB_DEBUG_SM, "Session manager's vendor: %s\n", vendor);
 +    ob_debug_type(OB_DEBUG_SM, "Session manager's vendor: %s", vendor);
  
      if (!strcmp(vendor, "KDE")) {
          /* ksmserver guarantees that phase 1 will complete before allowing any
      free(vendor);
  
      if (!SmcRequestSaveYourselfPhase2(conn, sm_save_yourself_2, savedata)) {
 -        ob_debug_type(OB_DEBUG_SM, "Requst for phase 2 failed\n");
 +        ob_debug_type(OB_DEBUG_SM, "Requst for phase 2 failed");
          g_free(savedata);
          SmcSaveYourselfDone(conn, FALSE);
      }
  
  static void sm_die(SmcConn conn, SmPointer data)
  {
 -    ob_debug_type(OB_DEBUG_SM, "Die requested\n");
 +    ob_debug_type(OB_DEBUG_SM, "Die requested");
      ob_exit(0);
  }
  
  static void sm_save_complete(SmcConn conn, SmPointer data)
  {
 -    ob_debug_type(OB_DEBUG_SM, "Save complete\n");
 +    ob_debug_type(OB_DEBUG_SM, "Save complete");
  }
  
  static void sm_shutdown_cancelled(SmcConn conn, SmPointer data)
  {
 -    ob_debug_type(OB_DEBUG_SM, "Shutdown cancelled\n");
 +    ob_debug_type(OB_DEBUG_SM, "Shutdown cancelled");
  }
  
  static gboolean session_save_to_file(const ObSMSaveData *savedata)
  
              if (!c->sm_client_id) {
                  ob_debug_type(OB_DEBUG_SM, "Client %s does not have a "
 -                              "session id set\n",
 +                              "session id set",
                                c->title);
                  if (!c->wm_command) {
                      ob_debug_type(OB_DEBUG_SM, "Client %s does not have an "
                                    "oldskool wm_command set either. We won't "
 -                                  "be saving its data\n",
 +                                  "be saving its data",
                                    c->title);
                      continue;
                  }
              }
  
 -            ob_debug_type(OB_DEBUG_SM, "Saving state for client %s\n",
 +            ob_debug_type(OB_DEBUG_SM, "Saving state for client %s",
                            c->title);
  
              prex = c->area.x;
@@@ -630,20 -632,20 +636,20 @@@ static void session_state_free(ObSessio
  
  static gboolean session_state_cmp(ObSessionState *s, ObClient *c)
  {
 -    ob_debug_type(OB_DEBUG_SM, "Comparing client against saved state: \n");
 -    ob_debug_type(OB_DEBUG_SM, "  client id: %s \n", c->sm_client_id);
 -    ob_debug_type(OB_DEBUG_SM, "  client name: %s \n", c->name);
 -    ob_debug_type(OB_DEBUG_SM, "  client class: %s \n", c->class);
 -    ob_debug_type(OB_DEBUG_SM, "  client role: %s \n", c->role);
 -    ob_debug_type(OB_DEBUG_SM, "  client type: %d \n", c->type);
 -    ob_debug_type(OB_DEBUG_SM, "  client command: %s \n",
 +    ob_debug_type(OB_DEBUG_SM, "Comparing client against saved state: ");
 +    ob_debug_type(OB_DEBUG_SM, "  client id: %s ", c->sm_client_id);
 +    ob_debug_type(OB_DEBUG_SM, "  client name: %s ", c->name);
 +    ob_debug_type(OB_DEBUG_SM, "  client class: %s ", c->class);
 +    ob_debug_type(OB_DEBUG_SM, "  client role: %s ", c->role);
 +    ob_debug_type(OB_DEBUG_SM, "  client type: %d ", c->type);
 +    ob_debug_type(OB_DEBUG_SM, "  client command: %s ",
                    c->wm_command ? c->wm_command : "(null)");
 -    ob_debug_type(OB_DEBUG_SM, "  state id: %s \n", s->id);
 -    ob_debug_type(OB_DEBUG_SM, "  state name: %s \n", s->name);
 -    ob_debug_type(OB_DEBUG_SM, "  state class: %s \n", s->class);
 -    ob_debug_type(OB_DEBUG_SM, "  state role: %s \n", s->role);
 -    ob_debug_type(OB_DEBUG_SM, "  state type: %d \n", s->type);
 -    ob_debug_type(OB_DEBUG_SM, "  state command: %s \n",
 +    ob_debug_type(OB_DEBUG_SM, "  state id: %s ", s->id);
 +    ob_debug_type(OB_DEBUG_SM, "  state name: %s ", s->name);
 +    ob_debug_type(OB_DEBUG_SM, "  state class: %s ", s->class);
 +    ob_debug_type(OB_DEBUG_SM, "  state role: %s ", s->role);
 +    ob_debug_type(OB_DEBUG_SM, "  state type: %d ", s->type);
 +    ob_debug_type(OB_DEBUG_SM, "  state command: %s ",
                    s->command ? s->command : "(null)");
  
      if ((c->sm_client_id && s->id && !strcmp(c->sm_client_id, s->id)) ||
@@@ -678,117 -680,108 +684,117 @@@ GList* session_state_find(ObClient *c
  
  static void session_load_file(const gchar *path)
  {
 -    xmlDocPtr doc;
 +    ObtParseInst *i;
      xmlNodePtr node, n, m;
      GList *it, *inext;
  
 -    if (!parse_load(path, "openbox_session", &doc, &node))
 +    i = obt_parse_instance_new();
 +
 +    if (!obt_parse_load_file(i, path, "openbox_session")) {
 +        ob_debug_type(OB_DEBUG_SM, "ERROR: session file is missing root node");
 +        obt_parse_instance_unref(i);
          return;
 +    }
 +    node = obt_parse_root(i);
  
 -    if ((n = parse_find_node("desktop", node->children)))
 -        session_desktop = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node->children, "desktop")))
 +        session_desktop = obt_parse_node_int(n);
  
 -    if ((n = parse_find_node("numdesktops", node->children)))
 -        session_num_desktops = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node->children, "numdesktops")))
 +        session_num_desktops = obt_parse_node_int(n);
  
 -    if ((n = parse_find_node("desktoplayout", node->children))) {
 +    if ((n = obt_parse_find_node(node->children, "desktoplayout"))) {
          /* make sure they are all there for it to be valid */
 -        if ((m = parse_find_node("orientation", n->children)))
 -            session_desktop_layout.orientation = parse_int(doc, m);
 -        if (m && (m = parse_find_node("startcorner", n->children)))
 -            session_desktop_layout.start_corner = parse_int(doc, m);
 -        if (m && (m = parse_find_node("columns", n->children)))
 -            session_desktop_layout.columns = parse_int(doc, m);
 -        if (m && (m = parse_find_node("rows", n->children)))
 -            session_desktop_layout.rows = parse_int(doc, m);
 +        if ((m = obt_parse_find_node(n->children, "orientation")))
 +            session_desktop_layout.orientation = obt_parse_node_int(m);
 +        if (m && (m = obt_parse_find_node(n->children, "startcorner")))
 +            session_desktop_layout.start_corner = obt_parse_node_int(m);
 +        if (m && (m = obt_parse_find_node(n->children, "columns")))
 +            session_desktop_layout.columns = obt_parse_node_int(m);
 +        if (m && (m = obt_parse_find_node(n->children, "rows")))
 +            session_desktop_layout.rows = obt_parse_node_int(m);
          session_desktop_layout_present = m != NULL;
      }
  
 -    if ((n = parse_find_node("desktopnames", node->children))) {
 -        for (m = parse_find_node("name", n->children); m;
 -             m = parse_find_node("name", m->next))
 +    if ((n = obt_parse_find_node(node->children, "desktopnames"))) {
 +        for (m = obt_parse_find_node(n->children, "name"); m;
 +             m = obt_parse_find_node(m->next, "name"))
          {
              session_desktop_names = g_slist_append(session_desktop_names,
 -                                                   parse_string(doc, m));
 +                                                   obt_parse_node_string(m));
          }
      }
  
 -    for (node = parse_find_node("window", node->children); node != NULL;
 -         node = parse_find_node("window", node->next))
 +    ob_debug_type(OB_DEBUG_SM, "loading windows");
 +    for (node = obt_parse_find_node(node->children, "window"); node != NULL;
 +         node = obt_parse_find_node(node->next, "window"))
      {
          ObSessionState *state;
  
          state = g_new0(ObSessionState, 1);
  
 -        if (!parse_attr_string("id", node, &state->id))
 -            if (!parse_attr_string("command", node, &state->command))
 +        if (!obt_parse_attr_string(node, "id", &state->id))
 +            if (!obt_parse_attr_string(node, "command", &state->command))
              goto session_load_bail;
 -        if (!(n = parse_find_node("name", node->children)))
 +        if (!(n = obt_parse_find_node(node->children, "name")))
              goto session_load_bail;
 -        state->name = parse_string(doc, n);
 -        if (!(n = parse_find_node("class", node->children)))
 +        state->name = obt_parse_node_string(n);
 +        if (!(n = obt_parse_find_node(node->children, "class")))
              goto session_load_bail;
 -        state->class = parse_string(doc, n);
 -        if (!(n = parse_find_node("role", node->children)))
 +        state->class = obt_parse_node_string(n);
 +        if (!(n = obt_parse_find_node(node->children, "role")))
              goto session_load_bail;
 -        state->role = parse_string(doc, n);
 -        if (!(n = parse_find_node("windowtype", node->children)))
 +        state->role = obt_parse_node_string(n);
 +        if (!(n = obt_parse_find_node(node->children, "windowtype")))
              goto session_load_bail;
 -        state->type = parse_int(doc, n);
 -        if (!(n = parse_find_node("desktop", node->children)))
 +        state->type = obt_parse_node_int(n);
 +        if (!(n = obt_parse_find_node(node->children, "desktop")))
              goto session_load_bail;
 -        state->desktop = parse_int(doc, n);
 -        if (!(n = parse_find_node("x", node->children)))
 +        state->desktop = obt_parse_node_int(n);
 +        if (!(n = obt_parse_find_node(node->children, "x")))
              goto session_load_bail;
 -        state->x = parse_int(doc, n);
 -        if (!(n = parse_find_node("y", node->children)))
 +        state->x = obt_parse_node_int(n);
 +        if (!(n = obt_parse_find_node(node->children, "y")))
              goto session_load_bail;
 -        state->y = parse_int(doc, n);
 -        if (!(n = parse_find_node("width", node->children)))
 +        state->y = obt_parse_node_int(n);
 +        if (!(n = obt_parse_find_node(node->children, "width")))
              goto session_load_bail;
 -        state->w = parse_int(doc, n);
 -        if (!(n = parse_find_node("height", node->children)))
 +        state->w = obt_parse_node_int(n);
 +        if (!(n = obt_parse_find_node(node->children, "height")))
              goto session_load_bail;
 -        state->h = parse_int(doc, n);
 +        state->h = obt_parse_node_int(n);
  
          state->shaded =
 -            parse_find_node("shaded", node->children) != NULL;
 +            obt_parse_find_node(node->children, "shaded") != NULL;
          state->iconic =
 -            parse_find_node("iconic", node->children) != NULL;
 +            obt_parse_find_node(node->children, "iconic") != NULL;
          state->skip_pager =
 -            parse_find_node("skip_pager", node->children) != NULL;
 +            obt_parse_find_node(node->children, "skip_pager") != NULL;
          state->skip_taskbar =
 -            parse_find_node("skip_taskbar", node->children) != NULL;
 +            obt_parse_find_node(node->children, "skip_taskbar") != NULL;
          state->fullscreen =
 -            parse_find_node("fullscreen", node->children) != NULL;
 +            obt_parse_find_node(node->children, "fullscreen") != NULL;
          state->above =
 -            parse_find_node("above", node->children) != NULL;
 +            obt_parse_find_node(node->children, "above") != NULL;
          state->below =
 -            parse_find_node("below", node->children) != NULL;
 +            obt_parse_find_node(node->children, "below") != NULL;
          state->max_horz =
 -            parse_find_node("max_horz", node->children) != NULL;
 +            obt_parse_find_node(node->children, "max_horz") != NULL;
          state->max_vert =
 -            parse_find_node("max_vert", node->children) != NULL;
 +            obt_parse_find_node(node->children, "max_vert") != NULL;
          state->undecorated =
 -            parse_find_node("undecorated", node->children) != NULL;
 +            obt_parse_find_node(node->children, "undecorated") != NULL;
          state->focused =
 -            parse_find_node("focused", node->children) != NULL;
 +            obt_parse_find_node(node->children, "focused") != NULL;
  
          /* save this. they are in the file in stacking order, so preserve
             that order here */
          session_saved_state = g_list_append(session_saved_state, state);
 +        ob_debug_type(OB_DEBUG_SM, "loaded %s", state->name);
          continue;
  
      session_load_bail:
 +        ob_debug_type(OB_DEBUG_SM, "loading FAILED");
          session_state_free(state);
      }
  
                  !strcmp(s1->class, s2->class) &&
                  !strcmp(s1->role, s2->role))
              {
 +                ob_debug_type(OB_DEBUG_SM, "removing duplicate %s", s2->name);
                  session_state_free(s2);
                  session_saved_state =
                      g_list_delete_link(session_saved_state, jt);
          }
  
          if (founddup) {
 +            ob_debug_type(OB_DEBUG_SM, "removing duplicate %s", s1->name);
              session_state_free(s1);
              session_saved_state = g_list_delete_link(session_saved_state, it);
          }
      }
  
 -    xmlFreeDoc(doc);
 +    obt_parse_instance_unref(i);
  }
  
  void session_request_logout(gboolean silent)