]> Dogcows Code - chaz/openbox/blobdiff - src/screen.cc
new code for bindings/callbacks. much sexier. now passes python classes back to the...
[chaz/openbox] / src / screen.cc
index 24520cea551543725be4d36822d78726a01270ca..da603ed8cb3d690152853fa13c5cc46539651f78 100644 (file)
 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
 
-#ifdef    HAVE_CONFIG_H
-#include "../config.h"
-#endif // HAVE_CONFIG_H
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif
 
 extern "C" {
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-
-#ifdef    XINERAMA
-#  include <X11/Xlib.h>
-#  include <X11/extensions/Xinerama.h>
-#endif // XINERAMA
-
-#ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-#endif // HAVE_STDLIB_H
-
-#ifdef HAVE_STRING_H
-#  include <string.h>
-#endif // HAVE_STRING_H
-
-#ifdef    HAVE_CTYPE_H
-#  include <ctype.h>
-#endif // HAVE_CTYPE_H
+#ifdef    HAVE_STDIO_H
+#  include <stdio.h>
+#endif // HAVE_STDIO_H
 
 #ifdef    HAVE_UNISTD_H
 #  include <sys/types.h>
 #  include <unistd.h>
 #endif // HAVE_UNISTD_H
 
-#ifdef    HAVE_DIRENT_H
-#  include <dirent.h>
-#endif // HAVE_DIRENT_H
-
-#ifdef    HAVE_LOCALE_H
-#  include <locale.h>
-#endif // HAVE_LOCALE_H
-
-#ifdef    HAVE_SYS_STAT_H
-#  include <sys/stat.h>
-#endif // HAVE_SYS_STAT_H
-
-#ifdef    HAVE_STDARG_H
-#  include <stdarg.h>
-#endif // HAVE_STDARG_H
+#include "gettext.h"
+#define _(str) gettext(str)
 }
 
-#include <assert.h>
-
-#include <algorithm>
-#include <functional>
-#include <string>
-using std::string;
-
 #include "screen.hh"
-#include "otk/font.hh"
-#include "otk/gccache.hh"
-#include "otk/image.hh"
-#include "otk/assassin.hh"
+#include "client.hh"
 #include "openbox.hh"
