From 4060a219e649bf2afaaa661334c5fb02fc7d86a2 Mon Sep 17 00:00:00 2001
From: fluxgen <fluxgen>
Date: Sun, 5 Jan 2003 22:22:33 +0000
Subject: major changes to make FluxboxWindow use FbWinFrame and decouple it
 from buttons and menus

---
 src/Window.cc | 2670 ++++++++++++++-------------------------------------------
 1 file changed, 649 insertions(+), 2021 deletions(-)

diff --git a/src/Window.cc b/src/Window.cc
index e54a1de..2a26188 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -1,8 +1,8 @@
 // Window.cc for Fluxbox Window Manager
-// Copyright (c) 2001 - 2002 Henrik Kinnunen (fluxgen@linuxmail.org)
+// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
 //
 // Window.cc for Blackbox - an X11 Window manager
-// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
+// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
 //
 // Permission is hereby granted, free of charge, to any person obtaining a
 // copy of this software and associated documentation files (the "Software"),
@@ -16,13 +16,13 @@
 //
 // 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
+// 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.
 
-// $Id: Window.cc,v 1.107 2002/12/09 14:17:50 rathnor Exp $
+// $Id: Window.cc,v 1.108 2003/01/05 22:22:33 fluxgen Exp $
 
 #include "Window.hh"
 
@@ -35,15 +35,13 @@
 #include "StringUtil.hh"
 #include "Netizen.hh"
 #include "ImageControl.hh"
+#include "FbWinFrameTheme.hh"
+
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif // HAVE_CONFIG_H
 
-#ifdef SLIT
-#include "Slit.hh"
-#endif // SLIT
-
 //use GNU extensions
 #ifndef	 _GNU_SOURCE
 #define	 _GNU_SOURCE
@@ -58,152 +56,142 @@
 
 using namespace std;
 
-FluxboxWindow::FluxboxWindow(Window w, BScreen *s):
+namespace {
+
+void grabButton(Display *display, unsigned int button, 
+                               Window window, Cursor cursor) {
+
+    //numlock
+    XGrabButton(display, button, Mod1Mask|Mod2Mask, window, True,
+                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+                GrabModeAsync, None, cursor);
+    //scrolllock
+    XGrabButton(display, button, Mod1Mask|Mod5Mask, window, True,
+                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+                GrabModeAsync, None, cursor);
+	
+    //capslock
+    XGrabButton(display, button, Mod1Mask|LockMask, window, True,
+                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+                GrabModeAsync, None, cursor);
+
+    //capslock+numlock
+    XGrabButton(display, Button1, Mod1Mask|LockMask|Mod2Mask, window, True,
+                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+                GrabModeAsync, None, cursor);
+
+    //capslock+scrolllock
+    XGrabButton(display, button, Mod1Mask|LockMask|Mod5Mask, window, True,
+                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+                GrabModeAsync, None, cursor);
+	
+    //capslock+numlock+scrolllock
+    XGrabButton(display, button, Mod1Mask|LockMask|Mod2Mask|Mod5Mask, window, True,
+                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+                GrabModeAsync, None, cursor);
+
+    //numlock+scrollLock
+    XGrabButton(display, button, Mod1Mask|Mod2Mask|Mod5Mask, window, True,
+                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
+                GrabModeAsync, None, cursor);
+	
+}
+
+};
+
+FluxboxWindow::FluxboxWindow(Window w, BScreen *s, int screen_num, BImageControl &imgctrl, FbWinFrameTheme &tm):
     m_hintsig(*this),
     m_statesig(*this),
     m_workspacesig(*this),
-    image_ctrl(0),
+    m_diesig(*this),
     moving(false), resizing(false), shaded(false), maximized(false),
     visible(false), iconic(false), transient(false), focused(false),
-    stuck(false), modal(false), send_focus_message(false), managed(false),
-    screen(0),
+    stuck(false), modal(false), send_focus_message(false), m_managed(false),
+    screen(s),
     timer(this),
     display(0),
     lastButtonPressTime(0),
     m_windowmenu(0),
     m_layer(LAYER_NORMAL), old_decoration(DECOR_NORMAL),
-    tab(0) {
-	
+    tab(0),
+    m_frame(tm, imgctrl, screen_num, 0, 0, 100, 100) {
+
+    // redirect events from frame to us
+    m_frame.setEventHandler(*this); 
+
     lastFocusTime.tv_sec = lastFocusTime.tv_usec = 0;
-#ifdef DEBUG
-    fprintf(stderr,
-            I18n::instance()->
-            getMessage(
-                FBNLS::WindowSet, FBNLS::WindowCreating,
-                "FluxboxWindow::FluxboxWindow(): creating 0x%lx\n"),
-            w);
 
-#endif //DEBUG
+    // display connection
+    display = FbTk::App::instance()->display();
 
-    Fluxbox *fluxbox = Fluxbox::instance();
-    display = fluxbox->getXDisplay();
-	
     blackbox_attrib.workspace = workspace_number = window_number = -1;
 
-    blackbox_attrib.flags = blackbox_attrib.attrib = blackbox_attrib.stack = 0l;
+    blackbox_attrib.flags = blackbox_attrib.attrib = blackbox_attrib.stack = 0;
     blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
     blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
+
     //use tab as default
     decorations.tab = true;
+    // enable decorations
     decorations.enabled = true;
+    // set client window
     client.window = w;
-    frame.window = frame.plate = frame.title = frame.handle = None;
-    frame.right_grip = frame.left_grip = None;
-
-    frame.utitle = frame.ftitle = frame.uhandle = frame.fhandle = None;
-    frame.ulabel = frame.flabel = frame.ubutton = frame.fbutton = None;
-    frame.pbutton = frame.ugrip = frame.fgrip = None;
-
-    //get decorations
-    vector<Fluxbox::Titlebar> dir = fluxbox->getTitlebarLeft();
-    for (char c=0; c<2; c++) {
-        for (unsigned int i=0; i<dir.size(); i++) {
-            switch (dir[i]) {
-            case Fluxbox::SHADE:
-                decorations.shade = true;
-                break;
-            case Fluxbox::MAXIMIZE:
-                decorations.maximize = true;	
-                break;
-            case Fluxbox::MINIMIZE:
-                decorations.iconify = true;			
-                break;
-            case Fluxbox::STICK:
-                decorations.sticky = true;
-                break;
-            case Fluxbox::CLOSE:
-                decorations.close = true;
-                break;
-            case Fluxbox::MENU:
-                decorations.menu = true;
-                break;
-            default:
-                break;
-            }
-        }
-        //next right
-        dir = fluxbox->getTitlebarRight();
-    }
-	
+
+    // set default values for decoration
     decorations.menu = true;	//override menu option
-	
+    // all decorations on by default
     decorations.titlebar = decorations.border = decorations.handle = true;
+    decorations.maximize = decorations.close = decorations.sticky = decorations.shade =
+	decorations.tab = true;
+
+
     functions.resize = functions.move = functions.iconify = functions.maximize = true;
     functions.close = decorations.close = false;
 
     client.wm_hint_flags = client.normal_hint_flags = 0;
     client.transient_for = 0;
-    client.mwm_hint = (MwmHints *) 0;
+    client.mwm_hint = 0;
     client.blackbox_hint = 0;
+    Fluxbox *fluxbox = Fluxbox::instance();
 
-    fluxbox->grab();
-    if (! validateClient())
-        return;
+    getBlackboxHints();
+    if (! client.blackbox_hint)
+        getMWMHints();
+    
+    // get size, aspect, minimum/maximum size and other hints set
+    // by the client
+    getWMProtocols();
+    getWMHints(); 
+    getWMNormalHints();
 
     // fetch client size and placement
     XWindowAttributes wattrib;
     if ((! XGetWindowAttributes(display, client.window, &wattrib)) ||
-        (! wattrib.screen) || wattrib.override_redirect) {
-        fluxbox->ungrab();
+        !wattrib.screen // no screen?
+        || wattrib.override_redirect) { // override redirect
         return;
     }
 
-    if (s)
-        screen = s;
-    else
-        screen = fluxbox->searchScreen(RootWindowOfScreen(wattrib.screen));
-
-    if (!screen) {
-        fluxbox->ungrab();
-        return;
-    }
-	
-    image_ctrl = screen->getImageControl();
-
-    client.x = wattrib.x;
-    client.y = wattrib.y;
+    // save old border width so we can restore it later
+    client.old_bw = wattrib.border_width;
+    client.x = wattrib.x; client.y = wattrib.y;
     client.width = wattrib.width;
     client.height = wattrib.height;
-    client.old_bw = wattrib.border_width;
 
+    m_frame.move(wattrib.x, wattrib.y);
+    m_frame.resizeForClient(wattrib.width, wattrib.height);
 
     timer.setTimeout(fluxbox->getAutoRaiseDelay());
     timer.fireOnce(true);
 
-    getBlackboxHints();
-    if (! client.blackbox_hint)
-        getMWMHints();
-
-    // get size, aspect, minimum/maximum size and other hints set by the
-    // client
-    getWMProtocols();
-    getWMHints();
-    getWMNormalHints();
-#ifdef SLIT
-
     if (client.initial_state == WithdrawnState) {
-        screen->getSlit()->addClient(client.window);
-        fluxbox->ungrab();
         return;
     }
-#endif // SLIT
-
-    managed = true; //mark for usage
-
-    fluxbox->saveWindowSearch(client.window, this);
 
-    // determine if this is a transient window
-    checkTransient();
+    m_managed = true; //this window is managed
+	
+    // update transient infomation
+    updateTransientInfo();
 	
     // adjust the window decorations based on transience and window sizes
     if (transient) {
@@ -228,15 +216,9 @@ FluxboxWindow::FluxboxWindow(Window w, BScreen *s):
         setGravityOffsets();
 
         if (! fluxbox->isStartup()) {
-#ifdef XINERAMA
-            unsigned int head = 0;
-            if (screen->hasXinerama()) {
-                head = screen->getHead(frame.x, frame.y);
-            }
-#endif // XINERAMA
 
-            int real_x = frame.x;
-            int real_y = frame.y;
+            int real_x = m_frame.x();
+            int real_y = m_frame.y();
 
             if (decorations.tab) {
                 if (screen->getTabPlacement() == Tab::PTOP) {
@@ -248,63 +230,25 @@ FluxboxWindow::FluxboxWindow(Window w, BScreen *s):
                 }
             }
 
-#ifdef XINERAMA
-            // check is within the current head, so it won't overlap heads
-            if (real_x >= screen->getHeadX(head) && 
-                real_y + frame.y_border >= screen->getHeadY(head) &&
-                (real_x + frame.width) <=
-                (screen->getHeadX(head) + screen->getHeadWidth(head)) &&
-                (real_y + frame.height) <=
-                (screen->getHeadY(head) + screen->getHeadHeight(head)) )
-                place_window = false;
-#else // !XINERAMA
             if (real_x >= 0 && 
-                real_y + frame.y_border >= 0 &&
+                real_y + m_frame.y() >= 0 &&
                 real_x <= (signed) screen->getWidth() &&
                 real_y <= (signed) screen->getHeight())
                 place_window = false;
-#endif // XIENRAMA
 
         } else
             place_window = false;
 
     }
 
-    frame.window = createToplevelWindow(frame.x, frame.y, frame.width,
-                                        frame.height,
-                                        screen->getBorderWidth());	//create frame window
-	
-    fluxbox->saveWindowSearch(frame.window, this);	//save frame window
-
-    frame.plate = createChildWindow(frame.window); //Create plate window
-    fluxbox->saveWindowSearch(frame.plate, this);	//save plate window
-	
-    createTitlebar();
-    createHandle();
-
     associateClientWindow();
 
     grabButtons();
 				
     positionWindows();
 
-    // use tab? and don't create a tab on windows that's not
-    // maximizable as default (such as dialogs)
-    if (decorations.tab && fluxbox->useTabs() && isGroupable())
-        tab = new Tab(this, 0, 0);
-
-    decorate();
-	
-    XRaiseWindow(display, frame.plate);
-    XMapSubwindows(display, frame.plate);
-    if (decorations.titlebar)
-        XMapSubwindows(display, frame.title);
-	
-    XMapSubwindows(display, frame.window);
-
     if (decorations.menu) {
-        std::auto_ptr<Windowmenu> tmp(new Windowmenu(*this));
-        m_windowmenu = tmp;
+        m_windowmenu.reset(new Windowmenu(*this));
     }
 
     if (workspace_number < 0 || workspace_number >= screen->getCount())
@@ -312,38 +256,40 @@ FluxboxWindow::FluxboxWindow(Window w, BScreen *s):
     else
         screen->getWorkspace(workspace_number)->addWindow(this, place_window);
 
-    configure(frame.x, frame.y, frame.width, frame.height);
+    moveResize(m_frame.x(), m_frame.y(), m_frame.width(), m_frame.height());
 
-    if (shaded) {
+    if (shaded) { // start shaded
         shaded = false;
         shade();
     }
 
-    if (maximized && functions.maximize) {
-        int m = maximized;
+    if (maximized && functions.maximize) { // start maximized
         maximized = false;
-        maximize(m);
+        maximize();
     }	
 
     if (stuck) {
         stuck = false;
         stick();
-        deiconify(); //omnipresent, so show it
+        deiconify(); //we're omnipresent and visible
     }
 
+    // no focus default
     setFocusFlag(false);
 
-#ifdef DEBUG
-    fprintf(stderr, "%s(%d): FluxboxWindow(this=%p)\n", __FILE__, __LINE__, this);
-#endif // DEBUG
+    // finaly show the frame and the client window
+    m_frame.show();
 
-    fluxbox->ungrab();
 }
 
 
 FluxboxWindow::~FluxboxWindow() {
+    // notify die
+    m_diesig.notify();
+
     if (screen == 0) //the window wasn't created 
         return;
+
     timer.stop();
 
     Fluxbox *fluxbox = Fluxbox::instance();
@@ -399,40 +345,9 @@ FluxboxWindow::~FluxboxWindow() {
         fluxbox->removeGroupSearch(client.window_group);
         client.window_group = 0;
     }
-		
-    destroyTitlebar();	
-
-    destroyHandle();
-
-    if (frame.fbutton) {
-        image_ctrl->removeImage(frame.fbutton);
-        frame.fbutton = 0;
-    }
 
-    if (frame.ubutton) {
-        image_ctrl->removeImage(frame.ubutton);
-        frame.ubutton = 0;
-    }
-
-    if (frame.pbutton) {
-        image_ctrl->removeImage(frame.pbutton);
-        frame.pbutton = 0;
-    }
-
-	
-    if (frame.plate) {
-        fluxbox->removeWindowSearch(frame.plate);
-        XDestroyWindow(display, frame.plate);
-        frame.plate = 0;
-    }
-
-    if (frame.window) {
-        fluxbox->removeWindowSearch(frame.window);
-        XDestroyWindow(display, frame.window);
-        frame.window = 0;
-    }
-
-    fluxbox->removeWindowSearch(client.window);
+    if (client.window)
+        fluxbox->removeWindowSearch(client.window);
 
 #ifdef DEBUG
     cerr<<__FILE__<<"("<<__LINE__<<"): ~FluxboxWindow("<<this<<")"<<endl;
@@ -445,584 +360,60 @@ bool FluxboxWindow::isGroupable() const {
     return false;
 }
 
-Window FluxboxWindow::createToplevelWindow(
-    int x, int y, unsigned int width,
-    unsigned int height,
-    unsigned int borderwidth)
-{
-    XSetWindowAttributes attrib_create;
-    unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWColormap |
-        CWOverrideRedirect | CWEventMask;
-
-    attrib_create.background_pixmap = None;
-    attrib_create.colormap = screen->colormap();
-    attrib_create.override_redirect = True;
-    attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
-        ButtonMotionMask | EnterWindowMask;
-
-    return (XCreateWindow(display, screen->getRootWindow(), x, y, width, height,
-                          borderwidth, screen->getDepth(), InputOutput,
-                          screen->getVisual(), create_mask,
-                          &attrib_create));
-}
-
-
-Window FluxboxWindow::createChildWindow(Window parent, Cursor cursor) {
-    XSetWindowAttributes attrib_create;
-    unsigned long create_mask = CWBackPixmap | CWBorderPixel | CWEventMask;
-
-    attrib_create.background_pixmap = None;
-    attrib_create.event_mask = ButtonPressMask | ButtonReleaseMask |
-        ButtonMotionMask | ExposureMask |
-        EnterWindowMask | LeaveWindowMask;
-
-    if (cursor) {
-        create_mask |= CWCursor;
-        attrib_create.cursor = cursor;
-    }
-
-    return (XCreateWindow(display, parent, 0, 0, 1, 1, 0,
-                          screen->getDepth(), InputOutput, screen->getVisual(),
-                          create_mask, &attrib_create));
-}
-
-
 void FluxboxWindow::associateClientWindow() {
     XSetWindowBorderWidth(display, client.window, 0);
-    getWMName();
-    getWMIconName();
-
-    XChangeSaveSet(display, client.window, SetModeInsert);
-    XSetWindowAttributes attrib_set;
-
-    XSelectInput(display, frame.plate, NoEventMask);
-    XReparentWindow(display, client.window, frame.plate, 0, 0);
-    XSelectInput(display, frame.plate, SubstructureRedirectMask);
-
-    XFlush(display);
-
-    attrib_set.event_mask = 
-        PropertyChangeMask | StructureNotifyMask | FocusChangeMask;
-    attrib_set.do_not_propagate_mask = 
-        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask;
-
-    XChangeWindowAttributes(display, client.window, CWEventMask|CWDontPropagate,
-                            &attrib_set);
-
-#ifdef		SHAPE
-    if (Fluxbox::instance()->hasShapeExtensions()) {
-        XShapeSelectInput(display, client.window, ShapeNotifyMask);
-
-        int foo;
-        unsigned int ufoo;
-
-        XShapeQueryExtents(display, client.window, &frame.shaped, &foo, &foo,
-                           &ufoo, &ufoo, &foo, &foo, &foo, &ufoo, &ufoo);
-
-        if (frame.shaped) {
-            XShapeCombineShape(display, frame.window, ShapeBounding,
-                               frame.mwm_border_w, frame.y_border +
-                               frame.mwm_border_w, client.window,
-                               ShapeBounding, ShapeSet);
-
-            int num = 1;
-            XRectangle xrect[2];
-            xrect[0].x = xrect[0].y = 0;
-            xrect[0].width = frame.width;
-            xrect[0].height = frame.y_border;
-
-            if (decorations.handle) {
-                xrect[1].x = 0;
-                xrect[1].y = frame.y_handle;
-                xrect[1].width = frame.width;
-                xrect[1].height = frame.handle_h + screen->getBorderWidth();
-                num++;
-            }
+    updateTitleFromClient();
+    updateIconNameFromClient();
 
-            XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
-                                    xrect, num, ShapeUnion, Unsorted);
-        }
-    }
-#endif // SHAPE
-    //create the buttons
-    if (decorations.iconify) 
-        createButton(Fluxbox::MINIMIZE, FluxboxWindow::iconifyPressed_cb, 
-                     FluxboxWindow::iconifyButton_cb, FluxboxWindow::iconifyDraw_cb);
-    if (decorations.maximize)
-        createButton(Fluxbox::MAXIMIZE, FluxboxWindow::maximizePressed_cb, 
-                     FluxboxWindow::maximizeButton_cb, FluxboxWindow::maximizeDraw_cb);
-    if (decorations.close) 
-        createButton(Fluxbox::CLOSE, FluxboxWindow::closePressed_cb, 
-                     FluxboxWindow::closeButton_cb, FluxboxWindow::closeDraw_cb);		
-    if (decorations.sticky)
-        createButton(Fluxbox::STICK, FluxboxWindow::stickyPressed_cb, 
-                     FluxboxWindow::stickyButton_cb, FluxboxWindow::stickyDraw_cb);
-
-    if (decorations.menu)//TODO
-        createButton(Fluxbox::MENU, 0, 0, 0);
-
-    if (decorations.shade)
-        createButton(Fluxbox::SHADE, 0, FluxboxWindow::shadeButton_cb, FluxboxWindow::shadeDraw_cb);
-
-    if (frame.ubutton) {
-        for (unsigned int i=0; i<buttonlist.size(); i++)
-            XSetWindowBackgroundPixmap(display, buttonlist[i].win, frame.ubutton);	 
-	
-    } else {
-        for (unsigned int i=0; i<buttonlist.size(); i++)
-            XSetWindowBackground(display, buttonlist[i].win, frame.ubutton_pixel);	 
-    }
-}
-
-
-void FluxboxWindow::decorate() {
-		
-    if (tab)
-        tab->decorate();
-
-    Pixmap tmp = frame.fbutton;
-    const FbTk::Texture *texture = &(screen->getWindowStyle()->b_focus);
-    if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-        frame.fbutton = None;
-        frame.fbutton_pixel = texture->color().pixel();
-    } else
-        frame.fbutton =
-            image_ctrl->renderImage(frame.button_w, frame.button_h, *texture);
-    if (tmp) image_ctrl->removeImage(tmp);
-
-    tmp = frame.ubutton;
-    texture = &(screen->getWindowStyle()->b_unfocus);
-    if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-        frame.ubutton = None;
-        frame.ubutton_pixel = texture->color().pixel();
-    } else
-        frame.ubutton =
-            image_ctrl->renderImage(frame.button_w, frame.button_h, *texture);
-    if (tmp) image_ctrl->removeImage(tmp);
-
-    tmp = frame.pbutton;
-    texture = &(screen->getWindowStyle()->b_pressed);
-    if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-        frame.pbutton = None;
-        frame.pbutton_pixel = texture->color().pixel();
-    } else
-        frame.pbutton =
-            image_ctrl->renderImage(frame.button_w, frame.button_h, *texture);
-    if (tmp) image_ctrl->removeImage(tmp);
+    m_frame.setClientWindow(client.window);
 
-    if (decorations.titlebar) {
-        tmp = frame.ftitle;
-        texture = &(screen->getWindowStyle()->t_focus);
-        if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-            frame.ftitle = None;
-            frame.ftitle_pixel = texture->color().pixel();
-        } else
-            frame.ftitle =
-                image_ctrl->renderImage(frame.width, frame.title_h, *texture);
-		
-        if (tmp) 
-            image_ctrl->removeImage(tmp);
-
-        tmp = frame.utitle;
-        texture = &(screen->getWindowStyle()->t_unfocus);
-        if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-            frame.utitle = None;
-            frame.utitle_pixel = texture->color().pixel();
-        } else
-            frame.utitle =
-                image_ctrl->renderImage(frame.width, frame.title_h, *texture);
-        if (tmp) image_ctrl->removeImage(tmp);
-
-        XSetWindowBorder(display, frame.title,
-			 screen->getBorderColor()->pixel());
-
-        decorateLabel();
-		
-    }
-
-    if (decorations.border) {
-        frame.fborder_pixel = screen->getWindowStyle()->f_focus.pixel();
-        frame.uborder_pixel = screen->getWindowStyle()->f_unfocus.pixel();
-    }
-
-    if (decorations.handle) {
-        tmp = frame.fhandle;
-        texture = &(screen->getWindowStyle()->h_focus);
-        if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-            frame.fhandle = None;
-            frame.fhandle_pixel = texture->color().pixel();
-        } else
-            frame.fhandle =
-                image_ctrl->renderImage(frame.width, frame.handle_h, *texture);
-        if (tmp) image_ctrl->removeImage(tmp);
-
-        tmp = frame.uhandle;
-        texture = &(screen->getWindowStyle()->h_unfocus);
-        if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-            frame.uhandle = None;
-            frame.uhandle_pixel = texture->color().pixel();
-        } else
-            frame.uhandle =
-                image_ctrl->renderImage(frame.width, frame.handle_h, *texture);
-        if (tmp)
-            image_ctrl->removeImage(tmp);
-
-        tmp = frame.fgrip;
-        texture = &(screen->getWindowStyle()->g_focus);
-        if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-            frame.fgrip = None;
-            frame.fgrip_pixel = texture->color().pixel();
-        } else
-            frame.fgrip =
-                image_ctrl->renderImage(frame.grip_w, frame.grip_h, *texture);
-        if (tmp)
-            image_ctrl->removeImage(tmp);
-
-        tmp = frame.ugrip;
-        texture = &(screen->getWindowStyle()->g_unfocus);
-        if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-            frame.ugrip = None;
-            frame.ugrip_pixel = texture->color().pixel();
-        } else
-            frame.ugrip =
-                image_ctrl->renderImage(frame.grip_w, frame.grip_h, *texture);
-        if (tmp) image_ctrl->removeImage(tmp);
-
-        XSetWindowBorder(display, frame.handle,
-                         screen->getBorderColor()->pixel());
-        XSetWindowBorder(display, frame.left_grip,
-                         screen->getBorderColor()->pixel());
-        XSetWindowBorder(display, frame.right_grip,
-                         screen->getBorderColor()->pixel());
-    }
-		
-    XSetWindowBorder(display, frame.window,
-                     screen->getBorderColor()->pixel());
+    // make sure the frame reconfigures
+    m_frame.reconfigure();
 }
 
 
