From 19875e5a5ba474387971ede597cdc4aa7454d4c0 Mon Sep 17 00:00:00 2001
From: rathnor <rathnor>
Date: Mon, 3 Mar 2003 21:51:13 +0000
Subject: Add code for toolbar modes

---
 ChangeLog                |   9 +-
 src/AtomHandler.hh       |  23 ++--
 src/Ewmh.cc              |  14 +--
 src/Ewmh.hh              |  18 +--
 src/FbTk/EventManager.cc |   5 +-
 src/Gnome.cc             |  14 +--
 src/Gnome.hh             |  18 +--
 src/IconBar.cc           |  25 +++-
 src/IconBar.hh           |   4 +-
 src/Screen.cc            | 138 ++++++++++++++--------
 src/Screen.hh            |  27 +++--
 src/Toolbar.cc           |  75 +++++++-----
 src/Toolbar.hh           |  14 ++-
 src/ToolbarHandler.cc    | 295 +++++++++++++++++++++++++++++++++++++++++++++++
 src/ToolbarHandler.hh    |  93 +++++++++++++++
 src/Window.cc            |  22 ++--
 src/fluxbox.cc           |  19 ++-
 17 files changed, 657 insertions(+), 156 deletions(-)
 create mode 100644 src/ToolbarHandler.cc
 create mode 100644 src/ToolbarHandler.hh

diff --git a/ChangeLog b/ChangeLog
index f3e9af4..b8797a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,12 @@
 (Format: Year/Month/Day)
 Changes for 0.9.1:
-
--------------------------------------------
+*03/03/03:
+   * Add code for Toolbar modes (Simon)
+     AtomHandler.hh EventManager.cc Ewmh.hh/cc Gnome.hh/cc 
+     IconBar.hh/cc Screen.hh/cc Toolbar.hh/cc ToolbarHandler.hh/cc 
+     Window.cc fluxbox.cc
+ 
+------------------------------------------- 
 Changes for 0.9.0:
 *03/02/23:
    * Fixed auto hide option for toolbar menu (Henrik)
diff --git a/src/AtomHandler.hh b/src/AtomHandler.hh
index 03d6b33..fcc0cd4 100644
--- a/src/AtomHandler.hh
+++ b/src/AtomHandler.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: AtomHandler.hh,v 1.6 2003/02/02 16:32:37 rathnor Exp $
+// $Id: AtomHandler.hh,v 1.7 2003/03/03 21:51:00 rathnor Exp $
 
 #ifndef ATOMHANDLER_HH
 #define ATOMHANDLER_HH
@@ -32,23 +32,24 @@ class BScreen;
 class AtomHandler {
 public:
     virtual ~AtomHandler() { }
-	
-    virtual void initForScreen(const BScreen &screen) = 0;
+
+    virtual void initForScreen(BScreen &screen) = 0;
     virtual void setupWindow(FluxboxWindow &win) = 0;
-	
-    virtual void updateClientList(const BScreen &screen) = 0;
-    virtual void updateWorkspaceNames(const BScreen &screen) = 0;
-    virtual void updateCurrentWorkspace(const BScreen &screen) = 0;
-    virtual void updateWorkspaceCount(const BScreen &screen) = 0;
-	
+
+    virtual void updateClientList(BScreen &screen) = 0;
+    virtual void updateWorkspaceNames(BScreen &screen) = 0;
+    virtual void updateCurrentWorkspace(BScreen &screen) = 0;
+    virtual void updateWorkspaceCount(BScreen &screen) = 0;
+
+    virtual void updateWindowClose(FluxboxWindow &win) = 0;
     virtual void updateWorkspace(FluxboxWindow &win) = 0;
     virtual void updateState(FluxboxWindow &win) = 0;
     virtual void updateHints(FluxboxWindow &win) = 0;
     virtual void updateLayer(FluxboxWindow &win) = 0;
 
     virtual bool checkClientMessage(const XClientMessageEvent &ce, 
-                                    BScreen * const screen, FluxboxWindow * const win) = 0;
-	
+                                    BScreen * screen, FluxboxWindow * const win) = 0;
+
     /// should this object be updated or not?
     bool update() const { return m_update; }
 protected:
diff --git a/src/Ewmh.cc b/src/Ewmh.cc
index 278016c..210122d 100644
--- a/src/Ewmh.cc
+++ b/src/Ewmh.cc
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Ewmh.cc,v 1.10 2003/02/02 16:32:37 rathnor Exp $
+// $Id: Ewmh.cc,v 1.11 2003/03/03 21:51:00 rathnor Exp $
 
 #include "Ewmh.hh" 
 
@@ -42,7 +42,7 @@ Ewmh::~Ewmh() {
     }
 }
 
