]> Dogcows Code - chaz/openbox/commitdiff
Merge branch 'backport' into work
authorDana Jansens <danakj@orodu.net>
Sat, 12 Dec 2009 00:02:11 +0000 (19:02 -0500)
committerDana Jansens <danakj@orodu.net>
Sat, 12 Dec 2009 00:02:11 +0000 (19:02 -0500)
Conflicts:
openbox/config.c
openbox/event.c
openbox/prop.c
openbox/prop.h
openbox/screen.c
openbox/screen.h

23 files changed:
1  2 
Makefile.am
data/rc.xml
obt/prop.c
obt/prop.h
openbox/actions/focus.c
openbox/client.c
openbox/client.h
openbox/config.c
openbox/config.h
openbox/event.c
openbox/focus.c
openbox/focus.h
openbox/focus_cycle.c
openbox/focus_cycle_popup.c
openbox/frame.c
openbox/keyboard.c
openbox/openbox.c
openbox/place.c
openbox/screen.c
openbox/screen.h
openbox/stacking.c
po/POTFILES.in
render/image.c

diff --combined Makefile.am
index c72a40b3d2c3e63d022470e419faef34ed3c33e5,660b5ef5f6cbf2569fe2cc2f1d7ade226c84d757..786b97b0cb44f5a1e4d318d07bdbc2d7d46155db
@@@ -8,11 -8,11 +8,12 @@@ 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
+ appsdir         = $(datadir)/applications
  
  theme = Clearlooks
  
@@@ -26,7 -26,7 +27,7 @@@ check_PROGRAMS = 
        render/rendertest
  
  lib_LTLIBRARIES = \
 -      parser/libobparser.la \
 +      obt/libobt.la \
        render/libobrender.la
  
  bin_PROGRAMS = \
@@@ -46,13 -46,15 +47,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 -64,16 +63,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/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 ##
  
@@@ -394,7 -394,7 +395,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 ##
  
+ dist_apps_DATA = \
+       data/openbox.desktop
  dist_pixmap_DATA = \
        data/openbox.png
  
@@@ -468,6 -463,7 +472,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 \
@@@ -544,7 -538,7 +548,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 data/rc.xml
index f223f67889522ec7894268f8fc7919d5e41960f7,8f5ee28bfee714faae5399b0947bcd66c0700528..4e96305dbf63cacf65fc293989c1ef1bb09ec25e
    <center>yes</center>
    <!-- whether to place windows in the center of the free area found or
         the top left corner -->
-   <monitor>Any</monitor>
+   <monitor>Active</monitor>
    <!-- with Smart placement on a multi-monitor system, try to place new windows
         on: 'Any' - any monitor, 'Mouse' - where the mouse is, 'Active' - where
         the active window is -->
+   <primaryMonitor>1</primaryMonitor>
+   <!-- The monitor where Openbox should place popup dialogs such as the
+        focus cycling popup, or the desktop switch popup.  It can be an index
+        from 1, specifying a particular monitor.  Or it can be one of the
+        following: 'Mouse' - where the mouse is, or
+                   'Active' - where the active window is -->
  </placement>
  
  <theme>
      </mousebind>
  
      <mousebind button="Up" action="Click">
 -      <action name="Shade"/>
 -      <action name="FocusToBottom"/>
 -      <action name="Unfocus"/>
 -      <action name="Lower"/>
 +      <action name="if">
 +        <shaded>no</shaded>
 +        <then>
 +          <action name="Shade"/>
 +          <action name="FocusToBottom"/>
 +          <action name="Unfocus"/>
 +          <action name="Lower"/>
 +        </then>
 +      </action>
      </mousebind>
      <mousebind button="Down" action="Click">
 -      <action name="Unshade"/>
 -      <action name="Raise"/>
 +      <action name="if">
 +        <shaded>yes</shaded>
 +        <then>
 +          <action name="Unshade"/>
 +          <action name="Raise"/>
 +        </then>
 +      </action>
      </mousebind>
  
      <mousebind button="Right" action="Press">
    </context>
  
    <context name="Desktop">
 -    <mousebind button="Up" action="Press">
 +    <mousebind button="Up" action="Click">
        <action name="GoToDesktop"><to>previous</to></action>
      </mousebind>
 -    <mousebind button="Down" action="Press">
 +    <mousebind button="Down" action="Click">
        <action name="GoToDesktop"><to>next</to></action>
      </mousebind>
  
 -    <mousebind button="A-Up" action="Press">
 +    <mousebind button="A-Up" action="Click">
        <action name="GoToDesktop"><to>previous</to></action>
      </mousebind>
 -    <mousebind button="A-Down" action="Press">
 +    <mousebind button="A-Down" action="Click">
        <action name="GoToDesktop"><to>next</to></action>
      </mousebind>
 -    <mousebind button="C-A-Up" action="Press">
 +    <mousebind button="C-A-Up" action="Click">
        <action name="GoToDesktop"><to>previous</to></action>
      </mousebind>
 -    <mousebind button="C-A-Down" action="Press">
 +    <mousebind button="C-A-Down" action="Click">
        <action name="GoToDesktop"><to>next</to></action>
      </mousebind>
  
    </context>
  
    <context name="MoveResize">
 -    <mousebind button="Up" action="Press">
 +    <mousebind button="Up" action="Click">
        <action name="GoToDesktop"><to>previous</to></action>
      </mousebind>
 -    <mousebind button="Down" action="Press">
 +    <mousebind button="Down" action="Click">
        <action name="GoToDesktop"><to>next</to></action>
      </mousebind>
 -    <mousebind button="A-Up" action="Press">
 +    <mousebind button="A-Up" action="Click">
        <action name="GoToDesktop"><to>previous</to></action>
      </mousebind>
 -    <mousebind button="A-Down" action="Press">
 +    <mousebind button="A-Down" action="Click">
        <action name="GoToDesktop"><to>next</to></action>
      </mousebind>
    </context>
diff --combined obt/prop.c
index 185bf5374eaa99d3d7362c56307fb871db262be0,0000000000000000000000000000000000000000..f4c8db17a7cbe466028d0f0596de385a49663c96
mode 100644,000000..100644
--- /dev/null
@@@ -1,498 -1,0 +1,501 @@@
 +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 +
 +   obt/prop.c for the Openbox window manager
 +   Copyright (c) 2006        Mikael Magnusson
 +   Copyright (c) 2003-2007   Dana Jansens
 +
 +   This program is free software; you can redistribute it and/or modify
 +   it under the terms of the GNU General Public License as published by
 +   the Free Software Foundation; either version 2 of the License, or
 +   (at your option) any later version.
 +
 +   This program is distributed in the hope that it will be useful,
 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +   GNU General Public License for more details.
 +
 +   See the COPYING file for a copy of the GNU General Public License.
 +*/
 +
 +#include "obt/prop.h"
 +#include "obt/display.h"
 +
 +#include <X11/Xatom.h>
 +#ifdef HAVE_STRING_H
 +#  include <string.h>
 +#endif
 +
 +Atom prop_atoms[OBT_PROP_NUM_ATOMS];
 +gboolean prop_started = FALSE;
 +
 +#define CREATE_NAME(var, name) (prop_atoms[OBT_PROP_##var] = \
 +                                XInternAtom((obt_display), (name), FALSE))
 +#define CREATE(var) CREATE_NAME(var, #var)
 +#define CREATE_(var) CREATE_NAME(var, "_" #var)
 +
 +void obt_prop_startup(void)
 +{
 +    if (prop_started) return;
 +    prop_started = TRUE;
 +
 +    g_assert(obt_display);
 +
 +    CREATE(CARDINAL);
 +    CREATE(WINDOW);
 +    CREATE(PIXMAP);
 +    CREATE(ATOM);
 +    CREATE(STRING);
 +    CREATE_NAME(UTF8, "UTF8_STRING");
 +
 +    CREATE(MANAGER);
 +
 +    CREATE(WM_COLORMAP_WINDOWS);
 +    CREATE(WM_PROTOCOLS);
 +    CREATE(WM_STATE);
 +    CREATE(WM_CHANGE_STATE);
 +    CREATE(WM_DELETE_WINDOW);
 +    CREATE(WM_TAKE_FOCUS);
 +    CREATE(WM_NAME);
 +    CREATE(WM_ICON_NAME);
 +    CREATE(WM_CLASS);
 +    CREATE(WM_WINDOW_ROLE);
 +    CREATE(WM_CLIENT_MACHINE);
 +    CREATE(WM_COMMAND);
 +    CREATE(WM_CLIENT_LEADER);
 +    CREATE(WM_TRANSIENT_FOR);
 +    CREATE_(MOTIF_WM_HINTS);
 +    CREATE_(MOTIF_WM_INFO);
 +
 +    CREATE(SM_CLIENT_ID);
 +
 +    CREATE_(NET_WM_FULL_PLACEMENT);
 +
 +    CREATE_(NET_SUPPORTED);
 +    CREATE_(NET_CLIENT_LIST);
 +    CREATE_(NET_CLIENT_LIST_STACKING);
 +    CREATE_(NET_NUMBER_OF_DESKTOPS);
 +    CREATE_(NET_DESKTOP_GEOMETRY);
 +    CREATE_(NET_DESKTOP_VIEWPORT);
 +    CREATE_(NET_CURRENT_DESKTOP);
 +    CREATE_(NET_DESKTOP_NAMES);
 +    CREATE_(NET_ACTIVE_WINDOW);
 +/*    CREATE_(NET_RESTACK_WINDOW);*/
 +    CREATE_(NET_WORKAREA);
 +    CREATE_(NET_SUPPORTING_WM_CHECK);
 +    CREATE_(NET_DESKTOP_LAYOUT);
 +    CREATE_(NET_SHOWING_DESKTOP);
 +
 +    CREATE_(NET_CLOSE_WINDOW);
 +    CREATE_(NET_WM_MOVERESIZE);
 +    CREATE_(NET_MOVERESIZE_WINDOW);
 +    CREATE_(NET_REQUEST_FRAME_EXTENTS);
 +    CREATE_(NET_RESTACK_WINDOW);
 +
 +    CREATE_(NET_STARTUP_ID);
 +
 +    CREATE_(NET_WM_NAME);
 +    CREATE_(NET_WM_VISIBLE_NAME);
 +    CREATE_(NET_WM_ICON_NAME);
 +    CREATE_(NET_WM_VISIBLE_ICON_NAME);
 +    CREATE_(NET_WM_DESKTOP);
 +    CREATE_(NET_WM_WINDOW_TYPE);
 +    CREATE_(NET_WM_STATE);
 +    CREATE_(NET_WM_STRUT);
 +    CREATE_(NET_WM_STRUT_PARTIAL);
 +    CREATE_(NET_WM_ICON);
 +    CREATE_(NET_WM_ICON_GEOMETRY);
 +    CREATE_(NET_WM_PID);
 +    CREATE_(NET_WM_ALLOWED_ACTIONS);
 +    CREATE_(NET_WM_USER_TIME);
 +/*  CREATE_(NET_WM_USER_TIME_WINDOW); */
 +    CREATE_(KDE_NET_WM_FRAME_STRUT);
 +    CREATE_(NET_FRAME_EXTENTS);
 +
 +    CREATE_(NET_WM_PING);
 +#ifdef SYNC
 +    CREATE_(NET_WM_SYNC_REQUEST);
 +    CREATE_(NET_WM_SYNC_REQUEST_COUNTER);
 +#endif
 +
 +    CREATE_(NET_WM_WINDOW_TYPE_DESKTOP);
 +    CREATE_(NET_WM_WINDOW_TYPE_DOCK);
 +    CREATE_(NET_WM_WINDOW_TYPE_TOOLBAR);
 +    CREATE_(NET_WM_WINDOW_TYPE_MENU);
 +    CREATE_(NET_WM_WINDOW_TYPE_UTILITY);
 +    CREATE_(NET_WM_WINDOW_TYPE_SPLASH);
 +    CREATE_(NET_WM_WINDOW_TYPE_DIALOG);
 +    CREATE_(NET_WM_WINDOW_TYPE_NORMAL);
 +    CREATE_(NET_WM_WINDOW_TYPE_POPUP_MENU);
 +
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPLEFT] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOP] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPRIGHT] = 2;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_RIGHT] = 3;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT] = 4;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOM] = 5;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT] = 6;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_LEFT] = 7;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_MOVE] = 8;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_SIZE_KEYBOARD] = 9;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_MOVE_KEYBOARD] = 10;
 +    prop_atoms[OBT_PROP_NET_WM_MOVERESIZE_CANCEL] = 11;
 +
 +    CREATE_(NET_WM_ACTION_MOVE);
 +    CREATE_(NET_WM_ACTION_RESIZE);
 +    CREATE_(NET_WM_ACTION_MINIMIZE);
 +    CREATE_(NET_WM_ACTION_SHADE);
 +    CREATE_(NET_WM_ACTION_MAXIMIZE_HORZ);
 +    CREATE_(NET_WM_ACTION_MAXIMIZE_VERT);
 +    CREATE_(NET_WM_ACTION_FULLSCREEN);
 +    CREATE_(NET_WM_ACTION_CHANGE_DESKTOP);
 +    CREATE_(NET_WM_ACTION_CLOSE);
 +    CREATE_(NET_WM_ACTION_ABOVE);
 +    CREATE_(NET_WM_ACTION_BELOW);
 +
 +    CREATE_(NET_WM_STATE_MODAL);
 +/*    CREATE_(NET_WM_STATE_STICKY);*/
 +    CREATE_(NET_WM_STATE_MAXIMIZED_VERT);
 +    CREATE_(NET_WM_STATE_MAXIMIZED_HORZ);
 +    CREATE_(NET_WM_STATE_SHADED);
 +    CREATE_(NET_WM_STATE_SKIP_TASKBAR);
 +    CREATE_(NET_WM_STATE_SKIP_PAGER);
 +    CREATE_(NET_WM_STATE_HIDDEN);
 +    CREATE_(NET_WM_STATE_FULLSCREEN);
 +    CREATE_(NET_WM_STATE_ABOVE);
 +    CREATE_(NET_WM_STATE_BELOW);
 +    CREATE_(NET_WM_STATE_DEMANDS_ATTENTION);
 +
 +    prop_atoms[OBT_PROP_NET_WM_STATE_ADD] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_STATE_REMOVE] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_STATE_TOGGLE] = 2;
 +
 +    prop_atoms[OBT_PROP_NET_WM_ORIENTATION_HORZ] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_ORIENTATION_VERT] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_TOPLEFT] = 0;
 +    prop_atoms[OBT_PROP_NET_WM_TOPRIGHT] = 1;
 +    prop_atoms[OBT_PROP_NET_WM_BOTTOMRIGHT] = 2;
 +    prop_atoms[OBT_PROP_NET_WM_BOTTOMLEFT] = 3;
 +
 +    CREATE_(KDE_WM_CHANGE_STATE);
 +    CREATE_(KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
 +
 +/*
 +    CREATE_NAME(ROOTPMAPId, "_XROOTPMAP_ID");
 +    CREATE_NAME(ESETROOTId, "ESETROOT_PMAP_ID");
 +*/
 +
 +    CREATE_(OPENBOX_PID);
 +    CREATE_(OB_THEME);
 +    CREATE_(OB_CONFIG_FILE);
 +    CREATE_(OB_WM_ACTION_UNDECORATE);
 +    CREATE_(OB_WM_STATE_UNDECORATED);
 +    CREATE_(OB_CONTROL);
++    CREATE_(OB_ROLE);
++    CREATE_(OB_NAME);
++    CREATE_(OB_CLASS);
 +}
 +
 +Atom obt_prop_atom(ObtPropAtom a)
 +{
 +    g_assert(prop_started);
 +    g_assert(a < OBT_PROP_NUM_ATOMS);
 +    return prop_atoms[a];
 +}
 +
 +static gboolean get_prealloc(Window win, Atom prop, Atom type, gint size,
 +                             guchar *data, gulong num)
 +{
 +    gboolean ret = FALSE;
 +    gint res;
 +    guchar *xdata = NULL;
 +    Atom ret_type;
 +    gint ret_size;
 +    gulong ret_items, bytes_left;
 +    glong num32 = 32 / size * num; /* num in 32-bit elements */
 +
 +    res = XGetWindowProperty(obt_display, win, prop, 0l, num32,
 +                             FALSE, type, &ret_type, &ret_size,
 +                             &ret_items, &bytes_left, &xdata);
 +    if (res == Success && ret_items && xdata) {
 +        if (ret_size == size && ret_items >= num) {
 +            guint i;
 +            for (i = 0; i < num; ++i)
 +                switch (size) {
 +                case 8:
 +                    data[i] = xdata[i];
 +                    break;
 +                case 16:
 +                    ((guint16*)data)[i] = ((gushort*)xdata)[i];
 +                    break;
 +                case 32:
 +                    ((guint32*)data)[i] = ((gulong*)xdata)[i];
 +                    break;
 +                default:
 +                    g_assert_not_reached(); /* unhandled size */
 +                }
 +            ret = TRUE;
 +        }
 +        XFree(xdata);
 +    }
 +    return ret;
 +}
 +
 +static gboolean get_all(Window win, Atom prop, Atom type, gint size,
 +                        guchar **data, guint *num)
 +{
 +    gboolean ret = FALSE;
 +    gint res;
 +    guchar *xdata = NULL;
 +    Atom ret_type;
 +    gint ret_size;
 +    gulong ret_items, bytes_left;
 +
 +    res = XGetWindowProperty(obt_display, win, prop, 0l, G_MAXLONG,
 +                             FALSE, type, &ret_type, &ret_size,
 +                             &ret_items, &bytes_left, &xdata);
 +    if (res == Success) {
 +        if (ret_size == size && ret_items > 0) {
 +            guint i;
 +
 +            *data = g_malloc(ret_items * (size / 8));
 +            for (i = 0; i < ret_items; ++i)
 +                switch (size) {
 +                case 8:
 +                    (*data)[i] = xdata[i];
 +                    break;
 +                case 16:
 +                    ((guint16*)*data)[i] = ((gushort*)xdata)[i];
 +                    break;
 +                case 32:
 +                    ((guint32*)*data)[i] = ((gulong*)xdata)[i];
 +                    break;
 +                default:
 +                    g_assert_not_reached(); /* unhandled size */
 +                }
 +            *num = ret_items;
 +            ret = TRUE;
 +        }
 +        XFree(xdata);
 +    }
 +    return ret;
 +}
 +
 +static gboolean get_stringlist(Window win, Atom prop, gchar ***list, gint *nstr)
 +{
 +    XTextProperty tprop;
 +    gboolean ret = FALSE;
 +
 +    if (XGetTextProperty(obt_display, win, &tprop, prop) && tprop.nitems) {
 +        if (XTextPropertyToStringList(&tprop, list, nstr))
 +            ret = TRUE;
 +        XFree(tprop.value);
 +    }
 +    return ret;
 +}
 +
 +gboolean obt_prop_get32(Window win, Atom prop, Atom type, guint32 *ret)
 +{
 +    return get_prealloc(win, prop, type, 32, (guchar*)ret, 1);
 +}
 +
 +gboolean obt_prop_get_array32(Window win, Atom prop, Atom type, guint32 **ret,
 +                              guint *nret)
 +{
 +    return get_all(win, prop, type, 32, (guchar**)ret, nret);
 +}
 +
 +gboolean obt_prop_get_string_locale(Window win, Atom prop, gchar **ret)
 +{
 +    gchar **list;
 +    gint nstr;
 +    gchar *s;
 +
 +    if (get_stringlist(win, prop, &list, &nstr) && nstr) {
 +        s = g_locale_to_utf8(list[0], -1, NULL, NULL, NULL);
 +        XFreeStringList(list);
 +        if (s) {
 +            *ret = s;
 +            return TRUE;
 +        }
 +    }
 +    return FALSE;
 +}
 +
 +gboolean obt_prop_get_strings_locale(Window win, Atom prop, gchar ***ret)
 +{
 +    GSList *strs = NULL, *it;
 +    gchar *raw, *p;
 +    guint num, i, count = 0;
 +
 +    if (get_all(win, prop, OBT_PROP_ATOM(STRING), 8,
 +                (guchar**)&raw, &num))
 +    {
 +        p = raw;
 +        while (p < raw + num) {
 +            ++count;
 +            strs = g_slist_append(strs, p);
 +            p += strlen(p) + 1; /* next string */
 +        }
 +
 +        *ret = g_new0(gchar*, count + 1);
 +        (*ret)[count] = NULL; /* null terminated list */
 +
 +        for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) {
 +            (*ret)[i] = g_locale_to_utf8(it->data, -1, NULL, NULL, NULL);
 +            /* make sure translation did not fail */
 +            if (!(*ret)[i])
 +                (*ret)[i] = g_strdup("");
 +        }
 +        g_free(raw);
 +        g_slist_free(strs);
 +        return TRUE;
 +    }
 +    return FALSE;
 +}
 +
 +gboolean obt_prop_get_string_utf8(Window win, Atom prop, gchar **ret)
 +{
 +    gchar *raw;
 +    gchar *str;
 +    guint num;
 +
 +    if (get_all(win, prop, OBT_PROP_ATOM(UTF8), 8,
 +                (guchar**)&raw, &num))
 +    {
 +        str = g_strndup(raw, num); /* grab the first string from the list */
 +        g_free(raw);
 +        if (g_utf8_validate(str, -1, NULL)) {
 +            *ret = str;
 +            return TRUE;
 +        }
 +        g_free(str);
 +    }
 +    return FALSE;
 +}
 +
 +gboolean obt_prop_get_strings_utf8(Window win, Atom prop, gchar ***ret)
 +{
 +    GSList *strs = NULL, *it;
 +    gchar *raw, *p;
 +    guint num, i, count = 0;
 +
 +    if (get_all(win, prop, OBT_PROP_ATOM(UTF8), 8,
 +                (guchar**)&raw, &num))
 +    {
 +        p = raw;
 +        while (p < raw + num) {
 +            ++count;
 +            strs = g_slist_append(strs, p);
 +            p += strlen(p) + 1; /* next string */
 +        }
 +
 +        *ret = g_new0(gchar*, count + 1);
 +
 +        for (i = 0, it = strs; it; ++i, it = g_slist_next(it)) {
 +            if (g_utf8_validate(it->data, -1, NULL))
 +                (*ret)[i] = g_strdup(it->data);
 +            else
 +                (*ret)[i] = g_strdup("");
 +        }
 +        g_free(raw);
 +        g_slist_free(strs);
 +        return TRUE;
 +    }
 +    return FALSE;
 +}
 +
 +void obt_prop_set32(Window win, Atom prop, Atom type, gulong val)
 +{
 +    XChangeProperty(obt_display, win, prop, type, 32, PropModeReplace,
 +                    (guchar*)&val, 1);
 +}
 +
 +void obt_prop_set_array32(Window win, Atom prop, Atom type, gulong *val,
 +                      guint num)
 +{
 +    XChangeProperty(obt_display, win, prop, type, 32, PropModeReplace,
 +                    (guchar*)val, num);
 +}
 +
 +void obt_prop_set_string_locale(Window win, Atom prop, const gchar *val)
 +{
 +    gchar const *s[2] = { val, NULL };
 +    obt_prop_set_strings_locale(win, prop, s);
 +}
 +
 +void obt_prop_set_strings_locale(Window win, Atom prop, const gchar **strs)
 +{
 +    gint i, count;
 +    gchar **lstrs;
 +    XTextProperty tprop;
 +
 +    /* count the strings in strs, and convert them to the locale format */
 +    for (count = 0; strs[count]; ++count);
 +    lstrs = g_new0(char*, count);
 +    for (i = 0; i < count; ++i) {
 +        lstrs[i] = g_locale_from_utf8(strs[i], -1, NULL, NULL, NULL);
 +        if (!lstrs[i]) {
 +            lstrs[i] = g_strdup(""); /* make it an empty string */
 +            g_warning("Unable to translate string '%s' from UTF8 to locale "
 +                      "format", strs[i]);
 +        }
 +    }
 +
 +
 +    XStringListToTextProperty(lstrs, count, &tprop);
 +    XSetTextProperty(obt_display, win, &tprop, prop);
 +    XFree(tprop.value);
 +}
 +
 +void obt_prop_set_string_utf8(Window win, Atom prop, const gchar *val)
 +{
 +    XChangeProperty(obt_display, win, prop, OBT_PROP_ATOM(UTF8), 8,
 +                    PropModeReplace, (const guchar*)val, strlen(val));
 +}
 +
 +void obt_prop_set_strings_utf8(Window win, Atom prop, const gchar **strs)
 +{
 +    GString *str;
 +    gchar const **s;
 +
 +    str = g_string_sized_new(0);
 +    for (s = strs; *s; ++s) {
 +        str = g_string_append(str, *s);
 +        str = g_string_append_c(str, '\0');
 +    }
 +    XChangeProperty(obt_display, win, prop, obt_prop_atom(OBT_PROP_UTF8), 8,
 +                    PropModeReplace, (guchar*)str->str, str->len);
 +    g_string_free(str, TRUE);
 +}
 +
 +void obt_prop_erase(Window win, Atom prop)
 +{
 +    XDeleteProperty(obt_display, win, prop);
 +}
 +
 +void obt_prop_message(gint screen, Window about, Atom messagetype,
 +                      glong data0, glong data1, glong data2, glong data3,
 +                      glong data4, glong mask)
 +{
 +    obt_prop_message_to(obt_root(screen), about, messagetype,
 +                        data0, data1, data2, data3, data4, mask);
 +}
 +
 +void obt_prop_message_to(Window to, Window about,
 +                         Atom messagetype,
 +                         glong data0, glong data1, glong data2, glong data3,
 +                         glong data4, glong mask)
 +{
 +    XEvent ce;
 +    ce.xclient.type = ClientMessage;
 +    ce.xclient.message_type = messagetype;
 +    ce.xclient.display = obt_display;
 +    ce.xclient.window = about;
 +    ce.xclient.format = 32;
 +    ce.xclient.data.l[0] = data0;
 +    ce.xclient.data.l[1] = data1;
 +    ce.xclient.data.l[2] = data2;
 +    ce.xclient.data.l[3] = data3;
 +    ce.xclient.data.l[4] = data4;
 +    XSendEvent(obt_display, to, FALSE, mask, &ce);
 +}
diff --combined obt/prop.h
index ae22b6fd65258a880af715f1cb08fee4cbf986c3,0000000000000000000000000000000000000000..52c1de1eee68b89f56e4d515939ee074be5f13f3
mode 100644,000000..100644
--- /dev/null
@@@ -1,282 -1,0 +1,285 @@@
 +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
 +
 +   obt/prop.h for the Openbox window manager
 +   Copyright (c) 2006        Mikael Magnusson
 +   Copyright (c) 2003-2007   Dana Jansens
 +
 +   This program is free software; you can redistribute it and/or modify
 +   it under the terms of the GNU General Public License as published by
 +   the Free Software Foundation; either version 2 of the License, or
 +   (at your option) any later version.
 +
 +   This program is distributed in the hope that it will be useful,
 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +   GNU General Public License for more details.
 +
 +   See the COPYING file for a copy of the GNU General Public License.
 +*/
 +
 +#ifndef __obt_prop_h
 +#define __obt_prop_h
 +
 +#include <X11/Xlib.h>
 +#include <glib.h>
 +
 +G_BEGIN_DECLS
 +
 +typedef enum {
 +    /* types */
 +    OBT_PROP_CARDINAL, /*!< The atom which represents the Cardinal data type */
 +    OBT_PROP_WINDOW,   /*!< The atom which represents window ids */
 +    OBT_PROP_PIXMAP,   /*!< The atom which represents pixmap ids */
 +    OBT_PROP_ATOM,     /*!< The atom which represents atom values */
 +    OBT_PROP_STRING,   /*!< The atom which represents ascii strings */
 +    OBT_PROP_UTF8,     /*!< The atom which represents utf8-encoded strings */
 +
 +    /* selection stuff */
 +    OBT_PROP_MANAGER,
 +
 +    /* window hints */
 +    OBT_PROP_WM_COLORMAP_WINDOWS,
 +    OBT_PROP_WM_PROTOCOLS,
 +    OBT_PROP_WM_STATE,
 +    OBT_PROP_WM_DELETE_WINDOW,
 +    OBT_PROP_WM_TAKE_FOCUS,
 +    OBT_PROP_WM_CHANGE_STATE,
 +    OBT_PROP_WM_NAME,
 +    OBT_PROP_WM_ICON_NAME,
 +    OBT_PROP_WM_CLASS,
 +    OBT_PROP_WM_WINDOW_ROLE,
 +    OBT_PROP_WM_CLIENT_MACHINE,
 +    OBT_PROP_WM_COMMAND,
 +    OBT_PROP_WM_CLIENT_LEADER,
 +    OBT_PROP_WM_TRANSIENT_FOR,
 +    OBT_PROP_MOTIF_WM_HINTS,
 +    OBT_PROP_MOTIF_WM_INFO,
 +
 +    /* SM atoms */
 +    OBT_PROP_SM_CLIENT_ID,
 +
 +    /* NETWM atoms */
 +
 +    /* Atoms that are used inside messages - these don't go in net_supported */
 +
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPLEFT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOP,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_TOPRIGHT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_RIGHT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOM,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_LEFT,
 +    OBT_PROP_NET_WM_MOVERESIZE_MOVE,
 +    OBT_PROP_NET_WM_MOVERESIZE_SIZE_KEYBOARD,
 +    OBT_PROP_NET_WM_MOVERESIZE_MOVE_KEYBOARD,
 +    OBT_PROP_NET_WM_MOVERESIZE_CANCEL,
 +
 +    OBT_PROP_NET_WM_STATE_ADD,
 +    OBT_PROP_NET_WM_STATE_REMOVE,
 +    OBT_PROP_NET_WM_STATE_TOGGLE,
 +
 +    OBT_PROP_NET_WM_ORIENTATION_HORZ,
 +    OBT_PROP_NET_WM_ORIENTATION_VERT,
 +    OBT_PROP_NET_WM_TOPLEFT,
 +    OBT_PROP_NET_WM_TOPRIGHT,
 +    OBT_PROP_NET_WM_BOTTOMRIGHT,
 +    OBT_PROP_NET_WM_BOTTOMLEFT,
 +
 +    OBT_PROP_NET_WM_WINDOW_TYPE_POPUP_MENU,
 +
 +    OBT_PROP_PRIVATE_PADDING1,
 +    OBT_PROP_PRIVATE_PADDING2,
 +    OBT_PROP_PRIVATE_PADDING3,
 +    OBT_PROP_PRIVATE_PADDING4,
 +    OBT_PROP_PRIVATE_PADDING5,
 +    OBT_PROP_PRIVATE_PADDING6,
 +    OBT_PROP_PRIVATE_PADDING7,
 +    OBT_PROP_PRIVATE_PADDING8,
 +    OBT_PROP_PRIVATE_PADDING9,
 +    OBT_PROP_PRIVATE_PADDING10,
 +    OBT_PROP_PRIVATE_PADDING11,
 +    OBT_PROP_PRIVATE_PADDING12,
 +
 +    /* Everything below here must go in net_supported on the root window */
 +
 +    /* root window properties */
 +    OBT_PROP_NET_SUPPORTED,
 +    OBT_PROP_NET_CLIENT_LIST,
 +    OBT_PROP_NET_CLIENT_LIST_STACKING,
 +    OBT_PROP_NET_NUMBER_OF_DESKTOPS,
 +    OBT_PROP_NET_DESKTOP_GEOMETRY,
 +    OBT_PROP_NET_DESKTOP_VIEWPORT,
 +    OBT_PROP_NET_CURRENT_DESKTOP,
 +    OBT_PROP_NET_DESKTOP_NAMES,
 +    OBT_PROP_NET_ACTIVE_WINDOW,
 +/*    Atom net_restack_window;*/
 +    OBT_PROP_NET_WORKAREA,
 +    OBT_PROP_NET_SUPPORTING_WM_CHECK,
 +    OBT_PROP_NET_DESKTOP_LAYOUT,
 +    OBT_PROP_NET_SHOWING_DESKTOP,
 +
 +    /* root window messages */
 +    OBT_PROP_NET_CLOSE_WINDOW,
 +    OBT_PROP_NET_WM_MOVERESIZE,
 +    OBT_PROP_NET_MOVERESIZE_WINDOW,
 +    OBT_PROP_NET_REQUEST_FRAME_EXTENTS,
 +    OBT_PROP_NET_RESTACK_WINDOW,
 +
 +    /* helpful hints to apps that aren't used for anything */
 +    OBT_PROP_NET_WM_FULL_PLACEMENT,
 +
 +    /* startup-notification extension */
 +    OBT_PROP_NET_STARTUP_ID,
 +
 +    /* application window properties */
 +    OBT_PROP_NET_WM_NAME,
 +    OBT_PROP_NET_WM_VISIBLE_NAME,
 +    OBT_PROP_NET_WM_ICON_NAME,
 +    OBT_PROP_NET_WM_VISIBLE_ICON_NAME,
 +    OBT_PROP_NET_WM_DESKTOP,
 +    OBT_PROP_NET_WM_WINDOW_TYPE,
 +    OBT_PROP_NET_WM_STATE,
 +    OBT_PROP_NET_WM_STRUT,
 +    OBT_PROP_NET_WM_STRUT_PARTIAL,
 +    OBT_PROP_NET_WM_ICON,
 +    OBT_PROP_NET_WM_ICON_GEOMETRY,
 +    OBT_PROP_NET_WM_PID,
 +    OBT_PROP_NET_WM_ALLOWED_ACTIONS,
 +    OBT_PROP_NET_WM_USER_TIME,
 +/*  OBT_PROP_NET_WM_USER_TIME_WINDOW, */
 +    OBT_PROP_NET_FRAME_EXTENTS,
 +
 +    /* application protocols */
 +    OBT_PROP_NET_WM_PING,
 +#ifdef SYNC
 +    OBT_PROP_NET_WM_SYNC_REQUEST,
 +    OBT_PROP_NET_WM_SYNC_REQUEST_COUNTER,
 +#endif
 +
 +    OBT_PROP_NET_WM_WINDOW_TYPE_DESKTOP,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_DOCK,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_TOOLBAR,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_MENU,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_UTILITY,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_SPLASH,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_DIALOG,
 +    OBT_PROP_NET_WM_WINDOW_TYPE_NORMAL,
 +
 +    OBT_PROP_NET_WM_ACTION_MOVE,
 +    OBT_PROP_NET_WM_ACTION_RESIZE,
 +    OBT_PROP_NET_WM_ACTION_MINIMIZE,
 +    OBT_PROP_NET_WM_ACTION_SHADE,
 +/*    OBT_PROP_NET_WM_ACTION_STICK,*/
 +    OBT_PROP_NET_WM_ACTION_MAXIMIZE_HORZ,
 +    OBT_PROP_NET_WM_ACTION_MAXIMIZE_VERT,
 +    OBT_PROP_NET_WM_ACTION_FULLSCREEN,
 +    OBT_PROP_NET_WM_ACTION_CHANGE_DESKTOP,
 +    OBT_PROP_NET_WM_ACTION_CLOSE,
 +    OBT_PROP_NET_WM_ACTION_ABOVE,
 +    OBT_PROP_NET_WM_ACTION_BELOW,
 +
 +    OBT_PROP_NET_WM_STATE_MODAL,
 +/*    OBT_PROP_NET_WM_STATE_STICKY,*/
 +    OBT_PROP_NET_WM_STATE_MAXIMIZED_VERT,
 +    OBT_PROP_NET_WM_STATE_MAXIMIZED_HORZ,
 +    OBT_PROP_NET_WM_STATE_SHADED,
 +    OBT_PROP_NET_WM_STATE_SKIP_TASKBAR,
 +    OBT_PROP_NET_WM_STATE_SKIP_PAGER,
 +    OBT_PROP_NET_WM_STATE_HIDDEN,
 +    OBT_PROP_NET_WM_STATE_FULLSCREEN,
 +    OBT_PROP_NET_WM_STATE_ABOVE,
 +    OBT_PROP_NET_WM_STATE_BELOW,
 +    OBT_PROP_NET_WM_STATE_DEMANDS_ATTENTION,
 +
 +    /* KDE atoms */
 +
 +    OBT_PROP_KDE_WM_CHANGE_STATE,
 +    OBT_PROP_KDE_NET_WM_FRAME_STRUT,
 +    OBT_PROP_KDE_NET_WM_WINDOW_TYPE_OVERRIDE,
 +
 +/*
 +    OBT_PROP_ROOTPMAPID,
 +    OBT_PROP_ESETROOTID,
 +*/
 +
 +    /* Openbox specific atoms */
 +
 +    OBT_PROP_OB_WM_ACTION_UNDECORATE,
 +    OBT_PROP_OB_WM_STATE_UNDECORATED,
 +    OBT_PROP_OPENBOX_PID, /* this is depreecated in favour of ob_control */
 +    OBT_PROP_OB_THEME,
 +    OBT_PROP_OB_CONFIG_FILE,
 +    OBT_PROP_OB_CONTROL,
++    OBT_PROP_OB_ROLE,
++    OBT_PROP_OB_NAME,
++    OBT_PROP_OB_CLASS,
 +
 +    OBT_PROP_NUM_ATOMS
 +} ObtPropAtom;
 +
 +Atom obt_prop_atom(ObtPropAtom a);
 +
 +gboolean obt_prop_get32(Window win, Atom prop, Atom type, guint32 *ret);
 +gboolean obt_prop_get_array32(Window win, Atom prop, Atom type, guint32 **ret,
 +                              guint *nret);
 +gboolean obt_prop_get_string_locale(Window win, Atom prop, gchar **ret);
 +gboolean obt_prop_get_string_utf8(Window win, Atom prop, gchar **ret);
 +gboolean obt_prop_get_strings_locale(Window win, Atom prop, gchar ***ret);
 +gboolean obt_prop_get_strings_utf8(Window win, Atom prop, gchar ***ret);
 +
 +void obt_prop_set32(Window win, Atom prop, Atom type, gulong val);
 +void obt_prop_set_array32(Window win, Atom prop, Atom type, gulong *val,
 +                          guint num);
 +void obt_prop_set_string_locale(Window win, Atom prop, const gchar *val);
 +void obt_prop_set_string_utf8(Window win, Atom prop, const gchar *val);
 +void obt_prop_set_strings_locale(Window win, Atom prop, const gchar **strs);
 +void obt_prop_set_strings_utf8(Window win, Atom prop, const gchar **strs);
 +
 +void obt_prop_erase(Window win, Atom prop);
 +
 +void obt_prop_message(gint screen, Window about, Atom messagetype,
 +                      glong data0, glong data1, glong data2, glong data3,
 +                      glong data4, glong mask);
 +void obt_prop_message_to(Window to, Window about, Atom messagetype,
 +                         glong data0, glong data1, glong data2, glong data3,
 +                         glong data4, glong mask);
 +
 +#define OBT_PROP_ATOM(prop) obt_prop_atom(OBT_PROP_##prop)
 +
 +#define OBT_PROP_GET32(win, prop, type, ret) \
 +    (obt_prop_get32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), ret))
 +#define OBT_PROP_GETA32(win, prop, type, ret, nret) \
 +    (obt_prop_get_array32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), \
 +                          ret, nret))
 +#define OBT_PROP_GETS(win, prop, type, ret) \
 +    (obt_prop_get_string_##type(win, OBT_PROP_ATOM(prop), ret))
 +#define OBT_PROP_GETSS(win, prop, type, ret) \
 +    (obt_prop_get_strings_##type(win, OBT_PROP_ATOM(prop), ret))
 +
 +#define OBT_PROP_SET32(win, prop, type, val) \
 +    (obt_prop_set32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), val))
 +#define OBT_PROP_SETA32(win, prop, type, val, num) \
 +    (obt_prop_set_array32(win, OBT_PROP_ATOM(prop), OBT_PROP_ATOM(type), \
 +                          val, num))
 +#define OBT_PROP_SETS(win, prop, type, val) \
 +    (obt_prop_set_string_##type(win, OBT_PROP_ATOM(prop), val))
 +#define OBT_PROP_SETSS(win, prop, type, strs) \
 +    (obt_prop_set_strings_##type(win, OBT_PROP_ATOM(prop), strs))
 +
 +#define OBT_PROP_ERASE(win, prop) (obt_prop_erase(win, OBT_PROP_ATOM(prop)))
 +
 +#define OBT_PROP_MSG(screen, about, msgtype, data0, data1, data2, data3, \
 +                     data4) \
 +    (obt_prop_message(screen, about, OBT_PROP_ATOM(msgtype), \
 +                      data0, data1, data2, data3, data4, \
 +                      SubstructureNotifyMask | SubstructureRedirectMask))
 +
 +#define OBT_PROP_MSG_TO(to, about, msgtype, data0, data1, data2, data3, \
 +                        data4, mask) \
 +    (obt_prop_message_to(to, about, OBT_PROP_ATOM(msgtype), \
 +                         data0, data1, data2, data3, data4, mask))
 +
 +G_END_DECLS
 +
 +#endif /* __obt_prop_h */