-void FluxboxWindow::decorateLabel() {
-    Pixmap tmp = frame.flabel;
-    FbTk::Texture *texture = &(screen->getWindowStyle()->l_focus);
-    if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-        frame.flabel = None;
-        frame.flabel_pixel = texture->color().pixel();		
-    } else
-        frame.flabel = image_ctrl->renderImage(frame.label_w, frame.label_h, *texture);
-			
-    if (tmp) image_ctrl->removeImage(tmp);
-
-    tmp = frame.ulabel;
-    texture = &(screen->getWindowStyle()->l_unfocus);
-    if (texture->type() == (FbTk::Texture::FLAT | FbTk::Texture::SOLID)) {
-        frame.ulabel = None;
-        frame.ulabel_pixel = texture->color().pixel();
-    } else
-        frame.ulabel = image_ctrl->renderImage(frame.label_w, frame.label_h, *texture);
-		
-    if (tmp) image_ctrl->removeImage(tmp);
-}
-
 void FluxboxWindow::grabButtons() {
     Fluxbox *fluxbox = Fluxbox::instance();
 
     XGrabButton(display, Button1, AnyModifier, 
-		frame.plate, True, ButtonPressMask,
+		m_frame.clientArea().window(), True, ButtonPressMask,
 		GrabModeSync, GrabModeSync, None, None);		
-    XUngrabButton(display, Button1, Mod1Mask|Mod2Mask|Mod3Mask, frame.plate);
+    XUngrabButton(display, Button1, Mod1Mask|Mod2Mask|Mod3Mask, m_frame.clientArea().window());
 
 
-    XGrabButton(display, Button1, Mod1Mask, frame.window, True,
+    XGrabButton(display, Button1, Mod1Mask, m_frame.window().window(), True,
 		ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 		GrabModeAsync, None, fluxbox->getMoveCursor());
 
     //----grab with "all" modifiers
-    grabButton(display, Button1, frame.window, fluxbox->getMoveCursor());
+    grabButton(display, Button1, m_frame.window().window(), fluxbox->getMoveCursor());
 	
-    XGrabButton(display, Button2, Mod1Mask, frame.window, True,
+    XGrabButton(display, Button2, Mod1Mask, m_frame.window().window(), True,
 		ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None);
 		
-    XGrabButton(display, Button3, Mod1Mask, frame.window, True,
+    XGrabButton(display, Button3, Mod1Mask, m_frame.window().window(), True,
 		ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
 		GrabModeAsync, None, fluxbox->getLowerRightAngleCursor());
 	
     //---grab with "all" modifiers
-    grabButton(display, Button3, frame.window, fluxbox->getLowerRightAngleCursor());
-}
-
-void FluxboxWindow::createButton(int type, ButtonEventProc pressed, ButtonEventProc released, ButtonDrawProc draw) {
-    Button b;
-    b.win = createChildWindow(frame.title);
-    Fluxbox::instance()->saveWindowSearch(b.win, this);
-    b.type = type;
-    b.used = true;
-    b.draw = draw;
-    b.pressed = pressed;
-    b.released = released;
-    buttonlist.push_back(b);
-}
-
-
-Window FluxboxWindow::findTitleButton(int type) {
-    for (unsigned int i=0; i<buttonlist.size(); i++) {
-        if (buttonlist[i].type == type)
-            return buttonlist[i].win;
-    }
-    return 0;
-}
-void FluxboxWindow::stickyButton_cb(FluxboxWindow *t, XButtonEvent *be) {
-    t->stick();
-    FluxboxWindow::stickyDraw_cb(t, be->window, false);
-}
-
-void FluxboxWindow::stickyPressed_cb(FluxboxWindow *t, XButtonEvent *be) {
-    FluxboxWindow::stickyDraw_cb(t, be->window, true);
-}
-
-void FluxboxWindow::iconifyButton_cb(FluxboxWindow *t, XButtonEvent *be) {
-    t->iconify();
-    FluxboxWindow::iconifyDraw_cb(t, be->window, false);
-}
-
-void FluxboxWindow::iconifyPressed_cb(FluxboxWindow *t, XButtonEvent *be) {
-    t->screen->getWorkspace(t->workspace_number)->lowerWindow(t);
-    FluxboxWindow::iconifyDraw_cb(t, be->window, true);
-}
-
-void FluxboxWindow::maximizeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
-    FluxboxWindow::maximizeDraw_cb(t, be->window, false);
-    t->maximize(be->button); 
-}
-
-void FluxboxWindow::maximizePressed_cb(FluxboxWindow *t, XButtonEvent *be) {
-    FluxboxWindow::maximizeDraw_cb(t, be->window, true); 
-}
-
-void FluxboxWindow::closeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
-    t->close();
-    FluxboxWindow::closeDraw_cb(t, be->window, false);
-}
-
-void FluxboxWindow::closePressed_cb(FluxboxWindow *t, XButtonEvent *be) {
-    FluxboxWindow::closeDraw_cb(t, be->window, true);
-}
-
-void FluxboxWindow::shadeButton_cb(FluxboxWindow *t, XButtonEvent *be) {
-    FluxboxWindow::shadeDraw_cb(t, be->window, false);
-    t->shade();
-    if (t->tab)
-        t->tab->shade();
-}
-
-void FluxboxWindow::stickyDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
-    t->drawButtonBase(w, pressed);
-    if (t->stuck) {
-        XFillRectangle(t->display, w, 
-                       ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
-			t->screen->getWindowStyle()->b_pic_unfocus_gc),
-                       t->frame.button_w/2-t->frame.button_w/4, t->frame.button_h/2-t->frame.button_h/4,
-                       t->frame.button_w/2, t->frame.button_h/2);
-    } else {
-        XFillRectangle(t->display, w, 
-                       ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
-			t->screen->getWindowStyle()->b_pic_unfocus_gc),
-                       t->frame.button_w/2, t->frame.button_h/2,
-                       t->frame.button_w/5, t->frame.button_h/5);
-    }
-}
-
-void FluxboxWindow::iconifyDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
-    t->drawButtonBase(w, pressed);
-    XDrawRectangle(t->display, w,
-                   ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
-                    t->screen->getWindowStyle()->b_pic_unfocus_gc),
-                   2, t->frame.button_h - 5, t->frame.button_w - 5, 2);
-}
-
-void FluxboxWindow::maximizeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
-    t->drawButtonBase(w, pressed);
-    XDrawRectangle(t->display, w,
-                   ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
-                    t->screen->getWindowStyle()->b_pic_unfocus_gc),
-                   2, 2, t->frame.button_w - 5, t->frame.button_h - 5);
-    XDrawLine(t->display, w,
-              ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
-               t->screen->getWindowStyle()->b_pic_unfocus_gc),
-              2, 3, t->frame.button_w - 3, 3);
-}
-
-void FluxboxWindow::closeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
-    t->drawButtonBase(w, pressed);
-    XDrawLine(t->display, w,
-              ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
-               t->screen->getWindowStyle()->b_pic_unfocus_gc), 2, 2,
-              t->frame.button_w - 3, t->frame.button_h - 3);
-    XDrawLine(t->display, w,
-              ((t->focused) ? t->screen->getWindowStyle()->b_pic_focus_gc :
-               t->screen->getWindowStyle()->b_pic_unfocus_gc), 2,
-              t->frame.button_h - 3,
-              t->frame.button_w - 3, 2);
-}
-
-void FluxboxWindow::shadeDraw_cb(FluxboxWindow *t, Window w, bool pressed) {
-    t->drawButtonBase(w, pressed);
-}
-
-void FluxboxWindow::grabButton(Display *display, unsigned int button, 
-                               Window window, Cursor cursor) {
-
-    //numlock
-    XGrabButton(display, button, Mod1Mask|Mod2Mask, window, True,
-                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
-                GrabModeAsync, None, cursor);
-    //scrolllock
-    XGrabButton(display, button, Mod1Mask|Mod5Mask, window, True,
-                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
-                GrabModeAsync, None, cursor);
-	
-    //capslock
-    XGrabButton(display, button, Mod1Mask|LockMask, window, True,
-                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
-                GrabModeAsync, None, cursor);
-
-    //capslock+numlock
-    XGrabButton(display, Button1, Mod1Mask|LockMask|Mod2Mask, window, True,
-                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
-                GrabModeAsync, None, cursor);
-
-    //capslock+scrolllock
-    XGrabButton(display, button, Mod1Mask|LockMask|Mod5Mask, window, True,
-                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
-                GrabModeAsync, None, cursor);
-	
-    //capslock+numlock+scrolllock
-    XGrabButton(display, button, Mod1Mask|LockMask|Mod2Mask|Mod5Mask, window, True,
-                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
-                GrabModeAsync, None, cursor);
-
-    //numlock+scrollLock
-    XGrabButton(display, button, Mod1Mask|Mod2Mask|Mod5Mask, window, True,
-                ButtonReleaseMask | ButtonMotionMask, GrabModeAsync,
-                GrabModeAsync, None, cursor);
-	
-}
-
-void FluxboxWindow::drawButtonBase(Window w, bool pressed) {
-    if (! pressed) {
-        if (focused) {
-            if (frame.fbutton)
-                XSetWindowBackgroundPixmap(display, w, frame.fbutton);
-            else
-                XSetWindowBackground(display, w, frame.fbutton_pixel);
-        } else {
-            if (frame.ubutton)
-                XSetWindowBackgroundPixmap(display, w, frame.ubutton);
-            else
-                XSetWindowBackground(display, w, frame.ubutton_pixel);
-        }
-    } else {
-        if (frame.pbutton)
-            XSetWindowBackgroundPixmap(display, w, frame.pbutton);
-        else
-            XSetWindowBackground(display, w, frame.pbutton_pixel);
-    }
-    XClearWindow(display, w);
-
-}
-
-void FluxboxWindow::positionButtons(bool redecorate_label) {
-    unsigned int bw = frame.button_w + frame.bevel_w + 1,
-        by = frame.bevel_w + 1, lx = by, lw = frame.width - by;	
-    Fluxbox *fluxbox = Fluxbox::instance();
-    vector<Fluxbox::Titlebar> left = fluxbox->getTitlebarLeft();
-    vector<Fluxbox::Titlebar> right = fluxbox->getTitlebarRight();
-
-    //left side buttons
-    for (unsigned int i=0; i<left.size(); i++) {
-        Window w = findTitleButton(left[i]);	//get Window of button
-        if (w) {
-            XMoveResizeWindow(display, w, lx, by,
-                              frame.button_w, frame.button_h);
-            XMapWindow(display, w);
-            XClearWindow(display, w);
-            lx += bw;
-            lw -= bw;
-        }		
-    }
-	
-    int bx = frame.width - bw;
-
-    //right side buttons
-    for (int i=right.size()-1; i>=0; i--) {
-        Window w = findTitleButton(right[i]);	//get window of button
-        if (w) {
-            XMoveResizeWindow(display, w, bx, by,
-                              frame.button_w, frame.button_h);
-            XMapWindow(display, w);
-            XClearWindow(display, w);
-            bx -= bw;
-            lw -= bw;
-        }
-    }
-	
-    //Draw the label
-    frame.label_w = lw - by;
-    XMoveResizeWindow(display, frame.label, lx, frame.bevel_w,
-                      frame.label_w, frame.label_h);
-    if (redecorate_label) 
-        decorateLabel();
-    if (tab) {
-        tab->setPosition();
-        tab->draw(false);
-    }
-    redrawLabel();
-    redrawAllButtons();
+    grabButton(display, Button3, m_frame.window().window(), fluxbox->getLowerRightAngleCursor());
 }
 
 
 void FluxboxWindow::reconfigure() {
-    upsize();
-	
-    if (Fluxbox::instance()->useTabs()) {
-        //no tab and we allowed to use tab? then create it 
-        if (!tab && isGroupable()) {
-            tab = new Tab(this, 0, 0);		
-            if (current_state == IconicState)
-                tab->iconify();
-            else if (current_state == WithdrawnState)
-                tab->withdraw();
-        }
-    } else {		
-        if (tab != 0) { //got a tab? then destroy it
-            delete tab;
-            tab = 0;
-        }
-    }
-	
-    client.x = frame.x + frame.mwm_border_w + screen->getBorderWidth();
-    client.y = frame.y + frame.y_border + frame.mwm_border_w +
-        screen->getBorderWidth();
-
-    if (getTitle().size() > 0) {
-        client.title_text_w = screen->getWindowStyle()->font.textWidth(getTitle().c_str(), getTitle().size());
 
-        client.title_text_w += (frame.bevel_w * 4);
-    }
+    upsize();
 
-		
     positionWindows();
-    decorate();
 
-				
-    XClearWindow(display, frame.window);
     setFocusFlag(focused);
 
-    configure(frame.x, frame.y, frame.width, frame.height);
+    moveResize(m_frame.x(), m_frame.y(), m_frame.width(), m_frame.height());
 	
     grabButtons();
 
     if (m_windowmenu.get()) {
-        m_windowmenu->move(m_windowmenu->x(), frame.y + frame.title_h);
+        m_windowmenu->move(m_windowmenu->x(), m_frame.y() + m_frame.titleHeight());
         m_windowmenu->reconfigure();
     }
 		
@@ -1031,46 +422,32 @@ void FluxboxWindow::reconfigure() {
 
 
 void FluxboxWindow::positionWindows() {
-    XResizeWindow(display, frame.window, frame.width,
-                  ((shaded) ? frame.title_h : frame.height));
-    XSetWindowBorderWidth(display, frame.window, screen->getBorderWidth());
-    XSetWindowBorderWidth(display, frame.plate, screen->getFrameWidth() *
-                          decorations.border);
-    XMoveResizeWindow(display, frame.plate, 0, frame.y_border,
-                      client.width, client.height);
-    XMoveResizeWindow(display, client.window, 0, 0, client.width, client.height);
 
-    if (decorations.titlebar) {
-        XSetWindowBorderWidth(display, frame.title, screen->getBorderWidth());
-        XMoveResizeWindow(display, frame.title, -screen->getBorderWidth(),
-                          -screen->getBorderWidth(), frame.width, frame.title_h);
+    m_frame.window().setBorderWidth(screen->getBorderWidth());
+    m_frame.clientArea().setBorderWidth(screen->getFrameWidth());
 
-        positionButtons();
-    } else if (frame.title)
-        XUnmapWindow(display, frame.title);
+    if (decorations.titlebar) {
+        m_frame.titlebar().setBorderWidth(screen->getBorderWidth());
+        m_frame.showTitlebar();
+    } else
+        m_frame.hideTitlebar();
 
     if (decorations.handle) {
-        XSetWindowBorderWidth(display, frame.handle, screen->getBorderWidth());
-        XSetWindowBorderWidth(display, frame.left_grip, screen->getBorderWidth());
-        XSetWindowBorderWidth(display, frame.right_grip, screen->getBorderWidth());
-
-        XMoveResizeWindow(display, frame.handle, -screen->getBorderWidth(),
-                          frame.y_handle - screen->getBorderWidth(),
-                          frame.width, frame.handle_h);
-        XMoveResizeWindow(display, frame.left_grip, -screen->getBorderWidth(),
-                          -screen->getBorderWidth(), frame.grip_w, frame.grip_h);
-        XMoveResizeWindow(display, frame.right_grip,
-                          frame.width - frame.grip_w - screen->getBorderWidth(),
-                          -screen->getBorderWidth(), frame.grip_w, frame.grip_h);
-        XMapSubwindows(display, frame.handle);
-    } else if (frame.handle)
-        XUnmapWindow(display, frame.handle);
+        m_frame.handle().setBorderWidth(screen->getBorderWidth());
+        m_frame.gripLeft().setBorderWidth(screen->getBorderWidth());
+        m_frame.gripRight().setBorderWidth(screen->getBorderWidth());
+        m_frame.showHandle();
+    } else 
+        m_frame.hideHandle();
+	
+    m_frame.reconfigure();
+	
     if (tab)
         tab->setPosition();
 }
 
 
-void FluxboxWindow::getWMName() {
+void FluxboxWindow::updateTitleFromClient() {
 
     XTextProperty text_prop;
     char **list;
@@ -1094,23 +471,22 @@ void FluxboxWindow::getWMName() {
             } else
                 client.title = (char *)text_prop.value;
             XFree((char *) text_prop.value);
-        } else
+        } else { // ok, we don't have a name, set default name
             client.title = i18n->getMessage(
-                FBNLS::WindowSet, FBNLS::WindowUnnamed,
-                "Unnamed");
+                                            FBNLS::WindowSet, FBNLS::WindowUnnamed,
+                                            "Unnamed");
+        }
     } else {
         client.title = i18n->getMessage(
-            FBNLS::WindowSet, FBNLS::WindowUnnamed,
-            "Unnamed");
+                                        FBNLS::WindowSet, FBNLS::WindowUnnamed,
+                                        "Unnamed");
     }