-void Ewmh::initForScreen(const BScreen &screen) {
+void Ewmh::initForScreen(BScreen &screen) {
     Display *disp = BaseDisplay::getXDisplay();
 
     Window wincheck = XCreateSimpleWindow(disp,
@@ -119,7 +119,7 @@ void Ewmh::setupWindow(FluxboxWindow &win) {
     }
 }
 
-void Ewmh::updateClientList(const BScreen &screen) {
+void Ewmh::updateClientList(BScreen &screen) {
     size_t num=0;
 
     BScreen::Workspaces::const_iterator workspace_it = screen.getWorkspacesList().begin();
@@ -165,7 +165,7 @@ void Ewmh::updateClientList(const BScreen &screen) {
     delete [] wl;
 }
 
-void Ewmh::updateWorkspaceNames(const BScreen &screen) {
+void Ewmh::updateWorkspaceNames(BScreen &screen) {
     XTextProperty text;
     const size_t number_of_desks = screen.getWorkspaceNames().size();
 	
@@ -186,7 +186,7 @@ void Ewmh::updateWorkspaceNames(const BScreen &screen) {
         delete [] names[i];	
 }
 
-void Ewmh::updateCurrentWorkspace(const BScreen &screen) {
+void Ewmh::updateCurrentWorkspace(BScreen &screen) {
     size_t workspace = screen.getCurrentWorkspaceID();
     XChangeProperty(BaseDisplay::getXDisplay(), 
                     screen.getRootWindow(),
@@ -195,7 +195,7 @@ void Ewmh::updateCurrentWorkspace(const BScreen &screen) {
 
 }
 
-void Ewmh::updateWorkspaceCount(const BScreen &screen) {
+void Ewmh::updateWorkspaceCount(BScreen &screen) {
     size_t numworkspaces = screen.getCount();
     XChangeProperty(BaseDisplay::getXDisplay(), screen.getRootWindow(),
                     m_net_number_of_desktops, XA_CARDINAL, 32, PropModeReplace,
@@ -225,7 +225,7 @@ void Ewmh::updateWorkspace(FluxboxWindow &win) {
 }
 
 // return true if we did handle the atom here
-bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * const screen, FluxboxWindow * const win) {
+bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win) {
 
     if (ce.message_type == m_net_wm_desktop) {
         if (screen == 0)
diff --git a/src/Ewmh.hh b/src/Ewmh.hh
index 74b201c..b21e4a4 100644
--- a/src/Ewmh.hh
+++ b/src/Ewmh.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Ewmh.hh,v 1.5 2003/02/02 16:32:37 rathnor Exp $
+// $Id: Ewmh.hh,v 1.6 2003/03/03 21:51:00 rathnor Exp $
 
 #include "AtomHandler.hh"
 
@@ -31,13 +31,13 @@ public:
 
     Ewmh();
     ~Ewmh();
-    void initForScreen(const BScreen &screen);
+    void initForScreen(BScreen &screen);
     void setupWindow(FluxboxWindow &win);
 	
-    void updateClientList(const BScreen &screen);
-    void updateWorkspaceNames(const BScreen &screen);
-    void updateCurrentWorkspace(const BScreen &screen);
-    void updateWorkspaceCount(const BScreen &screen);
+    void updateClientList(BScreen &screen);
+    void updateWorkspaceNames(BScreen &screen);
+    void updateCurrentWorkspace(BScreen &screen);
+    void updateWorkspaceCount(BScreen &screen);
 
     void updateState(FluxboxWindow &win);
     void updateLayer(FluxboxWindow &win);
@@ -46,7 +46,11 @@ public:
 
 
     bool checkClientMessage(const XClientMessageEvent &ce, 
-                            BScreen * const screen, FluxboxWindow * const win);
+                            BScreen * screen, FluxboxWindow * const win);
+
+    //ignore these ones
+    void updateWindowClose(FluxboxWindow &win) {}
+
 private:
 	
     enum { STATE_REMOVE = 0, STATE_ADD = 1, STATE_TOGGLE = 2};
diff --git a/src/FbTk/EventManager.cc b/src/FbTk/EventManager.cc
index cd1ee68..3f28464 100644
--- a/src/FbTk/EventManager.cc
+++ b/src/FbTk/EventManager.cc
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: EventManager.cc,v 1.4 2003/02/23 14:30:18 fluxgen Exp $
+// $Id: EventManager.cc,v 1.5 2003/03/03 21:51:13 rathnor Exp $
 
 #include "EventManager.hh"
 #include "FbWindow.hh"
@@ -95,7 +95,8 @@ void EventManager::registerEventHandler(EventHandler &ev, Window win) {
 }
 
 void EventManager::unregisterEventHandler(Window win) {
-    m_eventhandlers.erase(win);
+    if (win != None)
+        m_eventhandlers.erase(win);
 }
 
 };
diff --git a/src/Gnome.cc b/src/Gnome.cc
index 54e7d45..c8d4a70 100644
--- a/src/Gnome.cc
+++ b/src/Gnome.cc
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Gnome.cc,v 1.11 2003/02/18 15:11:07 rathnor Exp $
+// $Id: Gnome.cc,v 1.12 2003/03/03 21:51:01 rathnor Exp $
 
 #include "Gnome.hh"
 
@@ -43,7 +43,7 @@ Gnome::~Gnome() {
     }
 }
 
-void Gnome::initForScreen(const BScreen &screen) {
+void Gnome::initForScreen(BScreen &screen) {
     Display *disp = BaseDisplay::getXDisplay();
     // create the GNOME window
     Window gnome_win = XCreateSimpleWindow(disp,
@@ -120,7 +120,7 @@ void Gnome::setupWindow(FluxboxWindow &win) {
 
 }
 
-void Gnome::updateClientList(const BScreen &screen) {
+void Gnome::updateClientList(BScreen &screen) {
     size_t num=0;
 
     BScreen::Workspaces::const_iterator workspace_it = screen.getWorkspacesList().begin();
@@ -162,7 +162,7 @@ void Gnome::updateClientList(const BScreen &screen) {
     delete wl;
 }
 
-void Gnome::updateWorkspaceNames(const BScreen &screen) {
+void Gnome::updateWorkspaceNames(BScreen &screen) {
     XTextProperty	text;
     int number_of_desks = screen.getWorkspaceNames().size();
 	
@@ -185,7 +185,7 @@ void Gnome::updateWorkspaceNames(const BScreen &screen) {
         delete [] names[i];
 }
 
-void Gnome::updateCurrentWorkspace(const BScreen &screen) {
+void Gnome::updateCurrentWorkspace(BScreen &screen) {
     int workspace = screen.getCurrentWorkspaceID();
     XChangeProperty(BaseDisplay::getXDisplay(), 
                     screen.getRootWindow(),
@@ -195,7 +195,7 @@ void Gnome::updateCurrentWorkspace(const BScreen &screen) {
     updateClientList(screen); // make sure the client list is updated too
 }
 
-void Gnome::updateWorkspaceCount(const BScreen &screen) {
+void Gnome::updateWorkspaceCount(BScreen &screen) {
     int numworkspaces = screen.getCount();
     XChangeProperty(BaseDisplay::getXDisplay(), screen.getRootWindow(),
                     m_gnome_wm_win_workspace_count, XA_CARDINAL, 32, PropModeReplace,
@@ -242,7 +242,7 @@ void Gnome::updateHints(FluxboxWindow &win) {
 	
 }
 
-bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * const screen, FluxboxWindow * const win) {
+bool Gnome::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win) {
     if (ce.message_type == m_gnome_wm_win_workspace) {
 #ifdef DEBUG
         cerr<<__FILE__<<"("<<__LINE__<<"): Got workspace atom="<<ce.data.l[0]<<endl;
diff --git a/src/Gnome.hh b/src/Gnome.hh
index 2910dd6..e36cae2 100644
--- a/src/Gnome.hh
+++ b/src/Gnome.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Gnome.hh,v 1.5 2003/02/02 16:32:37 rathnor Exp $
+// $Id: Gnome.hh,v 1.6 2003/03/03 21:51:01 rathnor Exp $
 
 #ifndef GNOME_HH
 #define GNOME_HH
@@ -64,22 +64,24 @@ public:
 	
     Gnome();
     ~Gnome();
-    void initForScreen(const BScreen &screen);
+    void initForScreen(BScreen &screen);
     void setupWindow(FluxboxWindow &win);
 
-    void updateClientList(const BScreen &screen);
-    void updateWorkspaceNames(const BScreen &screen);
-    void updateCurrentWorkspace(const BScreen &screen);
-    void updateWorkspaceCount(const BScreen &screen);
+    void updateClientList(BScreen &screen);
+    void updateWorkspaceNames(BScreen &screen);
+    void updateCurrentWorkspace(BScreen &screen);
+    void updateWorkspaceCount(BScreen &screen);
 
     void updateState(FluxboxWindow &win);
     void updateLayer(FluxboxWindow &win);
     void updateHints(FluxboxWindow &win);
     void updateWorkspace(FluxboxWindow &win);
 
-
-    bool checkClientMessage(const XClientMessageEvent &ce, BScreen * const screen, FluxboxWindow * const win);
+    bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, FluxboxWindow * const win);
 	
+    // ignore these ones
+    void updateWindowClose(FluxboxWindow &win) {}
+
 private:
     void setLayer(FluxboxWindow *win, int layer);
     void setState(FluxboxWindow *win, int state);
diff --git a/src/IconBar.cc b/src/IconBar.cc
index ac0834f..39ef4a6 100644
--- a/src/IconBar.cc
+++ b/src/IconBar.cc
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: IconBar.cc,v 1.25 2003/02/23 14:29:08 fluxgen Exp $
+// $Id: IconBar.cc,v 1.26 2003/03/03 21:51:01 rathnor Exp $
 
 #include "IconBar.hh"
 #include "i18n.hh"
@@ -120,9 +120,9 @@ Window IconBar::delIcon(FluxboxWindow *fluxboxwin) {
         IconList::iterator it =
             std::find(m_iconlist.begin(), m_iconlist.end(), obj);
         if (it != m_iconlist.end()) {
-            m_iconlist.erase(it);								
+            m_iconlist.erase(it);
             retwin = obj->getIconWin();		
-            delete obj;				
+            delete obj;
             XDestroyWindow(m_display, retwin);
             repositionIcons();		
         }
@@ -131,6 +131,25 @@ Window IconBar::delIcon(FluxboxWindow *fluxboxwin) {
 }
 
 /**
+ * Removes all icons from list
+ * Return X Windows of the removed iconobjs
+ */
+IconBar::WindowList *IconBar::delAllIcons() {
+    Window retwin = None;
+    WindowList *ret = new WindowList();
+    while (!m_iconlist.empty()) {
+            IconBarObj *obj = m_iconlist.back();
+            m_iconlist.pop_back();
+            retwin = obj->getIconWin();
+            ret->push_back(retwin);
+            delete obj;
+            XDestroyWindow(m_display, retwin);
+    }
+    repositionIcons();
+    return ret;
+}
+
+/**
  renders theme to m_focus_pm
  with the size width * height
 */
diff --git a/src/IconBar.hh b/src/IconBar.hh
index 8a30f55..1ac3809 100644
--- a/src/IconBar.hh
+++ b/src/IconBar.hh
@@ -19,7 +19,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: IconBar.hh,v 1.10 2003/02/23 00:50:53 fluxgen Exp $
+// $Id: IconBar.hh,v 1.11 2003/03/03 21:51:03 rathnor Exp $
 
 #ifndef ICONBAR_HH
 #define ICONBAR_HH
@@ -52,12 +52,14 @@ private:
 class IconBar
 {
 public:
+    typedef std::list<Window> WindowList;
     IconBar(BScreen *scrn, Window parent, FbTk::Font &font);
     ~IconBar();
     void draw(); //TODO
     void reconfigure();
     Window addIcon(FluxboxWindow *fluxboxwin);
     Window delIcon(FluxboxWindow *fluxboxwin);
+    WindowList *delAllIcons();
     void buttonPressEvent(XButtonEvent *be);	
     FluxboxWindow *findWindow(Window w);
     IconBarObj *findIcon(FluxboxWindow * const fluxboxwin);
diff --git a/src/Screen.cc b/src/Screen.cc
index e39b28a..076965f 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Screen.cc,v 1.116 2003/02/23 12:02:30 fluxgen Exp $
+// $Id: Screen.cc,v 1.117 2003/03/03 21:51:04 rathnor Exp $
 
 
 #include "Screen.hh"
@@ -202,6 +202,26 @@ setFromString(const char *strval) {
         setDefaultValue();
 }
 
+template<>
+void Resource<ToolbarHandler::ToolbarMode>::
+setFromString(const char *strval) {
+    if (strcasecmp(strval, "Off") == 0) 
+        m_value = ToolbarHandler::OFF;
+    else if (strcasecmp(strval, "None") == 0) 
+        m_value = ToolbarHandler::NONE;
+    else if (strcasecmp(strval, "Icons") == 0) 
+        m_value = ToolbarHandler::ICONS;
+    else if (strcasecmp(strval, "WorkspaceIcons") == 0) 
+        m_value = ToolbarHandler::WORKSPACEICONS;
+    else if (strcasecmp(strval, "Workspace") == 0) 
+        m_value = ToolbarHandler::WORKSPACE;
+    else if (strcasecmp(strval, "AllWindows") == 0) 
+        m_value = ToolbarHandler::ALLWINDOWS;
+    else
+        setDefaultValue();
+}
+
+
 //--------- resource accessors --------------
 template<>
 string Resource<Tab::Alignment>::
@@ -260,6 +280,34 @@ getString() {
     return string("BottomCenter");
 }
 
+template<>
+string Resource<ToolbarHandler::ToolbarMode>::
+getString() {
+    switch (m_value) {
+    case ToolbarHandler::OFF:
+        return string("Off");
+        break;
+    case ToolbarHandler::NONE:
+        return string("None");
+        break;
+    case ToolbarHandler::LASTMODE:
+    case ToolbarHandler::ICONS:
+        return string("Icons");
+        break;
+    case ToolbarHandler::WORKSPACEICONS:
+        return string("Workspace");
+        break;
+    case ToolbarHandler::WORKSPACE:
+        return string("Workspace");
+        break;
+    case ToolbarHandler::ALLWINDOWS:
+        return string("AllWindows");
+        break;
+    }
+    // default string
+    return string("Icons");
+}
+
 namespace {
 
 class AddWorkspaceCmd:public FbTk::Command {
@@ -373,6 +421,7 @@ BScreen::ScreenResource::ScreenResource(ResourceManager &rm,
     toolbar_layernum(rm, Fluxbox::instance()->getDesktopLayer(), scrname+".toolbar.layer", altscrname+".Toolbar.Layer"),
     tab_placement(rm, Tab::PTOP, scrname+".tab.placement", altscrname+".Tab.Placement"),
     tab_alignment(rm, Tab::ALEFT, scrname+".tab.alignment", altscrname+".Tab.Alignment"),
+    toolbar_mode(rm, ToolbarHandler::ICONS, scrname+".toolbar.mode", altscrname+".Toolbar.Mode"),
     toolbar_on_head(rm, 0, scrname+".toolbar.onhead", altscrname+".Toolbar.onHead"),
     toolbar_placement(rm, Toolbar::BOTTOMCENTER, scrname+".toolbar.placement", altscrname+".Toolbar.Placement")
 {
@@ -390,7 +439,8 @@ BScreen::BScreen(ResourceManager &rm,
                              theme(0), m_windowtheme(scrn), 
                              m_menutheme(new FbTk::MenuTheme(scrn)),
                              resource(rm, screenname, altscreenname),
-                             m_root_theme(new RootTheme(*this))
+                             m_root_theme(new RootTheme(*this)),
+                             m_toolbarhandler(0)
 {
     Display *disp = FbTk::App::instance()->display();
 
@@ -524,31 +574,11 @@ BScreen::BScreen(ResourceManager &rm,
     m_slit.reset(new Slit(*this, *layerManager().getLayer(getSlitLayerNum())));
 #endif // SLIT
 
-    m_toolbar.reset(new Toolbar(*this, *layerManager().getLayer(getToolbarLayerNum())));
-    m_toolbar->setPlacement(*resource.toolbar_placement);
-    // setup toolbar width menu item
-    FbTk::MenuItem *toolbar_menuitem = new IntResMenuItem("Toolbar width percent",
-                                                          resource.toolbar_width_percent,
-                                                          0, 100); // min/max value
-    FbTk::RefCount<FbTk::Command> reconfig_toolbar(new FbTk::
-                                                   SimpleCommand<Toolbar>
-                                                   (*(m_toolbar.get()), &Toolbar::reconfigure));
-    FbTk::RefCount<FbTk::Command> save_resources(new FbTk::
-                                                 SimpleCommand<Fluxbox>
-                                                 (*Fluxbox::instance(), &Fluxbox::save_rc));
-    FbTk::MacroCommand *toolbar_menuitem_macro = new FbTk::MacroCommand();
-    toolbar_menuitem_macro->add(reconfig_toolbar);
-    toolbar_menuitem_macro->add(save_resources);
-
-    FbTk::RefCount<FbTk::Command> reconfig_toolbar_and_save_resource(toolbar_menuitem_macro);
+    m_toolbarhandler = new ToolbarHandler(*this, getToolbarMode());
 
-    toolbar_menuitem->setCommand(reconfig_toolbar_and_save_resource);    
+    if (getToolbar()) 
+        getToolbar()->setPlacement(*resource.toolbar_placement);
 
-    m_toolbar->menu().insert(toolbar_menuitem, 0);
-
-    m_toolbar->menu().insert(new BoolMenuItem("Auto hide", *resource.toolbar_auto_hide, reconfig_toolbar), 0);
-
-    
     setupWorkspacemenu(*this, *workspacemenu);
 
     m_configmenu.reset(createMenuFromScreen(*this));
@@ -556,7 +586,8 @@ BScreen::BScreen(ResourceManager &rm,
 
     workspacemenu->setItemSelected(2, true);
 
-    m_toolbar->reconfigure();
+    if (getToolbar() != 0)
+        getToolbar()->reconfigure();
 
     initMenu(); // create and initiate rootmenu
 
@@ -622,11 +653,13 @@ BScreen::BScreen(ResourceManager &rm,
         }
     }
 
-    if (! isSloppyFocus()) {
-        XSetInputFocus(disp, m_toolbar->getWindowID(),
+    if (! isSloppyFocus() && getToolbar() != 0) {
+        XSetInputFocus(disp, getToolbar()->getWindowID(),
                        RevertToParent, CurrentTime);
     }
 
+    // set the toolbarhandler after the windows are setup, so it catches their state properly
+
     XFree(children);
     XFlush(disp);
 }
@@ -668,6 +701,14 @@ BScreen::~BScreen() {
 
 }
 
+const FbTk::Menu &BScreen::getToolbarModemenu() const {
+    return m_toolbarhandler->getModeMenu();
+}
+
+FbTk::Menu &BScreen::getToolbarModemenu() {
+    return m_toolbarhandler->getModeMenu();
+}
+
 /// TODO
 unsigned int BScreen::getMaxLeft() const {
     return 0;
@@ -702,8 +743,8 @@ void BScreen::reconfigure() {
 
     FbTk::ThemeManager::instance().load(filename.c_str()); // new theme engine
 
-    if (m_toolbar.get())
-        m_toolbar->theme().font().setAntialias(*resource.antialias);
+    if (getToolbar())
+        getToolbar()->theme().font().setAntialias(*resource.antialias);
 
     theme->reconfigure(*resource.antialias);
     
@@ -758,10 +799,11 @@ void BScreen::reconfigure() {
 
 
     //    m_toolbar->setPlacement(*resource.toolbar_placement);
-    m_toolbar->reconfigure();
-    if (m_toolbar->theme().font().isAntialias() != *resource.antialias)
-        m_toolbar->theme().font().setAntialias(*resource.antialias);
-   
+    if (getToolbar() != 0) {
+        getToolbar()->reconfigure();
+        if (getToolbar()->theme().font().isAntialias() != *resource.antialias)
+            getToolbar()->theme().font().setAntialias(*resource.antialias);
+    }
 #ifdef SLIT    
     if (m_slit.get()) {
         m_slit->setPlacement(static_cast<Slit::Placement>(getSlitPlacement()));
@@ -808,12 +850,9 @@ void BScreen::updateWorkspaceNamesAtom() {
 void BScreen::addIcon(FluxboxWindow *w) {
     if (! w) return;
 
-    w->setWorkspace(-1);
     w->setWindowNumber(iconList.size());
 
     iconList.push_back(w);
-
-    m_toolbar->addIcon(w);
 }
 
 
@@ -829,11 +868,9 @@ void BScreen::removeIcon(FluxboxWindow *w) {
                 iconList.erase(it);
                 break;
             }
-	}
+        }
     }
-		
-    m_toolbar->delIcon(w);
-	
+    
     Icons::iterator it = iconList.begin();
     Icons::iterator it_end = iconList.end();
     for (int i = 0; it != it_end; ++it, ++i) {
@@ -873,8 +910,9 @@ int BScreen::addWorkspace() {
 		
     workspacemenu->update();
     saveWorkspaces(workspacesList.size());
-    m_toolbar->reconfigure();
-
+    if (getToolbar() != 0)
+        getToolbar()->reconfigure();
+    
     updateNetizenWorkspaceCount();	
 	
 	
@@ -901,7 +939,8 @@ int BScreen::removeLastWorkspace() {
     workspacesList.pop_back();		
     delete wkspc;
 
-    m_toolbar->reconfigure();
+    if (getToolbar() != 0)
+        getToolbar()->reconfigure();
 
     updateNetizenWorkspaceCount();
     saveWorkspaces(workspacesList.size());
@@ -949,7 +988,8 @@ void BScreen::changeWorkspaceID(unsigned int id) {
         current_workspace = getWorkspace(id);
 
         workspacemenu->setItemSelected(current_workspace->workspaceID() + 2, true);
-        m_toolbar->redrawWorkspaceLabel(true);
+        if (getToolbar() != 0)
+            getToolbar()->redrawWorkspaceLabel(true);
 
         current_workspace->showAll();
 
@@ -1309,7 +1349,7 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id, bool ig
 #endif // DEBUG
     }
 
-    if (w->getWorkspaceNumber() == wkspc_id)
+    if (!w->isIconic() && w->getWorkspaceNumber() == wkspc_id)
         return;
 
 
@@ -1781,11 +1821,9 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) {
     if (getSlit() != 0)
         menu.insert("Slit", &getSlit()->menu());
 #endif // SLIT
-
     menu.insert(i18n->getMessage(
-                                 ToolbarSet, ToolbarToolbarTitle,
-                                 "Toolbar"), &m_toolbar->menu());
-
+        ToolbarSet, ToolbarToolbarTitle,
+        "Toolbar"), &m_toolbarhandler->getToolbarMenu());
     menu.insert(new
                 BoolMenuItem(i18n->getMessage(
                                               ConfigmenuSet, ConfigmenuImageDithering,
diff --git a/src/Screen.hh b/src/Screen.hh
index 03a96b7..af60665 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Screen.hh,v 1.72 2003/02/23 00:55:07 fluxgen Exp $
+// $Id: Screen.hh,v 1.73 2003/03/03 21:51:06 rathnor Exp $
 
 #ifndef	 SCREEN_HH
 #define	 SCREEN_HH
@@ -36,6 +36,7 @@
 #include "FbWinFrameTheme.hh"
 #include "MultLayers.hh"
 #include "XLayerItem.hh"
+#include "ToolbarHandler.hh"
 #include "fluxbox.hh"
 
 #include <X11/Xlib.h>
@@ -78,7 +79,7 @@ public:
             int scrn, int number_of_layers);
     ~BScreen();
 
-    inline bool doToolbarAutoHide() const { return *resource.toolbar_auto_hide; }
+    inline bool &doToolbarAutoHide() { return *resource.toolbar_auto_hide; }
     inline Toolbar::Placement toolbarPlacement() const { return *resource.toolbar_placement; }
     inline bool isSloppyFocus() const { return (*resource.focus_model == Fluxbox::SLOPPYFOCUS); }
     inline bool isSemiSloppyFocus() const { return (*resource.focus_model == Fluxbox::SEMISLOPPYFOCUS); }
@@ -103,6 +104,8 @@ public:
     inline FbTk::ImageControl *getImageControl() { return image_control; }
     const FbTk::Menu * const getRootmenu() const { return m_rootmenu.get(); }
     FbTk::Menu * const getRootmenu() { return m_rootmenu.get(); }
+    const FbTk::Menu &getToolbarModemenu() const ;
+    FbTk::Menu &getToolbarModemenu() ;
 	
     inline const std::string &getRootCommand() const { return *resource.rootcommand; }
     inline Fluxbox::FocusModel getFocusModel() const { return *resource.focus_model; }
@@ -121,8 +124,11 @@ public:
     inline unsigned int getSlitOnHead() const { return resource.slit_on_head; }
     inline void saveSlitOnHead(unsigned int h) { resource.slit_on_head = h;  }
 
-    inline const Toolbar *getToolbar() const { return m_toolbar.get(); }
-    inline Toolbar *getToolbar() { return m_toolbar.get(); }
+    inline const Toolbar *getToolbar() const { return m_toolbarhandler->getToolbar(); }
+    inline Toolbar *getToolbar() { return m_toolbarhandler->getToolbar(); }
+
+    inline const ToolbarHandler &getToolbarHandler() const { return *m_toolbarhandler; }
+    inline ToolbarHandler &getToolbarHandler() { return *m_toolbarhandler; }
 
     inline Workspace *getWorkspace(unsigned int w) { return ( w < workspacesList.size() ? workspacesList[w] : 0); }
     inline Workspace *getCurrentWorkspace() { return current_workspace; }
@@ -175,6 +181,9 @@ public:
     inline int getToolbarOnHead() { return *resource.toolbar_on_head; }
 
     inline int getToolbarWidthPercent() const { return *resource.toolbar_width_percent; }
+    inline Resource<int> &getToolbarWidthPercentResource() { return resource.toolbar_width_percent; }
+    inline const Resource<int> &getToolbarWidthPercentResource() const { return resource.toolbar_width_percent; }
+    inline ToolbarHandler::ToolbarMode getToolbarMode() const { return *resource.toolbar_mode; }
     inline int getPlacementPolicy() const { return resource.placement_policy; }
     inline int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; }
     inline int getRowPlacementDirection() const { return resource.row_direction; }
@@ -191,16 +200,14 @@ public:
     inline void setRootColormapInstalled(Bool r) { root_colormap_installed = r;  }
     inline void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd;  }
     inline void saveFocusModel(Fluxbox::FocusModel model) { resource.focus_model = model; }
-    //DEL inline void saveSloppyFocus(bool s) { resource.sloppy_focus = s;  }
-    //DEL inline void saveSemiSloppyFocus(bool s) { resource.semi_sloppy_focus = s;  }
-    //DEL inline void saveAutoRaise(bool a) { resource.auto_raise = a;  }
     inline void saveWorkspaces(int w) { *resource.workspaces = w;  }
+
     inline void saveToolbarAutoHide(bool r) { *resource.toolbar_auto_hide = r;  }
     inline void saveToolbarWidthPercent(int w) { *resource.toolbar_width_percent = w;  }
+    inline void saveToolbarMode(ToolbarHandler::ToolbarMode m) { *resource.toolbar_mode = m; }
     inline void saveToolbarPlacement(Toolbar::Placement place) { *resource.toolbar_placement = place; }
     inline void saveToolbarOnHead(int head) { *resource.toolbar_on_head = head;  }
 
-
     inline void savePlacementPolicy(int p) { resource.placement_policy = p;  }
     inline void saveRowPlacementDirection(int d) { resource.row_direction = d;  }
     inline void saveColPlacementDirection(int d) { resource.col_direction = d;  }
@@ -358,7 +365,7 @@ private:
 #ifdef SLIT
     std::auto_ptr<Slit> m_slit;
 #endif // SLIT
-    std::auto_ptr<Toolbar> m_toolbar;
+
     Workspace *current_workspace;
     std::auto_ptr<FbTk::Menu> workspacemenu;
 
@@ -394,6 +401,7 @@ private:
 
         Resource<Tab::Placement> tab_placement;
         Resource<Tab::Alignment> tab_alignment;
+        Resource<ToolbarHandler::ToolbarMode> toolbar_mode;
         Resource<int> toolbar_on_head;
         Resource<Toolbar::Placement> toolbar_placement;
         bool slit_auto_hide;
@@ -410,6 +418,7 @@ private:
     } resource;
 
     std::auto_ptr<RootTheme> m_root_theme;
+    ToolbarHandler *m_toolbarhandler;
 };
 
 
diff --git a/src/Toolbar.cc b/src/Toolbar.cc
index 38e4bc3..1aa8764 100644
--- a/src/Toolbar.cc
+++ b/src/Toolbar.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Toolbar.cc,v 1.64 2003/02/23 19:13:22 fluxgen Exp $
+// $Id: Toolbar.cc,v 1.65 2003/03/03 21:51:07 rathnor Exp $
 
 #include "Toolbar.hh"
 
@@ -84,6 +84,7 @@ private:
     Toolbar::Placement m_place;
 };
 
+
 void setupMenus(Toolbar &tbar) {
     I18n *i18n = I18n::instance();
     using namespace FBNLS;
@@ -213,7 +214,7 @@ Toolbar::Frame::~Frame() {
     evm.remove(clock);
 }
 
-Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width):
+Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, FbTk::Menu &menu, size_t width):
     editing(false),
     hidden(scrn.doToolbarAutoHide()), 
     do_auto_hide(scrn.doToolbarAutoHide()),
@@ -222,8 +223,7 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width):
     image_ctrl(*scrn.getImageControl()),
     clock_timer(this), 	// get the clock updating every minute
     hide_timer(&hide_handler),
-    m_toolbarmenu(*scrn.menuTheme(), 
-                  scrn.getScreenNumber(), *scrn.getImageControl()),
+    m_toolbarmenu(menu),
     m_placementmenu(*scrn.menuTheme(),
                     scrn.getScreenNumber(), *scrn.getImageControl()),
     m_layermenu(*scrn.menuTheme(), 
@@ -267,9 +267,9 @@ Toolbar::Toolbar(BScreen &scrn, FbTk::XLayer &layer, size_t width):
     frame.base = frame.label = frame.wlabel = frame.clk = frame.button =
         frame.pbutton = None;
 
-		
-    if (Fluxbox::instance()->useIconBar())
-        m_iconbar.reset(new IconBar(&screen(), frame.window_label.window(), m_theme.font()));
+    //DEL/fix -> remove useIconBar resource
+//    if (Fluxbox::instance()->useIconBar())
+    m_iconbar.reset(new IconBar(&screen(), frame.window_label.window(), m_theme.font()));
 
 
     XMapSubwindows(display, frame.window.window());
@@ -325,7 +325,43 @@ void Toolbar::delIcon(FluxboxWindow *w) {
     if (m_iconbar.get() != 0)
         FbTk::EventManager::instance()->remove(m_iconbar->delIcon(w));
 }
-		
+
+void Toolbar::delAllIcons() {
+    if (m_iconbar.get() == 0)
+        return;
+
+    IconBar::WindowList *deleted = m_iconbar->delAllIcons();
+    IconBar::WindowList::iterator it = deleted->begin();
+    IconBar::WindowList::iterator it_end = deleted->end();
+    for (; it != it_end; ++it) {
+        FbTk::EventManager::instance()->remove(*it);
+    }
+    delete deleted;
+}
+    
+bool Toolbar::containsIcon(FluxboxWindow &win) {
+    return (m_iconbar->findIcon(&win) != 0);
+}
+
+void Toolbar::enableIconBar() {
+    // already on
+    if (m_iconbar.get() != 0) 
+        return;
+    m_iconbar.reset(new IconBar(&screen(), frame.window_label.window(), m_theme.font()));
+}
+
+void Toolbar::disableIconBar() {
+    // already off
+    if (m_iconbar.get() == 0) 
+        return;
+    
+    delAllIcons();
+
+    m_iconbar.reset(0); // destroy iconbar
+
+}
+
+
 void Toolbar::reconfigure() {
 
     if (do_auto_hide == false && 
@@ -592,29 +628,6 @@ void Toolbar::reconfigure() {
 
     m_toolbarmenu.reconfigure();
 
-    if (Fluxbox::instance()->useIconBar()) {
-        if (m_iconbar.get() == 0) { // create new iconbar if we don't have one
-            m_iconbar.reset(new IconBar(&screen(), frame.window_label.window(), m_theme.font()));
-            if (screen().getIconCount()) {
-                BScreen::Icons & l = screen().getIconList();
-                BScreen::Icons::iterator it = l.begin();
-                BScreen::Icons::iterator it_end = l.end();
-                for(; it != it_end; ++it) {
-                    addIcon(*it);
-                }
-            }
-			
-        } else 
-            m_iconbar->reconfigure();
-    } else if (m_iconbar.get() != 0) {
-        BScreen::Icons & l = screen().getIconList();
-        BScreen::Icons::iterator it = l.begin();
-        BScreen::Icons::iterator it_end = l.end();
-        for(; it != it_end; ++it)
-            delIcon(*it);
-
-        m_iconbar.reset(0); // destroy iconbar
-    }
 }
 
 
diff --git a/src/Toolbar.hh b/src/Toolbar.hh
index 2b9668d..9ed481b 100644
--- a/src/Toolbar.hh
+++ b/src/Toolbar.hh
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Toolbar.hh,v 1.25 2003/02/23 00:50:02 fluxgen Exp $
+// $Id: Toolbar.hh,v 1.26 2003/03/03 21:51:08 rathnor Exp $
 
 #ifndef	 TOOLBAR_HH
 #define	 TOOLBAR_HH
@@ -63,7 +63,7 @@ public:
     };
 
     /// create a toolbar on the screen with specific width
-    explicit Toolbar(BScreen &screen, FbTk::XLayer &layer, size_t width = 200);
+    explicit Toolbar(BScreen &screen, FbTk::XLayer &layer, FbTk::Menu &menu, size_t width = 200);
     /// destructor
     virtual ~Toolbar();
 
@@ -71,7 +71,13 @@ public:
     void addIcon(FluxboxWindow *w);
     /// remove icon from iconbar
     void delIcon(FluxboxWindow *w);
-	
+    /// remove all icons
+    void delAllIcons();
+    bool containsIcon(FluxboxWindow &win);
+
+    void enableIconBar();
+    void disableIconBar();
+
     inline const FbTk::Menu &menu() const { return m_toolbarmenu; }
     inline FbTk::Menu &menu() { return m_toolbarmenu; }
     inline FbTk::Menu &placementMenu() { return m_placementmenu; }
@@ -160,7 +166,7 @@ private:
     FbTk::ImageControl &image_ctrl; 
     FbTk::Timer clock_timer; ///< timer to update clock
     FbTk::Timer hide_timer; ///< timer to for auto hide toolbar
-    FbTk::Menu m_toolbarmenu;
+    FbTk::Menu &m_toolbarmenu;
     FbTk::Menu m_placementmenu;
     LayerMenu<Toolbar> m_layermenu;
     std::auto_ptr<IconBar> m_iconbar;
diff --git a/src/ToolbarHandler.cc b/src/ToolbarHandler.cc
new file mode 100644
index 0000000..f05f399
--- /dev/null
+++ b/src/ToolbarHandler.cc
@@ -0,0 +1,295 @@
+// ToolbarHandler for fluxbox
+// Copyright (c) 2003 Simon Bowden (rathnor at fluxbox.org)
+//                and Henrik Kinnunen (fluxgen at fluxbox.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+// $Id: ToolbarHandler.cc,v 1.1 2003/03/03 21:51:09 rathnor Exp $
+
+/**
+ * The ToolbarHandler class acts as a rough interface to the toolbar.
+ * It deals with whether it should be there or not, so anything that
+ * always needs to be accessible must come through the handler.
+ */
+
+#include "ToolbarHandler.hh"
+#include "Window.hh"
+#include "Screen.hh"
+#include "Workspace.hh"
+#include "MenuItem.hh"
+#include "Menu.hh"
+#include "FbCommands.hh"
+#include "RefCount.hh"
+#include "SimpleCommand.hh"
+#include "MacroCommand.hh"
+#include "IntResMenuItem.hh"
+#include "BoolMenuItem.hh"
+
+namespace {
+
+class ToolbarModeMenuItem : public FbTk::MenuItem {
+public:
+    ToolbarModeMenuItem(const char *label, ToolbarHandler &handler, ToolbarHandler::ToolbarMode mode, FbTk::RefCount<FbTk::Command> &cmd):
+        FbTk::MenuItem(label, cmd), m_handler(handler), m_mode(mode) {
+    }
+    bool isEnabled() const { return m_handler.getMode() != m_mode; }
+    void click(int button, int time) {
+        m_handler.setMode(m_mode);
+        FbTk::MenuItem::click(button, time);
+    }
+
+private:
+    ToolbarHandler &m_handler;
+    ToolbarHandler::ToolbarMode m_mode;
+};
+
+void setupModeMenu(FbTk::Menu &menu, ToolbarHandler &handler) {
+    //I18n *i18n = I18n::instance();
+    //using namespace FBNLS;
+    using namespace FbTk;
+
+    RefCount<Command> saverc_cmd(new SimpleCommand<Fluxbox>(
+        *Fluxbox::instance(), 
+        &Fluxbox::save_rc));
+    
+    //TODO: nls
+    menu.insert(new ToolbarModeMenuItem("Off", handler, 
+                                        ToolbarHandler::OFF, saverc_cmd));
+    menu.insert(new ToolbarModeMenuItem("None", handler, 
+                                        ToolbarHandler::NONE, saverc_cmd));
+    menu.insert(new ToolbarModeMenuItem("Icons", handler, 
+                                        ToolbarHandler::ICONS, saverc_cmd));
+    menu.insert(new ToolbarModeMenuItem("Workspace Icons", handler, 
+                                        ToolbarHandler::WORKSPACEICONS, saverc_cmd));
+    menu.insert(new ToolbarModeMenuItem("Workspace", handler, 
+                                        ToolbarHandler::WORKSPACE, saverc_cmd));
+    menu.insert(new ToolbarModeMenuItem("All Windows", handler, 
+                                        ToolbarHandler::ALLWINDOWS, saverc_cmd));
+    menu.update();
+}
+                
+}; // end anonymous namespace
+
+ToolbarHandler::ToolbarHandler(BScreen &screen, ToolbarMode mode) 
+    : m_screen(screen), m_mode(mode), m_toolbar(0), m_current_workspace(0),
+      m_modemenu(*screen.menuTheme(),
+                 screen.getScreenNumber(), *screen.getImageControl()),
+      m_toolbarmenu(*screen.menuTheme(),
+                 screen.getScreenNumber(), *screen.getImageControl())
+{
+    m_modemenu.setInternalMenu();
+    setupModeMenu(m_modemenu, *this);
+    setMode(mode, false); // the atomhandler part will initialise it shortly
+}
+
+void ToolbarHandler::setMode(ToolbarMode mode, bool initialise) {
+    if (mode < 0 || mode >= LASTMODE || (mode == m_mode && initialise)) return;
+    if (mode == OFF) {
+        m_toolbarmenu.removeAll();
+        //TODO: nls
+        m_toolbarmenu.insert("Mode...", &m_modemenu);
+        m_toolbar.reset(0);
+        m_toolbarmenu.update();
+        return;
+    } else if (!m_toolbar.get()) {
+        m_toolbarmenu.removeAll();
+
+        m_toolbarmenu.insert("Mode...", &m_modemenu);
+        m_toolbar.reset(new Toolbar(m_screen, 
+                                    *m_screen.layerManager().getLayer(m_screen.getToolbarLayerNum()), m_toolbarmenu));
+
+    }
+    
+
+    if (mode == NONE) {
+        // disableIconBar will clean up
+        m_toolbar->disableIconBar();
+    } else {
+        // rebuild it
+        // be sure the iconbar is on
+        m_toolbar->enableIconBar();
+        m_toolbar->delAllIcons();
+    }
+    // reset Toolbar, and reload it (initForScreen)
+    m_mode = mode;
+    if (initialise)
+        initForScreen(m_screen);
+}
+
+void ToolbarHandler::initForScreen(BScreen &screen) {
+    if (&m_screen != &screen) return;
+    switch (m_mode) {
+    case OFF:
+        break;
+    case NONE:
+        break;
+    case ALLWINDOWS:
+    {
+        BScreen::Workspaces::const_iterator workspace_it = m_screen.getWorkspacesList().begin();
+        BScreen::Workspaces::const_iterator workspace_it_end = m_screen.getWorkspacesList().end();
+        for (; workspace_it != workspace_it_end; ++workspace_it) {
+            Workspace::Windows &wins = (*workspace_it)->getWindowList();
+            Workspace::Windows::iterator wit = wins.begin();
+            Workspace::Windows::iterator wit_end = wins.end();
+            for (; wit != wit_end; ++wit) {
+                m_toolbar->addIcon(*wit);
+            }
+        }
+    }
+    // fall through and add icons
+    case LASTMODE:
+    case ICONS: 
+    {
+        BScreen::Icons &iconlist = m_screen.getIconList();
+        BScreen::Icons::iterator iconit = iconlist.begin();
+        BScreen::Icons::iterator iconit_end = iconlist.end();
+        for(; iconit != iconit_end; ++iconit) {
+            m_toolbar->addIcon(*iconit);
+        }
+    }
+    break;
+    case WORKSPACE:
+    {
+        Workspace::Windows &wins = m_screen.getCurrentWorkspace()->getWindowList();
+        Workspace::Windows::iterator wit = wins.begin();
+        Workspace::Windows::iterator wit_end = wins.end();
+        for (; wit != wit_end; ++wit) {
+            m_toolbar->addIcon(*wit);
+        }
+    }
+    // fall through and add icons for this workspace
+    case WORKSPACEICONS:
+    {
+        m_current_workspace = m_screen.getCurrentWorkspaceID();
+        
+        BScreen::Icons &wiconlist = m_screen.getIconList();
+        BScreen::Icons::iterator iconit = wiconlist.begin();
+        BScreen::Icons::iterator iconit_end = wiconlist.end();
+        for(; iconit != iconit_end; ++iconit) {
+            if ((*iconit)->getWorkspaceNumber() == m_current_workspace)
+                m_toolbar->addIcon(*iconit);
+        }
+    }
+    break;
+    }
+}
+
+void ToolbarHandler::setupWindow(FluxboxWindow &win) {
+    if (win.getScreen() != &m_screen) return;
+    switch (m_mode) {
+    case OFF:
+    case NONE:
+        break;
+    case WORKSPACE:
+        if (win.getWorkspaceNumber() == m_current_workspace)    
+            m_toolbar->addIcon(&win);
+        break;
+    case WORKSPACEICONS:
+        if (win.getWorkspaceNumber() != m_current_workspace) 
+            break;
+        // else fall through and add the icon
+    case LASTMODE:
+    case ICONS:
+        if (win.isIconic()) {
+            m_toolbar->addIcon(&win);
+        }
+        break;
+    case ALLWINDOWS:
+        m_toolbar->addIcon(&win);
+        break;
+    }
+}
+
+void ToolbarHandler::updateWindowClose(FluxboxWindow &win) {
+    if (win.getScreen() != &m_screen) return;
+    // check status of window (in current workspace, etc) and remove if necessary
+    switch (m_mode) {
+    case OFF:
+    case NONE:
+        break;
+    case WORKSPACEICONS:
+        if (win.getWorkspaceNumber() != m_current_workspace) 
+            break;
+        // else fall through and remove the icon
+    case LASTMODE:
+    case ICONS:
+        if (win.isIconic()) {
+            m_toolbar->delIcon(&win);
+        }
+        break;
+    case WORKSPACE:
+        if (win.getWorkspaceNumber() == m_current_workspace)
+            m_toolbar->delIcon(&win);
+        break;
+    case ALLWINDOWS:
+        m_toolbar->delIcon(&win);
+        break;
+    }
+}
+
+void ToolbarHandler::updateState(FluxboxWindow &win) {
+    if (win.getScreen() != &m_screen) return;
+
+    // this function only relevant for icons
+    switch (m_mode) {
+    case OFF:
+    case NONE:
+    case ALLWINDOWS:
+        break;
+    case WORKSPACE:
+    case WORKSPACEICONS:
+        if (win.getWorkspaceNumber() != m_current_workspace) break;
+        // else fall through and do the same as icons (knowing it is the right ws)
+    case LASTMODE:
+    case ICONS:
+        // if the window is iconic (it mustn't have been before), then add it
+        // else remove it
+        if (win.isIconic()) {
+            if (!m_toolbar->containsIcon(win)) {
+                m_toolbar->addIcon(&win);
+            }
+        } else {
+            m_toolbar->delIcon(&win);
+        }
+        break;
+    }
+}
+        
+
+void ToolbarHandler::updateWorkspace(FluxboxWindow &win) {
+    if (win.getScreen() != &m_screen) return;
+    // don't care about current workspace except if in workspace mode
+    if (m_mode != WORKSPACE) return;
+    if (win.getWorkspaceNumber() == m_current_workspace) {
+        m_toolbar->addIcon(&win);
+    } else {
+        // relies on the fact that this runs but does nothing if window isn't contained.
+        m_toolbar->delIcon(&win);
+    }
+}
+
+void ToolbarHandler::updateCurrentWorkspace(BScreen &screen) {
+    if (&screen != &m_screen) return;
+    // if only displaying current workspace, update list
+    // otherwise ignore it
+    if (m_mode != WORKSPACE && m_mode != WORKSPACEICONS) return;
+    m_toolbar->delAllIcons();
+    initForScreen(m_screen);
+}
+
diff --git a/src/ToolbarHandler.hh b/src/ToolbarHandler.hh
new file mode 100644
index 0000000..6e5f450
--- /dev/null
+++ b/src/ToolbarHandler.hh
@@ -0,0 +1,93 @@
+// ToolbarHandler for fluxbox
+// Copyright (c) 2003 Simon Bowden (rathnor at fluxbox.org)
+//                and Henrik Kinnunen (fluxgen at fluxbox.org)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+// $Id: ToolbarHandler.hh,v 1.1 2003/03/03 21:51:09 rathnor Exp $
+
+#ifndef TOOLBARHANDLER_HH
+#define TOOLBARHANDLER_HH
+
+#include "AtomHandler.hh"
+#include "Menu.hh"
+#include "Toolbar.hh"
+
+class FluxboxWindow;
+class BScreen;
+
+class ToolbarHandler : public AtomHandler {
+public:
+    enum ToolbarMode {
+        OFF=0,
+        NONE,
+        ICONS,
+	WORKSPACEICONS,
+        WORKSPACE,
+        ALLWINDOWS,
+        LASTMODE
+    };
+
+    ToolbarHandler(BScreen &screen, ToolbarMode mode);
+    ~ToolbarHandler() { }
+
+    void setMode(ToolbarMode mode, bool initialise = true);
+    ToolbarMode getMode() { return m_mode; };
+
+    inline const Toolbar *getToolbar() const { return m_toolbar.get(); }
+    inline Toolbar *getToolbar() { return m_toolbar.get(); }
+  
+
+    void initForScreen(BScreen &screen);
+    void setupWindow(FluxboxWindow &win);
+    
+    void updateState(FluxboxWindow &win);
+    void updateWindowClose(FluxboxWindow &win);
+    void updateWorkspace(FluxboxWindow &win);
+    void updateCurrentWorkspace(BScreen &screen);
+
+    // these ones don't affect us
+    void updateWorkspaceNames(BScreen &screen) {}
+    void updateWorkspaceCount(BScreen &screen) {}
+    void updateClientList(BScreen &screen) {}
+    void updateHints(FluxboxWindow &win) {}
+    void updateLayer(FluxboxWindow &win) {}
+
+    bool checkClientMessage(const XClientMessageEvent &ce, 
+                            BScreen * screen, FluxboxWindow * const win) { return false; }
+
+    inline FbTk::Menu &getModeMenu() { return m_modemenu; }
+    inline const FbTk::Menu &getModeMenu() const { return m_modemenu; }
+    inline FbTk::Menu &getToolbarMenu() { return m_toolbarmenu; }
+    inline const FbTk::Menu &getToolbarMenu() const { return m_toolbarmenu; }
+
+    inline BScreen &screen() { return m_screen; }
+    inline const BScreen &screen() const { return m_screen; }
+
+private:
+    BScreen &m_screen;
+    ToolbarMode m_mode;
+    std::auto_ptr<Toolbar> m_toolbar;
+    unsigned int m_current_workspace;
+
+    FbTk::Menu m_modemenu;
+    FbTk::Menu m_toolbarmenu;
+};
+
+#endif // TOOLBARHANDLER_HH
diff --git a/src/Window.cc b/src/Window.cc
index 9f5cf39..a950ae4 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: Window.cc,v 1.127 2003/02/23 13:58:36 rathnor Exp $
+// $Id: Window.cc,v 1.128 2003/03/03 21:51:09 rathnor Exp $
 
 #include "Window.hh"
 
@@ -377,7 +377,7 @@ FluxboxWindow::~FluxboxWindow() {
         Workspace *workspace = screen->getWorkspace(workspace_number);
         if (workspace)
             workspace->removeWindow(this);
-    } else //it's iconic
+    } else
         screen->removeIcon(this);
 	
     if (tab != 0) {
@@ -1015,25 +1015,25 @@ void FluxboxWindow::iconify() {
 
     m_windowmenu.hide();
 
-    setState(IconicState);
-
-
     XSelectInput(display, client.window, NoEventMask);
     XUnmapWindow(display, client.window);
     XSelectInput(display, client.window,
                  PropertyChangeMask | StructureNotifyMask | FocusChangeMask);
 
-    m_frame.hide();
-
     visible = false;
     iconic = true;
 	
+    setState(IconicState);
+
+    m_frame.hide();
+
     screen->getWorkspace(workspace_number)->removeWindow(this);
 
     if (client.transient_for) {
         if (! client.transient_for->iconic)
             client.transient_for->iconify();
     }
+
     screen->addIcon(this);
 
     if (tab) //if this window got a tab then iconify it too
@@ -1057,6 +1057,10 @@ void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
     } else if (workspace_number != screen->getCurrentWorkspace()->workspaceID())
         return;
 
+    bool was_iconic = iconic;
+
+    iconic = false;
+    visible = true;
     setState(NormalState);
 
     XSelectInput(display, client.window, NoEventMask);
@@ -1066,14 +1070,12 @@ void FluxboxWindow::deiconify(bool reassoc, bool do_raise) {
 
     m_frame.show();
 
-    if (iconic && screen->doFocusNew())
+    if (was_iconic && screen->doFocusNew())
         setInputFocus();
 
     if (focused != m_frame.focused())
         m_frame.setFocus(focused);
 
-    visible = true;
-    iconic = false;
 
     if (reassoc && client.transients.size()) {
         // deiconify all transients
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 9afbced..6155a72 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -22,7 +22,7 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 // DEALINGS IN THE SOFTWARE.
 
-// $Id: fluxbox.cc,v 1.102 2003/03/01 07:30:42 fluxgen Exp $
+// $Id: fluxbox.cc,v 1.103 2003/03/03 21:51:11 rathnor Exp $
 
 
 #include "fluxbox.hh"
@@ -447,7 +447,9 @@ Fluxbox::Fluxbox(int m_argc, char **m_argv, const char *dpy_name, const char *rc
             continue;
         }
         screenList.push_back(screen);
-		
+        
+        m_atomhandler.push_back(&screen->getToolbarHandler());
+        
         // attach screen signals to this
         screen->currentWorkspaceSig().attach(this);
         screen->workspaceCountSig().attach(this);
@@ -1449,7 +1451,7 @@ void Fluxbox::handleSignal(int signum) {
 
 void Fluxbox::update(FbTk::Subject *changedsub) {
 //TODO: fix signaling, this does not look good
-    if (typeid(*changedsub) == typeid(FluxboxWindow)) {
+    if (typeid(*changedsub) == typeid(FluxboxWindow::WinSubject)) {
         FluxboxWindow::WinSubject *winsub = dynamic_cast<FluxboxWindow::WinSubject *>(changedsub);
         FluxboxWindow &win = winsub->win();
         if ((&(win.hintSig())) == changedsub) { // hint signal
@@ -1476,6 +1478,14 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
                 if (m_atomhandler[i]->update())
                     m_atomhandler[i]->updateLayer(win);
             }
+        } else if ((&(win.dieSig())) == changedsub) { // window death signal
+#ifdef DEBUG
+            cerr<<__FILE__<<"("<<__LINE__<<") WINDOW die signal from "<<&win<<endl;
+#endif // DEBUG
+            for (size_t i=0; i<m_atomhandler.size(); ++i) {
+                if (m_atomhandler[i]->update())
+                    m_atomhandler[i]->updateWindowClose(win);
+            }
         } else if ((&(win.workspaceSig())) == changedsub) {  // workspace signal
 #ifdef DEBUG
             cerr<<__FILE__<<"("<<__LINE__<<") WINDOW workspace signal from "<<&win<<endl;
@@ -1534,6 +1544,7 @@ void Fluxbox::attachSignals(FluxboxWindow &win) {
     win.stateSig().attach(this);
     win.workspaceSig().attach(this);
     win.layerSig().attach(this);
+    win.dieSig().attach(this);
     for (size_t i=0; i<m_atomhandler.size(); ++i) {
         m_atomhandler[i]->setupWindow(win);
     }
@@ -2073,7 +2084,7 @@ void Fluxbox::load_rc(BScreen *screen) {
     if (screen->getToolbarWidthPercent() <= 0 || 
         screen->getToolbarWidthPercent() > 100)
         screen->saveToolbarWidthPercent(66);
-
+    
     if (screen->getTabWidth()>512)
         screen->saveTabWidth(512);
     else if (screen->getTabWidth()<0)
-- 
cgit v0.11.2