diff --combined openbox/actions/focus.c
index 4d0f220d1320dcc9ada4b8546d26c2aee35ec498,8da8ed5ee6c5ca0d626cfbbf7b623af98c52efd8..e25a79eac09b6b653d7ec21e4b3986339202603e
@@@ -2,31 -2,44 +2,32 @@@
  #include "openbox/event.h"
  #include "openbox/client.h"
  #include "openbox/focus.h"
+ #include "openbox/screen.h"
  
  typedef struct {
      gboolean here;
  } Options;
  
 -static gpointer setup_func(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node);
 -static void     free_func(gpointer options);
 +static gpointer setup_func(xmlNodePtr node);
  static gboolean run_func(ObActionsData *data, gpointer options);
  
  void action_focus_startup(void)
  {
 -    actions_register("Focus",
 -                     setup_func,
 -                     free_func,
 -                     run_func,
 -                     NULL, NULL);
 +    actions_register("Focus", setup_func, g_free, 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);
  
 -    if ((n = parse_find_node("here", node)))
 -        o->here = parse_bool(doc, n);
 +    if ((n = obt_parse_find_node(node, "here")))
 +        o->here = obt_parse_node_bool(n);
      return o;
  }
  
 -static void free_func(gpointer options)
 -{
 -    Options *o = options;
 -
 -    g_free(o);
 -}
 -
  /* Always return FALSE because its not interactive */
  static gboolean run_func(ObActionsData *data, gpointer options)
  {
@@@ -44,7 -57,7 +45,7 @@@
               data->context != OB_FRAME_CONTEXT_FRAME))
          {
              actions_client_move(data, TRUE);
-             client_activate(data->client, o->here, FALSE, FALSE, TRUE);
+             client_activate(data->client, TRUE, o->here, FALSE, FALSE, TRUE);
              actions_client_move(data, FALSE);
          }
      } else if (data->context == OB_FRAME_CONTEXT_DESKTOP) {
diff --combined openbox/client.c
index 50a0dbeee956fc743e8a0423f75598ed5d4140e6,e3a7d6ecd2ef7bf25dd363ee4106c74abbf57827..184ae171e8d2b50a0fee2f1a64391cd36eb6a81a
  #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>
@@@ -75,6 -76,7 +75,7 @@@ static RrImage *client_default_ico
  static void client_get_all(ObClient *self, gboolean real);
  static void client_get_startup_id(ObClient *self);
  static void client_get_session_ids(ObClient *self);
+ static void client_save_session_ids(ObClient *self);
  static void client_get_area(ObClient *self);
  static void client_get_desktop(ObClient *self);
  static void client_get_state(ObClient *self);
@@@ -184,8 -186,8 +185,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
          (user_time != 0) &&
          /* this checks for focus=false for the window */
          (!settings || settings->focus != 0) &&
-         focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE))
+         focus_valid_target(self, FALSE, FALSE, TRUE, FALSE, FALSE,
+                            settings->focus == 1))
      {
          activate = TRUE;
      }
  
      /* 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) {
          activate = client_can_steal_focus(self, map_time, launch_time);
  
      /* 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);
  
@@@ -525,7 -610,7 +527,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);
@@@ -694,7 -779,7 +696,7 @@@ static gboolean client_can_steal_focus(
      /* This is focus stealing prevention */
      ob_debug_type(OB_DEBUG_FOCUS,
                    "Want to focus new window 0x%x at time %u "
 -                  "launched at %u (last user interaction time %u)\n",
 +                  "launched at %u (last user interaction time %u)",
                    self->window, steal_time, launch_time,
                    event_last_user_time);
  
              ob_debug_type(OB_DEBUG_FOCUS,
                            "Not focusing the window because the user is "
                            "working in another window that is not "
 -                          "its parent\n");
 +                          "its parent");
          }
          /* If the new window is a transient (and its relatives aren't
             focused) */
              steal = FALSE;
              ob_debug_type(OB_DEBUG_FOCUS,
                            "Not focusing the window because it is a "
 -                          "transient, and its relatives aren't focused\n");
 +                          "transient, and its relatives aren't focused");
          }
          /* Don't steal focus from globally active clients.
             I stole this idea from KWin. It seems nice.
              steal = FALSE;
              ob_debug_type(OB_DEBUG_FOCUS,
                            "Not focusing the window because a globally "
 -                          "active client has focus\n");
 +                          "active client has focus");
          }
          /* Don't move focus if it's not going to go to this window
             anyway */
              steal = FALSE;
              ob_debug_type(OB_DEBUG_FOCUS,
                            "Not focusing the window because another window "
 -                          "would get the focus anyway\n");
 +                          "would get the focus anyway");
          }
          /* Don't move focus if the window is not visible on the current
             desktop and none of its relatives are focused */
      if (!steal)
          ob_debug_type(OB_DEBUG_FOCUS,
                        "Focus stealing prevention activated for %s at "
 -                      "time %u (last user interaction time %u)\n",
 +                      "time %u (last user interaction time %u)",
                        self->title, steal_time, event_last_user_time);
      return steal;
  }
@@@ -807,7 -892,7 +809,7 @@@ static ObAppSettings *client_get_settin
              match = FALSE;
  
          if (match) {
 -            ob_debug("Window matching: %s\n", app->name);
 +            ob_debug("Window matching: %s", app->name);
  
              /* copy the settings to our struct, overriding the existing
                 settings if they are not defaults */
@@@ -862,17 -947,17 +864,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;
@@@ -1075,6 -1160,7 +1077,7 @@@ static void client_get_all(ObClient *se
      /* get the session related properties, these can change decorations
         from per-app settings */
      client_get_session_ids(self);
+     client_save_session_ids(self);
  
      /* now we got everything that can affect the decorations */
      if (!real)
  
  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);
  }
  
@@@ -1142,12 -1227,12 +1145,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);
          }
      }
@@@ -1195,32 -1280,32 +1198,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;
          }
  
@@@ -1232,14 -1317,14 +1235,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;
@@@ -1253,22 -1338,22 +1256,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;
@@@ -1403,8 -1488,8 +1406,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];
@@@ -1423,27 -1508,26 +1426,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 */
@@@ -1518,8 -1602,7 +1521,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;
@@@ -1530,7 -1613,7 +1533,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);
  }
  
@@@ -1538,7 -1621,7 +1541,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 */
@@@ -1562,7 -1645,7 +1565,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)
@@@ -1775,38 -1858,38 +1778,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);
@@@ -1830,7 -1913,7 +1833,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)
@@@ -1919,10 -2002,10 +1922,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;
  }
  
@@@ -1993,9 -2076,8 +1996,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;
  
          STRUT_PARTIAL_SET(strut, 0, 0, 0, 0,
                            0, 0, 0, 0, 0, 0, 0, 0);
  
-     if (!STRUT_EQUAL(strut, self->strut)) {
+     if (!PARTIAL_STRUT_EQUAL(strut, self->strut)) {
          self->strut = strut;
  
          /* updating here is pointless while we're being mapped cuz we're not in
@@@ -2056,7 -2138,7 +2059,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,
@@@ -2177,8 -2259,7 +2180,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 */
@@@ -2195,23 -2276,23 +2198,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;
      }
  }
  
 -    PROP_SETS(self->window, ob_role, self->role);
 -    PROP_SETS(self->window, ob_name, self->name);
 -    PROP_SETS(self->window, ob_class, self->class);
+ /*! Save the session IDs as seen by Openbox when the window mapped, so that
+   users can still access them later if the app changes them */
+ static void client_save_session_ids(ObClient *self)
+ {
++    OBT_PROP_SETS(self->window, OB_ROLE, utf8, self->role);
++    OBT_PROP_SETS(self->window, OB_NAME, utf8, self->name);
++    OBT_PROP_SETS(self->window, OB_CLASS, utf8, self->class);
+ }
  static void client_change_wm_state(ObClient *self)
  {
      gulong state[2];
          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);
      }
  }
  
@@@ -2319,30 -2409,30 +2331,30 @@@ static void client_change_state(ObClien
  
      num = 0;
      if (self->modal)
 -        netstate[num++] = prop_atoms.net_wm_state_modal;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MODAL);
      if (self->shaded)
 -        netstate[num++] = prop_atoms.net_wm_state_shaded;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SHADED);
      if (self->iconic)
 -        netstate[num++] = prop_atoms.net_wm_state_hidden;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_HIDDEN);
      if (self->skip_taskbar)
 -        netstate[num++] = prop_atoms.net_wm_state_skip_taskbar;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR);
      if (self->skip_pager)
 -        netstate[num++] = prop_atoms.net_wm_state_skip_pager;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER);
      if (self->fullscreen)
 -        netstate[num++] = prop_atoms.net_wm_state_fullscreen;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN);
      if (self->max_vert)
 -        netstate[num++] = prop_atoms.net_wm_state_maximized_vert;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT);
      if (self->max_horz)
 -        netstate[num++] = prop_atoms.net_wm_state_maximized_horz;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ);
      if (self->above)
 -        netstate[num++] = prop_atoms.net_wm_state_above;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_ABOVE);
      if (self->below)
 -        netstate[num++] = prop_atoms.net_wm_state_below;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_BELOW);
      if (self->demands_attention)
 -        netstate[num++] = prop_atoms.net_wm_state_demands_attention;
 +        netstate[num++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
      if (self->undecorated)
 -        netstate[num++] = prop_atoms.ob_wm_state_undecorated;
 -    PROP_SETA32(self->window, net_wm_state, atom, netstate, num);
 +        netstate[num++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
 +    OBT_PROP_SETA32(self->window, NET_WM_STATE, ATOM, netstate, num);
  
      if (self->frame)
          frame_adjust_state(self->frame);
@@@ -2367,7 -2457,7 +2379,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;
@@@ -2636,7 -2726,7 +2648,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
@@@ -2954,7 -3044,7 +2966,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 */
@@@ -3101,7 -3191,7 +3113,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);
@@@ -3126,7 -3216,7 +3138,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) {
@@@ -3301,12 -3391,12 +3313,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 */
@@@ -3414,14 -3504,14 +3426,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);
      }
  }
  
@@@ -3461,13 -3551,13 +3473,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 -3614,14 +3536,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 -3631,10 +3553,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 -3671,10 +3593,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,47 -3872,47 +3759,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();
  
 -    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 desktop, gboolean raise,
+ void client_activate(ObClient *self, gboolean desktop,
+                      gboolean here, gboolean raise,
                       gboolean unshade, gboolean user)
  {
      if ((user && (desktop ||
                    self->desktop == screen_desktop)) ||
          client_can_steal_focus(self, event_curtime, CurrentTime))
      {
-         client_present(self, FALSE, raise, unshade);
+         client_present(self, here, raise, unshade);
      }
      else
          client_hilite(self, TRUE);
@@@ -4102,15 -4228,15 +4115,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;
      }