-    //Note: repeated?
-    client.title_text_w = screen->getWindowStyle()->font.textWidth(getTitle().c_str(), getTitle().size());
-    client.title_text_w += (frame.bevel_w * 4);
-	
+
+    m_frame.setTitle(client.title);	
 }
 
 
-void FluxboxWindow::getWMIconName() {
+void FluxboxWindow::updateIconNameFromClient() {
 
     XTextProperty text_prop;
     char **list;
@@ -1141,14 +517,15 @@ void FluxboxWindow::getWMIconName() {
 
 
 void FluxboxWindow::getWMProtocols() {
-    Atom *proto;
+    Atom *proto = 0;
     int num_return = 0;
     Fluxbox *fluxbox = Fluxbox::instance();
 
     if (XGetWMProtocols(display, client.window, &proto, &num_return)) {
+
         for (int i = 0; i < num_return; ++i) {
             if (proto[i] == fluxbox->getWMDeleteAtom())
-                functions.close = decorations.close = true;
+                functions.close = true;
             else if (proto[i] == fluxbox->getWMTakeFocusAtom())
                 send_focus_message = true;
             else if (proto[i] == fluxbox->getFluxboxStructureMessagesAtom())
@@ -1156,7 +533,10 @@ void FluxboxWindow::getWMProtocols() {
         }
 
         XFree(proto);
+    } else {
+        cerr<<"Warning: Failed to read WM Protocols"<<endl;
     }
+
 }
 
 
@@ -1332,12 +712,12 @@ void FluxboxWindow::getBlackboxHints() {
     int format;
     Atom atom_return;
     unsigned long num, len;
-    Fluxbox *fluxbox = Fluxbox::instance();
+    FbAtoms *atoms = FbAtoms::instance();
 	
     if (XGetWindowProperty(display, client.window,
-                           fluxbox->getFluxboxHintsAtom(), 0,
+                           atoms->getFluxboxHintsAtom(), 0,
                            PropBlackboxHintsElements, False,
-                           fluxbox->getFluxboxHintsAtom(), &atom_return,
+                           atoms->getFluxboxHintsAtom(), &atom_return,
                            &format, &num, &len,
                            (unsigned char **) &client.blackbox_hint) == Success &&
         client.blackbox_hint) {
@@ -1370,77 +750,55 @@ void FluxboxWindow::getBlackboxHints() {
     }
 }
 
+void FluxboxWindow::move(int x, int y) {
+    moveResize(x, y, m_frame.width(), m_frame.height());
+}
 
-void FluxboxWindow::configure(int dx, int dy,
-                              unsigned int dw, unsigned int dh) {
+void FluxboxWindow::resize(unsigned int width, unsigned int height) {
+    moveResize(m_frame.x(), m_frame.y(), width, height);
+}
 
-    //we don't want negative size
-    if (dw < 0 || dh < 0)
-        return;
+void FluxboxWindow::moveResize(int new_x, int new_y,
+                               unsigned int new_width, unsigned int new_height) {
 
-    bool send_event = (frame.x != dx || frame.y != dy);
+    bool send_event = (m_frame.x() != new_x || m_frame.y() != new_y);
 
-    if ((dw != frame.width) || (dh != frame.height)) {
-        if ((((signed) frame.width) + dx) < 0) 
-            dx = 0;
-        if ((((signed) frame.height) + dy) < 0) 
-            dy = 0;
+    if (new_width != m_frame.width() || new_height != m_frame.height()) {
+        if ((((signed) m_frame.width()) + new_x) < 0) 
+            new_x = 0;
+        if ((((signed) m_frame.height()) + new_y) < 0) 
+            new_y = 0;
 
-        frame.x = dx;
-        frame.y = dy;
-        frame.width = dw;
-        frame.height = dh;
-		
         downsize();
 
-#ifdef	SHAPE
-        if (Fluxbox::instance()->hasShapeExtensions() && frame.shaped) {
-            XShapeCombineShape(display, frame.window, ShapeBounding,
-                               frame.mwm_border_w, frame.y_border +
-                               frame.mwm_border_w, client.window,
-                               ShapeBounding, ShapeSet);
-
-            int num = 1;
-            XRectangle xrect[2];
-            xrect[0].x = xrect[0].y = 0;
-            xrect[0].width = frame.width;
-            xrect[0].height = frame.y_border;
-
-            if (decorations.handle) {
-                xrect[1].x = 0;
-                xrect[1].y = frame.y_handle;
-                xrect[1].width = frame.width;
-                xrect[1].height = frame.handle_h + screen->getBorderWidth();
-                num++;
-            }
+        m_frame.moveResize(new_x, new_y, new_width, new_height);
+        if (tab)
+            tab->resize();
 
-            XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
-                                    xrect, num, ShapeUnion, Unsorted);
-        }
-#endif // SHAPE
-        XMoveResizeWindow(display, frame.window, frame.x, frame.y,
-                          frame.width, frame.height);
         positionWindows();
-        decorate();
         setFocusFlag(focused);
-        redrawAllButtons();
         shaded = false;
+        send_event = true;
     } else {
-        frame.x = dx;
-        frame.y = dy;
-
-        XMoveWindow(display, frame.window, frame.x, frame.y);
+        m_frame.move(new_x, new_y);
         //move the tab and the chain		
         if (tab)
             tab->setPosition();
 		
-        if (! moving) send_event = true;
+        //    if (! moving)
+        send_event = true;
     }
 
     if (send_event && ! moving) {
-        client.x = dx + frame.mwm_border_w + screen->getBorderWidth();
-        client.y = dy + frame.y_border + frame.mwm_border_w +
-            screen->getBorderWidth();
+        /*
+          Send event telling where the root position 
+          of the client window is. (ie frame pos + client pos inside the frame = send pos)
+        */
+
+        client.width = m_frame.clientArea().width();
+        client.height = m_frame.clientArea().height();
+        client.x = m_frame.x();
+        client.y = m_frame.y();
 
         XEvent event;
         event.type = ConfigureNotify;
@@ -1448,44 +806,45 @@ void FluxboxWindow::configure(int dx, int dy,
         event.xconfigure.display = display;
         event.xconfigure.event = client.window;
         event.xconfigure.window = client.window;
-        event.xconfigure.x = client.x;
-        event.xconfigure.y = client.y;
+        event.xconfigure.x = m_frame.x() + m_frame.clientArea().x();
+        event.xconfigure.y = m_frame.y() + m_frame.clientArea().y();
         event.xconfigure.width = client.width;
         event.xconfigure.height = client.height;
         event.xconfigure.border_width = client.old_bw;
-        event.xconfigure.above = frame.window;
+        event.xconfigure.above = m_frame.window().window();
         event.xconfigure.override_redirect = false;
 
         XSendEvent(display, client.window, False, StructureNotifyMask, &event);
 
         screen->updateNetizenConfigNotify(&event);
     }
-}
-
+}	
 
 bool FluxboxWindow::setInputFocus() {
-    //TODO hint skip focus
 
-    if (((signed) (frame.x + frame.width)) < 0) {
-        if (((signed) (frame.y + frame.y_border)) < 0)
-            configure(screen->getBorderWidth(), screen->getBorderWidth(),
-                      frame.width, frame.height);
-        else if (frame.y > (signed) screen->getHeight())
-            configure(screen->getBorderWidth(), screen->getHeight() - frame.height,
-                      frame.width, frame.height);
-        else
-            configure(screen->getBorderWidth(), frame.y + screen->getBorderWidth(),
-                      frame.width, frame.height);
-    } else if (frame.x > (signed) screen->getWidth()) {
-        if (((signed) (frame.y + frame.y_border)) < 0)
-            configure(screen->getWidth() - frame.width, screen->getBorderWidth(),
-                      frame.width, frame.height);
-        else if (frame.y > (signed) screen->getHeight())
-            configure(screen->getWidth() - frame.width,
-                      screen->getHeight() - frame.height, frame.width, frame.height);
-        else
-            configure(screen->getWidth() - frame.width,
-                      frame.y + screen->getBorderWidth(), frame.width, frame.height);
+    //TODO hint skip focus
+    if (((signed) (m_frame.x() + m_frame.width())) < 0) {
+        if (((signed) (m_frame.y() + m_frame.height())) < 0) {
+            moveResize(screen->getBorderWidth(), screen->getBorderWidth(),
+                       m_frame.width(), m_frame.height());
+        } else if (m_frame.y() > (signed) screen->getHeight()) {
+            moveResize(screen->getBorderWidth(), screen->getHeight() - m_frame.height(),
+                       m_frame.width(), m_frame.height());
+        } else {
+            moveResize(screen->getBorderWidth(), m_frame.y() + screen->getBorderWidth(),
+                       m_frame.width(), m_frame.height());
+        }
+    } else if (m_frame.x() > (signed) screen->getWidth()) {
+        if (((signed) (m_frame.y() + m_frame.height())) < 0) {
+            moveResize(screen->getWidth() - m_frame.width(), screen->getBorderWidth(),
+                       m_frame.width(), m_frame.height());
+        } else if (m_frame.y() > (signed) screen->getHeight()) {
+            moveResize(screen->getWidth() - m_frame.width(),
+                       screen->getHeight() - m_frame.height(), m_frame.width(), m_frame.height());
+        } else {
+            moveResize(screen->getWidth() - m_frame.width(),
+                       m_frame.y() + screen->getBorderWidth(), m_frame.width(), m_frame.height());
+        }
     }
 
     if (! validateClient())
@@ -1507,7 +866,9 @@ bool FluxboxWindow::setInputFocus() {
         } else {
             return false;
         }
-		
+
+	m_frame.setFocus(true);
+	
         Fluxbox *fb = Fluxbox::instance();
         fb->setFocusedWindow(this);
 			
@@ -1536,32 +897,33 @@ bool FluxboxWindow::setInputFocus() {
     return ret;
 }
 
-//------------ setTab --------------
-// Enables or disables the tab on the window
-//----------------------------------
+/**
+   Enables or disables the tab on the window
+*/
 void FluxboxWindow::setTab(bool flag) {
-    if (flag) {
-        if (!tab && isGroupable())
-            tab = new Tab(this, 0, 0);
+    /*    if (flag) {
+          if (!tab && isGroupable())
+          tab = new Tab(this, 0, 0);
 		
-        if (tab) {
-            tab->focus(); // draws the tab with correct texture
-            tab->setPosition(); // set tab windows position
-        }
-
-    } else if (tab) {
-        delete tab;
-        tab = 0;		
-    }	
-    decorations.tab = flag;
-}
-
-//------------- iconify ----------------
-// Unmaps the window and removes it from workspace list
-//--------------------------------------
+          if (tab) {
+          tab->focus(); // draws the tab with correct texture
+          tab->setPosition(); // set tab windows position
+          }
+
+          } else if (tab) {
+          delete tab;
+          tab = 0;		
+          }	
+          decorations.tab = flag;
+    */
+}
+
+/**
+   Unmaps the window and removes it from workspace list
+*/
 void FluxboxWindow::iconify() {
 
-    if (iconic)
+    if (iconic) // no need to iconify if we're already
         return;
 
     if (m_windowmenu.get())
@@ -1569,12 +931,14 @@ void FluxboxWindow::iconify() {
 
     setState(IconicState);
 
+
     XSelectInput(display, client.window, NoEventMask);
     XUnmapWindow(display, client.window);
     XSelectInput(display, client.window,
                  PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
 
-    XUnmapWindow(display, frame.window);
+    m_frame.hide();
+
     visible = false;
     iconic = true;
 	
@@ -1601,7 +965,7 @@ void FluxboxWindow::iconify() {
 }
 
 
-void FluxboxWindow::deiconify(bool reassoc, bool raise) {
+void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
     if (iconic || reassoc) {
         screen->reassociateWindow(this, screen->getCurrentWorkspace()->workspaceID(), false);
     } else if (workspace_number != screen->getCurrentWorkspace()->workspaceID())
@@ -1614,12 +978,14 @@ void FluxboxWindow::deiconify(bool reassoc, bool raise) {
     XSelectInput(display, client.window,
                  PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
 
-    XMapSubwindows(display, frame.window);
-    XMapWindow(display, frame.window);
+    m_frame.show();
 
     if (iconic && screen->doFocusNew())
         setInputFocus();
 
+    if (focused != m_frame.focused())
+        m_frame.setFocus(focused);
+
     visible = true;
     iconic = false;
 
@@ -1635,45 +1001,44 @@ void FluxboxWindow::deiconify(bool reassoc, bool raise) {
     if (tab)
         tab->deiconify();
 			
-    if (raise) {		
-        screen->getWorkspace(workspace_number)->raiseWindow(this);
-        if (tab)
-            tab->raise();
-    }
+    if (do_raise)
+	raise();
 }
 
-
+/**
+   Send close request to client window
+*/
 void FluxboxWindow::close() {
-    Fluxbox *fluxbox = Fluxbox::instance();
+    // fill in XClientMessage structure for delete message
     XEvent ce;
     ce.xclient.type = ClientMessage;
-    ce.xclient.message_type = fluxbox->getWMProtocolsAtom();
-    ce.xclient.display = display;
+    ce.xclient.message_type = FbAtoms::instance()->getWMProtocolsAtom();
+    ce.xclient.display = FbTk::App::instance()->display();
     ce.xclient.window = client.window;
     ce.xclient.format = 32;
-    ce.xclient.data.l[0] = fluxbox->getWMDeleteAtom();
+    ce.xclient.data.l[0] = FbAtoms::instance()->getWMDeleteAtom();
     ce.xclient.data.l[1] = CurrentTime;
     ce.xclient.data.l[2] = 0l;
     ce.xclient.data.l[3] = 0l;
     ce.xclient.data.l[4] = 0l;
+    // send event delete message to client window
     XSendEvent(display, client.window, false, NoEventMask, &ce);
 }
 
-
+/**
+ Set window in withdrawn state
+*/
 void FluxboxWindow::withdraw() {
     visible = false;
     iconic = false;
+
     if (isMoving())
         stopMoving();
+
     if (isResizing())
         stopResizing();
 
-    XUnmapWindow(display, frame.window);
-
-    XSelectInput(display, client.window, NoEventMask);
-    XUnmapWindow(display, client.window);
-    XSelectInput(display, client.window,
-                 PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
+    m_frame.hide();
 
     if (m_windowmenu.get())
         m_windowmenu->hide();
@@ -1682,314 +1047,47 @@ void FluxboxWindow::withdraw() {
         tab->withdraw();
 }
 
-
-void FluxboxWindow::maximize(unsigned int button) {
-    // deiconify if we're iconic
+/**
+   Maximize window both horizontal and vertical
+*/
+void FluxboxWindow::maximize() {
     if (isIconic())
         deiconify();
 
-    if (! maximized) {
-        int dx, dy;
-        unsigned int dw, dh, slitModL = 0, slitModR = 0, slitModT = 0, slitModB = 0;
-
-#ifdef XINERAMA
-        // get the head the window is on, taking the middle of the window to
-        // make it feel right, maybe someone will like client.x, client.y better
-        // tough?
-        unsigned int head = (screen->hasXinerama()) ?
-            screen->getHead(client.x + (client.width / 2), client.y + (client.height / 2))
-            : 0;
-#endif // XINERAMA
-
-
-#ifdef	SLIT
-
-#ifdef XINERAMA
-	// take the slit in account if it's on the same head
-	// (always true if we don't have xinerama
-	if (!screen->hasXinerama() || screen->getSlitOnHead() == head) {
-#endif // XINERAMA
-
-            Slit* mSlt = screen->getSlit();
-
-            if(!screen->doMaxOverSlit() && !screen->doFullMax() && (mSlt->width() > 1))
-		{
-                    switch(screen->getSlitDirection())
-			{
-			case Slit::VERTICAL:
-                            switch(screen->getSlitPlacement())
-				{
-				case Slit::TOPRIGHT:
-				case Slit::CENTERRIGHT:
-				case Slit::BOTTOMRIGHT:
-                                    slitModR = mSlt->width() + screen->getBevelWidth();
-                                    break;
-				default:
-                                    slitModL = mSlt->width() + screen->getBevelWidth();
-                                    break;
-				}
-                            break;
-			case Slit::HORIZONTAL:
-                            switch(screen->getSlitPlacement())
-				{
-				case Slit::TOPLEFT:
-				case Slit::TOPCENTER:
-				case Slit::TOPRIGHT:
-                                    slitModT = mSlt->height() + screen->getBevelWidth();
-                                    switch (screen->getToolbarPlacement()) {
-                                    case Toolbar::TOPLEFT:
-                                    case Toolbar::TOPCENTER:
-                                    case Toolbar::TOPRIGHT:
-                                        slitModT -= screen->getToolbar()->exposedHeight() + 
-                                            screen->getBorderWidth();
-                                        break;
-                                    default:
-                                        break;
-                                    }				
-                                    break;
-				default:
-                                    slitModB = mSlt->height() + screen->getBevelWidth();
-                                    switch (screen->getToolbarPlacement()) {
-                                    case Toolbar::BOTTOMLEFT:
-                                    case Toolbar::BOTTOMCENTER:
-                                    case Toolbar::BOTTOMRIGHT:
-                                        slitModB -= screen->getToolbar()->exposedHeight() + 
-                                            screen->getBorderWidth();
-                                        break;
-                                    default:
-                                        break;
-                                    }	
-                                    break;
-				}	
-                            break;
-			}
-		}		
-#ifdef XINERAMA
-	}
-#endif // XINERAMA
-
-#endif // SLIT
-	
-        blackbox_attrib.premax_x = frame.x;
-        blackbox_attrib.premax_y = frame.y;
-        blackbox_attrib.premax_w = frame.width;
-        blackbox_attrib.premax_h = frame.height;
-
-#ifdef XINERAMA
-        dw = screen->getHeadWidth(head) - slitModL - slitModR;
-#else // !XINERAMA
-        dw = screen->getWidth() - slitModL - slitModR;
-#endif // XINERAMA
-        dw -= screen->getBorderWidth2x();
-        dw -= frame.mwm_border_w * 2;
-        dw -= client.base_width;
-
-#ifdef XINERAMA
-        dh = screen->getHeadHeight(head) - slitModT - slitModB;
-#else // !XINERAMA
-        dh = screen->getHeight() - slitModT - slitModB;
-#endif // XINERAMA
-        dh -= screen->getBorderWidth2x();
-        dh -= frame.mwm_border_w * 2;
-        dh -= ((frame.handle_h + screen->getBorderWidth()) * decorations.handle);
-        dh -= client.base_height;
-        dh -= frame.y_border;
-
-        if (! screen->doFullMax()) {
-#ifdef XINERAMA
-            if (screen->hasXinerama()) {
-				// is the toolbar on this head?
-                if ((screen->getToolbarOnHead() == (signed) head) ||
-                    (screen->getToolbarOnHead() < 0)) {
-                    dh -= screen->getToolbar()->exposedHeight() +
-                        screen->getBorderWidth2x();
-                }
-            } else {
-                dh -= screen->getToolbar()->exposedHeight() +
-                    screen->getBorderWidth2x();
-            }
-#else // !XINERAMA
-            dh -= screen->getToolbar()->exposedHeight() +
-                screen->getBorderWidth2x();
-#endif // XINERAMA
-        }
-
-        if (dw < client.min_width) dw = client.min_width;
-        if (dh < client.min_height) dh = client.min_height;
-        if (client.max_width != 0 && dw > client.max_width) dw = client.max_width;
-        if (client.max_height != 0 && dh > client.max_height) dh = client.max_height;
-
-        dw -= (dw % client.width_inc);
-        dw += client.base_width;
-        dh -= (dh % client.height_inc);
-        dh += client.base_height;
-
-        dw += frame.mwm_border_w * 2;
-
-        dh += frame.y_border;
-        dh += (frame.handle_h + screen->getBorderWidth());
-        dh += frame.mwm_border_w * 2;
-
-#ifdef XINERAMA
-        dx = screen->getHeadX(head) +
-            ((screen->getHeadWidth(head) + slitModL - slitModR - dw) / 2)
-            - screen->getBorderWidth();
-#else // !XINERAMA
-        dx = ((screen->getWidth()+ slitModL - slitModR - dw) / 2) - screen->getBorderWidth();
-#endif // XINERAMA
-
-        if (screen->doFullMax()) {
-#ifdef XINERAMA
-            dy = screen->getHeadY(head) +
-                ((screen->getHeadHeight(head) - dh) / 2) - screen->getBorderWidth();
-#else // !XINERAMA
-            dy = ((screen->getHeight() - dh) / 2) - screen->getBorderWidth();
-#endif // XINERAMA
-        } else {
-#ifdef XINERAMA
-            if (screen->hasXinerama()) { // xinerama
-                dy = screen->getHeadY(head);
-				// is the toolbar on this head?
-                if ((screen->getToolbarOnHead() == (signed) head) ||
-                    (screen->getToolbarOnHead() < 0)) {
-                    dy += (((screen->getHeadHeight(head) + slitModT - slitModB
-                             - (screen->getToolbar()->exposedHeight())) - dh) / 2)
-                        - screen->getBorderWidth2x();
-                } else {
-                    dy += ((screen->getHeadHeight(head) + slitModT - slitModB - dh) / 2) -
-                        screen->getBorderWidth();
-                }
-            } else { // no xinerama
-                dy = (((screen->getHeight() + slitModT - slitModB -
-                        (screen->getToolbar()->exposedHeight())) - dh) / 2) -
-                    screen->getBorderWidth2x();
-            }
-#else // !XINERAMA
-            dy = (((screen->getHeight() + slitModT - slitModB - (screen->getToolbar()->exposedHeight()))
-                   - dh) / 2) - screen->getBorderWidth2x();
-#endif // XINERAMA
-
-            switch (screen->getToolbarPlacement()) {
-            case Toolbar::TOPLEFT:
-            case Toolbar::TOPCENTER:
-            case Toolbar::TOPRIGHT:
-#ifdef XINERAMA
-				// if < 0 than it's over ALL heads, with no xinerama it's there too
-                if (!screen->hasXinerama() ||
-                    (screen->getToolbarOnHead() == (signed) head) ||
-                    (screen->getToolbarOnHead() < 0)) {
-                    dy += screen->getToolbar()->exposedHeight() +
-                        screen->getBorderWidth2x();
-                }
-#else // !XINERAMA
-                dy += screen->getToolbar()->exposedHeight() +
-                    screen->getBorderWidth2x();
-#endif // XINERAMA
-                break;
-            default:
-                break;
-            }
-        }
-
-        if (hasTab()) {
-            switch(screen->getTabPlacement()) {			
-            case Tab::PTOP:
-                dy += screen->getTabHeight(); 
-                dh -= screen->getTabHeight();
-                break;
-            case Tab::PLEFT:
-                if (screen->isTabRotateVertical()) {
-                    dx += screen->getTabHeight();
-                    dw -= screen->getTabHeight();
-                } else {
-                    dx += screen->getTabWidth();
-                    dw -= screen->getTabWidth();
-                }	
-                break;
-            case Tab::PRIGHT:
-                if (screen->isTabRotateVertical())
-                    dw -= screen->getTabHeight();
-                else
-                    dw -= screen->getTabWidth();	
-                break;
-            case Tab::PBOTTOM:
-                dh -= screen->getTabHeight();
-                break;
-            default:
-                dy += screen->getTabHeight();
-                dh -= screen->getTabHeight();
-                break;
-            }
-        }
-
-        if (button == 2) { //expand max width
-            dw = frame.width;
-            dx = frame.x;
-        } else if (button == 3) { //expand max height
-            dh = frame.height;
-            dy = frame.y;
-        }
-
-        switch(button) {
-        case 1:
-            blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT;
-            blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT;
-
-            break;
-
-        case 2:
-            blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXVERT;
-            blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXVERT;
-
-            break;
-
-        case 3:
-            blackbox_attrib.flags |= BaseDisplay::ATTRIB_MAXHORIZ;
-            blackbox_attrib.attrib |= BaseDisplay::ATTRIB_MAXHORIZ;
-
-            break;
-        }
-
-        if (shaded) {
-            blackbox_attrib.flags ^= BaseDisplay::ATTRIB_SHADED;
-            blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_SHADED;
-            shaded = false;
-            if (hasTab())
-                getTab()->shade();
-        }
-
-        maximized = true;
-
-        configure(dx, dy, dw, dh);
-        if (tab)
-            tab->raise();
-        screen->getWorkspace(workspace_number)->raiseWindow(this);
-        setState(current_state);
-
-    } else {
-        maximized = false;
-
-        if (isShaded()) {
-            shade();
-            if (hasTab())
-                getTab()->shade();
-        }
-
-        blackbox_attrib.flags &= ! (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT);
-        blackbox_attrib.attrib &= ! (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT);
-
-        configure(blackbox_attrib.premax_x, blackbox_attrib.premax_y,
-                  blackbox_attrib.premax_w, blackbox_attrib.premax_h);
+    if (!maximized) {
+        // save old values
+        m_old_width = frame().width();
+        m_old_height = frame().height();
+        m_old_pos_x = frame().x();
+        m_old_pos_y = frame().y();
+        unsigned int left_x = screen->getMaxLeft();
+        unsigned int max_width = screen->getMaxRight();
+        unsigned int max_top = screen->getMaxTop();
+        moveResize(left_x, max_top, 
+                   max_width - left_x, screen->getMaxBottom() - max_top - m_frame.window().borderWidth());
+    } else { // demaximize, restore to old values
+        moveResize(m_old_pos_x, m_old_pos_y,
+                   m_old_width, m_old_height);
+    }
+    // toggle maximize
+    maximized = !maximized;
+}
 
-        blackbox_attrib.premax_x = blackbox_attrib.premax_y = 0;
-        blackbox_attrib.premax_w = blackbox_attrib.premax_h = 0;
+void FluxboxWindow::maximizeHorizontal() {
+    unsigned int left_x = screen->getMaxLeft();
+    unsigned int max_width = screen->getMaxRight();
+    moveResize(left_x, m_frame.y(), 
+               max_width - left_x, m_frame.height() - m_frame.window().borderWidth());
 
-        redrawAllButtons();
-        setState(current_state);
-    }
+}
 
-    if (tab) //resize all the windows in the tab group
-        tab->resize();
+/**
+ Maximize window horizontal
+ */
+void FluxboxWindow::maximizeVertical() {
+    unsigned int max_top = screen->getMaxTop();
+    moveResize(m_frame.x(), max_top,
+               m_frame.width() - m_frame.window().borderWidth(), screen->getMaxBottom() - max_top);
 }
 
 
@@ -2009,15 +1107,18 @@ void FluxboxWindow::setWorkspace(int n) {
 
 void FluxboxWindow::shade() {
     if (decorations.titlebar) {
+        // toggle shade on tab and frame
+        m_frame.shade();
+        if (tab)
+            tab->shade();
+
         if (shaded) {
-            XResizeWindow(display, frame.window, frame.width, frame.height);
             shaded = false;
             blackbox_attrib.flags ^= BaseDisplay::ATTRIB_SHADED;
             blackbox_attrib.attrib ^= BaseDisplay::ATTRIB_SHADED;
 
             setState(NormalState);
         } else {
-            XResizeWindow(display, frame.window, frame.width, frame.title_h);
             shaded = true;
             blackbox_attrib.flags |= BaseDisplay::ATTRIB_SHADED;
             blackbox_attrib.attrib |= BaseDisplay::ATTRIB_SHADED;
@@ -2047,12 +1148,29 @@ void FluxboxWindow::stick() {
         blackbox_attrib.flags |= BaseDisplay::ATTRIB_OMNIPRESENT;
         blackbox_attrib.attrib |= BaseDisplay::ATTRIB_OMNIPRESENT;
 
-    }
-    //find a STICK button in window
-    redrawAllButtons();
-    setState(current_state);
+    }
+    //TODO: make sure any button that listens to this state gets updated
+
+    setState(current_state);
+}
+
+void FluxboxWindow::lower() {
+    if (isIconic())
+        deiconify();
+
+    screen->getWorkspace(workspace_number)->lowerWindow(this);
+    if (hasTab())
+        getTab()->lower(); //lower the tab AND it's windows
 }
 
+void FluxboxWindow::raise() {
+    if (isIconic())
+        deiconify();
+    screen->getWorkspace(workspace_number)->raiseWindow(this);
+    //raise tab first if there is any
+    if (hasTab())
+        tab->raise();
+}
 
 void FluxboxWindow::setFocusFlag(bool focus) {
     focused = focus;
@@ -2061,66 +1179,10 @@ void FluxboxWindow::setFocusFlag(bool focus) {
     if (focused)
         gettimeofday(&lastFocusTime, 0);
 
-    if (decorations.titlebar) {
-        if (focused) {
-            if (frame.ftitle)
-                XSetWindowBackgroundPixmap(display, frame.title, frame.ftitle);
-            else
-                XSetWindowBackground(display, frame.title, frame.ftitle_pixel);
-        } else {
-            if (frame.utitle)
-                XSetWindowBackgroundPixmap(display, frame.title, frame.utitle);
-            else
-                XSetWindowBackground(display, frame.title, frame.utitle_pixel);
-        }
-        XClearWindow(display, frame.title);
-		
-        redrawLabel();
-        redrawAllButtons();
-    }
-
-    if (decorations.handle) {
-        if (focused) {
-            if (frame.fhandle)
-                XSetWindowBackgroundPixmap(display, frame.handle, frame.fhandle);
-            else
-                XSetWindowBackground(display, frame.handle, frame.fhandle_pixel);
-
-            if (frame.fgrip) {
-                XSetWindowBackgroundPixmap(display, frame.right_grip, frame.fgrip);
-                XSetWindowBackgroundPixmap(display, frame.left_grip, frame.fgrip);
-            } else {
-                XSetWindowBackground(display, frame.right_grip, frame.fgrip_pixel);
-                XSetWindowBackground(display, frame.left_grip, frame.fgrip_pixel);
-            }
-        } else {
-            if (frame.uhandle)
-                XSetWindowBackgroundPixmap(display, frame.handle, frame.uhandle);
-            else
-                XSetWindowBackground(display, frame.handle, frame.uhandle_pixel);
-
-            if (frame.ugrip) {
-                XSetWindowBackgroundPixmap(display, frame.right_grip, frame.ugrip);
-                XSetWindowBackgroundPixmap(display, frame.left_grip, frame.ugrip);
-            } else {
-                XSetWindowBackground(display, frame.right_grip, frame.ugrip_pixel);
-                XSetWindowBackground(display, frame.left_grip, frame.ugrip_pixel);
-            }
-        }
-        XClearWindow(display, frame.handle);
-        XClearWindow(display, frame.right_grip);
-        XClearWindow(display, frame.left_grip);
-    }
+    m_frame.setFocus(focus);
 	
     if (tab)
         tab->focus();
-	
-    if (decorations.border) {
-        if (focused)
-            XSetWindowBorder(display, frame.plate, frame.fborder_pixel);
-        else
-            XSetWindowBorder(display, frame.plate, frame.uborder_pixel);
-    }
 
     if ((screen->isSloppyFocus() || screen->isSemiSloppyFocus()) &&
         screen->doAutoRaise())
@@ -2139,7 +1201,7 @@ void FluxboxWindow::installColormap(bool install) {
     if (cmaps) {
         if (XGetWindowAttributes(display, client.window, &wattrib)) {
             if (install) {
-				// install the window's colormap
+                // install the window's colormap
                 for (i = 0; i < ncmap; i++) {
                     if (*(cmaps + i) == wattrib.colormap) {
                         // this window is using an installed color map... do not install
@@ -2147,7 +1209,7 @@ void FluxboxWindow::installColormap(bool install) {
                         break; //end for-loop (we dont need to check more)
                     }
                 }
-				// otherwise, install the window's colormap
+                // otherwise, install the window's colormap
                 if (install)
                     XInstallColormap(display, wattrib.colormap);
             } else {				
@@ -2182,7 +1244,6 @@ void FluxboxWindow::setState(unsigned long new_state) {
     m_statesig.notify();
 }
 
-//TODO: why ungrab in if-statement?
 bool FluxboxWindow::getState() {
     current_state = 0;
 
@@ -2196,7 +1257,6 @@ bool FluxboxWindow::getState() {
                             &atom_return, &foo, &nitems, &ulfoo,
                             (unsigned char **) &state) != Success) ||
         (! state)) {
-        fluxbox->ungrab();
         return false;
     }
 
@@ -2210,8 +1270,10 @@ bool FluxboxWindow::getState() {
     return ret;
 }
 
-
+//TODO: this functions looks odd
 void FluxboxWindow::setGravityOffsets() {
+    int newx = m_frame.x();
+    int newy = m_frame.y();
     // translate x coordinate
     switch (client.win_gravity) {
         // handle Westward gravity
@@ -2219,21 +1281,33 @@ void FluxboxWindow::setGravityOffsets() {
     case WestGravity:
     case SouthWestGravity:
     default:
-        frame.x = client.x;
+#ifdef DEBUG
+        cerr<<__FILE__<<": Default gravity: SouthWest, NorthWest, West"<<endl;
+#endif // DEBUG
+
+        newx = m_frame.x();
         break;
 
         // handle Eastward gravity
     case NorthEastGravity:
     case EastGravity:
     case SouthEastGravity:
-        frame.x = (client.x + client.width) - frame.width;
+#ifdef DEBUG
+        cerr<<__FILE__<<": Gravity: SouthEast, NorthEast, East"<<endl;
+#endif // DEBUG
+
+        newx = m_frame.x() + m_frame.clientArea().width() - m_frame.width();
         break;
 
         // no x translation desired - default
     case StaticGravity:
     case ForgetGravity:
     case CenterGravity:
-        frame.x = client.x - frame.mwm_border_w + screen->getBorderWidth();
+#ifdef DEBUG
+        cerr<<__FILE__<<": Gravity: Center, Forget, Static"<<endl;
+#endif // DEBUG
+
+        newx = m_frame.x();
     }
 
     // translate y coordinate
@@ -2243,24 +1317,26 @@ void FluxboxWindow::setGravityOffsets() {
     case NorthGravity:
     case NorthEastGravity:
     default:
-        frame.y = client.y;
+        newy = m_frame.y();
         break;
 
         // handle Southbound gravity
     case SouthWestGravity:
     case SouthGravity:
     case SouthEastGravity:
-        frame.y = (client.y + client.height) - frame.height;
+        newy = m_frame.y() + m_frame.clientArea().height() - m_frame.height();
         break;
 
         // no y translation desired - default
     case StaticGravity:
     case ForgetGravity:
     case CenterGravity:
-        frame.y = client.y - frame.y_border - frame.mwm_border_w -
-            screen->getBorderWidth();
+        newy = m_frame.y();
         break;
     }
+    // finaly move the frame
+    if (m_frame.x() != newx || m_frame.y() != newy)
+        m_frame.move(newx, newy);
 }
 
 
@@ -2300,8 +1376,6 @@ void FluxboxWindow::restoreAttributes() {
 
         shaded = false;
         shade();
-        if (tab)
-            tab->shade();
 			
         current_state = save_state;
     }
@@ -2327,20 +1401,13 @@ void FluxboxWindow::restoreAttributes() {
         int x = blackbox_attrib.premax_x, y = blackbox_attrib.premax_y;
         unsigned int w = blackbox_attrib.premax_w, h = blackbox_attrib.premax_h;
         maximized = false;
-
-        int m;
         if ((blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ) &&
             (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT))
-            m = ((blackbox_attrib.attrib & (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ?
-                 1 : 0);
+            maximize();
         else if (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXVERT)
-            m = ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
+            maximizeVertical();
         else if (blackbox_attrib.flags & BaseDisplay::ATTRIB_MAXHORIZ)
-            m = ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
-        else
-            m = 0;
-
-        if (m) maximize(m);
+            maximizeHorizontal();
 
         blackbox_attrib.premax_x = x;
         blackbox_attrib.premax_y = y;
@@ -2351,6 +1418,9 @@ void FluxboxWindow::restoreAttributes() {
     setState(current_state);
 }
 
+/**
+   Show the window menu at pos mx, my
+*/
 void FluxboxWindow::showMenu(int mx, int my) {
     if (m_windowmenu.get() == 0)
         return;
@@ -2369,14 +1439,14 @@ void FluxboxWindow::restoreGravity() {
     case WestGravity:
     case SouthWestGravity:
     default:
-        client.x = frame.x;
+        client.x = m_frame.x();
         break;
 
         // handle Eastward gravity
     case NorthEastGravity:
     case EastGravity:
     case SouthEastGravity:
-        client.x = (frame.x + frame.width) - client.width;
+        client.x = (m_frame.x() + m_frame.width()) - client.width;
         break;
     }
 
@@ -2387,18 +1457,21 @@ void FluxboxWindow::restoreGravity() {
     case NorthGravity:
     case NorthEastGravity:
     default:
-        client.y = frame.y;
+        client.y = m_frame.y();
         break;
 
         // handle Southbound gravity
     case SouthWestGravity:
     case SouthGravity:
     case SouthEastGravity:
-        client.y = (frame.y + frame.height) - client.height;
+        client.y = (m_frame.y() + m_frame.height()) - client.height;
         break;
     }
 }
 
+/**
+   Determine if this is the lowest tab of them all
+*/
 bool FluxboxWindow::isLowerTab() const {
     Tab* chkTab = (tab ? tab->first() : 0);
     while (chkTab) {
@@ -2411,69 +1484,29 @@ bool FluxboxWindow::isLowerTab() const {
     return false;
 }
 
-void FluxboxWindow::redrawLabel() {
-    if (focused) {
-        if (frame.flabel)
-            XSetWindowBackgroundPixmap(display, frame.label, frame.flabel);
-        else
-            XSetWindowBackground(display, frame.label, frame.flabel_pixel);
-    } else {
-        if (frame.ulabel)
-            XSetWindowBackgroundPixmap(display, frame.label, frame.ulabel);
-        else
-            XSetWindowBackground(display, frame.label, frame.ulabel_pixel);
-    }
-
-    XClearWindow(display, frame.label);
-
-    //no need to draw the title if we don't have any
-    if (getTitle().size() == 0)
-        return;
-
-    GC gc = ((focused) ? screen->getWindowStyle()->l_text_focus_gc :
-             screen->getWindowStyle()->l_text_unfocus_gc);
-
-    size_t newlen = getTitle().size();
-    const char *labeltext = getTitle().c_str();
-    FbTk::Font &font = screen->getWindowStyle()->font;
-
-    int align_x = DrawUtil::doAlignment(
-        frame.label_w, frame.bevel_w*2,
-        screen->getWindowStyle()->justify,
-        font,
-        labeltext, newlen, newlen);
-	
-    font.drawText(
-        frame.label,
-        screen->getScreenNumber(),
-        gc,
-        labeltext, newlen,
-        align_x, font.ascent() + 1);
-}
-
-
-void FluxboxWindow::redrawAllButtons() {
-    for (unsigned int i=0; i<buttonlist.size(); i++) {
-        if (buttonlist[i].draw)
-            buttonlist[i].draw(this, buttonlist[i].win, false);
+/**
+   Redirect any unhandled event to our handlers
+*/
+void FluxboxWindow::handleEvent(XEvent &event) {
+    switch (event.type) {
+    case ConfigureRequest:
+        configureRequestEvent(event.xconfigurerequest);
+    case MapNotify:
+        mapNotifyEvent(event.xmap);
+    case MapRequest:
+        mapRequestEvent(event.xmaprequest);
+        break;
+    default:
+        break;
     }
 }
 
-void FluxboxWindow::mapRequestEvent(XMapRequestEvent *re) {
-#ifdef DEBUG
-    fprintf(stderr,
-            I18n::instance()->getMessage(
-                FBNLS::WindowSet, FBNLS::WindowMapRequest,
-                "FluxboxWindow::mapRequestEvent() for 0x%lx\n"),
-            client.window);
-#endif // DEBUG
-    if (re->window != client.window)
+void FluxboxWindow::mapRequestEvent(XMapRequestEvent &re) {
+    // we're only conserned about client window event
+    if (re.window != client.window)
         return;
 
     Fluxbox *fluxbox = Fluxbox::instance();
-    fluxbox->grab();
-    if (! validateClient())
-        return;
 	
     bool get_state_ret = getState();
     if (! (get_state_ret && fluxbox->isStartup())) {
@@ -2495,7 +1528,7 @@ void FluxboxWindow::mapRequestEvent(XMapRequestEvent *re) {
 	break;
 
     case NormalState:
-        //check WM_CLASS only when we changed state to NormalState from 
+        // check WM_CLASS only when we changed state to NormalState from 
         // WithdrawnState (ICCC 4.1.2.5)
 				
         XClassHint ch;
@@ -2533,30 +1566,25 @@ void FluxboxWindow::mapRequestEvent(XMapRequestEvent *re) {
         break;
     }
 
-    fluxbox->ungrab();
-
 }
 
 
-void FluxboxWindow::mapNotifyEvent(XMapEvent *ne) {
-    if ((ne->window == client.window) && (! ne->override_redirect) && (visible)) {
+void FluxboxWindow::mapNotifyEvent(XMapEvent &ne) {
+    if (ne.window == client.window && (! ne.override_redirect) && (visible)) {
         Fluxbox *fluxbox = Fluxbox::instance();
         fluxbox->grab();
         if (! validateClient())
             return;
 
-        if (decorations.titlebar)
-            positionButtons();
-
         setState(NormalState);		
 			
-        redrawAllButtons();
-
         if (transient || screen->doFocusNew())
             setInputFocus();
         else
             setFocusFlag(false);			
-		
+
+	if (focused)
+            m_frame.setFocus(true);
 
         visible = true;
         iconic = false;
@@ -2576,52 +1604,40 @@ void FluxboxWindow::mapNotifyEvent(XMapEvent *ne) {
     }
 }
 
-//------------------- unmapNotify ------------------
-// Unmaps frame window and client window if 
-// event.window == client.window
-// Returns true if *this should die
-// else false
-//-------------------------------------------------
-bool FluxboxWindow::unmapNotifyEvent(XUnmapEvent *ue) {
-    if (ue->window != client.window)
-        return false;	
+/**
+   Unmaps frame window and client window if 
+   event.window == client.window
+   Returns true if *this should die
+   else false
+*/
+void FluxboxWindow::unmapNotifyEvent(XUnmapEvent &ue) {
+    if (ue.window != client.window)
+        return;
 	
 #ifdef DEBUG
-    fprintf(stderr,
-            I18n::instance()->getMessage(
-                FBNLS::WindowSet, FBNLS::WindowUnmapNotify,
-                "FluxboxWindow::unmapNotifyEvent() for 0x%lx\n"),
-            client.window);
+    cerr<<__FILE__<<": unmapNotifyEvent() 0x"<<hex<<client.window<<dec<<endl;
 #endif // DEBUG
 
     restore(false);
 
-    return true; // make sure this one deletes
 
 }
 
-//----------- destroyNotifyEvent -------------
-// Checks if event is for client.window.
-// Unmaps frame.window and returns true for destroy
-// of this FluxboxWindow else returns false.
-//--------------------------------------------
-bool FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent *de) {
-    if (de->window == client.window) {
+/**
+   Checks if event is for client.window.
+*/
+void FluxboxWindow::destroyNotifyEvent(XDestroyWindowEvent &de) {
+    if (de.window == client.window) {
 #ifdef DEBUG
         cerr<<__FILE__<<"("<<__LINE__<<"): DestroyNotifyEvent this="<<this<<endl;
 #endif // DEBUG
-        XUnmapWindow(display, frame.window);		
-        return true;
+        m_frame.hide();
     }
-    return false;
+
 }
 
 
 void FluxboxWindow::propertyNotifyEvent(Atom atom) {
-    Fluxbox *fluxbox = Fluxbox::instance();
-
-    if (! validateClient()) 
-        return;
 
     switch(atom) {
     case XA_WM_CLASS:
@@ -2630,7 +1646,7 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
         break;
 
     case XA_WM_TRANSIENT_FOR:
-        checkTransient();
+        updateTransientInfo();
         reconfigure();
 
         break;
@@ -2640,18 +1656,15 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
         break;
 
     case XA_WM_ICON_NAME:
-        getWMIconName();
+        updateIconNameFromClient();
         if (iconic)
             screen->iconUpdate();
         updateIcon();
         break;
 
     case XA_WM_NAME:
-        getWMName();
-
-        if (decorations.titlebar)
-            redrawLabel();
-
+        updateTitleFromClient();
+ 
         if (hasTab()) // update tab
             getTab()->draw(false);
 
@@ -2686,31 +1699,26 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
  
     	}
 
-        int x = frame.x, y = frame.y;
-        unsigned int w = frame.width, h = frame.height;
+        // save old values
+        int x = m_frame.x(), y = m_frame.y();
+        unsigned int w = m_frame.width(), h = m_frame.height();
 
         upsize();
 
-        if ((x != frame.x) || (y != frame.y) ||
-            (w != frame.width) || (h != frame.height))
+        // reconfigure if the old values changed
+        if ((x != m_frame.x()) || (y != m_frame.y()) ||
+            (w != m_frame.width()) || (h != m_frame.height()))
             reconfigure();
 
         break; 
     }
 
     default:
-        if (atom == fluxbox->getWMProtocolsAtom()) {
+        if (atom == FbAtoms::instance()->getWMProtocolsAtom()) {
             getWMProtocols();
-
-            if (decorations.close && !findTitleButton(Fluxbox::CLOSE)) {	
-                createButton(Fluxbox::CLOSE, FluxboxWindow::closePressed_cb, 
-                             FluxboxWindow::closeButton_cb, FluxboxWindow::closeDraw_cb);
-
-                if (decorations.titlebar)
-                    positionButtons(true);
-                if (m_windowmenu.get())
-                    m_windowmenu->reconfigure();
-            }
+            // reset window actions
+            screen->setupWindowActions(*this);
+            //!!TODO  check this area
         } 
         break;
     }
@@ -2718,407 +1726,216 @@ void FluxboxWindow::propertyNotifyEvent(Atom atom) {
 }
 
 
-void FluxboxWindow::exposeEvent(XExposeEvent *ee) {
-    if (frame.label == ee->window && decorations.titlebar)
-        redrawLabel();
-    else 
-        redrawAllButtons();
-
+void FluxboxWindow::exposeEvent(XExposeEvent &ee) {
+    m_frame.exposeEvent(ee);
 }
 
 
-void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent *cr) {
-    if (cr->window == client.window) {
-        Fluxbox *fluxbox = Fluxbox::instance();
-        fluxbox->grab();
+void FluxboxWindow::configureRequestEvent(XConfigureRequestEvent &cr) {
+    if (cr.window == client.window) {
         if (! validateClient())
             return;
 
-        int cx = frame.x, cy = frame.y;
-        unsigned int cw = frame.width, ch = frame.height;
+        int cx = m_frame.x(), cy = m_frame.y();
+        unsigned int cw = m_frame.width(), ch = m_frame.height();
 
-        if (cr->value_mask & CWBorderWidth)
-            client.old_bw = cr->border_width;
+        if (cr.value_mask & CWBorderWidth)
+            client.old_bw = cr.border_width;
 
-        if (cr->value_mask & CWX)
-            cx = cr->x - frame.mwm_border_w - screen->getBorderWidth();
+        if (cr.value_mask & CWX)
+            cx = cr.x;// - frame_mwm_border_w - screen->getBorderWidth();
 
-        if (cr->value_mask & CWY)
-            cy = cr->y - frame.y_border - frame.mwm_border_w -
-                screen->getBorderWidth();
+        if (cr.value_mask & CWY)
+            cy = cr.y - m_frame.titlebar().height(); // - frame_mwm_border_w - screen->getBorderWidth();
 
-        if (cr->value_mask & CWWidth)
-            cw = cr->width + (frame.mwm_border_w * 2);
+        if (cr.value_mask & CWWidth)
+            cw = cr.width;// + (frame_mwm_border_w * 2);
 
-        if (cr->value_mask & CWHeight) {
-            ch = cr->height + (frame.y_border + (frame.mwm_border_w * 2) +
-                               screen->getBorderWidth()) * decorations.border + 
-                frame.handle_h*decorations.handle;			
+        if (cr.value_mask & CWHeight) {
+            ch = cr.height;
         }
-        if (frame.x != cx || frame.y != cy ||
-            frame.width != cw || frame.height != ch) {
-            configure(cx, cy, cw, ch);
-            if (tab)
-                tab->resize();
+
+        if (m_frame.x() != cx || m_frame.y() != cy ||
+            m_frame.width() != cw || m_frame.height() != ch) {
+            moveResize(cx, cy, cw, ch);
         }
-        if (cr->value_mask & CWStackMode) {
-            switch (cr->detail) {
+
+        if (cr.value_mask & CWStackMode) {
+            switch (cr.detail) {
             case Above:
             case TopIf:
             default:
-                if (iconic)
-                    deiconify();
-//!!TODO check this and the line below..
-//				if (tab)
-//					tab->raise();
-                screen->getWorkspace(workspace_number)->raiseWindow(this);
+                raise();
                 break;
 
             case Below:
             case BottomIf:
-                if (iconic)
-                    deiconify();
-
-//				if (tab)
-//					tab->raise();
-                screen->getWorkspace(workspace_number)->lowerWindow(this);
+                lower();
                 break;
             }
         }
-
-        fluxbox->ungrab();
     }
 }
 
 
-void FluxboxWindow::buttonPressEvent(XButtonEvent *be) {
-    Fluxbox *fluxbox = Fluxbox::instance();
-    fluxbox->grab();
-	
-    if (! validateClient())	
-        return;
-	
-    if (be->button == 1 || (be->button == 3 && be->state == Mod1Mask)) {
-        if ((! focused) && (! screen->isSloppyFocus()))	 //check focus
+void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
+
+    if (be.button == 1 || (be.button == 3 && be.state == Mod1Mask)) {
+        if ((! focused) && (! screen->isSloppyFocus())) { //check focus 
             setInputFocus(); 
-		
-        //Redraw buttons
-        for (unsigned int i=0; i<buttonlist.size(); i++) {
-            if (be->window == buttonlist[i].win && buttonlist[i].draw)
-                buttonlist[i].draw(this, be->window, true);
         }
 
-        if (frame.plate == be->window) {
+        if (m_frame.clientArea() == be.window) {
 			
             if (m_windowmenu.get() && m_windowmenu->isVisible()) //hide menu if its visible
                 m_windowmenu->hide();
-            //raise tab first, if there is any, so the focus on windows get 
-            //right and dont "hide" the tab behind other windows
-            if (tab)
-                tab->raise();
-			
-            screen->getWorkspace(workspace_number)->raiseWindow(this);
 
-            XAllowEvents(display, ReplayPointer, be->time);
+            raise();
+
+            XAllowEvents(display, ReplayPointer, be.time);
 			
         } else {
-		
-            if (frame.title == be->window || frame.label == be->window) {
-                if (((be->time - lastButtonPressTime) <=
-                     fluxbox->getDoubleClickInterval()) ||
-                    (be->state & ControlMask)) {
-                    lastButtonPressTime = 0;
-                    shade();
-                    if (tab) //shade windows in the tablist too
-                        tab->shade();
-                } else
-                    lastButtonPressTime = be->time;			
-            }
-			
-			
-            frame.grab_x = be->x_root - frame.x - screen->getBorderWidth();
-            frame.grab_y = be->y_root - frame.y - screen->getBorderWidth();
+				
+            button_grab_x = be.x_root - m_frame.x() - screen->getBorderWidth();
+            button_grab_y = be.y_root - m_frame.y() - screen->getBorderWidth();
 
             if (m_windowmenu.get() && m_windowmenu->isVisible())
                 m_windowmenu->hide();
-            //raise tab first if there is any
-            if (hasTab())
-                tab->raise();
-		
-            screen->getWorkspace(workspace_number)->raiseWindow(this);
-        }
-    } else if (be->button == 2 && be->window == frame.label) {
-        screen->getWorkspace(workspace_number)->lowerWindow(this);
-        if (hasTab())
-            getTab()->lower(); //lower the tab AND it's windows
-
-    } else if (m_windowmenu.get() && be->button == 3 &&
-               (frame.title == be->window || frame.label == be->window ||
-                frame.handle == be->window)) {
-
-        int mx = 0, my = 0;
-
-        if (frame.title == be->window || frame.label == be->window) {
-            mx = be->x_root - (m_windowmenu->width() / 2);
-            my = frame.y + frame.title_h;
-        } else if (frame.handle == be->window) {
-            mx = be->x_root - (m_windowmenu->width() / 2);
-            my = frame.y + frame.y_handle - m_windowmenu->height();
-        } else {
-            bool buttonproc=false;
-			
-            if (buttonproc)
-                mx = be->x_root - (m_windowmenu->width() / 2);
-
-            if (be->y <= (signed) frame.bevel_w)
-                my = frame.y + frame.y_border;
-            else
-                my = be->y_root - (m_windowmenu->height() / 2);
-        }
 
-        if (mx > (signed) (frame.x + frame.width - m_windowmenu->width()))
-            mx = frame.x + frame.width - m_windowmenu->width();
-        if (mx < frame.x)
-            mx = frame.x;
-
-        if (my > (signed) (frame.y + frame.y_handle - m_windowmenu->height()))
-            my = frame.y + frame.y_handle - m_windowmenu->height();
-        if (my < (signed) (frame.y + ((decorations.titlebar) ? frame.title_h :
-                                      frame.y_border)))
-            my = frame.y +
-                ((decorations.titlebar) ? frame.title_h : frame.y_border);
-
-        if (m_windowmenu.get()) {
-            if (! m_windowmenu->isVisible()) { // if not window menu is visible then show it
-                showMenu(mx, my);
-            } else //else hide menu
-                m_windowmenu->hide(); 
-        }
-		
-    } else if (be->button == 4) { //scroll to tab right
-        if (tab && tab->next()) {
-            tab->next()->getWindow()->setInputFocus();
-            screen->getWorkspace(workspace_number)->raiseWindow(tab->next()->getWindow());
-        }
-    } else if (be->button == 5) { //scroll to tab left
-        if (tab && tab->prev()) {
-            tab->prev()->getWindow()->setInputFocus();
-            screen->getWorkspace(workspace_number)->raiseWindow(tab->prev()->getWindow());
+            raise();
         }
+    } else if (be.button == 2 && be.window == m_frame.label()) {
+        lower();
     }
-	
-    fluxbox->ungrab();
 }
 
 
-void FluxboxWindow::buttonReleaseEvent(XButtonEvent *re) {
-    Fluxbox *fluxbox = Fluxbox::instance();
-    fluxbox->grab();
-
-    if (! validateClient())
-        return;
-
+void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) {
     if (isMoving())
         stopMoving();		
     else if (isResizing())
         stopResizing();
-    else if (re->window == frame.window) {
-        if (re->button == 2 && re->state == Mod1Mask)
+    else if (re.window == m_frame.window()) {
+        if (re.button == 2 && re.state == Mod1Mask)
             XUngrabPointer(display, CurrentTime);
-    } else {
-        if ((re->x >= 0) && ((unsigned) re->x <= frame.button_w) &&
-            (re->y >= 0) && ((unsigned) re->y <= frame.button_h)) {
-            for (unsigned int i=0; i<buttonlist.size(); i++) {
-                if (re->window == buttonlist[i].win &&
-                    buttonlist[i].released) {
-                    buttonlist[i].released(this, re);	
-                    break;					
-                }
-            }
-        } 
-        redrawAllButtons();
     }
-
-    fluxbox->ungrab();
 }
 
 
-void FluxboxWindow::motionNotifyEvent(XMotionEvent *me) {
-    if ((me->state & Button1Mask) && functions.move &&
-        (frame.title == me->window || frame.label == me->window ||
-         frame.handle == me->window || frame.window == me->window) && !isResizing()) {
+void FluxboxWindow::motionNotifyEvent(XMotionEvent &me) {
+    if ((me.state & Button1Mask) && functions.move &&
+        (m_frame.titlebar() == me.window || m_frame.label() == me.window ||
+         m_frame.handle() == me.window || m_frame.window() == me.window) && !isResizing()) {
 			 
         if (! isMoving()) {
-            startMoving(me->window);			
+            startMoving(me.window);
         } else {			
-            int dx = me->x_root - frame.grab_x, dy = me->y_root - frame.grab_y;
+            int dx = me.x_root - button_grab_x, 
+                dy = me.y_root - button_grab_y;
 
             dx -= screen->getBorderWidth();
             dy -= screen->getBorderWidth();
 
-            if (screen->getEdgeSnapThreshold()) {
-                int drx = screen->getWidth() - (dx + frame.snap_w);
-
-                if (dx > 0 && dx < drx && dx < screen->getEdgeSnapThreshold()) 
-                    dx = 0;
-                else if (drx > 0 && drx < screen->getEdgeSnapThreshold())
-                    dx = screen->getWidth() - frame.snap_w;
-
-                int dtty, dbby, dty, dby;
-                switch (screen->getToolbarPlacement()) {
-                case Toolbar::TOPLEFT:
-                case Toolbar::TOPCENTER:
-                case Toolbar::TOPRIGHT:
-                    dtty = screen->getToolbar()->exposedHeight() +
-                        screen->getBorderWidth();
-                    dbby = screen->getHeight();
-                    break;
-
-                default:
-                    dtty = 0;
-                    dbby = screen->getToolbar()->y();
-                    break;
-                }
-
-                dty = dy - dtty;
-                dby = dbby - (dy + frame.snap_h);
-
-                if (dy > 0 && dty < screen->getEdgeSnapThreshold())
-                    dy = dtty;
-                else if (dby > 0 && dby < screen->getEdgeSnapThreshold())
-                    dy = dbby - frame.snap_h;
-            }
             // Warp to next or previous workspace?, must have moved sideways some
-            int moved_x=me->x_root - frame.resize_x;
+            int moved_x = me.x_root - last_resize_x;
             // save last event point
-            frame.resize_x = me->x_root;
-            frame.resize_y = me->y_root;
+            last_resize_x = me.x_root;
+            last_resize_y = me.y_root;
             if (moved_x && screen->isWorkspaceWarping()) {
                 int cur_id = screen->getCurrentWorkspaceID();
                 int new_id = cur_id;
                 const int warpPad = screen->getEdgeSnapThreshold();
-                if (me->x_root >= int(screen->getWidth()) - warpPad - 1 &&
-                    frame.x < int(me->x_root - frame.grab_x - screen->getBorderWidth())) {
+                if (me.x_root >= int(screen->getWidth()) - warpPad - 1 &&
+                    m_frame.x() < int(me.x_root - button_grab_x - screen->getBorderWidth())) {
                     //warp right
                     new_id = (cur_id + 1) % screen->getCount();
-                    dx = -me->x_root;
-                } else if (me->x_root <= warpPad &&
-                           frame.x > int(me->x_root - frame.grab_x - screen->getBorderWidth())) {
+                    dx = - me.x_root;
+                } else if (me.x_root <= warpPad &&
+                           m_frame.x() > int(me.x_root - button_grab_x - screen->getBorderWidth())) {
                     //warp left
                     new_id = (cur_id - 1 + screen->getCount()) % screen->getCount();
-                    dx = screen->getWidth() - me->x_root-1;
+                    dx = screen->getWidth() - me.x_root-1;
                 }
+
                 if (new_id != cur_id) {
                     XWarpPointer(display, None, None, 0, 0, 0, 0, dx, 0);
 
                     screen->changeWorkspaceID(new_id);
 
-                    frame.resize_x = me->x_root+dx;
-                    if (!screen->doOpaqueMove()) {
-                        dx += frame.move_x; // for rectangle in correct position
-                    } else {
-                        dx += frame.x; // for window in correct position
-                    }
+                    last_resize_x = me.x_root + dx;
+                    
+                    dx += m_frame.x(); // for window in correct position
+                
                 }
             }
 
+            /*
+              if (! screen->doOpaqueMove()) {
+              XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
+              frame.move_x, frame.move_y, frame.resize_w, frame.resize_h);
 
-            if (! screen->doOpaqueMove()) {
-                XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                               frame.move_x, frame.move_y, frame.resize_w, frame.resize_h);
-
-                frame.move_x = dx;
-                frame.move_y = dy;
+              frame.move_x = dx;
+              frame.move_y = dy;
 
-                XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                               frame.move_x, frame.move_y, frame.resize_w,
-                               frame.resize_h);
-            } else {
-                configure(dx, dy, frame.width, frame.height);
-            }
+              XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
+              frame.move_x, frame.move_y, frame.resize_w,
+              frame.resize_h);
+              } else {
+            */
+            moveResize(dx, dy, m_frame.width(), m_frame.height());
+            //			}
 
             if (screen->doShowWindowPos())
                 screen->showPosition(dx, dy);
         } // end if moving
     } else if (functions.resize &&
-               (((me->state & Button1Mask) && (me->window == frame.right_grip ||
-                                               me->window == frame.left_grip)) ||
-                me->window == frame.window)) {
-        bool left = (me->window == frame.left_grip);
+               (((me.state & Button1Mask) && (me.window == m_frame.gripRight() ||
+                                              me.window == m_frame.gripLeft())) ||
+                me.window == m_frame.window())) {
+		
+        bool left = (me.window == m_frame.gripLeft());
 
         if (! resizing) {			
-            startResizing(me, left); 
+            startResizing(me.window, me.x, me.y, left); 
         } else if (resizing) {
+            // draw over old rect
             XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                           frame.resize_x, frame.resize_y,
-                           frame.resize_w-1, frame.resize_h-1);
+                           last_resize_x, last_resize_y,
+                           last_resize_w - 1, last_resize_h-1);
+
 
-            int gx, gy;
+            // move rectangle
+            int gx = 0, gy = 0;
 
-            frame.resize_h = frame.height + (me->y - frame.grab_y);
-            if (frame.resize_h < 1)
-                frame.resize_h = 1;
+            last_resize_h = m_frame.height() + (me.y - button_grab_y);
+            if (last_resize_h < 1)
+                last_resize_h = 1;
 
             if (left) {
-                frame.resize_x = me->x_root - frame.grab_x;
-                if (frame.resize_x > (signed) (frame.x + frame.width))
-                    frame.resize_x = frame.resize_x + frame.width - 1;
+                last_resize_x = me.x_root - button_grab_x;
+                if (last_resize_x > (signed) (m_frame.x() + m_frame.width()))
+                    last_resize_x = last_resize_x + m_frame.width() - 1;
 
                 left_fixsize(&gx, &gy);
             } else {
-                frame.resize_w = frame.width + (me->x - frame.grab_x);
-                if (frame.resize_w < 1)
-                    frame.resize_w = 1;
+                last_resize_w = m_frame.width() + (me.x - button_grab_x);
+                if (last_resize_w < 1) // clamp to 1
+                    last_resize_w = 1;
 
                 right_fixsize(&gx, &gy);
             }
 
+            // draw resize rectangle
             XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                           frame.resize_x, frame.resize_y,
-                           frame.resize_w-1, frame.resize_h-1);
+                           last_resize_x, last_resize_y,
+                           last_resize_w - 1, last_resize_h - 1);
 
             if (screen->doShowWindowPos())
                 screen->showGeometry(gx, gy);
         }
     }
-}
-
-
-#ifdef		SHAPE
-void FluxboxWindow::shapeEvent(XShapeEvent *) {
-    Fluxbox *fluxbox = Fluxbox::instance();
-	
-    if (fluxbox->hasShapeExtensions()) {
-        if (frame.shaped) {			
-            fluxbox->grab();
-            if (! validateClient())
-                return;
-            XShapeCombineShape(display, frame.window, ShapeBounding,
-                               frame.mwm_border_w, frame.y_border +
-                               frame.mwm_border_w, client.window,
-                               ShapeBounding, ShapeSet);
-
-            int num = 1;
-            XRectangle xrect[2];
-            xrect[0].x = xrect[0].y = 0;
-            xrect[0].width = frame.width;
-            xrect[0].height = frame.y_border;
-
-            if (decorations.handle) {
-                xrect[1].x = 0;
-                xrect[1].y = frame.y_handle;
-                xrect[1].width = frame.width;
-                xrect[1].height = frame.handle_h + screen->getBorderWidth();
-                num++;
-            }
 
-            XShapeCombineRectangles(display, frame.window, ShapeBounding, 0, 0,
-                                    xrect, num, ShapeUnion, Unsorted);
-            fluxbox->ungrab();
-        }
-    }
 }
-#endif // SHAPE
 
 // TODO: functions should not be affected by decoration
 void FluxboxWindow::setDecoration(Decoration decoration) {
@@ -3141,8 +1958,7 @@ void FluxboxWindow::setDecoration(Decoration decoration) {
             decorations.menu = true;
         functions.resize = functions.move = functions.iconify =
             functions.maximize = true;
-        XMapSubwindows(display, frame.window);
-        XMapWindow(display, frame.window);
+        m_frame.show();
 
 	break;
 
@@ -3151,8 +1967,7 @@ void FluxboxWindow::setDecoration(Decoration decoration) {
             functions.move = functions.iconify = true;
         decorations.border = decorations.handle = decorations.maximize =
             functions.resize = functions.maximize = false;
-        XMapSubwindows(display, frame.window);
-        XMapWindow(display, frame.window);
+        m_frame.show();
 	break;
 
     case DECOR_TOOL:
@@ -3160,7 +1975,6 @@ void FluxboxWindow::setDecoration(Decoration decoration) {
         decorations.iconify = decorations.border = decorations.handle =
             decorations.maximize = functions.resize = functions.maximize =
             functions.iconify = false;
-        decorate();
 	break;
     }
 
@@ -3212,41 +2026,43 @@ void FluxboxWindow::startMoving(Window win) {
         m_windowmenu->hide();
 
     fluxbox->maskWindowEvents(client.window, this);
+    /* TODO: opaque moving
+       if (! screen->doOpaqueMove()) {
+       fluxbox->grab();
 
-    if (! screen->doOpaqueMove()) {
-        fluxbox->grab();
-
-        frame.move_x = frame.x;
-        frame.move_y = frame.y;
-        frame.move_ws = screen->getCurrentWorkspaceID();
-        frame.resize_w = frame.width + screen->getBorderWidth2x();
-        frame.resize_h = ((shaded) ? frame.title_h : frame.height) +
-            screen->getBorderWidth2x();
+       frame.move_x = frame.x;
+       frame.move_y = frame.y;
+       frame.move_ws = screen->getCurrentWorkspaceID();
+       frame.resize_w = frame.width + screen->getBorderWidth2x();
+       frame.resize_h = ((shaded) ? frame.title_h : frame.height) +
+       screen->getBorderWidth2x();
 
-        if (screen->doShowWindowPos())
-            screen->showPosition(frame.x, frame.y);
+       if (screen->doShowWindowPos())
+       screen->showPosition(frame.x, frame.y);
 
-        XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                       frame.move_x, frame.move_y,
-                       frame.resize_w, frame.resize_h);
-    }
+       XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
+       frame.move_x, frame.move_y,
+       frame.resize_w, frame.resize_h);
+       }*/
 }
 
 void FluxboxWindow::stopMoving() {
     moving = false;
     Fluxbox *fluxbox = Fluxbox::instance();
-					
+
     fluxbox->maskWindowEvents(0, (FluxboxWindow *) 0);
 
-    if (! screen->doOpaqueMove()) {
-        XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                       frame.move_x, frame.move_y, frame.resize_w,
-                       frame.resize_h);
+    /* TODO: non opaque moving
+       if (! screen->doOpaqueMove()) {
+       XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
+       frame.move_x, frame.move_y, frame.resize_w,
+       frame.resize_h);
 
-        configure(frame.move_x, frame.move_y, frame.width, frame.height);
-        fluxbox->ungrab();
-    } else
-        configure(frame.x, frame.y, frame.width, frame.height);
+       configure(frame.move_x, frame.move_y, frame.width, frame.height);
+       fluxbox->ungrab();
+       } else
+    */
+    moveResize(m_frame.x(), m_frame.y(), m_frame.width(), m_frame.height());
 
     screen->hideGeometry();
     XUngrabPointer(display, CurrentTime);
@@ -3255,70 +2071,30 @@ void FluxboxWindow::stopMoving() {
 }
 
 void FluxboxWindow::pauseMoving() {
-    screen->hideGeometry(); // otherwise our window gets raised above it
-    if (screen->doOpaqueMove()) {
-        return;
-    }
-
-    // remove old rectangle
-    XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                   frame.move_x, frame.move_y, frame.resize_w, frame.resize_h);
 
-    Fluxbox::instance()->ungrab();
-    if (workspace_number != frame.move_ws) {
-        // get it out of view
-        frame.save_x = frame.x;
-        frame.save_y = frame.y;
-        frame.x = screen->getWidth()/2;
-        frame.y = screen->getHeight()+screen->getTabHeight()+10; // +10 to be safe
-        configure(frame.x, frame.y, frame.width, frame.height);
-    }
 }
 
 
 void FluxboxWindow::resumeMoving() {
-    if (screen->doOpaqueMove()) {
-        setInputFocus();
-        screen->raiseFocus();
-        if (screen->doShowWindowPos())
-            screen->showPosition(frame.x, frame.y);
-        return;
-    }
 
-    if (workspace_number != frame.move_ws) {
-        frame.x = frame.save_x;
-        frame.y = frame.save_y;
-    } else {
-        // back on home workspace, display window
-        configure(frame.x, frame.y, frame.width, frame.height);
-    }
-    Fluxbox::instance()->grab();
-    setInputFocus();
-    screen->raiseFocus();
-    if (screen->doShowWindowPos())
-        screen->showPosition(frame.move_x, frame.move_y);
-    XSync(display, false);
-    XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                   frame.move_x, frame.move_y, frame.resize_w,
-                   frame.resize_h);
 }
 
 
-void FluxboxWindow::startResizing(XMotionEvent *me, bool left) {
+void FluxboxWindow::startResizing(Window win, int x, int y, bool left) {
     resizing = true;
     Fluxbox *fluxbox = Fluxbox::instance();
-    XGrabPointer(display, me->window, false, ButtonMotionMask |	ButtonReleaseMask, 
+    XGrabPointer(display, win, false, ButtonMotionMask | ButtonReleaseMask, 
                  GrabModeAsync, GrabModeAsync, None,
-                 ((left) ? fluxbox->getLowerLeftAngleCursor() : fluxbox->getLowerRightAngleCursor()),
+                 (left ? fluxbox->getLowerLeftAngleCursor() : fluxbox->getLowerRightAngleCursor()),
                  CurrentTime);
 
-    int gx, gy;
-    frame.grab_x = me->x - screen->getBorderWidth();
-    frame.grab_y = me->y - screen->getBorderWidth2x();
-    frame.resize_x = frame.x;
-    frame.resize_y = frame.y;
-    frame.resize_w = frame.width + screen->getBorderWidth2x();
-    frame.resize_h = frame.height + screen->getBorderWidth2x();
+    int gx = 0, gy = 0;
+    button_grab_x = x - screen->getBorderWidth();
+    button_grab_y = y - screen->getBorderWidth2x();
+    last_resize_x = m_frame.x();
+    last_resize_y = m_frame.y();
+    last_resize_w = m_frame.width() + screen->getBorderWidth2x();
+    last_resize_h = m_frame.height() + screen->getBorderWidth2x();
 
     if (left)
         left_fixsize(&gx, &gy);
@@ -3329,33 +2105,29 @@ void FluxboxWindow::startResizing(XMotionEvent *me, bool left) {
         screen->showGeometry(gx, gy);
 
     XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                   frame.resize_x, frame.resize_y,
-                   frame.resize_w-1, frame.resize_h-1);
+                   last_resize_x, last_resize_y,
+                   last_resize_w - 1, last_resize_h - 1);
 }
 
 void FluxboxWindow::stopResizing(Window win) {
     resizing = false;
 	
     XDrawRectangle(display, screen->getRootWindow(), screen->getOpGC(),
-                   frame.resize_x, frame.resize_y,
-                   frame.resize_w-1, frame.resize_h-1);
+                   last_resize_x, last_resize_y,
+                   last_resize_w - 1, last_resize_h - 1);
 
     screen->hideGeometry();
 
-    if (win && win == frame.left_grip)
+    if (win && win == m_frame.gripLeft())
         left_fixsize();
     else
         right_fixsize();
 
 	
-    configure(frame.resize_x, frame.resize_y,
-              frame.resize_w - screen->getBorderWidth2x(),
-              frame.resize_h - screen->getBorderWidth2x());
+    moveResize(last_resize_x, last_resize_y,
+               last_resize_w - screen->getBorderWidth2x(),
+               last_resize_h - screen->getBorderWidth2x());
 	
-    if (tab)
-        tab->resize();
-			
-    Fluxbox::instance()->ungrab();
     XUngrabPointer(display, CurrentTime);
 }
 
@@ -3371,128 +2143,14 @@ void FluxboxWindow::updateIcon() {
     }
 }
 
-void FluxboxWindow::createTitlebar() {
-
-    frame.title = createChildWindow(frame.window); //create titlebar win
-    if (decorations.titlebar) {	//have titlebar decorations?		
-        Fluxbox *fb = Fluxbox::instance();
-        fb->saveWindowSearch(frame.title, this);	//save titlebar win
-        frame.label = createChildWindow(frame.title); //create label win in titlebar
-        fb->saveWindowSearch(frame.label, this);	//save label win
-    }
-}
-
-void FluxboxWindow::destroyTitlebar() {
-    Fluxbox *fb = Fluxbox::instance();
-	
-    while ( !buttonlist.empty()) {	//destroy all buttons on titlebar
-        fb->removeWindowSearch(buttonlist.back().win);	
-        XDestroyWindow(display, buttonlist.back().win);
-        buttonlist.pop_back();
-    }
-	
-    if (frame.title) {
-        if (frame.ftitle) {
-            image_ctrl->removeImage(frame.ftitle);
-            frame.ftitle = 0;
-        }
-
-        if (frame.utitle) {
-            image_ctrl->removeImage(frame.utitle);
-            frame.utitle = 0;
-        }
-
-        if (frame.flabel) {
-            image_ctrl->removeImage(frame.flabel);
-            frame.flabel = 0;
-        }
-
-        if( frame.ulabel) {
-            image_ctrl->removeImage(frame.ulabel);
-            frame.ulabel = 0;
-        }
-
-        fb->removeWindowSearch(frame.label);
-        fb->removeWindowSearch(frame.title);
-
-        XDestroyWindow(display, frame.label);
-        frame.label = 0;
-        XDestroyWindow(display, frame.title);
-        frame.title = 0;
-    }
-
-	
-}
-
-void FluxboxWindow::createHandle() {
-
-    if (!decorations.handle)
-        return;
-		
-    Fluxbox *fluxbox = Fluxbox::instance();
-    frame.handle = createChildWindow(frame.window); //create handle win
-    fluxbox->saveWindowSearch(frame.handle, this);	//save handle win
-
-    frame.left_grip = // create left handle
-        createChildWindow(frame.handle, fluxbox->getLowerLeftAngleCursor());
-    fluxbox->saveWindowSearch(frame.left_grip, this); //save left handle
-
-    frame.right_grip = // create right handle
-        createChildWindow(frame.handle, fluxbox->getLowerRightAngleCursor());
-    fluxbox->saveWindowSearch(frame.right_grip, this); //save right handle
-	
-}
-
-void FluxboxWindow::destroyHandle() {
-    if (frame.fhandle) {
-        image_ctrl->removeImage(frame.fhandle);
-        frame.fhandle = 0;
-    }
-
-    if (frame.uhandle) {
-        image_ctrl->removeImage(frame.uhandle);
-        frame.uhandle = 0;
-    }
-
-    if (frame.fgrip) {
-        image_ctrl->removeImage(frame.fgrip);
-        frame.fgrip = 0;
-    }
-
-    if (frame.ugrip) {
-        image_ctrl->removeImage(frame.ugrip);
-        frame.ugrip = 0;
-    }
-    Fluxbox *fluxbox = Fluxbox::instance();
-
-    if (frame.right_grip != 0) {
-        fluxbox->removeWindowSearch(frame.right_grip);
-        XDestroyWindow(display, frame.right_grip);
-        frame.right_grip = 0;
-    }
-	
-    if (frame.left_grip != 0) {
-        fluxbox->removeWindowSearch(frame.left_grip);
-        XDestroyWindow(display, frame.left_grip);
-        frame.left_grip = 0;	
-    }
-	
-    if (frame.handle != 0) {
-        fluxbox->removeWindowSearch(frame.handle);
-        XDestroyWindow(display, frame.handle);
-        frame.handle = 0;
-    }
-
-}
-
-void FluxboxWindow::checkTransient() {
+void FluxboxWindow::updateTransientInfo() {
     // remove us from parent
     if (client.transient_for != 0) {
         client.transient_for->client.transients.remove(this);
     }
     client.transient_for = 0;
 	
-	// determine if this is a transient window
+    // determine if this is a transient window
     Window win;
     if (!XGetTransientForHint(display, client.window, &win))
         return;
@@ -3537,22 +2195,26 @@ void FluxboxWindow::restore(bool remap) {
 
     restoreGravity();
 
-    XUnmapWindow(display, frame.window);
+    m_frame.hide();
+    // make sure the frame doesn't change client window anymore
+    m_frame.removeClient();
+
     XUnmapWindow(display, client.window);
 
+    // restore old border width
     XSetWindowBorderWidth(display, client.window, client.old_bw);
+
     XEvent dummy;
     if (! XCheckTypedWindowEvent(display, client.window, ReparentNotify,
                                  &dummy)) {
 #ifdef DEBUG
-        fprintf(stderr,
-                I18n::instance()->getMessage(
-                    FBNLS::WindowSet, FBNLS::WindowUnmapNotifyReparent,		
-                    "FluxboxWindow::restore: reparent 0x%lx to "
-                    "root.\n"), client.window);
+        cerr<<"FluxboxWindow::restore: reparent 0x"<<hex<<client.window<<dec<<"to root"<<endl;
 #endif // DEBUG
+
+        // reparent to screen window
         XReparentWindow(display, client.window, screen->getRootWindow(),
-			client.x, client.y);
+			m_frame.x(), m_frame.y());
+
     }
 
     if (remap)
@@ -3562,124 +2224,80 @@ void FluxboxWindow::restore(bool remap) {
 
 
 void FluxboxWindow::timeout() {
-    if (tab)
-        tab->raise();
-    screen->getWorkspace(workspace_number)->raiseWindow(this);
+    raise();
 }
 
 
-void FluxboxWindow::changeBlackboxHints(BaseDisplay::BlackboxHints *net) {
-    if ((net->flags & BaseDisplay::ATTRIB_SHADED) &&
+void FluxboxWindow::changeBlackboxHints(const BaseDisplay::BlackboxHints &net) {
+    if ((net.flags & BaseDisplay::ATTRIB_SHADED) &&
         ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_SHADED) !=
-         (net->attrib & BaseDisplay::ATTRIB_SHADED)))
+         (net.attrib & BaseDisplay::ATTRIB_SHADED)))
         shade();
 
-    if ((net->flags & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)) &&
+    if ((net.flags & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)) &&
         ((blackbox_attrib.attrib & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)) !=
-         (net->attrib & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)))) {
+         (net.attrib & (BaseDisplay::ATTRIB_MAXVERT | BaseDisplay::ATTRIB_MAXHORIZ)))) {
         if (maximized) {
-            maximize(0);
+            maximize();
         } else {
-            int m = 0;
+            if ((net.flags & BaseDisplay::ATTRIB_MAXHORIZ) && (net.flags & BaseDisplay::ATTRIB_MAXVERT))
+            	maximize();
+            else if (net.flags & BaseDisplay::ATTRIB_MAXVERT)
+                maximizeVertical();
+            else if (net.flags & BaseDisplay::ATTRIB_MAXHORIZ)
+                maximizeHorizontal();
 
-            if ((net->flags & BaseDisplay::ATTRIB_MAXHORIZ) && (net->flags & BaseDisplay::ATTRIB_MAXVERT))
-                m = ((net->attrib & (BaseDisplay::ATTRIB_MAXHORIZ | BaseDisplay::ATTRIB_MAXVERT)) ?	1 : 0);
-            else if (net->flags & BaseDisplay::ATTRIB_MAXVERT)
-                m = ((net->attrib & BaseDisplay::ATTRIB_MAXVERT) ? 2 : 0);
-            else if (net->flags & BaseDisplay::ATTRIB_MAXHORIZ)
-                m = ((net->attrib & BaseDisplay::ATTRIB_MAXHORIZ) ? 3 : 0);
-
-            maximize(m);
         }
     }
 
-    if ((net->flags & BaseDisplay::ATTRIB_OMNIPRESENT) &&
+    if ((net.flags & BaseDisplay::ATTRIB_OMNIPRESENT) &&
         ((blackbox_attrib.attrib & BaseDisplay::ATTRIB_OMNIPRESENT) !=
-         (net->attrib & BaseDisplay::ATTRIB_OMNIPRESENT)))
+         (net.attrib & BaseDisplay::ATTRIB_OMNIPRESENT)))
         stick();
 
-    if ((net->flags & BaseDisplay::ATTRIB_WORKSPACE) &&
-        (workspace_number !=  net->workspace)) {
+    if ((net.flags & BaseDisplay::ATTRIB_WORKSPACE) &&
+        (workspace_number !=  net.workspace)) {
 
         if (getTab()) // disconnect from tab chain before sending it to another workspace
             getTab()->disconnect();
 
-        screen->reassociateWindow(this, net->workspace, true);
+        screen->reassociateWindow(this, net.workspace, true);
 
-        if (screen->getCurrentWorkspaceID() != net->workspace)
+        if (screen->getCurrentWorkspaceID() != net.workspace)
             withdraw();
         else 
             deiconify();
     }
 
-    if (net->flags & BaseDisplay::ATTRIB_DECORATION) {
-        old_decoration = static_cast<Decoration>(net->decoration);
+    if (net.flags & BaseDisplay::ATTRIB_DECORATION) {
+        old_decoration = static_cast<Decoration>(net.decoration);
         setDecoration(old_decoration);
     }
 
 }
 
-
 void FluxboxWindow::upsize() {
+    m_frame.setBevel(screen->getBevelWidth());
+    m_frame.handle().resize(m_frame.handle().width(), screen->getHandleWidth());
+    m_frame.gripLeft().resize(m_frame.buttonHeight(), screen->getHandleWidth());
+    m_frame.gripRight().resize(m_frame.gripLeft().width(), m_frame.gripLeft().height());
     // convert client.width/height into frame sizes
-
-    frame.bevel_w = screen->getBevelWidth();
-    frame.mwm_border_w = screen->getFrameWidth() * decorations.border;
-	
-    frame.title_h = screen->getWindowStyle()->font.height() + 
-        (frame.bevel_w*2 + 2)*decorations.titlebar;
-
-    frame.label_h = (frame.title_h - (frame.bevel_w * 2)) * decorations.titlebar;
-    frame.button_w = frame.button_h = frame.label_h - 2;
-
-    frame.y_border = (frame.title_h + screen->getBorderWidth()) * decorations.titlebar;
-    frame.border_h = client.height + (frame.mwm_border_w * 2);
-
-    frame.y_handle = frame.y_border + frame.border_h +
-        (screen->getBorderWidth() * decorations.handle);
-    frame.handle_h = decorations.handle * screen->getHandleWidth();
-
-    frame.grip_w = (frame.button_h * 2) * decorations.handle;
-    frame.grip_h = screen->getHandleWidth() * decorations.handle;
-
-    frame.width = client.width + (frame.mwm_border_w * 2);
-    frame.height = frame.y_handle + frame.handle_h;
-
-    frame.snap_w = frame.width + screen->getBorderWidth2x();
-    frame.snap_h = frame.height + screen->getBorderWidth2x();
+    m_frame.resizeForClient(client.width, client.height);
+ 
 }
 
 
+///TODO
 void FluxboxWindow::downsize() {
-    // convert frame.width/height into client sizes
-
-    frame.y_handle = frame.height - frame.handle_h;
-    frame.border_h = frame.y_handle - frame.y_border -
-        (screen->getBorderWidth() * decorations.handle);
-
-    client.x = frame.x + frame.mwm_border_w + screen->getBorderWidth();
-    client.y = frame.y + frame.y_border + frame.mwm_border_w +
-        screen->getBorderWidth();
-
-    client.width = frame.width - (frame.mwm_border_w * 2);
-    client.height = frame.height - frame.y_border -
-        (frame.mwm_border_w * 2) - frame.handle_h -
-        (screen->getBorderWidth() * decorations.handle);
-
-    frame.y_handle = frame.border_h + frame.y_border + screen->getBorderWidth();
-
-    frame.snap_w = frame.width + screen->getBorderWidth2x();
-    frame.snap_h = frame.height + screen->getBorderWidth2x();
+	
 }
 
 
 void FluxboxWindow::right_fixsize(int *gx, int *gy) {
     // calculate the size of the client window and conform it to the
     // size specified by the size hints of the client window...
-    int dx = frame.resize_w - client.base_width - (frame.mwm_border_w * 2) -
-        screen->getBorderWidth2x();
-    int dy = frame.resize_h - frame.y_border - client.base_height -
-        frame.handle_h - (screen->getBorderWidth() * (2+decorations.border)) - (frame.mwm_border_w * 2);
+    int dx = last_resize_w - client.base_width;
+    int dy = last_resize_h - client.base_height;
 
     if (dx < (signed) client.min_width)
         dx = client.min_width;
@@ -3690,6 +2308,7 @@ void FluxboxWindow::right_fixsize(int *gx, int *gy) {
     if (client.max_height > 0 && (unsigned) dy > client.max_height)
         dy = client.max_height;
 
+    // make it snap
     dx /= client.width_inc;
     dy /= client.height_inc;
 
@@ -3699,39 +2318,48 @@ void FluxboxWindow::right_fixsize(int *gx, int *gy) {
     dx = (dx * client.width_inc) + client.base_width;
     dy = (dy * client.height_inc) + client.base_height;
 
-    frame.resize_w = dx + (frame.mwm_border_w * 2) + screen->getBorderWidth2x();
-    frame.resize_h = dy + frame.y_border + frame.handle_h +
-        (frame.mwm_border_w * 2) +	(screen->getBorderWidth() *
-                                         (2+decorations.border));
+    last_resize_w = dx;
+    last_resize_h = dy;
 }
 
-
 void FluxboxWindow::left_fixsize(int *gx, int *gy) {
-    // calculate the size of the client window and conform it to the
-    // size specified by the size hints of the client window...
-    int dx = frame.x + frame.width - frame.resize_x - client.base_width -
-        (frame.mwm_border_w * 2);
-    int dy = frame.resize_h - frame.y_border - client.base_height -
-        frame.handle_h - (screen->getBorderWidth() * (2+decorations.border)) - (frame.mwm_border_w * 2);
+    int dx = m_frame.width() + m_frame.x() - last_resize_x;
+    int dy = last_resize_h - client.base_height;
+
+    // check minimum size
+    if (dx < static_cast<signed int>(client.min_width))
+        dx = client.min_width;
+    if (dy < static_cast<signed int>(client.min_height))
+        dy = client.min_height;
+
+    // check maximum size
+    if (client.max_width > 0 && dx > static_cast<signed int>(client.max_width))
+        dx = client.max_width;
+    if (client.max_height > 0 && dy > static_cast<signed int>(client.max_height))
+        dy = client.max_height;
 
-    if (dx < (signed) client.min_width) dx = client.min_width;
-    if (dy < (signed) client.min_height) dy = client.min_height;
-    if (client.max_width > 0 && (unsigned) dx > client.max_width) dx = client.max_width;
-    if (client.max_height > 0 && (unsigned) dy > client.max_height) dy = client.max_height;
+    // make sure we have valid increment
+    if (client.width_inc == 0)
+        client.width_inc = 1;
+    if (client.height_inc == 0)
+        client.height_inc = 1;
 
+    // set snaping
     dx /= client.width_inc;
     dy /= client.height_inc;
 
-    if (gx) *gx = dx;
-    if (gy) *gy = dy;
+    // set return values
+    if (gx != 0)
+        *gx = dx;
+    if (gy != 0)
+        *gy = dy;
 
-    dx = (dx * client.width_inc) + client.base_width;
-    dy = (dy * client.height_inc) + client.base_height;
+    // snapping
+    dx = dx * client.width_inc + client.base_width;
+    dy = dy * client.height_inc + client.base_height;
 
-    frame.resize_w = dx + (frame.mwm_border_w * 2) + screen->getBorderWidth2x();
-    frame.resize_x = frame.x + frame.width - frame.resize_w +
-        screen->getBorderWidth2x();
-    frame.resize_h = dy + frame.y_border + frame.handle_h +
-        (frame.mwm_border_w * 2) + (screen->getBorderWidth() *
-                                    (2+decorations.border));
+    // update last resize 
+    last_resize_w = dx;
+    last_resize_h = dy;
+    last_resize_x = m_frame.x() + m_frame.width() - last_resize_w;	
 }
-- 
cgit v0.11.2