This commit was manufactured by cvs2svn to create tag openbox-1_0_2
authorunknown <unknown>
Fri, 10 May 2002 06:04:59 +0000 (06:04 +0000)
committerunknown <unknown>
Fri, 10 May 2002 06:04:59 +0000 (06:04 +0000)
'openbox-1_0_2'.

22 files changed:
1  2 
CHANGELOG
configure
configure.in
nls/C/Configmenu.m
src/Basemenu.cc
src/Basemenu.h
src/Configmenu.cc
src/Geometry.cc
src/Resource.h
src/Screen.cc
src/Screen.h
src/Slit.cc
src/Slit.h
src/Toolbar.cc
src/Window.cc
src/Window.h
src/Workspace.cc
src/Workspace.h
src/openbox.cc
src/openbox.h
util/bsetbg
util/bsetroot.cc

diff --cc CHANGELOG
index 338776d9e92150ee564144208a8705dd51c92841,a0d67376b6c87fc6393f6aa8c7794dfca69f39c9..121bf9c4d4f0a65757f792f831f564b1a3bc7bfb
+++ b/CHANGELOG
@@@ -1,5 -1,49 +1,46 @@@
  Changelog for Openbox:
  
 -1.1.0:
 - * bsetroot supports transparent applications by
 -   setting the xrootpmap_id property on the root
 -   window                                               (Sean Perry)
++1.0.2:
++ * better fix for gcc 3 compatibility.                  (Ben Jansens)
 - * added ClickMouse window placement algorithm/type.    (Ben Jansens)
 - 
 - * added UnderMouse window placement algorithm/type.    (Ben Jansens)
++ * fix bug where rc file settings would not load due
++   to the changes for gcc 3.                            (Ben Jansens)
++1.0.1:
+  * improved logic for decorating windows when the
 -   decoration level is changed                          (Ben Jansens)
++   decoration level is changed.                         (Ben Jansens)
 - * fix positioning of the window menu                   (Ben Jansens)
++ * fix positioning of the window menu.                  (Ben Jansens)
+  * save the titlebarLayout in the default config file.  (Ben Jansens)
+  * gcc 3 compatibilty                                   (Ben Jansens)
+ 1.0.0:
+  * maximizing windows takes the slit into account as
+    well as the toolbar when 'Full Maximization' is off  (Ben Jansens)
+  * better handling of the rc file and its configuration
+    options. The file is written each time an option in
+    the file is changed, instead of being written at
+    shutdown. This means that you can edit the file by
+    hand while in Openbox, and then choose reconfig or
+    restart to have it use the new rc file.              (Ben Jansens)
+  * added a runtime option for hiding the toolbar.       (Scott Moynes)
+       
+  * made shaded windows edge-snap correctly to the
+    bottom for their size instead for their unshaded
+    size.                                                (Ben Jansens)
+  * added BestFit window placement algorithm/type.       (Ruhi Bloodworth)
++0.99.1:
+  * forced a redraw of the close button after pressing
+    it. Some applications (eg. acroread) ignore the
+    close request and you end up with a funky close
+    button.                                              (Scott Moynes)
 - * fix positioning of the window menu                   (Ben Jansens)
 -
  0.99.0:
   * renamed header files from *.hh to *.h.               (Ben Jansens)
  
diff --cc configure
index 6c1c5dd78357ada362c659786a0815b430b5306e,aba5e36854e96779da77b4825dbf20f8c1ffa8f4..490882d294c241d37c8dc25ede302bf3ce80d032
+++ b/configure
  
  PACKAGE=openbox
  
- VERSION=0.99.0
 -VERSION=1.1.0
++VERSION=1.0.2
  
  if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
-   { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
- echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
-    { (exit 1); exit 1; }; }
+   { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
  fi
  
  
diff --cc configure.in
index 65699008971b7b97fffbc3b6f427eb9c0166b8c7,f37715db42e67fae0dc5d503962431625f46db9c..ad037a4dddbd038944ad7b57ca9e5b6fd37ad04b
@@@ -1,7 -1,7 +1,7 @@@
  dnl configure.in for Openbox
  dnl Initialize autoconf and automake
  AC_INIT(src/openbox.cc)
- AM_INIT_AUTOMAKE(openbox,0.99.0,no-define)
 -AM_INIT_AUTOMAKE(openbox,1.1.0,no-define)
++AM_INIT_AUTOMAKE(openbox,1.0.2,no-define)
  
  dnl Determine default prefix
  test x$prefix = "xNONE" && prefix="$ac_default_prefix"
index d01e3c157249ad518c769bb4ab3986861297d0fe,f6b422a230b33c6013ffff1ee7c1afe8609edaaa..741e468d2159f69d854d59423d197363337745ff
@@@ -28,6 -28,12 +28,8 @@@ $ #SmartCol
  # Smart Placement (Columns)
  $ #Cascade
  # Cascade Placement
 -$ #UnderMouse
 -# Under Mouse Placement
 -$ #ClickMouse
 -# Click Mouse Placement
+ $ #BestFit
+ # Best Fit Placement
  $ #LeftRight
  # Left to Right
  $ #RightLeft
diff --cc src/Basemenu.cc
index b0e9760623ba6141298d0b8e9091db7621c1cbb3,8a3429a0b737657f932ba1d6cb2789bcc8ec90a7..c5ecd3bb0902d4b237f8a7193f67a9863787e53f
@@@ -140,14 -141,12 +141,14 @@@ Basemenu::Basemenu(BScreen &scrn) : ope
  
    attrib.event_mask |= PointerMotionMask;
    menu.frame = XCreateWindow(display, menu.window, 0,
-                            menu.title_h + screen->getBorderWidth(),
+                            menu.title_h + screen.getBorderWidth(),
                             menu.width, menu.frame_h, 0,
-                            screen->getDepth(), InputOutput,
-                            screen->getVisual(), attrib_mask, &attrib);
-   openbox->saveMenuSearch(menu.frame, this);
+                            screen.getDepth(), InputOutput,
+                            screen.getVisual(), attrib_mask, &attrib);
+   openbox.saveMenuSearch(menu.frame, this);
  
 +  menuitems = new LinkedList<BasemenuItem>;
 +
    // even though this is the end of the constructor the menu is still not
    // completely created.  items must be inserted and it must be update()'d
  }