@@@ -4122,39 -4248,26 +4135,26 @@@ void client_find_edge_directional(ObCli
                                    gint *dest, gboolean *near_edge)
  {
      GList *it;
-     Rect *a, *mon;
+     Rect *a;
      Rect dock_area;
      gint edge;
+     guint i;
  
      a = screen_area(self->desktop, SCREEN_AREA_ALL_MONITORS,
                      &self->frame->area);
-     mon = screen_area(self->desktop, SCREEN_AREA_ONE_MONITOR,
-                       &self->frame->area);
  
      switch (dir) {
      case OB_DIRECTION_NORTH:
-         if (my_head >= RECT_TOP(*mon) + 1)
-             edge = RECT_TOP(*mon) - 1;
-         else
-             edge = RECT_TOP(*a) - 1;
+         edge = RECT_TOP(*a) - 1;
          break;
      case OB_DIRECTION_SOUTH:
-         if (my_head <= RECT_BOTTOM(*mon) - 1)
-             edge = RECT_BOTTOM(*mon) + 1;
-         else
-             edge = RECT_BOTTOM(*a) + 1;
+         edge = RECT_BOTTOM(*a) + 1;
          break;
      case OB_DIRECTION_EAST:
-         if (my_head <= RECT_RIGHT(*mon) - 1)
-             edge = RECT_RIGHT(*mon) + 1;
-         else
-             edge = RECT_RIGHT(*a) + 1;
+         edge = RECT_RIGHT(*a) + 1;
          break;
      case OB_DIRECTION_WEST:
-         if (my_head >= RECT_LEFT(*mon) + 1)
-             edge = RECT_LEFT(*mon) - 1;
-         else
-             edge = RECT_LEFT(*a) - 1;
+         edge = RECT_LEFT(*a) - 1;
          break;
      default:
          g_assert_not_reached();
      *dest = edge;
      *near_edge = TRUE;
  
+     /* search for edges of monitors */
+     for (i = 0; i < screen_num_monitors; ++i) {
+         Rect *area = screen_area(self->desktop, i, NULL);
+         detect_edge(*area, dir, my_head, my_size, my_edge_start,
+                     my_edge_size, dest, near_edge);
+         g_free(area);
+     }
+     /* search for edges of clients */
      for (it = client_list; it; it = g_list_next(it)) {
          ObClient *cur = it->data;
  
              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);
      detect_edge(dock_area, dir, my_head, my_size, my_edge_start,
                  my_edge_size, dest, near_edge);
      g_free(a);
-     g_free(mon);
  }
  
  void client_find_move_directional(ObClient *self, ObDirection dir,
@@@ -4296,10 -4417,10 +4304,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
index 30cab17b31f70988981f413805760814d98ca5a8,3b1e042cbd5ff593648d091d6c31063fb0d9e35a..8126abe2d2fa76bb9c701d7fb09ff38b6c871b0b
@@@ -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.
@@@ -575,13 -577,16 +575,16 @@@ gboolean client_focus(ObClient *self)
    when the user deliberately selects a window for use.
    @param desktop If true, and the window is on another desktop, it will still
                   be activated.
+   @param here If true, and the window is on another desktop, it will be moved
+               to the current desktop, otherwise the desktop will switch to
+               where the window is.
    @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 desktop, gboolean raise,
-                      gboolean unshade, gboolean user);
+ void client_activate(ObClient *self, gboolean desktop, gboolean here,
+                      gboolean raise, gboolean unshade, gboolean user);
  
  /*! Bring all of its helper windows to its desktop. These are the utility and
    stuff windows. */
@@@ -725,7 -730,7 +728,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/config.c
index 5c0691ca93d01857393b4493c1206f4d0eae67a5,73302dfd01ba6f65265de12b1f03eb4b1c811b63..0d28be2cb8d1568f59559249478fee2e89040c68
  #include "keyboard.h"
  #include "mouse.h"
  #include "actions.h"
 -#include "prop.h"
  #include "translate.h"
  #include "client.h"
  #include "screen.h"
 -#include "parser/parse.h"
  #include "openbox.h"
  #include "gettext.h"
 +#include "obt/paths.h"
  
  gboolean config_focus_new;
  gboolean config_focus_follow;
@@@ -39,11 -40,13 +39,14 @@@ ObPlacePolicy  config_place_policy
  gboolean       config_place_center;
  ObPlaceMonitor config_place_monitor;
  
+ guint          config_primary_monitor_index;
+ ObPlaceMonitor config_primary_monitor;
  StrutPartial config_margins;
  
  gchar   *config_theme;
  gboolean config_theme_keepborder;
 +guint    config_theme_window_list_icon_size;
  
  gchar   *config_title_layout;
  
@@@ -147,9 -150,10 +150,9 @@@ void config_app_settings_copy_non_defau
      }
  }
  
 -static void config_parse_gravity_coord(xmlDocPtr doc, xmlNodePtr node,
 -                                       GravityCoord *c)
 +static void config_parse_gravity_coord(xmlNodePtr node, GravityCoord *c)
  {
 -    gchar *s = parse_string(doc, node);
 +    gchar *s = obt_parse_node_string(node);
      if (!g_ascii_strcasecmp(s, "center"))
          c->center = TRUE;
      else {
     the monitor, so <position><x>center</x></position><monitor>2</monitor>
     will center the window on the second monitor.
  */
 -static void parse_per_app_settings(ObParseInst *inst, xmlDocPtr doc,
 -                                   xmlNodePtr node, gpointer data)
 +static void parse_per_app_settings(xmlNodePtr node, gpointer d)
  {
 -    xmlNodePtr app = parse_find_node("application", node->children);
 +    xmlNodePtr app = obt_parse_find_node(node->children, "application");
      gchar *name = NULL, *class = NULL, *role = NULL, *type = NULL;
      gboolean name_set, class_set, type_set;
      gboolean x_pos_given;
  
      while (app) {
 -        name_set = class_set = type_set = x_pos_given = FALSE;
 +        x_pos_given = FALSE;
  
 -        class_set = parse_attr_string("class", app, &class);
 -        name_set = parse_attr_string("name", app, &name);
 -        type_set = parse_attr_string("type", app, &type);
 +        class_set = obt_parse_attr_string(app, "class", &class);
 +        name_set = obt_parse_attr_string(app, "name", &name);
 +        type_set = obt_parse_attr_string(app, "type", &type);
          if (class_set || name_set) {
              xmlNodePtr n, c;
              ObAppSettings *settings = config_create_app_settings();;
                      settings->type = OB_CLIENT_TYPE_DESKTOP;
              }
  
 -            if (parse_attr_string("role", app, &role))
 +            if (obt_parse_attr_string(app, "role", &role))
                  settings->role = g_pattern_spec_new(role);
  
 -            if ((n = parse_find_node("decor", app->children)))
 -                if (!parse_contains("default", doc, n))
 -                    settings->decor = parse_bool(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "decor")))
 +                if (!obt_parse_node_contains(n, "default"))
 +                    settings->decor = obt_parse_node_bool(n);
  
 -            if ((n = parse_find_node("shade", app->children)))
 -                if (!parse_contains("default", doc, n))
 -                    settings->shade = parse_bool(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "shade")))
 +                if (!obt_parse_node_contains(n, "default"))
 +                    settings->shade = obt_parse_node_bool(n);
  
 -            if ((n = parse_find_node("position", app->children))) {
 -                if ((c = parse_find_node("x", n->children)))
 -                    if (!parse_contains("default", doc, c)) {
 -                        config_parse_gravity_coord(doc, c,
 -                                                   &settings->position.x);
 +            if ((n = obt_parse_find_node(app->children, "position"))) {
 +                if ((c = obt_parse_find_node(n->children, "x")))
 +                    if (!obt_parse_node_contains(c, "default")) {
 +                        config_parse_gravity_coord(c, &settings->position.x);
                          x_pos_given = TRUE;
                      }
  
 -                if (x_pos_given && (c = parse_find_node("y", n->children)))
 -                    if (!parse_contains("default", doc, c)) {
 -                        config_parse_gravity_coord(doc, c,
 -                                                   &settings->position.y);
 +                if (x_pos_given && (c = obt_parse_find_node(n->children, "y")))
 +                    if (!obt_parse_node_contains(c, "default")) {
 +                        config_parse_gravity_coord(c, &settings->position.y);
                          settings->pos_given = TRUE;
                      }
  
                  if (settings->pos_given &&
 -                    (c = parse_find_node("monitor", n->children)))
 -                    if (!parse_contains("default", doc, c)) {
 -                        gchar *s = parse_string(doc, c);
 +                    (c = obt_parse_find_node(n->children, "monitor")))
 +                    if (!obt_parse_node_contains(c, "default")) {
 +                        gchar *s = obt_parse_node_string(c);
                          if (!g_ascii_strcasecmp(s, "mouse"))
                              settings->monitor = 0;
                          else
 -                            settings->monitor = parse_int(doc, c);
 +                            settings->monitor = obt_parse_node_int(c);
                          g_free(s);
                      }
  
 -                parse_attr_bool("force", n, &settings->pos_force);
 +                obt_parse_attr_bool(n, "force", &settings->pos_force);
              }
  
 -            if ((n = parse_find_node("focus", app->children)))
 -                if (!parse_contains("default", doc, n))
 -                    settings->focus = parse_bool(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "focus")))
 +                if (!obt_parse_node_contains(n, "default"))
 +                    settings->focus = obt_parse_node_bool(n);
  
 -            if ((n = parse_find_node("desktop", app->children))) {
 -                if (!parse_contains("default", doc, n)) {
 -                    gchar *s = parse_string(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "desktop"))) {
 +                if (!obt_parse_node_contains(n, "default")) {
 +                    gchar *s = obt_parse_node_string(n);
                      if (!g_ascii_strcasecmp(s, "all"))
                          settings->desktop = DESKTOP_ALL;
                      else {
 -                        gint i = parse_int(doc, n);
 +                        gint i = obt_parse_node_int(n);
                          if (i > 0)
                              settings->desktop = i;
                      }
                  }
              }
  
 -            if ((n = parse_find_node("layer", app->children)))
 -                if (!parse_contains("default", doc, n)) {
 -                    gchar *s = parse_string(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "layer")))
 +                if (!obt_parse_node_contains(n, "default")) {
 +                    gchar *s = obt_parse_node_string(n);
                      if (!g_ascii_strcasecmp(s, "above"))
                          settings->layer = 1;
                      else if (!g_ascii_strcasecmp(s, "below"))
                      g_free(s);
                  }
  
 -            if ((n = parse_find_node("iconic", app->children)))
 -                if (!parse_contains("default", doc, n))
 -                    settings->iconic = parse_bool(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "iconic")))
 +                if (!obt_parse_node_contains(n, "default"))
 +                    settings->iconic = obt_parse_node_bool(n);
  
 -            if ((n = parse_find_node("skip_pager", app->children)))
 -                if (!parse_contains("default", doc, n))
 -                    settings->skip_pager = parse_bool(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "skip_pager")))
 +                if (!obt_parse_node_contains(n, "default"))
 +                    settings->skip_pager = obt_parse_node_bool(n);
  
 -            if ((n = parse_find_node("skip_taskbar", app->children)))
 -                if (!parse_contains("default", doc, n))
 -                    settings->skip_taskbar = parse_bool(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "skip_taskbar")))
 +                if (!obt_parse_node_contains(n, "default"))
 +                    settings->skip_taskbar = obt_parse_node_bool(n);
  
 -            if ((n = parse_find_node("fullscreen", app->children)))
 -                if (!parse_contains("default", doc, n))
 -                    settings->fullscreen = parse_bool(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "fullscreen")))
 +                if (!obt_parse_node_contains(n, "default"))
 +                    settings->fullscreen = obt_parse_node_bool(n);
  
 -            if ((n = parse_find_node("maximized", app->children)))
 -                if (!parse_contains("default", doc, n)) {
 -                    gchar *s = parse_string(doc, n);
 +            if ((n = obt_parse_find_node(app->children, "maximized")))
 +                if (!obt_parse_node_contains(n, "default")) {
 +                    gchar *s = obt_parse_node_string(n);
                      if (!g_ascii_strcasecmp(s, "horizontal")) {
                          settings->max_horz = TRUE;
                          settings->max_vert = FALSE;
                          settings->max_vert = TRUE;
                      } else
                          settings->max_horz = settings->max_vert =
 -                            parse_bool(doc, n);
 +                            obt_parse_node_bool(n);
                      g_free(s);
                  }
  
              name = class = role = NULL;
          }
  
 -        app = parse_find_node("application", app->next);
 +        app = obt_parse_find_node(app->next, "application");
      }
  }
  
  
  */
  
 -static void parse_key(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                      GList *keylist)
 +static void parse_key(xmlNodePtr node, GList *keylist)
  {
      gchar *key;
      xmlNodePtr n;
      gboolean is_chroot = FALSE;
  
 -    if (!parse_attr_string("key", node, &key))
 +    if (!obt_parse_attr_string(node, "key", &key))
          return;
  
 -    parse_attr_bool("chroot", node, &is_chroot);
 +    obt_parse_attr_bool(node, "chroot", &is_chroot);
  
      keylist = g_list_append(keylist, key);
  
 -    if ((n = parse_find_node("keybind", node->children))) {
 +    if ((n = obt_parse_find_node(node->children, "keybind"))) {
          while (n) {
 -            parse_key(i, doc, n, keylist);
 -            n = parse_find_node("keybind", n->next);
 +            parse_key(n, keylist);
 +            n = obt_parse_find_node(n->next, "keybind");
          }
      }
 -    else if ((n = parse_find_node("action", node->children))) {
 +    else if ((n = obt_parse_find_node(node->children, "action"))) {
          while (n) {
              ObActionsAct *action;
  
 -            action = actions_parse(i, doc, n);
 +            action = actions_parse(n);
              if (action)
                  keyboard_bind(keylist, action);
 -            n = parse_find_node("action", n->next);
 +            n = obt_parse_find_node(n->next, "action");
          }
      }
  
      keylist = g_list_delete_link(keylist, g_list_last(keylist));
  }
  
 -static void parse_keyboard(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                           gpointer data)
 +static void parse_keyboard(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
      gchar *key;
  
      keyboard_unbind_all();
  
 -    if ((n = parse_find_node("chainQuitKey", node->children))) {
 -        key = parse_string(doc, n);
 +    if ((n = obt_parse_find_node(node->children, "chainQuitKey"))) {
 +        key = obt_parse_node_string(n);
          translate_key(key, &config_keyboard_reset_state,
                        &config_keyboard_reset_keycode);
          g_free(key);
      }
  
 -    if ((n = parse_find_node("keybind", node->children)))
 +    if ((n = obt_parse_find_node(node->children, "keybind")))
          while (n) {
 -            parse_key(i, doc, n, NULL);
 -            n = parse_find_node("keybind", n->next);
 +            parse_key(n, NULL);
 +            n = obt_parse_find_node(n->next, "keybind");
          }
  }
  
  
  */
  
 -static void parse_mouse(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                        gpointer data)
 +static void parse_mouse(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n, nbut, nact;
      gchar *buttonstr;
  
      node = node->children;
  
 -    if ((n = parse_find_node("dragThreshold", node)))
 -        config_mouse_threshold = parse_int(doc, n);
 -    if ((n = parse_find_node("doubleClickTime", node)))
 -        config_mouse_dclicktime = parse_int(doc, n);
 -    if ((n = parse_find_node("screenEdgeWarpTime", node))) {
 -        config_mouse_screenedgetime = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node, "dragThreshold")))
 +        config_mouse_threshold = obt_parse_node_int(n);
 +    if ((n = obt_parse_find_node(node, "doubleClickTime")))
 +        config_mouse_dclicktime = obt_parse_node_int(n);
-     if ((n = obt_parse_find_node(node, "screenEdgeWarpTime")))
++    if ((n = obt_parse_find_node(node, "screenEdgeWarpTime"))) {
 +        config_mouse_screenedgetime = obt_parse_node_int(n);
+         /* minimum value of 25 for this property, when it is 1 and you hit the
+            edge it basically never stops */
+         if (config_mouse_screenedgetime && config_mouse_screenedgetime < 25)
+             config_mouse_screenedgetime = 25;
+     }
  
 -    n = parse_find_node("context", node);
 +    n = obt_parse_find_node(node, "context");
      while (n) {
 -        if (!parse_attr_string("name", n, &contextstr))
 +        if (!obt_parse_attr_string(n, "name", &contextstr))
              goto next_n;
 -        nbut = parse_find_node("mousebind", n->children);
 +        nbut = obt_parse_find_node(n->children, "mousebind");
          while (nbut) {
 -            if (!parse_attr_string("button", nbut, &buttonstr))
 +            if (!obt_parse_attr_string(nbut, "button", &buttonstr))
                  goto next_nbut;
 -            if (parse_attr_contains("press", nbut, "action")) {
 +            if (obt_parse_attr_contains(nbut, "action", "press")) {
                  mact = OB_MOUSE_ACTION_PRESS;
 -            } else if (parse_attr_contains("release", nbut, "action")) {
 +            } else if (obt_parse_attr_contains(nbut, "action", "release")) {
                  mact = OB_MOUSE_ACTION_RELEASE;
 -            } else if (parse_attr_contains("click", nbut, "action")) {
 +            } else if (obt_parse_attr_contains(nbut, "action", "click")) {
                  mact = OB_MOUSE_ACTION_CLICK;
 -            } else if (parse_attr_contains("doubleclick", nbut,"action")) {
 +            } else if (obt_parse_attr_contains(nbut, "action","doubleclick")) {
                  mact = OB_MOUSE_ACTION_DOUBLE_CLICK;
 -            } else if (parse_attr_contains("drag", nbut, "action")) {
 +            } else if (obt_parse_attr_contains(nbut, "action", "drag")) {
                  mact = OB_MOUSE_ACTION_MOTION;
              } else
                  goto next_nbut;
 -            nact = parse_find_node("action", nbut->children);
 +            nact = obt_parse_find_node(nbut->children, "action");
              while (nact) {
                  ObActionsAct *action;
  
 -                if ((action = actions_parse(i, doc, nact)))
 +                if ((action = actions_parse(nact)))
                      mouse_bind(buttonstr, contextstr, mact, action);
 -                nact = parse_find_node("action", nact->next);
 +                nact = obt_parse_find_node(nact->next, "action");
              }
              g_free(buttonstr);
          next_nbut:
 -            nbut = parse_find_node("mousebind", nbut->next);
 +            nbut = obt_parse_find_node(nbut->next, "mousebind");
          }
          g_free(contextstr);
      next_n:
 -        n = parse_find_node("context", n->next);
 +        n = obt_parse_find_node(n->next, "context");
      }
  }
  
 -static void parse_focus(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                        gpointer data)
 +static void parse_focus(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
  
 -    if ((n = parse_find_node("focusNew", node)))
 -        config_focus_new = parse_bool(doc, n);
 -    if ((n = parse_find_node("followMouse", node)))
 -        config_focus_follow = parse_bool(doc, n);
 -    if ((n = parse_find_node("focusDelay", node)))
 -        config_focus_delay = parse_int(doc, n);
 -    if ((n = parse_find_node("raiseOnFocus", node)))
 -        config_focus_raise = parse_bool(doc, n);
 -    if ((n = parse_find_node("focusLast", node)))
 -        config_focus_last = parse_bool(doc, n);
 -    if ((n = parse_find_node("underMouse", node)))
 -        config_focus_under_mouse = parse_bool(doc, n);
 +    if ((n = obt_parse_find_node(node, "focusNew")))
 +        config_focus_new = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "followMouse")))
 +        config_focus_follow = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "focusDelay")))
 +        config_focus_delay = obt_parse_node_int(n);
 +    if ((n = obt_parse_find_node(node, "raiseOnFocus")))
 +        config_focus_raise = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "focusLast")))
 +        config_focus_last = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "underMouse")))
 +        config_focus_under_mouse = obt_parse_node_bool(n);
  }
  
 -static void parse_placement(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                            gpointer data)
 +static void parse_placement(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
  
 -    if ((n = parse_find_node("policy", node)))
 -        if (parse_contains("UnderMouse", doc, n))
 +    if ((n = obt_parse_find_node(node, "policy")))
 +        if (obt_parse_node_contains(n, "UnderMouse"))
              config_place_policy = OB_PLACE_POLICY_MOUSE;
 -    if ((n = parse_find_node("center", node)))
 -        config_place_center = parse_bool(doc, n);
 -    if ((n = parse_find_node("monitor", node))) {
 -        if (parse_contains("active", doc, n))
 +    if ((n = obt_parse_find_node(node, "center")))
 +        config_place_center = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "monitor"))) {
 +        if (obt_parse_node_contains(n, "active"))
              config_place_monitor = OB_PLACE_MONITOR_ACTIVE;
 -        else if (parse_contains("mouse", doc, n))
 +        else if (obt_parse_node_contains(n, "mouse"))
              config_place_monitor = OB_PLACE_MONITOR_MOUSE;
      }
 -    if ((n = parse_find_node("primaryMonitor", node))) {
 -        config_primary_monitor_index = parse_int(doc, n);
++    if ((n = obt_parse_find_node(node, "primaryMonitor"))) {
++        config_primary_monitor_index = obt_parse_node_int(n);
+         if (!config_primary_monitor_index) {
 -            if (parse_contains("mouse", doc, n))
++            if (obt_parse_node_contains(n, "mouse"))
+                 config_primary_monitor = OB_PLACE_MONITOR_MOUSE;
+         }
+     }
  }
  
 -static void parse_margins(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                          gpointer data)
 +static void parse_margins(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
  
 -    if ((n = parse_find_node("top", node)))
 -        config_margins.top = MAX(0, parse_int(doc, n));
 -    if ((n = parse_find_node("left", node)))
 -        config_margins.left = MAX(0, parse_int(doc, n));
 -    if ((n = parse_find_node("right", node)))
 -        config_margins.right = MAX(0, parse_int(doc, n));
 -    if ((n = parse_find_node("bottom", node)))
 -        config_margins.bottom = MAX(0, parse_int(doc, n));
 +    if ((n = obt_parse_find_node(node, "top")))
 +        config_margins.top = MAX(0, obt_parse_node_int(n));
 +    if ((n = obt_parse_find_node(node, "left")))
 +        config_margins.left = MAX(0, obt_parse_node_int(n));
 +    if ((n = obt_parse_find_node(node, "right")))
 +        config_margins.right = MAX(0, obt_parse_node_int(n));
 +    if ((n = obt_parse_find_node(node, "bottom")))
 +        config_margins.bottom = MAX(0, obt_parse_node_int(n));
  }
  
 -static void parse_theme(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                        gpointer data)
 +static void parse_theme(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
  
 -    if ((n = parse_find_node("name", node))) {
 +    if ((n = obt_parse_find_node(node, "name"))) {
          gchar *c;
  
          g_free(config_theme);
 -        c = parse_string(doc, n);
 -        config_theme = parse_expand_tilde(c);
 +        c = obt_parse_node_string(n);
 +        config_theme = obt_paths_expand_tilde(c);
          g_free(c);
      }
 -    if ((n = parse_find_node("titleLayout", node))) {
 +    if ((n = obt_parse_find_node(node, "titleLayout"))) {
          gchar *c, *d;
  
          g_free(config_title_layout);
 -        config_title_layout = parse_string(doc, n);
 +        config_title_layout = obt_parse_node_string(n);
  
          /* replace duplicates with spaces */
          for (c = config_title_layout; *c != '\0'; ++c)
              for (d = c+1; *d != '\0'; ++d)
                  if (*c == *d) *d = ' ';
      }
 -    if ((n = parse_find_node("keepBorder", node)))
 -        config_theme_keepborder = parse_bool(doc, n);
 -    if ((n = parse_find_node("animateIconify", node)))
 -        config_animate_iconify = parse_bool(doc, n);
 +    if ((n = obt_parse_find_node(node, "keepBorder")))
 +        config_theme_keepborder = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "animateIconify")))
 +        config_animate_iconify = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "windowListIconSize"))) {
 +        config_theme_window_list_icon_size = obt_parse_node_int(n);
 +        if (config_theme_window_list_icon_size < 16)
 +            config_theme_window_list_icon_size = 16;
 +        else if (config_theme_window_list_icon_size > 96)
 +            config_theme_window_list_icon_size = 96;
 +    }
  
 -    n = parse_find_node("font", node);
 +    n = obt_parse_find_node(node, "font");
      while (n) {
          xmlNodePtr   fnode;
          RrFont     **font;
          RrFontWeight weight = RrDefaultFontWeight;
          RrFontSlant  slant = RrDefaultFontSlant;
  
 -        if (parse_attr_contains("ActiveWindow", n, "place"))
 +        if (obt_parse_attr_contains(n, "place", "ActiveWindow"))
              font = &config_font_activewindow;
 -        else if (parse_attr_contains("InactiveWindow", n, "place"))
 +        else if (obt_parse_attr_contains(n, "place", "InactiveWindow"))
              font = &config_font_inactivewindow;
 -        else if (parse_attr_contains("MenuHeader", n, "place"))
 +        else if (obt_parse_attr_contains(n, "place", "MenuHeader"))
              font = &config_font_menutitle;
 -        else if (parse_attr_contains("MenuItem", n, "place"))
 +        else if (obt_parse_attr_contains(n, "place", "MenuItem"))
              font = &config_font_menuitem;
 -        else if (parse_attr_contains("OnScreenDisplay", n, "place"))
 +        else if (obt_parse_attr_contains(n, "place", "OnScreenDisplay"))
              font = &config_font_osd;
          else
              goto next_font;
  
 -        if ((fnode = parse_find_node("name", n->children))) {
 +        if ((fnode = obt_parse_find_node(n->children, "name"))) {
              g_free(name);
 -            name = parse_string(doc, fnode);
 +            name = obt_parse_node_string(fnode);
          }
 -        if ((fnode = parse_find_node("size", n->children))) {
 -            int s = parse_int(doc, fnode);
 +        if ((fnode = obt_parse_find_node(n->children, "size"))) {
 +            int s = obt_parse_node_int(fnode);
              if (s > 0) size = s;
          }
 -        if ((fnode = parse_find_node("weight", n->children))) {
 -            gchar *w = parse_string(doc, fnode);
 +        if ((fnode = obt_parse_find_node(n->children, "weight"))) {
 +            gchar *w = obt_parse_node_string(fnode);
              if (!g_ascii_strcasecmp(w, "Bold"))
                  weight = RR_FONTWEIGHT_BOLD;
              g_free(w);
          }
 -        if ((fnode = parse_find_node("slant", n->children))) {
 -            gchar *s = parse_string(doc, fnode);
 +        if ((fnode = obt_parse_find_node(n->children, "slant"))) {
 +            gchar *s = obt_parse_node_string(fnode);
              if (!g_ascii_strcasecmp(s, "Italic"))
                  slant = RR_FONTSLANT_ITALIC;
              if (!g_ascii_strcasecmp(s, "Oblique"))
          *font = RrFontOpen(ob_rr_inst, name, size, weight, slant);
          g_free(name);
      next_font:
 -        n = parse_find_node("font", n->next);
 +        n = obt_parse_find_node(n->next, "font");
      }
  }
  
 -static void parse_desktops(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                           gpointer data)
 +static void parse_desktops(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
  
 -    if ((n = parse_find_node("number", node))) {
 -        gint d = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node, "number"))) {
 +        gint d = obt_parse_node_int(n);
          if (d > 0)
              config_desktops_num = (unsigned) d;
      }
 -    if ((n = parse_find_node("firstdesk", node))) {
 -        gint d = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node, "firstdesk"))) {
 +        gint d = obt_parse_node_int(n);
          if (d > 0)
              config_screen_firstdesk = (unsigned) d;
      }
 -    if ((n = parse_find_node("names", node))) {
 +    if ((n = obt_parse_find_node(node, "names"))) {
          GSList *it;
          xmlNodePtr nname;
  
          g_slist_free(config_desktops_names);
          config_desktops_names = NULL;
  
 -        nname = parse_find_node("name", n->children);
 +        nname = obt_parse_find_node(n->children, "name");
          while (nname) {
 -            config_desktops_names = g_slist_append(config_desktops_names,
 -                                                   parse_string(doc, nname));
 -            nname = parse_find_node("name", nname->next);
 +            config_desktops_names =
 +                g_slist_append(config_desktops_names,
 +                               obt_parse_node_string(nname));
 +            nname = obt_parse_find_node(nname->next, "name");
          }
      }
 -    if ((n = parse_find_node("popupTime", node)))
 -        config_desktop_popup_time = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node, "popupTime")))
 +        config_desktop_popup_time = obt_parse_node_int(n);
  }
  
 -static void parse_resize(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                         gpointer data)
 +static void parse_resize(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
  
 -    if ((n = parse_find_node("drawContents", node)))
 -        config_resize_redraw = parse_bool(doc, n);
 -    if ((n = parse_find_node("popupShow", node))) {
 -        config_resize_popup_show = parse_int(doc, n);
 -        if (parse_contains("Always", doc, n))
 +    if ((n = obt_parse_find_node(node, "drawContents")))
 +        config_resize_redraw = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "popupShow"))) {
 +        config_resize_popup_show = obt_parse_node_int(n);
 +        if (obt_parse_node_contains(n, "Always"))
              config_resize_popup_show = 2;
 -        else if (parse_contains("Never", doc, n))
 +        else if (obt_parse_node_contains(n, "Never"))
              config_resize_popup_show = 0;
 -        else if (parse_contains("Nonpixel", doc, n))
 +        else if (obt_parse_node_contains(n, "Nonpixel"))
              config_resize_popup_show = 1;
      }
 -    if ((n = parse_find_node("popupPosition", node))) {
 -        if (parse_contains("Top", doc, n))
 +    if ((n = obt_parse_find_node(node, "popupPosition"))) {
 +        if (obt_parse_node_contains(n, "Top"))
              config_resize_popup_pos = OB_RESIZE_POS_TOP;
 -        else if (parse_contains("Center", doc, n))
 +        else if (obt_parse_node_contains(n, "Center"))
              config_resize_popup_pos = OB_RESIZE_POS_CENTER;
 -        else if (parse_contains("Fixed", doc, n)) {
 +        else if (obt_parse_node_contains(n, "Fixed")) {
              config_resize_popup_pos = OB_RESIZE_POS_FIXED;
  
 -            if ((n = parse_find_node("popupFixedPosition", node))) {
 +            if ((n = obt_parse_find_node(node, "popupFixedPosition"))) {
                  xmlNodePtr n2;
  
 -                if ((n2 = parse_find_node("x", n->children)))
 -                    config_parse_gravity_coord(doc, n2,
 +                if ((n2 = obt_parse_find_node(n->children, "x")))
 +                    config_parse_gravity_coord(n2,
                                                 &config_resize_popup_fixed.x);
 -                if ((n2 = parse_find_node("y", n->children)))
 -                    config_parse_gravity_coord(doc, n2,
 +                if ((n2 = obt_parse_find_node(n->children, "y")))
 +                    config_parse_gravity_coord(n2,
                                                 &config_resize_popup_fixed.y);
  
                  config_resize_popup_fixed.x.pos =
      }
  }
  
 -static void parse_dock(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                       gpointer data)
 +static void parse_dock(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
  
 -    if ((n = parse_find_node("position", node))) {
 -        if (parse_contains("TopLeft", doc, n))
 +    if ((n = obt_parse_find_node(node, "position"))) {
 +        if (obt_parse_node_contains(n, "TopLeft"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_NORTHWEST;
 -        else if (parse_contains("Top", doc, n))
 +        else if (obt_parse_node_contains(n, "Top"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_NORTH;
 -        else if (parse_contains("TopRight", doc, n))
 +        else if (obt_parse_node_contains(n, "TopRight"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_NORTHEAST;
 -        else if (parse_contains("Right", doc, n))
 +        else if (obt_parse_node_contains(n, "Right"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_EAST;
 -        else if (parse_contains("BottomRight", doc, n))
 +        else if (obt_parse_node_contains(n, "BottomRight"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_SOUTHEAST;
 -        else if (parse_contains("Bottom", doc, n))
 +        else if (obt_parse_node_contains(n, "Bottom"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_SOUTH;
 -        else if (parse_contains("BottomLeft", doc, n))
 +        else if (obt_parse_node_contains(n, "BottomLeft"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_SOUTHWEST;
 -        else if (parse_contains("Left", doc, n))
 +        else if (obt_parse_node_contains(n, "Left"))
              config_dock_floating = FALSE,
              config_dock_pos = OB_DIRECTION_WEST;
 -        else if (parse_contains("Floating", doc, n))
 +        else if (obt_parse_node_contains(n, "Floating"))
              config_dock_floating = TRUE;
      }
      if (config_dock_floating) {
 -        if ((n = parse_find_node("floatingX", node)))
 -            config_dock_x = parse_int(doc, n);
 -        if ((n = parse_find_node("floatingY", node)))
 -            config_dock_y = parse_int(doc, n);
 +        if ((n = obt_parse_find_node(node, "floatingX")))
 +            config_dock_x = obt_parse_node_int(n);
 +        if ((n = obt_parse_find_node(node, "floatingY")))
 +            config_dock_y = obt_parse_node_int(n);
      } else {
 -        if ((n = parse_find_node("noStrut", node)))
 -            config_dock_nostrut = parse_bool(doc, n);
 +        if ((n = obt_parse_find_node(node, "noStrut")))
 +            config_dock_nostrut = obt_parse_node_bool(n);
      }
 -    if ((n = parse_find_node("stacking", node))) {
 -        if (parse_contains("above", doc, n))
 -            config_dock_layer = OB_STACKING_LAYER_ABOVE;
 -        else if (parse_contains("normal", doc, n))
 +    if ((n = obt_parse_find_node(node, "stacking"))) {
 +        if (obt_parse_node_contains(n, "normal"))
              config_dock_layer = OB_STACKING_LAYER_NORMAL;
 -        else if (parse_contains("below", doc, n))
 +        else if (obt_parse_node_contains(n, "below"))
              config_dock_layer = OB_STACKING_LAYER_BELOW;
 +        else if (obt_parse_node_contains(n, "above"))
 +            config_dock_layer = OB_STACKING_LAYER_ABOVE;
      }
 -    if ((n = parse_find_node("direction", node))) {
 -        if (parse_contains("horizontal", doc, n))
 +    if ((n = obt_parse_find_node(node, "direction"))) {
 +        if (obt_parse_node_contains(n, "horizontal"))
              config_dock_orient = OB_ORIENTATION_HORZ;
 -        else if (parse_contains("vertical", doc, n))
 +        else if (obt_parse_node_contains(n, "vertical"))
              config_dock_orient = OB_ORIENTATION_VERT;
      }
 -    if ((n = parse_find_node("autoHide", node)))
 -        config_dock_hide = parse_bool(doc, n);
 -    if ((n = parse_find_node("hideDelay", node)))
 -        config_dock_hide_delay = parse_int(doc, n);
 -    if ((n = parse_find_node("showDelay", node)))
 -        config_dock_show_delay = parse_int(doc, n);
 -    if ((n = parse_find_node("moveButton", node))) {
 -        gchar *str = parse_string(doc, n);
 +    if ((n = obt_parse_find_node(node, "autoHide")))
 +        config_dock_hide = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "hideDelay")))
 +        config_dock_hide_delay = obt_parse_node_int(n);
 +    if ((n = obt_parse_find_node(node, "showDelay")))
 +        config_dock_show_delay = obt_parse_node_int(n);
 +    if ((n = obt_parse_find_node(node, "moveButton"))) {
 +        gchar *str = obt_parse_node_string(n);
          guint b, s;
          if (translate_button(str, &s, &b)) {
              config_dock_app_move_button = b;
      }
  }
  
 -static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                       gpointer data)
 +static void parse_menu(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
      node = node->children;
  
 -    if ((n = parse_find_node("hideDelay", node)))
 -        config_menu_hide_delay = parse_int(doc, n);
 -    if ((n = parse_find_node("middle", node)))
 -        config_menu_middle = parse_bool(doc, n);
 -    if ((n = parse_find_node("submenuShowDelay", node)))
 -        config_submenu_show_delay = parse_int(doc, n);
 -    if ((n = parse_find_node("applicationIcons", node)))
 -        config_menu_client_list_icons = parse_bool(doc, n);
 -    if ((n = parse_find_node("manageDesktops", node)))
 -        config_menu_manage_desktops = parse_bool(doc, n);
 -
 -    while ((node = parse_find_node("file", node))) {
 -            gchar *c = parse_string(doc, node);
 +    if ((n = obt_parse_find_node(node, "hideDelay")))
 +        config_menu_hide_delay = obt_parse_node_int(n);
 +    if ((n = obt_parse_find_node(node, "middle")))
 +        config_menu_middle = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "submenuShowDelay")))
 +        config_submenu_show_delay = obt_parse_node_int(n);
 +    if ((n = obt_parse_find_node(node, "applicationIcons")))
 +        config_menu_client_list_icons = obt_parse_node_bool(n);
 +    if ((n = obt_parse_find_node(node, "manageDesktops")))
 +        config_menu_manage_desktops = obt_parse_node_bool(n);
 +
 +    while ((node = obt_parse_find_node(node, "file"))) {
 +            gchar *c = obt_parse_node_string(node);
              config_menu_files = g_slist_append(config_menu_files,
 -                                               parse_expand_tilde(c));
 +                                               obt_paths_expand_tilde(c));
              g_free(c);
              node = node->next;
      }
  }
  
 -static void parse_resistance(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
 -                             gpointer data)
 +static void parse_resistance(xmlNodePtr node, gpointer d)
  {
      xmlNodePtr n;
  
      node = node->children;
 -    if ((n = parse_find_node("strength", node)))
 -        config_resist_win = parse_int(doc, n);
 -    if ((n = parse_find_node("screen_edge_strength", node)))
 -        config_resist_edge = parse_int(doc, n);
 +    if ((n = obt_parse_find_node(node, "strength")))
 +        config_resist_win = obt_parse_node_int(n);
 +    if ((n = obt_parse_find_node(node, "screen_edge_strength")))
 +        config_resist_edge = obt_parse_node_int(n);
  }
  
  typedef struct
@@@ -903,7 -926,7 +918,7 @@@ static void bind_default_mouse(void
                     actions_parse_string(it->actname));
  }
  
 -void config_startup(ObParseInst *i)
 +void config_startup(ObtParseInst *i)
  {
      config_focus_new = TRUE;
      config_focus_follow = FALSE;
      config_focus_last = TRUE;
      config_focus_under_mouse = FALSE;
  
 -    parse_register(i, "focus", parse_focus, NULL);
 +    obt_parse_register(i, "focus", parse_focus, NULL);
  
      config_place_policy = OB_PLACE_POLICY_SMART;
      config_place_center = TRUE;
      config_place_monitor = OB_PLACE_MONITOR_ANY;
  
 -    parse_register(i, "placement", parse_placement, NULL);
+     config_primary_monitor_index = 1;
+     config_primary_monitor = OB_PLACE_MONITOR_ACTIVE;
 +    obt_parse_register(i, "placement", parse_placement, NULL);
  
      STRUT_PARTIAL_SET(config_margins, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  
 -    parse_register(i, "margins", parse_margins, NULL);
 +    obt_parse_register(i, "margins", parse_margins, NULL);
  
      config_theme = NULL;
  
      config_animate_iconify = TRUE;
      config_title_layout = g_strdup("NLIMC");
      config_theme_keepborder = TRUE;
 +    config_theme_window_list_icon_size = 36;
  
      config_font_activewindow = NULL;
      config_font_inactivewindow = NULL;
      config_font_menuitem = NULL;
      config_font_menutitle = NULL;
  
 -    parse_register(i, "theme", parse_theme, NULL);
 +    obt_parse_register(i, "theme", parse_theme, NULL);
  
      config_desktops_num = 4;
      config_screen_firstdesk = 1;
      config_desktops_names = NULL;
      config_desktop_popup_time = 875;
  
 -    parse_register(i, "desktops", parse_desktops, NULL);
 +    obt_parse_register(i, "desktops", parse_desktops, NULL);
  
      config_resize_redraw = TRUE;
      config_resize_popup_show = 1; /* nonpixel increments */
      GRAVITY_COORD_SET(config_resize_popup_fixed.x, 0, FALSE, FALSE);
      GRAVITY_COORD_SET(config_resize_popup_fixed.y, 0, FALSE, FALSE);
  
 -    parse_register(i, "resize", parse_resize, NULL);
 +    obt_parse_register(i, "resize", parse_resize, NULL);
  
      config_dock_layer = OB_STACKING_LAYER_ABOVE;
      config_dock_pos = OB_DIRECTION_NORTHEAST;
      config_dock_app_move_button = 2; /* middle */
      config_dock_app_move_modifiers = 0;
  
 -    parse_register(i, "dock", parse_dock, NULL);
 +    obt_parse_register(i, "dock", parse_dock, NULL);
  
      translate_key("C-g", &config_keyboard_reset_state,
                    &config_keyboard_reset_keycode);
  
      bind_default_keyboard();
  
 -    parse_register(i, "keyboard", parse_keyboard, NULL);
 +    obt_parse_register(i, "keyboard", parse_keyboard, NULL);
  
      config_mouse_threshold = 8;
      config_mouse_dclicktime = 200;
  
      bind_default_mouse();
  
 -    parse_register(i, "mouse", parse_mouse, NULL);
 +    obt_parse_register(i, "mouse", parse_mouse, NULL);
  
      config_resist_win = 10;
      config_resist_edge = 20;
  
 -    parse_register(i, "resistance", parse_resistance, NULL);
 +    obt_parse_register(i, "resistance", parse_resistance, NULL);
  
      config_menu_hide_delay = 250;
      config_menu_middle = FALSE;
      config_menu_manage_desktops = TRUE;
      config_menu_files = NULL;
  
 -    parse_register(i, "menu", parse_menu, NULL);
 +    obt_parse_register(i, "menu", parse_menu, NULL);
  
      config_per_app_settings = NULL;
  
 -    parse_register(i, "applications", parse_per_app_settings, NULL);
 +    obt_parse_register(i, "applications", parse_per_app_settings, NULL);
  }
  
  void config_shutdown(void)
diff --combined openbox/config.h
index 248f97b36279fac14d73c5e8da65001039aab405,33fcd6844be0a5e93c637b48b90e8cb73479104c..d9e897a16c18e2ccb155dc3ca7d501b7e2e07fee
  #include "geom.h"
  #include "moveresize.h"
  #include "render/render.h"
 +#include "obt/parse.h"
  
  #include <glib.h>
  
 -struct _ObParseInst;
 -
  typedef struct _ObAppSettings ObAppSettings;
  
  struct _ObAppSettings
@@@ -82,6 -83,12 +82,12 @@@ extern gboolean config_place_center
    already on another monitor) */
  extern ObPlaceMonitor config_place_monitor;
  
+ /*! Place dialogs and stuff on this monitor.  Index starts at 1.  If this is
+   0, then use the config_primary_monitor instead. */
+ extern guint config_primary_monitor_index;
+ /*! Where to place dialogs and stuff if it is not specified by index. */
+ extern ObPlaceMonitor config_primary_monitor;
  /*! User-specified margins around the edge of the screen(s) */
  extern StrutPartial config_margins;
  
@@@ -132,8 -139,6 +138,8 @@@ extern gboolean config_theme_keepborder
  extern gchar *config_title_layout;
  /*! Animate windows iconifying and restoring */
  extern gboolean config_animate_iconify;
 +/*! Size of icons in focus switching dialogs */
 +extern guint config_theme_window_list_icon_size;
  
  /*! The font for the active window's title */
  extern RrFont *config_font_activewindow;
@@@ -189,11 -194,11 +195,11 @@@ extern GSList *config_menu_files
  /*! Per app settings */
  extern GSList *config_per_app_settings;
  
 -void config_startup(struct _ObParseInst *i);
 -void config_shutdown();
 +void config_startup(ObtParseInst *i);
 +void config_shutdown(void);
  
  /*! Create an ObAppSettings structure with the default values */
 -ObAppSettings* config_create_app_settings();
 +ObAppSettings* config_create_app_settings(void);
  /*! Copies any settings in src to dest, if they are their default value in
    src. */
  void config_app_settings_copy_non_defaults(const ObAppSettings *src,
diff --combined openbox/event.c
index 4ddb7ac75c906b6a41c9b19c173c355916d84932,b4bd82702699bc5e1e4727e64ebb101a897f9d9e..04c6a7c6914f1d371dd9d5fd99a36ab1be38aef5
@@@ -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
                                         another desktop, but we still don't
                                         want it! */
-         client_activate(client, FALSE, TRUE, TRUE, TRUE);
+         client_activate(client, FALSE, FALSE, TRUE, TRUE, TRUE);
          break;
      case ClientMessage:
          /* validate cuz we query stuff off the client here */
          if (e->xclient.format != 32) return;
  
          msgtype = e->xclient.message_type;
 -        if (msgtype == prop_atoms.wm_change_state) {
 +        if (msgtype == OBT_PROP_ATOM(WM_CHANGE_STATE)) {
              compress_client_message_event(e, &ce, client->window, msgtype);
              client_set_wm_state(client, e->xclient.data.l[0]);
 -        } else if (msgtype == prop_atoms.net_wm_desktop) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_WM_DESKTOP)) {
              compress_client_message_event(e, &ce, client->window, msgtype);
              if ((unsigned)e->xclient.data.l[0] < screen_num_desktops ||
                  (unsigned)e->xclient.data.l[0] == DESKTOP_ALL)
                  client_set_desktop(client, (unsigned)e->xclient.data.l[0],
                                     FALSE, FALSE);
 -        } else if (msgtype == prop_atoms.net_wm_state) {
 +        } else if (msgtype == OBT_PROP_ATOM(NET_WM_STATE)) {
              gulong ignore_start;
  
              /* can't compress these */
 -            ob_debug("net_wm_state %s %ld %ld for 0x%lx\n",
 +            ob_debug("net_wm_state %s %ld %ld for 0x%lx",
                       (e->xclient.data.l[0] == 0 ? "Remove" :
                        e->xclient.data.l[0] == 1 ? "Add" :
                        e->xclient.data.l[0] == 2 ? "Toggle" : "INVALID"),
                               e->xclient.data.l[1], e->xclient.data.l[2]);
              if (!config_focus_under_mouse)
                  event_end_ignore_all_enters(ignore_start);
 -        } else if (msgtype == prop_atoms.net_close_window) {
 -            ob_debug("net_close_window for 0x%lx\n", client->window);
 +        } else if (msgtype == OBT_PROP_ATOM(NET_CLOSE_WINDOW)) {
 +            ob_debug("net_close_window for 0x%lx", client->window);
              client_close(client);
 -        } else if (msgtype == prop_atoms.net_active_window) {
 -            ob_debug("net_active_window for 0x%lx source=%s\n",
 +        } else if (msgtype == OBT_PROP_ATOM(NET_ACTIVE_WINDOW)) {
 +            ob_debug("net_active_window for 0x%lx source=%s",
                       client->window,
                       (e->xclient.data.l[0] == 0 ? "unknown" :
                        (e->xclient.data.l[0] == 1 ? "application" :
                  if (e->xclient.data.l[1] == 0)
                      ob_debug_type(OB_DEBUG_APP_BUGS,
                                    "_NET_ACTIVE_WINDOW message for window %s is"
 -                                  " missing a timestamp\n", client->title);
 +                                  " missing a timestamp", client->title);
              } else
                  ob_debug_type(OB_DEBUG_APP_BUGS,
                                "_NET_ACTIVE_WINDOW message for window %s is "
 -                              "missing source indication\n", client->title);
 +                              "missing source indication", client->title);
-             client_activate(client, FALSE, TRUE, TRUE,
+             client_activate(client, FALSE, 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);
              }
@@@ -1647,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);
@@@ -1698,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 */
@@@ -1956,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)
@@@ -2026,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)
@@@ -2078,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
index fc0fd99bac47c560ce05de3fe114b25d407b675a,a0e9c6662f205e402be3853a49f51520deec4d9a..a75c170f649e72bf62c07456e603742e976e1229
  #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;
@@@ -95,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);
      }
  }
  
@@@ -107,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:
             3. it is not shaded
          */
          if ((allow_omnipresent || c->desktop == screen_desktop) &&
-             focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, FALSE) &&
+             focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) &&
              !c->shaded &&
              (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:
             a splashscreen or a desktop window (save the desktop as a
             backup fallback though)
          */
-         if (focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, TRUE) &&
+         if (focus_valid_target(c, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE) &&
              (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;
          }
      }
@@@ -183,17 -184,11 +183,11 @@@ ObClient* focus_fallback(gboolean allow
  
  void focus_nothing(void)
  {
-     /* Install our own colormap */
-     if (focus_client != NULL) {
-         screen_install_colormap(focus_client, FALSE);
-         screen_install_colormap(NULL, TRUE);
-     }
      /* nothing is focused, update the colormap and _the root property_ */
      focus_set_client(NULL);
  
      /* 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);
  }
  
@@@ -280,7 -275,7 +274,7 @@@ static gboolean focus_target_has_siblin
          /* check that it's not a helper window to avoid infinite recursion */
          if (c != ft && c->type == OB_CLIENT_TYPE_NORMAL &&
              focus_valid_target(c, TRUE, iconic_windows, all_desktops,
-                                FALSE, FALSE))
+                                FALSE, FALSE, FALSE))
          {
              return TRUE;
          }
@@@ -293,7 -288,8 +287,8 @@@ gboolean focus_valid_target(ObClient *f
                              gboolean iconic_windows,
                              gboolean all_desktops,
                              gboolean dock_windows,
-                             gboolean desktop_windows)
+                             gboolean desktop_windows,
+                             gboolean user_request)
  {
      gboolean ok = FALSE;
  
                 !focus_target_has_siblings(ft, iconic_windows, all_desktops))));
  
      /* it's not set to skip the taskbar (but this only applies to normal typed
-        windows, and is overridden if the window is modal) */
+        windows, and is overridden if the window is modal or if the user asked
+        for this window to be focused) */
      ok = ok && (ft->type != OB_CLIENT_TYPE_NORMAL ||
                  ft->modal ||
+                 user_request ||
                  !ft->skip_taskbar);
  
      /* it's not going to just send focus off somewhere else (modal window),
                                                       iconic_windows,
                                                       all_desktops,
                                                       dock_windows,
-                                                      desktop_windows));
+                                                      desktop_windows,
+                                                      FALSE));
      }
  
      return ok;
diff --combined openbox/focus.h
index 4f37b7281fce234a4850b0967a9f2efa4f1b14dc,19ab406ea554a958a18c5aa0de568940adbbf642..80ce3a38728dcfd29586e190336da1690eeb52de
@@@ -41,7 -41,7 +41,7 @@@ void focus_shutdown(gboolean reconfig)
  void focus_set_client(struct _ObClient *client);
  
  /*! Focus nothing, but let keyboard events be caught. */
 -void focus_nothing();
 +void focus_nothing(void);
  
  /*! Call this when you need to focus something! */
  struct _ObClient* focus_fallback(gboolean allow_refocus,
@@@ -69,6 -69,7 +69,7 @@@ gboolean focus_valid_target(struct _ObC
                              gboolean iconic_windows,
                              gboolean all_desktops,
                              gboolean dock_windows,
-                             gboolean desktop_windows);
+                             gboolean desktop_windows,
+                             gboolean user_request);
  
  #endif
diff --combined openbox/focus_cycle.c
index 063de6447bfa3b5f44d9483a752e1ac768764888,20a738f43bc13d017f2a2f181d3306500f3c12f5..d5654b3d1e627f3dedbf3582b2255e408d11cf38
@@@ -19,6 -19,7 +19,6 @@@
  
  #include "focus_cycle.h"
  #include "focus_cycle_indicator.h"
 -#include "focus_cycle_popup.h"
  #include "client.h"
  #include "frame.h"
  #include "focus.h"
@@@ -59,7 -60,8 +59,8 @@@ void focus_cycle_stop(ObClient *ifclien
                             focus_cycle_iconic_windows,
                             focus_cycle_all_desktops,
                             focus_cycle_dock_windows,
-                            focus_cycle_desktop_windows))
+                            focus_cycle_desktop_windows,
+                            FALSE))
      {
          focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,TRUE);
          focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
@@@ -69,7 -71,7 +70,7 @@@
  ObClient* focus_cycle(gboolean forward, gboolean all_desktops,
                        gboolean dock_windows, gboolean desktop_windows,
                        gboolean linear, gboolean interactive,
 -                      gboolean showbar, gboolean dialog,
 +                      gboolean showbar, ObFocusCyclePopupMode mode,
                        gboolean done, gboolean cancel)
  {
      static GList *order = NULL;
                                 focus_cycle_iconic_windows,
                                 focus_cycle_all_desktops,
                                 focus_cycle_dock_windows,
-                                focus_cycle_desktop_windows))
+                                focus_cycle_desktop_windows,
+                                FALSE))
          {
              if (interactive) {
                  if (ft != focus_cycle_target) { /* prevents flicker */
                      focus_cycle_target = ft;
                      focus_cycle_draw_indicator(showbar ? ft : NULL);
                  }
 -                if (dialog)
 -                    /* same arguments as focus_target_valid */
 -                    focus_cycle_popup_show(ft,
 -                                           focus_cycle_iconic_windows,
 -                                           focus_cycle_all_desktops,
 -                                           focus_cycle_dock_windows,
 -                                           focus_cycle_desktop_windows);
 +                /* same arguments as focus_target_valid */
 +                focus_cycle_popup_show(ft,
 +                                       focus_cycle_iconic_windows,
 +                                       focus_cycle_all_desktops,
 +                                       focus_cycle_dock_windows,
 +                                       focus_cycle_desktop_windows,
 +                                       mode);
                  return focus_cycle_target;
              } else if (ft != focus_cycle_target) {
                  focus_cycle_target = ft;
@@@ -188,7 -191,7 +190,7 @@@ static ObClient *focus_find_directional
          if (cur == c)
              continue;
          if (!focus_valid_target(it->data, TRUE, FALSE, FALSE, dock_windows,
-                                 desktop_windows))
+                                 desktop_windows, FALSE))
              continue;
  
          /* find the centre coords of this window, from the
@@@ -296,7 -299,7 +298,7 @@@ ObClient* focus_directional_cycle(ObDir
                                     focus_cycle_iconic_windows,
                                     focus_cycle_all_desktops,
                                     focus_cycle_dock_windows,
-                                    focus_cycle_desktop_windows))
+                                    focus_cycle_desktop_windows, FALSE))
                  ft = it->data;
      }
  
index a60534add5bfb0c798215fdc46aabf2e5c730723,a544bf147190b7cede39a83294e72f1cf2f383ef..2ad786c06eb0c1c671dda1a4c86f0b55447d7fba
@@@ -23,7 -23,6 +23,7 @@@
  #include "screen.h"
  #include "focus.h"
  #include "openbox.h"
 +#include "config.h"
  #include "window.h"
  #include "event.h"
  #include "render/render.h"
  #include <X11/Xlib.h>
  #include <glib.h>
  
 -#define ICON_SIZE 40
 -#define ICON_HILITE_WIDTH 2
 -#define ICON_HILITE_MARGIN 1
 +/* Size of the icons, which can appear inside or outside of a hilite box */
 +#define ICON_SIZE (gint)config_theme_window_list_icon_size
 +/* Size of the hilite box around a window's icon */
 +#define HILITE_SIZE (ICON_SIZE + 2*HILITE_OFFSET)
 +/* Width of the outer ring around the hilite box */
 +#define HILITE_WIDTH 2
 +/* Space between the outer ring around the hilite box and the icon inside it */
 +#define HILITE_MARGIN 1
 +/* Total distance from the edge of the hilite box to the icon inside it */
 +#define HILITE_OFFSET (HILITE_WIDTH + HILITE_MARGIN)
 +/* Margin area around the outside of the dialog */
  #define OUTSIDE_BORDER 3
 +/* Margin area around the text */
  #define TEXT_BORDER 2
 +/* Scroll the list-mode list when the cursor gets within this many rows of the
 +   top or bottom */
 +#define SCROLL_MARGIN 4
  
  typedef struct _ObFocusCyclePopup       ObFocusCyclePopup;
  typedef struct _ObFocusCyclePopupTarget ObFocusCyclePopupTarget;
@@@ -57,9 -44,7 +57,9 @@@ struct _ObFocusCyclePopupTarge
      ObClient *client;
      RrImage *icon;
      gchar *text;
 -    Window win;
 +    Window iconwin;
 +    /* This is used when the popup is in list mode */
 +    Window textwin;
  };
  
  struct _ObFocusCyclePopup
      ObWindow obwin;
      Window bg;
  
 -    Window text;
 +    /* This is used when the popup is in icon mode */
 +    Window icon_mode_text;
 +
 +    Window list_mode_up;
 +    Window list_mode_down;
  
      GList *targets;
      gint n_targets;
  
      gint maxtextw;
  
 +    /* How are the list is scrolled, in scroll mode */
 +    gint scroll;
 +
      RrAppearance *a_bg;
      RrAppearance *a_text;
 +    RrAppearance *a_hilite_text;
      RrAppearance *a_icon;
 -
 -    RrPixel32 *hilite_rgba;
 +    RrAppearance *a_arrow;
  
      gboolean mapped;
 +    ObFocusCyclePopupMode mode;
  };
  
  /*! This popup shows all possible windows */
@@@ -111,7 -88,7 +111,7 @@@ static void   popup_render   (ObFocusCy
  static Window create_window(Window parent, guint bwidth, gulong mask,
                              XSetWindowAttributes *attr)
  {
 -    return XCreateWindow(ob_display, parent, 0, 0, 1, 1, bwidth,
 +    return XCreateWindow(obt_display, parent, 0, 0, 1, 1, bwidth,
                           RrDepth(ob_rr_inst), InputOutput,
                           RrVisual(ob_rr_inst), mask, attr);
  }
  void focus_cycle_popup_startup(gboolean reconfig)
  {
      XSetWindowAttributes attrib;
 +    RrPixel32 *p;
  
      single_popup = icon_popup_new();
  
 -    popup.obwin.type = Window_Internal;
 +    popup.obwin.type = OB_WINDOW_CLASS_INTERNAL;
      popup.a_bg = RrAppearanceCopy(ob_rr_theme->osd_hilite_bg);
 -    popup.a_text = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
 -    popup.a_icon = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
 +    popup.a_hilite_text = RrAppearanceCopy(ob_rr_theme->osd_hilite_label);
 +    popup.a_text = RrAppearanceCopy(ob_rr_theme->a_unfocused_label);
 +    popup.a_icon = RrAppearanceCopy(ob_rr_theme->a_clear);
 +    popup.a_arrow = RrAppearanceCopy(ob_rr_theme->a_clear_tex);
  
 +    popup.a_hilite_text->surface.parent = popup.a_bg;
      popup.a_text->surface.parent = popup.a_bg;
      popup.a_icon->surface.parent = popup.a_bg;
  
 +    popup.a_text->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
 +    popup.a_hilite_text->texture[0].data.text.justify = RR_JUSTIFY_LEFT;
 +
 +    /* 2 textures. texture[0] is the icon.  texture[1] is the hilight, and
 +       may or may not be used */
 +    RrAppearanceAddTextures(popup.a_icon, 2);
 +
      RrAppearanceClearTextures(popup.a_icon);
      popup.a_icon->texture[0].type = RR_TEXTURE_IMAGE;
  
 -    RrAppearanceAddTextures(popup.a_bg, 1);
 -    popup.a_bg->texture[0].type = RR_TEXTURE_RGBA;
 +    RrAppearanceClearTextures(popup.a_arrow);
 +    popup.a_arrow->texture[0].type = RR_TEXTURE_MASK;
 +    popup.a_arrow->texture[0].data.mask.color =
 +        ob_rr_theme->osd_color;
  
      attrib.override_redirect = True;
      attrib.border_pixel=RrColorPixel(ob_rr_theme->osd_border_color);
 -    popup.bg = create_window(RootWindow(ob_display, ob_screen),
 -                             ob_rr_theme->obwidth,
 +    popup.bg = create_window(obt_root(ob_screen), ob_rr_theme->obwidth,
                               CWOverrideRedirect | CWBorderPixel, &attrib);
  
 -    popup.text = create_window(popup.bg, 0, 0, NULL);
 +    /* create the text window used for the icon-mode popup */
 +    popup.icon_mode_text = create_window(popup.bg, 0, 0, NULL);
 +
 +    /* create the windows for the up and down arrows */
 +    popup.list_mode_up = create_window(popup.bg, 0, 0, NULL);
 +    popup.list_mode_down = create_window(popup.bg, 0, 0, NULL);
  
      popup.targets = NULL;
      popup.n_targets = 0;
      popup.last_target = NULL;
  
 -    popup.hilite_rgba = NULL;
 +    /* set up the hilite texture for the icon */
 +    popup.a_icon->texture[1].data.rgba.width = HILITE_SIZE;
 +    popup.a_icon->texture[1].data.rgba.height = HILITE_SIZE;
 +    popup.a_icon->texture[1].data.rgba.alpha = 0xff;
 +    p = g_new(RrPixel32, HILITE_SIZE * HILITE_SIZE);
 +    popup.a_icon->texture[1].data.rgba.data = p;
 +
 +    /* create the hilite under the target icon */
 +    {
 +        RrPixel32 color;
 +        gint x, y, o;
 +
 +        color = ((ob_rr_theme->osd_color->r & 0xff) << RrDefaultRedOffset) +
 +            ((ob_rr_theme->osd_color->g & 0xff) << RrDefaultGreenOffset) +
 +            ((ob_rr_theme->osd_color->b & 0xff) << RrDefaultBlueOffset);
 +
 +        o = 0;
 +        for (x = 0; x < HILITE_SIZE; x++)
 +            for (y = 0; y < HILITE_SIZE; y++) {
 +                guchar a;
  
 -    XMapWindow(ob_display, popup.text);
 +                if (x < HILITE_WIDTH ||
 +                    x >= HILITE_SIZE - HILITE_WIDTH ||
 +                    y < HILITE_WIDTH ||
 +                    y >= HILITE_SIZE - HILITE_WIDTH)
 +                {
 +                    /* the border of the target */
 +                    a = 0x88;
 +                } else {
 +                    /* the background of the target */
 +                    a = 0x22;
 +                }
 +
 +                p[o++] = color + (a << RrDefaultAlphaOffset);
 +            }
 +    }
  
      stacking_add(INTERNAL_AS_WINDOW(&popup));
 -    g_hash_table_insert(window_map, &popup.bg, &popup);
 +    window_add(&popup.bg, INTERNAL_AS_WINDOW(&popup));
  }
  
  void focus_cycle_popup_shutdown(gboolean reconfig)
  {
      icon_popup_free(single_popup);
  
 -    g_hash_table_remove(window_map, &popup.bg);
 +    window_remove(popup.bg);
      stacking_remove(INTERNAL_AS_WINDOW(&popup));
  
      while(popup.targets) {
  
          RrImageUnref(t->icon);
          g_free(t->text);
 -        XDestroyWindow(ob_display, t->win);
 +        XDestroyWindow(obt_display, t->iconwin);
 +        XDestroyWindow(obt_display, t->textwin);
          g_free(t);
  
          popup.targets = g_list_delete_link(popup.targets, popup.targets);
      }
  
 -    g_free(popup.hilite_rgba);
 -    popup.hilite_rgba = NULL;
 +    g_free(popup.a_icon->texture[1].data.rgba.data);
 +    popup.a_icon->texture[1].data.rgba.data = NULL;
  
 -    XDestroyWindow(ob_display, popup.text);
 -    XDestroyWindow(ob_display, popup.bg);
 +    XDestroyWindow(obt_display, popup.list_mode_up);
 +    XDestroyWindow(obt_display, popup.list_mode_down);
 +    XDestroyWindow(obt_display, popup.icon_mode_text);
 +    XDestroyWindow(obt_display, popup.bg);
  
 +    RrAppearanceFree(popup.a_arrow);
      RrAppearanceFree(popup.a_icon);
 +    RrAppearanceFree(popup.a_hilite_text);
      RrAppearanceFree(popup.a_text);
      RrAppearanceFree(popup.a_bg);
  }
@@@ -263,7 -185,8 +263,8 @@@ static void popup_setup(ObFocusCyclePop
                                 iconic_windows,
                                 all_desktops,
                                 dock_windows,
-                                desktop_windows))
+                                desktop_windows,
+                                FALSE))
          {
              gchar *text = popup_get_name(ft);
  
              p->a_text->texture[0].data.text.string = text;
              maxwidth = MAX(maxwidth, RrMinWidth(p->a_text));
  
 -            if (!create_targets)
 +            if (!create_targets) {
                  g_free(text);
 -            else {
 +            else {
                  ObFocusCyclePopupTarget *t = g_new(ObFocusCyclePopupTarget, 1);
  
                  t->client = ft;
                  t->text = text;
                  t->icon = client_icon(t->client);
                  RrImageRef(t->icon); /* own the icon so it won't go away */
 -                t->win = create_window(p->bg, 0, 0, NULL);
 -
 -                XMapWindow(ob_display, t->win);
 +                t->iconwin = create_window(p->bg, 0, 0, NULL);
 +                t->textwin = create_window(p->bg, 0, 0, NULL);
  
                  p->targets = g_list_prepend(p->targets, t);
                  ++n;
@@@ -326,31 -250,18 +327,31 @@@ static void popup_render(ObFocusCyclePo
      gint l, t, r, b;
      gint x, y, w, h;
      Rect *screen_area = NULL;
 -    gint icons_per_row;
 -    gint icon_rows;
 -    gint textx, texty, textw, texth;
 -    gint rgbax, rgbay, rgbaw, rgbah;
 -    gint icons_center_x;
 -    gint innerw, innerh;
      gint i;
      GList *it;
      const ObFocusCyclePopupTarget *newtarget;
 -    gint newtargetx, newtargety;
 +    ObFocusCyclePopupMode mode = p->mode;
 +    gint icons_per_row;
 +    gint icon_rows;
 +    gint textw, texth;
 +    gint selected_pos;
 +    gint last_scroll;
 +
 +    /* vars for icon mode */
 +    gint icon_mode_textx;
 +    gint icon_mode_texty;
 +    gint icons_center_x;
 +
 +    /* vars for list mode */
 +    gint list_mode_icon_column_w = HILITE_SIZE + OUTSIDE_BORDER;
 +    gint up_arrow_x, down_arrow_x;
 +    gint up_arrow_y, down_arrow_y;
 +    gboolean showing_arrows = FALSE;
 +
 +    g_assert(mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS ||
 +             mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST);
  
-     screen_area = screen_physical_area_active();
+     screen_area = screen_physical_area_primary();
  
      /* get the outside margins */
      RrMargins(p->a_bg, &ml, &mt, &mr, &mb);
      t = mt + OUTSIDE_BORDER;
      b = mb + OUTSIDE_BORDER;
  
 -    /* get the icon pictures' sizes */
 -    innerw = ICON_SIZE - (ICON_HILITE_WIDTH + ICON_HILITE_MARGIN) * 2;
 -    innerh = ICON_SIZE - (ICON_HILITE_WIDTH + ICON_HILITE_MARGIN) * 2;
 -
      /* get the width from the text and keep it within limits */
      w = l + r + p->maxtextw;
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST)
 +        /* when in list mode, there are icons down the side */
 +        w += list_mode_icon_column_w;
      w = MIN(w, MAX(screen_area->width/3, POPUP_WIDTH)); /* max width */
      w = MAX(w, POPUP_WIDTH); /* min width */
  
 -    /* how many icons will fit in that row? make the width fit that */
 -    w -= l + r;
 -    icons_per_row = (w + ICON_SIZE - 1) / ICON_SIZE;
 -    w = icons_per_row * ICON_SIZE + l + r;
 -
 -    /* how many rows do we need? */
 -    icon_rows = (p->n_targets-1) / icons_per_row + 1;
 +    /* get the text height */
 +    texth = RrMinHeight(p->a_hilite_text);
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST)
 +        texth = MAX(MAX(texth, RrMinHeight(p->a_text)), HILITE_SIZE);
 +    else
 +        texth += TEXT_BORDER * 2;
 +
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS) {
 +        /* how many icons will fit in that row? make the width fit that */
 +        w -= l + r;
 +        icons_per_row = (w + HILITE_SIZE - 1) / HILITE_SIZE;
 +        w = icons_per_row * HILITE_SIZE + l + r;
 +
 +        /* how many rows do we need? */
 +        icon_rows = (p->n_targets-1) / icons_per_row + 1;
 +    } else {
 +        /* in list mode, there is one column of icons.. */
 +        icons_per_row = 1;
 +        /* maximum is 80% of the screen height */
 +        icon_rows = MIN(p->n_targets,
 +                        (4*screen_area->height/5) /* 80% of the screen */
 +                        /
 +                        MAX(HILITE_SIZE, texth)); /* height of each row */
 +        /* but make sure there is always one */
 +        icon_rows = MAX(icon_rows, 1);
 +    }
  
 -    /* get the text dimensions */
 +    /* get the text width */
      textw = w - l - r;
 -    texth = RrMinHeight(p->a_text) + TEXT_BORDER * 2;
 -
 -    /* find the height of the dialog */
 -    h = t + b + (icon_rows * ICON_SIZE) + (OUTSIDE_BORDER + texth);
 -
 -    /* get the position of the text */
 -    textx = l;
 -    texty = h - texth - b;
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST)
 +        /* leave space on the side for the icons */
 +        textw -= list_mode_icon_column_w;
  
 -    /* find the position for the popup (include the outer borders) */
 -    x = screen_area->x + (screen_area->width -
 -                          (w + ob_rr_theme->obwidth * 2)) / 2;
 -    y = screen_area->y + (screen_area->height -
 -                          (h + ob_rr_theme->obwidth * 2)) / 2;
 -
 -    /* get the dimensions of the target hilite texture */
 -    rgbax = ml;
 -    rgbay = mt;
 -    rgbaw = w - ml - mr;
 -    rgbah = h - mt - mb;
 -
 -    /* center the icons if there is less than one row */
 -    if (icon_rows == 1)
 -        icons_center_x = (w - p->n_targets * ICON_SIZE) / 2;
 -    else
 -        icons_center_x = 0;
 +    if (!p->mapped)
 +        /* reset the scrolling when the dialog is first shown */
 +        p->scroll = 0;
  
 -    if (!p->mapped) {
 -        /* position the background but don't draw it*/
 -        XMoveResizeWindow(ob_display, p->bg, x, y, w, h);
 -
 -        /* set up the hilite texture for the background */
 -        p->a_bg->texture[0].data.rgba.width = rgbaw;
 -        p->a_bg->texture[0].data.rgba.height = rgbah;
 -        p->a_bg->texture[0].data.rgba.alpha = 0xff;
 -        p->hilite_rgba = g_new(RrPixel32, rgbaw * rgbah);
 -        p->a_bg->texture[0].data.rgba.data = p->hilite_rgba;
 -
 -        /* position the text, but don't draw it */
 -        XMoveResizeWindow(ob_display, p->text, textx, texty, textw, texth);
 -        p->a_text->surface.parentx = textx;
 -        p->a_text->surface.parenty = texty;
 -    }
 +    /* find the height of the dialog */
 +    h = t + b + (icon_rows * MAX(HILITE_SIZE, texth));
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS)
 +        /* in icon mode the text sits below the icons, so make some space */
 +        h += OUTSIDE_BORDER + texth;
  
      /* find the focused target */
 +    newtarget = NULL;
      for (i = 0, it = p->targets; it; ++i, it = g_list_next(it)) {
          const ObFocusCyclePopupTarget *target = it->data;
 -        const gint row = i / icons_per_row; /* starting from 0 */
 -        const gint col = i % icons_per_row; /* starting from 0 */
 -
          if (target->client == c) {
              /* save the target */
              newtarget = target;
 -            newtargetx = icons_center_x + l + (col * ICON_SIZE);
 -            newtargety = t + (row * ICON_SIZE);
 +            break;
 +        }
 +    }
 +    selected_pos = i;
 +    g_assert(newtarget != NULL);
  
 -            if (!p->mapped)
 -                break; /* if we're not dimensioning, then we're done */
 +    /* scroll the list if needed */
 +    last_scroll = p->scroll;
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST) {
 +        const gint top = p->scroll + SCROLL_MARGIN;
 +        const gint bottom = p->scroll + icon_rows - SCROLL_MARGIN;
 +        const gint min_scroll = 0;
 +        const gint max_scroll = p->n_targets - icon_rows;
 +
 +        if (top - selected_pos >= 0) {
 +            p->scroll -= top - selected_pos + 1;
 +            p->scroll = MAX(p->scroll, min_scroll);
 +        } else if (selected_pos - bottom >= 0) {
 +            p->scroll += selected_pos - bottom + 1;
 +            p->scroll = MIN(p->scroll, max_scroll);
          }
      }
  
 -    g_assert(newtarget != NULL);
 +    /* show the scroll arrows when appropriate */
 +    if (p->scroll && mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST) {
 +        XMapWindow(obt_display, p->list_mode_up);
 +        showing_arrows = TRUE;
 +    } else
 +        XUnmapWindow(obt_display, p->list_mode_up);
  
 -    /* create the hilite under the target icon */
 +    if (p->scroll < p->n_targets - icon_rows &&
 +        mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST)
      {
 -        RrPixel32 color;
 -        gint i, j, o;
 +        XMapWindow(obt_display, p->list_mode_down);
 +        showing_arrows = TRUE;
 +    } else
 +        XUnmapWindow(obt_display, p->list_mode_down);
  
 -        color = ((ob_rr_theme->osd_color->r & 0xff) << RrDefaultRedOffset) +
 -            ((ob_rr_theme->osd_color->g & 0xff) << RrDefaultGreenOffset) +
 -            ((ob_rr_theme->osd_color->b & 0xff) << RrDefaultBlueOffset);
 +    /* make space for the arrows */
 +    if (showing_arrows)
 +        h += ob_rr_theme->up_arrow_mask->height + OUTSIDE_BORDER
 +            + ob_rr_theme->down_arrow_mask->height + OUTSIDE_BORDER;
  
 -        o = 0;
 -        for (i = 0; i < rgbah; ++i)
 -            for (j = 0; j < rgbaw; ++j) {
 -                guchar a;
 -                const gint x = j + rgbax - newtargetx;
 -                const gint y = i + rgbay - newtargety;
 +    /* center the icons if there is less than one row */
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS && icon_rows == 1)
 +        icons_center_x = (w - p->n_targets * HILITE_SIZE) / 2;
 +    else
 +        icons_center_x = 0;
  
 -                if (x < 0 || x >= ICON_SIZE ||
 -                    y < 0 || y >= ICON_SIZE)
 -                {
 -                    /* outside the target */
 -                    a = 0x00;
 -                }
 -                else if (x < ICON_HILITE_WIDTH ||
 -                         x >= ICON_SIZE - ICON_HILITE_WIDTH ||
 -                         y < ICON_HILITE_WIDTH ||
 -                         y >= ICON_SIZE - ICON_HILITE_WIDTH)
 -                {
 -                    /* the border of the target */
 -                    a = 0x88;
 -                }
 -                else {
 -                    /* the background of the target */
 -                    a = 0x22;
 -                }
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS) {
 +        /* get the position of the text */
 +        icon_mode_textx = l;
 +        icon_mode_texty = h - texth - b;
 +    }
  
 -                p->hilite_rgba[o++] =
 -                    color + (a << RrDefaultAlphaOffset);
 -            }
 +    /* find the position for the popup (include the outer borders) */
 +    x = screen_area->x + (screen_area->width -
 +                          (w + ob_rr_theme->obwidth * 2)) / 2;
 +    y = screen_area->y + (screen_area->height -
 +                          (h + ob_rr_theme->obwidth * 2)) / 2;
 +
 +    if (!p->mapped) {
 +        /* position the background but don't draw it */
 +        XMoveResizeWindow(obt_display, p->bg, x, y, w, h);
 +
 +        if (mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS) {
 +            /* position the text */
 +            XMoveResizeWindow(obt_display, p->icon_mode_text,
 +                              icon_mode_textx, icon_mode_texty, textw, texth);
 +            XMapWindow(obt_display, popup.icon_mode_text);
 +        } else {
 +            XUnmapWindow(obt_display, popup.icon_mode_text);
 +
 +            up_arrow_x = (w - ob_rr_theme->up_arrow_mask->width) / 2;
 +            up_arrow_y = t;
 +
 +            down_arrow_x = (w - ob_rr_theme->down_arrow_mask->width) / 2;
 +            down_arrow_y = h - b - ob_rr_theme->down_arrow_mask->height;
 +
 +            /* position the arrows */
 +            XMoveResizeWindow(obt_display, p->list_mode_up,
 +                              up_arrow_x, up_arrow_y,
 +                              ob_rr_theme->up_arrow_mask->width,
 +                              ob_rr_theme->up_arrow_mask->height);
 +            XMoveResizeWindow(obt_display, p->list_mode_down,
 +                              down_arrow_x, down_arrow_y,
 +                              ob_rr_theme->down_arrow_mask->width,
 +                              ob_rr_theme->down_arrow_mask->height);
 +        }
      }
  
      /* * * draw everything * * */
  
      /* draw the background */
 -    RrPaint(p->a_bg, p->bg, w, h);
 +    if (!p->mapped)
 +        RrPaint(p->a_bg, p->bg, w, h);
 +
 +    /* draw the scroll arrows */
 +    if (!p->mapped && mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST) {
 +        p->a_arrow->texture[0].data.mask.mask =
 +            ob_rr_theme->up_arrow_mask;
 +        p->a_arrow->surface.parent = p->a_bg;
 +        p->a_arrow->surface.parentx = up_arrow_x;
 +        p->a_arrow->surface.parenty = up_arrow_y;
 +        RrPaint(p->a_arrow, p->list_mode_up, 
 +                ob_rr_theme->up_arrow_mask->width,
 +                ob_rr_theme->up_arrow_mask->height);
 +
 +        p->a_arrow->texture[0].data.mask.mask =
 +            ob_rr_theme->down_arrow_mask;
 +        p->a_arrow->surface.parent = p->a_bg;
 +        p->a_arrow->surface.parentx = down_arrow_x;
 +        p->a_arrow->surface.parenty = down_arrow_y;
 +        RrPaint(p->a_arrow, p->list_mode_down, 
 +                ob_rr_theme->down_arrow_mask->width,
 +                ob_rr_theme->down_arrow_mask->height);
 +    }
  
 -    /* draw the icons */
 +    /* draw the icons and text */
      for (i = 0, it = p->targets; it; ++i, it = g_list_next(it)) {
          const ObFocusCyclePopupTarget *target = it->data;
  
 -        /* have to redraw the targetted icon and last targetted icon,
 -           they can pick up the hilite changes in the backgroud */
 -        if (!p->mapped || newtarget == target || p->last_target == target) {
 -            const gint row = i / icons_per_row; /* starting from 0 */
 -            const gint col = i % icons_per_row; /* starting from 0 */
 -            gint innerx, innery;
 -
 -            /* find the dimensions of the icon inside it */
 -            innerx = icons_center_x + l + (col * ICON_SIZE);
 -            innerx += ICON_HILITE_WIDTH + ICON_HILITE_MARGIN;
 -            innery = t + (row * ICON_SIZE);
 -            innery += ICON_HILITE_WIDTH + ICON_HILITE_MARGIN;
 -
 -            /* move the icon */
 -            XMoveResizeWindow(ob_display, target->win,
 -                              innerx, innery, innerw, innerh);
 +        /* have to redraw the targetted icon and last targetted icon
 +         * to update the hilite */
 +        if (!p->mapped || newtarget == target || p->last_target == target ||
 +            last_scroll != p->scroll)
 +        {
 +            /* row and column start from 0 */
 +            const gint row = i / icons_per_row - p->scroll;
 +            const gint col = i % icons_per_row;
 +            gint iconx, icony;
 +            gint list_mode_textx, list_mode_texty;
 +            RrAppearance *text;
 +
 +            /* find the coordinates for the icon */
 +            iconx = icons_center_x + l + (col * HILITE_SIZE);
 +            icony = t + (showing_arrows ? ob_rr_theme->up_arrow_mask->height
 +                                          + OUTSIDE_BORDER
 +                         : 0)
 +                + (row * MAX(texth, HILITE_SIZE))
 +                + MAX(texth - HILITE_SIZE, 0) / 2;
 +
 +            /* find the dimensions of the text box */
 +            list_mode_textx = iconx + HILITE_SIZE + TEXT_BORDER;
 +            list_mode_texty = icony;
 +
 +            /* position the icon */
 +            XMoveResizeWindow(obt_display, target->iconwin,
 +                              iconx, icony, HILITE_SIZE, HILITE_SIZE);
 +
 +            /* position the text */
 +            if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST)
 +                XMoveResizeWindow(obt_display, target->textwin,
 +                                  list_mode_textx, list_mode_texty,
 +                                  textw, texth);
 +
 +            /* show/hide the right windows */
 +            if (row >= 0 && row < icon_rows) {
 +                XMapWindow(obt_display, target->iconwin);
 +                if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST)
 +                    XMapWindow(obt_display, target->textwin);
 +                else
 +                    XUnmapWindow(obt_display, target->textwin);
 +            } else {
 +                XUnmapWindow(obt_display, target->textwin);
 +                if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST)
 +                    XUnmapWindow(obt_display, target->iconwin);
 +                else
 +                    XMapWindow(obt_display, target->iconwin);
 +            }
  
              /* get the icon from the client */
 +            p->a_icon->texture[0].data.image.twidth = ICON_SIZE;
 +            p->a_icon->texture[0].data.image.theight = ICON_SIZE;
 +            p->a_icon->texture[0].data.image.tx = HILITE_OFFSET;
 +            p->a_icon->texture[0].data.image.ty = HILITE_OFFSET;
              p->a_icon->texture[0].data.image.alpha =
                  target->client->iconic ? OB_ICONIC_ALPHA : 0xff;
              p->a_icon->texture[0].data.image.image = target->icon;
  
 +            /* Draw the hilite? */
 +            p->a_icon->texture[1].type = (target == newtarget) ?
 +                RR_TEXTURE_RGBA : RR_TEXTURE_NONE;
 +
              /* draw the icon */
 -            p->a_icon->surface.parentx = innerx;
 -            p->a_icon->surface.parenty = innery;
 -            RrPaint(p->a_icon, target->win, innerw, innerh);
 +            p->a_icon->surface.parentx = iconx;
 +            p->a_icon->surface.parenty = icony;
 +            RrPaint(p->a_icon, target->iconwin, HILITE_SIZE, HILITE_SIZE);
 +
 +            /* draw the text */
 +            if (mode == OB_FOCUS_CYCLE_POPUP_MODE_LIST ||
 +                target == newtarget)
 +            {
 +                text = (target == newtarget) ? p->a_hilite_text : p->a_text;
 +                text->texture[0].data.text.string = target->text;
 +                text->surface.parentx =
 +                    mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS ?
 +                    icon_mode_textx : list_mode_textx;
 +                text->surface.parenty =
 +                    mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS ?
 +                    icon_mode_texty : list_mode_texty;
 +                RrPaint(text,
 +                        (mode == OB_FOCUS_CYCLE_POPUP_MODE_ICONS ?
 +                         p->icon_mode_text : target->textwin),
 +                        textw, texth);
 +            }
          }
      }
  
 -    /* draw the text */
 -    p->a_text->texture[0].data.text.string = newtarget->text;
 -    p->a_text->surface.parentx = textx;
 -    p->a_text->surface.parenty = texty;
 -    RrPaint(p->a_text, p->text, textw, texth);
 -
      p->last_target = newtarget;
  
      g_free(screen_area);
 +
 +    XFlush(obt_display);
  }
  
  void focus_cycle_popup_show(ObClient *c, gboolean iconic_windows,
                              gboolean all_desktops, gboolean dock_windows,
 -                            gboolean desktop_windows)
 +                            gboolean desktop_windows,
 +                            ObFocusCyclePopupMode mode)
  {
      g_assert(c != NULL);
  
 +    if (mode == OB_FOCUS_CYCLE_POPUP_MODE_NONE) {
 +        focus_cycle_popup_hide();
 +        return;
 +    }
 +
      /* do this stuff only when the dialog is first showing */
 -    if (!popup.mapped)
 -        popup_setup(&popup, TRUE, iconic_windows, all_desktops,
 +    if (!popup.mapped) {
 +        popup_setup(&popup, TRUE, iconic_windows, all_desktops, 
                      dock_windows, desktop_windows);
 +        /* this is fixed once the dialog is shown */
 +        popup.mode = mode;
 +    }
      g_assert(popup.targets != NULL);
  
      popup_render(&popup, c);
  
      if (!popup.mapped) {
          /* show the dialog */
 -        XMapWindow(ob_display, popup.bg);
 -        XFlush(ob_display);
 +        XMapWindow(obt_display, popup.bg);
 +        XFlush(obt_display);
          popup.mapped = TRUE;
          screen_hide_desktop_popup();
      }
@@@ -673,8 -472,8 +674,8 @@@ void focus_cycle_popup_hide(void
  
      ignore_start = event_start_ignore_all_enters();
  
 -    XUnmapWindow(ob_display, popup.bg);
 -    XFlush(ob_display);
 +    XUnmapWindow(obt_display, popup.bg);
 +    XFlush(obt_display);
  
      event_end_ignore_all_enters(ignore_start);
  
  
          RrImageUnref(t->icon);
          g_free(t->text);
 -        XDestroyWindow(ob_display, t->win);
 +        XDestroyWindow(obt_display, t->iconwin);
 +        XDestroyWindow(obt_display, t->textwin);
          g_free(t);
  
          popup.targets = g_list_delete_link(popup.targets, popup.targets);
      }
      popup.n_targets = 0;
      popup.last_target = NULL;
 -
 -    g_free(popup.hilite_rgba);
 -    popup.hilite_rgba = NULL;
  }
  
  void focus_cycle_popup_single_show(struct _ObClient *c,
          g_assert(popup.targets == NULL);
  
          /* position the popup */
-         a = screen_physical_area_active();
+         a = screen_physical_area_primary();
          icon_popup_position(single_popup, CenterGravity,
                              a->x + a->width / 2, a->y + a->height / 2);
          icon_popup_height(single_popup, POPUP_HEIGHT);
diff --combined openbox/frame.c
index 72eab32bff10c1198d5d595f5a3afb560c20ee17,20697d32a091aa958ed3a0bb3b77e25f92db0ae0..6387d7ef113528e44decc1ba1718fd1bb8c2b249
  #include "frame.h"
  #include "client.h"
  #include "openbox.h"
 -#include "extensions.h"
 -#include "prop.h"
  #include "grab.h"
+ #include "debug.h"
  #include "config.h"
  #include "framerender.h"
 -#include "mainloop.h"
  #include "focus_cycle.h"
  #include "focus_cycle_indicator.h"
  #include "moveresize.h"
  #include "screen.h"
  #include "render/theme.h"
 +#include "obt/display.h"
 +#include "obt/prop.h"
  
  #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
                           ButtonPressMask | ButtonReleaseMask | \
@@@ -55,7 -57,7 +56,7 @@@ static void frame_adjust_cursors(ObFram
  static Window createWindow(Window parent, Visual *visual,
                             gulong mask, XSetWindowAttributes *attrib)
  {
 -    return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
 +    return XCreateWindow(obt_display, parent, 0, 0, 1, 1, 0,
                           (visual ? 32 : RrDepth(ob_rr_inst)), InputOutput,
                           (visual ? visual : RrVisual(ob_rr_inst)),
                           mask, attrib);
@@@ -72,7 -74,7 +73,7 @@@ static Visual *check_32bit_client(ObCli
      if (RrDepth(ob_rr_inst) == 32)
          return NULL;
  
 -    ret = XGetWindowAttributes(ob_display, c->window, &wattrib);
 +    ret = XGetWindowAttributes(obt_display, c->window, &wattrib);
      g_assert(ret != BadDrawable);
      g_assert(ret != BadWindow);
  
@@@ -101,12 -103,13 +102,12 @@@ ObFrame *frame_new(ObClient *client
          mask = CWColormap | CWBackPixel | CWBorderPixel;
          /* create a colormap with the visual */
          self->colormap = attrib.colormap =
 -            XCreateColormap(ob_display,
 -                            RootWindow(ob_display, ob_screen),
 +            XCreateColormap(obt_display, obt_root(ob_screen),
                              visual, AllocNone);
 -        attrib.background_pixel = BlackPixel(ob_display, ob_screen);
 -        attrib.border_pixel = BlackPixel(ob_display, ob_screen);
 +        attrib.background_pixel = BlackPixel(obt_display, ob_screen);
 +        attrib.border_pixel = BlackPixel(obt_display, ob_screen);
      }
 -    self->window = createWindow(RootWindow(ob_display, ob_screen), visual,
 +    self->window = createWindow(obt_root(ob_screen), visual,
                                  mask, &attrib);
  
      /* create the visible decor windows */
      self->focused = FALSE;
  
      /* the other stuff is shown based on decor settings */
 -    XMapWindow(ob_display, self->label);
 -    XMapWindow(ob_display, self->backback);
 -    XMapWindow(ob_display, self->backfront);
 +    XMapWindow(obt_display, self->label);
 +    XMapWindow(obt_display, self->backback);
 +    XMapWindow(obt_display, self->backfront);
  
      self->max_press = self->close_press = self->desk_press =
          self->iconify_press = self->shade_press = FALSE;
  static void set_theme_statics(ObFrame *self)
  {
      /* set colors/appearance/sizes for stuff that doesn't change */
 -    XResizeWindow(ob_display, self->max,
 +    XResizeWindow(obt_display, self->max,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->iconify,
 +    XResizeWindow(obt_display, self->iconify,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->icon,
 +    XResizeWindow(obt_display, self->icon,
                    ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
 -    XResizeWindow(ob_display, self->close,
 +    XResizeWindow(obt_display, self->close,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->desk,
 +    XResizeWindow(obt_display, self->desk,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->shade,
 +    XResizeWindow(obt_display, self->shade,
                    ob_rr_theme->button_size, ob_rr_theme->button_size);
 -    XResizeWindow(ob_display, self->tltresize,
 +    XResizeWindow(obt_display, self->tltresize,
                    ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
 -    XResizeWindow(ob_display, self->trtresize,
 +    XResizeWindow(obt_display, self->trtresize,
                    ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
 -    XResizeWindow(ob_display, self->tllresize,
 +    XResizeWindow(obt_display, self->tllresize,
                    ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
 -    XResizeWindow(ob_display, self->trrresize,
 +    XResizeWindow(obt_display, self->trrresize,
                    ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
  }
  
@@@ -224,9 -227,9 +225,9 @@@ void frame_free(ObFrame *self
  {
      free_theme_statics(self);
  
 -    XDestroyWindow(ob_display, self->window);
 +    XDestroyWindow(obt_display, self->window);
      if (self->colormap)
 -        XFreeColormap(ob_display, self->colormap);
 +        XFreeColormap(obt_display, self->colormap);
  
      g_free(self);
  }
@@@ -240,8 -243,8 +241,8 @@@ void frame_show(ObFrame *self
             the client gets its MapNotify, i.e. to make sure the client is
             _visible_ when it gets MapNotify. */
          grab_server(TRUE);
 -        XMapWindow(ob_display, self->client->window);
 -        XMapWindow(ob_display, self->window);
 +        XMapWindow(obt_display, self->client->window);
 +        XMapWindow(obt_display, self->window);
          grab_server(FALSE);
      }
  }
@@@ -251,10 -254,10 +252,10 @@@ void frame_hide(ObFrame *self
      if (self->visible) {
          self->visible = FALSE;
          if (!frame_iconify_animating(self))
 -            XUnmapWindow(ob_display, self->window);
 +            XUnmapWindow(obt_display, self->window);
          /* we unmap the client itself so that we can get MapRequest
             events, and because the ICCCM tells us to! */
 -        XUnmapWindow(ob_display, self->client->window);
 +        XUnmapWindow(obt_display, self->client->window);
          self->client->ignore_unmaps += 1;
      }
  }
@@@ -274,13 -277,13 +275,13 @@@ void frame_adjust_shape_kind(ObFrame *s
      if (!((kind == ShapeBounding && self->client->shaped) ||
            (kind == ShapeInput && self->client->shaped_input))) {
          /* clear the shape on the frame window */
 -        XShapeCombineMask(ob_display, self->window, kind,
 +        XShapeCombineMask(obt_display, self->window, kind,
                            self->size.left,
                            self->size.top,
                            None, ShapeSet);
      } else {
          /* make the frame's shape match the clients */
 -        XShapeCombineShape(ob_display, self->window, kind,
 +        XShapeCombineShape(obt_display, self->window, kind,
                             self->size.left,
                             self->size.top,
                             self->client->window,
              ++num;
          }
  
 -        XShapeCombineRectangles(ob_display, self->window,
 -                                kind, 0, 0, xrect, num,
 +        XShapeCombineRectangles(obt_display, self->window,
 +                                ShapeBounding, 0, 0, xrect, num,
                                  ShapeUnion, Unsorted);
      }
  }
@@@ -368,8 -371,7 +369,7 @@@ void frame_adjust_area(ObFrame *self, g
  
          STRUT_SET(self->size,
                    self->cbwidth_l + (!self->max_horz ? self->bwidth : 0),
-                   self->cbwidth_t +
-                   (!self->max_horz || !self->max_vert ? self->bwidth : 0),
+                   self->cbwidth_t + self->bwidth,
                    self->cbwidth_r + (!self->max_horz ? self->bwidth : 0),
                    self->cbwidth_b +
                    (!self->max_horz || !self->max_vert ? self->bwidth : 0));
                  ob_rr_theme->grip_width - self->size.bottom;
  
              if (self->cbwidth_l) {
 -                XMoveResizeWindow(ob_display, self->innerleft,
 +                XMoveResizeWindow(obt_display, self->innerleft,
                                    self->size.left - self->cbwidth_l,
                                    self->size.top,
                                    self->cbwidth_l, self->client->area.height);
  
 -                XMapWindow(ob_display, self->innerleft);
 +                XMapWindow(obt_display, self->innerleft);
              } else
 -                XUnmapWindow(ob_display, self->innerleft);
 +                XUnmapWindow(obt_display, self->innerleft);
  
              if (self->cbwidth_l && innercornerheight > 0) {
 -                XMoveResizeWindow(ob_display, self->innerbll,
 +                XMoveResizeWindow(obt_display, self->innerbll,
                                    0,
                                    self->client->area.height - 
                                    (ob_rr_theme->grip_width -
                                    self->cbwidth_l,
                                    ob_rr_theme->grip_width - self->size.bottom);
  
 -                XMapWindow(ob_display, self->innerbll);
 +                XMapWindow(obt_display, self->innerbll);
              } else
 -                XUnmapWindow(ob_display, self->innerbll);
 +                XUnmapWindow(obt_display, self->innerbll);
  
              if (self->cbwidth_r) {
 -                XMoveResizeWindow(ob_display, self->innerright,
 +                XMoveResizeWindow(obt_display, self->innerright,
                                    self->size.left + self->client->area.width,
                                    self->size.top,
                                    self->cbwidth_r, self->client->area.height);
  
 -                XMapWindow(ob_display, self->innerright);
 +                XMapWindow(obt_display, self->innerright);
              } else
 -                XUnmapWindow(ob_display, self->innerright);
 +                XUnmapWindow(obt_display, self->innerright);
  
              if (self->cbwidth_r && innercornerheight > 0) {
 -                XMoveResizeWindow(ob_display, self->innerbrr,
 +                XMoveResizeWindow(obt_display, self->innerbrr,
                                    0,
                                    self->client->area.height - 
                                    (ob_rr_theme->grip_width -
                                    self->cbwidth_r,
                                    ob_rr_theme->grip_width - self->size.bottom);
  
 -                XMapWindow(ob_display, self->innerbrr);
 +                XMapWindow(obt_display, self->innerbrr);
              } else
 -                XUnmapWindow(ob_display, self->innerbrr);
 +                XUnmapWindow(obt_display, self->innerbrr);
  
              if (self->cbwidth_t) {
 -                XMoveResizeWindow(ob_display, self->innertop,
 +                XMoveResizeWindow(obt_display, self->innertop,
                                    self->size.left - self->cbwidth_l,
                                    self->size.top - self->cbwidth_t,
                                    self->client->area.width +
                                    self->cbwidth_l + self->cbwidth_r,
                                    self->cbwidth_t);
  
 -                XMapWindow(ob_display, self->innertop);
 +                XMapWindow(obt_display, self->innertop);
              } else
 -                XUnmapWindow(ob_display, self->innertop);
 +                XUnmapWindow(obt_display, self->innertop);
  
              if (self->cbwidth_b) {
 -                XMoveResizeWindow(ob_display, self->innerbottom,
 +                XMoveResizeWindow(obt_display, self->innerbottom,
                                    self->size.left - self->cbwidth_l,
                                    self->size.top + self->client->area.height,
                                    self->client->area.width +
                                    self->cbwidth_l + self->cbwidth_r,
                                    self->cbwidth_b);
  
 -                XMoveResizeWindow(ob_display, self->innerblb,
 +                XMoveResizeWindow(obt_display, self->innerblb,
                                    0, 0,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->cbwidth_b);
 -                XMoveResizeWindow(ob_display, self->innerbrb,
 +                XMoveResizeWindow(obt_display, self->innerbrb,
                                    self->client->area.width +
                                    self->cbwidth_l + self->cbwidth_r -
                                    (ob_rr_theme->grip_width + self->bwidth),
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->cbwidth_b);
  
 -                XMapWindow(ob_display, self->innerbottom);
 -                XMapWindow(ob_display, self->innerblb);
 -                XMapWindow(ob_display, self->innerbrb);
 +                XMapWindow(obt_display, self->innerbottom);
 +                XMapWindow(obt_display, self->innerblb);
 +                XMapWindow(obt_display, self->innerbrb);
              } else {
 -                XUnmapWindow(ob_display, self->innerbottom);
 -                XUnmapWindow(ob_display, self->innerblb);
 -                XUnmapWindow(ob_display, self->innerbrb);
 +                XUnmapWindow(obt_display, self->innerbottom);
 +                XUnmapWindow(obt_display, self->innerblb);
 +                XUnmapWindow(obt_display, self->innerbrb);
              }
  
              if (self->bwidth) {
                  /* height of titleleft and titleright */
                  titlesides = (!self->max_horz ? ob_rr_theme->grip_width : 0);
  
 -                XMoveResizeWindow(ob_display, self->titletop,
 +                XMoveResizeWindow(obt_display, self->titletop,
                                    ob_rr_theme->grip_width + self->bwidth, 0,
                                    /* width + bwidth*2 - bwidth*2 - grips*2 */
                                    self->width - ob_rr_theme->grip_width * 2,
                                    self->bwidth);
 -                XMoveResizeWindow(ob_display, self->titletopleft,
 +                XMoveResizeWindow(obt_display, self->titletopleft,
                                    0, 0,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->bwidth);
 -                XMoveResizeWindow(ob_display, self->titletopright,
 +                XMoveResizeWindow(obt_display, self->titletopright,
                                    self->client->area.width +
                                    self->size.left + self->size.right -
                                    ob_rr_theme->grip_width - self->bwidth,
                                    self->bwidth);
  
                  if (titlesides > 0) {
 -                    XMoveResizeWindow(ob_display, self->titleleft,
 +                    XMoveResizeWindow(obt_display, self->titleleft,
                                        0, self->bwidth,
                                        self->bwidth,
                                        titlesides);
 -                    XMoveResizeWindow(ob_display, self->titleright,
 +                    XMoveResizeWindow(obt_display, self->titleright,
                                        self->client->area.width +
                                        self->size.left + self->size.right -
                                        self->bwidth,
                                        self->bwidth,
                                        titlesides);
  
 -                    XMapWindow(ob_display, self->titleleft);
 -                    XMapWindow(ob_display, self->titleright);
 +                    XMapWindow(obt_display, self->titleleft);
 +                    XMapWindow(obt_display, self->titleright);
                  } else {
 -                    XUnmapWindow(ob_display, self->titleleft);
 -                    XUnmapWindow(ob_display, self->titleright);
 +                    XUnmapWindow(obt_display, self->titleleft);
 +                    XUnmapWindow(obt_display, self->titleright);
                  }
  
 -                XMapWindow(ob_display, self->titletop);
 -                XMapWindow(ob_display, self->titletopleft);
 -                XMapWindow(ob_display, self->titletopright);
 +                XMapWindow(obt_display, self->titletop);
 +                XMapWindow(obt_display, self->titletopleft);
 +                XMapWindow(obt_display, self->titletopright);
  
                  if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
 -                    XMoveResizeWindow(ob_display, self->titlebottom,
 +                    XMoveResizeWindow(obt_display, self->titlebottom,
                                        (self->max_horz ? 0 : self->bwidth),
                                        ob_rr_theme->title_height + self->bwidth,
                                        self->width,
                                        self->bwidth);
  
 -                    XMapWindow(ob_display, self->titlebottom);
 +                    XMapWindow(obt_display, self->titlebottom);
                  } else
 -                    XUnmapWindow(ob_display, self->titlebottom);
 +                    XUnmapWindow(obt_display, self->titlebottom);
              } else {
 -                XUnmapWindow(ob_display, self->titlebottom);
 +                XUnmapWindow(obt_display, self->titlebottom);
  
 -                XUnmapWindow(ob_display, self->titletop);
 -                XUnmapWindow(ob_display, self->titletopleft);
 -                XUnmapWindow(ob_display, self->titletopright);
 -                XUnmapWindow(ob_display, self->titleleft);
 -                XUnmapWindow(ob_display, self->titleright);
 +                XUnmapWindow(obt_display, self->titletop);
 +                XUnmapWindow(obt_display, self->titletopleft);
 +                XUnmapWindow(obt_display, self->titletopright);
 +                XUnmapWindow(obt_display, self->titleleft);
 +                XUnmapWindow(obt_display, self->titleright);
              }
  
              if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
 -                XMoveResizeWindow(ob_display, self->title,
 +                XMoveResizeWindow(obt_display, self->title,
                                    (self->max_horz ? 0 : self->bwidth),
                                    self->bwidth,
                                    self->width, ob_rr_theme->title_height);
  
 -                XMapWindow(ob_display, self->title);
 +                XMapWindow(obt_display, self->title);
  
                  if (self->decorations & OB_FRAME_DECOR_GRIPS) {
 -                    XMoveResizeWindow(ob_display, self->topresize,
 +                    XMoveResizeWindow(obt_display, self->topresize,
                                        ob_rr_theme->grip_width,
                                        0,
                                        self->width - ob_rr_theme->grip_width *2,
                                        ob_rr_theme->paddingy + 1);
  
 -                    XMoveWindow(ob_display, self->tltresize, 0, 0);
 -                    XMoveWindow(ob_display, self->tllresize, 0, 0);
 -                    XMoveWindow(ob_display, self->trtresize,
 +                    XMoveWindow(obt_display, self->tltresize, 0, 0);
 +                    XMoveWindow(obt_display, self->tllresize, 0, 0);
 +                    XMoveWindow(obt_display, self->trtresize,
                                  self->width - ob_rr_theme->grip_width, 0);
 -                    XMoveWindow(ob_display, self->trrresize,
 +                    XMoveWindow(obt_display, self->trrresize,
                                  self->width - ob_rr_theme->paddingx - 1, 0);
  
 -                    XMapWindow(ob_display, self->topresize);
 -                    XMapWindow(ob_display, self->tltresize);
 -                    XMapWindow(ob_display, self->tllresize);
 -                    XMapWindow(ob_display, self->trtresize);
 -                    XMapWindow(ob_display, self->trrresize);
 +                    XMapWindow(obt_display, self->topresize);
 +                    XMapWindow(obt_display, self->tltresize);
 +                    XMapWindow(obt_display, self->tllresize);
 +                    XMapWindow(obt_display, self->trtresize);
 +                    XMapWindow(obt_display, self->trrresize);
                  } else {
 -                    XUnmapWindow(ob_display, self->topresize);
 -                    XUnmapWindow(ob_display, self->tltresize);
 -                    XUnmapWindow(ob_display, self->tllresize);
 -                    XUnmapWindow(ob_display, self->trtresize);
 -                    XUnmapWindow(ob_display, self->trrresize);
 +                    XUnmapWindow(obt_display, self->topresize);
 +                    XUnmapWindow(obt_display, self->tltresize);
 +                    XUnmapWindow(obt_display, self->tllresize);
 +                    XUnmapWindow(obt_display, self->trtresize);
 +                    XUnmapWindow(obt_display, self->trrresize);
                  }
              } else
 -                XUnmapWindow(ob_display, self->title);
 +                XUnmapWindow(obt_display, self->title);
          }
  
          if ((self->decorations & OB_FRAME_DECOR_TITLEBAR))
              gint sidebwidth = self->max_horz ? 0 : self->bwidth;
  
              if (self->bwidth && self->size.bottom) {
 -                XMoveResizeWindow(ob_display, self->handlebottom,
 +                XMoveResizeWindow(obt_display, self->handlebottom,
                                    ob_rr_theme->grip_width +
                                    self->bwidth + sidebwidth,
                                    self->size.top + self->client->area.height +
                                                   sidebwidth) * 2,
                                    self->bwidth);
  
 +
                  if (sidebwidth) {
 -                    XMoveResizeWindow(ob_display, self->lgripleft,
 +                    XMoveResizeWindow(obt_display, self->lgripleft,
                                        0,
                                        self->size.top +
                                        self->client->area.height +
                                        (!self->max_horz ?
                                         ob_rr_theme->grip_width :
                                         self->size.bottom - self->cbwidth_b));
 -                    XMoveResizeWindow(ob_display, self->rgripright,
 +                    XMoveResizeWindow(obt_display, self->rgripright,
                                    self->size.left +
                                        self->client->area.width +
                                        self->size.right - self->bwidth,
                                         ob_rr_theme->grip_width :
                                         self->size.bottom - self->cbwidth_b));
  
 -                    XMapWindow(ob_display, self->lgripleft);
 -                    XMapWindow(ob_display, self->rgripright);
 +                    XMapWindow(obt_display, self->lgripleft);
 +                    XMapWindow(obt_display, self->rgripright);
                  } else {
 -                    XUnmapWindow(ob_display, self->lgripleft);
 -                    XUnmapWindow(ob_display, self->rgripright);
 +                    XUnmapWindow(obt_display, self->lgripleft);
 +                    XUnmapWindow(obt_display, self->rgripright);
                  }
  
 -                XMoveResizeWindow(ob_display, self->lgripbottom,
 +                XMoveResizeWindow(obt_display, self->lgripbottom,
                                    sidebwidth,
                                    self->size.top + self->client->area.height +
                                    self->size.bottom - self->bwidth,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->bwidth);
 -                XMoveResizeWindow(ob_display, self->rgripbottom,
 +                XMoveResizeWindow(obt_display, self->rgripbottom,
                                    self->size.left + self->client->area.width +
                                    self->size.right - self->bwidth - sidebwidth-
                                    ob_rr_theme->grip_width,
                                    ob_rr_theme->grip_width + self->bwidth,
                                    self->bwidth);
  
 -                XMapWindow(ob_display, self->handlebottom);
 -                XMapWindow(ob_display, self->lgripbottom);
 -                XMapWindow(ob_display, self->rgripbottom);
 +                XMapWindow(obt_display, self->handlebottom);
 +                XMapWindow(obt_display, self->lgripbottom);
 +                XMapWindow(obt_display, self->rgripbottom);
  
                  if (self->decorations & OB_FRAME_DECOR_HANDLE &&
                      ob_rr_theme->handle_height > 0)
                  {
 -                    XMoveResizeWindow(ob_display, self->handletop,
 +                    XMoveResizeWindow(obt_display, self->handletop,
                                        ob_rr_theme->grip_width +
                                        self->bwidth + sidebwidth,
                                        FRAME_HANDLE_Y(self),
                                        self->width - (ob_rr_theme->grip_width +
                                                       sidebwidth) * 2,
                                        self->bwidth);
 -                    XMapWindow(ob_display, self->handletop);
 +                    XMapWindow(obt_display, self->handletop);
  
                      if (self->decorations & OB_FRAME_DECOR_GRIPS) {
 -                        XMoveResizeWindow(ob_display, self->handleleft,
 +                        XMoveResizeWindow(obt_display, self->handleleft,
                                            ob_rr_theme->grip_width,
                                            0,
                                            self->bwidth,
                                            ob_rr_theme->handle_height);
 -                        XMoveResizeWindow(ob_display, self->handleright,
 +                        XMoveResizeWindow(obt_display, self->handleright,
                                            self->width -
                                            ob_rr_theme->grip_width -
                                            self->bwidth,
                                            self->bwidth,
                                            ob_rr_theme->handle_height);
  
 -                        XMoveResizeWindow(ob_display, self->lgriptop,
 +                        XMoveResizeWindow(obt_display, self->lgriptop,
                                            sidebwidth,
                                            FRAME_HANDLE_Y(self),
                                            ob_rr_theme->grip_width +
                                            self->bwidth,
                                            self->bwidth);
 -                        XMoveResizeWindow(ob_display, self->rgriptop,
 +                        XMoveResizeWindow(obt_display, self->rgriptop,
                                            self->size.left +
                                            self->client->area.width +
                                            self->size.right - self->bwidth -
                                            self->bwidth,
                                            self->bwidth);
  
 -                        XMapWindow(ob_display, self->handleleft);
 -                        XMapWindow(ob_display, self->handleright);
 -                        XMapWindow(ob_display, self->lgriptop);
 -                        XMapWindow(ob_display, self->rgriptop);
 +                        XMapWindow(obt_display, self->handleleft);
 +                        XMapWindow(obt_display, self->handleright);
 +                        XMapWindow(obt_display, self->lgriptop);
 +                        XMapWindow(obt_display, self->rgriptop);
                      } else {
 -                        XUnmapWindow(ob_display, self->handleleft);
 -                        XUnmapWindow(ob_display, self->handleright);
 -                        XUnmapWindow(ob_display, self->lgriptop);
 -                        XUnmapWindow(ob_display, self->rgriptop);
 +                        XUnmapWindow(obt_display, self->handleleft);
 +                        XUnmapWindow(obt_display, self->handleright);
 +                        XUnmapWindow(obt_display, self->lgriptop);
 +                        XUnmapWindow(obt_display, self->rgriptop);
                      }
                  } else {
 -                    XUnmapWindow(ob_display, self->handleleft);
 -                    XUnmapWindow(ob_display, self->handleright);
 -                    XUnmapWindow(ob_display, self->lgriptop);
 -                    XUnmapWindow(ob_display, self->rgriptop);
 +                    XUnmapWindow(obt_display, self->handleleft);
 +                    XUnmapWindow(obt_display, self->handleright);
 +                    XUnmapWindow(obt_display, self->lgriptop);
 +                    XUnmapWindow(obt_display, self->rgriptop);
  
 -                    XUnmapWindow(ob_display, self->handletop);
 +                    XUnmapWindow(obt_display, self->handletop);
                  }
              } else {
 -                XUnmapWindow(ob_display, self->handleleft);
 -                XUnmapWindow(ob_display, self->handleright);
 -                XUnmapWindow(ob_display, self->lgriptop);
 -                XUnmapWindow(ob_display, self->rgriptop);
 -
 -                XUnmapWindow(ob_display, self->handletop);
 -
 -                XUnmapWindow(ob_display, self->handlebottom);
 -                XUnmapWindow(ob_display, self->lgripleft);
 -                XUnmapWindow(ob_display, self->rgripright);
 -                XUnmapWindow(ob_display, self->lgripbottom);
 -                XUnmapWindow(ob_display, self->rgripbottom);
 +                XUnmapWindow(obt_display, self->handleleft);
 +                XUnmapWindow(obt_display, self->handleright);
 +                XUnmapWindow(obt_display, self->lgriptop);
 +                XUnmapWindow(obt_display, self->rgriptop);
 +
 +                XUnmapWindow(obt_display, self->handletop);
 +
 +                XUnmapWindow(obt_display, self->handlebottom);
 +                XUnmapWindow(obt_display, self->lgripleft);
 +                XUnmapWindow(obt_display, self->rgripright);
 +                XUnmapWindow(obt_display, self->lgripbottom);
 +                XUnmapWindow(obt_display, self->rgripbottom);
              }
  
              if (self->decorations & OB_FRAME_DECOR_HANDLE &&
                  ob_rr_theme->handle_height > 0)
              {
 -                XMoveResizeWindow(ob_display, self->handle,
 +                XMoveResizeWindow(obt_display, self->handle,
                                    sidebwidth,
                                    FRAME_HANDLE_Y(self) + self->bwidth,
                                    self->width, ob_rr_theme->handle_height);
 -                XMapWindow(ob_display, self->handle);
 +                XMapWindow(obt_display, self->handle);
  
                  if (self->decorations & OB_FRAME_DECOR_GRIPS) {
 -                    XMoveResizeWindow(ob_display, self->lgrip,
 +                    XMoveResizeWindow(obt_display, self->lgrip,
                                        0, 0,
                                        ob_rr_theme->grip_width,
                                        ob_rr_theme->handle_height);
 -                    XMoveResizeWindow(ob_display, self->rgrip,
 +                    XMoveResizeWindow(obt_display, self->rgrip,
                                        self->width - ob_rr_theme->grip_width,
                                        0,
                                        ob_rr_theme->grip_width,
                                        ob_rr_theme->handle_height);
  
 -                    XMapWindow(ob_display, self->lgrip);
 -                    XMapWindow(ob_display, self->rgrip);
 +                    XMapWindow(obt_display, self->lgrip);
 +                    XMapWindow(obt_display, self->rgrip);
                  } else {
 -                    XUnmapWindow(ob_display, self->lgrip);
 -                    XUnmapWindow(ob_display, self->rgrip);
 +                    XUnmapWindow(obt_display, self->lgrip);
 +                    XUnmapWindow(obt_display, self->rgrip);
                  }
              } else {
 -                XUnmapWindow(ob_display, self->lgrip);
 -                XUnmapWindow(ob_display, self->rgrip);
 +                XUnmapWindow(obt_display, self->lgrip);
 +                XUnmapWindow(obt_display, self->rgrip);
  
 -                XUnmapWindow(ob_display, self->handle);
 +                XUnmapWindow(obt_display, self->handle);
              }
  
              if (self->bwidth && !self->max_horz &&
                  (self->client->area.height + self->size.top +
                   self->size.bottom) > ob_rr_theme->grip_width * 2)
              {
 -                XMoveResizeWindow(ob_display, self->left,
 +                XMoveResizeWindow(obt_display, self->left,
                                    0,
                                    self->bwidth + ob_rr_theme->grip_width,
                                    self->bwidth,
                                    self->size.top + self->size.bottom -
                                    ob_rr_theme->grip_width * 2);
  
 -                XMapWindow(ob_display, self->left);
 +                XMapWindow(obt_display, self->left);
              } else
 -                XUnmapWindow(ob_display, self->left);
 +                XUnmapWindow(obt_display, self->left);
  
              if (self->bwidth && !self->max_horz &&
                  (self->client->area.height + self->size.top +
                   self->size.bottom) > ob_rr_theme->grip_width * 2)
              {
 -                XMoveResizeWindow(ob_display, self->right,
 +                XMoveResizeWindow(obt_display, self->right,
                                    self->client->area.width + self->cbwidth_l +
                                    self->cbwidth_r + self->bwidth,
                                    self->bwidth + ob_rr_theme->grip_width,
                                    self->size.top + self->size.bottom -
                                    ob_rr_theme->grip_width * 2);
  
 -                XMapWindow(ob_display, self->right);
 +                XMapWindow(obt_display, self->right);
              } else
 -                XUnmapWindow(ob_display, self->right);
 +                XUnmapWindow(obt_display, self->right);
  
 -            XMoveResizeWindow(ob_display, self->backback,
 +            XMoveResizeWindow(obt_display, self->backback,
                                self->size.left, self->size.top,
                                self->client->area.width,
                                self->client->area.height);
                 but don't do this during an iconify animation. it will be
                 reflected afterwards.
              */
 -            XMoveResizeWindow(ob_display, self->window,
 +            XMoveResizeWindow(obt_display, self->window,
                                self->area.x,
                                self->area.y,
                                self->area.width,
             also this correctly positions the client when it maps.
             this also needs to be run when the frame's decorations sizes change!
          */
 -        XMoveWindow(ob_display, self->client->window,
 +        XMoveWindow(obt_display, self->client->window,
                      self->size.left, self->size.top);
  
          if (resized) {
              vals[1] = self->size.right;
              vals[2] = self->size.top;
              vals[3] = self->size.bottom;
 -            PROP_SETA32(self->client->window, net_frame_extents,
 -                        cardinal, vals, 4);
 -            PROP_SETA32(self->client->window, kde_net_wm_frame_strut,
 -                        cardinal, vals, 4);
 +            OBT_PROP_SETA32(self->client->window, NET_FRAME_EXTENTS,
 +                            CARDINAL, vals, 4);
 +            OBT_PROP_SETA32(self->client->window, KDE_NET_WM_FRAME_STRUT,
 +                            CARDINAL, vals, 4);
          }
  
          /* if this occurs while we are focus cycling, the indicator needs to
              focus_cycle_update_indicator(self->client);
      }
      if (resized && (self->decorations & OB_FRAME_DECOR_TITLEBAR))
 -        XResizeWindow(ob_display, self->label, self->label_width,
 +        XResizeWindow(obt_display, self->label, self->label_width,
                        ob_rr_theme->label_height);
  
  }
@@@ -884,58 -885,58 +884,58 @@@ static void frame_adjust_cursors(ObFram
          /* these ones turn off when max vert, and some when shaded */
          a.cursor = ob_cursor(r && topbot && !sh ?
                               OB_CURSOR_NORTH : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->topresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->titletop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->topresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titletop, CWCursor, &a);
          a.cursor = ob_cursor(r && topbot ? OB_CURSOR_SOUTH : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->handle, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handletop, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handlebottom, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handle, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handletop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handlebottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbottom, CWCursor, &a);
  
          /* these ones change when shaded */
          a.cursor = ob_cursor(r ? (sh ? OB_CURSOR_WEST : OB_CURSOR_NORTHWEST) :
                               OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->titleleft, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->tltresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->tllresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->titletopleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titleleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->tltresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->tllresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titletopleft, CWCursor, &a);
          a.cursor = ob_cursor(r ? (sh ? OB_CURSOR_EAST : OB_CURSOR_NORTHEAST) :
                               OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->titleright, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->trtresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->trrresize, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->titletopright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titleright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->trtresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->trrresize, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->titletopright, CWCursor,&a);
  
          /* these ones are pretty static */
          a.cursor = ob_cursor(r ? OB_CURSOR_WEST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->left, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->left, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerleft, CWCursor, &a);
          a.cursor = ob_cursor(r ? OB_CURSOR_EAST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->right, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->right, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerright, CWCursor, &a);
          a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHWEST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->lgrip, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handleleft, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->lgripleft, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->lgriptop, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->lgripbottom, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbll, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerblb, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgrip, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handleleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgripleft, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgriptop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->lgripbottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbll, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerblb, CWCursor, &a);
          a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHEAST : OB_CURSOR_NONE);
 -        XChangeWindowAttributes(ob_display, self->rgrip, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->handleright, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->rgripright, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->rgriptop, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->rgripbottom, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbrr, CWCursor, &a);
 -        XChangeWindowAttributes(ob_display, self->innerbrb, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgrip, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->handleright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgripright, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgriptop, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->rgripbottom, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbrr, CWCursor, &a);
 +        XChangeWindowAttributes(obt_display, self->innerbrb, CWCursor, &a);
      }
  }
  
  void frame_adjust_client_area(ObFrame *self)
  {
      /* adjust the window which is there to prevent flashing on unmap */
 -    XMoveResizeWindow(ob_display, self->backfront, 0, 0,
 +    XMoveResizeWindow(obt_display, self->backfront, 0, 0,
                        self->client->area.width,
                        self->client->area.height);
  }
@@@ -948,10 -949,13 +948,13 @@@ void frame_adjust_state(ObFrame *self
  
  void frame_adjust_focus(ObFrame *self, gboolean hilite)
  {
+     ob_debug_type(OB_DEBUG_FOCUS,
+                   "Frame for 0x%x has focus: %d\n",
+                   self->client->window, hilite);
      self->focused = hilite;
      self->need_render = TRUE;
      framerender_frame(self);
 -    XFlush(ob_display);
 +    XFlush(obt_display);
  }
  
  void frame_adjust_title(ObFrame *self)
@@@ -974,7 -978,7 +977,7 @@@ void frame_grab_client(ObFrame *self
      */
  
      /* reparent the client to the frame */
 -    XReparentWindow(ob_display, self->client->window, self->window, 0, 0);
 +    XReparentWindow(obt_display, self->client->window, self->window, 0, 0);
  
      /*
        When reparenting the client window, it is usually not mapped yet, since
  
      /* select the event mask on the client's parent (to receive config/map
         req's) the ButtonPress is to catch clicks on the client border */
 -    XSelectInput(ob_display, self->window, FRAME_EVENTMASK);
 +    XSelectInput(obt_display, self->window, FRAME_EVENTMASK);
  
      /* set all the windows for the frame in the window_map */
 -    g_hash_table_insert(window_map, &self->window, self->client);
 -    g_hash_table_insert(window_map, &self->backback, self->client);
 -    g_hash_table_insert(window_map, &self->backfront, self->client);
 -    g_hash_table_insert(window_map, &self->innerleft, self->client);
 -    g_hash_table_insert(window_map, &self->innertop, self->client);
 -    g_hash_table_insert(window_map, &self->innerright, self->client);
 -    g_hash_table_insert(window_map, &self->innerbottom, self->client);
 -    g_hash_table_insert(window_map, &self->innerblb, self->client);
 -    g_hash_table_insert(window_map, &self->innerbll, self->client);
 -    g_hash_table_insert(window_map, &self->innerbrb, self->client);
 -    g_hash_table_insert(window_map, &self->innerbrr, self->client);
 -    g_hash_table_insert(window_map, &self->title, self->client);
 -    g_hash_table_insert(window_map, &self->label, self->client);
 -    g_hash_table_insert(window_map, &self->max, self->client);
 -    g_hash_table_insert(window_map, &self->close, self->client);
 -    g_hash_table_insert(window_map, &self->desk, self->client);
 -    g_hash_table_insert(window_map, &self->shade, self->client);
 -    g_hash_table_insert(window_map, &self->icon, self->client);
 -    g_hash_table_insert(window_map, &self->iconify, self->client);
 -    g_hash_table_insert(window_map, &self->handle, self->client);
 -    g_hash_table_insert(window_map, &self->lgrip, self->client);
 -    g_hash_table_insert(window_map, &self->rgrip, self->client);
 -    g_hash_table_insert(window_map, &self->topresize, self->client);
 -    g_hash_table_insert(window_map, &self->tltresize, self->client);
 -    g_hash_table_insert(window_map, &self->tllresize, self->client);
 -    g_hash_table_insert(window_map, &self->trtresize, self->client);
 -    g_hash_table_insert(window_map, &self->trrresize, self->client);
 -    g_hash_table_insert(window_map, &self->left, self->client);
 -    g_hash_table_insert(window_map, &self->right, self->client);
 -    g_hash_table_insert(window_map, &self->titleleft, self->client);
 -    g_hash_table_insert(window_map, &self->titletop, self->client);
 -    g_hash_table_insert(window_map, &self->titletopleft, self->client);
 -    g_hash_table_insert(window_map, &self->titletopright, self->client);
 -    g_hash_table_insert(window_map, &self->titleright, self->client);
 -    g_hash_table_insert(window_map, &self->titlebottom, self->client);
 -    g_hash_table_insert(window_map, &self->handleleft, self->client);
 -    g_hash_table_insert(window_map, &self->handletop, self->client);
 -    g_hash_table_insert(window_map, &self->handleright, self->client);
 -    g_hash_table_insert(window_map, &self->handlebottom, self->client);
 -    g_hash_table_insert(window_map, &self->lgripleft, self->client);
 -    g_hash_table_insert(window_map, &self->lgriptop, self->client);
 -    g_hash_table_insert(window_map, &self->lgripbottom, self->client);
 -    g_hash_table_insert(window_map, &self->rgripright, self->client);
 -    g_hash_table_insert(window_map, &self->rgriptop, self->client);
 -    g_hash_table_insert(window_map, &self->rgripbottom, self->client);
 +    window_add(&self->window, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->backback, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->backfront, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innertop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerblb, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbll, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbrb, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->innerbrr, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->title, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->label, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->max, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->close, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->desk, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->shade, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->icon, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->iconify, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handle, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgrip, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgrip, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->topresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->tltresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->tllresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->trtresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->trrresize, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->left, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->right, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titleleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titletop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titletopleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titletopright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titleright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->titlebottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handleleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handletop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handleright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->handlebottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgripleft, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgriptop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->lgripbottom, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgripright, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgriptop, CLIENT_AS_WINDOW(self->client));
 +    window_add(&self->rgripbottom, CLIENT_AS_WINDOW(self->client));
  }
  
  void frame_release_client(ObFrame *self)
      gboolean reparent = TRUE;
  
      /* if there was any animation going on, kill it */
 -    ob_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 -                                     self, FALSE);
 +    obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 +                                      self, FALSE);
  
      /* check if the app has already reparented its window away */
 -    while (XCheckTypedWindowEvent(ob_display, self->client->window,
 +    while (XCheckTypedWindowEvent(obt_display, self->client->window,
                                    ReparentNotify, &ev))
      {
          /* This check makes sure we don't catch our own reparent action to
          */
          if (ev.xreparent.parent != self->window) {
              reparent = FALSE;
 -            XPutBackEvent(ob_display, &ev);
 +            XPutBackEvent(obt_display, &ev);
              break;
          }
      }
      if (reparent) {
          /* according to the ICCCM - if the client doesn't reparent itself,
             then we will reparent the window to root for them */
 -        XReparentWindow(ob_display, self->client->window,
 -                        RootWindow(ob_display, ob_screen),
 -                        self->client->area.x,
 -                        self->client->area.y);
 +        XReparentWindow(obt_display, self->client->window, obt_root(ob_screen),
 +                        self->client->area.x, self->client->area.y);
      }
  
      /* remove all the windows for the frame from the window_map */
 -    g_hash_table_remove(window_map, &self->window);
 -    g_hash_table_remove(window_map, &self->backback);
 -    g_hash_table_remove(window_map, &self->backfront);
 -    g_hash_table_remove(window_map, &self->innerleft);
 -    g_hash_table_remove(window_map, &self->innertop);
 -    g_hash_table_remove(window_map, &self->innerright);
 -    g_hash_table_remove(window_map, &self->innerbottom);
 -    g_hash_table_remove(window_map, &self->innerblb);
 -    g_hash_table_remove(window_map, &self->innerbll);
 -    g_hash_table_remove(window_map, &self->innerbrb);
 -    g_hash_table_remove(window_map, &self->innerbrr);
 -    g_hash_table_remove(window_map, &self->title);
 -    g_hash_table_remove(window_map, &self->label);
 -    g_hash_table_remove(window_map, &self->max);
 -    g_hash_table_remove(window_map, &self->close);
 -    g_hash_table_remove(window_map, &self->desk);
 -    g_hash_table_remove(window_map, &self->shade);
 -    g_hash_table_remove(window_map, &self->icon);
 -    g_hash_table_remove(window_map, &self->iconify);
 -    g_hash_table_remove(window_map, &self->handle);
 -    g_hash_table_remove(window_map, &self->lgrip);
 -    g_hash_table_remove(window_map, &self->rgrip);
 -    g_hash_table_remove(window_map, &self->topresize);
 -    g_hash_table_remove(window_map, &self->tltresize);
 -    g_hash_table_remove(window_map, &self->tllresize);
 -    g_hash_table_remove(window_map, &self->trtresize);
 -    g_hash_table_remove(window_map, &self->trrresize);
 -    g_hash_table_remove(window_map, &self->left);
 -    g_hash_table_remove(window_map, &self->right);
 -    g_hash_table_remove(window_map, &self->titleleft);
 -    g_hash_table_remove(window_map, &self->titletop);
 -    g_hash_table_remove(window_map, &self->titletopleft);
 -    g_hash_table_remove(window_map, &self->titletopright);
 -    g_hash_table_remove(window_map, &self->titleright);
 -    g_hash_table_remove(window_map, &self->titlebottom);
 -    g_hash_table_remove(window_map, &self->handleleft);
 -    g_hash_table_remove(window_map, &self->handletop);
 -    g_hash_table_remove(window_map, &self->handleright);
 -    g_hash_table_remove(window_map, &self->handlebottom);
 -    g_hash_table_remove(window_map, &self->lgripleft);
 -    g_hash_table_remove(window_map, &self->lgriptop);
 -    g_hash_table_remove(window_map, &self->lgripbottom);
 -    g_hash_table_remove(window_map, &self->rgripright);
 -    g_hash_table_remove(window_map, &self->rgriptop);
 -    g_hash_table_remove(window_map, &self->rgripbottom);
 -
 -    ob_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
 +    window_remove(self->window);
 +    window_remove(self->backback);
 +    window_remove(self->backfront);
 +    window_remove(self->innerleft);
 +    window_remove(self->innertop);
 +    window_remove(self->innerright);
 +    window_remove(self->innerbottom);
 +    window_remove(self->innerblb);
 +    window_remove(self->innerbll);
 +    window_remove(self->innerbrb);
 +    window_remove(self->innerbrr);
 +    window_remove(self->title);
 +    window_remove(self->label);
 +    window_remove(self->max);
 +    window_remove(self->close);
 +    window_remove(self->desk);
 +    window_remove(self->shade);
 +    window_remove(self->icon);
 +    window_remove(self->iconify);
 +    window_remove(self->handle);
 +    window_remove(self->lgrip);
 +    window_remove(self->rgrip);
 +    window_remove(self->topresize);
 +    window_remove(self->tltresize);
 +    window_remove(self->tllresize);
 +    window_remove(self->trtresize);
 +    window_remove(self->trrresize);
 +    window_remove(self->left);
 +    window_remove(self->right);
 +    window_remove(self->titleleft);
 +    window_remove(self->titletop);
 +    window_remove(self->titletopleft);
 +    window_remove(self->titletopright);
 +    window_remove(self->titleright);
 +    window_remove(self->titlebottom);
 +    window_remove(self->handleleft);
 +    window_remove(self->handletop);
 +    window_remove(self->handleright);
 +    window_remove(self->handlebottom);
 +    window_remove(self->lgripleft);
 +    window_remove(self->lgriptop);
 +    window_remove(self->lgripbottom);
 +    window_remove(self->rgripright);
 +    window_remove(self->rgriptop);
 +    window_remove(self->rgripbottom);
 +
 +    obt_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
  }
  
  /* is there anything present between us and the label? */
@@@ -1236,53 -1242,53 +1239,53 @@@ static void layout_title(ObFrame *self
  
      /* position and map the elements */
      if (self->icon_on) {
 -        XMapWindow(ob_display, self->icon);
 -        XMoveWindow(ob_display, self->icon, self->icon_x,
 +        XMapWindow(obt_display, self->icon);
 +        XMoveWindow(obt_display, self->icon, self->icon_x,
                      ob_rr_theme->paddingy);
      } else
 -        XUnmapWindow(ob_display, self->icon);
 +        XUnmapWindow(obt_display, self->icon);
  
      if (self->desk_on) {
 -        XMapWindow(ob_display, self->desk);
 -        XMoveWindow(ob_display, self->desk, self->desk_x,
 +        XMapWindow(obt_display, self->desk);
 +        XMoveWindow(obt_display, self->desk, self->desk_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->desk);
 +        XUnmapWindow(obt_display, self->desk);
  
      if (self->shade_on) {
 -        XMapWindow(ob_display, self->shade);
 -        XMoveWindow(ob_display, self->shade, self->shade_x,
 +        XMapWindow(obt_display, self->shade);
 +        XMoveWindow(obt_display, self->shade, self->shade_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->shade);
 +        XUnmapWindow(obt_display, self->shade);
  
      if (self->iconify_on) {
 -        XMapWindow(ob_display, self->iconify);
 -        XMoveWindow(ob_display, self->iconify, self->iconify_x,
 +        XMapWindow(obt_display, self->iconify);
 +        XMoveWindow(obt_display, self->iconify, self->iconify_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->iconify);
 +        XUnmapWindow(obt_display, self->iconify);
  
      if (self->max_on) {
 -        XMapWindow(ob_display, self->max);
 -        XMoveWindow(ob_display, self->max, self->max_x,
 +        XMapWindow(obt_display, self->max);
 +        XMoveWindow(obt_display, self->max, self->max_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->max);
 +        XUnmapWindow(obt_display, self->max);
  
      if (self->close_on) {
 -        XMapWindow(ob_display, self->close);
 -        XMoveWindow(ob_display, self->close, self->close_x,
 +        XMapWindow(obt_display, self->close);
 +        XMoveWindow(obt_display, self->close, self->close_x,
                      ob_rr_theme->paddingy + 1);
      } else
 -        XUnmapWindow(ob_display, self->close);
 +        XUnmapWindow(obt_display, self->close);
  
      if (self->label_on && self->label_width > 0) {
 -        XMapWindow(ob_display, self->label);
 -        XMoveWindow(ob_display, self->label, self->label_x,
 +        XMapWindow(obt_display, self->label);
 +        XMoveWindow(obt_display, self->label, self->label_x,
                      ob_rr_theme->paddingy);
      } else
 -        XUnmapWindow(ob_display, self->label);
 +        XUnmapWindow(obt_display, self->label);
  }
  
  ObFrameContext frame_context_from_string(const gchar *name)
@@@ -1337,7 -1343,7 +1340,7 @@@ ObFrameContext frame_context(ObClient *
      if (moveresize_in_progress)
          return OB_FRAME_CONTEXT_MOVE_RESIZE;
  
 -    if (win == RootWindow(ob_display, ob_screen))
 +    if (win == obt_root(ob_screen))
          return OB_FRAME_CONTEXT_ROOT ;
      if (client == NULL) return OB_FRAME_CONTEXT_NONE;
      if (win == client->window) {
@@@ -1630,12 -1636,12 +1633,12 @@@ void frame_flash_start(ObFrame *self
      self->flash_on = self->focused;
  
      if (!self->flashing)
 -        ob_main_loop_timeout_add(ob_main_loop,
 -                                 G_USEC_PER_SEC * 0.6,
 -                                 flash_timeout,
 -                                 self,
 -                                 g_direct_equal,
 -                                 flash_done);
 +        obt_main_loop_timeout_add(ob_main_loop,
 +                                  G_USEC_PER_SEC * 0.6,
 +                                  flash_timeout,
 +                                  self,
 +                                  g_direct_equal,
 +                                  flash_done);
      g_get_current_time(&self->flash_end);
      g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5);
  
@@@ -1721,8 -1727,8 +1724,8 @@@ static gboolean frame_animate_iconify(g
          h = self->size.top; /* just the titlebar */
      }
  
 -    XMoveResizeWindow(ob_display, self->window, x, y, w, h);
 -    XFlush(ob_display);
 +    XMoveResizeWindow(obt_display, self->window, x, y, w, h);
 +    XFlush(obt_display);
  
      if (time == 0)
          frame_end_iconify_animation(self);
@@@ -1736,7 -1742,7 +1739,7 @@@ void frame_end_iconify_animation(ObFram
      if (self->iconify_animation_going == 0) return;
  
      if (!self->visible)
 -        XUnmapWindow(ob_display, self->window);
 +        XUnmapWindow(obt_display, self->window);
      else {
          /* Send a ConfigureNotify when the animation is done, this fixes
             KDE's pager showing the window in the wrong place.  since the
      /* we're not animating any more ! */
      self->iconify_animation_going = 0;
  
 -    XMoveResizeWindow(ob_display, self->window,
 +    XMoveResizeWindow(obt_display, self->window,
                        self->area.x, self->area.y,
                        self->area.width, self->area.height);
      /* we delay re-rendering until after we're done animating */
      framerender_frame(self);
 -    XFlush(ob_display);
 +    XFlush(obt_display);
  }
  
  void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying)
      }
  
      if (new_anim) {
 -        ob_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 -                                         self, FALSE);
 -        ob_main_loop_timeout_add(ob_main_loop,
 -                                 FRAME_ANIMATE_ICONIFY_STEP_TIME,
 -                                 frame_animate_iconify, self,
 -                                 g_direct_equal, NULL);
 +        obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
 +                                          self, FALSE);
 +        obt_main_loop_timeout_add(ob_main_loop,
 +                                  FRAME_ANIMATE_ICONIFY_STEP_TIME,
 +                                  frame_animate_iconify, self,
 +                                  g_direct_equal, NULL);
  
          /* do the first step */
          frame_animate_iconify(self);
  
          /* show it during the animation even if it is not "visible" */
          if (!self->visible)
 -            XMapWindow(ob_display, self->window);
 +            XMapWindow(obt_display, self->window);
      }
  }
diff --combined openbox/keyboard.c
index 410eb6e0aaa139bd66967afb6ffae8414a75dafa,aebee293f760998e2e4abd94db8124421cc66b72..ade18d04c6d52a8e72735155e36c811753dff233
@@@ -17,6 -17,7 +17,6 @@@
     See the COPYING file for a copy of the GNU General Public License.
  */
  
 -#include "mainloop.h"
  #include "focus.h"
  #include "screen.h"
  #include "frame.h"
@@@ -25,6 -26,7 +25,6 @@@
  #include "grab.h"
  #include "client.h"
  #include "actions.h"
 -#include "prop.h"
  #include "menuframe.h"
  #include "config.h"
  #include "keytree.h"
@@@ -44,20 -46,20 +44,20 @@@ static void grab_keys(gboolean grab
  {
      KeyBindingTree *p;
  
 -    ungrab_all_keys(RootWindow(ob_display, ob_screen));
 +    ungrab_all_keys(obt_root(ob_screen));
  
      if (grab) {
          p = curpos ? curpos->first_child : keyboard_firstnode;
          while (p) {
              if (p->key)
 -                grab_key(p->key, p->state, RootWindow(ob_display, ob_screen),
 +                grab_key(p->key, p->state, obt_root(ob_screen),
                           GrabModeAsync);
              p = p->next_sibling;
          }
          if (curpos)
              grab_key(config_keyboard_reset_keycode,
                       config_keyboard_reset_state,
 -                     RootWindow(ob_display, ob_screen), GrabModeAsync);
 +                     obt_root(ob_screen), GrabModeAsync);
      }
  }
  
@@@ -89,7 -91,7 +89,7 @@@ static void set_curpos(KeyBindingTree *
              g_free(oldtext);
          }
  
-         a = screen_physical_area_active();
+         a = screen_physical_area_primary();
          popup_position(popup, NorthWestGravity, a->x + 10, a->y + 10);
          /* 1 second delay for the popup to show */
          popup_delay_show(popup, G_USEC_PER_SEC, text);
@@@ -219,7 -221,7 +219,7 @@@ void keyboard_event(ObClient *client, c
      if (e->xkey.keycode == config_keyboard_reset_keycode &&
          e->xkey.state == config_keyboard_reset_state)
      {
 -        ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
 +        obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
          keyboard_reset_chains(-1);
          return;
      }
                  menu_frame_hide_all();
  
              if (p->first_child != NULL) { /* part of a chain */
 -                ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
 +                obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
                  /* 3 second timeout for chains */
 -                ob_main_loop_timeout_add(ob_main_loop, 3 * G_USEC_PER_SEC,
 -                                         chain_timeout, NULL,
 -                                         g_direct_equal, NULL);
 +                obt_main_loop_timeout_add(ob_main_loop, 3 * G_USEC_PER_SEC,
 +                                          chain_timeout, NULL,
 +                                          g_direct_equal, NULL);
                  set_curpos(p);
              } else if (p->chroot)         /* an empty chroot */
                  set_curpos(p);
@@@ -314,7 -316,7 +314,7 @@@ void keyboard_startup(gboolean reconfig
  
  void keyboard_shutdown(gboolean reconfig)
  {
 -    ob_main_loop_timeout_remove(ob_main_loop, chain_timeout);
 +    obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
  
      keyboard_unbind_all();
      set_curpos(NULL);
diff --combined openbox/openbox.c
index e912c64c02c6f42e7553796ce3f6a49fdeac5664,60e147c357eeee55a304a0db3f81905e45049184..29506c00b74b681b671a65b7502450e3781a6c1a
  #include "openbox.h"
  #include "session.h"
  #include "dock.h"
 -#include "modkeys.h"
  #include "event.h"
  #include "menu.h"
  #include "client.h"
 -#include "xerror.h"
 -#include "prop.h"
  #include "screen.h"
  #include "actions.h"
  #include "startupnotify.h"
  #include "framerender.h"
  #include "keyboard.h"
  #include "mouse.h"
 -#include "extensions.h"
  #include "menuframe.h"
  #include "grab.h"
  #include "group.h"
  #include "config.h"
  #include "ping.h"
 -#include "mainloop.h"
  #include "prompt.h"
  #include "gettext.h"
 -#include "parser/parse.h"
  #include "render/render.h"
  #include "render/theme.h"
 +#include "obt/display.h"
 +#include "obt/prop.h"
 +#include "obt/keyboard.h"
 +#include "obt/parse.h"
  
  #ifdef HAVE_FCNTL_H
  #  include <fcntl.h>
@@@ -86,7 -88,8 +86,7 @@@
  RrInstance   *ob_rr_inst;
  RrImageCache *ob_rr_icons;
  RrTheme      *ob_rr_theme;
 -ObMainLoop   *ob_main_loop;
 -Display      *ob_display;
 +ObtMainLoop  *ob_main_loop;
  gint          ob_screen;
  gboolean      ob_replace_wm = FALSE;
  gboolean      ob_sm_use = TRUE;
@@@ -119,8 -122,6 +119,8 @@@ gint main(gint argc, gchar **argv
  
      ob_set_state(OB_STATE_STARTING);
  
 +    ob_debug_startup();
 +
      /* initialize the locale */
      if (!setlocale(LC_ALL, ""))
          g_message("Couldn't set locale from environment.");
      program_name = g_path_get_basename(argv[0]);
      g_set_prgname(program_name);
  
 -    if (!remote_control) {
 -        parse_paths_startup();
 -
 +    if (!remote_control)
          session_startup(argc, argv);
 -    }
  
 -    ob_display = XOpenDisplay(NULL);
 -    if (ob_display == NULL)
 +    if (!obt_display_open(NULL))
          ob_exit_with_error(_("Failed to open the display from the DISPLAY environment variable."));
 -    if (fcntl(ConnectionNumber(ob_display), F_SETFD, 1) == -1)
 -        ob_exit_with_error("Failed to set display as close-on-exec");
  
      if (remote_control) {
 -        prop_startup();
 -
          /* Send client message telling the OB process to:
           * remote_control = 1 -> reconfigure
           * remote_control = 2 -> restart */
 -        PROP_MSG(RootWindow(ob_display, ob_screen),
 -                 ob_control, remote_control, 0, 0, 0);
 -        XCloseDisplay(ob_display);
 +        OBT_PROP_MSG(ob_screen, obt_root(ob_screen),
 +                     OB_CONTROL, remote_control, 0, 0, 0, 0);
 +        obt_display_close();
          exit(EXIT_SUCCESS);
      }
  
 -    ob_main_loop = ob_main_loop_new(ob_display);
 +    ob_main_loop = obt_main_loop_new();
  
      /* set up signal handler */
 -    ob_main_loop_signal_add(ob_main_loop, SIGUSR1, signal_handler, NULL, NULL);
 -    ob_main_loop_signal_add(ob_main_loop, SIGUSR2, signal_handler, NULL, NULL);
 -    ob_main_loop_signal_add(ob_main_loop, SIGTERM, signal_handler, NULL, NULL);
 -    ob_main_loop_signal_add(ob_main_loop, SIGINT, signal_handler, NULL, NULL);
 -    ob_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler, NULL, NULL);
 -    ob_main_loop_signal_add(ob_main_loop, SIGPIPE, signal_handler, NULL, NULL);
 -    ob_main_loop_signal_add(ob_main_loop, SIGCHLD, signal_handler, NULL, NULL);
 +    obt_main_loop_signal_add(ob_main_loop, SIGUSR1, signal_handler, NULL,NULL);
 +    obt_main_loop_signal_add(ob_main_loop, SIGUSR2, signal_handler, NULL,NULL);
 +    obt_main_loop_signal_add(ob_main_loop, SIGTERM, signal_handler, NULL,NULL);
 +    obt_main_loop_signal_add(ob_main_loop, SIGINT, signal_handler,  NULL,NULL);
 +    obt_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler,  NULL,NULL);
 +    obt_main_loop_signal_add(ob_main_loop, SIGPIPE, signal_handler, NULL,NULL);
 +    obt_main_loop_signal_add(ob_main_loop, SIGCHLD, signal_handler, NULL,NULL);
  
 -    ob_screen = DefaultScreen(ob_display);
 +    ob_screen = DefaultScreen(obt_display);
  
 -    ob_rr_inst = RrInstanceNew(ob_display, ob_screen);
 +    ob_rr_inst = RrInstanceNew(obt_display, ob_screen);
      if (ob_rr_inst == NULL)
          ob_exit_with_error(_("Failed to initialize the obrender library."));
      /* Saving 3 resizes of an RrImage makes a lot of sense for icons, as there
      */
      ob_rr_icons = RrImageCacheNew(3);
  
 -    XSynchronize(ob_display, xsync);
 +    XSynchronize(obt_display, xsync);
  
      /* check for locale support */
      if (!XSupportsLocale())
      if (!XSetLocaleModifiers(""))
          g_message(_("Cannot set locale modifiers for the X server."));
  
 -    /* set our error handler */
 -    XSetErrorHandler(xerror_handler);
 -
      /* set the DISPLAY environment variable for any lauched children, to the
         display we're using, so they open in the right place. */
 -    setenv("DISPLAY", DisplayString(ob_display), TRUE);
 +    setenv("DISPLAY", DisplayString(obt_display), TRUE);
  
      /* create available cursors */
      cursors[OB_CURSOR_NONE] = None;
      cursors[OB_CURSOR_NORTHWEST] = load_cursor("top_left_corner",
                                                 XC_top_left_corner);
  
 -    prop_startup(); /* get atoms values for the display */
 -    extensions_query_all(); /* find which extensions are present */
 -
      if (screen_annex()) { /* it will be ours! */
          do {
              ObPrompt *xmlprompt = NULL;
  
 -            modkeys_startup(reconfigure);
 +            if (reconfigure) obt_keyboard_reload();
  
              /* get the keycodes for keys we use */
 -            keys[OB_KEY_RETURN] = modkeys_sym_to_code(XK_Return);
 -            keys[OB_KEY_ESCAPE] = modkeys_sym_to_code(XK_Escape);
 -            keys[OB_KEY_LEFT] = modkeys_sym_to_code(XK_Left);
 -            keys[OB_KEY_RIGHT] = modkeys_sym_to_code(XK_Right);
 -            keys[OB_KEY_UP] = modkeys_sym_to_code(XK_Up);
 -            keys[OB_KEY_DOWN] = modkeys_sym_to_code(XK_Down);
 -            keys[OB_KEY_TAB] = modkeys_sym_to_code(XK_Tab);
 -            keys[OB_KEY_SPACE] = modkeys_sym_to_code(XK_space);
 +            keys[OB_KEY_RETURN] = obt_keyboard_keysym_to_keycode(XK_Return);
 +            keys[OB_KEY_ESCAPE] = obt_keyboard_keysym_to_keycode(XK_Escape);
 +            keys[OB_KEY_LEFT] = obt_keyboard_keysym_to_keycode(XK_Left);
 +            keys[OB_KEY_RIGHT] = obt_keyboard_keysym_to_keycode(XK_Right);
 +            keys[OB_KEY_UP] = obt_keyboard_keysym_to_keycode(XK_Up);
 +            keys[OB_KEY_DOWN] = obt_keyboard_keysym_to_keycode(XK_Down);
 +            keys[OB_KEY_TAB] = obt_keyboard_keysym_to_keycode(XK_Tab);
 +            keys[OB_KEY_SPACE] = obt_keyboard_keysym_to_keycode(XK_space);
  
              {
 -                ObParseInst *i;
 -                xmlDocPtr doc;
 -                xmlNodePtr node;
 +                ObtParseInst *i;
  
                  /* startup the parsing so everything can register sections
                     of the rc */
 -                i = parse_startup();
 +                i = obt_parse_instance_new();
  
                  /* register all the available actions */
                  actions_startup(reconfigure);
                  config_startup(i);
  
                  /* parse/load user options */
 -                if (parse_load_rc(config_file, &doc, &node)) {
 -                    parse_tree(i, doc, node->xmlChildrenNode);
 -                    parse_close(doc);
 +                if ((config_file &&
 +                     obt_parse_load_file(i, config_file, "openbox_config")) ||
 +                    obt_parse_load_config_file(i, "openbox", "rc.xml",
 +                                               "openbox_config"))
 +                {
 +                    obt_parse_tree_from_root(i);
 +                    obt_parse_close(i);
                  }
                  else {
                      g_message(_("Unable to find a valid config file, using some simple defaults"));
                      gchar *p = g_filename_to_utf8(config_file, -1,
                                                    NULL, NULL, NULL);
                      if (p)
 -                        PROP_SETS(RootWindow(ob_display, ob_screen),
 -                                  ob_config_file, p);
 +                        OBT_PROP_SETS(obt_root(ob_screen), OB_CONFIG_FILE,
 +                                      utf8, p);
                      g_free(p);
                  }
                  else
 -                    PROP_ERASE(RootWindow(ob_display, ob_screen),
 -                               ob_config_file);
 +                    OBT_PROP_ERASE(obt_root(ob_screen), OB_CONFIG_FILE);
  
                  /* we're done with parsing now, kill it */
 -                parse_shutdown(i);
 +                obt_parse_instance_unref(i);
              }
  
              /* load the theme specified in the rc file */
                  if (ob_rr_theme == NULL)
                      ob_exit_with_error(_("Unable to load a theme."));
  
 -                PROP_SETS(RootWindow(ob_display, ob_screen),
 -                          ob_theme, ob_rr_theme->name);
 +                OBT_PROP_SETS(obt_root(ob_screen),
 +                              OB_THEME, utf8, ob_rr_theme->name);
              }
  
              if (reconfigure) {
                  ObWindow *w;
  
                  /* get all the existing windows */
 -                client_manage_all();
 +                window_manage_all();
                  focus_nothing();
  
                  /* focus what was focused if a wm was already running */
 -                if (PROP_GET32(RootWindow(ob_display, ob_screen),
 -                               net_active_window, window, &xid) &&
 -                    (w = g_hash_table_lookup(window_map, &xid)) &&
 -                    WINDOW_IS_CLIENT(w))
 +                if (OBT_PROP_GET32(obt_root(ob_screen),
 +                                   NET_ACTIVE_WINDOW, WINDOW, &xid) &&
 +                    (w = window_find(xid)) && WINDOW_IS_CLIENT(w))
                  {
                      client_focus(WINDOW_AS_CLIENT(w));
                  }
                  }
              }
  
 -            ob_main_loop_run(ob_main_loop);
 +            obt_main_loop_run(ob_main_loop);
              ob_set_state(reconfigure ?
                           OB_STATE_RECONFIGURING : OB_STATE_EXITING);
  
                  xmlprompt = NULL;
              }
  
 -            if (!reconfigure) {
 -                dock_remove_all();
 -                client_unmanage_all();
 -            }
 +            if (!reconfigure)
 +                window_unmanage_all();
  
              prompt_shutdown(reconfigure);
              menu_shutdown(reconfigure);
              event_shutdown(reconfigure);
              config_shutdown();
              actions_shutdown(reconfigure);
 -            modkeys_shutdown(reconfigure);
          } while (reconfigure);
      }
  
 -    XSync(ob_display, FALSE);
 +    XSync(obt_display, FALSE);
  
      RrThemeFree(ob_rr_theme);
      RrImageCacheUnref(ob_rr_icons);
  
      session_shutdown(being_replaced);
  
 -    XCloseDisplay(ob_display);
 -
 -    parse_paths_shutdown();
 +    obt_display_close();
  
      if (restart) {
 +        ob_debug_shutdown();
          if (restart_path != NULL) {
              gint argcp;
              gchar **argvp;
      g_free(ob_sm_id);
      g_free(program_name);
  
 +    if (!restart)
 +        ob_debug_shutdown();
 +
      return exitcode;
  }
  
@@@ -478,11 -494,11 +478,11 @@@ static void signal_handler(gint signal
  {
      switch (signal) {
      case SIGUSR1:
 -        ob_debug("Caught signal %d. Restarting.\n", signal);
 +        ob_debug("Caught signal %d. Restarting.", signal);
          ob_restart();
          break;
      case SIGUSR2:
 -        ob_debug("Caught signal %d. Reconfiguring.\n", signal);
 +        ob_debug("Caught signal %d. Reconfiguring.", signal);
          ob_reconfigure();
          break;
      case SIGCHLD:
          while (waitpid(-1, NULL, WNOHANG) > 0);
          break;
      default:
 -        ob_debug("Caught signal %d. Exiting.\n", signal);
 +        ob_debug("Caught signal %d. Exiting.", signal);
          /* TERM and INT return a 0 code */
          ob_exit(!(signal == SIGTERM || signal == SIGINT));
      }
  }
  
 -static void print_version()
 +static void print_version(void)
  {
      g_print("Openbox %s\n", PACKAGE_VERSION);
      g_print(_("Copyright (c)"));
      g_print("under certain conditions. See the file COPYING for details.\n\n");
  }
  
 -static void print_help()
 +static void print_help(void)
  {
      g_print(_("Syntax: openbox [options]\n"));
      g_print(_("\nOptions:\n"));
      g_print(_("  --sync              Run in synchronous mode\n"));
      g_print(_("  --debug             Display debugging output\n"));
      g_print(_("  --debug-focus       Display debugging output for focus handling\n"));
 +    g_print(_("  --debug-session     Display debugging output for session management\n"));
      g_print(_("  --debug-xinerama    Split the display into fake xinerama screens\n"));
      g_print(_("\nPlease report bugs at %s\n"), PACKAGE_BUGREPORT);
  }
@@@ -544,10 -559,23 +544,23 @@@ static void remove_args(gint *argc, gch
      *argc -= num;
  }
  
 -static void parse_env()
 +static void parse_env(void)
  {
+     const gchar *id;
      /* unset this so we don't pass it on unknowingly */
      unsetenv("DESKTOP_STARTUP_ID");
+     /* this is how gnome-session passes in a session client id */
+     id = g_getenv("DESKTOP_AUTOSTART_ID");
+     if (id) {
+         unsetenv("DESKTOP_AUTOSTART_ID");
+         if (ob_sm_id) g_free(ob_sm_id);
+         ob_sm_id = g_strdup(id);
+         ob_debug_type(OB_DEBUG_SM,
+                       "DESKTOP_AUTOSTART_ID %s supercedes --sm-client-id\n",
+                       ob_sm_id);
+     }
  }
  
  static void parse_args(gint *argc, gchar **argv)
              xsync = TRUE;
          }
          else if (!strcmp(argv[i], "--debug")) {
 -            ob_debug_show_output(TRUE);
 -            ob_debug_enable(OB_DEBUG_SM, TRUE);
 +            ob_debug_enable(OB_DEBUG_NORMAL, TRUE);
              ob_debug_enable(OB_DEBUG_APP_BUGS, TRUE);
          }
          else if (!strcmp(argv[i], "--debug-focus")) {
 -            ob_debug_show_output(TRUE);
 -            ob_debug_enable(OB_DEBUG_SM, TRUE);
 -            ob_debug_enable(OB_DEBUG_APP_BUGS, TRUE);
              ob_debug_enable(OB_DEBUG_FOCUS, TRUE);
          }
 +        else if (!strcmp(argv[i], "--debug-session")) {
 +            ob_debug_enable(OB_DEBUG_SM, TRUE);
 +        }
          else if (!strcmp(argv[i], "--debug-xinerama")) {
              ob_debug_xinerama = TRUE;
          }
                     what we want */
                  config_file = argv[i+1];
                  ++i; /* skip the argument */
 -                ob_debug("--config-file %s\n", config_file);
 +                ob_debug("--config-file %s", config_file);
              }
          }
          else if (!strcmp(argv[i], "--sm-save-file")) {
                  ob_sm_save_file = g_strdup(argv[i+1]);
                  remove_args(argc, argv, i, 2);
                  --i; /* this arg was removed so go back */
 -                ob_debug_type(OB_DEBUG_SM, "--sm-save-file %s\n",
 +                ob_debug_type(OB_DEBUG_SM, "--sm-save-file %s",
                                ob_sm_save_file);
              }
          }
                  ob_sm_id = g_strdup(argv[i+1]);
                  remove_args(argc, argv, i, 2);
                  --i; /* this arg was removed so go back */
 -                ob_debug_type(OB_DEBUG_SM, "--sm-client-id %s\n", ob_sm_id);
 +                ob_debug_type(OB_DEBUG_SM, "--sm-client-id %s", ob_sm_id);
              }
          }
          else if (!strcmp(argv[i], "--sm-disable")) {
@@@ -652,16 -681,16 +665,16 @@@ static Cursor load_cursor(const gchar *
      Cursor c = None;
  
  #if USE_XCURSOR
 -    c = XcursorLibraryLoadCursor(ob_display, name);
 +    c = XcursorLibraryLoadCursor(obt_display, name);
  #endif
      if (c == None)
 -        c = XCreateFontCursor(ob_display, fontval);
 +        c = XCreateFontCursor(obt_display, fontval);
      return c;
  }
  
  void ob_exit_with_error(const gchar *msg)
  {
 -    g_message(msg);
 +    g_message("%s", msg);
      session_shutdown(TRUE);
      exit(EXIT_FAILURE);
  }
@@@ -672,13 -701,13 +685,13 @@@ void ob_restart_other(const gchar *path
      ob_restart();
  }
  
 -void ob_restart()
 +void ob_restart(void)
  {
      restart = TRUE;
      ob_exit(0);
  }
  
 -void ob_reconfigure()
 +void ob_reconfigure(void)
  {
      reconfigure = TRUE;
      ob_exit(0);
  void ob_exit(gint code)
  {
      exitcode = code;
 -    ob_main_loop_exit(ob_main_loop);
 +    obt_main_loop_exit(ob_main_loop);
  }
  
 -void ob_exit_replace()
 +void ob_exit_replace(void)
  {
      exitcode = 0;
      being_replaced = TRUE;
 -    ob_main_loop_exit(ob_main_loop);
 +    obt_main_loop_exit(ob_main_loop);
  }
  
  Cursor ob_cursor(ObCursor cursor)
@@@ -709,7 -738,7 +722,7 @@@ KeyCode ob_keycode(ObKey key
      return keys[key];
  }
  
 -ObState ob_state()
 +ObState ob_state(void)
  {
      return state;
  }
diff --combined openbox/place.c
index aac40e8a099249c0620e7513269f556b766c56d8,d1d0481b3c0cad544d60f159c4e106bd944857cf..ee8bf7ebc1d139241e51097b19c571297469cabe
@@@ -43,20 -43,7 +43,7 @@@ static void add_choice(guint *choice, g
  
  static Rect *pick_pointer_head(ObClient *c)
  {
-     guint i;
-     gint px, py;
-     if (screen_pointer_pos(&px, &py)) {
-         for (i = 0; i < screen_num_monitors; ++i) {
-             Rect *monitor = screen_physical_area_monitor(i);
-             gboolean contain = RECT_CONTAINS(*monitor, px, py);
-             g_free(monitor);
-             if (contain)
-                 return screen_area(c->desktop, i, NULL);
-         }
-         g_assert_not_reached();
-     } else
-         return NULL;
+     return screen_area(c->desktop, screen_monitor_pointer(), NULL);
  }
  
  /*! Pick a monitor to place a window on. */
@@@ -76,7 -63,7 +63,7 @@@ static Rect **pick_head(ObClient *c
      /* try direct parent first */
      if ((p = client_direct_parent(c))) {
          add_choice(choice, client_monitor(p));
 -        ob_debug("placement adding choice %d for parent\n",
 +        ob_debug("placement adding choice %d for parent",
                   client_monitor(p));
      }
  
@@@ -92,7 -79,7 +79,7 @@@
                   itc->desktop == DESKTOP_ALL || c->desktop == DESKTOP_ALL))
              {
                  add_choice(choice, client_monitor(it->data));
 -                ob_debug("placement adding choice %d for group sibling\n",
 +                ob_debug("placement adding choice %d for group sibling",
                           client_monitor(it->data));
              }
          }
              if (itc != c) {
                  add_choice(choice, client_monitor(it->data));
                  ob_debug("placement adding choice %d for group sibling on "
 -                         "another desktop\n", client_monitor(it->data));
 +                         "another desktop", client_monitor(it->data));
              }
          }
      }
          config_place_monitor != OB_PLACE_MONITOR_MOUSE)
      {
          add_choice(choice, client_monitor(focus_client));
 -        ob_debug("placement adding choice %d for normal focused window\n",
 +        ob_debug("placement adding choice %d for normal focused window",
                   client_monitor(focus_client));
      }
  
          g_free(monitor);
          if (contain) {
              add_choice(choice, i);
 -            ob_debug("placement adding choice %d for mouse pointer\n", i);
 +            ob_debug("placement adding choice %d for mouse pointer", i);
              break;
          }
      }
diff --combined openbox/screen.c
index b53671fabbaad8889c8f6cbf04e74c78963818c0,8d0460d570a7a70daecaefa9bc7dc35956c9735c..8012942beb65a09ebfe0c88d32cab8010995edce
  #include "debug.h"
  #include "openbox.h"
  #include "dock.h"
 -#include "xerror.h"
 -#include "prop.h"
  #include "grab.h"
  #include "startupnotify.h"
  #include "moveresize.h"
  #include "config.h"
 -#include "mainloop.h"
  #include "screen.h"
  #include "client.h"
  #include "session.h"
  #include "event.h"
  #include "focus.h"
  #include "popup.h"
 -#include "extensions.h"
  #include "render/render.h"
  #include "gettext.h"
 +#include "obt/display.h"
 +#include "obt/prop.h"
 +#include "obt/mainloop.h"
  
  #include <X11/Xlib.h>
  #ifdef HAVE_UNISTD_H
@@@ -56,7 -57,7 +56,7 @@@ static void     screen_tell_ksplash(voi
  static void     screen_fallback_focus(void);
  
  guint           screen_num_desktops;
- guint           screen_num_monitors = 0;
+ guint           screen_num_monitors;
  guint           screen_desktop;
  guint           screen_last_desktop;
  gboolean        screen_showing_desktop;
@@@ -76,7 -77,7 +76,7 @@@ static GSList *struts_left = NULL
  static GSList *struts_right = NULL;
  static GSList *struts_bottom = NULL;
  
- static ObPagerPopup **desktop_popup = NULL;
+ static ObPagerPopup *desktop_popup;
  
  /*! The number of microseconds that you need to be on a desktop before it will
    replace the remembered "last desktop" */
@@@ -90,10 -91,10 +90,10 @@@ static gboolean replace_wm(void
      Time timestamp;
  
      wm_sn = g_strdup_printf("WM_S%d", ob_screen);
 -    wm_sn_atom = XInternAtom(ob_display, wm_sn, FALSE);
 +    wm_sn_atom = XInternAtom(obt_display, wm_sn, FALSE);
      g_free(wm_sn);
  
 -    current_wm_sn_owner = XGetSelectionOwner(ob_display, wm_sn_atom);
 +    current_wm_sn_owner = XGetSelectionOwner(obt_display, wm_sn_atom);
      if (current_wm_sn_owner == screen_support_win)
          current_wm_sn_owner = None;
      if (current_wm_sn_owner) {
                        ob_screen);
              return FALSE;
          }
 -        xerror_set_ignore(TRUE);
 -        xerror_occured = FALSE;
 +        obt_display_ignore_errors(TRUE);
  
          /* We want to find out when the current selection owner dies */
 -        XSelectInput(ob_display, current_wm_sn_owner, StructureNotifyMask);
 -        XSync(ob_display, FALSE);
 +        XSelectInput(obt_display, current_wm_sn_owner, StructureNotifyMask);
 +        XSync(obt_display, FALSE);
  
 -        xerror_set_ignore(FALSE);
 -        if (xerror_occured)
 +        obt_display_ignore_errors(FALSE);
 +        if (obt_display_error_occured)
              current_wm_sn_owner = None;
      }
  
      timestamp = event_get_server_time();
  
 -    XSetSelectionOwner(ob_display, wm_sn_atom, screen_support_win,
 +    XSetSelectionOwner(obt_display, wm_sn_atom, screen_support_win,
                         timestamp);
  
 -    if (XGetSelectionOwner(ob_display, wm_sn_atom) != screen_support_win) {
 +    if (XGetSelectionOwner(obt_display, wm_sn_atom) != screen_support_win) {
          g_message(_("Could not acquire window manager selection on screen %d"),
                    ob_screen);
          return FALSE;
        const gulong timeout = G_USEC_PER_SEC * 15; /* wait for 15s max */
  
        while (wait < timeout) {
 -          if (XCheckWindowEvent(ob_display, current_wm_sn_owner,
 +          if (XCheckWindowEvent(obt_display, current_wm_sn_owner,
                                  StructureNotifyMask, &event) &&
                event.type == DestroyNotify)
                break;
      }
  
      /* Send client message indicating that we are now the WM */
 -    prop_message(RootWindow(ob_display, ob_screen), prop_atoms.manager,
 -                 timestamp, wm_sn_atom, screen_support_win, 0,
 -                 SubstructureNotifyMask);
 +    obt_prop_message(ob_screen, obt_root(ob_screen), OBT_PROP_ATOM(MANAGER),
 +                     timestamp, wm_sn_atom, screen_support_win, 0, 0,
 +                     SubstructureNotifyMask);
  
      return TRUE;
  }
@@@ -158,33 -160,37 +158,33 @@@ gboolean screen_annex(void
      XSetWindowAttributes attrib;
      pid_t pid;
      gint i, num_support;
 -    Atom *prop_atoms_start, *wm_supported_pos;
      gulong *supported;
  
      /* create the netwm support window */
      attrib.override_redirect = TRUE;
      attrib.event_mask = PropertyChangeMask;
 -    screen_support_win = XCreateWindow(ob_display,
 -                                       RootWindow(ob_display, ob_screen),
 +    screen_support_win = XCreateWindow(obt_display, obt_root(ob_screen),
                                         -100, -100, 1, 1, 0,
                                         CopyFromParent, InputOutput,
                                         CopyFromParent,
                                         CWEventMask | CWOverrideRedirect,
                                         &attrib);
 -    XMapWindow(ob_display, screen_support_win);
 -    XLowerWindow(ob_display, screen_support_win);
 +    XMapWindow(obt_display, screen_support_win);
 +    XLowerWindow(obt_display, screen_support_win);
  
      if (!replace_wm()) {
 -        XDestroyWindow(ob_display, screen_support_win);
 +        XDestroyWindow(obt_display, screen_support_win);
          return FALSE;
      }
  
 -    xerror_set_ignore(TRUE);
 -    xerror_occured = FALSE;
 -    XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
 -                 ROOT_EVENTMASK);
 -    xerror_set_ignore(FALSE);
 -    if (xerror_occured) {
 +    obt_display_ignore_errors(TRUE);
 +    XSelectInput(obt_display, obt_root(ob_screen), ROOT_EVENTMASK);
 +    obt_display_ignore_errors(FALSE);
 +    if (obt_display_error_occured) {
          g_message(_("A window manager is already running on screen %d"),
                    ob_screen);
  
 -        XDestroyWindow(ob_display, screen_support_win);
 +        XDestroyWindow(obt_display, screen_support_win);
          return FALSE;
      }
  
  
      /* set the OPENBOX_PID hint */
      pid = getpid();
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               openbox_pid, cardinal, pid);
 +    OBT_PROP_SET32(obt_root(ob_screen), OPENBOX_PID, CARDINAL, pid);
  
      /* set supporting window */
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_supporting_wm_check, window, screen_support_win);
 +    OBT_PROP_SET32(obt_root(ob_screen),
 +                   NET_SUPPORTING_WM_CHECK, WINDOW, screen_support_win);
  
      /* set properties on the supporting window */
 -    PROP_SETS(screen_support_win, net_wm_name, "Openbox");
 -    PROP_SET32(screen_support_win, net_supporting_wm_check,
 -               window, screen_support_win);
 +    OBT_PROP_SETS(screen_support_win, NET_WM_NAME, utf8, "Openbox");
 +    OBT_PROP_SET32(screen_support_win, NET_SUPPORTING_WM_CHECK,
 +                   WINDOW, screen_support_win);
  
      /* set the _NET_SUPPORTED_ATOMS hint */
  
 -    /* this is all the atoms after net_supported in the prop_atoms struct */
 -    prop_atoms_start = (Atom*)&prop_atoms;
 -    wm_supported_pos = (Atom*)&(prop_atoms.net_supported);
 -    num_support = sizeof(prop_atoms) / sizeof(Atom) -
 -        (wm_supported_pos - prop_atoms_start) - 1;
 +    /* this is all the atoms after NET_SUPPORTED in the ObtPropAtoms enum */
 +    num_support = OBT_PROP_NUM_ATOMS - OBT_PROP_NET_SUPPORTED - 1;
      i = 0;
      supported = g_new(gulong, num_support);
 -    supported[i++] = prop_atoms.net_supporting_wm_check;
 -    supported[i++] = prop_atoms.net_wm_full_placement;
 -    supported[i++] = prop_atoms.net_current_desktop;
 -    supported[i++] = prop_atoms.net_number_of_desktops;
 -    supported[i++] = prop_atoms.net_desktop_geometry;
 -    supported[i++] = prop_atoms.net_desktop_viewport;
 -    supported[i++] = prop_atoms.net_active_window;
 -    supported[i++] = prop_atoms.net_workarea;
 -    supported[i++] = prop_atoms.net_client_list;
 -    supported[i++] = prop_atoms.net_client_list_stacking;
 -    supported[i++] = prop_atoms.net_desktop_names;
 -    supported[i++] = prop_atoms.net_close_window;
 -    supported[i++] = prop_atoms.net_desktop_layout;
 -    supported[i++] = prop_atoms.net_showing_desktop;
 -    supported[i++] = prop_atoms.net_wm_name;
 -    supported[i++] = prop_atoms.net_wm_visible_name;
 -    supported[i++] = prop_atoms.net_wm_icon_name;
 -    supported[i++] = prop_atoms.net_wm_visible_icon_name;
 -    supported[i++] = prop_atoms.net_wm_desktop;
 -    supported[i++] = prop_atoms.net_wm_strut;
 -    supported[i++] = prop_atoms.net_wm_strut_partial;
 -    supported[i++] = prop_atoms.net_wm_icon;
 -    supported[i++] = prop_atoms.net_wm_icon_geometry;
 -    supported[i++] = prop_atoms.net_wm_window_type;
 -    supported[i++] = prop_atoms.net_wm_window_type_desktop;
 -    supported[i++] = prop_atoms.net_wm_window_type_dock;
 -    supported[i++] = prop_atoms.net_wm_window_type_toolbar;
 -    supported[i++] = prop_atoms.net_wm_window_type_menu;
 -    supported[i++] = prop_atoms.net_wm_window_type_utility;
 -    supported[i++] = prop_atoms.net_wm_window_type_splash;
 -    supported[i++] = prop_atoms.net_wm_window_type_dialog;
 -    supported[i++] = prop_atoms.net_wm_window_type_normal;
 -    supported[i++] = prop_atoms.net_wm_allowed_actions;
 -    supported[i++] = prop_atoms.net_wm_action_move;
 -    supported[i++] = prop_atoms.net_wm_action_resize;
 -    supported[i++] = prop_atoms.net_wm_action_minimize;
 -    supported[i++] = prop_atoms.net_wm_action_shade;
 -    supported[i++] = prop_atoms.net_wm_action_maximize_horz;
 -    supported[i++] = prop_atoms.net_wm_action_maximize_vert;
 -    supported[i++] = prop_atoms.net_wm_action_fullscreen;
 -    supported[i++] = prop_atoms.net_wm_action_change_desktop;
 -    supported[i++] = prop_atoms.net_wm_action_close;
 -    supported[i++] = prop_atoms.net_wm_action_above;
 -    supported[i++] = prop_atoms.net_wm_action_below;
 -    supported[i++] = prop_atoms.net_wm_state;
 -    supported[i++] = prop_atoms.net_wm_state_modal;
 -    supported[i++] = prop_atoms.net_wm_state_maximized_vert;
 -    supported[i++] = prop_atoms.net_wm_state_maximized_horz;
 -    supported[i++] = prop_atoms.net_wm_state_shaded;
 -    supported[i++] = prop_atoms.net_wm_state_skip_taskbar;
 -    supported[i++] = prop_atoms.net_wm_state_skip_pager;
 -    supported[i++] = prop_atoms.net_wm_state_hidden;
 -    supported[i++] = prop_atoms.net_wm_state_fullscreen;
 -    supported[i++] = prop_atoms.net_wm_state_above;
 -    supported[i++] = prop_atoms.net_wm_state_below;
 -    supported[i++] = prop_atoms.net_wm_state_demands_attention;
 -    supported[i++] = prop_atoms.net_moveresize_window;
 -    supported[i++] = prop_atoms.net_wm_moveresize;
 -    supported[i++] = prop_atoms.net_wm_user_time;
 +    supported[i++] = OBT_PROP_ATOM(NET_SUPPORTING_WM_CHECK);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_FULL_PLACEMENT);
 +    supported[i++] = OBT_PROP_ATOM(NET_CURRENT_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_NUMBER_OF_DESKTOPS);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_GEOMETRY);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_VIEWPORT);
 +    supported[i++] = OBT_PROP_ATOM(NET_ACTIVE_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WORKAREA);
 +    supported[i++] = OBT_PROP_ATOM(NET_CLIENT_LIST);
 +    supported[i++] = OBT_PROP_ATOM(NET_CLIENT_LIST_STACKING);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_NAMES);
 +    supported[i++] = OBT_PROP_ATOM(NET_CLOSE_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_DESKTOP_LAYOUT);
 +    supported[i++] = OBT_PROP_ATOM(NET_SHOWING_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_VISIBLE_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ICON_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_VISIBLE_ICON_NAME);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STRUT);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STRUT_PARTIAL);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ICON);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ICON_GEOMETRY);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DOCK);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_TOOLBAR);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_MENU);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_UTILITY);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_SPLASH);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_NORMAL);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ALLOWED_ACTIONS);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MOVE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_RESIZE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MINIMIZE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_SHADE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_HORZ);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_MAXIMIZE_VERT);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_FULLSCREEN);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_CHANGE_DESKTOP);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_CLOSE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_ABOVE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_ACTION_BELOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_MODAL);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_VERT);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_MAXIMIZED_HORZ);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_SHADED);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_TASKBAR);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_SKIP_PAGER);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_HIDDEN);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_FULLSCREEN);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_ABOVE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_BELOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_STATE_DEMANDS_ATTENTION);
 +    supported[i++] = OBT_PROP_ATOM(NET_MOVERESIZE_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_MOVERESIZE);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_USER_TIME);
  /*
 -    supported[i++] = prop_atoms.net_wm_user_time_window;
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_USER_TIME_WINDOW);
  */
 -    supported[i++] = prop_atoms.net_frame_extents;
 -    supported[i++] = prop_atoms.net_request_frame_extents;
 -    supported[i++] = prop_atoms.net_restack_window;
 -    supported[i++] = prop_atoms.net_startup_id;
 +    supported[i++] = OBT_PROP_ATOM(NET_FRAME_EXTENTS);
 +    supported[i++] = OBT_PROP_ATOM(NET_REQUEST_FRAME_EXTENTS);
 +    supported[i++] = OBT_PROP_ATOM(NET_RESTACK_WINDOW);
 +    supported[i++] = OBT_PROP_ATOM(NET_STARTUP_ID);
  #ifdef SYNC
 -    supported[i++] = prop_atoms.net_wm_sync_request;
 -    supported[i++] = prop_atoms.net_wm_sync_request_counter;
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_SYNC_REQUEST_COUNTER);
  #endif
 -    supported[i++] = prop_atoms.net_wm_pid;
 -    supported[i++] = prop_atoms.net_wm_ping;
 -
 -    supported[i++] = prop_atoms.kde_wm_change_state;
 -    supported[i++] = prop_atoms.kde_net_wm_frame_strut;
 -    supported[i++] = prop_atoms.kde_net_wm_window_type_override;
 -
 -    supported[i++] = prop_atoms.ob_wm_action_undecorate;
 -    supported[i++] = prop_atoms.ob_wm_state_undecorated;
 -    supported[i++] = prop_atoms.openbox_pid;
 -    supported[i++] = prop_atoms.ob_theme;
 -    supported[i++] = prop_atoms.ob_config_file;
 -    supported[i++] = prop_atoms.ob_control;
 -    supported[i++] = prop_atoms.ob_role;
 -    supported[i++] = prop_atoms.ob_name;
 -    supported[i++] = prop_atoms.ob_class;
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_PID);
 +    supported[i++] = OBT_PROP_ATOM(NET_WM_PING);
 +
 +    supported[i++] = OBT_PROP_ATOM(KDE_WM_CHANGE_STATE);
 +    supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_FRAME_STRUT);
 +    supported[i++] = OBT_PROP_ATOM(KDE_NET_WM_WINDOW_TYPE_OVERRIDE);
 +
 +    supported[i++] = OBT_PROP_ATOM(OB_WM_ACTION_UNDECORATE);
 +    supported[i++] = OBT_PROP_ATOM(OB_WM_STATE_UNDECORATED);
 +    supported[i++] = OBT_PROP_ATOM(OPENBOX_PID);
 +    supported[i++] = OBT_PROP_ATOM(OB_THEME);
 +    supported[i++] = OBT_PROP_ATOM(OB_CONFIG_FILE);
 +    supported[i++] = OBT_PROP_ATOM(OB_CONTROL);
++    supported[i++] = OBT_PROP_ATOM(OB_ROLE);
++    supported[i++] = OBT_PROP_ATOM(OB_NAME);
++    supported[i++] = OBT_PROP_ATOM(OB_CLASS);
      g_assert(i == num_support);
  
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_supported, atom, supported, num_support);
 +    OBT_PROP_SETA32(obt_root(ob_screen),
 +                    NET_SUPPORTED, ATOM, supported, num_support);
      g_free(supported);
  
      screen_tell_ksplash();
@@@ -327,14 -340,14 +330,14 @@@ static void screen_tell_ksplash(void
         hear it anyways. perhaps it is for old ksplash. or new ksplash. or
         something. oh well. */
      e.xclient.type = ClientMessage;
 -    e.xclient.display = ob_display;
 -    e.xclient.window = RootWindow(ob_display, ob_screen);
 +    e.xclient.display = obt_display;
 +    e.xclient.window = obt_root(ob_screen);
      e.xclient.message_type =
 -        XInternAtom(ob_display, "_KDE_SPLASH_PROGRESS", False);
 +        XInternAtom(obt_display, "_KDE_SPLASH_PROGRESS", False);
      e.xclient.format = 8;
      strcpy(e.xclient.data.b, "wm started");
 -    XSendEvent(ob_display, RootWindow(ob_display, ob_screen),
 -               False, SubstructureNotifyMask, &e );
 +    XSendEvent(obt_display, obt_root(ob_screen),
 +               False, SubstructureNotifyMask, &e);
  }
  
  void screen_startup(gboolean reconfig)
      guint32 d;
      gboolean namesexist = FALSE;
  
-     if (reconfig) {
-         guint i;
-         /* recreate the pager popups to use any new theme stuff. it was
-            freed in screen_shutdown() already. */
-         desktop_popup = g_new(ObPagerPopup*, screen_num_monitors);
-         for (i = 0; i < screen_num_monitors; i++) {
-             desktop_popup[i] = pager_popup_new();
-             pager_popup_height(desktop_popup[i], POPUP_HEIGHT);
-             pager_popup_text_width_to_strings(desktop_popup[i],
-                                               screen_desktop_names,
-                                               screen_num_desktops);
-         }
+     desktop_popup = pager_popup_new();
+     pager_popup_height(desktop_popup, POPUP_HEIGHT);
  
+     if (reconfig) {
+         /* update the pager popup's width */
+         pager_popup_text_width_to_strings(desktop_popup,
+                                           screen_desktop_names,
+                                           screen_num_desktops);
          return;
      }
  
      screen_resize();
  
      /* have names already been set for the desktops? */
 -    if (PROP_GETSS(RootWindow(ob_display, ob_screen),
 -                   net_desktop_names, utf8, &names))
 -    {
 +    if (OBT_PROP_GETSS(obt_root(ob_screen), NET_DESKTOP_NAMES, utf8, &names)) {
          g_strfreev(names);
          namesexist = TRUE;
      }
              names[i] = g_strdup(it->data);
  
          /* set the root window property */
 -        PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names,names);
 +        OBT_PROP_SETSS(obt_root(ob_screen),
 +                       NET_DESKTOP_NAMES, utf8, (const gchar**)names);
  
          g_strfreev(names);
      }
         this will also set the default names from the config file up for
         desktops that don't have names yet */
      screen_num_desktops = 0;
 -    if (PROP_GET32(RootWindow(ob_display, ob_screen),
 -                   net_number_of_desktops, cardinal, &d))
 +    if (OBT_PROP_GET32(obt_root(ob_screen),
 +                       NET_NUMBER_OF_DESKTOPS, CARDINAL, &d))
      {
          if (d != config_desktops_num) {
              /* TRANSLATORS: If you need to specify a different order of the
  
      screen_desktop = screen_num_desktops;  /* something invalid */
      /* start on the current desktop when a wm was already running */
 -    if (PROP_GET32(RootWindow(ob_display, ob_screen),
 -                   net_current_desktop, cardinal, &d) &&
 +    if (OBT_PROP_GET32(obt_root(ob_screen),
 +                       NET_CURRENT_DESKTOP, CARDINAL, &d) &&
          d < screen_num_desktops)
      {
          screen_set_desktop(d, FALSE);
  
      /* don't start in showing-desktop mode */
      screen_showing_desktop = FALSE;
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_showing_desktop, cardinal, screen_showing_desktop);
 +    OBT_PROP_SET32(obt_root(ob_screen),
 +                   NET_SHOWING_DESKTOP, CARDINAL, screen_showing_desktop);
  
      if (session_desktop_layout_present &&
          screen_validate_layout(&session_desktop_layout))
  
  void screen_shutdown(gboolean reconfig)
  {
-     guint i;
-     for (i = 0; i < screen_num_monitors; i++)
-         pager_popup_free(desktop_popup[i]);
-     g_free(desktop_popup);
-     desktop_popup = NULL;
+     pager_popup_free(desktop_popup);
  
      if (reconfig)
          return;
  
 -    XSelectInput(ob_display, RootWindow(ob_display, ob_screen),
 -                 NoEventMask);
 +    XSelectInput(obt_display, obt_root(ob_screen), NoEventMask);
  
      /* we're not running here no more! */
 -    PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid);
 +    OBT_PROP_ERASE(obt_root(ob_screen), OPENBOX_PID);
      /* not without us */
 -    PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported);
 +    OBT_PROP_ERASE(obt_root(ob_screen), NET_SUPPORTED);
      /* don't keep this mode */
 -    PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop);
 +    OBT_PROP_ERASE(obt_root(ob_screen), NET_SHOWING_DESKTOP);
  
 -    XDestroyWindow(ob_display, screen_support_win);
 +    XDestroyWindow(obt_display, screen_support_win);
  
      g_strfreev(screen_desktop_names);
      screen_desktop_names = NULL;
@@@ -478,8 -482,8 +470,8 @@@ void screen_resize(void
      GList *it;
      gulong geometry[2];
  
 -    w = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen));
 -    h = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen));
 +    w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +    h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));
  
      if (w == oldw && h == oldh) return;
  
      /* Set the _NET_DESKTOP_GEOMETRY hint */
      screen_physical_size.width = geometry[0] = w;
      screen_physical_size.height = geometry[1] = h;
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_desktop_geometry, cardinal, geometry, 2);
 +    OBT_PROP_SETA32(obt_root(ob_screen),
 +                    NET_DESKTOP_GEOMETRY, CARDINAL, geometry, 2);
  
      if (ob_state() != OB_STATE_RUNNING)
          return;
      screen_update_areas();
      dock_configure();
  
-     /* make sure all windows are visible */
      for (it = client_list; it; it = g_list_next(it))
          client_move_onscreen(it->data, FALSE);
  }
  
  void screen_set_num_desktops(guint num)
  {
 -    guint old;
      gulong *viewport;
      GList *it, *stacking_copy;
  
  
      if (screen_num_desktops == num) return;
  
 -    old = screen_num_desktops;
      screen_num_desktops = num;
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_number_of_desktops, cardinal, num);
 +    OBT_PROP_SET32(obt_root(ob_screen), NET_NUMBER_OF_DESKTOPS, CARDINAL, num);
  
      /* set the viewport hint */
      viewport = g_new0(gulong, num * 2);
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_desktop_viewport, cardinal, viewport, num * 2);
 +    OBT_PROP_SETA32(obt_root(ob_screen),
 +                    NET_DESKTOP_VIEWPORT, CARDINAL, viewport, num * 2);
      g_free(viewport);
  
      /* the number of rows/columns will differ */
@@@ -613,7 -619,8 +604,7 @@@ void screen_set_desktop(guint num, gboo
  
      if (previous == num) return;
  
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_current_desktop, cardinal, num);
 +    OBT_PROP_SET32(obt_root(ob_screen), NET_CURRENT_DESKTOP, CARDINAL, num);
  
      /* This whole thing decides when/how to save the screen_last_desktop so
         that it can be restored later if you want */
          }
      }
      screen_desktop_timeout = FALSE;
 -    ob_main_loop_timeout_remove(ob_main_loop, last_desktop_func);
 -    ob_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME,
 -                             last_desktop_func, NULL, NULL, NULL);
 +    obt_main_loop_timeout_remove(ob_main_loop, last_desktop_func);
 +    obt_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME,
 +                              last_desktop_func, NULL, NULL, NULL);
  
 -    ob_debug("Moving to desktop %d\n", num+1);
 +    ob_debug("Moving to desktop %d", num+1);
  
      if (ob_state() == OB_STATE_RUNNING)
          screen_show_desktop_popup(screen_desktop);
          if (WINDOW_IS_CLIENT(it->data)) {
              ObClient *c = it->data;
              client_hide(c);
+             if (c == focus_client) {
+                 /* c was focused and we didn't do fallback clearly so make sure
+                    openbox doesnt still consider the window focused.
+                    this happens when using NextWindow with allDesktops, since
+                    it doesnt want to move focus on desktop change, but the
+                    focus is not going to stay with the current window, which
+                    has now disappeared */
+                 focus_set_client(NULL);
+             }
          }
      }
  
@@@ -740,7 -756,7 +740,7 @@@ void screen_add_desktop(gboolean curren
                     parent - which will have to be on the same desktop */
                  !client_direct_parent(c))
              {
 -                ob_debug("moving window %s\n", c->title);
 +                ob_debug("moving window %s", c->title);
                  client_set_desktop(c, c->desktop+1, FALSE, TRUE);
              }
          }
@@@ -781,7 -797,7 +781,7 @@@ void screen_remove_desktop(gboolean cur
                     parent - which will have to be on the same desktop */
                  !client_direct_parent(c))
              {
 -                ob_debug("moving window %s\n", c->title);
 +                ob_debug("moving window %s", c->title);
                  client_set_desktop(c, c->desktop - 1, TRUE, TRUE);
              }
              /* raise all the windows that are on the current desktop which
                  (d == DESKTOP_ALL || d == screen_desktop))
              {
                  stacking_raise(CLIENT_AS_WINDOW(c));
 -                ob_debug("raising window %s\n", c->title);
 +                ob_debug("raising window %s", c->title);
              }
          }
      }
      /* fallback focus like we're changing desktops */
      if (screen_desktop < screen_num_desktops - 1) {
          screen_fallback_focus();
 -        ob_debug("fake desktop change\n");
 +        ob_debug("fake desktop change");
      }
  
      screen_set_num_desktops(screen_num_desktops-1);
@@@ -918,52 -934,39 +918,41 @@@ static guint translate_row_col(guint r
  
  static gboolean hide_desktop_popup_func(gpointer data)
  {
-     guint i;
-     for (i = 0; i < screen_num_monitors; i++) {
-         pager_popup_hide(desktop_popup[i]);
-     }
+     pager_popup_hide(desktop_popup);
      return FALSE; /* don't repeat */
  }
  
  void screen_show_desktop_popup(guint d)
  {
      Rect *a;
-     guint i;
  
      /* 0 means don't show the popup */
      if (!config_desktop_popup_time) return;
  
-     for (i = 0; i < screen_num_monitors; i++) {
-         a = screen_physical_area_monitor(i);
-         pager_popup_position(desktop_popup[i], CenterGravity,
-                              a->x + a->width / 2, a->y + a->height / 2);
-         pager_popup_icon_size_multiplier(desktop_popup[i],
-                                          (screen_desktop_layout.columns /
-                                           screen_desktop_layout.rows) / 2,
-                                          (screen_desktop_layout.rows/
-                                           screen_desktop_layout.columns) / 2);
-         pager_popup_max_width(desktop_popup[i],
-                               MAX(a->width/3, POPUP_WIDTH));
-         pager_popup_show(desktop_popup[i], screen_desktop_names[d], d);
-         obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
-         obt_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000,
-                                   hide_desktop_popup_func, desktop_popup[i],
-                                   g_direct_equal, NULL);
-         g_free(a);
-     }
+     a = screen_physical_area_primary();
+     pager_popup_position(desktop_popup, CenterGravity,
+                          a->x + a->width / 2, a->y + a->height / 2);
+     pager_popup_icon_size_multiplier(desktop_popup,
+                                      (screen_desktop_layout.columns /
+                                       screen_desktop_layout.rows) / 2,
+                                      (screen_desktop_layout.rows/
+                                       screen_desktop_layout.columns) / 2);
+     pager_popup_max_width(desktop_popup,
+                           MAX(a->width/3, POPUP_WIDTH));
+     pager_popup_show(desktop_popup, screen_desktop_names[d], d);
 -    ob_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
 -    ob_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000,
 -                             hide_desktop_popup_func, NULL, NULL, NULL);
++    obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
++    obt_main_loop_timeout_add(ob_main_loop, config_desktop_popup_time * 1000,
++                              hide_desktop_popup_func, desktop_popup,
++                              g_direct_equal, NULL);
+     g_free(a);
  }
  
  void screen_hide_desktop_popup(void)
  {
-     guint i;
-     for (i = 0; i < screen_num_monitors; i++) {
-         obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func,
-                                           desktop_popup[i], FALSE);
-         pager_popup_hide(desktop_popup[i]);
-     }
 -    ob_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
++    obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func,
++                                      desktop_popup, FALSE);
+     pager_popup_hide(desktop_popup);
  }
  
  guint screen_find_desktop(guint from, ObDirection dir,
@@@ -1121,13 -1124,13 +1110,13 @@@ void screen_update_layout(void
      screen_desktop_layout.rows = 1;
      screen_desktop_layout.columns = screen_num_desktops;
  
 -    if (PROP_GETA32(RootWindow(ob_display, ob_screen),
 -                    net_desktop_layout, cardinal, &data, &num)) {
 +    if (OBT_PROP_GETA32(obt_root(ob_screen),
 +                        NET_DESKTOP_LAYOUT, CARDINAL, &data, &num)) {
          if (num == 3 || num == 4) {
  
 -            if (data[0] == prop_atoms.net_wm_orientation_vert)
 +            if (data[0] == OBT_PROP_ATOM(NET_WM_ORIENTATION_VERT))
                  l.orientation = OB_ORIENTATION_VERT;
 -            else if (data[0] == prop_atoms.net_wm_orientation_horz)
 +            else if (data[0] == OBT_PROP_ATOM(NET_WM_ORIENTATION_HORZ))
                  l.orientation = OB_ORIENTATION_HORZ;
              else
                  return;
              if (num < 4)
                  l.start_corner = OB_CORNER_TOPLEFT;
              else {
 -                if (data[3] == prop_atoms.net_wm_topleft)
 +                if (data[3] == OBT_PROP_ATOM(NET_WM_TOPLEFT))
                      l.start_corner = OB_CORNER_TOPLEFT;
 -                else if (data[3] == prop_atoms.net_wm_topright)
 +                else if (data[3] == OBT_PROP_ATOM(NET_WM_TOPRIGHT))
                      l.start_corner = OB_CORNER_TOPRIGHT;
 -                else if (data[3] == prop_atoms.net_wm_bottomright)
 +                else if (data[3] == OBT_PROP_ATOM(NET_WM_BOTTOMRIGHT))
                      l.start_corner = OB_CORNER_BOTTOMRIGHT;
 -                else if (data[3] == prop_atoms.net_wm_bottomleft)
 +                else if (data[3] == OBT_PROP_ATOM(NET_WM_BOTTOMLEFT))
                      l.start_corner = OB_CORNER_BOTTOMLEFT;
                  else
                      return;
@@@ -1166,8 -1169,8 +1155,8 @@@ void screen_update_desktop_names(void
      g_strfreev(screen_desktop_names);
      screen_desktop_names = NULL;
  
 -    if (PROP_GETSS(RootWindow(ob_display, ob_screen),
 -                   net_desktop_names, utf8, &screen_desktop_names))
 +    if (OBT_PROP_GETSS(obt_root(ob_screen),
 +                       NET_DESKTOP_NAMES, utf8, &screen_desktop_names))
          for (i = 0; screen_desktop_names[i] && i < screen_num_desktops; ++i);
      else
          i = 0;
  
          /* if we changed any names, then set the root property so we can
             all agree on the names */
 -        PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names,
 -                   screen_desktop_names);
 +        OBT_PROP_SETSS(obt_root(ob_screen), NET_DESKTOP_NAMES,
 +                       utf8, (const gchar**)screen_desktop_names);
      }
  
      /* resize the pager for these names */
-     for (i = 0; i < screen_num_monitors; i++) {
-         pager_popup_text_width_to_strings(desktop_popup[i],
-                                           screen_desktop_names,
-                                           screen_num_desktops);
-     }
+     pager_popup_text_width_to_strings(desktop_popup,
+                                       screen_desktop_names,
+                                       screen_num_desktops);
  }
  
  void screen_show_desktop(gboolean show, ObClient *show_only)
      }
  
      show = !!show; /* make it boolean */
 -    PROP_SET32(RootWindow(ob_display, ob_screen),
 -               net_showing_desktop, cardinal, show);
 +    OBT_PROP_SET32(obt_root(ob_screen), NET_SHOWING_DESKTOP, CARDINAL, show);
  }
  
  void screen_install_colormap(ObClient *client, gboolean install)
  {
      if (client == NULL || client->colormap == None) {
          if (install)
 -            XInstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst));
 +            XInstallColormap(obt_display, RrColormap(ob_rr_inst));
          else
 -            XUninstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst));
 +            XUninstallColormap(obt_display, RrColormap(ob_rr_inst));
      } else {
 -        xerror_set_ignore(TRUE);
 +        obt_display_ignore_errors(TRUE);
          if (install)
 -            XInstallColormap(RrDisplay(ob_rr_inst), client->colormap);
 +            XInstallColormap(obt_display, client->colormap);
          else
 -            XUninstallColormap(RrDisplay(ob_rr_inst), client->colormap);
 -        xerror_set_ignore(FALSE);
 +            XUninstallColormap(obt_display, client->colormap);
 +        obt_display_ignore_errors(FALSE);
      }
  }
  
@@@ -1321,89 -1323,16 +1308,65 @@@ typedef struct 
      } \
  }
  
 +static void get_xinerama_screens(Rect **xin_areas, guint *nxin)
 +{
 +    guint i;
 +    gint n, l, r, t, b;
 +#ifdef XINERAMA
 +    XineramaScreenInfo *info;
 +#endif
 +
 +    if (ob_debug_xinerama) {
 +        gint w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +        gint h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen));
 +        *nxin = 2;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        RECT_SET((*xin_areas)[0], 0, 0, w/2, h);
 +        RECT_SET((*xin_areas)[1], w/2, 0, w-(w/2), h);
 +    }
 +#ifdef XINERAMA
 +    else if (obt_display_extension_xinerama &&
 +             (info = XineramaQueryScreens(obt_display, &n))) {
 +        *nxin = n;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        for (i = 0; i < *nxin; ++i)
 +            RECT_SET((*xin_areas)[i], info[i].x_org, info[i].y_org,
 +                     info[i].width, info[i].height);
 +        XFree(info);
 +    }
 +#endif
 +    else {
 +        *nxin = 1;
 +        *xin_areas = g_new(Rect, *nxin + 1);
 +        RECT_SET((*xin_areas)[0], 0, 0,
 +                 WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)),
 +                 HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)));
 +    }
 +
 +    /* returns one extra with the total area in it */
 +    l = (*xin_areas)[0].x;
 +    t = (*xin_areas)[0].y;
 +    r = (*xin_areas)[0].x + (*xin_areas)[0].width - 1;
 +    b = (*xin_areas)[0].y + (*xin_areas)[0].height - 1;
 +    for (i = 1; i < *nxin; ++i) {
 +        l = MIN(l, (*xin_areas)[i].x);
 +        t = MIN(l, (*xin_areas)[i].y);
 +        r = MAX(r, (*xin_areas)[i].x + (*xin_areas)[i].width - 1);
 +        b = MAX(b, (*xin_areas)[i].y + (*xin_areas)[i].height - 1);
 +    }
 +    RECT_SET((*xin_areas)[*nxin], l, t, r - l + 1, b - t + 1);
 +}
 +
  void screen_update_areas(void)
  {
-     guint i, j, onum;
+     guint i, j;
      gulong *dims;
      GList *it;
      GSList *sit;
  
-     onum = screen_num_monitors;
      g_free(monitor_area);
 -    extensions_xinerama_screens(&monitor_area, &screen_num_monitors);
 +    get_xinerama_screens(&monitor_area, &screen_num_monitors);
  
-     if (screen_num_monitors < onum) {
-         /* free some of the pager popups */
-         for (i = screen_num_monitors; i < onum; ++i)
-             pager_popup_free(desktop_popup[i]);
-         desktop_popup = g_renew(ObPagerPopup*, desktop_popup,
-                                 screen_num_monitors);
-     }
-     else {
-         /* add some more pager popups */
-         desktop_popup = g_renew(ObPagerPopup*, desktop_popup,
-                                 screen_num_monitors);
-         for (i = onum; i < screen_num_monitors; ++i) {
-             desktop_popup[i] = pager_popup_new();
-             pager_popup_height(desktop_popup[i], POPUP_HEIGHT);
-             if (screen_desktop_names) /* the areas are initialized before the
-                                          desktop names */
-                 pager_popup_text_width_to_strings(desktop_popup[i],
-                                                   screen_desktop_names,
-                                                   screen_num_desktops);
-         }
-     }
      /* set up the user-specified margins */
      config_margins.top_start = RECT_LEFT(monitor_area[screen_num_monitors]);
      config_margins.top_end = RECT_RIGHT(monitor_area[screen_num_monitors]);
  
      /* all the work areas are not used here, only the ones for the first
         monitor are */
 -    PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal,
 -                dims, 4 * screen_num_desktops);
 +    OBT_PROP_SETA32(obt_root(ob_screen), NET_WORKAREA, CARDINAL,
 +                    dims, 4 * screen_num_desktops);
  
      /* the area has changed, adjust all the windows if they need it */
      for (it = client_list; it; it = g_list_next(it))
@@@ -1590,7 -1519,7 +1553,7 @@@ Rect* screen_area(guint desktop, guint 
  {
      Rect *a;
      GSList *it;
 -    gint l, r, t, b, al, ar, at, ab;
 +    gint l, r, t, b;
      guint i, d;
      gboolean us = search != NULL; /* user provided search */
  
  
      /* only include monitors which the search area lines up with */
      if (RECT_INTERSECTS_RECT(monitor_area[screen_num_monitors], *search)) {
 -        al = l = RECT_RIGHT(monitor_area[screen_num_monitors]);
 -        at = t = RECT_BOTTOM(monitor_area[screen_num_monitors]);
 -        ar = r = RECT_LEFT(monitor_area[screen_num_monitors]);
 -        ab = b = RECT_TOP(monitor_area[screen_num_monitors]);
 +        l = RECT_RIGHT(monitor_area[screen_num_monitors]);
 +        t = RECT_BOTTOM(monitor_area[screen_num_monitors]);
 +        r = RECT_LEFT(monitor_area[screen_num_monitors]);
 +        b = RECT_TOP(monitor_area[screen_num_monitors]);
          for (i = 0; i < screen_num_monitors; ++i) {
              /* add the monitor if applicable */
              if (RANGES_INTERSECT(search->x, search->width,
                                   monitor_area[i].x, monitor_area[i].width))
              {
 -                at = t = MIN(t, RECT_TOP(monitor_area[i]));
 -                ab = b = MAX(b, RECT_BOTTOM(monitor_area[i]));
 +                t = MIN(t, RECT_TOP(monitor_area[i]));
 +                b = MAX(b, RECT_BOTTOM(monitor_area[i]));
              }
              if (RANGES_INTERSECT(search->y, search->height,
                                   monitor_area[i].y, monitor_area[i].height))
              {
 -                al = l = MIN(l, RECT_LEFT(monitor_area[i]));
 -                ar = r = MAX(r, RECT_RIGHT(monitor_area[i]));
 +                l = MIN(l, RECT_LEFT(monitor_area[i]));
 +                r = MAX(r, RECT_RIGHT(monitor_area[i]));
              }
          }
      } else {
 -        al = l = RECT_LEFT(monitor_area[screen_num_monitors]);
 -        at = t = RECT_TOP(monitor_area[screen_num_monitors]);
 -        ar = r = RECT_RIGHT(monitor_area[screen_num_monitors]);
 -        ab = b = RECT_BOTTOM(monitor_area[screen_num_monitors]);
 +        l = RECT_LEFT(monitor_area[screen_num_monitors]);
 +        t = RECT_TOP(monitor_area[screen_num_monitors]);
 +        r = RECT_RIGHT(monitor_area[screen_num_monitors]);
 +        b = RECT_BOTTOM(monitor_area[screen_num_monitors]);
      }
  
      for (d = 0; d < screen_num_desktops; ++d) {
@@@ -1746,36 -1675,61 +1709,61 @@@ gboolean screen_physical_area_monitor_c
      return RECT_INTERSECTS_RECT(monitor_area[head], *search);
  }
  
Rect* screen_physical_area_active(void)
guint screen_monitor_active(void)
  {
-     Rect *a;
-     gint x, y;
      if (moveresize_client)
-         a = screen_physical_area_monitor(client_monitor(focus_client));
+         return client_monitor(moveresize_client);
      else if (focus_client)
-         a = screen_physical_area_monitor(client_monitor(focus_client));
-     else {
-         Rect mon;
-         if (screen_pointer_pos(&x, &y))
-             RECT_SET(mon, x, y, 1, 1);
+         return client_monitor(focus_client);
+     else
+         return screen_monitor_pointer();
+ }
+ Rect* screen_physical_area_active(void)
+ {
+     return screen_physical_area_monitor(screen_monitor_active());
+ }
+ guint screen_monitor_primary(void)
+ {
+     if (config_primary_monitor_index > 0) {
+         if (config_primary_monitor_index-1 < screen_num_monitors)
+             return config_primary_monitor_index - 1;
          else
-             RECT_SET(mon, 0, 0, 1, 1);
-         a = screen_physical_area_monitor(screen_find_monitor(&mon));
+             return 0;
      }
-     return a;
+     else if (config_primary_monitor == OB_PLACE_MONITOR_ACTIVE)
+         return screen_monitor_active();
+     else /* config_primary_monitor == OB_PLACE_MONITOR_MOUSE */
+         return screen_monitor_pointer();
+ }
+ Rect *screen_physical_area_primary(void)
+ {
+     return screen_physical_area_monitor(screen_monitor_primary());
  }
  
  void screen_set_root_cursor(void)
  {
      if (sn_app_starting())
 -        XDefineCursor(ob_display, RootWindow(ob_display, ob_screen),
 +        XDefineCursor(obt_display, obt_root(ob_screen),
                        ob_cursor(OB_CURSOR_BUSYPOINTER));
      else
 -        XDefineCursor(ob_display, RootWindow(ob_display, ob_screen),
 +        XDefineCursor(obt_display, obt_root(ob_screen),
                        ob_cursor(OB_CURSOR_POINTER));
  }
  
+ guint screen_monitor_pointer()
+ {
+     Rect mon;
+     gint x, y;
+     if (screen_pointer_pos(&x, &y))
+         RECT_SET(mon, x, y, 1, 1);
+     else
+         RECT_SET(mon, 0, 0, 1, 1);
+     return screen_find_monitor(&mon);
+ }
  gboolean screen_pointer_pos(gint *x, gint *y)
  {
      Window w;
      guint u;
      gboolean ret;
  
 -    ret = !!XQueryPointer(ob_display, RootWindow(ob_display, ob_screen),
 +    ret = !!XQueryPointer(obt_display, obt_root(ob_screen),
                            &w, &w, x, y, &i, &i, &u);
      if (!ret) {
 -        for (i = 0; i < ScreenCount(ob_display); ++i)
 +        for (i = 0; i < ScreenCount(obt_display); ++i)
              if (i != ob_screen)
 -                if (XQueryPointer(ob_display, RootWindow(ob_display, i),
 +                if (XQueryPointer(obt_display, obt_root(i),
                                    &w, &w, x, y, &i, &i, &u))
                      break;
      }
diff --combined openbox/screen.h
index 11915f11a78e4cc7d420a0bee1c79211af432365,7df47f396fca396f3094ad595d1c52e4e236416f..1479db16a38dee947174497a53317231e68b1149
@@@ -53,7 -53,7 +53,7 @@@ extern ObDesktopLayout screen_desktop_l
  extern gchar **screen_desktop_names;
  
  /*! Take over the screen, set the basic hints on it claming it as ours */
 -gboolean screen_annex();
 +gboolean screen_annex(void);
  
  /*! Once the screen is ours, set up its initial state */
  void screen_startup(gboolean reconfig);
@@@ -61,7 -61,7 +61,7 @@@
  void screen_shutdown(gboolean reconfig);
  
  /*! Figure out the new size of the screen and adjust stuff for it */
 -void screen_resize();
 +void screen_resize(void);
  
  /*! Change the number of available desktops */
  void screen_set_num_desktops(guint num);
@@@ -78,7 -78,7 +78,7 @@@ guint screen_find_desktop(guint from, O
  /*! Show the desktop popup/notification */
  void screen_show_desktop_popup(guint d);
  /*! Hide it */
 -void screen_hide_desktop_popup();
 +void screen_hide_desktop_popup(void);
  
  /*! Shows and focuses the desktop and hides all the client windows, or
    returns to the normal state, showing client windows.
  void screen_show_desktop(gboolean show, struct _ObClient *show_only);
  
  /*! Updates the desktop layout from the root property if available */
 -void screen_update_layout();
 +void screen_update_layout(void);
  
  /*! Get desktop names from the root window property */
 -void screen_update_desktop_names();
 +void screen_update_desktop_names(void);
  
  /*! Installs or uninstalls a colormap for a client. If client is NULL, then
    it handles the root colormap. */
  void screen_install_colormap(struct _ObClient *client, gboolean install);
  
 -void screen_update_areas();
 +void screen_update_areas(void);
  
 -Rect *screen_physical_area_all_monitors();
 +Rect *screen_physical_area_all_monitors(void);
  
  Rect *screen_physical_area_monitor(guint head);
  
+ /*! Returns the monitor which contains the active window, or the one
+   containing the pointer otherwise. */
+ guint screen_monitor_active(void);
  Rect *screen_physical_area_active(void);
  
+ /*! Returns the primary monitor, as specified by the config */
+ guint screen_monitor_primary(void);
+ Rect *screen_physical_area_primary(void);
  /* doesn't include struts which the search area is already outside of when
     'search' is not NULL */
  #define SCREEN_AREA_ALL_MONITORS ((unsigned)-1)
@@@ -127,10 -136,13 +136,13 @@@ guint screen_find_monitor(Rect *search)
  
  /*! Sets the root cursor. This function decides which cursor to use, but you
    gotta call it to let it know it should change. */
 -void screen_set_root_cursor();
 +void screen_set_root_cursor(void);
  
  /*! Gives back the pointer's position in x and y. Returns TRUE if the pointer
    is on this screen and FALSE if it is on another screen. */
  gboolean screen_pointer_pos(gint *x, gint *y);
  
+ /*! Returns the monitor which contains the pointer device */
+ guint screen_monitor_pointer(void);
  #endif
diff --combined openbox/stacking.c
index 2a34f71dc4eea10305c1037a0ae24b64d9d4025b,1638908bd55ffb3c13c83f1991197ea5b808b288..cb710e5e0f8940a4be76fba10058be00623b4028
@@@ -18,6 -18,7 +18,6 @@@
  */
  
  #include "openbox.h"
 -#include "prop.h"
  #include "screen.h"
  #include "focus.h"
  #include "client.h"
@@@ -26,7 -27,6 +26,7 @@@
  #include "window.h"
  #include "event.h"
  #include "debug.h"
 +#include "obt/prop.h"
  
  GList  *stacking_list = NULL;
  /*! When true, stacking changes will not be reflected on the screen.  This is
@@@ -55,8 -55,8 +55,8 @@@ void stacking_set_list(void
          }
      }
  
 -    PROP_SETA32(RootWindow(ob_display, ob_screen),
 -                net_client_list_stacking, window, (gulong*)windows, i);
 +    OBT_PROP_SETA32(obt_root(ob_screen), NET_CLIENT_LIST_STACKING, WINDOW,
 +                    (gulong*)windows, i);
  
      g_free(windows);
  }
@@@ -69,8 -69,6 +69,8 @@@ static void do_restack(GList *wins, GLi
  
  #ifdef DEBUG
      GList *next;
 +
 +    g_assert(wins);
      /* pls only restack stuff in the same layer at a time */
      for (it = wins; it; it = next) {
          next = g_list_next(it);
  #endif
  
      if (!pause_changes)
 -        XRestackWindows(ob_display, win, i);
 +        XRestackWindows(obt_display, win, i);
      g_free(win);
  
      stacking_set_list();
@@@ -134,7 -132,7 +134,7 @@@ void stacking_temp_raise(ObWindow *wind
  
      win[1] = window_top(window);
      start = event_start_ignore_all_enters();
 -    XRestackWindows(ob_display, win, 2);
 +    XRestackWindows(obt_display, win, 2);
      event_end_ignore_all_enters(start);
  
      pause_changes = TRUE;
@@@ -152,7 -150,7 +152,7 @@@ void stacking_restore(void
      for (i = 1, it = stacking_list; it; ++i, it = g_list_next(it))
          win[i] = window_top(it->data);
      start = event_start_ignore_all_enters();
 -    XRestackWindows(ob_display, win, i);
 +    XRestackWindows(obt_display, win, i);
      event_end_ignore_all_enters(start);
      g_free(win);
  
@@@ -218,6 -216,7 +218,7 @@@ static void restack_windows(ObClient *s
      GList *it, *last, *below, *above, *next;
      GList *wins = NULL;
  
+     GList *group_helpers = NULL;
      GList *group_modals = NULL;
      GList *group_trans = NULL;
      GList *modals = NULL;
  
                  /* only move windows in the same stacking layer */
                  if (ch->layer == selected->layer &&
+                     /* looking for windows that are transients, and so would
+                        remain above the selected window */
                      client_search_transient(selected, ch))
                  {
                      if (client_is_direct_child(selected, ch)) {
                          else
                              trans = g_list_prepend(trans, ch);
                      }
+                     else if (client_helper(ch)) {
+                         if (selected->transient) {
+                             /* helpers do not stay above transient windows */
+                             continue;
+                         }
+                         group_helpers = g_list_prepend(group_helpers, ch);
+                     }
                      else {
                          if (ch->modal)
                              group_modals = g_list_prepend(group_modals, ch);
          }
      }
  
-     /* put transients of the selected window right above it */
+     /* put modals above other direct transients */
      wins = g_list_concat(modals, trans);
+     /* put helpers below direct transients */
+     wins = g_list_concat(wins, group_helpers);
+     /* put the selected window right below these children */
      wins = g_list_append(wins, selected);
  
      /* if selected window is transient for group then raise it above others */
@@@ -635,20 -648,21 +650,20 @@@ gboolean stacking_restack_request(ObCli
                      sibling->iconic))
      {
          ob_debug("Setting restack sibling to NULL, they are not on the same "
 -                 "desktop or it is iconified\n");
 +                 "desktop or it is iconified");
          sibling = NULL;
      }
  
      switch (detail) {
      case Below:
 -        ob_debug("Restack request Below for client %s sibling %s\n",
 +        ob_debug("Restack request Below for client %s sibling %s",
                   client->title, sibling ? sibling->title : "(all)");
          /* just lower it */
          stacking_lower(CLIENT_AS_WINDOW(client));
          ret = TRUE;
          break;
      case BottomIf:
 -        ob_debug("Restack request BottomIf for client %s sibling "
 -                 "%s\n",
 +        ob_debug("Restack request BottomIf for client %s sibling %s",
                   client->title, sibling ? sibling->title : "(all)");
          /* if this client occludes sibling (or anything if NULL), then
             lower it to the bottom */
          }
          break;
      case Above:
 -        ob_debug("Restack request Above for client %s sibling %s\n",
 +        ob_debug("Restack request Above for client %s sibling %s",
                   client->title, sibling ? sibling->title : "(all)");
          stacking_raise(CLIENT_AS_WINDOW(client));
          ret = TRUE;
          break;
      case TopIf:
 -        ob_debug("Restack request TopIf for client %s sibling %s\n",
 +        ob_debug("Restack request TopIf for client %s sibling %s",
                   client->title, sibling ? sibling->title : "(all)");
          if (stacking_occluded(client, sibling)) {
              stacking_raise(CLIENT_AS_WINDOW(client));
          }
          break;
      case Opposite:
 -        ob_debug("Restack request Opposite for client %s sibling "
 -                 "%s\n",
 +        ob_debug("Restack request Opposite for client %s sibling %s",
                   client->title, sibling ? sibling->title : "(all)");
          if (stacking_occluded(client, sibling)) {
              stacking_raise(CLIENT_AS_WINDOW(client));
diff --combined po/POTFILES.in
index 9bd4f66a9cae0f8966ac725224bca4fc9c2c5a61,85938dee820228b3550891eb7f726e6f5fd76367..200e9ca31ef74786f8c22244af7628992c8b0b57
@@@ -2,13 -2,11 +2,12 @@@
  openbox/actions.c
  openbox/actions/execute.c
  openbox/actions/exit.c
- openbox/actions/session.c
  openbox/client.c
  openbox/client_list_combined_menu.c
  openbox/client_list_menu.c
  openbox/client_menu.c
  openbox/config.c
 +openbox/debug.c
  openbox/keyboard.c
  openbox/menu.c
  openbox/mouse.c
@@@ -17,4 -15,5 +16,4 @@@ openbox/screen.
  openbox/session.c
  openbox/startupnotify.c
  openbox/translate.c
 -openbox/xerror.c
  openbox/prompt.c
diff --combined render/image.c
index fc30714e8f9a7fb13ab97f55c8bed6f4b9ab4ab8,c8e839ce90ae0510d775d0ee87611c94323d492d..79f47fe280829c6ad3a5d07f6f9846e38885f922
@@@ -74,10 -74,10 +74,10 @@@ static void AddPicture(RrImage *self, R
      g_hash_table_insert(self->cache->table, (*list)[0], self);
  
  #ifdef DEBUG
 -    g_message("Adding %s picture to the cache:\n    "
 -              "Image 0x%x, w %d h %d Hash %u",
 -              (*list == self->original ? "ORIGINAL" : "RESIZED"),
 -              (guint)self, pic->width, pic->height, RrImagePicHash(pic));
 +    g_debug("Adding %s picture to the cache:\n    "
 +            "Image 0x%lx, w %d h %d Hash %u",
 +            (*list == self->original ? "ORIGINAL" : "RESIZED"),
 +            (gulong)self, pic->width, pic->height, RrImagePicHash(pic));
  #endif
  }
  
@@@ -89,11 -89,11 +89,11 @@@ static void RemovePicture(RrImage *self
      gint j;
  
  #ifdef DEBUG
 -    g_message("Removing %s picture from the cache:\n    "
 -              "Image 0x%x, w %d h %d Hash %u",
 -              (*list == self->original ? "ORIGINAL" : "RESIZED"),
 -              (guint)self, (*list)[i]->width, (*list)[i]->height,
 -              RrImagePicHash((*list)[i]));
 +    g_debug("Removing %s picture from the cache:\n    "
 +            "Image 0x%lx, w %d h %d Hash %u",
 +            (*list == self->original ? "ORIGINAL" : "RESIZED"),
 +            (gulong)self, (*list)[i]->width, (*list)[i]->height,
 +            RrImagePicHash((*list)[i]));
  #endif
  
      /* remove the picture as a key in the cache */
@@@ -221,7 -221,7 +221,7 @@@ static RrImagePic* ResizeImage(RrPixel3
      return pic;
  }
  
- /*! This drawns an RGBA picture into the target, within the rectangle specified
+ /*! This draws an RGBA picture into the target, within the rectangle specified
    by the area parameter.  If the area's size differs from the source's then it
    will be centered within the rectangle */
  void DrawRGBA(RrPixel32 *target, gint target_w, gint target_h,
@@@ -330,8 -330,8 +330,8 @@@ void RrImageUnref(RrImage *self
  {
      if (self && --self->ref == 0) {
  #ifdef DEBUG
 -        g_message("Refcount to 0, removing ALL pictures from the cache:\n    "
 -                  "Image 0x%x", (guint)self);
 +        g_debug("Refcount to 0, removing ALL pictures from the cache:\n    "
 +                "Image 0x%lx", (gulong)self);
  #endif
          while (self->n_original > 0)
              RemovePicture(self, &self->original, 0, &self->n_original);
@@@ -353,8 -353,8 +353,8 @@@ void RrImageAddPicture(RrImage *self, R
      for (i = 0; i < self->n_original; ++i)
          if (self->original[i]->width == w && self->original[i]->height == h) {
  #ifdef DEBUG
 -            g_message("Found duplicate ORIGINAL image:\n    "
 -                      "Image 0x%x, w %d h %d", (guint)self, w, h);
 +            g_debug("Found duplicate ORIGINAL image:\n    "
 +                    "Image 0x%lx, w %d h %d", (gulong)self, w, h);
  #endif
              return;
          }
@@@ -405,11 -405,13 +405,13 @@@ void RrImageDrawImage(RrPixel32 *target
      pic = NULL;
      free_pic = FALSE;
  
-     /* is there an original of this size? (only w or h has to be right cuz
-        we maintain aspect ratios) */
+     /* is there an original of this size? (only the larger of
+        w or h has to be right cuz we maintain aspect ratios) */
      for (i = 0; i < self->n_original; ++i)
-         if (self->original[i]->width == area->width ||
-             self->original[i]->height == area->height)
+         if ((self->original[i]->width >= self->original[i]->height &&
+              self->original[i]->width == area->width) ||
+             (self->original[i]->width <= self->original[i]->height &&
+              self->original[i]->height == area->height))
          {
              pic = self->original[i];
              break;
  
      /* is there a resize of this size? */
      for (i = 0; i < self->n_resized; ++i)
-         if (self->resized[i]->width == area->width ||
-             self->resized[i]->height == area->height)
+         if ((self->resized[i]->width >= self->resized[i]->height &&
+              self->resized[i]->width == area->width) ||
+             (self->resized[i]->width <= self->resized[i]->height &&
+              self->resized[i]->height == area->height))
          {
              gint j;
              RrImagePic *saved;
This page took 0.361799 seconds and 4 git commands to generate.