-#include "util.hh"
-#include "bbwindow.hh"
-#include "workspace.hh"
-#include "util.hh"
-#include "atom.hh"
-
-#ifndef   FONT_ELEMENT_SIZE
-#define   FONT_ELEMENT_SIZE 50
-#endif // FONT_ELEMENT_SIZE
-
-namespace ob {
-
-static bool running = True;
+#include "frame.hh"
+#include "bindings.hh"
+#include "python.hh"
+#include "otk/display.hh"
 
+static bool running;
 static int anotherWMRunning(Display *display, XErrorEvent *) {
-  fprintf(stderr,
-          "BScreen::BScreen: an error occured while querying the X server.\n"
-          "  another window manager already running on display %s.\n",
-          DisplayString(display));
-
-  running = False;
-
-  return(-1);
+  printf(_("Another window manager already running on display %s.\n"),
+         DisplayString(display));
+  running = true;
+  return -1;
 }
 
 
-BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(scrn) {
-  blackbox = bb;
-  screenstr = "session.screen" + itostring(scrn) + '.';
-  config = blackbox->getConfig();
-  xatom = blackbox->getXAtom();
-
-  event_mask = ColormapChangeMask | EnterWindowMask | PropertyChangeMask |
-    SubstructureRedirectMask | ButtonPressMask | ButtonReleaseMask;
-
-  XErrorHandler old = XSetErrorHandler((XErrorHandler) anotherWMRunning);
-  XSelectInput(otk::OBDisplay::display, getRootWindow(), event_mask);
-  XSync(otk::OBDisplay::display, False);
-  XSetErrorHandler((XErrorHandler) old);
-
-  managed = running;
-  if (! managed) return;
-
-  fprintf(stderr, "BScreen::BScreen: managing screen %d "
-          "using visual 0x%lx, depth %d\n",
-          getScreenNumber(), XVisualIDFromVisual(getVisual()),
-          getDepth());
-
-  resource.wstyle.font = (otk::BFont *) 0;
-
-  geom_pixmap = None;
-
-  xatom->setSupported(this);    // set-up netwm support
-#ifdef    HAVE_GETPID
-  xatom->setValue(getRootWindow(), XAtom::blackbox_pid, XAtom::cardinal,
-                  (unsigned long) getpid());
-#endif // HAVE_GETPID
-  unsigned long geometry[] = { getWidth(),
-                               getHeight()};
-  xatom->setValue(getRootWindow(), OBAtom::net_desktop_geometry,
-                  OBAtom::cardinal, geometry, 2);
-  unsigned long viewport[] = {0,0};
-  xatom->setValue(getRootWindow(), OBAtom::net_desktop_viewport,
-                  OBAtom::cardinal, viewport, 2);
-                  
-
-  XDefineCursor(otk::OBDisplay::display, getRootWindow(),
-                blackbox->getSessionCursor());
-
-  updateAvailableArea();
-
-  image_control =
-    new otk::BImageControl(Openbox::instance->timerManager(),
-                           this, True, blackbox->getColorsPerChannel(),
-                           blackbox->getCacheLife(), blackbox->getCacheMax());
-  image_control->installRootColormap();
-  root_colormap_installed = True;
-
-  load_rc();
-  LoadStyle();
-
-  XGCValues gcv;
-  gcv.foreground = WhitePixel(otk::OBDisplay::display, getScreenNumber())
-    ^ BlackPixel(otk::OBDisplay::display, getScreenNumber());
-  gcv.function = GXxor;
-  gcv.subwindow_mode = IncludeInferiors;
-  opGC = XCreateGC(otk::OBDisplay::display, getRootWindow(),
-                   GCForeground | GCFunction | GCSubwindowMode, &gcv);
-
-  const char *s = "0: 0000 x 0: 0000";
-  geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2;
-  geom_h = resource.wstyle.font->height() + resource.bevel_width * 2;
-
-  XSetWindowAttributes attrib;
-  unsigned long mask = CWBorderPixel | CWColormap | CWSaveUnder;
-  attrib.border_pixel = getBorderColor()->pixel();
-  attrib.colormap = getColormap();
-  attrib.save_under = True;
-
-  geom_window = XCreateWindow(otk::OBDisplay::display, getRootWindow(),
-                              0, 0, geom_w, geom_h, resource.border_width,
-                              getDepth(), InputOutput, getVisual(),
-                              mask, &attrib);
-  geom_visible = False;
-
-  otk::BTexture* texture = &(resource.wstyle.l_focus);
-  geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
-  if (geom_pixmap == ParentRelative) {
-    texture = &(resource.wstyle.t_focus);
-    geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
-  }
-  if (! geom_pixmap)
-    XSetWindowBackground(otk::OBDisplay::display, geom_window,
-                         texture->color().pixel());
-  else
-    XSetWindowBackgroundPixmap(otk::OBDisplay::display,
-                               geom_window, geom_pixmap);
-
-  if (resource.workspaces > 0) {
-    for (unsigned int i = 0; i < resource.workspaces; ++i) {
-      Workspace *wkspc = new Workspace(this, workspacesList.size());
-      workspacesList.push_back(wkspc);
+namespace ob {
 
+
+OBScreen::OBScreen(int screen)
+  : _number(screen),
+    _root(screen)
+{
+  assert(screen >= 0); assert(screen < ScreenCount(otk::OBDisplay::display));
+  _info = otk::OBDisplay::screenInfo(screen);
+
+  ::running = false;
+  XErrorHandler old = XSetErrorHandler(::anotherWMRunning);
+  XSelectInput(otk::OBDisplay::display, _info->rootWindow(),
+               OBScreen::event_mask);
+  XSync(otk::OBDisplay::display, false);
+  XSetErrorHandler(old);
+
+  _managed = !::running;
+  if (! _managed) return; // was unable to manage the screen
+
+  printf(_("Managing screen %d: visual 0x%lx, depth %d\n"),
+         _number, XVisualIDFromVisual(_info->visual()), _info->depth());
+
+  Openbox::instance->property()->set(_info->rootWindow(),
+                                     otk::OBProperty::openbox_pid,
+                                     otk::OBProperty::Atom_Cardinal,
+                                     (unsigned long) getpid());
+
+  // set the mouse cursor for the root window (the default cursor)
+  XDefineCursor(otk::OBDisplay::display, _info->rootWindow(),
+                Openbox::instance->cursors().session);
+
+  // initialize the shit that is used for all drawing on the screen
+  _image_control = new otk::BImageControl(Openbox::instance->timerManager(),
+                                          _info, true);
+  _image_control->installRootColormap();
+  _root_cmap_installed = True;
+
+  // initialize the screen's style
+  _style.setImageControl(_image_control);
+  std::string stylepath;
+  python_get_string("theme", &stylepath);
+  otk::Configuration sconfig(false);
+  sconfig.setFile(otk::expandTilde(stylepath));
+  if (!sconfig.load()) {
+    sconfig.setFile(otk::expandTilde(DEFAULTSTYLE));
+    if (!sconfig.load()) {
+      printf(_("Unable to load default style: %s. Aborting.\n"), DEFAULTSTYLE);
+      ::exit(1);
     }
-  } else {
-    Workspace *wkspc = new Workspace(this, workspacesList.size());
-    workspacesList.push_back(wkspc);
   }
-  saveWorkspaceNames();
+  _style.load(sconfig);
+  
+  // Set the netwm atoms for geomtery and viewport
+  unsigned long geometry[] = { _info->width(),
+                               _info->height() };
+  Openbox::instance->property()->set(_info->rootWindow(),
+                                     otk::OBProperty::net_desktop_geometry,
+                                     otk::OBProperty::Atom_Cardinal,
+                                     geometry, 2);
+  unsigned long viewport[] = { 0, 0 };
+  Openbox::instance->property()->set(_info->rootWindow(),
+                                     otk::OBProperty::net_desktop_viewport,
+                                     otk::OBProperty::Atom_Cardinal,
+                                     viewport, 2);
+
+  // create the window which gets focus when no clients get it
+  XSetWindowAttributes attr;
+  attr.override_redirect = true;
+  _focuswindow = XCreateWindow(otk::OBDisplay::display, _info->rootWindow(),
+                               -100, -100, 1, 1, 0, 0, InputOnly,
+                               _info->visual(), CWOverrideRedirect, &attr);
+  XMapWindow(otk::OBDisplay::display, _focuswindow);
+  
+  // these may be further updated if any pre-existing windows are found in
+  // the manageExising() function
+  setClientList();     // initialize the client lists, which will be empty
+  calcArea();          // initialize the available working area
+}
 
-  updateNetizenWorkspaceCount();
 
-  current_workspace = workspacesList.front();
-  
-  xatom->setValue(getRootWindow(), OBAtom::net_current_desktop,
-                  OBAtom::cardinal, 0); //first workspace
+OBScreen::~OBScreen()
+{
+  if (! _managed) return;
 
-  raiseWindows(0, 0);     // this also initializes the empty stacking list
+  // unmanage all windows
+  while (!clients.empty())
+    unmanageWindow(clients.front());
 
-  updateClientList();     // initialize the client lists, which will be empty
-  updateAvailableArea();
+  delete _image_control;
+}
 
-  changeWorkspaceID(0);
 
+void OBScreen::manageExisting()
+{
   unsigned int i, j, nchild;
   Window r, p, *children;
-  XQueryTree(otk::OBDisplay::display, getRootWindow(), &r, &p,
+  XQueryTree(otk::OBDisplay::display, _info->rootWindow(), &r, &p,
              &children, &nchild);
 
   // preen the window list of all icon windows... for better dockapp support
@@ -233,7 +159,7 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(scrn) {
 
   // manage shown windows
   for (i = 0; i < nchild; ++i) {
-    if (children[i] == None || ! blackbox->validateWindow(children[i]))
+    if (children[i] == None)
       continue;
 
     XWindowAttributes attrib;
@@ -247,1312 +173,35 @@ BScreen::BScreen(Blackbox *bb, unsigned int scrn) : ScreenInfo(scrn) {
   }
 
   XFree(children);
-
-  // call this again just in case a window we found updates the Strut list
-  updateAvailableArea();
-}
-
-
-BScreen::~BScreen(void) {
-  if (! managed) return;
-
-  if (geom_pixmap != None)
-    image_control->removeImage(geom_pixmap);
-
-  if (geom_window != None)
-    XDestroyWindow(otk::OBDisplay::display, geom_window);
-
-  std::for_each(workspacesList.begin(), workspacesList.end(),
-                otk::PointerAssassin());
-
-  std::for_each(iconList.begin(), iconList.end(), otk::PointerAssassin());
-
-  while (! systrayWindowList.empty())
-    removeSystrayWindow(systrayWindowList[0]);
-
-  delete image_control;
-
-  if (resource.wstyle.font)
-    delete resource.wstyle.font;
-
-  if (resource.wstyle.close_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.close_button.mask);
-  if (resource.wstyle.max_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.max_button.mask);
-  if (resource.wstyle.icon_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.icon_button.mask);
-  if (resource.wstyle.stick_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.stick_button.mask);
-
-  resource.wstyle.max_button.mask = resource.wstyle.close_button.mask =
-    resource.wstyle.icon_button.mask =
-    resource.wstyle.stick_button.mask = None;
-  
-  XFreeGC(otk::OBDisplay::display, opGC);
-}
-
-
-void BScreen::saveSloppyFocus(bool s) {
-  resource.sloppy_focus = s;
-
-  string fmodel;
-  if (resource.sloppy_focus) {
-    fmodel = "SloppyFocus";
-    if (resource.auto_raise) fmodel += " AutoRaise";
-    if (resource.click_raise) fmodel += " ClickRaise";
-  } else {
-    fmodel = "ClickToFocus";
-  }
-  config->setValue(screenstr + "focusModel", fmodel);
-}
-
-
-void BScreen::saveAutoRaise(bool a) {
-  resource.auto_raise = a;
-  saveSloppyFocus(resource.sloppy_focus);
-}
-
-
-void BScreen::saveClickRaise(bool c) {
-  resource.click_raise = c;
-  saveSloppyFocus(resource.sloppy_focus);
-}
-
-
-void BScreen::saveImageDither(bool d) {
-  image_control->setDither(d);
-  config->setValue(screenstr + "imageDither", doImageDither());
-}
-
-
-void BScreen::saveOpaqueMove(bool o) {
-  resource.opaque_move = o;
-  config->setValue(screenstr + "opaqueMove", resource.opaque_move);
-}
-
-
-void BScreen::saveFullMax(bool f) {
-  resource.full_max = f;
-  config->setValue(screenstr + "fullMaximization", resource.full_max);
 }
 
 
-void BScreen::saveFocusNew(bool f) {
-  resource.focus_new = f;
-  config->setValue(screenstr + "focusNewWindows", resource.focus_new);
+//! Adds a window's strut to the screen's list of reserved spaces
+void OBScreen::addStrut(otk::Strut *strut)
+{
+  _struts.push_back(strut);
 }
 
 
-void BScreen::saveFocusLast(bool f) {
-  resource.focus_last = f;
-  config->setValue(screenstr + "focusLastWindow", resource.focus_last);
+//! Removes a window's strut from the screen's list of reserved spaces
+void OBScreen::removeStrut(otk::Strut *strut)
+{
+  _struts.remove(strut);
 }
 
 
-void BScreen::saveAAFonts(bool f) {
-  resource.aa_fonts = f;
-  config->setValue(screenstr + "antialiasFonts", resource.aa_fonts);
-  reconfigure();
-}
-
-
-void BScreen::saveShadowFonts(bool f) {
-  resource.shadow_fonts = f;
-  config->setValue(screenstr + "dropShadowFonts", resource.shadow_fonts);
-  reconfigure();
-}
-
-
-void BScreen::saveWindowToEdgeSnap(int s) {
-  resource.snap_to_edges = s;
-
-  const char *snap;
-  switch (resource.snap_to_edges) {
-  case WindowNoSnap: snap = "NoSnap"; break;
-  case WindowResistance: snap = "Resistance"; break;
-  case WindowSnap: default: snap = "Snap"; break;
-  }
-  config->setValue(screenstr + "windowToEdgeSnap", snap);
-}
-
-
-void BScreen::saveWindowToWindowSnap(int s) {
-  resource.snap_to_windows = s;
-  
-  const char *snap;
-  switch (resource.snap_to_windows) {
-  case WindowNoSnap: snap = "NoSnap"; break;
-  case WindowResistance: snap = "Resistance"; break;
-  case WindowSnap: default: snap = "Snap"; break;
-  }
-  config->setValue(screenstr + "windowToWindowSnap", snap);
-}
-
-
-void BScreen::saveResizeZones(unsigned int z) {
-  resource.resize_zones = z;
-  config->setValue(screenstr + "resizeZones", resource.resize_zones);
-}
-
-
-void BScreen::saveWindowCornerSnap(bool s) {
-  resource.window_corner_snap = s;
-  config->setValue(screenstr + "windowCornerSnap",
-                   resource.window_corner_snap);
-}
-
-
-void BScreen::saveWorkspaces(unsigned int w) {
-  resource.workspaces = w;
-  config->setValue(screenstr + "workspaces", resource.workspaces);
-}
-
-
-void BScreen::savePlacementPolicy(int p) {
-  resource.placement_policy = p; 
-  const char *placement;
-  switch (resource.placement_policy) {
-  case CascadePlacement: placement = "CascadePlacement"; break;
-  case UnderMousePlacement: placement = "UnderMousePlacement"; break;
-  case ClickMousePlacement: placement = "ClickMousePlacement"; break;
-  case ColSmartPlacement: placement = "ColSmartPlacement"; break;
-  case RowSmartPlacement: default: placement = "RowSmartPlacement"; break;
-  }
-  config->setValue(screenstr + "windowPlacement", placement);
-}
-
-
-void BScreen::saveResistanceSize(int s) {
-  resource.resistance_size = s;
-  config->setValue(screenstr + "resistanceSize",
-                   resource.resistance_size);
-}
-
-
-void BScreen::saveSnapThreshold(int t) {
-  resource.snap_threshold = t;
-  config->setValue(screenstr + "edgeSnapThreshold",
-                   resource.snap_threshold);
-}
-
-
-void BScreen::saveSnapOffset(int t) {
-  resource.snap_offset = t;
-  config->setValue(screenstr + "edgeSnapOffset",
-                   resource.snap_offset);
-}
-
-
-void BScreen::saveRowPlacementDirection(int d) {
-  resource.row_direction = d;
-  config->setValue(screenstr + "rowPlacementDirection",
-                   resource.row_direction == LeftRight ?
-                   "LeftToRight" : "RightToLeft");
-}
-
-
-void BScreen::saveColPlacementDirection(int d) {
-  resource.col_direction = d;
-  config->setValue(screenstr + "colPlacementDirection",
-                   resource.col_direction == TopBottom ?
-                   "TopToBottom" : "BottomToTop");
-}
-
-
-void BScreen::saveStrftimeFormat(const std::string& format) {
-  resource.strftime_format = format;
-  config->setValue(screenstr + "strftimeFormat", resource.strftime_format);
-}
-
-
-void BScreen::saveWorkspaceNames() {
-  string names;
-  for (unsigned int i = 0; i < workspacesList.size(); ++i) {
-    names += workspacesList[i]->getName();
-    if (i < workspacesList.size() - 1)
-      names += ',';
-  }
-
-  config->setValue(screenstr + "workspaceNames", names);
-}
-
-
-void BScreen::savePlaceIgnoreShaded(bool i) {
-  resource.ignore_shaded = i;
-  config->setValue(screenstr + "placementIgnoreShaded",
-                   resource.ignore_shaded);
-}
-
-
-void BScreen::savePlaceIgnoreMaximized(bool i) {
-  resource.ignore_maximized = i;
-  config->setValue(screenstr + "placementIgnoreMaximized",
-                   resource.ignore_maximized);
-}
-
-
-void BScreen::saveAllowScrollLock(bool a) {
-  resource.allow_scroll_lock = a;
-  config->setValue(screenstr + "disableBindingsWithScrollLock",
-                   resource.allow_scroll_lock);
-}
-
-
-void BScreen::saveWorkspaceWarping(bool w) {
-  resource.workspace_warping = w;
-  config->setValue(screenstr + "workspaceWarping",
-                   resource.workspace_warping);
-}
-
-
-void BScreen::saveRootScrollDirection(int d) {
-  resource.root_scroll = d;
-  const char *dir;
-  switch (resource.root_scroll) {
-  case NoScroll: dir = "None"; break;
-  case ReverseScroll: dir = "Reverse"; break;
-  case NormalScroll: default: dir = "Normal"; break;
-  }
-  config->setValue(screenstr + "rootScrollDirection", dir);
-}
-
-
-void BScreen::save_rc(void) {
-  saveSloppyFocus(resource.sloppy_focus);
-  saveAutoRaise(resource.auto_raise);
-  saveImageDither(doImageDither());
-  saveShadowFonts(resource.shadow_fonts);
-  saveAAFonts(resource.aa_fonts);
-  saveResizeZones(resource.resize_zones);
-  saveOpaqueMove(resource.opaque_move);
-  saveFullMax(resource.full_max);
-  saveFocusNew(resource.focus_new);
-  saveFocusLast(resource.focus_last);
-  saveWindowToWindowSnap(resource.snap_to_windows);
-  saveWindowToEdgeSnap(resource.snap_to_edges);
-  saveWindowCornerSnap(resource.window_corner_snap);
-  saveWorkspaces(resource.workspaces);
-  savePlacementPolicy(resource.placement_policy);
-  saveSnapThreshold(resource.snap_threshold);
-  saveSnapOffset(resource.snap_offset);
-  saveResistanceSize(resource.resistance_size);
-  saveRowPlacementDirection(resource.row_direction);
-  saveColPlacementDirection(resource.col_direction);
-  saveStrftimeFormat(resource.strftime_format); 
-  savePlaceIgnoreShaded(resource.ignore_shaded);
-  savePlaceIgnoreMaximized(resource.ignore_maximized);
-  saveAllowScrollLock(resource.allow_scroll_lock);
-  saveWorkspaceWarping(resource.workspace_warping);
-  saveRootScrollDirection(resource.root_scroll);
-}
-
-
-void BScreen::load_rc(void) {
-  std::string s;
-  bool b;
-
-  if (! config->getValue(screenstr + "fullMaximization", resource.full_max))
-    resource.full_max = false;
-
-  if (! config->getValue(screenstr + "focusNewWindows", resource.focus_new))
-    resource.focus_new = false;
-
-  if (! config->getValue(screenstr + "focusLastWindow", resource.focus_last))
-    resource.focus_last = false;
-
-  if (! config->getValue(screenstr + "workspaces", resource.workspaces))
-    resource.workspaces = 1;
-
-  if (! config->getValue(screenstr + "opaqueMove", resource.opaque_move))
-    resource.opaque_move = false;
-
-  if (! config->getValue(screenstr + "antialiasFonts", resource.aa_fonts))
-    resource.aa_fonts = true;
-
-  if (! resource.aa_fonts ||
-      ! config->getValue(screenstr + "dropShadowFonts", resource.shadow_fonts))
-    resource.shadow_fonts = false;
-
-  if (! config->getValue(screenstr + "resizeZones", resource.resize_zones) ||
-      (resource.resize_zones != 1 && resource.resize_zones != 2 &&
-       resource.resize_zones != 4))
-      resource.resize_zones = 4;
-
-  resource.snap_to_windows = WindowResistance;
-  if (config->getValue(screenstr + "windowToWindowSnap", s)) {
-    if (s == "NoSnap")
-      resource.snap_to_windows = WindowNoSnap;
-    else if (s == "Snap")
-      resource.snap_to_windows = WindowSnap;
-  }
-
-  resource.snap_to_edges = WindowResistance;
-  if (config->getValue(screenstr + "windowToEdgeSnap", s)) {
-    if (s == "NoSnap")
-      resource.snap_to_edges = WindowNoSnap;
-    else if (s == "Snap")
-      resource.snap_to_edges = WindowSnap;
-  }
-
-  if (! config->getValue(screenstr + "windowCornerSnap",
-                         resource.window_corner_snap))
-    resource.window_corner_snap = true;
-
-  if (! config->getValue(screenstr + "imageDither", b))
-    b = true;
-  image_control->setDither(b);
-
-  if (! config->getValue(screenstr + "edgeSnapOffset",
-                        resource.snap_offset))
-    resource.snap_offset = 0;
-  if (resource.snap_offset > 50)  // sanity check, setting this huge would
-    resource.snap_offset = 50;    // seriously suck.
-  
-  if (! config->getValue(screenstr + "edgeSnapThreshold",
-                        resource.snap_threshold))
-    resource.snap_threshold = 4;
-  
-  if (! config->getValue(screenstr + "resistanceSize",
-                        resource.resistance_size))
-    resource.resistance_size = 18;
-  
-  if (config->getValue(screenstr + "rowPlacementDirection", s) &&
-      s == "RightToLeft")
-    resource.row_direction = RightLeft;
-  else
-    resource.row_direction = LeftRight;
-
-  if (config->getValue(screenstr + "colPlacementDirection", s) &&
-      s == "BottomToTop")
-    resource.col_direction = BottomTop;
-  else
-    resource.col_direction = TopBottom;
-
-  if (config->getValue(screenstr + "workspaceNames", s)) {
-    OBAtom::StringVect workspaceNames;
-
-    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
-      workspaceNames.push_back(string(tmp, it)); // s[tmp:it]
-      if (it == end)
-        break;
-      ++it;
-    }
-
-    xatom->setValue(getRootWindow(), OBAtom::net_desktop_names, OBAtom::utf8,
-                    workspaceNames);
-  }
-
-  resource.sloppy_focus = true;
-  resource.auto_raise = false;
-  resource.click_raise = false;
-  if (config->getValue(screenstr + "focusModel", s)) {
-    if (s.find("ClickToFocus") != string::npos) {
-      resource.sloppy_focus = false;
-    } else {
-      // must be sloppy
-      if (s.find("AutoRaise") != string::npos)
-        resource.auto_raise = true;
-      if (s.find("ClickRaise") != string::npos)
-        resource.click_raise = true;
-    }
-  }
-
-  if (config->getValue(screenstr + "windowPlacement", s)) {
-    if (s == "CascadePlacement")
-      resource.placement_policy = CascadePlacement;
-    else if (s == "UnderMousePlacement")
-      resource.placement_policy = UnderMousePlacement;
-    else if (s == "ClickMousePlacement")
-      resource.placement_policy = ClickMousePlacement;
-    else if (s == "ColSmartPlacement")
-      resource.placement_policy = ColSmartPlacement;
-    else //if (s == "RowSmartPlacement")
-      resource.placement_policy = RowSmartPlacement;
-  } else
-    resource.placement_policy = RowSmartPlacement;
-
-  if (! config->getValue(screenstr + "strftimeFormat",
-                         resource.strftime_format))
-    resource.strftime_format = "%I:%M %p";
-  
-  if (! config->getValue(screenstr + "placementIgnoreShaded",
-                         resource.ignore_shaded))
-    resource.ignore_shaded = true;
-
-  if (! config->getValue(screenstr + "placementIgnoreMaximized",
-                         resource.ignore_maximized))
-    resource.ignore_maximized = true;
-
-  if (! config->getValue(screenstr + "disableBindingsWithScrollLock",
-                       resource.allow_scroll_lock))
-    resource.allow_scroll_lock = false;
-
-  if (! config->getValue(screenstr + "workspaceWarping",
-                         resource.workspace_warping))
-    resource.workspace_warping = false;
-
-  resource.root_scroll = NormalScroll;
-  if (config->getValue(screenstr + "rootScrollDirection", s)) {
-    if (s == "None")
-      resource.root_scroll = NoScroll;
-    else if (s == "Reverse")
-      resource.root_scroll = ReverseScroll;
-  }
-}
-
-
-void BScreen::changeWorkspaceCount(unsigned int new_count) {
-  assert(new_count > 0);
-
-  if (new_count < workspacesList.size()) {
-    // shrink
-    for (unsigned int i = workspacesList.size(); i > new_count; --i)
-      removeLastWorkspace();
-    // removeLast already sets the current workspace to the 
-    // last available one.
-  } else if (new_count > workspacesList.size()) {
-    // grow
-    for(unsigned int i = workspacesList.size(); i < new_count; ++i)
-      addWorkspace();
-  }
-}
-
-
-void BScreen::reconfigure(void) {
-  // don't reconfigure while saving the initial rc file, it's a waste and it
-  // breaks somethings (workspace names)
-  if (blackbox->state() == Openbox::State_Starting) return;
-
-  load_rc();
-  LoadStyle();
-
-  // we need to do this explicitly, because just loading this value from the rc
-  // does nothing
-  changeWorkspaceCount(resource.workspaces);
-
-  XGCValues gcv;
-  gcv.foreground = WhitePixel(otk::OBDisplay::display,
-                              getScreenNumber());
-  gcv.function = GXinvert;
-  gcv.subwindow_mode = IncludeInferiors;
-  XChangeGC(otk::OBDisplay::display, opGC,
-            GCForeground | GCFunction | GCSubwindowMode, &gcv);
-
-  const char *s = "0: 0000 x 0: 0000";
-
-  geom_w = resource.wstyle.font->measureString(s) + resource.bevel_width * 2;
-  geom_h = resource.wstyle.font->height() + resource.bevel_width * 2;
-
-  otk::BTexture* texture = &(resource.wstyle.l_focus);
-  geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
-  if (geom_pixmap == ParentRelative) {
-    texture = &(resource.wstyle.t_focus);
-    geom_pixmap = texture->render(geom_w, geom_h, geom_pixmap);
-  }
-  if (! geom_pixmap)
-    XSetWindowBackground(otk::OBDisplay::display, geom_window,
-                         texture->color().pixel());
-  else
-    XSetWindowBackgroundPixmap(otk::OBDisplay::display,
-                               geom_window, geom_pixmap);
-
-  XSetWindowBorderWidth(otk::OBDisplay::display, geom_window,
-                        resource.border_width);
-  XSetWindowBorder(otk::OBDisplay::display, geom_window,
-                   resource.border_color.pixel());
-
-  typedef std::vector<int> SubList;
-  SubList remember_subs;
-
-  raiseWindows(0, 0);
-
-  std::for_each(workspacesList.begin(), workspacesList.end(),
-                std::mem_fun(&Workspace::reconfigure));
-
-  BlackboxWindowList::iterator iit = iconList.begin();
-  for (; iit != iconList.end(); ++iit) {
-    BlackboxWindow *bw = *iit;
-    if (bw->validateClient())
-      bw->reconfigure();
-  }
-
-  otk::BImageControl::timeout(image_control);
-}
-
-
-void BScreen::LoadStyle(void) {
-  Configuration style(False);
-
-  const char *sfile = blackbox->getStyleFilename();
-  if (sfile != NULL) {
-    style.setFile(sfile);
-    if (! style.load()) {
-      style.setFile(DEFAULTSTYLE);
-      if (! style.load())
-        style.create();  // hardcoded default values will be used.
-    }
-  }
-
-  // merge in the rc file
-  style.merge(config->file(), True);
-
-  string s;
-
-  // load fonts/fontsets
-  if (resource.wstyle.font)
-    delete resource.wstyle.font;
-
-  resource.wstyle.font = readDatabaseFont("window.", style);
-
-  // load window config
-  resource.wstyle.t_focus =
-    readDatabaseTexture("window.title.focus", "white", style);
-  resource.wstyle.t_unfocus =
-    readDatabaseTexture("window.title.unfocus", "black", style);
-  resource.wstyle.l_focus =
-    readDatabaseTexture("window.label.focus", "white", style);
-  resource.wstyle.l_unfocus =
-    readDatabaseTexture("window.label.unfocus", "black", style);
-  resource.wstyle.h_focus =
-    readDatabaseTexture("window.handle.focus", "white", style);
-  resource.wstyle.h_unfocus =
-    readDatabaseTexture("window.handle.unfocus", "black", style);
-  resource.wstyle.g_focus =
-    readDatabaseTexture("window.grip.focus", "white", style);
-  resource.wstyle.g_unfocus =
-    readDatabaseTexture("window.grip.unfocus", "black", style);
-  resource.wstyle.b_focus =
-    readDatabaseTexture("window.button.focus", "white", style);
-  resource.wstyle.b_unfocus =
-    readDatabaseTexture("window.button.unfocus", "black", style);
-  resource.wstyle.b_pressed =
-    readDatabaseTexture("window.button.pressed", "black", style);
-
-  //if neither of these can be found, we will use the previous resource
-  resource.wstyle.b_pressed_focus =
-    readDatabaseTexture("window.button.pressed.focus", "black", style, true);
-  resource.wstyle.b_pressed_unfocus =
-    readDatabaseTexture("window.button.pressed.unfocus", "black", style, true);
-
-  if (resource.wstyle.close_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.close_button.mask);
-  if (resource.wstyle.max_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.max_button.mask);
-  if (resource.wstyle.icon_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.icon_button.mask);
-  if (resource.wstyle.stick_button.mask != None)
-    XFreePixmap(otk::OBDisplay::display, resource.wstyle.stick_button.mask);
-
-  resource.wstyle.close_button.mask = resource.wstyle.max_button.mask =
-    resource.wstyle.icon_button.mask =
-    resource.wstyle.icon_button.mask = None;
-  
-  readDatabaseMask("window.button.close.mask", resource.wstyle.close_button,
-                   style);
-  readDatabaseMask("window.button.max.mask", resource.wstyle.max_button,
-                   style);
-  readDatabaseMask("window.button.icon.mask", resource.wstyle.icon_button,
-                   style);
-  readDatabaseMask("window.button.stick.mask", resource.wstyle.stick_button,
-                   style);
-
-  // we create the window.frame texture by hand because it exists only to
-  // make the code cleaner and is not actually used for display
-  otk::BColor color = readDatabaseColor("window.frame.focusColor", "white",
-                                        style);
-  resource.wstyle.f_focus = otk::BTexture("solid flat", getScreenNumber(),
-                                          image_control);
-  resource.wstyle.f_focus.setColor(color);
-
-  color = readDatabaseColor("window.frame.unfocusColor", "white", style);
-  resource.wstyle.f_unfocus = otk::BTexture("solid flat", getScreenNumber(),
-                                            image_control);
-  resource.wstyle.f_unfocus.setColor(color);
-
-  resource.wstyle.l_text_focus =
-    readDatabaseColor("window.label.focus.textColor", "black", style);
-  resource.wstyle.l_text_unfocus =
-    readDatabaseColor("window.label.unfocus.textColor", "white", style);
-  resource.wstyle.b_pic_focus =
-    readDatabaseColor("window.button.focus.picColor", "black", style);
-  resource.wstyle.b_pic_unfocus =
-    readDatabaseColor("window.button.unfocus.picColor", "white", style);
-
-  resource.wstyle.justify = LeftJustify;
-  if (style.getValue("window.justify", s)) {
-    if (s == "right" || s == "Right")
-      resource.wstyle.justify = RightJustify;
-    else if (s == "center" || s == "Center")
-      resource.wstyle.justify = CenterJustify;
-  }
-
-  // sanity checks
-  if (resource.wstyle.t_focus.texture() == otk::BTexture::Parent_Relative)
-    resource.wstyle.t_focus = resource.wstyle.f_focus;
-  if (resource.wstyle.t_unfocus.texture() == otk::BTexture::Parent_Relative)
-    resource.wstyle.t_unfocus = resource.wstyle.f_unfocus;
-  if (resource.wstyle.h_focus.texture() == otk::BTexture::Parent_Relative)
-    resource.wstyle.h_focus = resource.wstyle.f_focus;
-  if (resource.wstyle.h_unfocus.texture() == otk::BTexture::Parent_Relative)
-    resource.wstyle.h_unfocus = resource.wstyle.f_unfocus;
-
-  resource.border_color =
-    readDatabaseColor("borderColor", "black", style);
-
-  // load bevel, border and handle widths
-  if (! style.getValue("handleWidth", resource.handle_width) ||
-      resource.handle_width > (getWidth() / 2) || resource.handle_width == 0)
-    resource.handle_width = 6;
-
-  if (! style.getValue("borderWidth", resource.border_width))
-    resource.border_width = 1;
-
-  if (! style.getValue("bevelWidth", resource.bevel_width) ||
-      resource.bevel_width > (getWidth() / 2) || resource.bevel_width == 0)
-    resource.bevel_width = 3;
-
-  if (! style.getValue("frameWidth", resource.frame_width) ||
-      resource.frame_width > (getWidth() / 2))
-    resource.frame_width = resource.bevel_width;
-
-  if (style.getValue("rootCommand", s))
-    bexec(s, displayString());
-}
-
-
-void BScreen::addIcon(BlackboxWindow *w) {
-  if (! w) return;
-
-  w->setWorkspace(BSENTINEL);
-  w->setWindowNumber(iconList.size());
-
-  iconList.push_back(w);
-}
-
-
-void BScreen::removeIcon(BlackboxWindow *w) {
-  if (! w) return;
-
-  iconList.remove(w);
-
-  BlackboxWindowList::iterator it = iconList.begin(),
-    end = iconList.end();
-  for (int i = 0; it != end; ++it)
-    (*it)->setWindowNumber(i++);
-}
-
-
-BlackboxWindow *BScreen::getIcon(unsigned int index) {
-  if (index < iconList.size()) {
-    BlackboxWindowList::iterator it = iconList.begin();
-    while (index-- > 0) // increment to index
-      ++it;
-    return *it;
-  }
-
-  return (BlackboxWindow *) 0;
-}
-
-
-unsigned int BScreen::addWorkspace(void) {
-  Workspace *wkspc = new Workspace(this, workspacesList.size());
-  workspacesList.push_back(wkspc);
-  saveWorkspaces(getWorkspaceCount());
-  saveWorkspaceNames();
-
-  return workspacesList.size();
-}
-
-
-unsigned int BScreen::removeLastWorkspace(void) {
-  if (workspacesList.size() == 1)
-    return 1;
-
-  Workspace *wkspc = workspacesList.back();
-
-  if (current_workspace->getID() == wkspc->getID())
-    changeWorkspaceID(current_workspace->getID() - 1);
-
-  wkspc->removeAll();
-
-  workspacesList.pop_back();
-  delete wkspc;
-
-  saveWorkspaces(getWorkspaceCount());
-  saveWorkspaceNames();
-
-  updateNetizenWorkspaceCount();
-
-  return workspacesList.size();
-}
-
-
-void BScreen::changeWorkspaceID(unsigned int id) {
-  if (! current_workspace || id == current_workspace->getID()) return;
-
-  BlackboxWindow *focused = blackbox->getFocusedWindow();
-  if (focused && focused->getScreen() == this) {
-    assert(focused->isStuck() ||
-           focused->getWorkspaceNumber() == current_workspace->getID());
-
-    current_workspace->setLastFocusedWindow(focused);
-  } else {
-    // if no window had focus, no need to store a last focus
-    current_workspace->setLastFocusedWindow((BlackboxWindow *) 0);
-  }
-
-  // when we switch workspaces, unfocus whatever was focused if it is going
-  // to be unmapped
-  if (focused && ! focused->isStuck())
-    blackbox->setFocusedWindow((BlackboxWindow *) 0);
-
-  current_workspace->hideAll();
-
-  current_workspace = getWorkspace(id);
-
-  xatom->setValue(getRootWindow(), OBAtom::net_current_desktop,
-                  OBAtom::cardinal, id);
-
-  current_workspace->showAll();
-
-  int x, y, rx, ry;
-  Window c, r;
-  unsigned int m;
-  BlackboxWindow *win = (BlackboxWindow *) 0;
-  bool f = False;
-
-  XSync(otk::OBDisplay::display, False);
-
-  // If sloppy focus and we can find the client window under the pointer,
-  // try to focus it.  
-  if (resource.sloppy_focus &&
-      XQueryPointer(otk::OBDisplay::display, getRootWindow(), &r, &c,
-                    &rx, &ry, &x, &y, &m) &&
-      c != None) {
-    if ( (win = blackbox->searchWindow(c)) )
-      f = win->setInputFocus();
-  }
-
-  // If that fails, and we're doing focus_last, try to focus the last window.
-  if (! f && resource.focus_last &&
-      (win = current_workspace->getLastFocusedWindow()))
-    f = win->setInputFocus();
-
-  /*
-    if we found a focus target, then we set the focused window explicitly
-    because it is possible to switch off this workspace before the x server
-    generates the FocusIn event for the window. if that happens, openbox would
-    lose track of what window was the 'LastFocused' window on the workspace.
-
-    if we did not find a focus target, then set the current focused window to
-    nothing.
-  */
-  if (f)
-    blackbox->setFocusedWindow(win);
-  else
-    blackbox->setFocusedWindow((BlackboxWindow *) 0);
-}
-
+void OBScreen::calcArea()
+{
+  otk::Rect old_area = _area;
 
 /*
- * Set the _NET_CLIENT_LIST root window property.
- */
-void BScreen::updateClientList(void) {
-  if (windowList.size() > 0) {
-    Window *windows = new Window[windowList.size()];
-    Window *win_it = windows;
-    BlackboxWindowList::iterator it = windowList.begin();
-    const BlackboxWindowList::iterator end = windowList.end();
-    for (; it != end; ++it, ++win_it)
-      *win_it = (*it)->getClientWindow();
-    xatom->setValue(getRootWindow(), OBAtom::net_client_list, OBAtom::window,
-                    windows, windowList.size());
-    delete [] windows;
-  } else
-    xatom->setValue(getRootWindow(), OBAtom::net_client_list, OBAtom::window,
-                    0, 0);
-
-  updateStackingList();
-}
-
-
-/*
- * Set the _NET_CLIENT_LIST_STACKING root window property.
- */
-void BScreen::updateStackingList(void) {
-
-  BlackboxWindowList stack_order;
-
-  /*
-   * Get the stacking order from all of the workspaces.
-   * We start with the current workspace so that the sticky windows will be
-   * in the right order on the current workspace.
-   * XXX: Do we need to have sticky windows in the list once for each workspace?
-   */
-  getCurrentWorkspace()->appendStackOrder(stack_order);
-  for (unsigned int i = 0; i < getWorkspaceCount(); ++i)
-    if (i != getCurrentWorkspaceID())
-      getWorkspace(i)->appendStackOrder(stack_order);
-
-  if (stack_order.size() > 0) {
-    // set the client list atoms
-    Window *windows = new Window[stack_order.size()];
-    Window *win_it = windows;
-    BlackboxWindowList::iterator it = stack_order.begin(),
-                                 end = stack_order.end();
-    for (; it != end; ++it, ++win_it)
-      *win_it = (*it)->getClientWindow();
-    xatom->setValue(getRootWindow(), OBAtom::net_client_list_stacking,
-                    OBAtom::window, windows, stack_order.size());
-    delete [] windows;
-  } else
-    xatom->setValue(getRootWindow(), OBAtom::net_client_list_stacking,
-                    OBAtom::window, 0, 0);
-}
-
-
-void BScreen::addSystrayWindow(Window window) {
-  XGrabServer(otk::OBDisplay::display);
-  
-  XSelectInput(otk::OBDisplay::display, window, StructureNotifyMask);
-  systrayWindowList.push_back(window);
-  xatom->setValue(getRootWindow(), OBAtom::kde_net_system_tray_windows,
-                  OBAtom::window,
-                  &systrayWindowList[0], systrayWindowList.size());
-  blackbox->saveSystrayWindowSearch(window, this);
-
-  XUngrabServer(otk::OBDisplay::display);
-}
-
-
-void BScreen::removeSystrayWindow(Window window) {
-  XGrabServer(otk::OBDisplay::display);
-  
-  WindowList::iterator it = systrayWindowList.begin();
-  const WindowList::iterator end = systrayWindowList.end();
-  for (; it != end; ++it)
-    if (*it == window) {
-      systrayWindowList.erase(it);
-      xatom->setValue(getRootWindow(), OBAtom::kde_net_system_tray_windows,
-                      OBAtom::window,
-                      &systrayWindowList[0], systrayWindowList.size());
-      blackbox->removeSystrayWindowSearch(window);
-      XSelectInput(otk::OBDisplay::display, window, NoEventMask);
-      break;
-    }
-
-  assert(it != end);    // not a systray window
-
-  XUngrabServer(otk::OBDisplay::display);
-}
-
-
-void BScreen::manageWindow(Window w) {
-  // is the window a KDE systray window?
-  Window systray;
-  if (xatom->getValue(w, OBAtom::kde_net_wm_system_tray_window_for,
-                      OBAtom::window, systray) && systray != None) {
-    addSystrayWindow(w);
-    return;
-  }
-
-  // is the window a docking app
-  XWMHints *wmhint = XGetWMHints(otk::OBDisplay::display, w);
-  if (wmhint && (wmhint->flags & StateHint) &&
-      wmhint->initial_state == WithdrawnState) {
-    //slit->addClient(w);
-    return;
-  }
-
-  new BlackboxWindow(blackbox, w, this);
-
-  BlackboxWindow *win = blackbox->searchWindow(w);
-  if (! win)
-    return;
-
-  if (win->isDesktop()) {
-    desktopWindowList.push_back(win->getFrameWindow());
-  } else { // if (win->isNormal()) {
-    // don't list desktop windows as managed windows
-    windowList.push_back(win);
-    updateClientList();
-  
-    if (win->isTopmost())
-      specialWindowList.push_back(win->getFrameWindow());
-  }
-  
-  XMapRequestEvent mre;
-  mre.window = w;
-  if (blackbox->state() == Openbox::State_Starting &&
-      win->isNormal())
-    win->restoreAttributes();
-  win->mapRequestEvent(&mre);
-}
-
-
-void BScreen::unmanageWindow(BlackboxWindow *w, bool remap) {
-  // is the window a KDE systray window?
-  Window systray;
-  if (xatom->getValue(w->getClientWindow(),
-                      OBAtom::kde_net_wm_system_tray_window_for,
-                      OBAtom::window, systray) && systray != None) {
-    removeSystrayWindow(w->getClientWindow());
-    return;
-  }
-
-  w->restore(remap);
-
-  // Remove the modality so that its parent won't try to re-focus the window
-  if (w->isModal()) w->setModal(False);
-  
-  if (w->getWorkspaceNumber() != BSENTINEL &&
-      w->getWindowNumber() != BSENTINEL) {
-    getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
-    if (w->isStuck()) {
-      for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i)
-        if (i != w->getWorkspaceNumber())
-          getWorkspace(i)->removeWindow(w, True);
-    }
-  } else if (w->isIconic())
-    removeIcon(w);
-
-  if (w->isDesktop()) {
-    WindowList::iterator it = desktopWindowList.begin();
-    const WindowList::iterator end = desktopWindowList.end();
-    for (; it != end; ++it)
-      if (*it == w->getFrameWindow()) {
-        desktopWindowList.erase(it);
-        break;
-      }
-    assert(it != end);  // the window wasnt a desktop window?
-  } else { // if (w->isNormal()) {
-    // we don't list desktop windows as managed windows
-    windowList.remove(w);
-    updateClientList();
-
-    if (w->isTopmost()) {
-      WindowList::iterator it = specialWindowList.begin();
-      const WindowList::iterator end = specialWindowList.end();
-      for (; it != end; ++it)
-        if (*it == w->getFrameWindow()) {
-          specialWindowList.erase(it);
-          break;
-        }
-      assert(it != end);  // the window wasnt a special window?
-    }
-  }
-
-  if (blackbox->getFocusedWindow() == w)
-    blackbox->setFocusedWindow((BlackboxWindow *) 0);
-
-  /*
-    some managed windows can also be window group controllers.  when
-    unmanaging such windows, we should also delete the window group.
-  */
-  BWindowGroup *group = blackbox->searchGroup(w->getClientWindow());
-  delete group;
-
-  delete w;
-}
-
-
-void BScreen::updateWorkArea(void) {
-  if (workspacesList.size() > 0) {
-    unsigned long *dims = new unsigned long[4 * workspacesList.size()];
-    for (unsigned int i = 0, m = workspacesList.size(); i < m; ++i) {
-      // XXX: this could be different for each workspace
-      const otk::Rect &area = availableArea();
-      dims[(i * 4) + 0] = area.x();
-      dims[(i * 4) + 1] = area.y();
-      dims[(i * 4) + 2] = area.width();
-      dims[(i * 4) + 3] = area.height();
-    }
-    xatom->setValue(getRootWindow(), OBAtom::net_workarea, OBAtom::cardinal,
-                    dims, 4 * workspacesList.size());
-    delete [] dims;
-  } else
-    xatom->setValue(getRootWindow(), OBAtom::net_workarea, OBAtom::cardinal,
-                    0, 0);
-}
-
-
-void BScreen::updateNetizenWorkspaceCount(void) {
-  xatom->setValue(getRootWindow(), OBAtom::net_number_of_desktops,
-                  OBAtom::cardinal, workspacesList.size());
-
-  updateWorkArea();
-}
-
-
-void BScreen::updateNetizenWindowFocus(void) {
-  Window f = ((blackbox->getFocusedWindow()) ?
-              blackbox->getFocusedWindow()->getClientWindow() : None);
-
-  xatom->setValue(getRootWindow(), OBAtom::net_active_window,
-                  OBAtom::window, f);
-}
-
-
-void BScreen::raiseWindows(Window *workspace_stack, unsigned int num) {
-  // the 13 represents the number of blackbox windows such as menus
-  int bbwins = 15;
-#ifdef    XINERAMA
-  ++bbwins;
-#endif // XINERAMA
-
-  Window *session_stack = new
-    Window[(num + specialWindowList.size() + bbwins)];
-  unsigned int i = 0, k = num;
-
-  WindowList::iterator sit, send = specialWindowList.end();
-  for (sit = specialWindowList.begin(); sit != send; ++sit)
-    *(session_stack + i++) = *sit;
-
-  while (k--)
-    *(session_stack + i++) = *(workspace_stack + k);
-
-  XRestackWindows(otk::OBDisplay::display, session_stack, i);
-
-  delete [] session_stack;
-
-  updateStackingList();
-}
-
-
-void BScreen::lowerWindows(Window *workspace_stack, unsigned int num) {
-  assert(num > 0);  // this would cause trouble in the XRaiseWindow call
-
-  Window *session_stack = new Window[(num + desktopWindowList.size())];
-  unsigned int i = 0, k = num;
-
-  XLowerWindow(otk::OBDisplay::display, workspace_stack[0]);
-
-  while (k--)
-    *(session_stack + i++) = *(workspace_stack + k);
-
-  WindowList::iterator dit = desktopWindowList.begin();
-  const WindowList::iterator d_end = desktopWindowList.end();
-  for (; dit != d_end; ++dit)
-    *(session_stack + i++) = *dit;
-
-  XRestackWindows(otk::OBDisplay::display, session_stack, i);
-
-  delete [] session_stack;
-
-  updateStackingList();
-}
-
-
-void BScreen::reassociateWindow(BlackboxWindow *w, unsigned int wkspc_id,
-                                bool ignore_sticky) {
-  if (! w) return;
-
-  if (wkspc_id == BSENTINEL)
-    wkspc_id = current_workspace->getID();
-
-  if (w->getWorkspaceNumber() == wkspc_id)
-    return;
-
-  if (w->isIconic()) {
-    removeIcon(w);
-    getWorkspace(wkspc_id)->addWindow(w);
-    if (w->isStuck())
-      for (unsigned int i = 0; i < getNumberOfWorkspaces(); ++i)
-        if (i != w->getWorkspaceNumber())
-          getWorkspace(i)->addWindow(w, True);
-  } else if (ignore_sticky || ! w->isStuck()) {
-    if (w->isStuck())
-      w->stick();
-    getWorkspace(w->getWorkspaceNumber())->removeWindow(w);
-    getWorkspace(wkspc_id)->addWindow(w);
-  }
-  updateStackingList();
-}
-
-
-void BScreen::propagateWindowName(const BlackboxWindow *bw) {
-  if (bw->isIconic()) {
-  } else {
-  }
-}
-
-
-void BScreen::nextFocus(void) const {
-  BlackboxWindow *focused = blackbox->getFocusedWindow(),
-    *next = focused;
-
-  if (focused &&
-      focused->getScreen()->getScreenNumber() == getScreenNumber() &&
-      current_workspace->getCount() > 1) {
-    do {
-      next = current_workspace->getNextWindowInList(next);
-    } while (next != focused && ! next->setInputFocus());
-
-    if (next != focused)
-      current_workspace->raiseWindow(next);
-  } else if (current_workspace->getCount() > 0) {
-    next = current_workspace->getTopWindowOnStack();
-    next->setInputFocus();
-    current_workspace->raiseWindow(next);
-  }
-}
-
-
-void BScreen::prevFocus(void) const {
-  BlackboxWindow *focused = blackbox->getFocusedWindow(),
-    *next = focused;
-
-  if (focused) {
-    // if window is not on this screen, ignore it
-    if (focused->getScreen()->getScreenNumber() != getScreenNumber())
-      focused = (BlackboxWindow*) 0;
-  }
-  
-  if (focused &&
-      focused->getScreen()->getScreenNumber() == getScreenNumber() &&
-      current_workspace->getCount() > 1) {
-    // next is the next window to receive focus, current is a place holder
-    do {
-      next = current_workspace->getPrevWindowInList(next);
-    } while (next != focused && ! next->setInputFocus());
-
-    if (next != focused)
-      current_workspace->raiseWindow(next);
-  } else if (current_workspace->getCount() > 0) {
-    next = current_workspace->getTopWindowOnStack();
-    next->setInputFocus();
-    current_workspace->raiseWindow(next);
-  }
-}
-
-
-void BScreen::raiseFocus(void) const {
-  BlackboxWindow *focused = blackbox->getFocusedWindow();
-  if (! focused)
-    return;
-
-  // if on this Screen, raise it
-  if (focused->getScreen()->getScreenNumber() == getScreenNumber()) {
-    Workspace *workspace = getWorkspace(focused->getWorkspaceNumber());
-    workspace->raiseWindow(focused);
-  }
-}
-
-
-void BScreen::shutdown(void) {
-  XSelectInput(otk::OBDisplay::display, getRootWindow(), NoEventMask);
-  XSync(otk::OBDisplay::display, False);
-
-  while(! windowList.empty())
-    unmanageWindow(windowList.front(), True);
-
-  while(! desktopWindowList.empty()) {
-    BlackboxWindow *win = blackbox->searchWindow(desktopWindowList.front());
-    assert(win);
-    unmanageWindow(win, True);
-  }
-}
-
-
-void BScreen::showPosition(int x, int y) {
-  if (! geom_visible) {
-    XMoveResizeWindow(otk::OBDisplay::display, geom_window,
-                      (getWidth() - geom_w) / 2,
-                      (getHeight() - geom_h) / 2, geom_w, geom_h);
-    XMapWindow(otk::OBDisplay::display, geom_window);
-    XRaiseWindow(otk::OBDisplay::display, geom_window);
-
-    geom_visible = True;
-  }
-
-  char label[1024];
-
-  sprintf(label, "X: %4d x Y: %4d", x, y);
-
-  XClearWindow(otk::OBDisplay::display, geom_window);
-
-  resource.wstyle.font->drawString(geom_window,
-                                   resource.bevel_width, resource.bevel_width,
-                                   resource.wstyle.l_text_focus,
-                                   label);
-}
-
-
-void BScreen::showGeometry(unsigned int gx, unsigned int gy) {
-  if (! geom_visible) {
-    XMoveResizeWindow(otk::OBDisplay::display, geom_window,
-                      (getWidth() - geom_w) / 2,
-                      (getHeight() - geom_h) / 2, geom_w, geom_h);
-    XMapWindow(otk::OBDisplay::display, geom_window);
-    XRaiseWindow(otk::OBDisplay::display, geom_window);
-
-    geom_visible = True;
-  }
-
-  char label[1024];
-
-  sprintf(label, "W: %4d x H: %4d", gx, gy);
-
-  XClearWindow(otk::OBDisplay::display, geom_window);
-
-  resource.wstyle.font->drawString(geom_window,
-                                   resource.bevel_width, resource.bevel_width,
-                                   resource.wstyle.l_text_focus,
-                                   label);
-}
-
-
-void BScreen::hideGeometry(void) {
-  if (geom_visible) {
-    XUnmapWindow(otk::OBDisplay::display, geom_window);
-    geom_visible = False;
-  }
-}
-
-
-void BScreen::addStrut(Strut *strut) {
-  strutList.push_back(strut);
-}
-
-
-void BScreen::removeStrut(Strut *strut) {
-  strutList.remove(strut);
-}
-
-
-const otk::Rect& BScreen::availableArea(void) const {
-  if (doFullMax())
-    return getRect(); // return the full screen
-  return usableArea;
-}
-
-
-#ifdef    XINERAMA
-const RectList& BScreen::allAvailableAreas(void) const {
-  assert(isXineramaActive());
-  assert(xineramaUsableArea.size() > 0);
-  fprintf(stderr, "1found x %d y %d w %d h %d\n",
-          xineramaUsableArea[0].x(), xineramaUsableArea[0].y(),
-          xineramaUsableArea[0].width(), xineramaUsableArea[0].height());
-  return xineramaUsableArea;
-}
-#endif // XINERAMA
-
-
-void BScreen::updateAvailableArea(void) {
-  otk::Rect old_area = usableArea;
-  usableArea = getRect(); // reset to full screen
-
 #ifdef    XINERAMA
   // reset to the full areas
   if (isXineramaActive())
     xineramaUsableArea = getXineramaAreas();
 #endif // XINERAMA
-
+*/
+  
   /* these values represent offsets from the screen edge
    * we look for the biggest offset on each edge and then apply them
    * all at once
@@ -1561,10 +210,10 @@ void BScreen::updateAvailableArea(void) {
   unsigned int current_left = 0, current_right = 0, current_top = 0,
     current_bottom = 0;
 
-  StrutList::const_iterator it = strutList.begin(), end = strutList.end();
+  StrutList::const_iterator it = _struts.begin(), end = _struts.end();
 
   for(; it != end; ++it) {
-    Strut *strut = *it;
+    otk::Strut *strut = *it;
     if (strut->left > current_left)
       current_left = strut->left;
     if (strut->top > current_top)
@@ -1575,10 +224,11 @@ void BScreen::updateAvailableArea(void) {
       current_bottom = strut->bottom;
   }
 
-  usableArea.setPos(current_left, current_top);
-  usableArea.setSize(usableArea.width() - (current_left + current_right),
-                     usableArea.height() - (current_top + current_bottom));
+  _area.setRect(current_left, current_top,
+                _info->width() - (current_left + current_right),
+                _info->height() - (current_top + current_bottom));
 
+/*
 #ifdef    XINERAMA
   if (isXineramaActive()) {
     // keep each of the ximerama-defined areas inside the strut
@@ -1599,195 +249,206 @@ void BScreen::updateAvailableArea(void) {
     }
   }
 #endif // XINERAMA
+*/
+  
+  if (old_area != _area)
+    // XXX: re-maximize windows
 
-  if (old_area != usableArea) {
-    BlackboxWindowList::iterator it = windowList.begin(),
-      end = windowList.end();
-    for (; it != end; ++it)
-      if ((*it)->isMaximized()) (*it)->remaximize();
-  }
-
-  updateWorkArea();  
+  setWorkArea();
 }
 
 
-Workspace* BScreen::getWorkspace(unsigned int index) const {
-  assert(index < workspacesList.size());
-  return workspacesList[index];
-}
+void OBScreen::setClientList()
+{
+  Window *windows;
 
+  // create an array of the window ids
+  if (clients.size() > 0) {
+    Window *win_it;
+    
+    windows = new Window[clients.size()];
+    win_it = windows;
+    ClientList::const_iterator it = clients.begin();
+    const ClientList::const_iterator end = clients.end();
+    for (; it != end; ++it, ++win_it)
+      *win_it = (*it)->window();
+  } else
+    windows = (Window*) 0;
 
-void BScreen::buttonPressEvent(const XButtonEvent *xbutton) {
-  if (xbutton->button == 1) {
-    if (! isRootColormapInstalled())
-      image_control->installRootColormap();
-
-  // mouse wheel up
-  } else if ((xbutton->button == 4 && resource.root_scroll == NormalScroll) ||
-             (xbutton->button == 5 && resource.root_scroll == ReverseScroll)) {
-    if (getCurrentWorkspaceID() >= getWorkspaceCount() - 1)
-      changeWorkspaceID(0);
-    else
-      changeWorkspaceID(getCurrentWorkspaceID() + 1);
-  // mouse wheel down
-  } else if ((xbutton->button == 5 && resource.root_scroll == NormalScroll) ||
-             (xbutton->button == 4 && resource.root_scroll == ReverseScroll)) {
-    if (getCurrentWorkspaceID() == 0)
-      changeWorkspaceID(getWorkspaceCount() - 1);
-    else
-      changeWorkspaceID(getCurrentWorkspaceID() - 1);
-  }
-}
+  Openbox::instance->property()->set(_info->rootWindow(),
+                                     otk::OBProperty::net_client_list,
+                                     otk::OBProperty::Atom_Window,
+                                     windows, clients.size());
 
+  if (clients.size())
+    delete [] windows;
 
-void BScreen::propertyNotifyEvent(const XPropertyEvent *pe) {
-  if (pe->atom == xatom->getAtom(OBAtom::net_desktop_names)) {
-    // _NET_WM_DESKTOP_NAMES
-    WorkspaceList::iterator it = workspacesList.begin();
-    const WorkspaceList::iterator end = workspacesList.end();
-    for (; it != end; ++it) {
-      (*it)->readName(); // re-read its name from the window property
-      //workspacemenu->changeWorkspaceLabel((*it)->getID(), (*it)->getName());
-    }
-    //workspacemenu->update();
-    saveWorkspaceNames();
-  }
+  setStackingList();
 }
 
 
-void BScreen::toggleFocusModel(FocusModel model) {
-  std::for_each(windowList.begin(), windowList.end(),
-                std::mem_fun(&BlackboxWindow::ungrabButtons));
+void OBScreen::setStackingList()
+{
+  // The below comment is wrong now hopefully :> but ill keep it here for
+  // reference anyways
+  /*
+    Get the stacking order from all of the workspaces.
+    We start with the current workspace so that the sticky windows will be
+    in the right order on the current workspace.
+  */
+  /*
+  Openbox::instance->property()->set(_info->getRootWindow(),
+                                     otk::OBProperty::net_client_list_stacking,
+                                     otk::OBProperty::Atom_Window,
+                                     _stacking, _stacking.size());
+  */
+}
 
-  if (model == SloppyFocus) {
-    saveSloppyFocus(True);
-  } else {
-    // we're cheating here to save writing the config file 3 times
-    resource.auto_raise = False;
-    resource.click_raise = False;
-    saveSloppyFocus(False);
-  }
 
-  std::for_each(windowList.begin(), windowList.end(),
-                std::mem_fun(&BlackboxWindow::grabButtons));
+void OBScreen::setWorkArea() {
+  unsigned long area[] = { _area.x(), _area.y(),
+                           _area.width(), _area.height() };
+  Openbox::instance->property()->set(_info->rootWindow(),
+                                     otk::OBProperty::net_workarea,
+                                     otk::OBProperty::Atom_Cardinal,
+                                     area, 4);
+  /*
+  if (workspacesList.size() > 0) {
+    unsigned long *dims = new unsigned long[4 * workspacesList.size()];
+    for (unsigned int i = 0, m = workspacesList.size(); i < m; ++i) {
+      // XXX: this could be different for each workspace
+      const otk::Rect &area = availableArea();
+      dims[(i * 4) + 0] = area.x();
+      dims[(i * 4) + 1] = area.y();
+      dims[(i * 4) + 2] = area.width();
+      dims[(i * 4) + 3] = area.height();
+    }
+    xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
+               otk::OBProperty::Atom_Cardinal,
+               dims, 4 * workspacesList.size());
+    delete [] dims;
+  } else
+    xatom->set(getRootWindow(), otk::OBProperty::net_workarea,
+               otk::OBProperty::Atom_Cardinal, 0, 0);
+  */
 }
 
-void BScreen::readDatabaseMask(const string &rname, PixmapMask &pixmapMask,
-                               const Configuration &style) {
-  string s;
-  int hx, hy; //ignored
-  int ret = BitmapOpenFailed; //default to failure.
-  
-  if (style.getValue(rname, s))
-  {
-    if (s[0] != '/' && s[0] != '~')
-    {
-      std::string xbmFile = std::string("~/.openbox/buttons/") + s;
-      ret = XReadBitmapFile(otk::OBDisplay::display, getRootWindow(),
-                            expandTilde(xbmFile).c_str(), &pixmapMask.w,
-                            &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
-    } else
-      ret = XReadBitmapFile(otk::OBDisplay::display, getRootWindow(),
-                            expandTilde(s).c_str(), &pixmapMask.w,
-                            &pixmapMask.h, &pixmapMask.mask, &hx, &hy);
-    
-    if (ret == BitmapSuccess)
-      return;
-  }
 
-  pixmapMask.mask = None;
-  pixmapMask.w = pixmapMask.h = 0;
-}
+void OBScreen::manageWindow(Window window)
+{
+  OBClient *client = 0;
+  XWMHints *wmhint;
+  XSetWindowAttributes attrib_set;
 
-otk::BTexture BScreen::readDatabaseTexture(const string &rname,
-                                           const string &default_color,
-                                           const Configuration &style, 
-                                           bool allowNoTexture) {
-  otk::BTexture texture;
-  string s;
-
-  if (style.getValue(rname, s))
-    texture = otk::BTexture(s);
-  else if (allowNoTexture) //no default
-    texture.setTexture(otk::BTexture::NoTexture);
-  else
-    texture.setTexture(otk::BTexture::Solid | otk::BTexture::Flat);
-
-  // associate this texture with this screen
-  texture.setScreen(getScreenNumber());
-  texture.setImageControl(image_control);
-
-  if (texture.texture() != otk::BTexture::NoTexture) {
-    texture.setColor(readDatabaseColor(rname + ".color", default_color,
-                                       style));
-    texture.setColorTo(readDatabaseColor(rname + ".colorTo", default_color,
-                                         style));
-    texture.setBorderColor(readDatabaseColor(rname + ".borderColor",
-                                             default_color, style));
+  // is the window a docking app
+  if ((wmhint = XGetWMHints(otk::OBDisplay::display, window))) {
+    if ((wmhint->flags & StateHint) &&
+        wmhint->initial_state == WithdrawnState) {
+      //slit->addClient(w); // XXX: make dock apps work!
+      XFree(wmhint);
+      return;
+    }
+    XFree(wmhint);
   }
 
-  return texture;
-}
+  otk::OBDisplay::grab();
 
+  // choose the events we want to receive on the CLIENT window
+  attrib_set.event_mask = OBClient::event_mask;
+  attrib_set.do_not_propagate_mask = OBClient::no_propagate_mask;
+  XChangeWindowAttributes(otk::OBDisplay::display, window,
+                          CWEventMask|CWDontPropagate, &attrib_set);
 
-otk::BColor BScreen::readDatabaseColor(const string &rname,
-                                       const string &default_color,
-                                       const Configuration &style) {
-  otk::BColor color;
-  string s;
-  if (style.getValue(rname, s))
-    color = otk::BColor(s, getScreenNumber());
-  else
-    color = otk::BColor(default_color, getScreenNumber());
-  return color;
-}
+  // create the OBClient class, which gets all of the hints on the window
+  client = new OBClient(_number, window);
+  // register for events
+  Openbox::instance->registerHandler(window, client);
+  // add to the wm's map
+  Openbox::instance->addClient(window, client);
 
+  // we dont want a border on the client
+  client->toggleClientBorder(false);
+  
+  // specify that if we exit, the window should not be destroyed and should be
+  // reparented back to root automatically
+  XChangeSaveSet(otk::OBDisplay::display, window, SetModeInsert);
+
+  if (!client->positionRequested()) {
+    // XXX: position the window intelligenty
+  }
+
+  // create the decoration frame for the client window
+  client->frame = new OBFrame(client, &_style);
+
+  // add to the wm's map
+  Openbox::instance->addClient(client->frame->window(), client);
+  Openbox::instance->addClient(client->frame->plate(), client);
+  Openbox::instance->addClient(client->frame->titlebar(), client);
+  Openbox::instance->addClient(client->frame->label(), client);
+  Openbox::instance->addClient(client->frame->button_max(), client);
+  Openbox::instance->addClient(client->frame->button_iconify(), client);
+  Openbox::instance->addClient(client->frame->button_stick(), client);
+  Openbox::instance->addClient(client->frame->button_close(), client);
+  Openbox::instance->addClient(client->frame->handle(), client);
+  Openbox::instance->addClient(client->frame->grip_left(), client);
+  Openbox::instance->addClient(client->frame->grip_right(), client);
+
+  // XXX: if on the current desktop..
+  client->frame->show();
+  // XXX: handle any requested states such as shaded/maximized
+
+  otk::OBDisplay::ungrab();
+
+  // add to the screen's list
+  clients.push_back(client);
+  // update the root properties
+  setClientList();
+}
+
+
+void OBScreen::unmanageWindow(OBClient *client)
+{
+  OBFrame *frame = client->frame;
+
+  // XXX: pass around focus if this window was focused
+
+  // remove from the wm's map
+  Openbox::instance->removeClient(client->window());
+  Openbox::instance->removeClient(frame->window());
+  Openbox::instance->removeClient(frame->plate());
+  Openbox::instance->removeClient(frame->titlebar());
+  Openbox::instance->removeClient(frame->label());
+  Openbox::instance->removeClient(frame->button_max());
+  Openbox::instance->removeClient(frame->button_iconify());
+  Openbox::instance->removeClient(frame->button_stick());
+  Openbox::instance->removeClient(frame->button_close());
+  Openbox::instance->removeClient(frame->handle());
+  Openbox::instance->removeClient(frame->grip_left());
+  Openbox::instance->removeClient(frame->grip_right());
+  // unregister for handling events
+  Openbox::instance->clearHandler(client->window());
+  
+  // remove the window from our save set
+  XChangeSaveSet(otk::OBDisplay::display, client->window(), SetModeDelete);
 
-otk::BFont *BScreen::readDatabaseFont(const string &rbasename,
-                                      const Configuration &style) {
-  string fontname;
+  // we dont want events no more
+  XSelectInput(otk::OBDisplay::display, client->window(), NoEventMask);
 
-  string s;
+  frame->hide();
 
-  int i;
-  if (style.getValue(rbasename + "xft.font", s) &&
-      style.getValue(rbasename + "xft.size", i)) {
-    string family = s;
-    bool bold = False;
-    bool italic = False;
-    bool dropShadow = False;
+  // give the client its border back
+  client->toggleClientBorder(true);
 
-    if (style.getValue(rbasename + "xft.flags", s)) {
-      if (s.find("bold") != string::npos)
-        bold = True;
-      if (s.find("italic") != string::npos)
-        italic = True;
-      if (s.find("shadow") != string::npos)
-        dropShadow = True;
-    }
-    
-    unsigned char offset = 1;
-    if (style.getValue(rbasename + "xft.shadow.offset", s)) {
-      offset = atoi(s.c_str()); //doesn't detect errors
-      if (offset > CHAR_MAX)
-        offset = 1;
-    }
+  delete client->frame;
+  client->frame = 0;
 
-    unsigned char tint = 0x40;
-    if (style.getValue(rbasename + "xft.shadow.tint", s)) {
-      tint = atoi(s.c_str());
-    }
+  // remove from the screen's list
+  clients.remove(client);
+  delete client;
 
-    
-    otk::BFont *b = new otk::BFont(getScreenNumber(), family, i, bold, italic,
-                                   dropShadow && resource.shadow_fonts,
-                                   offset, tint, resource.aa_fonts);
-    if (b->valid())
-      return b;
-    delete b;
-  }
-    
-  exit(2);  // can't continue without a font
+  // update the root properties
+  setClientList();
 }
 
 }
This page took 0.056708 seconds and 4 git commands to generate.