@@@ -313,12 -319,12 +314,12 @@@ void Basemenu::update(void) 
      menu.item_w = ((menu.item_w < (unsigned int) ii) ? ii : menu.item_w);
    }
  
 -  if (menuitems.size()) {
 +  if (menuitems->count()) {
      menu.sublevels = 1;
  
 -    while (((menu.item_h * (menuitems.size() + 1) / menu.sublevels)
 +    while (((menu.item_h * (menuitems->count() + 1) / menu.sublevels)
-           + menu.title_h + screen->getBorderWidth()) >
-          screen->getHeight())
+           + menu.title_h + screen.getBorderWidth()) >
+          screen.size().h())
        menu.sublevels++;
  
      if (menu.sublevels < menu.minsub) menu.sublevels = menu.minsub;
diff --cc src/Basemenu.h
index ba28404c608879181de43cf727aca72cc82ea664,83ea35670348b2f902219bb52bf612d93e11d600..fc9c894c121f3471eeeb1adbf31bc8a010bc172b
@@@ -35,11 -35,11 +35,11 @@@ class BasemenuItem
  
  class Basemenu {
  private:
 -  menuitemList menuitems;
 +  LinkedList<BasemenuItem> *menuitems;
-   Openbox *openbox;
+   Openbox &openbox;
    Basemenu *parent;
    BImageControl *image_ctrl;
-   BScreen *screen;
+   BScreen &screen;
  
    Bool moving, visible, movable, torn, internal_menu, title_vis, shifted,
      hide_tree;
index 97faf779ecdcc77d457c625f385eb7843740686c,b8aef8ce841a7de4154d1cc430189f0bd739bf0e..413e0b250a2b54664aa252bc5810e4d548c92142
@@@ -85,10 -91,9 +91,10 @@@ void Configmenu::itemSelected(int butto
  
    switch(item->function()) {
    case 1: { // dither
-     screen->getImageControl()->
-       setDither((! screen->getImageControl()->doDither()));
 -    screen.setImageDither(!screen.getImageControl()->doDither());
++    screen.getImageControl()->
++      setDither((! screen.getImageControl()->doDither()));
  
-     setItemSelected(index, screen->getImageControl()->doDither());
+     setItemSelected(index, screen.getImageControl()->doDither());
  
      break;
    }
@@@ -162,20 -182,20 +183,20 @@@ void Configmenu::Focusmenu::itemSelecte
  
    switch (item->function()) {
    case 1: // click to focus
-     configmenu->screen->saveSloppyFocus(False);
-     configmenu->screen->saveAutoRaise(False);
+     configmenu->screen.setSloppyFocus(false);
+     configmenu->screen.setAutoRaise(false);
  
-     if (! configmenu->screen->getOpenbox()->getFocusedWindow())
-       XSetInputFocus(configmenu->screen->getOpenbox()->getXDisplay(),
-                    configmenu->screen->getToolbar()->getWindowID(),
 -    if (! configmenu->screen.getOpenbox().focusedWindow())
++    if (! configmenu->screen.getOpenbox().getFocusedWindow())
+       XSetInputFocus(configmenu->screen.getOpenbox().getXDisplay(),
+                    configmenu->screen.getToolbar()->getWindowID(),
                     RevertToParent, CurrentTime);
      else
-       XSetInputFocus(configmenu->screen->getOpenbox()->getXDisplay(),
-                    configmenu->screen->getOpenbox()->
+       XSetInputFocus(configmenu->screen.getOpenbox().getXDisplay(),
+                    configmenu->screen.getOpenbox().
 -                   focusedWindow()->getClientWindow(),
 +                   getFocusedWindow()->getClientWindow(),
                     RevertToParent, CurrentTime);
  
-     configmenu->screen->reconfigure();
+     configmenu->screen.reconfigure();
  
      break;
  
@@@ -215,6 -235,14 +236,8 @@@ Configmenu::Placementmenu::Placementmen
         BScreen::ColSmartPlacement);
    insert(i18n->getMessage(ConfigmenuSet, ConfigmenuCascade,
                          "Cascade Placement"), BScreen::CascadePlacement);
 -  insert(i18n->getMessage(ConfigmenuSet, ConfigmenuUnderMouse,
 -                          "Under Mouse Placement"),
 -         BScreen::UnderMousePlacement);
 -  insert(i18n->getMessage(ConfigmenuSet, ConfigmenuClickMouse,
 -                          "Click Mouse Placement"),
 -         BScreen::ClickMousePlacement);
+   insert(i18n->getMessage(ConfigmenuSet, ConfigmenuBestFit,
+                           "Best Fit Placement"), BScreen::BestFitPlacement);
    insert(i18n->getMessage(ConfigmenuSet, ConfigmenuLeftRight,
                          "Left to Right"), BScreen::LeftRight);
    insert(i18n->getMessage(ConfigmenuSet, ConfigmenuRightLeft,
                          "Bottom to Top"), BScreen::BottomTop);
    update();
  
-   switch (configmenu->screen->getPlacementPolicy()) {
+   setValues();
+ }
+ void Configmenu::Placementmenu::setValues() {
 -  const int p = configmenu->screen.placementPolicy();
 -  setItemSelected(0, p == BScreen::RowSmartPlacement);
 -  setItemSelected(1, p == BScreen::ColSmartPlacement);
 -  setItemSelected(2, p == BScreen::CascadePlacement);
 -  setItemSelected(3, p == BScreen::BestFitPlacement);
 -  setItemSelected(4, p == BScreen::UnderMousePlacement);
 -  setItemSelected(5, p == BScreen::ClickMousePlacement);
 -
 -  bool rl = (configmenu->screen.rowPlacementDirection() ==
++  switch (configmenu->screen.placementPolicy()) {
 +  case BScreen::RowSmartPlacement:
 +    setItemSelected(0, True);
 +    break;
 +
 +  case BScreen::ColSmartPlacement:
 +    setItemSelected(1, True);
 +    break;
 +
 +  case BScreen::CascadePlacement:
 +    setItemSelected(2, True);
 +    break;
++
++  case BScreen::BestFitPlacement:
++    setItemSelected(3, True);
++    break;
 +  }
 +
-   Bool rl = (configmenu->screen->getRowPlacementDirection() ==
++  Bool rl = (configmenu->screen.rowPlacementDirection() ==
             BScreen::LeftRight),
-        tb = (configmenu->screen->getColPlacementDirection() ==
+        tb = (configmenu->screen.colPlacementDirection() ==
             BScreen::TopBottom);
  
-   setItemSelected(3, rl);
-   setItemSelected(4, ! rl);
 -  setItemSelected(6, rl);
 -  setItemEnabled(6, (p != BScreen::UnderMousePlacement &&
 -                     p != BScreen::ClickMousePlacement));
 -  setItemSelected(7, !rl);
 -  setItemEnabled(7, (p != BScreen::UnderMousePlacement &&
 -                     p != BScreen::ClickMousePlacement));
 -
 -  setItemSelected(8, tb);
 -  setItemEnabled(8, (p != BScreen::UnderMousePlacement &&
 -                     p != BScreen::ClickMousePlacement));
 -  setItemSelected(9, !tb);
 -  setItemEnabled(9, (p != BScreen::UnderMousePlacement &&
 -                     p != BScreen::ClickMousePlacement));
++  setItemSelected(4, rl);
++  setItemSelected(5, !rl);
 +
-   setItemSelected(5, tb);
-   setItemSelected(6, ! tb);
++  setItemSelected(6, tb);
++  setItemSelected(7, !tb);
+ }
+ void Configmenu::Placementmenu::reconfigure() {
+   setValues();
+   Basemenu::reconfigure();
  }
  
  void Configmenu::Placementmenu::itemSelected(int button, int index) {
  
    switch (item->function()) {
    case BScreen::RowSmartPlacement:
-     configmenu->screen->savePlacementPolicy(item->function());
+     configmenu->screen.setPlacementPolicy(item->function());
 +
 +    setItemSelected(0, True);
 +    setItemSelected(1, False);
 +    setItemSelected(2, False);
++    setItemSelected(3, False);
 +
      break;
  
    case BScreen::ColSmartPlacement:
-     configmenu->screen->savePlacementPolicy(item->function());
+     configmenu->screen.setPlacementPolicy(item->function());
 +
 +    setItemSelected(0, False);
 +    setItemSelected(1, True);
 +    setItemSelected(2, False);
++    setItemSelected(3, False);
 +
      break;
  
    case BScreen::CascadePlacement:
-     configmenu->screen->savePlacementPolicy(item->function());
+     configmenu->screen.setPlacementPolicy(item->function());
 +
 +    setItemSelected(0, False);
 +    setItemSelected(1, False);
 +    setItemSelected(2, True);
++    setItemSelected(3, False);
 +
      break;
  
-   case BScreen::LeftRight:
-     configmenu->screen->saveRowPlacementDirection(BScreen::LeftRight);
+   case BScreen::BestFitPlacement:
+     configmenu->screen.setPlacementPolicy(item->function());
 -    break;
  
 -  case BScreen::UnderMousePlacement:
 -    configmenu->screen.setPlacementPolicy(item->function());
 -    break;
++    setItemSelected(0, False);
++    setItemSelected(1, False);
++    setItemSelected(2, False);
 +    setItemSelected(3, True);
-     setItemSelected(4, False);
  
 -  case BScreen::ClickMousePlacement:
 -    configmenu->screen.setPlacementPolicy(item->function());
      break;
  
-   case BScreen::RightLeft:
-     configmenu->screen->saveRowPlacementDirection(BScreen::RightLeft);
+   case BScreen::LeftRight:
+     configmenu->screen.setRowPlacementDirection(BScreen::LeftRight);
 +
-     setItemSelected(3, False);
 +    setItemSelected(4, True);
++    setItemSelected(5, False);
 +
      break;
  
-   case BScreen::TopBottom:
-     configmenu->screen->saveColPlacementDirection(BScreen::TopBottom);
+   case BScreen::RightLeft:
+     configmenu->screen.setRowPlacementDirection(BScreen::RightLeft);
 +
++    setItemSelected(4, False);
 +    setItemSelected(5, True);
-     setItemSelected(6, False);
 +
      break;
  
-   case BScreen::BottomTop:
-     configmenu->screen->saveColPlacementDirection(BScreen::BottomTop);
+   case BScreen::TopBottom:
+     configmenu->screen.setColPlacementDirection(BScreen::TopBottom);
 +
-     setItemSelected(5, False);
 +    setItemSelected(6, True);
++    setItemSelected(7, False);
++
+     break;
+   case BScreen::BottomTop:
+     configmenu->screen.setColPlacementDirection(BScreen::BottomTop);
++
++    setItemSelected(6, False);
++    setItemSelected(7, True);
 +
      break;
    }
 -  setValues();
  }
diff --cc src/Geometry.cc
index 0000000000000000000000000000000000000000,cdc39474e88bac7f639f9c1e5d263fdff02fe430..db1de4067015db4c69919065448f4a31d62fdf0e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,145 +1,145 @@@
 -    (x() < (r.x()+(signed)r.w()) ) &&
 -    ( (x()+(signed)w()) > r.x()) &&
 -    (y() < (r.y()+(signed)r.h()) ) &&
 -    ( (y()+(signed)h()) > r.y());
+ // Geometry.cc for Openbox
+ // Copyright (c) 2002 - 2002 ben Jansens (ben@orodu.net)
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a
+ // copy of this software and associated documentation files (the "Software"),
+ // to deal in the Software without restriction, including without limitation
+ // the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ // and/or sell copies of the Software, and to permit persons to whom the
+ // Software is furnished to do so, subject to the following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included in
+ // all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ // DEALINGS IN THE SOFTWARE.
+ #include "Geometry.h"
+ Point::Point() : m_x(0), m_y(0) {
+ }
+ Point::Point(const Point &point) : m_x(point.m_x), m_y(point.m_y) {
+ }
+ Point::Point(const int x, const int y) : m_x(x), m_y(y) {
+ }
+ void Point::setX(const int x) {
+   m_x = x;
+ }
+ void Point::setY(const int y) {
+   m_y = y;
+ }
+ Size::Size() : m_w(0), m_h(0) {
+ }
+ Size::Size(const Size &size) : m_w(size.m_w), m_h(size.m_h) {
+ }
+ Size::Size(const unsigned int w, const unsigned int h) : m_w(w), m_h(h) {
+ }
+ void Size::setW(const unsigned int w) {
+   m_w = w;
+ }
+ void Size::setH(const unsigned int h) {
+   m_h = h;
+ }
+ Rect::Rect() : m_origin(0, 0), m_size(0, 0) {
+ }
+ Rect::Rect(const Point &origin, const Size &size) : m_origin(origin),
+   m_size(size) {
+ }
+ Rect::Rect(const int x, const int y, const unsigned int w, const unsigned int h)
+   : m_origin(x, y), m_size(w, h) {
+ }
+ void Rect::setSize(const Size &size) {
+   m_size = size;
+ }
+ void Rect::setSize(const unsigned int w, const unsigned int h) {
+   m_size.setW(w);
+   m_size.setH(h);
+ }
+ void Rect::setOrigin(const Point &origin) {
+   m_origin = origin;
+ }
+ void Rect::setOrigin(const int x, const int y) {
+   m_origin.setX(x);
+   m_origin.setY(y);
+ }
+ void Rect::setX(const int x) {
+   m_origin.setX(x);
+ }
+ void Rect::setY(const int y) {
+   m_origin.setY(y);
+ }
+ void Rect::setW(unsigned int w) {
+   m_size.setW(w);
+ }
+ void Rect::setH(unsigned int h) {
+   m_size.setH(h);
+ }
+ bool Rect::Intersect(const Rect &r) const {
+   return
++    (x() < (r.x()+r.w()) ) &&
++    ( (x()+w()) > r.x()) &&
++    (y() < (r.y()+r.h()) ) &&
++    ( (y()+h()) > r.y());
+ }
+ Rect Rect::Inflate(const unsigned int i) const {
+   return Rect(x(), y(), w()+i, h()+i);
+ }
+ Rect Rect::Inflate(const unsigned int iw, const unsigned int ih) const {
+   return Rect(x(), y(), w()+iw, h()+ih);
+ }
+ Rect Rect::Inflate(const Size &i) const {
+   return Rect(x(), y(), w()+i.w(), h()+i.h());
+ }
+ Rect Rect::Deflate(const unsigned int d) const {
+   return Rect(x(), y(), w()-d, h()-d);
+ }
+ Rect Rect::Deflate(const unsigned int dw, const unsigned int dh) const {
+   return Rect(x(), y(), w()-dw, h()-dh);
+ }
+ Rect Rect::Deflate(const Size &d) const {
+   return Rect(x(), y(), w()-d.w(), h()-d.h());
+ }
+ Rect Rect::Translate(const int t) const {
+   return Rect(x()+t, y()+t, w(), h());
+ }
+ Rect Rect::Translate(const int tx, const int ty) const {
+   return Rect(x()+tx, y()+ty, w(), h());
+ }
+ Rect Rect::Translate(const Point &t) const {
+   return Rect(x()+t.x(), y()+t.y(), w(), h());
+ }
diff --cc src/Resource.h
index 0000000000000000000000000000000000000000,e75b87185dbec898bd88519401380373c6f47f72..7d7924943bfb4f9fe15928ef752d5bede98a7df8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,76 +1,76 @@@
 -  explicit Resource(const std::string &file);
+ // Resource.h for Openbox
+ // Copyright (c) 2002 - 2002 Ben Jansens (ben@orodu.net)
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a
+ // copy of this software and associated documentation files (the "Software"),
+ // to deal in the Software without restriction, including without limitation
+ // the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ // and/or sell copies of the Software, and to permit persons to whom the
+ // Software is furnished to do so, subject to the following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included in
+ // all copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ // DEALINGS IN THE SOFTWARE.
+ #ifndef   __Resource_hh
+ #define   __Resource_hh
+ #include <string>
+ #include <X11/Xlib.h>
+ #include <X11/Xresource.h>
+ class Resource {
+ public:
++  Resource(const std::string &file);
+   Resource();
+   virtual ~Resource();
+   inline const std::string &file() const {
+     return static_cast<const std::string &>(m_file);
+   }
+   void setFile(const std::string &file);
+   // defaults to true!
+   inline bool autoSave() const {
+     return m_autosave;
+   }
+   void setAutoSave(bool);
+   inline bool isModified() const {
+     return m_modified;
+   }
+   void save();
+   bool load();
+   void create();
+   void setValue(const std::string &rname, bool value);
+   void setValue(const std::string &rname, int value);
+   void setValue(const std::string &rname, long value);
+   void setValue(const std::string &rname, const std::string &value);
+   void setValue(const std::string &rname, const char *value);
+   bool getValue(const std::string &rname, const std::string &rclass,
+                 bool &value) const;
+   bool getValue(const std::string &rname, const std::string &rclass,
+                 long &value) const;
+   bool getValue(const std::string &rname, const std::string &rclass,
+                 std::string &value) const;
+ private:
+   static bool m_initialized;
+   std::string m_file;
+   bool m_modified;
+   bool m_autosave;
+   XrmDatabase m_database;
+ };
+ #endif // __Resource_hh
diff --cc src/Screen.cc
index 13c69bfa489a624e8e39c42fb50a98c6597fe7ee,3e7df54b4b5f7ad3aceb2f2092bfb8d70090c658..a156042984353c059a0f588c7118fb4083d9be82
@@@ -32,7 -32,7 +32,6 @@@
  
  #include <X11/Xatom.h>
  #include <X11/keysym.h>
- #include <assert.h>
 -#include <iostream>
  
  #include "i18n.h"
  #include "openbox.h"
  #include "Window.h"
  #include "Workspace.h"
  #include "Workspacemenu.h"
 -#include "Util.h"
  
- #ifdef    STDC_HEADERS
+ #ifdef    HAVE_STDLIB_H
  #  include <stdlib.h>
+ #endif // HAVE_STDLIB_H
+ #ifdef    HAVE_STRING_H
  #  include <string.h>
+ #endif // HAVE_STRING_H
+ #ifdef    HAVE_SYS_TYPES_H
  #  include <sys/types.h>
- #endif // STDC_HEADERS
+ #endif // HAVE_SYS_TYPES_H
  
  #ifdef    HAVE_CTYPE_H
  #  include <ctype.h>
@@@ -201,17 -211,17 +209,16 @@@ BScreen::BScreen(Openbox &ob, int scrn
            getDepth());
  
    rootmenu = 0;
-   resource.stylerc = 0;
  
    resource.mstyle.t_fontset = resource.mstyle.f_fontset =
-     resource.tstyle.fontset = resource.wstyle.fontset = (XFontSet) 0;
+     resource.tstyle.fontset = resource.wstyle.fontset = NULL;
    resource.mstyle.t_font = resource.mstyle.f_font = resource.tstyle.font =
-     resource.wstyle.font = (XFontStruct *) 0;
-   resource.root_command = NULL;
+     resource.wstyle.font = NULL;
 -  resource.root_command = NULL;
  
- #ifdef    HAVE_STRFTIME
-   resource.strftime_format = 0;
- #endif // HAVE_STRFTIME
+ #ifdef   SLIT
+   slit = NULL;
+ #endif // SLIT
+   toolbar = NULL;
  
  #ifdef    HAVE_GETPID
    pid_t bpid = getpid();
    image_control->installRootColormap();
    root_colormap_installed = True;
  
-   openbox->load_rc(this);
 +  image_control->setDither(resource.image_dither);
 +
+   load();       // load config options from Resources
    LoadStyle();
  
    XGCValues gcv;
      }
    }
  
-   workspacemenu = new Workspacemenu(this);
-   iconmenu = new Iconmenu(this);
-   configmenu = new Configmenu(this);
+   workspacemenu = new Workspacemenu(*this);
+   iconmenu = new Iconmenu(*this);
+   configmenu = new Configmenu(*this);
  
-   Workspace *wkspc = (Workspace *) 0;
+   Workspace *wkspc = NULL;
    if (resource.workspaces != 0) {
      for (int i = 0; i < resource.workspaces; ++i) {
-       wkspc = new Workspace(this, workspacesList->count());
+       wkspc = new Workspace(*this, workspacesList->count());
        workspacesList->insert(wkspc);
 -      saveWorkspaceNames();
        workspacemenu->insert(wkspc->getName(), wkspc->getMenu());
      }
    } else {
@@@ -584,7 -593,109 +591,7 @@@ BScreen::~BScreen(void) 
          resource.tstyle.b_pic_gc);
  }
  
- void BScreen::readDatabaseTexture(char *rname, char *rclass,
 -
 -Rect BScreen::availableArea() const {
 -  // the following code is temporary and will be taken care of by Screen in the
 -  // future (with the NETWM 'strut')
 -  Rect space(0, 0, size().w(), size().h());
 -  if (!resource.full_max) {
 -#ifdef    SLIT
 -    int slit_x = slit->autoHide() ? slit->hiddenOrigin().x() : slit->area().x(),
 -    slit_y = slit->autoHide() ? slit->hiddenOrigin().y() : slit->area().y();
 -    int tbarh = resource.hide_toolbar ? 0 :
 -      toolbar->getExposedHeight() + resource.border_width * 2;
 -    bool tbartop;
 -    switch (toolbar->placement()) {
 -    case Toolbar::TopLeft:
 -    case Toolbar::TopCenter:
 -    case Toolbar::TopRight:
 -      tbartop = true;
 -      break;
 -    case Toolbar::BottomLeft:
 -    case Toolbar::BottomCenter:
 -    case Toolbar::BottomRight:
 -      tbartop = false;
 -      break;
 -    default:
 -      ASSERT(false);      // unhandled placement
 -    }
 -    if ((slit->direction() == Slit::Horizontal &&
 -         (slit->placement() == Slit::TopLeft ||
 -          slit->placement() == Slit::TopRight)) ||
 -        slit->placement() == Slit::TopCenter) {
 -      // exclude top
 -      if (tbartop && slit_y + slit->area().h() < tbarh) {
 -        space.setY(space.y() + tbarh);
 -        space.setH(space.h() - tbarh);
 -      } else {
 -        space.setY(space.y() + (slit_y + slit->area().h() +
 -                                resource.border_width * 2));
 -        space.setH(space.h() - (slit_y + slit->area().h() +
 -                                resource.border_width * 2));
 -        if (!tbartop)
 -          space.setH(space.h() - tbarh);
 -      }
 -    } else if ((slit->direction() == Slit::Vertical &&
 -                (slit->placement() == Slit::TopRight ||
 -                 slit->placement() == Slit::BottomRight)) ||
 -               slit->placement() == Slit::CenterRight) {
 -      // exclude right
 -      space.setW(space.w() - (size().w() - slit_x));
 -      if (tbartop)
 -        space.setY(space.y() + tbarh);
 -      space.setH(space.h() - tbarh);
 -    } else if ((slit->direction() == Slit::Horizontal &&
 -                (slit->placement() == Slit::BottomLeft ||
 -                 slit->placement() == Slit::BottomRight)) ||
 -               slit->placement() == Slit::BottomCenter) {
 -      // exclude bottom
 -      if (!tbartop && (size().h() - slit_y) < tbarh) {
 -        space.setH(space.h() - tbarh);
 -      } else {
 -        space.setH(space.h() - (size().h() - slit_y));
 -        if (tbartop) {
 -          space.setY(space.y() + tbarh);
 -          space.setH(space.h() - tbarh);
 -        }
 -      }
 -    } else {// if ((slit->direction() == Slit::Vertical &&
 -      //      (slit->placement() == Slit::TopLeft ||
 -      //       slit->placement() == Slit::BottomLeft)) ||
 -      //     slit->placement() == Slit::CenterLeft)
 -      // exclude left
 -      space.setX(slit_x + slit->area().w() +
 -                 resource.border_width * 2);
 -      space.setW(space.w() - (slit_x + slit->area().w() +
 -                              resource.border_width * 2));
 -      if (tbartop)
 -        space.setY(space.y() + tbarh);
 -      space.setH(space.h() - tbarh);
 -    }
 -#else // !SLIT
 -    int tbarh = resource.hide_toolbar() ? 0 :
 -      toolbar->getExposedHeight() + resource.border_width * 2;
 -    switch (toolbar->placement()) {
 -    case Toolbar::TopLeft:
 -    case Toolbar::TopCenter:
 -    case Toolbar::TopRight:
 -      space.setY(toolbar->getExposedHeight());
 -      space.setH(space.h() - toolbar->getExposedHeight());
 -      break;
 -    case Toolbar::BottomLeft:
 -    case Toolbar::BottomCenter:
 -    case Toolbar::BottomRight:
 -      space.setH(space.h() - tbarh);
 -      break;
 -    default:
 -      ASSERT(false);      // unhandled placement
 -    }
 -#endif // SLIT
 -  }
 -  return space;
 -}
 -
 -
+ void BScreen::readDatabaseTexture(const char *rname, const char *rclass,
                                  BTexture *texture,
                                  unsigned long default_pixel)
  {
@@@ -830,7 -930,470 +826,463 @@@ XFontSet BScreen::createFontSet(const c
  }
  
  
 -void BScreen::setImageDither(bool d, bool reconfig) {
+ void BScreen::setSloppyFocus(bool b) {
+   resource.sloppy_focus = b;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".focusModel" << ends;
+   config.setValue(s.str(),
+                   (resource.sloppy_focus ?
+                   (resource.auto_raise ? "AutoRaiseSloppyFocus" : "SloppyFocus")
+                   : "ClickToFocus"));
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setAutoRaise(bool a) {
+   resource.auto_raise = a;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".focusModel" << ends;
+   config.setValue(s.str(),
+                   (resource.sloppy_focus ?
+                   (resource.auto_raise ? "AutoRaiseSloppyFocus" : "SloppyFocus")
+                   : "ClickToFocus"));
+   s.rdbuf()->freeze(0);
+ }
 -  image_control->setDither(d);
++void BScreen::setImageDither(bool d) {
+   resource.image_dither = d;
 -  if (reconfig)
 -    reconfigure();
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".imageDither" << ends;
+   config.setValue(s.str(), resource.image_dither);
 -  case UnderMousePlacement: placement = "UnderMousePlacement"; break;
 -  case ClickMousePlacement: placement = "ClickMousePlacement"; break;
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setOpaqueMove(bool o) {
+   resource.opaque_move = o;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".opaqueMove" << ends;
+   config.setValue(s.str(), resource.opaque_move);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setFullMax(bool f) {
+   resource.full_max = f;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".fullMaximization" << ends;
+   config.setValue(s.str(), resource.full_max);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setFocusNew(bool f) {
+   resource.focus_new = f;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".focusNewWindows" << ends;
+   config.setValue(s.str(), resource.focus_new);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setFocusLast(bool f) {
+   resource.focus_last = f;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".focusLastWindow" << ends;
+   config.setValue(s.str(), resource.focus_last);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setWindowZones(int z) {
+   resource.zones = z;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".windowZones" << ends;
+   config.setValue(s.str(), resource.zones);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setWorkspaceCount(int w) {
+   resource.workspaces = w;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".workspaces" << ends;
+   config.setValue(s.str(), resource.workspaces);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setPlacementPolicy(int p) {
+   resource.placement_policy = p;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".windowPlacement" << ends;
+   const char *placement;
+   switch (resource.placement_policy) {
+   case CascadePlacement: placement = "CascadePlacement"; break;
+   case BestFitPlacement: placement = "BestFitPlacement"; break;
+   case ColSmartPlacement: placement = "ColSmartPlacement"; break;
 -  s << "session.screen" << getScreenNumber() << ".rowPlacementDirection" << ends;
+   default:
+   case RowSmartPlacement: placement = "RowSmartPlacement"; break;
+   }
+   config.setValue(s.str(), placement);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setEdgeSnapThreshold(int t) {
+   resource.edge_snap_threshold = t;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".edgeSnapThreshold" << ends;
+   config.setValue(s.str(), resource.edge_snap_threshold);
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setRowPlacementDirection(int d) {
+   resource.row_direction = d;
+   ostrstream s;
 -  s << "session.screen" << getScreenNumber() << ".colPlacementDirection" << ends;
++  s << "session.screen" << getScreenNumber() << ".rowPlacementDirection" <<
++    ends;
+   config.setValue(s.str(),
+                   resource.row_direction == LeftRight ?
+                   "LeftToRight" : "RightToLeft");
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setColPlacementDirection(int d) {
+   resource.col_direction = d;
+   ostrstream s;
 -  setImageDither(resource.image_dither, false);
++  s << "session.screen" << getScreenNumber() << ".colPlacementDirection" <<
++    ends;
+   config.setValue(s.str(),
+                   resource.col_direction == TopBottom ?
+                   "TopToBottom" : "BottomToTop");
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setRootCommand(const char *cmd) {
+ if (resource.root_command != NULL)
+     delete [] resource.root_command;
+   if (cmd != NULL)
+     resource.root_command = bstrdup(cmd);
+   else
+     resource.root_command = NULL;
+   // this doesn't save to the Resources config because it can't be changed
+   // inside Openbox, and this way we dont add an empty command which would over-
+   // ride the styles command when none has been specified
+ }
+ #ifdef    HAVE_STRFTIME
+ void BScreen::setStrftimeFormat(const char *f) {
+   if (resource.strftime_format != NULL)
+     delete [] resource.strftime_format;
+   resource.strftime_format = bstrdup(f);
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".strftimeFormat" << ends;
+   config.setValue(s.str(), resource.strftime_format);
+   s.rdbuf()->freeze(0);
+ }
+ #else // !HAVE_STRFTIME
+ void BScreen::setDateFormat(int f) {
+   resource.date_format = f;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".dateFormat" << ends;
+   config.setValue(s.str(), resource.date_format == B_EuropeanDate ?
+                   "European" : "American");
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::setClock24Hour(Bool c) {
+   resource.clock24hour = c;
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".clockFormat" << ends;
+   config.setValue(s.str(), resource.clock24hour ? 24 : 12);
+   s.rdbuf()->freeze(0);
+ }
+ #endif // HAVE_STRFTIME
+ void BScreen::setHideToolbar(bool b) {
+   resource.hide_toolbar = b;
+   if (resource.hide_toolbar)
+     getToolbar()->unMapToolbar();
+   else
+     getToolbar()->mapToolbar();
+   ostrstream s;
+   s << "session.screen" << getScreenNumber() << ".hideToolbar" << ends;
+   config.setValue(s.str(), resource.hide_toolbar ? "True" : "False");
+   s.rdbuf()->freeze(0);
+ }
+ void BScreen::saveWorkspaceNames() {
+   ostrstream rc, names;
+   for (int i = 0; i < resource.workspaces; i++) {
+     Workspace *w = getWorkspace(i);
+     if (w != NULL) {
+       names << w->getName();
+       if (i < resource.workspaces-1)
+         names << ',';
+     }
+   }
+   names << ends;
+   rc << "session.screen" << getScreenNumber() << ".workspaceNames" << ends;
+   config.setValue(rc.str(), names.str());
+   rc.rdbuf()->freeze(0);
+   names.rdbuf()->freeze(0);
+ }
+ void BScreen::save() {
+   setSloppyFocus(resource.sloppy_focus);
+   setAutoRaise(resource.auto_raise);
 -    else //if (0 == strncasecmp(s.c_str(), "LeftToRight", s.length()))
++  setImageDither(resource.image_dither);
+   setOpaqueMove(resource.opaque_move);
+   setFullMax(resource.full_max);
+   setFocusNew(resource.focus_new);
+   setFocusLast(resource.focus_last);
+   setWindowZones(resource.zones);
+   setWorkspaceCount(resource.workspaces);
+   setPlacementPolicy(resource.placement_policy);
+   setEdgeSnapThreshold(resource.edge_snap_threshold);
+   setRowPlacementDirection(resource.row_direction);
+   setColPlacementDirection(resource.col_direction);
+   setRootCommand(resource.root_command);
+ #ifdef    HAVE_STRFTIME
+   // it deletes the current value before setting the new one, so we have to
+   // duplicate the current value.
+   string s = resource.strftime_format;
+   setStrftimeFormat(s.c_str()); 
+ #else // !HAVE_STRFTIME
+   setDateFormat(resource.date_format);
+   setClock24Hour(resource.clock24hour);
+ #endif // HAVE_STRFTIME
+   setHideToolbar(resource.hide_toolbar);
+ }
+ void BScreen::load() {
+   ostrstream rscreen, rname, rclass;
+   string s;
+   bool b;
+   long l;
+   rscreen << "session.screen" << getScreenNumber() << '.' << ends;
+   rname << rscreen.str() << "hideToolbar" << ends;
+   rclass << rscreen.str() << "HideToolbar" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     resource.hide_toolbar = b;
+   else
+     resource.hide_toolbar = false;
+   Toolbar *t = getToolbar();
+   if (t != NULL) {
+     if (resource.hide_toolbar)
+       t->unMapToolbar();
+     else
+       t->mapToolbar();
+   }
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "fullMaximization" << ends;
+   rclass << rscreen.str() << "FullMaximization" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     resource.full_max = b;
+   else
+     resource.full_max = false;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "focusNewWindows" << ends;
+   rclass << rscreen.str() << "FocusNewWindows" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     resource.focus_new = b;
+   else
+     resource.focus_new = false;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "focusLastWindow" << ends;
+   rclass << rscreen.str() << "FocusLastWindow" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     resource.focus_last = b;
+   else
+     resource.focus_last = false;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "rowPlacementDirection" << ends;
+   rclass << rscreen.str() << "RowPlacementDirection" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (0 == strncasecmp(s.c_str(), "RightToLeft", s.length()))
+       resource.row_direction = RightLeft;
 -    else //if (0 == strncasecmp(s.c_str(), "TopToBottom", s.length()))
++    else if (0 == strncasecmp(s.c_str(), "LeftToRight", s.length()))
+       resource.row_direction = LeftRight;
+   } else
+     resource.row_direction = LeftRight;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "colPlacementDirection" << ends;
+   rclass << rscreen.str() << "ColPlacementDirection" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (0 == strncasecmp(s.c_str(), "BottomToTop", s.length()))
+       resource.col_direction = BottomTop;
 -    } else { //if (0 == strncasecmp(s.c_str(), "SloppyFocus", s.length())) {
++    else if (0 == strncasecmp(s.c_str(), "TopToBottom", s.length()))
+       resource.col_direction = TopBottom;
+   } else
+     resource.col_direction = TopBottom;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "workspaces" << ends;
+   rclass << rscreen.str() << "Workspaces" << ends;
+   if (config.getValue(rname.str(), rclass.str(), l))
+     resource.workspaces = l;
+   else
+     resource.workspaces = 1;
+   removeWorkspaceNames();
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "workspaceNames" << ends;
+   rclass << rscreen.str() << "WorkspaceNames" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     string::const_iterator it = s.begin(), end = s.end();
+     while(1) {
+       string::const_iterator tmp = it;// current string.begin()
+       it = std::find(tmp, end, ',');       // look for comma between tmp and end
+       string name(tmp, it);           // name = s[tmp:it]
+       addWorkspaceName(name.c_str());
+       if (it == end)
+         break;
+       ++it;
+     }
+   }
+   
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "focusModel" << ends;
+   rclass << rscreen.str() << "FocusModel" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (0 == strncasecmp(s.c_str(), "ClickToFocus", s.length())) {
+       resource.auto_raise = false;
+       resource.sloppy_focus = false;
+     } else if (0 == strncasecmp(s.c_str(), "AutoRaiseSloppyFocus",
+                                 s.length())) {
+       resource.sloppy_focus = true;
+       resource.auto_raise = true;
 -    else if (0 == strncasecmp(s.c_str(), "UnderMousePlacement", s.length()))
 -      resource.placement_policy = UnderMousePlacement;
 -    else if (0 == strncasecmp(s.c_str(), "ClickMousePlacement", s.length()))
 -      resource.placement_policy = ClickMousePlacement;
 -    else //if (0 == strncasecmp(s.c_str(), "CascadePlacement", s.length()))
++    } else if (0 == strncasecmp(s.c_str(), "SloppyFocus", s.length())) {
+       resource.sloppy_focus = true;
+       resource.auto_raise = false;
+     }
+   } else {
+     resource.sloppy_focus = true;
+     resource.auto_raise = false;
+   }
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "windowZones" << ends;
+   rclass << rscreen.str() << "WindowZones" << ends;
+   if (config.getValue(rname.str(), rclass.str(), l))
+     resource.zones = (l == 1 || l == 2 || l == 4) ? l : 1;
+   else
+     resource.zones = 4;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "windowPlacement" << ends;
+   rclass << rscreen.str() << "WindowPlacement" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (0 == strncasecmp(s.c_str(), "RowSmartPlacement", s.length()))
+       resource.placement_policy = RowSmartPlacement;
+     else if (0 == strncasecmp(s.c_str(), "ColSmartPlacement", s.length()))
+       resource.placement_policy = ColSmartPlacement;
+     else if (0 == strncasecmp(s.c_str(), "BestFitPlacement", s.length()))
+       resource.placement_policy = BestFitPlacement;
 -    else //if (strncasecmp(s.c_str(), "American", s.length()))
++    else if (0 == strncasecmp(s.c_str(), "CascadePlacement", s.length()))
+       resource.placement_policy = CascadePlacement;
+   } else
+     resource.placement_policy = CascadePlacement;
+ #ifdef    HAVE_STRFTIME
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "strftimeFormat" << ends;
+   rclass << rscreen.str() << "StrftimeFormat" << ends;
+   if (resource.strftime_format != NULL)
+     delete [] resource.strftime_format;
+   if (config.getValue(rname.str(), rclass.str(), s))
+     resource.strftime_format = bstrdup(s.c_str());
+   else
+     resource.strftime_format = bstrdup("%I:%M %p");
+ #else // !HAVE_STRFTIME
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "dateFormat" << ends;
+   rclass << rscreen.str() << "DateFormat" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (strncasecmp(s.c_str(), "European", s.length()))
+       resource.date_format = B_EuropeanDate;
++    else if (strncasecmp(s.c_str(), "American", s.length()))
+       resource.date_format = B_AmericanDate;
+   } else
+     resource.date_format = B_AmericanDate;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "clockFormat" << ends;
+   rclass << rscreen.str() << "ClockFormat" << ends;
+   if (config.getValue(rname.str(), rclass.str(), l)) {
+     if (clock == 24)
+       resource.clock24hour = true;
+     else if (clock == 12)
+       resource.clock24hour =  false;
+   } else
+     resource.clock24hour =  false;
+ #endif // HAVE_STRFTIME
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "edgeSnapThreshold" << ends;
+   rclass << rscreen.str() << "EdgeSnapThreshold" << ends;
+   if (config.getValue(rname.str(), rclass.str(), l))
+     resource.edge_snap_threshold = l;
+   else
+     resource.edge_snap_threshold = 4;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "imageDither" << ends;
+   rclass << rscreen.str() << "ImageDither" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     resource.image_dither = b;
+   else
+     resource.image_dither = true;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "rootCommand" << ends;
+   rclass << rscreen.str() << "RootCommand" << ends;
+   if (resource.root_command != NULL)
+     delete [] resource.root_command;
+   
+   if (config.getValue(rname.str(), rclass.str(), s))
+     resource.root_command = bstrdup(s.c_str());
+   else
+     resource.root_command = NULL;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "opaqueMove" << ends;
+   rclass << rscreen.str() << "OpaqueMove" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     resource.opaque_move = b;
+   else
+     resource.opaque_move = false;
+   rscreen.rdbuf()->freeze(0);
+   rname.rdbuf()->freeze(0);
+   rclass.rdbuf()->freeze(0);
+ }
  void BScreen::reconfigure(void) {
+   load();
+   toolbar->load();
+ #ifdef    SLIT
+   slit->load();
+ #endif // SLIT
    LoadStyle();
  
    XGCValues gcv;
@@@ -1358,8 -1919,9 +1808,10 @@@ OpenboxWindow *BScreen::getIcon(int ind
  
  
  int BScreen::addWorkspace(void) {
-   Workspace *wkspc = new Workspace(this, workspacesList->count());
+   Workspace *wkspc = new Workspace(*this, workspacesList->count());
    workspacesList->insert(wkspc);
++  setWorkspaceCount(resource.workspaces+1);
+   saveWorkspaceNames();
  
    workspacemenu->insert(wkspc->getName(), wkspc->getMenu(),
                        wkspc->getWorkspaceID() + 2);
@@@ -1407,11 -1969,11 +1859,11 @@@ void BScreen::changeWorkspaceID(int id
      workspacemenu->setItemSelected(current_workspace->getWorkspaceID() + 2,
                                   False);
  
-     if (openbox->getFocusedWindow() &&
-       openbox->getFocusedWindow()->getScreen() == this &&
-         (! openbox->getFocusedWindow()->isStuck())) {
-       current_workspace->setLastFocusedWindow(openbox->getFocusedWindow());
-       openbox->setFocusedWindow((OpenboxWindow *) 0);
 -    if (openbox.focusedWindow() &&
 -      openbox.focusedWindow()->getScreen() == this &&
 -        (! openbox.focusedWindow()->isStuck())) {
 -      current_workspace->setLastFocusedWindow(openbox.focusedWindow());
 -      openbox.focusWindow((OpenboxWindow *) 0);
++    if (openbox.getFocusedWindow() &&
++      openbox.getFocusedWindow()->getScreen() == this &&
++        (! openbox.getFocusedWindow()->isStuck())) {
++      current_workspace->setLastFocusedWindow(openbox.getFocusedWindow());
++      openbox.setFocusedWindow(NULL);
      }
  
      current_workspace = getWorkspace(id);
@@@ -1445,8 -2007,8 +1897,8 @@@ void BScreen::addNetizen(Netizen *n) 
                       w->getWorkspaceID());
    }
  
-   Window f = ((openbox->getFocusedWindow()) ?
-               openbox->getFocusedWindow()->getClientWindow() : None);
 -  Window f = ((openbox.focusedWindow()) ?
 -              openbox.focusedWindow()->getClientWindow() : None);
++  Window f = ((openbox.getFocusedWindow()) ?
++              openbox.getFocusedWindow()->getClientWindow() : None);
    n->sendWindowFocus(f);
  }
  
@@@ -1480,8 -2042,8 +1932,8 @@@ void BScreen::updateNetizenWorkspaceCou
  
  
  void BScreen::updateNetizenWindowFocus(void) {
-   Window f = ((openbox->getFocusedWindow()) ?
-               openbox->getFocusedWindow()->getClientWindow() : None);
 -  Window f = ((openbox.focusedWindow()) ?
 -              openbox.focusedWindow()->getClientWindow() : None);
++  Window f = ((openbox.getFocusedWindow()) ?
++              openbox.getFocusedWindow()->getClientWindow() : None);
    LinkedListIterator<Netizen> it(netizenList);
    for (Netizen *n = it.current(); n; it++, n = it.current())
      n->sendWindowFocus(f);
@@@ -1625,11 -2176,11 +2066,11 @@@ void BScreen::nextFocus(void) 
    int focused_window_number = -1;
    OpenboxWindow *next;
  
-   if (openbox->getFocusedWindow()) {
-     if (openbox->getFocusedWindow()->getScreen()->getScreenNumber() ==
 -  if (openbox.focusedWindow()) {
 -    if (openbox.focusedWindow()->getScreen()->getScreenNumber() ==
++  if (openbox.getFocusedWindow()) {
++    if (openbox.getFocusedWindow()->getScreen()->getScreenNumber() ==
        getScreenNumber()) {
        have_focused = True;
-       focused_window_number = openbox->getFocusedWindow()->getWindowNumber();
 -      focused_window_number = openbox.focusedWindow()->getWindowNumber();
++      focused_window_number = openbox.getFocusedWindow()->getWindowNumber();
      }
    }
  
@@@ -1659,11 -2210,11 +2100,11 @@@ void BScreen::prevFocus(void) 
    int focused_window_number = -1;
    OpenboxWindow *prev;
  
-   if (openbox->getFocusedWindow()) {
-     if (openbox->getFocusedWindow()->getScreen()->getScreenNumber() ==
 -  if (openbox.focusedWindow()) {
 -    if (openbox.focusedWindow()->getScreen()->getScreenNumber() ==
++  if (openbox.getFocusedWindow()) {
++    if (openbox.getFocusedWindow()->getScreen()->getScreenNumber() ==
        getScreenNumber()) {
        have_focused = True;
-       focused_window_number = openbox->getFocusedWindow()->getWindowNumber();
 -      focused_window_number = openbox.focusedWindow()->getWindowNumber();
++      focused_window_number = openbox.getFocusedWindow()->getWindowNumber();
      }
    }
  
@@@ -1692,17 -2243,17 +2133,17 @@@ void BScreen::raiseFocus(void) 
    Bool have_focused = False;
    int focused_window_number = -1;
  
-   if (openbox->getFocusedWindow()) {
-     if (openbox->getFocusedWindow()->getScreen()->getScreenNumber() ==
 -  if (openbox.focusedWindow()) {
 -    if (openbox.focusedWindow()->getScreen()->getScreenNumber() ==
++  if (openbox.getFocusedWindow()) {
++    if (openbox.getFocusedWindow()->getScreen()->getScreenNumber() ==
        getScreenNumber()) {
        have_focused = True;
-       focused_window_number = openbox->getFocusedWindow()->getWindowNumber();
 -      focused_window_number = openbox.focusedWindow()->getWindowNumber();
++      focused_window_number = openbox.getFocusedWindow()->getWindowNumber();
      }
    }
  
    if ((getCurrentWorkspace()->getCount() > 1) && have_focused)
-     getWorkspace(openbox->getFocusedWindow()->getWorkspaceNumber())->
-       raiseWindow(openbox->getFocusedWindow());
 -    getWorkspace(openbox.focusedWindow()->getWorkspaceNumber())->
 -      raiseWindow(openbox.focusedWindow());
++    getWorkspace(openbox.getFocusedWindow()->getWorkspaceNumber())->
++      raiseWindow(openbox.getFocusedWindow());
  }
  
  
diff --cc src/Screen.h
index d49668f963c7153ecb74fd8aeac94e4f537993b1,124d4f98635501e60d89aca4f674638b285f1f27..8acae7ee0b7d4e0947af7541da3a15e07b3e1269
@@@ -173,134 -170,110 +170,108 @@@ protected
  
  
  public:
-   BScreen(Openbox *, int);
-   ~BScreen(void);
-   inline const Bool &isToolbarOnTop(void) const
-   { return resource.toolbar_on_top; }
-   inline const Bool &doToolbarAutoHide(void) const
-   { return resource.toolbar_auto_hide; }
-   inline const Bool &isSloppyFocus(void) const
-   { return resource.sloppy_focus; }
-   inline const Bool &isRootColormapInstalled(void) const
-   { return root_colormap_installed; }
-   inline const Bool &doAutoRaise(void) const { return resource.auto_raise; }
-   inline const Bool &isScreenManaged(void) const { return managed; }
-   inline const Bool &doImageDither(void) const
-   { return resource.image_dither; }
-   inline const Bool &doOrderedDither(void) const
-   { return resource.ordered_dither; }
-   inline const Bool &doOpaqueMove(void) const { return resource.opaque_move; }
-   inline const Bool &doFullMax(void) const { return resource.full_max; }
-   inline const Bool &doFocusNew(void) const { return resource.focus_new; }
-   inline const Bool &doFocusLast(void) const { return resource.focus_last; }
+   BScreen(Openbox &, int, Resource &);
+   ~BScreen();
  
+   inline const Bool &isScreenManaged() const { return managed; }
    inline const GC &getOpGC() const { return opGC; }
  
-   inline Openbox *getOpenbox(void) { return openbox; }
-   inline BColor *getBorderColor(void) { return &resource.border_color; }
-   inline BImageControl *getImageControl(void) { return image_control; }
-   inline Rootmenu *getRootmenu(void) { return rootmenu; }
+   inline Openbox &getOpenbox() { return openbox; }
+   inline BColor *getBorderColor() { return &resource.border_color; }
+   inline BImageControl *getImageControl() { return image_control; }
+   inline Rootmenu *getRootmenu() { return rootmenu; }
  
  #ifdef   SLIT
-   inline const Bool &isSlitOnTop(void) const { return resource.slit_on_top; }
-   inline const Bool &doSlitAutoHide(void) const
-   { return resource.slit_auto_hide; }
-   inline Slit *getSlit(void) { return slit; }
-   inline const int &getSlitPlacement(void) const
-   { return resource.slit_placement; }
-   inline const int &getSlitDirection(void) const
-   { return resource.slit_direction; }
-   inline void saveSlitPlacement(int p) { resource.slit_placement = p; }
-   inline void saveSlitDirection(int d) { resource.slit_direction = d; }
-   inline void saveSlitOnTop(Bool t)    { resource.slit_on_top = t; }
-   inline void saveSlitAutoHide(Bool t) { resource.slit_auto_hide = t; }
+   inline Slit *getSlit() { return slit; }
  #endif // SLIT
  
-   inline int getWindowZones(void) const
-   { return resource.zones; }
-   inline void saveWindowZones(int z) { resource.zones = z; }
-   
-   inline Toolbar *getToolbar(void) { return toolbar; }
+   inline Toolbar *getToolbar() { return toolbar; }
  
 -  Rect availableArea() const;
 -  
    inline Workspace *getWorkspace(int w) { return workspacesList->find(w); }
-   inline Workspace *getCurrentWorkspace(void) { return current_workspace; }
+   inline Workspace *getCurrentWorkspace() { return current_workspace; }
  
-   inline Workspacemenu *getWorkspacemenu(void) { return workspacemenu; }
+   inline Workspacemenu *getWorkspacemenu() { return workspacemenu; }
+   
+   inline void iconUpdate() { iconmenu->update(); }
  
-   inline const unsigned int &getHandleWidth(void) const
+   inline const unsigned int &getHandleWidth() const
    { return resource.handle_width; }
-   inline const unsigned int &getBevelWidth(void) const
+   inline const unsigned int &getBevelWidth() const
    { return resource.bevel_width; }
-   inline const unsigned int &getFrameWidth(void) const
+   inline const unsigned int &getFrameWidth() const
    { return resource.frame_width; }
-   inline const unsigned int &getBorderWidth(void) const
+   inline const unsigned int &getBorderWidth() const
    { return resource.border_width; }
  
    inline const int getCurrentWorkspaceID()
    { return current_workspace->getWorkspaceID(); }
-   inline const int getCount(void) { return workspacesList->count(); }
-   inline const int getIconCount(void) { return iconList->count(); }
-   inline const int &getNumberOfWorkspaces(void) const
-   { return resource.workspaces; }
-   inline const int &getToolbarPlacement(void) const
-   { return resource.toolbar_placement; }
-   inline const int &getToolbarWidthPercent(void) const
-   { return resource.toolbar_width_percent; }
-   inline const int &getPlacementPolicy(void) const
-   { return resource.placement_policy; }
-   inline const int &getEdgeSnapThreshold(void) const
-   { return resource.edge_snap_threshold; }
-   inline const int &getRowPlacementDirection(void) const
-   { return resource.row_direction; }
-   inline const int &getColPlacementDirection(void) const
-   { return resource.col_direction; }
-   inline void saveRootCommand(const char *cmd) {
-     if (resource.root_command != NULL)
-       delete [] resource.root_command;
-     if (cmd != NULL)
-       resource.root_command = bstrdup(cmd);
-     else
-       resource.root_command = NULL;
-   }
-   inline const char *getRootCommand(void) const
-   { return resource.root_command; }
-   
+   inline const int getWorkspaceCount() { return workspacesList->count(); }
+   inline const int getIconCount() { return iconList->count(); }
+   inline const Bool &isRootColormapInstalled() const
+     { return root_colormap_installed; }
    inline void setRootColormapInstalled(Bool r) { root_colormap_installed = r; }
-   inline void saveSloppyFocus(Bool s) { resource.sloppy_focus = s; }
-   inline void saveAutoRaise(Bool a) { resource.auto_raise = a; }
-   inline void saveWorkspaces(int w) { resource.workspaces = w; }
-   inline void saveToolbarOnTop(Bool r) { resource.toolbar_on_top = r; }
-   inline void saveToolbarAutoHide(Bool r) { resource.toolbar_auto_hide = r; }
-   inline void saveToolbarWidthPercent(int w)
-   { resource.toolbar_width_percent = w; }
-   inline void saveToolbarPlacement(int p) { resource.toolbar_placement = p; }
-   inline void savePlacementPolicy(int p) { resource.placement_policy = p; }
-   inline void saveRowPlacementDirection(int d) { resource.row_direction = d; }
-   inline void saveColPlacementDirection(int d) { resource.col_direction = d; }
-   inline void saveEdgeSnapThreshold(int t)
-   { resource.edge_snap_threshold = t; }
-   inline void saveImageDither(Bool d) { resource.image_dither = d; }
-   inline void saveOpaqueMove(Bool o) { resource.opaque_move = o; }
-   inline void saveFullMax(Bool f) { resource.full_max = f; }
-   inline void saveFocusNew(Bool f) { resource.focus_new = f; }
-   inline void saveFocusLast(Bool f) { resource.focus_last = f; }
-   inline void iconUpdate(void) { iconmenu->update(); }
+   
+   inline bool sloppyFocus() const { return resource.sloppy_focus; }
+   void setSloppyFocus(bool s);
+   
+   inline bool autoRaise() const { return resource.auto_raise; }
+   void setAutoRaise(bool a);
+   
+   inline bool imageDither() const { return resource.image_dither; }
 -  void setImageDither(bool d, bool reconfig = true);
++  void setImageDither(bool d);
+   
+   inline bool orderedDither() const { return resource.ordered_dither; }
+   
+   inline bool opaqueMove() const { return resource.opaque_move; }
+   void setOpaqueMove(bool o);
+   
+   inline bool fullMax() const { return resource.full_max; }
+   void setFullMax(bool f);
+   
+   inline bool focusNew() const { return resource.focus_new; }
+   void setFocusNew(bool f);
+   
+   inline bool focusLast() const { return resource.focus_last; }
+   void setFocusLast(bool f);
+   
+   inline int getWindowZones() const { return resource.zones; }
+   void setWindowZones(int z);
+   
+   inline int workspaceCount() const { return resource.workspaces; }
+   void setWorkspaceCount(int w);
+   inline int placementPolicy() const { return resource.placement_policy; }
+   void setPlacementPolicy(int p);
  
+   inline int edgeSnapThreshold() const { return resource.edge_snap_threshold; }
+   void setEdgeSnapThreshold(int t);
+   
+   inline int rowPlacementDirection() const { return resource.row_direction; }
+   void setRowPlacementDirection(int d);
+   
+   inline int colPlacementDirection() const { return resource.col_direction; }
+   void setColPlacementDirection(int d);
+   
+   inline char *rootCommand() const { return resource.root_command; }
+   inline void setRootCommand(const char *cmd);
+   
  #ifdef    HAVE_STRFTIME
-   inline char *getStrftimeFormat(void) { return resource.strftime_format; }
-   void saveStrftimeFormat(char *);
+   inline char *strftimeFormat() { return resource.strftime_format; }
+   void setStrftimeFormat(const char *);
  #else // !HAVE_STRFTIME
-   inline int getDateFormat(void) { return resource.date_format; }
-   inline void saveDateFormat(int f) { resource.date_format = f; }
-   inline Bool isClock24Hour(void) { return resource.clock24hour; }
-   inline void saveClock24Hour(Bool c) { resource.clock24hour = c; }
+   inline int dateFormat() { return resource.date_format; }
+   void setDateFormat(int f);
+   inline bool clock24Hour() { return resource.clock24hour; }
+   void setClock24Hour(Bool c);
  #endif // HAVE_STRFTIME
  
-   inline WindowStyle *getWindowStyle(void) { return &resource.wstyle; }
-   inline MenuStyle *getMenuStyle(void) { return &resource.mstyle; }
-   inline ToolbarStyle *getToolbarStyle(void) { return &resource.tstyle; }
+   inline bool hideToolbar() const { return resource.hide_toolbar; }
+   void setHideToolbar(bool);
+   inline WindowStyle *getWindowStyle() { return &resource.wstyle; }
+   inline MenuStyle *getMenuStyle() { return &resource.mstyle; }
+   inline ToolbarStyle *getToolbarStyle() { return &resource.tstyle; }
  
    OpenboxWindow *getIcon(int);
  
    void updateNetizenWindowRaise(Window);
    void updateNetizenWindowLower(Window);
  
-   enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement, LeftRight,
-          RightLeft, TopBottom, BottomTop };
+   enum { RowSmartPlacement = 1, ColSmartPlacement, CascadePlacement,
 -         BestFitPlacement, UnderMousePlacement, ClickMousePlacement,
 -         LeftRight, RightLeft, TopBottom, BottomTop };
++         BestFitPlacement, LeftRight, RightLeft, TopBottom, BottomTop };
    enum { LeftJustify = 1, RightJustify, CenterJustify };
    enum { RoundBullet = 1, TriangleBullet, SquareBullet, NoBullet };
    enum { Restart = 1, RestartOther, Exit, Shutdown, Execute, Reconfigure,
diff --cc src/Slit.cc
index 2eb940e746b01e53b86402e97dbfc4b550cc65c7,bbaeb1f150633af7f8bb56cf7c8c16bbb692116c..cb72800b97f1ea8debc762c595f5e9de38bb8295
  #include "Slit.h"
  #include "Toolbar.h"
  
- Slit::Slit(BScreen *scr) {
-   screen = scr;
-   openbox = screen->getOpenbox();
-   on_top = screen->isSlitOnTop();
-   hidden = do_auto_hide = screen->doSlitAutoHide();
-   display = screen->getBaseDisplay()->getXDisplay();
 -#include <strstream>
+ #include <string>
++#include <strstream>
+ using namespace std;
+ Slit::Slit(BScreen &scr, Resource &conf) : screen(scr),
+   openbox(scr.getOpenbox()), config(conf)
+ {
+   load();
+   
+   display = screen.getBaseDisplay().getXDisplay();
    frame.window = frame.pixmap = None;
  
-   timer = new BTimer(openbox, this);
-   timer->setTimeout(openbox->getAutoRaiseDelay());
+   timer = new BTimer(openbox, *this);
+   timer->setTimeout(openbox.getAutoRaiseDelay());
    timer->fireOnce(True);
  
-   slitmenu = new Slitmenu(this);
 +  clientList = new LinkedList<SlitClient>;
 +
+   slitmenu = new Slitmenu(*this);
  
    XSetWindowAttributes attrib;
    unsigned long create_mask = CWBackPixmap | CWBackPixel | CWBorderPixel |
@@@ -91,12 -90,13 +92,12 @@@ Slit::~Slit() 
    if (timer->isTiming()) timer->stop();
    delete timer;
  
 -  clientList.clear();
 -  
 +  delete clientList;
    delete slitmenu;
  
-   screen->getImageControl()->removeImage(frame.pixmap);
+   screen.getImageControl()->removeImage(frame.pixmap);
  
-   openbox->removeSlitSearch(frame.window);
+   openbox.removeSlitSearch(frame.window);
  
    XDestroyWindow(display, frame.window);
  
@@@ -156,10 -156,10 +157,10 @@@ void Slit::addClient(Window w) 
                   SubstructureNotifyMask | EnterWindowMask);
      XFlush(display);
  
 -    clientList.push_back(client);
 +    clientList->insert(client);
  
-     openbox->saveSlitSearch(client->client_window, this);
-     openbox->saveSlitSearch(client->icon_window, this);
+     openbox.saveSlitSearch(client->client_window, this);
+     openbox.saveSlitSearch(client->icon_window, this);
      reconfigure();
    }
  
  
  
  void Slit::removeClient(SlitClient *client, Bool remap) {
-   openbox->removeSlitSearch(client->client_window);
-   openbox->removeSlitSearch(client->icon_window);
+   openbox.removeSlitSearch(client->client_window);
+   openbox.removeSlitSearch(client->icon_window);
 -
 -  clientList.remove(client);
 +  clientList->remove(client);
  
-   screen->removeNetizen(client->window);
+   screen.removeNetizen(client->window);
  
-   if (remap && openbox->validateWindow(client->window)) {
+   if (remap && openbox.validateWindow(client->window)) {
      XSelectInput(display, frame.window, NoEventMask);
      XSelectInput(display, client->window, NoEventMask);
-     XReparentWindow(display, client->window, screen->getRootWindow(),
+     XReparentWindow(display, client->window, screen.getRootWindow(),
                    client->x, client->y);
      XChangeSaveSet(display, client->window, SetModeDelete);
      XSelectInput(display, frame.window, SubstructureRedirectMask |
@@@ -195,77 -196,186 +196,188 @@@ void Slit::removeClient(Window w, Bool 
  
    Bool reconf = False;
  
 -  slitClientList::iterator it;
 -  for (it = clientList.begin(); it != clientList.end(); it++)
 -    if ((*it)->window == w) {
 -      removeClient(*it, remap);
 +  LinkedListIterator<SlitClient> it(clientList);
 +  for (SlitClient *tmp = it.current(); tmp; it++, tmp = it.current()) {
 +    if (tmp->window == w) {
 +      removeClient(tmp, remap);
        reconf = True;
 +
        break;
      }
 +  }
  
 -  if (reconf)
 -    reconfigure();
 +  if (reconf) reconfigure();
  
-   openbox->ungrab();
+   openbox.ungrab();
+ }
+ void Slit::setOnTop(bool b) {
+   m_ontop = b;
+   ostrstream s;
+   s << "session.screen" << screen.getScreenNumber() << ".slit.onTop" << ends;
+   config.setValue(s.str(), m_ontop ? "True" : "False");
+   s.rdbuf()->freeze(0);
+ }
+ void Slit::setAutoHide(bool b) {
+   m_autohide = b;
+   ostrstream s;
+   s << "session.screen" << screen.getScreenNumber() << ".slit.autoHide" << ends;
+   config.setValue(s.str(), m_autohide ? "True" : "False");
+   s.rdbuf()->freeze(0);
+ }
+ void Slit::setPlacement(int p) {
+   m_placement = p;
+   ostrstream s;
 -  s << "session.screen" << screen.getScreenNumber() << ".slit.placement"
 -    << ends;
++  s << "session.screen" << screen.getScreenNumber() << ".slit.placement" <<
++    ends;
+   const char *placement;
+   switch (m_placement) {
+   case TopLeft: placement = "TopLeft"; break;
+   case CenterLeft: placement = "CenterLeft"; break;
+   case BottomLeft: placement = "BottomLeft"; break;
+   case TopCenter: placement = "TopCenter"; break;
+   case BottomCenter: placement = "BottomCenter"; break;
+   case TopRight: placement = "TopRight"; break;
+   case BottomRight: placement = "BottomRight"; break;
+   case CenterRight: default: placement = "CenterRight"; break;
+   }
+   config.setValue(s.str(), placement);
+   s.rdbuf()->freeze(0);
+ }
+ void Slit::setDirection(int d) {
+   m_direction = d;
+   ostrstream s;
 -  s << "session.screen" << screen.getScreenNumber() << ".slit.direction"
 -    << ends;
++  s << "session.screen" << screen.getScreenNumber() << ".slit.direction" <<
++    ends;
+   config.setValue(s.str(),
+                   m_direction == Horizontal ? "Horizontal" : "Vertical");
+   s.rdbuf()->freeze(0);
+ }
+ void Slit::save() {
+   setOnTop(m_ontop);
+   setAutoHide(m_autohide);
+   setPlacement(m_placement);
+   setDirection(m_direction);
  }
  
+ void Slit::load() {
+   ostrstream rscreen, rname, rclass;
+   string s;
+   bool b;
+   rscreen << "session.screen" << screen.getScreenNumber() << '.' << ends;
+   rname << rscreen.str() << "slit.placement" << ends;
+   rclass << rscreen.str() << "Slit.Placement" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (0 == strncasecmp(s.c_str(), "TopLeft", s.length()))
+       m_placement = TopLeft;
+     else if (0 == strncasecmp(s.c_str(), "CenterLeft", s.length()))
+       m_placement = CenterLeft;
+     else if (0 == strncasecmp(s.c_str(), "BottomLeft", s.length()))
+       m_placement = BottomLeft;
+     else if (0 == strncasecmp(s.c_str(), "TopCenter", s.length()))
+       m_placement = TopCenter;
+     else if (0 == strncasecmp(s.c_str(), "BottomCenter", s.length()))
+       m_placement = BottomCenter;
+     else if (0 == strncasecmp(s.c_str(), "TopRight", s.length()))
+       m_placement = TopRight;
+     else if (0 == strncasecmp(s.c_str(), "BottomRight", s.length()))
+       m_placement = BottomRight;
+     else if (0 == strncasecmp(s.c_str(), "CenterRight", s.length()))
+       m_placement = CenterRight;
+   } else
+     m_placement = CenterRight;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "slit.direction" << ends;
+   rclass << rscreen.str() << "Slit.Direction" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (0 == strncasecmp(s.c_str(), "Horizontal", s.length()))
+       m_direction = Horizontal;
+     else if (0 == strncasecmp(s.c_str(), "Vertical", s.length()))
+       m_direction = Vertical;
+   } else
+     m_direction = Vertical;
+  
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "slit.onTop" << ends;
+   rclass << rscreen.str() << "Slit.OnTop" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     m_ontop = b;
+   else
+     m_ontop = false;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "slit.autoHide" << ends;
+   rclass << rscreen.str() << "Slit.AutoHide" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     m_hidden = m_autohide = b;
+   else
+     m_hidden = m_autohide = false;
+   rscreen.rdbuf()->freeze(0);
+   rname.rdbuf()->freeze(0);
+   rclass.rdbuf()->freeze(0);
+ }
  
  void Slit::reconfigure(void) {
-   frame.width = 0;
-   frame.height = 0;
+   frame.area.setSize(0, 0);
 -  slitClientList::const_iterator it;
 +  LinkedListIterator<SlitClient> it(clientList);
 +  SlitClient *client;
  
-   switch (screen->getSlitDirection()) {
+   switch (m_direction) {
    case Vertical:
 -    for (it = clientList.begin(); it != clientList.end(); it++) {
 -      frame.area.setH(frame.area.h() + (*it)->height + screen.getBevelWidth());
 +    for (client = it.current(); client; it++, client = it.current()) {
-       frame.height += client->height + screen->getBevelWidth();
++      frame.area.setH(frame.area.h() + client->height + screen.getBevelWidth());
  
-       if (frame.width < client->width)
-         frame.width = client->width;
 -      if (frame.area.w() < (*it)->width)
 -        frame.area.setW((*it)->width);
++      if (frame.area.w() < client->width)
++        frame.area.setW(client->width);
      }
  
-     if (frame.width < 1)
-       frame.width = 1;
+     if (frame.area.w() < 1)
+       frame.area.setW(1);
      else
-       frame.width += (screen->getBevelWidth() * 2);
+       frame.area.setW(frame.area.w() + (screen.getBevelWidth() * 2));
  
-     if (frame.height < 1)
-       frame.height = 1;
+     if (frame.area.h() < 1)
+       frame.area.setH(1);
      else
-       frame.height += screen->getBevelWidth();
+       frame.area.setH(frame.area.h() + screen.getBevelWidth());
  
      break;
  
    case Horizontal:
 -    for (it = clientList.begin(); it != clientList.end(); it++) {
 -      frame.area.setW(frame.area.w() + (*it)->width + screen.getBevelWidth());
 +    for (client = it.current(); client; it++, client = it.current()) {
-       frame.width += client->width + screen->getBevelWidth();
++      frame.area.setW(frame.area.w() + client->width + screen.getBevelWidth());
  
-       if (frame.height < client->height)
-         frame.height = client->height;
 -      if (frame.area.h() < (*it)->height)
 -        frame.area.setH((*it)->height);
++      if (frame.area.h() < client->height)
++        frame.area.setH(client->height);
      }
  
-     if (frame.width < 1)
-       frame.width = 1;
+     if (frame.area.w() < 1)
+       frame.area.setW(1);
      else
-       frame.width += screen->getBevelWidth();
+       frame.area.setW(frame.area.w() + screen.getBevelWidth());
  
-     if (frame.height < 1)
-       frame.height = 1;
+     if (frame.area.h() < 1)
+       frame.area.setH(1);
      else
-       frame.height += (screen->getBevelWidth() * 2);
+       frame.area.setH(frame.area.h() + (screen.getBevelWidth() * 2));
  
      break;
    }
  
    reposition();
  
-   XSetWindowBorderWidth(display ,frame.window, screen->getBorderWidth());
+   XSetWindowBorderWidth(display ,frame.window, screen.getBorderWidth());
    XSetWindowBorder(display, frame.window,
-                    screen->getBorderColor()->getPixel());
+                    screen.getBorderColor()->getPixel());
  
 -  if (! clientList.size())
 +  if (! clientList->count())
      XUnmapWindow(display, frame.window);
    else
      XMapWindow(display, frame.window);
    XClearWindow(display, frame.window);
  
    int x, y;
 +  it.reset();
  
-   switch (screen->getSlitDirection()) {
+   switch (m_direction) {
    case Vertical:
      x = 0;
-     y = screen->getBevelWidth();
+     y = screen.getBevelWidth();
  
 -    for (it = clientList.begin(); it != clientList.end(); it++) {
 -      x = (frame.area.w() - (*it)->width) / 2;
 +    for (client = it.current(); client; it++, client = it.current()) {
-       x = (frame.width - client->width) / 2;
++      x = (frame.area.w() - client->width) / 2;
  
 -      XMoveResizeWindow(display, (*it)->window, x, y,
 -                        (*it)->width, (*it)->height);
 -      XMapWindow(display, (*it)->window);
 +      XMoveResizeWindow(display, client->window, x, y,
 +                        client->width, client->height);
 +      XMapWindow(display, client->window);
  
        // for ICCCM compliance
 -      (*it)->x = x;
 -      (*it)->y = y;
 +      client->x = x;
 +      client->y = y;
  
        XEvent event;
        event.type = ConfigureNotify;
        event.xconfigure.above = frame.window;
        event.xconfigure.override_redirect = False;
  
 -      XSendEvent(display, (*it)->window, False, StructureNotifyMask, &event);
 +      XSendEvent(display, client->window, False, StructureNotifyMask, &event);
  
-       y += client->height + screen->getBevelWidth();
 -      y += (*it)->height + screen.getBevelWidth();
++      y += client->height + screen.getBevelWidth();
      }
  
      break;
  
    case Horizontal:
-     x = screen->getBevelWidth();
+     x = screen.getBevelWidth();
      y = 0;
  
 -    for (it = clientList.begin(); it != clientList.end(); it++) {
 -      y = (frame.area.h() - (*it)->height) / 2;
 +    for (client = it.current(); client; it++, client = it.current()) {
-       y = (frame.height - client->height) / 2;
++      y = (frame.area.h() - client->height) / 2;
  
 -      XMoveResizeWindow(display, (*it)->window, x, y,
 -                        (*it)->width, (*it)->height);
 -      XMapWindow(display, (*it)->window);
 +      XMoveResizeWindow(display, client->window, x, y,
 +                        client->width, client->height);
 +      XMapWindow(display, client->window);
  
        // for ICCCM compliance
 -      (*it)->x = x;
 -      (*it)->y = y;
 +      client->x = x;
 +      client->y = y;
  
        XEvent event;
        event.type = ConfigureNotify;
        event.xconfigure.above = frame.window;
        event.xconfigure.override_redirect = False;
  
 -      XSendEvent(display, (*it)->window, False, StructureNotifyMask, &event);
 +      XSendEvent(display, client->window, False, StructureNotifyMask, &event);
  
-       x += client->width + screen->getBevelWidth();
 -      x += (*it)->width + screen.getBevelWidth();
++      x += client->width + screen.getBevelWidth();
      }
  
      break;
@@@ -586,17 -677,15 +680,17 @@@ void Slit::configureRequestEvent(XConfi
              client->height != ((unsigned) e->height)) {
            client->width = (unsigned) e->width;
            client->height = (unsigned) e->height;
 +
            reconf = True;
 +
            break;
          }
 -    }
  
 -    if (reconf)
 -      reconfigure();
 +    if (reconf) reconfigure();
 +
    }
-   openbox->ungrab();
 +
+   openbox.ungrab();
  }
  
  
diff --cc src/Slit.h
index 1cb89751d004aa5913e190be9459bc94252f6c1c,b07d9c6ca611b281a94c304ff61fb4d3b9466589..89d76dafa36ab1e62e4898873c5d5e0353975065
@@@ -27,7 -27,8 +27,8 @@@
  #include <X11/Xutil.h>
  
  #include "Basemenu.h"
 -#include <list>
 +#include "LinkedList.h"
+ #include "Geometry.h"
  
  // forward declaration
  class Slit;
@@@ -93,14 -96,17 +96,16 @@@ private
      unsigned int width, height;
    };
  
-   Bool on_top, hidden, do_auto_hide;
+   bool m_ontop, m_autohide, m_hidden;
+   int m_direction, m_placement; 
    Display *display;
  
-   Openbox *openbox;
-   BScreen *screen;
+   Openbox &openbox;
+   BScreen &screen;
+   Resource &config;
    BTimer *timer;
  
 -  typedef std::list<SlitClient *> slitClientList;
 -  slitClientList clientList;
 +  LinkedList<SlitClient> *clientList;
    Slitmenu *slitmenu;
  
    struct frame {
diff --cc src/Toolbar.cc
index d2e39c85a50b0cde76bc7ad31e45ea3fc0c39241,44a0059f5e0dd9de8c796dab533ad7e0ac8bf957..547d733f8f18c5ff898866e03527b46bd3013878
@@@ -189,9 -213,114 +213,114 @@@ Toolbar::~Toolbar() 
  }
  
  
- void Toolbar::reconfigure(void) {
-   frame.bevel_w = screen->getBevelWidth();
-   frame.width = screen->getWidth() * screen->getToolbarWidthPercent() / 100;
+ void Toolbar::setOnTop(bool b) {
+   m_ontop = b;
+   ostrstream s;
+   s << "session.screen" << screen.getScreenNumber() << ".toolbar.onTop" << ends;
+   config.setValue(s.str(), m_ontop ? "True" : "False");
+   s.rdbuf()->freeze(0);
+ }
+ void Toolbar::setAutoHide(bool b) {
+   m_autohide = b;
+   ostrstream s;
 -  s << "session.screen" << screen.getScreenNumber() << ".toolbar.autoHide"
 -    << ends;
++  s << "session.screen" << screen.getScreenNumber() << ".toolbar.autoHide" <<
++    ends;
+   config.setValue(s.str(), m_autohide ? "True" : "False");
+   s.rdbuf()->freeze(0);
+ }
+ void Toolbar::setWidthPercent(int w) {
+   m_width_percent = w;
+   ostrstream s;
+   s << "session.screen" << screen.getScreenNumber() << ".toolbar.widthPercent"
+     << ends;
+   config.setValue(s.str(), m_width_percent);
+   s.rdbuf()->freeze(0);
+ }
+ void Toolbar::setPlacement(int p) {
+   m_placement = p;
+   ostrstream s;
 -  s << "session.screen" << screen.getScreenNumber() << ".toolbar.placement"
 -    << ends;
++  s << "session.screen" << screen.getScreenNumber() << ".toolbar.placement" <<
++    ends;
+   const char *placement;
+   switch (m_placement) {
+   case TopLeft: placement = "TopLeft"; break;
+   case BottomLeft: placement = "BottomLeft"; break;
+   case TopCenter: placement = "TopCenter"; break;
+   case TopRight: placement = "TopRight"; break;
+   case BottomRight: placement = "BottomRight"; break;
+   case BottomCenter: default: placement = "BottomCenter"; break;
+   }
+   config.setValue(s.str(), placement);
+   s.rdbuf()->freeze(0);
+ }
+ void Toolbar::save() {
+   setOnTop(m_ontop);
+   setAutoHide(m_autohide);
+   setWidthPercent(m_width_percent);
+   setPlacement(m_placement);
+ }
+ void Toolbar::load() {
+   ostrstream rscreen, rname, rclass;
+   string s;
+   bool b;
+   long l;
+   rscreen << "session.screen" << screen.getScreenNumber() << '.' << ends;
+   rname << rscreen.str() << "toolbar.widthPercent" << ends;
+   rclass << rscreen.str() << "Toolbar.WidthPercent" << ends;
+   if (config.getValue(rname.str(), rclass.str(), l) && (l > 0 && l <= 100))
+     m_width_percent = l;
+   else
+     m_width_percent =66;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "toolbar.placement" << ends;
+   rclass << rscreen.str() << "Toolbar.Placement" << ends;
+   if (config.getValue(rname.str(), rclass.str(), s)) {
+     if (0 == strncasecmp(s.c_str(), "TopLeft", s.length()))
+       m_placement = TopLeft;
+     else if (0 == strncasecmp(s.c_str(), "BottomLeft", s.length()))
+       m_placement = BottomLeft;
+     else if (0 == strncasecmp(s.c_str(), "TopCenter", s.length()))
+       m_placement = TopCenter;
+     else if (0 == strncasecmp(s.c_str(), "TopRight", s.length()))
+       m_placement = TopRight;
+     else if ( 0 == strncasecmp(s.c_str(), "BottomRight", s.length()))
+       m_placement = BottomRight;
+     else if ( 0 == strncasecmp(s.c_str(), "BottomCenter", s.length()))
+       m_placement = BottomCenter;
+   } else
+     m_placement = BottomCenter;
+   
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "toolbar.onTop" << ends;
+   rclass << rscreen.str() << "Toolbar.OnTop" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     m_ontop = b;
+   else
+     m_ontop = false;
+   rname.seekp(0); rclass.seekp(0);
+   rname << rscreen.str() << "toolbar.autoHide" << ends;
+   rclass << rscreen.str() << "Toolbar.AutoHide" << ends;
+   if (config.getValue(rname.str(), rclass.str(), b))
+     m_hidden = m_autohide = b;
+   else
+     m_hidden = m_autohide = false;
+   rscreen.rdbuf()->freeze(0);
+   rname.rdbuf()->freeze(0);
+   rclass.rdbuf()->freeze(0);
+ }
+ void Toolbar::reconfigure() {
+   frame.bevel_w = screen.getBevelWidth();
+   frame.width = screen.size().w() * m_width_percent / 100;
    
    if (i18n->multibyte())
      frame.height =
    if (ttmp != -1) {
      tt = localtime(&ttmp);
      if (tt) {
-       char t[1024], *time_string = (char *) 0;
-       int len = strftime(t, 1024, screen->getStrftimeFormat(), tt);
+       char t[1025], *time_string = (char *) 0;
+       int len = strftime(t, 1024, screen.strftimeFormat(), tt);
 -      t[len++] = 'A';   // add size to the string for padding
 -      t[len++] = 'A';   // add size to the string for padding
++      t[len++-1] = ' ';   // add a space to the string for padding
+       t[len] = '\0';
  
        if (i18n->multibyte()) {
          XRectangle ink, logical;
@@@ -590,12 -722,12 +721,12 @@@ void Toolbar::checkClock(Bool redraw, B
  
  
  void Toolbar::redrawWindowLabel(Bool redraw) {
-   if (screen->getOpenbox()->getFocusedWindow()) {
 -  if (screen.getOpenbox().focusedWindow()) {
++  if (screen.getOpenbox().getFocusedWindow()) {
      if (redraw)
        XClearWindow(display, frame.window_label);
  
-     OpenboxWindow *foc = screen->getOpenbox()->getFocusedWindow();
-     if (foc->getScreen() != screen) return;
 -    OpenboxWindow *foc = screen.getOpenbox().focusedWindow();
++    OpenboxWindow *foc = screen.getOpenbox().getFocusedWindow();
+     if (foc->getScreen() != &screen) return;
  
      int dx = (frame.bevel_w * 2), dlen = strlen(*foc->getTitle());
      unsigned int l;
@@@ -842,12 -974,12 +973,12 @@@ void Toolbar::edit() 
                   CurrentTime);
    XClearWindow(display, frame.workspace_label);
  
-   openbox->setNoFocus(True);
-   if (openbox->getFocusedWindow())
-     openbox->getFocusedWindow()->setFocusFlag(False);
+   openbox.setNoFocus(True);
 -  if (openbox.focusedWindow())
 -    openbox.focusedWindow()->setFocusFlag(False);
++  if (openbox.getFocusedWindow())
++    openbox.getFocusedWindow()->setFocusFlag(False);
  
    XDrawRectangle(display, frame.workspace_label,
-                  screen->getWindowStyle()->l_text_focus_gc,
+                  screen.getWindowStyle()->l_text_focus_gc,
                   frame.workspace_label_w / 2, 0, 1,
                   frame.label_h - 1);
    
@@@ -1016,12 -1148,12 +1147,12 @@@ void Toolbar::keyPressEvent(XKeyEvent *
      if (ks == XK_Return || new_name_pos == 127) {
        *(new_workspace_name + new_name_pos) = 0;
  
-       editing = False;
+       m_editing = False;
  
-       openbox->setNoFocus(False);
-       if (openbox->getFocusedWindow()) {
-         openbox->getFocusedWindow()->setInputFocus();
-         openbox->getFocusedWindow()->setFocusFlag(True);
+       openbox.setNoFocus(False);
 -      if (openbox.focusedWindow()) {
 -        openbox.focusedWindow()->setInputFocus();
 -        openbox.focusedWindow()->setFocusFlag(True);
++      if (openbox.getFocusedWindow()) {
++        openbox.getFocusedWindow()->setInputFocus();
++        openbox.getFocusedWindow()->setFocusFlag(True);
        } else {
          XSetInputFocus(display, PointerRoot, None, CurrentTime);
        }
diff --cc src/Window.cc
index 4133ac0080b737e22f9879cc7624f2ff4d8993d9,5a28d23254053874f2bb3a565d2de027ed4c4458..d5e3293d349ae05bab66d85b007934e7e0b180c3
  #ifdef    SLIT
  #  include "Slit.h"
  #endif // SLIT
+ #include "Util.h"
  
 -#include <iostream>
 -using namespace std;
 -
  /*
   * Initializes the class with default values/the window's set initial values.
   */
@@@ -217,17 -219,17 +216,17 @@@ OpenboxWindow::OpenboxWindow(Openbox &o
    }
    upsize();
  
 -  place_window = true;
 +  Bool place_window = True;
-   if (openbox->isStartup() || flags.transient ||
+   if (openbox.isStartup() || flags.transient ||
        client.normal_hint_flags & (PPosition|USPosition)) {
      setGravityOffsets();
  
-     if ((openbox->isStartup()) ||
+     if ((openbox.isStartup()) ||
        (frame.x >= 0 &&
         (signed) (frame.y + frame.y_border) >= 0 &&
-        frame.x <= (signed) screen->getWidth() &&
-        frame.y <= (signed) screen->getHeight()))
+        frame.x <= (signed) screen->size().w() &&
+        frame.y <= (signed) screen->size().h()))
 -      place_window = false;
 +      place_window = False;
    }
  
    frame.window = createToplevelWindow(frame.x, frame.y, frame.width,
@@@ -1391,7 -1393,7 +1390,7 @@@ Bool OpenboxWindow::setInputFocus(void
        XSetInputFocus(display, screen->getRootWindow(),
                     RevertToNone, CurrentTime);
  
-     openbox->setFocusedWindow(this);
 -    openbox.focusWindow(this);
++    openbox.setFocusedWindow(this);
  
      if (flags.send_focus_message) {
        XEvent ce;
@@@ -1466,7 -1471,19 +1465,7 @@@ void OpenboxWindow::deiconify(Bool reas
    XMapSubwindows(display, frame.window);
    XMapWindow(display, frame.window);
  
-   if (flags.iconic && screen->doFocusNew()) setInputFocus();
 -  // if we're using the click to place placement type, then immediately
 -  // after the window is mapped, we need to start interactively moving it
 -  if (initial && place_window &&
 -      screen->placementPolicy() == BScreen::ClickMousePlacement) {
 -    int x, y, rx, ry;
 -    Window c, r;
 -    unsigned int m;
 -    XQueryPointer(openbox.getXDisplay(), screen->getRootWindow(),
 -                  &r, &c, &rx, &ry, &x, &y, &m);
 -    startMove(rx, ry);
 -  }
 -  
+   if (flags.iconic && screen->focusNew()) setInputFocus();
  
    flags.visible = True;
    flags.iconic = False;
@@@ -1534,15 -1557,14 +1533,113 @@@ void OpenboxWindow::maximize(unsigned i
      return;
    }
  
-   int dx = 0, dy = 0;
-   unsigned int dw, dh;
++  // the following code is temporary and will be taken care of by Screen in the
++  // future (with the NETWM 'strut')
++  Rect space(0, 0, screen->size().w(), screen->size().h());
++  if (! screen->fullMax()) {
++#ifdef    SLIT
++    Slit *slit = screen->getSlit();
++    int slit_x = slit->autoHide() ? slit->hiddenOrigin().x() : slit->area().x(),
++        slit_y = slit->autoHide() ? slit->hiddenOrigin().y() : slit->area().y();
++    Toolbar *toolbar = screen->getToolbar();
++    int tbarh = screen->hideToolbar() ? 0 :
++      toolbar->getExposedHeight() + screen->getBorderWidth() * 2;
++    bool tbartop;
++    switch (toolbar->placement()) {
++    case Toolbar::TopLeft:
++    case Toolbar::TopCenter:
++    case Toolbar::TopRight:
++      tbartop = true;
++      break;
++    case Toolbar::BottomLeft:
++    case Toolbar::BottomCenter:
++    case Toolbar::BottomRight:
++      tbartop = false;
++      break;
++    default:
++      ASSERT(false);      // unhandled placement
++    }
++    if ((slit->direction() == Slit::Horizontal &&
++         (slit->placement() == Slit::TopLeft ||
++          slit->placement() == Slit::TopRight)) ||
++        slit->placement() == Slit::TopCenter) {
++      // exclude top
++      if (tbartop && slit_y + slit->area().h() < tbarh) {
++        space.setY(space.y() + tbarh);
++        space.setH(space.h() - tbarh);
++      } else {
++        space.setY(space.y() + (slit_y + slit->area().h() +
++                                screen->getBorderWidth() * 2));
++        space.setH(space.h() - (slit_y + slit->area().h() +
++                                screen->getBorderWidth() * 2));
++        if (!tbartop)
++          space.setH(space.h() - tbarh);
++      }
++    } else if ((slit->direction() == Slit::Vertical &&
++              (slit->placement() == Slit::TopRight ||
++               slit->placement() == Slit::BottomRight)) ||
++             slit->placement() == Slit::CenterRight) {
++      // exclude right
++      space.setW(space.w() - (screen->size().w() - slit_x));
++      if (tbartop)
++        space.setY(space.y() + tbarh);
++      space.setH(space.h() - tbarh);
++    } else if ((slit->direction() == Slit::Horizontal &&
++              (slit->placement() == Slit::BottomLeft ||
++               slit->placement() == Slit::BottomRight)) ||
++             slit->placement() == Slit::BottomCenter) {
++      // exclude bottom
++      if (!tbartop && (screen->size().h() - slit_y) < tbarh) {
++        space.setH(space.h() - tbarh);
++      } else {
++        space.setH(space.h() - (screen->size().h() - slit_y));
++        if (tbartop) {
++          space.setY(space.y() + tbarh);
++          space.setH(space.h() - tbarh);
++        }
++      }
++    } else {// if ((slit->direction() == Slit::Vertical &&
++      //      (slit->placement() == Slit::TopLeft ||
++      //       slit->placement() == Slit::BottomLeft)) ||
++      //     slit->placement() == Slit::CenterLeft)
++      // exclude left
++      space.setX(slit_x + slit->area().w() +
++                 screen->getBorderWidth() * 2);
++      space.setW(space.w() - (slit_x + slit->area().w() +
++                              screen->getBorderWidth() * 2));
++      if (tbartop)
++        space.setY(space.y() + tbarh);
++      space.setH(space.h() - tbarh);
++    }
++#else // !SLIT
++    Toolbar *toolbar = screen->getToolbar();
++    int tbarh = screen->hideToolbar() ? 0 :
++      toolbar->getExposedHeight() + screen->getBorderWidth() * 2;
++    switch (toolbar->placement()) {
++    case Toolbar::TopLeft:
++    case Toolbar::TopCenter:
++    case Toolbar::TopRight:
++      space.setY(toolbar->getExposedHeight());
++      space.setH(space.h() - toolbar->getExposedHeight());
++      break;
++    case Toolbar::BottomLeft:
++    case Toolbar::BottomCenter:
++    case Toolbar::BottomRight:
++      space.setH(space.h() - tbarh);
++      break;
++    default:
++      ASSERT(false);      // unhandled placement
++    }
++#endif // SLIT
++  }
 +
    openbox_attrib.premax_x = frame.x;
    openbox_attrib.premax_y = frame.y;
    openbox_attrib.premax_w = frame.width;
    openbox_attrib.premax_h = frame.height;
  
-   dw = screen->getWidth();
 -  Rect space = screen->availableArea();
+   unsigned int dw = space.w(),
+                dh = space.h();
    dw -= frame.border_w * 2;
    dw -= frame.mwm_border_w * 2;
    dw -= client.base_width;
@@@ -1741,8 -1744,9 +1819,8 @@@ void OpenboxWindow::setFocusFlag(Bool f
        XSetWindowBorder(display, frame.plate, frame.uborder_pixel);
    }
  
-   if (screen->isSloppyFocus() && screen->doAutoRaise() && timer->isTiming())
+   if (screen->sloppyFocus() && screen->autoRaise() && timer->isTiming())
      timer->stop();
 -
  }
  
  
@@@ -2280,9 -2286,12 +2358,9 @@@ void OpenboxWindow::unmapNotifyEvent(XU
              client.window);
  #endif // DEBUG
  
-     openbox->grab();
+     openbox.grab();
      if (! validateClient()) return;
  
 -    if (flags.moving)
 -      endMove();
 -    
      XChangeSaveSet(display, client.window, SetModeDelete);
      XSelectInput(display, client.window, NoEventMask);
  
@@@ -2719,21 -2729,7 +2798,21 @@@ void OpenboxWindow::buttonReleaseEvent(
    // when the window is being interactively moved, a button release stops the
    // move where it is
    if (flags.moving) {
 -    endMove();
 +    flags.moving = False;
 +
-     openbox->maskWindowEvents(0, (OpenboxWindow *) 0);
-     if (!screen->doOpaqueMove()) {
++    openbox.maskWindowEvents(0, (OpenboxWindow *) 0);
++    if (!screen->opaqueMove()) {
 +      XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 +                     frame.move_x, frame.move_y, frame.resize_w - 1,
 +                     frame.resize_h - 1);
 +
 +      configure(frame.move_x, frame.move_y, frame.width, frame.height);
-       openbox->ungrab();
++      openbox.ungrab();
 +    } else {
 +      configure(frame.x, frame.y, frame.width, frame.height);
 +    }
 +    screen->hideGeometry();
 +    XUngrabPointer(display, CurrentTime);
    // when the window is being interactively resized, a button release stops the
    // resizing
    } else if (flags.resizing) {
  }
  
  
 -void OpenboxWindow::startMove(int x, int y) {
 -  ASSERT(!flags.moving);
 -
 -  // make sure only one window is moving at a time
 -  OpenboxWindow *w = openbox.getMaskedWindow();
 -  if (w != (OpenboxWindow *) 0 && w->flags.moving)
 -    w->endMove();
 -  
 -  XGrabPointer(display, frame.window, False, PointerMotionMask |
 -               ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
 -               None, openbox.getMoveCursor(), CurrentTime);
 -
 -  if (windowmenu && windowmenu->isVisible())
 -    windowmenu->hide();
 -
 -  flags.moving = True;
 +void OpenboxWindow::motionNotifyEvent(XMotionEvent *me) {
 +  if (!flags.resizing && (me->state & Button1Mask) && functions.move &&
 +      (frame.title == me->window || frame.label == me->window ||
 +       frame.handle == me->window || frame.window == me->window)) {
 +    if (! flags.moving) {
 +      XGrabPointer(display, me->window, False, Button1MotionMask |
 +                   ButtonReleaseMask, GrabModeAsync, GrabModeAsync,
-                    None, openbox->getMoveCursor(), CurrentTime);
++                   None, openbox.getMoveCursor(), CurrentTime);
  
 -  openbox.maskWindowEvents(client.window, this);
 +      if (windowmenu && windowmenu->isVisible())
 +        windowmenu->hide();
  
 -  if (! screen->opaqueMove()) {
 -    openbox.grab();
 +      flags.moving = True;
  
-       openbox->maskWindowEvents(client.window, this);
 -    frame.move_x = frame.x;
 -    frame.move_y = frame.y;
 -    frame.resize_w = frame.width + (frame.border_w * 2);
 -    frame.resize_h = ((flags.shaded) ? frame.title_h : frame.height) +
 -      (frame.border_w * 2);
++      openbox.maskWindowEvents(client.window, this);
  
-       if (! screen->doOpaqueMove()) {
-         openbox->grab();
 -    screen->showPosition(frame.x, frame.y);
++      if (! screen->opaqueMove()) {
++        openbox.grab();
  
 -    XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 -                   frame.move_x, frame.move_y,
 -                   frame.resize_w - 1, frame.resize_h - 1);
 -  }
 -  frame.grab_x = x - frame.x - frame.border_w;
 -  frame.grab_y = y - frame.y - frame.border_w;
 -  cout << "START MOVE " << client.window << " " << client.title << endl;
 -}
 +        frame.move_x = frame.x;
 +      frame.move_y = frame.y;
 +        frame.resize_w = frame.width + (frame.border_w * 2);
 +        frame.resize_h = ((flags.shaded) ? frame.title_h : frame.height) +
 +          (frame.border_w * 2);
  
 +      screen->showPosition(frame.x, frame.y);
  
 -void OpenboxWindow::doMove(int x, int y) {
 -  ASSERT(flags.moving);
 +      XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 +                     frame.move_x, frame.move_y,
 +                     frame.resize_w - 1, frame.resize_h - 1);
 +      }
 +    } else {
 +      int dx = me->x_root - frame.grab_x, dy = me->y_root - frame.grab_y;
 +
 +      dx -= frame.border_w;
 +      dy -= frame.border_w;
 +
-       int snap_distance = screen->getEdgeSnapThreshold();
++      int snap_distance = screen->edgeSnapThreshold();
++      // width/height of the snapping window
++      unsigned int snap_w = frame.width + (frame.border_w * 2);
++      unsigned int snap_h = area().h() + (frame.border_w * 2);
 +      if (snap_distance) {
-         int drx = screen->getWidth() - (dx + frame.snap_w);
++        int drx = screen->size().w() - (dx + snap_w);
 +
 +        if (dx < drx && (dx > 0 && dx < snap_distance) ||
 +                        (dx < 0 && dx > -snap_distance) )
 +          dx = 0;
 +        else if ( (drx > 0 && drx < snap_distance) ||
 +                  (drx < 0 && drx > -snap_distance) )
-           dx = screen->getWidth() - frame.snap_w;
++          dx = screen->size().w() - snap_w;
 +
 +        int dtty, dbby, dty, dby;
-         switch (screen->getToolbarPlacement()) {
++        switch (screen->getToolbar()->placement()) {
 +        case Toolbar::TopLeft:
 +        case Toolbar::TopCenter:
 +        case Toolbar::TopRight:
 +          dtty = screen->getToolbar()->getExposedHeight() +
 +               frame.border_w;
-           dbby = screen->getHeight();
++          dbby = screen->size().h();
 +          break;
 +
 +        default:
 +          dtty = 0;
-         dbby = screen->getToolbar()->getY();
++        dbby = screen->getToolbar()->area().y();
 +          break;
 +        }
  
 -  int dx = x - frame.grab_x, dy = y - frame.grab_y;
 +        dty = dy - dtty;
-         dby = dbby - (dy + frame.snap_h);
++        dby = dbby - (dy + snap_h);
  
 -  dx -= frame.border_w;
 -  dy -= frame.border_w;
 +        if ( (dy > 0 && dty < snap_distance) ||
 +            (dy < 0 && dty > -snap_distance) )
 +          dy = dtty;
 +        else if ( (dby > 0 && dby < snap_distance) ||
 +                 (dby < 0 && dby > -snap_distance) )
-           dy = dbby - frame.snap_h;
++          dy = dbby - snap_h;
 +      }
  
-       if (screen->doOpaqueMove()) {
 -  int snap_distance = screen->edgeSnapThreshold();
 -  // width/height of the snapping window
 -  unsigned int snap_w = frame.width + (frame.border_w * 2);
 -  unsigned int snap_h = area().h() + (frame.border_w * 2);
 -  if (snap_distance) {
 -    int drx = screen->size().w() - (dx + snap_w);
++      if (screen->opaqueMove()) {
 +      configure(dx, dy, frame.width, frame.height);
 +      } else {
 +      XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 +                     frame.move_x, frame.move_y, frame.resize_w - 1,
 +                     frame.resize_h - 1);
  
 -    if (dx < drx && (dx > 0 && dx < snap_distance) ||
 -        (dx < 0 && dx > -snap_distance) )
 -      dx = 0;
 -    else if ( (drx > 0 && drx < snap_distance) ||
 -             (drx < 0 && drx > -snap_distance) )
 -      dx = screen->size().w() - snap_w;
 +      frame.move_x = dx;
 +      frame.move_y = dy;
  
 -    int dtty, dbby, dty, dby;
 -    switch (screen->getToolbar()->placement()) {
 -    case Toolbar::TopLeft:
 -    case Toolbar::TopCenter:
 -    case Toolbar::TopRight:
 -      dtty = screen->getToolbar()->getExposedHeight() +
 -        frame.border_w;
 -      dbby = screen->size().h();
 -      break;
 +      XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 +                     frame.move_x, frame.move_y, frame.resize_w - 1,
 +                     frame.resize_h - 1);
 +      }
  
 -    default:
 -      dtty = 0;
 -      dbby = screen->getToolbar()->area().y();
 -      break;
 +      screen->showPosition(dx, dy);
      }
 -
 -    dty = dy - dtty;
 -    dby = dbby - (dy + snap_h);
 -
 -    if ( (dy > 0 && dty < snap_distance) ||
 -        (dy < 0 && dty > -snap_distance) )
 -      dy = dtty;
 -    else if ( (dby > 0 && dby < snap_distance) ||
 -             (dby < 0 && dby > -snap_distance) )
 -      dy = dbby - snap_h;
 -  }
 -
 -  if (screen->opaqueMove()) {
 -    configure(dx, dy, frame.width, frame.height);
 -  } else {
 -    XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 -                   frame.move_x, frame.move_y, frame.resize_w - 1,
 -                   frame.resize_h - 1);
 -
 -    frame.move_x = dx;
 -    frame.move_y = dy;
 -
 -    XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 -                   frame.move_x, frame.move_y, frame.resize_w - 1,
 -                   frame.resize_h - 1);
 -  }
 -
 -  screen->showPosition(dx, dy);
 -}
 -
 -
 -void OpenboxWindow::endMove() {
 -  ASSERT(flags.moving);
 -
 -  flags.moving = False;
 -
 -  openbox.maskWindowEvents(0, (OpenboxWindow *) 0);
 -  if (!screen->opaqueMove()) {
 -    XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
 -                   frame.move_x, frame.move_y, frame.resize_w - 1,
 -                   frame.resize_h - 1);
 -
 -    configure(frame.move_x, frame.move_y, frame.width, frame.height);
 -    openbox.ungrab();
 -  } else {
 -    configure(frame.x, frame.y, frame.width, frame.height);
 -  }
 -  screen->hideGeometry();
 -  XUngrabPointer(display, CurrentTime);
 -  // if there are any left over motions from the move, drop them now cuz they
 -  // cause problems
 -  XEvent e;
 -  while (XCheckTypedWindowEvent(display, frame.window, MotionNotify, &e));
 -  cout << "END MOVE " << client.window << " " << client.title << endl;
 -}
 -
 -
 -void OpenboxWindow::motionNotifyEvent(XMotionEvent *me) {
 -  if (flags.moving)
 -      doMove(me->x_root, me->y_root);
 -  else if (!flags.resizing && (me->state & Button1Mask) && functions.move &&
 -      (frame.title == me->window || frame.label == me->window ||
 -       frame.handle == me->window || frame.window == me->window))
 -    startMove(me->x_root, me->y_root);
 -  else if (functions.resize &&
 +  } else if (functions.resize &&
             (((me->state & Button1Mask) && (me->window == frame.right_grip ||
                                             me->window == frame.left_grip)) ||
 -            (me->state == (Mod1Mask | Button3Mask) &&
 +            (me->state & (Mod1Mask | Button3Mask) &&
                                             me->window == frame.window))) {
      Bool left = resize_zone & ZoneLeft;
  
diff --cc src/Window.h
index d6e9f809ea09792ba01a0503d76ccb6a9a33bbe2,fb988e234a1224b53320b8ee15f65aebe8c75e27..b916ca67a409cf8246196da58b49359126438cad
@@@ -238,71 -240,97 +239,96 @@@ protected
  
  
  public:
-   OpenboxWindow(Openbox *b, Window w, BScreen *s = (BScreen *) 0);
+   OpenboxWindow(Openbox &b, Window w, BScreen *s = (BScreen *) 0);
 -  virtual ~OpenboxWindow();
 -
 -  inline Bool isTransient() const { return flags.transient; }
 -  inline Bool isFocused() const { return flags.focused; }
 -  inline Bool isVisible() const { return flags.visible; }
 -  inline Bool isIconic() const { return flags.iconic; }
 -  inline Bool isShaded() const { return flags.shaded; }
 -  inline Bool isMaximized() const { return flags.maximized; }
 -  inline Bool isMaximizedFull() const { return flags.maximized == 1; }
 -  inline Bool isStuck() const { return flags.stuck; }
 -  inline Bool isIconifiable() const { return functions.iconify; }
 -  inline Bool isMaximizable() const { return functions.maximize; }
 -  inline Bool isResizable() const { return functions.resize; }
 -  inline Bool isClosable() const { return functions.close; }
 -
 -  inline Bool hasTitlebar() const { return decorations.titlebar; }
 -  inline Bool hasTransient() const
 +  virtual ~OpenboxWindow(void);
 +
 +  inline Bool isTransient(void) const { return flags.transient; }
 +  inline Bool isFocused(void) const { return flags.focused; }
 +  inline Bool isVisible(void) const { return flags.visible; }
 +  inline Bool isIconic(void) const { return flags.iconic; }
 +  inline Bool isShaded(void) const { return flags.shaded; }
 +  inline Bool isMaximized(void) const { return flags.maximized; }
 +  inline Bool isMaximizedFull(void) const { return flags.maximized == 1; }
 +  inline Bool isStuck(void) const { return flags.stuck; }
 +  inline Bool isIconifiable(void) const { return functions.iconify; }
 +  inline Bool isMaximizable(void) const { return functions.maximize; }
 +  inline Bool isResizable(void) const { return functions.resize; }
 +  inline Bool isClosable(void) const { return functions.close; }
 +
 +  inline Bool hasTitlebar(void) const { return decorations.titlebar; }
 +  inline Bool hasTransient(void) const
    { return ((client.transient) ? True : False); }
  
 -  inline OpenboxWindow *getTransient() { return client.transient; }
 -  inline OpenboxWindow *getTransientFor() { return client.transient_for; }
 +  inline OpenboxWindow *getTransient(void) { return client.transient; }
 +  inline OpenboxWindow *getTransientFor(void) { return client.transient_for; }
  
 -  inline BScreen *getScreen() { return screen; }
 +  inline BScreen *getScreen(void) { return screen; }
  
 -  inline const Window &getFrameWindow() const { return frame.window; }
 -  inline const Window &getClientWindow() const { return client.window; }
 +  inline const Window &getFrameWindow(void) const { return frame.window; }
 +  inline const Window &getClientWindow(void) const { return client.window; }
  
 -  inline Windowmenu * getWindowmenu() { return windowmenu; }
 +  inline Windowmenu * getWindowmenu(void) { return windowmenu; }
  
 -  inline char **getTitle() { return &client.title; }
 -  inline char **getIconTitle() { return &client.icon_title; }
 -  //inline const int &getXFrame() const { return frame.x; }
 -  //inline const int &getYFrame() const { return frame.y; }
 -  //inline const int &getXClient() const { return client.x; }
 -  //inline const int &getYClient() const { return client.y; }
 -  inline const int &getWorkspaceNumber() const { return workspace_number; }
 -  inline const int &getWindowNumber() const { return window_number; }
 +  inline char **getTitle(void) { return &client.title; }
 +  inline char **getIconTitle(void) { return &client.icon_title; }
-   inline const int &getXFrame(void) const { return frame.x; }
-   inline const int &getYFrame(void) const { return frame.y; }
-   inline const int &getXClient(void) const { return client.x; }
-   inline const int &getYClient(void) const { return client.y; }
++  //inline const int &getXFrame(void) const { return frame.x; }
++  //inline const int &getYFrame(void) const { return frame.y; }
++  //inline const int &getXClient(void) const { return client.x; }
++  //inline const int &getYClient(void) const { return client.y; }
 +  inline const int &getWorkspaceNumber(void) const { return workspace_number; }
 +  inline const int &getWindowNumber(void) const { return window_number; }
  
-   inline const unsigned int &getWidth(void) const { return frame.width; }
-   inline const unsigned int &getHeight(void) const { return frame.height; }
-   inline const unsigned int &getClientHeight(void) const
-   { return client.height; }
-   inline const unsigned int &getClientWidth(void) const
-   { return client.width; }
 -  //inline const unsigned int &getWidth() const { return frame.width; }
 -  //inline const unsigned int &getHeight() const {
++  //inline const unsigned int &getWidth(void) const { return frame.width; }
++  //inline const unsigned int &getHeight(void) const {
+   //  if (!flags.shaded)
+   //    return frame.height;
+   //  else
+   //    return frame.title_h;
+   //}
 -  //inline const unsigned int &getClientHeight() const
++  //inline const unsigned int &getClientHeight(void) const
+   //{ return client.height; }
 -  //inline const unsigned int &getClientWidth() const
++  //inline const unsigned int &getClientWidth(void) const
+   //{ return client.width; }
 -  inline const unsigned int &getTitleHeight() const
 +  inline const unsigned int &getTitleHeight(void) const
    { return frame.title_h; }
  
+   //inline const Point origin() const {
+   //  return Point(frame.x, frame.y);
+   //}
+   //inline const Point clientOrigin() const {
+   //  return Point(client.x, client.y);
+   //}
+   //inline const Size size() const {
+   //  return Size(frame.width, flags.shaded ? frame.title_h : frame.height);
+   //}
+   //inline const Size clientSize() const {
+   //  return Size(client.width, client.height);
+   //}
+   inline const Rect area() const {
+     return Rect(frame.x, frame.y, frame.width,
+                 flags.shaded ? frame.title_h : frame.height);
+   }
+   inline const Rect clientArea() const {
+     return Rect(client.x, client.y, client.width, client.height);
+   }
+   
    inline void setWindowNumber(int n) { window_number = n; }
    
 -  Bool validateClient();
 -  Bool setInputFocus();
 +  Bool validateClient(void);
 +  Bool setInputFocus(void);
  
    void setFocusFlag(Bool);
 -  void iconify();
 -  void deiconify(bool reassoc = true, bool raise = true, bool initial = false);
 -  void close();
 -  void withdraw();
 +  void iconify(void);
 +  void deiconify(Bool reassoc = True, Bool raise = True);
 +  void close(void);
 +  void withdraw(void);
    void maximize(unsigned int button);
 -  void shade();
 -  void stick();
 -  void unstick();
 -  void reconfigure();
 +  void shade(void);
 +  void stick(void);
 +  void unstick(void);
 +  void reconfigure(void);
    void installColormap(Bool);
 -  void restore();
 +  void restore(void);
    void configure(int dx, int dy, unsigned int dw, unsigned int dh);
    void setWorkspace(int n);
    void changeOpenboxHints(OpenboxHints *);
index fa1f7990f06770ea7765121321d501e15c8cab1a,d87373481e061776dd101e82c04b49c8bcccdc6a..d52f73de7ef730f9dc4288299c0e987c5d5ddd2f
  #  include <stdio.h>
  #endif // HAVE_STDIO_H
  
- #ifdef    STDC_HEADERS
+ #ifdef    HAVE_STDLIB_H
+ #  include <stdlib.h>
+ #endif // HAVE_STDLIB_H
+ #ifdef    HAVE_STRING_H
  #  include <string.h>
- #endif // STDC_HEADERS
+ #endif // HAVE_STRING_H
  
+ #include <algorithm>
+ #include <vector>
+ typedef std::vector<Rect> rectList;
  
- Workspace::Workspace(BScreen *scrn, int i) {
-   screen = scrn;
+ Workspace::Workspace(BScreen &scrn, int i) : screen(scrn) {
 -  cascade_x = cascade_y = 0;
 -  _focused = (OpenboxWindow *) 0;
 +
 +  cascade_x = cascade_y = 32;
 +
    id = i;
  
    stackingList = new LinkedList<OpenboxWindow>;
@@@ -111,14 -120,14 +121,14 @@@ const int Workspace::removeWindow(Openb
      if (w->isTransient() && w->getTransientFor() &&
        w->getTransientFor()->isVisible()) {
        w->getTransientFor()->setInputFocus();
-     } else if (screen->isSloppyFocus()) {
-       screen->getOpenbox()->setFocusedWindow((OpenboxWindow *) 0);
+     } else if (screen.sloppyFocus()) {
 -      screen.getOpenbox().focusWindow((OpenboxWindow *) 0);
++      screen.getOpenbox().setFocusedWindow((OpenboxWindow *) 0);
      } else {
        OpenboxWindow *top = stackingList->first();
        if (! top || ! top->setInputFocus()) {
-       screen->getOpenbox()->setFocusedWindow((OpenboxWindow *) 0);
-       XSetInputFocus(screen->getOpenbox()->getXDisplay(),
-                      screen->getToolbar()->getWindowID(),
 -      screen.getOpenbox().focusWindow((OpenboxWindow *) 0);
++      screen.getOpenbox().setFocusedWindow((OpenboxWindow *) 0);
+       XSetInputFocus(screen.getOpenbox().getXDisplay(),
+                      screen.getToolbar()->getWindowID(),
                       RevertToParent, CurrentTime);
        }
      }
@@@ -322,181 -341,290 +333,379 @@@ void Workspace::shutdown(void) 
    }
  }
  
- void Workspace::placeWindow(OpenboxWindow *win) {
-   Bool placed = False;
+ static rectList calcSpace(const Rect &win, const rectList &spaces) {
+   rectList result;
+   rectList::const_iterator siter;
+   for(siter=spaces.begin(); siter!=spaces.end(); ++siter) {
+     if(win.Intersect(*siter)) {
+       //Check for space to the left of the window
+       if(win.x() > siter->x())
+         result.push_back(Rect(siter->x(), siter->y(),
+                               win.x() - siter->x() - 1,
+                               siter->h()));
+       //Check for space above the window
+       if(win.y() > siter->y())
+         result.push_back(Rect(siter->x(), siter->y(),
+                               siter->w(),
+                               win.y() - siter->y() - 1));
+       //Check for space to the right of the window
+       if((win.x()+win.w()) <
+          (siter->x()+siter->w()))
+         result.push_back(Rect(win.x() + win.w() + 1,
+                               siter->y(),
+                               siter->x() + siter->w() -
+                               win.x() - win.w() - 1,
+                               siter->h()));
+       //Check for space below the window
+       if((win.y()+win.h()) <
+          (siter->y()+siter->h()))
+         result.push_back(Rect(siter->x(),
+                               win.y() + win.h() + 1,
+                               siter->w(),
+                               siter->y() + siter->h()-
+                               win.y() - win.h() - 1));
  
-   const int win_w = win->getWidth() + (screen->getBorderWidth() * 4),
-     win_h = win->getHeight() + (screen->getBorderWidth() * 4),
- #ifdef    SLIT
-     slit_x = screen->getSlit()->getX() - screen->getBorderWidth(),
-     slit_y = screen->getSlit()->getY() - screen->getBorderWidth(),
-     slit_w = screen->getSlit()->getWidth() +
-       (screen->getBorderWidth() * 4),
-     slit_h = screen->getSlit()->getHeight() +
-       (screen->getBorderWidth() * 4),
- #endif // SLIT
-     toolbar_x = screen->getToolbar()->getX() - screen->getBorderWidth(),
-     toolbar_y = screen->getToolbar()->getY() - screen->getBorderWidth(),
-     toolbar_w = screen->getToolbar()->getWidth() +
-       (screen->getBorderWidth() * 4),
-     toolbar_h = screen->getToolbar()->getHeight() + 
-       (screen->getBorderWidth() * 4),
-     start_pos = 0,
-     change_y =
-       ((screen->getColPlacementDirection() == BScreen::TopBottom) ? 1 : -1),
-     change_x =
-       ((screen->getRowPlacementDirection() == BScreen::LeftRight) ? 1 : -1),
-     delta_x = 8, delta_y = 8;
+     }
+     else
+       result.push_back(*siter);
+   }
+   return result;
+ }
 -bool rowRLBT(const Rect &first, const Rect &second){
 -  if (first.y()+first.h()==second.y()+second.h())
 -     return first.x()+first.w()>second.x()+second.w();
 -  return first.y()+first.h()>second.y()+second.h();
 -}
 - 
 -bool rowRLTB(const Rect &first, const Rect &second){
 -  if (first.y()==second.y())
 -     return first.x()+first.w()>second.x()+second.w();
 -  return first.y()<second.y();
 -}
 -bool rowLRBT(const Rect &first, const Rect &second){
 -  if (first.y()+first.h()==second.y()+second.h())
 -     return first.x()<second.x();
 -  return first.y()+first.h()>second.y()+second.h();
 -}
 - 
 -bool rowLRTB(const Rect &first, const Rect &second){
 -  if (first.y()==second.y())
 -     return first.x()<second.x();
 -  return first.y()<second.y();
++bool incWidth(const Rect &first, const Rect &second) {
++  return first.x() < second.x();
+ }
 - 
 -bool colLRTB(const Rect &first, const Rect &second){
 -  if (first.x()==second.x())
 -     return first.y()<second.y();
 -  return first.x()<second.x();
 -}
 - 
 -bool colLRBT(const Rect &first, const Rect &second){
 -  if (first.x()==second.x())
 -     return first.y()+first.h()>second.y()+second.h();
 -  return first.x()<second.x();
 +
++
++bool decWidth(const Rect &first, const Rect &second) {
++  if (second.x() == first.x())
++     return second.w() < first.w();
++  return second.x() < first.x();
+ }
 -bool colRLTB(const Rect &first, const Rect &second){
 -  if (first.x()+first.w()==second.x()+second.w())
 -     return first.y()<second.y();
 -  return first.x()+first.w()>second.x()+second.w();
++
++bool incHeight(const Rect &first, const Rect &second) {
++  return first.y() < second.y();
+ }
 - 
 -bool colRLBT(const Rect &first, const Rect &second){
 -  if (first.x()+first.w()==second.x()+second.w())
 -     return first.y()+first.h()>second.y()+second.h();
 -  return first.x()+first.w()>second.x()+second.w();
++
++
++bool decHeight(const Rect &first, const Rect &second) {
++  if (second.y() == first.y())
++     return second.h() < first.h();
++  return second.y() < first.y();
+ }
+ //BestFitPlacement finds the smallest free space that fits the window
+ //to be placed. It currentl ignores whether placement is right to left or top
+ //to bottom.
+ Point *Workspace::bestFitPlacement(const Size &win_size, const Rect &space) {
+   const Rect *best;
+   rectList spaces;
+   LinkedListIterator<OpenboxWindow> it(windowList);
+   rectList::const_iterator siter;
+   spaces.push_back(space); //initially the entire screen is free
+   it.reset();
+   
+   //Find Free Spaces
+   for (OpenboxWindow *cur=it.current(); cur!=NULL; it++, cur=it.current())
+      spaces = calcSpace(cur->area().Inflate(screen.getBorderWidth() * 4),
+                         spaces);
+   
++  //Sort the spaces by placement choice
++  if (screen.rowPlacementDirection() == BScreen::TopBottom)
++     sort(spaces.begin(), spaces.end(), decHeight);
++  else
++     sort(spaces.begin(), spaces.end(), incHeight);
++  if (screen.colPlacementDirection() == BScreen::TopBottom)
++     stable_sort(spaces.begin(), spaces.end(), incHeight);
++  else
++     stable_sort(spaces.begin(), spaces.end(), decHeight);
++
+   //Find first space that fits the window
+   best = NULL;
+   for (siter=spaces.begin(); siter!=spaces.end(); ++siter) {
+     if ((siter->w() >= win_size.w()) && (siter->h() >= win_size.h())) {
+       if (best==NULL)
+         best = &*siter;
+       else if(siter->w()*siter->h()<best->h()*best->w())
+         best = &*siter;
+     }
+   }
+   if (best != NULL) {
+     Point *pt = new Point(best->origin());
+     if (screen.colPlacementDirection() != BScreen::TopBottom)
+       pt->setY(pt->y() + (best->h() - win_size.h()));
+     if (screen.rowPlacementDirection() != BScreen::LeftRight)
+       pt->setX(pt->x() + (best->w() - win_size.w()));
+     return pt;
+   } else
+     return NULL; //fall back to cascade
+ }
 -Point *Workspace::underMousePlacement(const Size &win_size, const Rect &space) {
 -  Point *pt;
 -
 -  int x, y, rx, ry;
 -  Window c, r;
 -  unsigned int m;
 -  XQueryPointer(screen.getOpenbox().getXDisplay(), screen.getRootWindow(),
 -                &r, &c, &rx, &ry, &x, &y, &m);
 -  pt = new Point(rx - win_size.w() / 2, ry - win_size.h() / 2);
 -
 -  if (pt->x() < space.x())
 -    pt->setX(space.x());
 -  if (pt->y() < space.y())
 -    pt->setY(space.y());
 -  if (pt->x() + win_size.w() > space.x() + space.w())
 -    pt->setX(space.x() + space.w() - win_size.w());
 -  if (pt->y() + win_size.h() > space.y() + space.h())
 -    pt->setY(space.y() + space.h() - win_size.h());
 -  return pt;
 -}
+ Point *Workspace::rowSmartPlacement(const Size &win_size, const Rect &space) {
 -  const Rect *best;
 -  rectList spaces;
++  bool placed=false;
 +  int test_x, test_y, place_x = 0, place_y = 0;
++  int start_pos = 0;
++  int change_y =
++     ((screen.colPlacementDirection() == BScreen::TopBottom) ? 1 : -1);
++  int change_x =
++     ((screen.rowPlacementDirection() == BScreen::LeftRight) ? 1 : -1);
++  int delta_x = 8, delta_y = 8;
    LinkedListIterator<OpenboxWindow> it(windowList);
  
-   switch (screen->getPlacementPolicy()) {
-   case BScreen::RowSmartPlacement: {
-     test_y = (screen->getColPlacementDirection() == BScreen::TopBottom) ?
-       start_pos : screen->getHeight() - win_h - start_pos;
 -  rectList::const_iterator siter;
 -  spaces.push_back(space); //initially the entire screen is free
 -  it.reset();
 -  
 -  //Find Free Spaces
 -  for (OpenboxWindow *cur=it.current(); cur!=NULL; it++, cur=it.current())
 -     spaces = calcSpace(cur->area().Inflate(screen.getBorderWidth() * 4),
 -                        spaces);
 -  //Sort spaces by preference
 -  if(screen.rowPlacementDirection() == BScreen::RightLeft)
 -     if(screen.colPlacementDirection() == BScreen::TopBottom)
 -        sort(spaces.begin(),spaces.end(),rowRLTB);
 -     else
 -        sort(spaces.begin(),spaces.end(),rowRLBT);
 -  else
 -     if(screen.colPlacementDirection() == BScreen::TopBottom)
 -        sort(spaces.begin(),spaces.end(),rowLRTB);
 -     else
 -        sort(spaces.begin(),spaces.end(),rowLRBT);
 -  best = NULL;
 -  for (siter=spaces.begin(); siter!=spaces.end(); ++siter)
 -    if ((siter->w() >= win_size.w()) && (siter->h() >= win_size.h())) {
 -      best = &*siter;
 -      break;
++  test_y = (screen.colPlacementDirection() == BScreen::TopBottom) ?
++    start_pos : screen.size().h() - win_size.h() - start_pos;
 +
++  while(!placed &&
++        ((screen.colPlacementDirection() == BScreen::BottomTop) ?
++         test_y > 0 : test_y + win_size.h() < (signed) space.h())) {
++    test_x = (screen.rowPlacementDirection() == BScreen::LeftRight) ?
++      start_pos : space.w() - win_size.w() - start_pos;
 +    while (!placed &&
-          ((screen->getColPlacementDirection() == BScreen::BottomTop) ?
-           test_y > 0 : test_y + win_h < (signed) screen->getHeight())) {
-       test_x = (screen->getRowPlacementDirection() == BScreen::LeftRight) ?
-       start_pos : screen->getWidth() - win_w - start_pos;
-       while (!placed &&
-            ((screen->getRowPlacementDirection() == BScreen::RightLeft) ?
-             test_x > 0 : test_x + win_w < (signed) screen->getWidth())) {
-         placed = True;
-         it.reset();
-         for (OpenboxWindow *curr = it.current(); placed && curr;
-            it++, curr = it.current()) {
-           if (curr->isMaximizedFull()) // fully maximized, ignore it
-             continue;
-           int curr_w = curr->getWidth() + (screen->getBorderWidth() * 4);
-           int curr_h =
-           ((curr->isShaded()) ? curr->getTitleHeight() : curr->getHeight()) +
-             (screen->getBorderWidth() * 4);
-         
-           if (curr->getXFrame() < test_x + win_w &&
-               curr->getXFrame() + curr_w > test_x &&
-               curr->getYFrame() < test_y + win_h &&
-               curr->getYFrame() + curr_h > test_y) {
-             placed = False;
-         }
++           ((screen.rowPlacementDirection() == BScreen::RightLeft) ?
++            test_x > 0 : test_x + win_size.w() < (signed) space.w())) {
++      placed = true;
++
++      it.reset();
++      for (OpenboxWindow *curr = it.current(); placed && curr;
++           it++, curr = it.current()) {
++        int curr_w = curr->area().w() + (screen.getBorderWidth() * 4);
++        int curr_h = curr->area().h() + (screen.getBorderWidth() * 4);
++
++        if (curr->area().x() < test_x + win_size.w() &&
++            curr->area().x() + curr_w > test_x &&
++            curr->area().y() < test_y + win_size.h() &&
++            curr->area().y() + curr_h > test_y) {
++          placed = false;
 +        }
++      }
 +
-         if (placed &&
-           (toolbar_x < test_x + win_w &&
-              toolbar_x + toolbar_w > test_x &&
-              toolbar_y < test_y + win_h &&
-              toolbar_y + toolbar_h > test_y)
- #ifdef    SLIT
-              ||
-             (slit_x < test_x + win_w &&
-              slit_x + slit_w > test_x &&
-              slit_y < test_y + win_h &&
-              slit_y + slit_h > test_y)
- #endif // SLIT
-           )
-           placed = False;
++      // Removed code for checking toolbar and slit
++      // The space passed in should not include either
++
++      if (placed) {
++        place_x = test_x;
++        place_y = test_y;
++
++        break;
++      }   
++
++      test_x += (change_x * delta_x);
+     }
  
-         if (placed) {
-           place_x = test_x;
-           place_y = test_y;
 -  if (best != NULL) {
 -    Point *pt = new Point(best->origin());
 -    if (screen.colPlacementDirection() != BScreen::TopBottom)
 -      pt->setY(best->y() + best->h() - win_size.h());
 -    if (screen.rowPlacementDirection() != BScreen::LeftRight)
 -      pt->setX(best->x()+best->w()-win_size.w());
 -    return pt;
 -  } else
 -    return NULL; //fall back to cascade
++    test_y += (change_y * delta_y);
++  }
++  if (placed)
++    return new Point(place_x, place_y);
++  else
++    return NULL; // fall back to cascade
+ }
  
-           break;
+ Point *Workspace::colSmartPlacement(const Size &win_size, const Rect &space) {
 -  const Rect *best;
 -  rectList spaces;
++  Point *pt;
++  bool placed=false;
++  int test_x, test_y;
++  int start_pos = 0;
++  int change_y =
++    ((screen.colPlacementDirection() == BScreen::TopBottom) ? 1 : -1);
++  int change_x =
++    ((screen.rowPlacementDirection() == BScreen::LeftRight) ? 1 : -1);
++  int delta_x = 8, delta_y = 8;
+   LinkedListIterator<OpenboxWindow> it(windowList);
 -  rectList::const_iterator siter;
 -  spaces.push_back(space); //initially the entire screen is free
 -  it.reset();
 -  
 -  //Find Free Spaces
 -  for (OpenboxWindow *cur=it.current(); cur!=NULL; it++, cur=it.current())
 -     spaces = calcSpace(cur->area().Inflate(screen.getBorderWidth() * 4),
 -                        spaces);
 -  //Sort spaces by user preference
 -  if(screen.colPlacementDirection() == BScreen::TopBottom)
 -     if(screen.rowPlacementDirection() == BScreen::LeftRight)
 -        sort(spaces.begin(),spaces.end(),colLRTB);
 -     else
 -        sort(spaces.begin(),spaces.end(),colRLTB);
 -  else
 -     if(screen.rowPlacementDirection() == BScreen::LeftRight)
 -        sort(spaces.begin(),spaces.end(),colLRBT);
 -     else
 -        sort(spaces.begin(),spaces.end(),colRLBT);
++  test_x = (screen.rowPlacementDirection() == BScreen::LeftRight) ?
++    start_pos : screen.size().w() - win_size.w() - start_pos;
++
++  while(!placed &&
++        ((screen.rowPlacementDirection() == BScreen::RightLeft) ?
++         test_x > 0 : test_x + win_size.w() < (signed) space.w())) {
++    test_y = (screen.colPlacementDirection() == BScreen::TopBottom) ?
++      start_pos : screen.size().h() - win_size.h() - start_pos;
++
++    while(!placed &&
++          ((screen.colPlacementDirection() == BScreen::BottomTop) ?
++           test_y > 0 : test_y + win_size.h() < (signed) space.h())){
++
++      placed = true;
++
++      it.reset();
++      for (OpenboxWindow *curr = it.current(); placed && curr;
++           it++, curr = it.current()) {
++        int curr_w = curr->area().w() + (screen.getBorderWidth() * 4);
++        int curr_h = curr->area().h() + (screen.getBorderWidth() * 4);
++
++        if (curr->area().x() < test_x + win_size.w() &&
++            curr->area().x() + curr_w > test_x &&
++            curr->area().y() < test_y + win_size.h() &&
++            curr->area().y() + curr_h > test_y) {
++          placed = False;
 +        }
++      }
 -  //Find first space that fits the window
 -  best = NULL;
 -  for (siter=spaces.begin(); siter!=spaces.end(); ++siter)
 -    if ((siter->w() >= win_size.w()) && (siter->h() >= win_size.h())) {
 -      best = &*siter;
 -      break;
++      // Removed code checking for intersection with Toolbar and Slit
++      // The space passed to this method should not include either
++
++      if (placed) {
++        pt= new Point(test_x,test_y);
 +
-       test_x += (change_x * delta_x);
++        break;
 +      }
 +
 +      test_y += (change_y * delta_y);
      }
  
-     break;
 -  if (best != NULL) {
 -    Point *pt = new Point(best->origin());
 -    if (screen.colPlacementDirection() != BScreen::TopBottom)
 -      pt->setY(pt->y() + (best->h() - win_size.h()));
 -    if (screen.rowPlacementDirection() != BScreen::LeftRight)
 -      pt->setX(pt->x() + (best->w() - win_size.w()));
++    test_x += (change_x * delta_x);
 +  }
++  if (placed)
+     return pt;
 -  } else
 -    return NULL; //fall back to cascade
++  else
++    return NULL;
+ }
  
-   case BScreen::ColSmartPlacement: {
-     test_x = (screen->getRowPlacementDirection() == BScreen::LeftRight) ?
-       start_pos : screen->getWidth() - win_w - start_pos;
  
-     while (!placed &&
-          ((screen->getRowPlacementDirection() == BScreen::RightLeft) ?
-           test_x > 0 : test_x + win_w < (signed) screen->getWidth())) {
-       test_y = (screen->getColPlacementDirection() == BScreen::TopBottom) ?
-       start_pos : screen->getHeight() - win_h - start_pos;
-       
-       while (!placed &&
-            ((screen->getColPlacementDirection() == BScreen::BottomTop) ?
-             test_y > 0 : test_y + win_h < (signed) screen->getHeight())) {
-         placed = True;
-         it.reset();
-         for (OpenboxWindow *curr = it.current(); placed && curr;
-            it++, curr = it.current()) {
-           if (curr->isMaximizedFull()) // fully maximized, ignore it
-             continue;
-           int curr_w = curr->getWidth() + (screen->getBorderWidth() * 4);
-           int curr_h =
-             ((curr->isShaded()) ? curr->getTitleHeight() : curr->getHeight()) +
-             (screen->getBorderWidth() * 4);
-           if (curr->getXFrame() < test_x + win_w &&
-               curr->getXFrame() + curr_w > test_x &&
-               curr->getYFrame() < test_y + win_h &&
-               curr->getYFrame() + curr_h > test_y) {
-             placed = False;
-         }
-         }
 -Point *const Workspace::cascadePlacement(const OpenboxWindow &win,
 -                                         const Rect &space) {
 -  if ((cascade_x + win.area().w() + screen.getBorderWidth() * 2 >
 -       (space.x() + space.w())) ||
 -      (cascade_y + win.area().h() + screen.getBorderWidth() * 2 >
 -       (space.y() + space.h())))
 -    cascade_x = cascade_y = 0;
 -  if (cascade_x < space.x() || cascade_y < space.y()) {
 -    cascade_x = space.x();
 -    cascade_y = space.y();
 -  }
++Point *const Workspace::cascadePlacement(const OpenboxWindow *const win){
++  if (((unsigned) cascade_x > (screen.size().w() / 2)) ||
++      ((unsigned) cascade_y > (screen.size().h() / 2)))
++    cascade_x = cascade_y = 32;
 +
-         if (placed &&
-           (toolbar_x < test_x + win_w &&
-            toolbar_x + toolbar_w > test_x &&
-            toolbar_y < test_y + win_h &&
-            toolbar_y + toolbar_h > test_y)
- #ifdef    SLIT
-           ||
-           (slit_x < test_x + win_w &&
-            slit_x + slit_w > test_x &&
-            slit_y < test_y + win_h &&
-            slit_y + slit_h > test_y)
- #endif // SLIT
-           )
-         placed = False;
++  cascade_x += win->getTitleHeight();
++  cascade_y += win->getTitleHeight();
  
-       if (placed) {
-         place_x = test_x;
-         place_y = test_y;
 -  Point *p = new Point(cascade_x, cascade_y);
 -  cascade_x += win.getTitleHeight();
 -  cascade_y += win.getTitleHeight();
 -  return p;
++  return new Point(cascade_x, cascade_y);
+ }
  
-         break;
-       }
  
-       test_y += (change_y * delta_y);
-       }
 -void Workspace::placeWindow(OpenboxWindow &win) {
 -  Rect space = screen.availableArea();
 -  const Size window_size(win.area().w()+screen.getBorderWidth() * 2,
 -                         win.area().h()+screen.getBorderWidth() * 2);
++void Workspace::placeWindow(OpenboxWindow *win) {
++  ASSERT(win != NULL);
 +
-       test_x += (change_x * delta_x);
-     }
++  // the following code is temporary and will be taken care of by Screen in the
++  // future (with the NETWM 'strut')
++  Rect space(0, 0, screen.size().w(), screen.size().h());
 +
++#ifdef    SLIT
++    Slit *slit = screen.getSlit();
++    int slit_x = slit->autoHide() ? slit->hiddenOrigin().x() : slit->area().x(),
++        slit_y = slit->autoHide() ? slit->hiddenOrigin().y() : slit->area().y();
++    Toolbar *toolbar = screen.getToolbar();
++    int tbarh = screen.hideToolbar() ? 0 :
++      toolbar->getExposedHeight() + screen.getBorderWidth() * 2;
++    bool tbartop;
++    switch (toolbar->placement()) {
++    case Toolbar::TopLeft:
++    case Toolbar::TopCenter:
++    case Toolbar::TopRight:
++      tbartop = true;
++      break;
++    case Toolbar::BottomLeft:
++    case Toolbar::BottomCenter:
++    case Toolbar::BottomRight:
++      tbartop = false;
++      break;
++    default:
++      ASSERT(false);      // unhandled placement
++    }
++    if ((slit->direction() == Slit::Horizontal &&
++         (slit->placement() == Slit::TopLeft ||
++          slit->placement() == Slit::TopRight)) ||
++        slit->placement() == Slit::TopCenter) {
++      // exclude top
++      if (tbartop && slit_y + slit->area().h() < tbarh) {
++        space.setY(space.y() + tbarh);
++        space.setH(space.h() - tbarh);
++      } else {
++        space.setY(space.y() + (slit_y + slit->area().h() +
++                                screen.getBorderWidth() * 2));
++        space.setH(space.h() - (slit_y + slit->area().h() +
++                                screen.getBorderWidth() * 2));
++        if (!tbartop)
++          space.setH(space.h() - tbarh);
++      }
++    } else if ((slit->direction() == Slit::Vertical &&
++              (slit->placement() == Slit::TopRight ||
++               slit->placement() == Slit::BottomRight)) ||
++             slit->placement() == Slit::CenterRight) {
++      // exclude right
++      space.setW(space.w() - (screen.size().w() - slit_x));
++      if (tbartop)
++        space.setY(space.y() + tbarh);
++      space.setH(space.h() - tbarh);
++    } else if ((slit->direction() == Slit::Horizontal &&
++              (slit->placement() == Slit::BottomLeft ||
++               slit->placement() == Slit::BottomRight)) ||
++             slit->placement() == Slit::BottomCenter) {
++      // exclude bottom
++      if (!tbartop && (screen.size().h() - slit_y) < tbarh) {
++        space.setH(space.h() - tbarh);
++      } else {
++        space.setH(space.h() - (screen.size().h() - slit_y));
++        if (tbartop) {
++          space.setY(space.y() + tbarh);
++          space.setH(space.h() - tbarh);
++        }
++      }
++    } else {// if ((slit->direction() == Slit::Vertical &&
++      //      (slit->placement() == Slit::TopLeft ||
++      //       slit->placement() == Slit::BottomLeft)) ||
++      //     slit->placement() == Slit::CenterLeft)
++      // exclude left
++      space.setX(slit_x + slit->area().w() +
++                 screen.getBorderWidth() * 2);
++      space.setW(space.w() - (slit_x + slit->area().w() +
++                              screen.getBorderWidth() * 2));
++      if (tbartop)
++        space.setY(space.y() + tbarh);
++      space.setH(space.h() - tbarh);
++    }
++#else // !SLIT
++  Toolbar *toolbar = screen.getToolbar();
++  int tbarh = screen.hideToolbar() ? 0 :
++    toolbar->getExposedHeight() + screen.getBorderWidth() * 2;
++  switch (toolbar->placement()) {
++  case Toolbar::TopLeft:
++  case Toolbar::TopCenter:
++  case Toolbar::TopRight:
++    space.setY(toolbar->getExposedHeight());
++    space.setH(space.h() - toolbar->getExposedHeight());
++    break;
++  case Toolbar::BottomLeft:
++  case Toolbar::BottomCenter:
++  case Toolbar::BottomRight:
++    space.setH(space.h() - tbarh);
 +    break;
++  default:
++    ASSERT(false);      // unhandled placement
 +  }
-   } // switch
-   if (! placed) {
-     if (((unsigned) cascade_x > (screen->getWidth() / 2)) ||
-       ((unsigned) cascade_y > (screen->getHeight() / 2)))
-       cascade_x = cascade_y = 32;
++#endif // SLIT
 +
-     place_x = cascade_x;
-     place_y = cascade_y;
++  const Size window_size(win->area().w()+screen.getBorderWidth() * 4,
++                         win->area().h()+screen.getBorderWidth() * 4);
+   Point *place = NULL;
+   LinkedListIterator<OpenboxWindow> it(windowList);
  
-     cascade_x += win->getTitleHeight();
-     cascade_y += win->getTitleHeight();
-   }
-   
-   if (place_x + win_w > (signed) screen->getWidth())
-     place_x = (((signed) screen->getWidth()) - win_w) / 2;
-   if (place_y + win_h > (signed) screen->getHeight())
-     place_y = (((signed) screen->getHeight()) - win_h) / 2;
+   switch (screen.placementPolicy()) {
+   case BScreen::BestFitPlacement:
+     place = bestFitPlacement(window_size, space);
+     break;
+   case BScreen::RowSmartPlacement:
+     place = rowSmartPlacement(window_size, space);
+     break;
+   case BScreen::ColSmartPlacement:
+     place = colSmartPlacement(window_size, space);
+     break;
 -  case BScreen::UnderMousePlacement:
 -  case BScreen::ClickMousePlacement:
 -    place = underMousePlacement(window_size, space);
 -    break;
+   } // switch
  
-   win->configure(place_x, place_y, win->getWidth(), win->getHeight());
+   if (place == NULL)
 -    place = cascadePlacement(win, space);
++    place = cascadePlacement(win);
+  
+   ASSERT(place != NULL);  
 -  if (place->x() + window_size.w() > (signed) space.x() + space.w())
 -    place->setX(((signed) space.x() + space.w() - window_size.w()) / 2);
 -  if (place->y() + window_size.h() > (signed) space.y() + space.h())
 -    place->setY(((signed) space.y() + space.h() - window_size.h()) / 2);
++  if (place->x() + window_size.w() > (signed) screen.size().w())
++    place->setX(((signed) screen.size().w() - window_size.w()) / 2);
++  if (place->y() + window_size.h() > (signed) screen.size().h())
++    place->setY(((signed) screen.size().h() - window_size.h()) / 2);
 -  win.configure(place->x(), place->y(), win.area().w(), win.area().h());
++  win->configure(place->x(), place->y(), win->area().w(), win->area().h());
+   delete place;
  }
diff --cc src/Workspace.h
index f9700bdce74907d9b9dd26c419b559ea498ad180,01b520ad5a1844fe97212efa7e1df3bdd0508684..c2b920918793bfbc11e99b7c1e8f74bf8f9f05c8
@@@ -26,6 -26,6 +26,7 @@@
  #include <X11/Xlib.h>
  
  #include "LinkedList.h"
++#include "Geometry.h"
  
  class BScreen;
  class Clientmenu;
@@@ -43,32 -45,31 +44,35 @@@ private
    char *name;
    int id, cascade_x, cascade_y;
  
 -  OpenboxWindow *_focused;
  
  protected:
 -  void placeWindow(OpenboxWindow &);
 +  void placeWindow(OpenboxWindow *);
+   Point *bestFitPlacement(const Size &win_size, const Rect &space);
 -  Point *underMousePlacement(const Size &win_size, const Rect &space);
+   Point *rowSmartPlacement(const Size &win_size, const Rect &space);
+   Point *colSmartPlacement(const Size &win_size, const Rect &space);
 -  Point *const cascadePlacement(const OpenboxWindow &window, const Rect &space);
++  Point *const cascadePlacement(const OpenboxWindow* window);
  
  public:
-   Workspace(BScreen *, int = 0);
+   Workspace(BScreen &, int = 0);
    ~Workspace(void);
  
-   inline BScreen *getScreen(void) { return screen; }
+   inline BScreen &getScreen(void) { return screen; }
 +
    inline OpenboxWindow *getLastFocusedWindow(void) { return lastfocus; }
 +  
    inline Clientmenu *getMenu(void) { return clientmenu; }
 +
    inline const char *getName(void) const { return name; }
 +
    inline const int &getWorkspaceID(void) const { return id; }
 +  
    inline void setLastFocusedWindow(OpenboxWindow *w) { lastfocus = w; }
 -  inline OpenboxWindow *focusedWindow() { return _focused; }
 -  void focusWindow(OpenboxWindow *win);
 +
    OpenboxWindow *getWindow(int);
 +
    Bool isCurrent(void);
    Bool isLastWindow(OpenboxWindow *);
 +  
    const int addWindow(OpenboxWindow *, Bool = False);
    const int removeWindow(OpenboxWindow *);
    const int getCount(void);
diff --cc src/openbox.cc
index ad3ecc011ba4a6f4a8d39024845e5ded01f36363,3325bf382596cf0bb4bf61e06cacae3a1bd8e33b..77c5baca4b86a9c7c3df949583f72806fb943ada
@@@ -174,11 -182,11 +182,11 @@@ Openbox::Openbox(int m_argc, char **m_a
  
    no_focus = False;
  
-   resource.menu_file = resource.style_file = (char *) 0;
-   resource.titlebar_layout = (char *) NULL;
+   resource.menu_file = resource.style_file = NULL;
+   resource.titlebar_layout = NULL;
    resource.auto_raise_delay.tv_sec = resource.auto_raise_delay.tv_usec = 0;
  
-   focused_window = masked_window = (OpenboxWindow *) 0;
 -  masked_window = NULL;
++  focused_window = masked_window = NULL;
    masked = None;
  
    windowSearchList = new LinkedList<WindowSearch>;
               "Openbox::Openbox: no managable screens found, aborting.\n"));
      ::exit(3);
    }
 -  focused_screen = screenList->first();
  
+   // save current settings and default values
+   save();
+   
    XSynchronize(getXDisplay(), False);
    XSync(getXDisplay(), False);
  
diff --cc src/openbox.h
index 6f23e035d98e2fa1b839139840ac1bff0b4790f7,82abab7aaf73ad7ed374cfbdcc3487ad41cfd963..eae8bcff544f1901a42811711d11ac9489e684cb
@@@ -139,7 -140,8 +139,7 @@@ public
  
    OpenboxWindow *searchGroup(Window, OpenboxWindow *);
    OpenboxWindow *searchWindow(Window);
-   inline OpenboxWindow *getFocusedWindow(void) { return focused_window; }
 -  OpenboxWindow *focusedWindow();
 -  void focusWindow(OpenboxWindow *w);
++  inline OpenboxWindow *getFocusedWindow() { return focused_window; }
  
    BScreen *getScreen(int);
    BScreen *searchScreen(Window);
  
    Toolbar *searchToolbar(Window);
  
-   inline const char *getStyleFilename(void) const
+   inline const char *getStyleFilename() const
      { return resource.style_file; }
-   inline const char *getMenuFilename(void) const
+   inline const char *getMenuFilename() const
      { return resource.menu_file; }
  
-   inline const int &getColorsPerChannel(void) const
+   inline const int &getColorsPerChannel() const
      { return resource.colors_per_channel; }
  
-   inline const timeval &getAutoRaiseDelay(void) const
+   inline const timeval &getAutoRaiseDelay() const
      { return resource.auto_raise_delay; }
  
-   inline const char *getTitleBarLayout(void) const
+   inline const char *getTitleBarLayout() const
      { return resource.titlebar_layout; }
  
-   inline const unsigned long &getCacheLife(void) const
+   inline const unsigned long &getCacheLife() const
      { return resource.cache_life; }
-   inline const unsigned long &getCacheMax(void) const
+   inline const unsigned long &getCacheMax() const
      { return resource.cache_max; }
  
 -  inline OpenboxWindow *getMaskedWindow() const
 -    { return masked_window; }
    inline void maskWindowEvents(Window w, OpenboxWindow *bw)
      { masked = w; masked_window = bw; }
    inline void setNoFocus(Bool f) { no_focus = f; }
  
-   void shutdown(void);
-   void load_rc(BScreen *);
-   void saveStyleFilename(const char *);
-   void saveMenuFilename(const char *);
 +  void setFocusedWindow(OpenboxWindow *w);
+   void shutdown();
+   void setStyleFilename(const char *);
+   void setMenuFilename(const char *);
    void saveMenuSearch(Window, Basemenu *);
    void saveWindowSearch(Window, OpenboxWindow *);
    void saveToolbarSearch(Window, Toolbar *);
diff --cc util/bsetbg
index a0675aa6d0f7a69b53fe541a98fbf3231a0e5d01,23b0718d3ae485135e5fb211da6348e20ebce9e9..59d6b0939b0ad8b74dd5677d1290f4aee2ee9808
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
  # DEALINGS IN THE SOFTWARE.
  
- error_msg()
- {
-  case $INFO in yes|y|1) info_msg; esac
-  case $1 in
-    1)
-      echo; echo "$NAME: configuration error: $OPTION=\"$VALUE\"" 
-      echo "$NAME: please edit $CONFIG and provide the correct variable."
-      ;;
-    2)
-      echo; echo "$NAME: error: couldn't execute '$APP'! tried to run fallback option $ARGUMENT"
-      echo "$NAME: but quit because of the following error in $CONFIG:"
-      echo "$NAME: $OPTION= $VALUE"
-      echo "$NAME: please edit $CONFIG and provide the correct variable!"
-      ;;
-    3)
-      echo; echo "$NAME: error: couldn't find any suitable image applications in the system path!"
-      echo
-      error_msg url
-      ;;
-    4)
-      echo; echo "$NAME: error: invalid option, or non-existent image ($ARGUMENT)."
-      ;;
-    5)
-      echo; echo "$NAME: error: the image you specified ($IMAGE) could not be found."
-      ;;
-    6)
-      echo; echo "$NAME: error: please specify a valid image."
-      ;;
-    7)
-      echo; echo "$NAME: error: bsetroot couldn't be found! check your openbox installation."
-      ;;
-    8)
-      echo; echo "$NAME: error: wrong number of arguments!"
-      echo "$NAME: make sure you enclosed the options for '$APP' in double quotes."
-      ;;
-    nobgapp)
-      echo; echo "$NAME: error: tried to run '$VALUE' for $ARGUMENT argument,"
-      echo "$NAME: but couldnt find '$APP' in the path! please fix the following"
-      echo "$NAME: line in $CONFIG to point to an existing application:"
-      echo "$NAME: $OPTION=\"$VALUE\""
-      ;;
-    nogrep)
-      echo "$NAME: error: couldn't find grep!"
-      echo "this script needs grep to be in your path in order to function." 
-      echo "you can get GNU grep from ftp://ftp.gnu.org/bin/gnu/grep/" && exit 1
-      ;;
-    url)
-      echo "it is suggested that you use qiv, xli (xsetbg), or xv."
-      echo "you can obtain them at the following locations:"
-      echo
-      echo "   qiv: http://www.klografx.de/software/qiv.shtml"
-      echo "   xli: http://pantransit.reptiles.org/prog/#xli"
-      echo "   xv: http://www.trilon.com/xv/downloads.html"
-      echo
-      echo "the above URLs are current as of 05/23/2000."
-  esac
-  exit 1           
- }
- help_msg()
- {
-     echo "$NAME $VERSION: $MORE"
-     echo "options:"
-     echo
-     echo "  (none)                             image is set using default values"
-     echo
-     echo "  -full, -f                          image is set fullscreen"
-     echo "  -tile, -t                          image is set tiled"
-     echo "  -center, -c                        image is set centered"
-     echo
-     echo "  -app, -a <application>             image is set using <application> with"
-     echo "     <"'"application options"'">            quote-enclosed \"options\" and" 
-     echo "     -center, -c|-tile, -t|-full, -f    default fallback option"
-     echo
-     echo "  -display <string>                  display to connect to (bsetroot only)"
-     echo "  -mod <x> <y>                       sets bsetroot modula pattern"
-     echo "     -foreground, -fg <color>           modula foreground color"
-     echo "     -background, -bg <color>           modula background color"
-     echo
-     echo "  -gradient <texture>                sets bsetroot gradient texture"
-     echo "     -from <color>                      gradient start color"
-     echo "     -to <color>                        gradient end color"
-     echo
-     echo "  -solid <color>                     sets bsetroot solid color"
-     echo
-     echo "  -version, -v                       outputs $NAME's version number"
-     echo "  -info, -i                          outputs configuration info"
-     echo "  -help, -h                          this message"
-     echo
-     echo "usage: <options...> <image>"
-     exit 0 
- }
- info_msg()
- {
-     case $ERROR in
-       [1-3])
-           SUMMARY="error: some variables are blank"
-           ;;
-       4)
-           SUMMARY="no values have been specified"
-           ;;
-       0)
-           SUMMARY="looks good"
-     esac
-     case $APP_ERROR in [1-4])
-       SUMMARY="error: some applications couldn't be found!"
-     esac
-     case `which bsetroot 2>&1` in
-       */*bsetroot)
-           BSETROOT=`which bsetroot`
-           ;;
-       *)
-           BSETROOT="(error: not found)"
-           case $ERROR in
-               1-4)
-                   SUMMARY="$SUMMARY, and bsetroot does not seem to be present."
-                   ;;
-               *)
-                   SUMMARY="$SUMMARY, but bsetroot does not seem to be present."
-           esac
-     esac
-     echo "$NAME $VERSION configuration:"
-     echo
-     echo "  bsetroot:                          $BSETROOT"
-     echo
-     echo "  reading configuration from:        $CONFIG"
-     echo
-     echo "  configuration values:"
-     echo
-     case $FULL_BGAPP_MSG in 
-       *"not found")
-           echo "      fullscreen (ERROR):            $FULL_BGAPP_MSG"
-           ;;
-       *)
-           echo "      fullscreen (FULL):             $FULL_MSG"
-     esac
-     echo
-     case $TILE_BGAPP_MSG in 
-       *"not found")
-           echo "      tiled (ERROR):                 $TILE_BGAPP_MSG"
-           ;;
-       *)
-           echo "      tiled (TILE):                  $TILE_MSG"
-     esac
-     echo
-     case $CENTER_BGAPP_MSG in 
-       *"not found")
-           echo "      centered (ERROR):              $CENTER_BGAPP_MSG"
-           ;;
-       *)
-           echo "      centered (CENTER):             $CENTER_MSG"
-     esac
-     echo
-     case $DEFAULT_BGAPP_MSG in 
-       *"not found")
-           echo "      default (ERROR):               $DEFAULT_BGAPP_MSG"
-           ;;
-       *)
-           echo "      default (DEFAULT):             $DEFAULT_MSG"
-     esac
-     echo
-     echo "  summary: $SUMMARY"
-     exit 0
+ PATH=$PATH:/usr/bin:/usr/local/bin:/usr/X11R6/bin
+ display_full_cmd="display -geometry 800x600 -window root"
+ display_tile_cmd="display -window root"
+ display_center_cmd="display -backdrop -window root"
+ display_default_cmd="$display_center_cmd"
+ Esetroot_full_cmd="Esetroot -scale"
+ Esetroot_tile_cmd="Esetroot"
+ Esetroot_center_cmd="Esetroot -c"
+ Esetroot_default_cmd="$Esetroot_center_cmd"
+ wmsetbg_full_cmd="wmsetbg -s -S"
+ wmsetbg_tile_cmd="wmsetbg -t"
+ wmsetbg_center_cmd="wmsetbg -e"
+ wmsetbg_default_cmd="$wmsetbg_center_cmd"
+ qiv_full_cmd="qiv --root_s"
+ qiv_tile_cmd="qiv --root_t"
+ qiv_center_cmd="qiv --root"
+ qiv_default_cmd="$qiv_center_cmd"
+ xv_full_cmd="xv -max -smooth -root -quit"
+ xv_tile_cmd="xv -root -quit"
+ xv_center_cmd="xv -rmode 5 -root -quit"
+ xv_default_cmd="$xv_center_cmd"
+ xli_full_cmd="xli -fullscreen -onroot -quiet"
+ xli_tile_cmd="xli -onroot -quiet"
+ xli_center_cmd="xli -center -onroot quiet"
+ xli_default_cmd="$xli_center_cmd"
 -xsetbg_full_cmd="xsetbg -fullscreen"
++xsetbg_full_cmd="xsetbg -fillscreen"
+ xsetbg_tile_cmd="xsetbg"
+ xsetbg_center_cmd="xsetbg -center"
+ xsetbg_default_cmd="$xsetbg_center_cmd"
+ img_apps="qiv xli xv wmsetbg Esetroot display xsetbg"
+ me=${0##*/}
+ version=2.0
+ copyright="(c) 2000-$(date +%Y) by Timothy M. King (http://lordzork.com/)"
+ config=$HOME/.bsetbgrc
+ last_cmd_file=$HOME/.bsetbg_last_cmd
+ refresh_cmd=xrefresh
+ p=$me:
+ quit() {
+     [ "$1" ] && rc=$1 && shift 1
+     [ "$*" ] && echo -e $*
+     exit ${rc:-0}
  }
  
- find_app()
- {
-     case `which $1 2>&1` in 
-       */*$1)
-           echo "$NAME: checking for $1... `which $1`"
-           echo "### $app" >> $TMPFILE
-           echo "# FULL=\"$full\"" >> $TMPFILE
-           echo "# TILE=\"$tile\"" >> $TMPFILE
-           echo "# CENTER=\"$center\"" >> $TMPFILE
-           echo "# DEFAULT=\"$default\"" >> $TMPFILE
-           echo >> $TMPFILE
-           FULL=$full
-           TILE=$tile
-           CENTER=$center
-           DEFAULT=$default
-           APP=$app
-           ;;
-       *)
-       echo "$NAME: checking for $1... not found."
+ bool() {
+     case $1 in
+             [yY][eE][sS]|1|[yY]|[tT][rR][uU][eE]|[oO][nN]) : ;;
+             *) return 1 ;;
      esac
  }
  
index f0912cab39e0510dc0e59880194d80da33d9bfa6,56748c3098c8c7382972f2e97aa9d9a8c1273ac0..3452eaa26488e47679fb4bb73eb0aa1835c5db65
@@@ -22,13 -26,9 +25,13 @@@ bsetroot::bsetroot(int argc, char **arg
    grad = fore = back = (char *) 0;
  
    Bool mod = False, sol = False, grd = False;
 -  int mod_x = 0, mod_y = 0;
 +  int mod_x = 0, mod_y = 0, i = 0;
  
 -  for (int i = 1; i < argc; i++) {
 +  img_ctrl = new BImageControl*[getNumberOfScreens()];
 +  for (; i < getNumberOfScreens(); i++)
-     img_ctrl[i] = new BImageControl(this, getScreenInfo(i), True);
++    img_ctrl[i] = new BImageControl(*this, *getScreenInfo(i), True);
 +
 +  for (i = 1; i < argc; i++) {
      if (! strcmp("-help", argv[i])) {
        usage();
      } else if ((! strcmp("-fg", argv[i])) ||
@@@ -219,9 -267,9 +222,9 @@@ void bsetroot::gradient(void) 
      if (! texture.getColorTo()->isAllocated())
        texture.getColorTo()->setPixel(BlackPixel(getXDisplay(), screen));
  
 -    Pixmap pixmap =
 +    pixmaps[screen] =
-       img_ctrl[screen]->renderImage(getScreenInfo(screen)->getWidth(),
-                                     getScreenInfo(screen)->getHeight(),
+       img_ctrl[screen]->renderImage(getScreenInfo(screen)->size().w(),
+                                     getScreenInfo(screen)->size().h(),
                                      &texture);
  
      XSetWindowBackgroundPixmap(getXDisplay(),