From dbfddf8e0bcf8e7abbba671eff64c9679332a774 Mon Sep 17 00:00:00 2001
From: Mark Tiefenbruck <mark@fluxbox.org>
Date: Mon, 7 Jan 2008 02:26:32 -0800
Subject: added new ThemeProxy for automatically handling focused vs. unfocused
 ThemeItems

---
 src/CommandDialog.cc   |  8 +++---
 src/FbWinFrame.cc      | 35 +++++++++++--------------
 src/FbWinFrame.hh      |  6 ++---
 src/FbWinFrameTheme.cc |  8 ++++--
 src/FbWinFrameTheme.hh |  5 ++--
 src/FocusableTheme.hh  | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/IconButton.cc      | 61 ++++++++++++++-----------------------------
 src/IconButton.hh      | 11 +++++---
 src/IconbarTheme.cc    | 60 +++++++++++++++---------------------------
 src/IconbarTheme.hh    | 16 ++++--------
 src/IconbarTool.cc     | 23 +++++++++-------
 src/IconbarTool.hh     |  5 ++--
 src/Makefile.am        |  2 +-
 src/Screen.cc          | 20 +++++++-------
 src/ToolFactory.cc     | 16 +++++++-----
 src/ToolFactory.hh     |  2 +-
 src/Window.cc          |  7 +++--
 17 files changed, 196 insertions(+), 160 deletions(-)
 create mode 100644 src/FocusableTheme.hh

diff --git a/src/CommandDialog.cc b/src/CommandDialog.cc
index d88d755..17bd771 100644
--- a/src/CommandDialog.cc
+++ b/src/CommandDialog.cc
@@ -190,12 +190,12 @@ void CommandDialog::tabComplete() {
 
 void CommandDialog::render() {
     Pixmap tmp = m_pixmap;
-    if (!m_screen.winFrameTheme()->iconbarTheme().focusedTexture().usePixmap()) {
-        m_label.setBackgroundColor(m_screen.winFrameTheme()->iconbarTheme().focusedTexture().color());
+    if (!m_screen.winFrameTheme()->focusedIconbarTheme().texture().usePixmap()) {
+        m_label.setBackgroundColor(m_screen.winFrameTheme()->focusedIconbarTheme().texture().color());
         m_pixmap = 0;
     } else {
         m_pixmap = m_screen.imageControl().renderImage(m_label.width(), m_label.height(),
-                                                       m_screen.winFrameTheme()->iconbarTheme().focusedTexture());
+                                                       m_screen.winFrameTheme()->focusedIconbarTheme().texture());
         m_label.setBackgroundPixmap(m_pixmap);
     }
 
@@ -210,7 +210,7 @@ void CommandDialog::init() {
     // setup label
     // we listen to motion notify too
     m_label.setEventMask(m_label.eventMask() | ButtonPressMask | ButtonMotionMask);
-    m_label.setGC(m_screen.winFrameTheme()->iconbarTheme().focusedText().textGC());
+    m_label.setGC(m_screen.winFrameTheme()->focusedIconbarTheme().text().textGC());
     m_label.show();
 
     // setup text box
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc
index 36bf251..5cc7631 100644
--- a/src/FbWinFrame.cc
+++ b/src/FbWinFrame.cc
@@ -563,19 +563,14 @@ void FbWinFrame::removeAllButtons() {
     }
 }
 
-IconButton *FbWinFrame::createTab(Focusable &client) {
-    IconButton *button = new IconButton(m_tab_container, theme()->iconbarTheme(),
-                                        client);
+void FbWinFrame::createTab(FbTk::Button &button) {
+    button.show();
+    button.setEventMask(ExposureMask | ButtonPressMask |
+                        ButtonReleaseMask | ButtonMotionMask |
+                        EnterWindowMask);
+    FbTk::EventManager::instance()->add(button, button.window());
 
-    button->show();
-    button->setEventMask(ExposureMask | ButtonPressMask |
-                         ButtonReleaseMask | ButtonMotionMask |
-                         EnterWindowMask);
-    FbTk::EventManager::instance()->add(*button, button->window());
-
-    m_tab_container.insertItem(button);
-
-    return button;
+    m_tab_container.insertItem(&button);
 }
 
 void FbWinFrame::removeTab(IconButton *btn) {
@@ -1140,11 +1135,11 @@ void FbWinFrame::renderTitlebar() {
 
     //!! TODO: don't render label if internal tabs
 
-    render(theme()->iconbarTheme()->focusedTexture(), m_label_focused_color,
+    render(theme()->focusedIconbarTheme()->texture(), m_label_focused_color,
            m_label_focused_pm,
            m_label.width(), m_label.height());
 
-    render(theme()->iconbarTheme()->unfocusedTexture(), m_label_unfocused_color,
+    render(theme()->unfocusedIconbarTheme()->texture(), m_label_unfocused_color,
            m_label_unfocused_pm,
            m_label.width(), m_label.height());
 
@@ -1156,8 +1151,8 @@ void FbWinFrame::renderTabContainer() {
         return;
     }
 
-    const FbTk::Texture *tc_focused = &theme()->iconbarTheme()->focusedTexture();
-    const FbTk::Texture *tc_unfocused = &theme()->iconbarTheme()->unfocusedTexture();
+    const FbTk::Texture *tc_focused = &theme()->focusedIconbarTheme()->texture();
+    const FbTk::Texture *tc_unfocused = &theme()->unfocusedIconbarTheme()->texture();
 
     if (m_tabmode == EXTERNAL && tc_focused->type() & FbTk::Texture::PARENTRELATIVE)
         tc_focused = &theme()->titleFocusTexture();
@@ -1192,11 +1187,11 @@ void FbWinFrame::applyTitlebar() {
 
     if (m_tabmode != INTERNAL) {
         m_label.setGC(m_focused ?
-                      theme()->iconbarTheme()->focusedText().textGC() :
-                      theme()->iconbarTheme()->unfocusedText().textGC());
+                      theme()->focusedIconbarTheme()->text().textGC() :
+                      theme()->unfocusedIconbarTheme()->text().textGC());
         m_label.setJustify(m_focused ?
-                           theme()->iconbarTheme()->focusedText().justify() :
-                           theme()->iconbarTheme()->unfocusedText().justify());
+                           theme()->focusedIconbarTheme()->text().justify() :
+                           theme()->unfocusedIconbarTheme()->text().justify());
 
         if (label_pm != 0)
             m_label.setBackgroundPixmap(label_pm);
diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh
index 82c33dc..800bc0e 100644
--- a/src/FbWinFrame.hh
+++ b/src/FbWinFrame.hh
@@ -160,8 +160,8 @@ public:
     void addRightButton(FbTk::Button *btn);
     /// remove all buttons from titlebar
     void removeAllButtons();
-    /// adds a button to label window with specified title and command
-    IconButton *createTab(Focusable &client);
+    /// adds a button to tab container
+    void createTab(FbTk::Button &button);
     /// removes a specific button from label window
     void removeTab(IconButton *id);
     /// move label button to the left
@@ -253,7 +253,6 @@ public:
     FbTk::FbWindow &gripLeft() { return m_grip_left; }
     const FbTk::FbWindow &gripRight() const { return m_grip_right; }
     FbTk::FbWindow &gripRight() { return m_grip_right; }
-    const IconButton *currentLabel() const { return m_current_label; }
     bool focused() const { return m_focused; }
     bool isShaded() const { return m_shaded; }
     FbTk::ThemeProxy<FbWinFrameTheme> &theme() const { return m_theme; }
@@ -337,7 +336,6 @@ private:
     ButtonList m_buttons_left, ///< buttons to the left
         m_buttons_right; ///< buttons to the right
     typedef std::list<FbTk::TextButton *> LabelList;
-    IconButton *m_current_label; ///< which client button is focused at the moment
     int m_bevel;  ///< bevel between titlebar items and titlebar
     unsigned int m_decoration_mask; ///< bitmask of applied decorations
     bool m_use_titlebar; ///< if we should use titlebar
diff --git a/src/FbWinFrameTheme.cc b/src/FbWinFrameTheme.cc
index c72e4cf..634a0fd 100644
--- a/src/FbWinFrameTheme.cc
+++ b/src/FbWinFrameTheme.cc
@@ -55,7 +55,10 @@ FbWinFrameTheme::FbWinFrameTheme(int screen_num):
     m_button_pic_unfocus_gc(RootWindow(FbTk::App::instance()->display(), screen_num)),
     m_focused_alpha(255),
     m_unfocused_alpha(255),
-    m_iconbar_theme(screen_num, "window.label", "Window.Label") {
+    m_focused_iconbar_theme(screen_num, "window.label.focus",
+                            "Window.Label.Unfocus"),
+    m_unfocused_iconbar_theme(screen_num, "window.label.unfocus",
+                              "Window.Label.Unfocus") {
 
     *m_title_height = 0;
     // set defaults
@@ -111,6 +114,7 @@ void FbWinFrameTheme::reconfigTheme() {
     m_button_pic_focus_gc.setForeground(*m_button_focus_color);
     m_button_pic_unfocus_gc.setForeground(*m_button_unfocus_color);
 
-    m_iconbar_theme.reconfigTheme();
+    m_focused_iconbar_theme.reconfigTheme();
+    m_unfocused_iconbar_theme.reconfigTheme();
 }
 
diff --git a/src/FbWinFrameTheme.hh b/src/FbWinFrameTheme.hh
index 66448b6..bc8ed40 100644
--- a/src/FbWinFrameTheme.hh
+++ b/src/FbWinFrameTheme.hh
@@ -92,7 +92,8 @@ public:
     void setFocusedAlpha(unsigned char alpha) { m_focused_alpha = alpha; }
     void setUnfocusedAlpha(unsigned char alpha) { m_unfocused_alpha = alpha; }
 
-    IconbarTheme &iconbarTheme() { return m_iconbar_theme; }
+    IconbarTheme &focusedIconbarTheme() { return m_focused_iconbar_theme; }
+    IconbarTheme &unfocusedIconbarTheme() { return m_unfocused_iconbar_theme; }
 
     virtual FbTk::Subject &reconfigSig() { return FbTk::Theme::reconfigSig(); }
     virtual const FbTk::Subject &reconfigSig() const { return FbTk::Theme::reconfigSig(); }
@@ -128,7 +129,7 @@ private:
     unsigned char m_focused_alpha;
     unsigned char m_unfocused_alpha;
 
-    IconbarTheme m_iconbar_theme;
+    IconbarTheme m_focused_iconbar_theme, m_unfocused_iconbar_theme;
 };
 
 #endif // FBWINFRAMETHEME_HH
diff --git a/src/FocusableTheme.hh b/src/FocusableTheme.hh
new file mode 100644
index 0000000..d0f5d9e
--- /dev/null
+++ b/src/FocusableTheme.hh
@@ -0,0 +1,71 @@
+// FocusableTheme.hh
+// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot 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.
+
+#ifndef FOCUSABLETHEME_HH
+#define FOCUSABLETHEME_HH
+
+#include "Focusable.hh"
+#include "FbTk/Observer.hh"
+#include "FbTk/Theme.hh"
+
+template <typename BaseTheme>
+class FocusableTheme: public FbTk::ThemeProxy<BaseTheme>,
+                      private FbTk::Observer {
+public:
+    FocusableTheme(Focusable &win, FbTk::ThemeProxy<BaseTheme> &focused,
+                   FbTk::ThemeProxy<BaseTheme> &unfocused):
+        m_win(win), m_focused_theme(focused), m_unfocused_theme(unfocused) {
+        m_win.focusSig().attach(this);
+        m_win.attentionSig().attach(this);
+        m_focused_theme.reconfigSig().attach(this);
+        m_unfocused_theme.reconfigSig().attach(this);
+    }
+
+    Focusable &win() { return m_win; }
+    const Focusable &win() const { return m_win; }
+
+    FbTk::ThemeProxy<BaseTheme> &focusedTheme() { return m_focused_theme; }
+    const FbTk::ThemeProxy<BaseTheme> &focusedTheme() const { return m_focused_theme; }
+
+    FbTk::ThemeProxy<BaseTheme> &unfocusedTheme() { return m_unfocused_theme; }
+    const FbTk::ThemeProxy<BaseTheme> &unfocusedTheme() const { return m_unfocused_theme; }
+
+    FbTk::Subject &reconfigSig() { return m_reconfig_sig; }
+    const FbTk::Subject &reconfigSig() const { return m_reconfig_sig; }
+
+    virtual BaseTheme &operator *() {
+        return (m_win.isFocused() || m_win.getAttentionState()) ?
+               *m_focused_theme : *m_unfocused_theme;
+    }
+    virtual const BaseTheme &operator *() const {
+        return (m_win.isFocused() || m_win.getAttentionState()) ?
+               *m_focused_theme : *m_unfocused_theme;
+    }
+
+private:
+    void update(FbTk::Subject *subj) { m_reconfig_sig.notify(); }
+
+    Focusable &m_win;
+    FbTk::ThemeProxy<BaseTheme> &m_focused_theme, &m_unfocused_theme;
+    FbTk::Subject m_reconfig_sig;
+};
+
+#endif // FOCUSABLETHEME_HH
diff --git a/src/IconButton.cc b/src/IconButton.cc
index d64e23c..2df741a 100644
--- a/src/IconButton.cc
+++ b/src/IconButton.cc
@@ -25,7 +25,6 @@
 #include "IconbarTheme.hh"
 
 #include "Screen.hh"
-#include "Focusable.hh"
 
 #include "FbTk/App.hh"
 #include "FbTk/Command.hh"
@@ -47,15 +46,15 @@
 
 
 IconButton::IconButton(const FbTk::FbWindow &parent,
-        FbTk::ThemeProxy<IconbarTheme> &theme, Focusable &win):
-    FbTk::TextButton(parent, theme->focusedText().font(), win.title()),
+        FbTk::ThemeProxy<IconbarTheme> &focused_theme,
+        FbTk::ThemeProxy<IconbarTheme> &unfocused_theme, Focusable &win):
+    FbTk::TextButton(parent, focused_theme->text().font(), win.title()),
     m_win(win),
     m_icon_window(*this, 1, 1, 1, 1,
                   ExposureMask | ButtonPressMask | ButtonReleaseMask),
     m_use_pixmap(true),
-    m_theme(theme),
-    m_focused_pm(win.screen().imageControl()),
-    m_unfocused_pm(win.screen().imageControl()) {
+    m_theme(win, focused_theme, unfocused_theme),
+    m_pm(win.screen().imageControl()) {
 
     m_win.titleSig().attach(this);
     m_win.focusSig().attach(this);
@@ -118,47 +117,25 @@ void IconButton::setPixmap(bool use) {
 
 void IconButton::reconfigTheme() {
 
-    if (m_theme->focusedTexture().usePixmap())
-        m_focused_pm.reset(m_win.screen().imageControl().renderImage(
-                            width(), height(), m_theme->focusedTexture(),
-                            orientation()));
+    if (m_theme->texture().usePixmap())
+        m_pm.reset(m_win.screen().imageControl().renderImage(
+                           width(), height(), m_theme->texture(),
+                           orientation()));
     else
-        m_focused_pm.reset(0);
-
-    if (m_theme->unfocusedTexture().usePixmap())
-        m_unfocused_pm.reset(m_win.screen().imageControl().renderImage(
-                              width(), height(), m_theme->unfocusedTexture(),
-                              orientation()));
-    else
-        m_unfocused_pm.reset(0);
+        m_pm.reset(0);
 
     setAlpha(parent()->alpha());
 
-    if (m_win.isFocused() || m_win.getAttentionState()) {
-        if (m_focused_pm != 0)
-            setBackgroundPixmap(m_focused_pm);
-        else
-            setBackgroundColor(m_theme->focusedTexture().color());
-
-        setGC(m_theme->focusedText().textGC());
-        setFont(m_theme->focusedText().font());
-        setJustify(m_theme->focusedText().justify());
-        setBorderWidth(m_theme->focusedBorder().width());
-        setBorderColor(m_theme->focusedBorder().color());
-
-    } else {
-        if (m_unfocused_pm != 0)
-            setBackgroundPixmap(m_unfocused_pm);
-        else
-            setBackgroundColor(m_theme->unfocusedTexture().color());
-
-        setGC(m_theme->unfocusedText().textGC());
-        setFont(m_theme->unfocusedText().font());
-        setJustify(m_theme->unfocusedText().justify());
-        setBorderWidth(m_theme->unfocusedBorder().width());
-        setBorderColor(m_theme->unfocusedBorder().color());
+    if (m_pm != 0)
+        setBackgroundPixmap(m_pm);
+    else
+        setBackgroundColor(m_theme->texture().color());
 
-    }
+    setGC(m_theme->text().textGC());
+    setFont(m_theme->text().font());
+    setJustify(m_theme->text().justify());
+    setBorderWidth(m_theme->border().width());
+    setBorderColor(m_theme->border().color());
 
     updateBackground(false);
 
diff --git a/src/IconButton.hh b/src/IconButton.hh
index a0cd82e..b80a29b 100644
--- a/src/IconButton.hh
+++ b/src/IconButton.hh
@@ -23,12 +23,13 @@
 #ifndef ICONBUTTON_HH
 #define ICONBUTTON_HH
 
+#include "FocusableTheme.hh"
+
 #include "FbTk/CachedPixmap.hh"
 #include "FbTk/FbPixmap.hh"
 #include "FbTk/Observer.hh"
 #include "FbTk/TextButton.hh"
 
-class Focusable;
 class IconbarTheme;
 
 namespace FbTk {
@@ -38,7 +39,9 @@ template <class T> class ThemeProxy;
 class IconButton: public FbTk::TextButton, public FbTk::Observer {
 public:
     IconButton(const FbTk::FbWindow &parent,
-               FbTk::ThemeProxy<IconbarTheme> &theme, Focusable &window);
+               FbTk::ThemeProxy<IconbarTheme> &focused_theme,
+               FbTk::ThemeProxy<IconbarTheme> &unfocused_theme,
+               Focusable &window);
     virtual ~IconButton();
 
     void exposeEvent(XExposeEvent &event);
@@ -71,9 +74,9 @@ private:
     FbTk::FbPixmap m_icon_mask;
     bool m_use_pixmap;
 
-    FbTk::ThemeProxy<IconbarTheme> &m_theme;
+    FocusableTheme<IconbarTheme> m_theme;
     // cached pixmaps
-    FbTk::CachedPixmap m_focused_pm, m_unfocused_pm;
+    FbTk::CachedPixmap m_pm;
 };
 
 #endif // ICONBUTTON_HH
diff --git a/src/IconbarTheme.cc b/src/IconbarTheme.cc
index f2247aa..0be9cd1 100644
--- a/src/IconbarTheme.cc
+++ b/src/IconbarTheme.cc
@@ -27,26 +27,10 @@ IconbarTheme::IconbarTheme(int screen_num,
                            const std::string &name,
                            const std::string &altname):
     FbTk::Theme(screen_num),
-    m_focused_texture(*this,
-            name + (name == "window.label" ? ".focus" : ".focused"),
-            altname + (name == "window.label" ? ".Focus" : ".Focused")),
-    m_unfocused_texture(*this,
-            name + (name == "window.label" ? ".unfocus" : ".unfocused"),
-            altname + (name == "window.label" ? ".Unfocus" : ".Unfocused")),
+    m_texture(*this, name, altname),
     m_empty_texture(*this, name + ".empty", altname + ".Empty"),
-    m_focused_border(*this,
-            name + (name == "window.label" ? ".focus" : ".focused"),
-            altname + (name == "window.label" ? ".Focus" : ".Focused")),
-    m_unfocused_border(*this,
-            name + (name == "window.label" ? ".unfocus" : ".unfocused"),
-            altname + (name == "window.label" ? ".Unfocus" : ".Unfocused")),
     m_border(*this, name, altname),
-    m_focused_text(*this,
-            name + (name == "window.label" ? ".focus" : ".focused"),
-            altname + (name == "window.label" ? ".Focus" : ".Focused")),
-    m_unfocused_text(*this,
-            name + (name == "window.label" ? ".unfocus" : ".unfocused"),
-            altname + (name == "window.label" ? ".Unfocus" : ".Unfocused")),
+    m_text(*this, name, altname),
     m_name(name), m_altname(altname) {
 
     FbTk::ThemeManager::instance().loadTheme(*this);
@@ -58,48 +42,46 @@ IconbarTheme::~IconbarTheme() {
 
 
 void IconbarTheme::reconfigTheme() {
-    m_focused_text.updateTextColor();
-    m_unfocused_text.updateTextColor();
+    m_text.updateTextColor();
 }
 
 // fallback resources
 bool IconbarTheme::fallback(FbTk::ThemeItem_base &item) {
     using namespace FbTk;
     ThemeManager &tm = ThemeManager::instance();
-    std::string focus = (m_name == "window.label" ? ".focus" : ".focused");
-    std::string un = (m_name == "window.label" ? ".unfocus" : ".unfocused");
+    std::string base = m_name;
+    base.erase(base.find_last_of("."));
+    std::string altbase = m_altname;
+    altbase.erase(altbase.find_last_of("."));
 
-    if (&m_focused_texture == &item || &m_unfocused_texture == &item) {
+    if (&m_texture == &item) {
         return tm.loadItem(item, "toolbar.windowLabel", "toolbar.windowLabel");
     } else if (&m_empty_texture == &item) {
-        return (tm.loadItem(item, m_focused_texture.name(),
-                m_focused_texture.altName()) ||
+        return (tm.loadItem(item, "toolbar.iconbar.empty",
+                            "Toolbar.Iconbar.Empty") ||
+                tm.loadItem(item, m_texture.name(), m_texture.altName()) ||
                 tm.loadItem(item, "toolbar.windowLabel", "toolbar.windowLabel")
-                || tm.loadItem(item, "toolbar", "toolbar")); 
-    } else if (item.name() == m_name + focus + ".borderWidth" ||
-               item.name() == m_name + un + ".borderWidth")
+                || tm.loadItem(item, "toolbar", "toolbar"));
+    } else if (item.name() == m_name + ".borderWidth")
         // don't fallback for base border, for theme backwards compatibility
-        return (tm.loadItem(item, m_name + ".borderWidth",
-                            m_altname + ".BorderWidth") ||
+        return (tm.loadItem(item, base + ".borderWidth",
+                            altbase + ".BorderWidth") ||
                 tm.loadItem(item, "window.borderWidth", "Window.BorderWidth") ||
                 tm.loadItem(item, "borderWidth", "BorderWidth"));
 
-    else if (item.name() == m_name + focus + ".borderColor" ||
-             item.name() == m_name + un + ".borderColor")
+    else if (item.name() == m_name + ".borderColor")
 
-        return (tm.loadItem(item, m_name + ".borderColor",
-                            m_altname + ".BorderColor") ||
+        return (tm.loadItem(item, base + ".borderColor",
+                            altbase + ".BorderColor") ||
                 tm.loadItem(item, "window.borderColor", "Window.BorderColor") ||
                 tm.loadItem(item, "borderColor", "BorderColor"));
 
-    else if (item.name() == m_name + focus + ".font" ||
-             item.name() == m_name + un + ".font")
+    else if (item.name() == m_name + ".font")
 
         return tm.loadItem(item, "window.font", "Window.Font");
 
-    else if (item.name() == m_name + focus + ".justify" ||
-             item.name() == m_name + un + ".justify") {
-        return (tm.loadItem(item, m_name + ".justify", m_altname + ".Justify")
+    else if (item.name() == m_name + ".justify") {
+        return (tm.loadItem(item, base + ".justify", altbase + ".Justify")
                 || tm.loadItem(item, "window.justify", "Window.Justify"));
     }
 
diff --git a/src/IconbarTheme.hh b/src/IconbarTheme.hh
index 4dc5f32..e4b3c8b 100644
--- a/src/IconbarTheme.hh
+++ b/src/IconbarTheme.hh
@@ -36,15 +36,9 @@ public:
     void reconfigTheme();
     bool fallback(FbTk::ThemeItem_base &item);
 
-    FbTk::TextTheme &focusedText()  { return m_focused_text; }
-    FbTk::TextTheme &unfocusedText() { return m_unfocused_text; }
-
-    const FbTk::BorderTheme &focusedBorder() const { return m_focused_border; }
-    const FbTk::BorderTheme &unfocusedBorder() const { return m_unfocused_border; }
+    FbTk::TextTheme &text()  { return m_text; }
     const FbTk::BorderTheme &border() const { return m_border; }
-
-    const FbTk::Texture &focusedTexture() const { return *m_focused_texture; }
-    const FbTk::Texture &unfocusedTexture() const { return *m_unfocused_texture; }
+    const FbTk::Texture &texture() const { return *m_texture; }
     const FbTk::Texture &emptyTexture() const { return *m_empty_texture; }
 
     virtual FbTk::Subject &reconfigSig() { return FbTk::Theme::reconfigSig(); }
@@ -54,9 +48,9 @@ public:
     virtual const IconbarTheme &operator *() const { return *this; }
 
 private:
-    FbTk::ThemeItem<FbTk::Texture> m_focused_texture, m_unfocused_texture, m_empty_texture;
-    FbTk::BorderTheme m_focused_border, m_unfocused_border, m_border;
-    FbTk::TextTheme m_focused_text, m_unfocused_text;
+    FbTk::ThemeItem<FbTk::Texture> m_texture, m_empty_texture;
+    FbTk::BorderTheme m_border;
+    FbTk::TextTheme m_text;
     std::string m_name, m_altname;
 };
 
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc
index 3984b52..d8579f2 100644
--- a/src/IconbarTool.cc
+++ b/src/IconbarTool.cc
@@ -253,12 +253,14 @@ private:
 }; // end anonymous namespace
 
 IconbarTool::IconbarTool(const FbTk::FbWindow &parent,
-                         FbTk::ThemeProxy<IconbarTheme> &theme,
+                         FbTk::ThemeProxy<IconbarTheme> &focused_theme,
+                         FbTk::ThemeProxy<IconbarTheme> &unfocused_theme,
                          BScreen &screen, FbTk::Menu &menu):
     ToolbarItem(ToolbarItem::RELATIVE),
     m_screen(screen),
     m_icon_container(parent),
-    m_theme(theme),
+    m_focused_theme(focused_theme),
+    m_unfocused_theme(unfocused_theme),
     m_empty_pm( screen.imageControl() ),
     m_winlist(new FocusableList(screen)),
     m_mode("none"),
@@ -297,7 +299,8 @@ IconbarTool::IconbarTool(const FbTk::FbWindow &parent,
     menu.insert(m_menu.label(), &m_menu);
 
     // setup signals
-    theme.reconfigSig().attach(this);
+    focused_theme.reconfigSig().attach(this);
+    unfocused_theme.reconfigSig().attach(this);
     setMode(*m_rc_mode);
 }
 
@@ -402,7 +405,8 @@ void IconbarTool::update(FbTk::Subject *subj) {
 
     m_icon_container.setMaxSizePerClient(*m_rc_client_width);
 
-    if (subj == &m_theme.reconfigSig()) {
+    if (subj == &m_focused_theme.reconfigSig() ||
+        subj == &m_unfocused_theme.reconfigSig()) {
         setMode(*m_rc_mode);
         return;
     }
@@ -468,7 +472,7 @@ void IconbarTool::reset() {
 }
 
 void IconbarTool::updateSizing() {
-    m_icon_container.setBorderWidth(m_theme->border().width());
+    m_icon_container.setBorderWidth(m_focused_theme->border().width());
 
     IconMap::iterator icon_it = m_icons.begin();
     const IconMap::iterator icon_it_end = m_icons.end();
@@ -489,14 +493,14 @@ void IconbarTool::renderTheme() {
     updateSizing();
 
     // if we dont have any icons then we should render empty texture
-    if (!m_theme->emptyTexture().usePixmap()) {
+    if (!m_focused_theme->emptyTexture().usePixmap()) {
         m_empty_pm.reset( 0 );
-        m_icon_container.setBackgroundColor(m_theme->emptyTexture().color());
+        m_icon_container.setBackgroundColor(m_focused_theme->emptyTexture().color());
     } else {
         m_empty_pm.reset(m_screen.imageControl().
                           renderImage(m_icon_container.width(),
                                       m_icon_container.height(),
-                                      m_theme->emptyTexture(), orientation()));
+                                      m_focused_theme->emptyTexture(), orientation()));
         m_icon_container.setBackgroundPixmap(m_empty_pm);
     }
 
@@ -548,7 +552,8 @@ IconButton *IconbarTool::makeButton(Focusable &win) {
 #ifdef DEBUG
     cerr<<"IconbarTool::addWindow(0x"<<&win<<" title = "<<win.title()<<")"<<endl;
 #endif // DEBUG
-    IconButton *button = new IconButton(m_icon_container, m_theme, win);
+    IconButton *button = new IconButton(m_icon_container, m_focused_theme,
+                                        m_unfocused_theme, win);
 
     RefCmd focus_cmd(new ::FocusCommand(win));
     RefCmd menu_cmd(new ::ShowMenu(*fbwin));
diff --git a/src/IconbarTool.hh b/src/IconbarTool.hh
index 36609cc..58f8791 100644
--- a/src/IconbarTool.hh
+++ b/src/IconbarTool.hh
@@ -44,7 +44,8 @@ public:
     typedef std::map<Focusable *, IconButton *> IconMap;
 
     IconbarTool(const FbTk::FbWindow &parent,
-                FbTk::ThemeProxy<IconbarTheme> &theme, 
+                FbTk::ThemeProxy<IconbarTheme> &focused_theme,
+                FbTk::ThemeProxy<IconbarTheme> &unfocused_theme,
                 BScreen &screen, FbTk::Menu &menu);
     ~IconbarTool();
 
@@ -96,7 +97,7 @@ private:
 
     BScreen &m_screen;
     FbTk::Container m_icon_container;
-    FbTk::ThemeProxy<IconbarTheme> &m_theme;
+    FbTk::ThemeProxy<IconbarTheme> &m_focused_theme, &m_unfocused_theme;
     FbTk::CachedPixmap m_empty_pm; ///< pixmap for empty container
 
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 9b0b1aa..683179d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -141,7 +141,7 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \
 	AttentionNoticeHandler.hh AttentionNoticeHandler.cc \
 	IconButton.hh IconButton.cc \
 	IconbarTheme.hh IconbarTheme.cc \
-	Focusable.hh FocusableList.hh FocusableList.cc \
+	Focusable.hh FocusableList.hh FocusableList.cc FocusableTheme.hh \
 	${newwmspec_SOURCE} ${gnome_SOURCE} \
 	${REMEMBER_SOURCE} ${TOOLBAR_SOURCE}
 
diff --git a/src/Screen.cc b/src/Screen.cc
index 5edbcaf..7174cda 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -1795,7 +1795,7 @@ void BScreen::showPosition(int x, int y) {
 
     winFrameTheme()->font().drawText(m_pos_window,
                                     screenNumber(),
-                                    winFrameTheme()->iconbarTheme().focusedText().textGC(),
+                                    winFrameTheme()->focusedIconbarTheme().text().textGC(),
                                     label, strlen(label),
                                     winFrameTheme()->bevelWidth(),
                                     winFrameTheme()->bevelWidth() +
@@ -1847,7 +1847,7 @@ void BScreen::showGeometry(int gx, int gy) {
     //!! TODO: geom window again?! repeated
     winFrameTheme()->font().drawText(m_geom_window,
                                     screenNumber(),
-                                    winFrameTheme()->iconbarTheme().focusedText().textGC(),
+                                    winFrameTheme()->focusedIconbarTheme().text().textGC(),
                                     label, strlen(label),
                                     winFrameTheme()->bevelWidth(),
                                     winFrameTheme()->bevelWidth() +
@@ -1918,7 +1918,7 @@ void BScreen::renderGeomWindow() {
 
     Pixmap tmp = geom_pixmap;
 
-    if (winFrameTheme()->iconbarTheme().focusedTexture().type() & FbTk::Texture::PARENTRELATIVE) {
+    if (winFrameTheme()->focusedIconbarTheme().texture().type() & FbTk::Texture::PARENTRELATIVE) {
         if (!winFrameTheme()->titleFocusTexture().usePixmap()) {
             geom_pixmap = None;
             m_geom_window.setBackgroundColor(winFrameTheme()->titleFocusTexture().color());
@@ -1928,12 +1928,12 @@ void BScreen::renderGeomWindow() {
             m_geom_window.setBackgroundPixmap(geom_pixmap);
         }
     } else {
-        if (!winFrameTheme()->iconbarTheme().focusedTexture().usePixmap()) {
+        if (!winFrameTheme()->focusedIconbarTheme().texture().usePixmap()) {
             geom_pixmap = None;
-            m_geom_window.setBackgroundColor(winFrameTheme()->iconbarTheme().focusedTexture().color());
+            m_geom_window.setBackgroundColor(winFrameTheme()->focusedIconbarTheme().texture().color());
         } else {
             geom_pixmap = imageControl().renderImage(m_geom_window.width(), m_geom_window.height(),
-                                                     winFrameTheme()->iconbarTheme().focusedTexture());
+                                                     winFrameTheme()->focusedIconbarTheme().texture());
             m_geom_window.setBackgroundPixmap(geom_pixmap);
         }
     }
@@ -1956,7 +1956,7 @@ void BScreen::renderPosWindow() {
 
     Pixmap tmp = pos_pixmap;
 
-    if (winFrameTheme()->iconbarTheme().focusedTexture().type() & FbTk::Texture::PARENTRELATIVE) {
+    if (winFrameTheme()->focusedIconbarTheme().texture().type() & FbTk::Texture::PARENTRELATIVE) {
         if (!winFrameTheme()->titleFocusTexture().usePixmap()) {
             pos_pixmap = None;
             m_pos_window.setBackgroundColor(winFrameTheme()->titleFocusTexture().color());
@@ -1966,12 +1966,12 @@ void BScreen::renderPosWindow() {
             m_pos_window.setBackgroundPixmap(pos_pixmap);
         }
     } else {
-        if (!winFrameTheme()->iconbarTheme().focusedTexture().usePixmap()) {
+        if (!winFrameTheme()->focusedIconbarTheme().texture().usePixmap()) {
             pos_pixmap = None;
-            m_pos_window.setBackgroundColor(winFrameTheme()->iconbarTheme().focusedTexture().color());
+            m_pos_window.setBackgroundColor(winFrameTheme()->focusedIconbarTheme().texture().color());
         } else {
             pos_pixmap = imageControl().renderImage(m_pos_window.width(), m_pos_window.height(),
-                                                     winFrameTheme()->iconbarTheme().focusedTexture());
+                                                     winFrameTheme()->focusedIconbarTheme().texture());
             m_pos_window.setBackgroundPixmap(pos_pixmap);
         }
     }
diff --git a/src/ToolFactory.cc b/src/ToolFactory.cc
index cee0d93..87299cc 100644
--- a/src/ToolFactory.cc
+++ b/src/ToolFactory.cc
@@ -76,7 +76,8 @@ ToolFactory::ToolFactory(BScreen &screen):m_screen(screen),
     m_workspace_theme(new WorkspaceNameTheme(screen.screenNumber(), "toolbar.workspace", "Toolbar.Workspace")),
     m_systray_theme(new ButtonTheme(screen.screenNumber(), "toolbar.systray", "Toolbar.Systray",
                                     "toolbar.clock", "Toolbar.Systray")),
-    m_iconbar_theme(screen.screenNumber(), "toolbar.iconbar", "Toolbar.Iconbar") {
+    m_focused_iconbar_theme(screen.screenNumber(), "toolbar.iconbar.focused", "Toolbar.Iconbar.Focused"),
+    m_unfocused_iconbar_theme(screen.screenNumber(), "toolbar.iconbar.unfocused", "Toolbar.Iconbar.Unfocused") {
 
 }
 
@@ -95,7 +96,7 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
         witem->button().setOnClick(showmenu);
         item = witem;
     } else if (name == "iconbar") {
-        item = new IconbarTool(parent, m_iconbar_theme, screen(), tbar.menu());
+        item = new IconbarTool(parent, m_focused_iconbar_theme, m_unfocused_iconbar_theme, screen(), tbar.menu());
     } else if (name == "systemtray") {
         item = new SystemTray(parent, dynamic_cast<ButtonTheme &>(*m_systray_theme), screen());
     } else if (name == "clock") {
@@ -149,7 +150,8 @@ ToolbarItem *ToolFactory::create(const std::string &name, const FbTk::FbWindow &
 
 void ToolFactory::updateThemes() {
     m_clock_theme.reconfigTheme();
-    m_iconbar_theme.reconfigTheme();
+    m_focused_iconbar_theme.reconfigTheme();
+    m_unfocused_iconbar_theme.reconfigTheme();
     m_button_theme->reconfigTheme();
     m_workspace_theme->reconfigTheme();
 }
@@ -160,11 +162,11 @@ int ToolFactory::maxFontHeight() {
     if (max_height < m_clock_theme.font().height())
         max_height = m_clock_theme.font().height();
 
-    if (max_height < m_iconbar_theme.focusedText().font().height())
-        max_height = m_iconbar_theme.focusedText().font().height();
+    if (max_height < m_focused_iconbar_theme.text().font().height())
+        max_height = m_focused_iconbar_theme.text().font().height();
 
-    if (max_height < m_iconbar_theme.unfocusedText().font().height())
-        max_height = m_iconbar_theme.unfocusedText().font().height();
+    if (max_height < m_unfocused_iconbar_theme.text().font().height())
+        max_height = m_unfocused_iconbar_theme.text().font().height();
 
     if (max_height < m_workspace_theme->font().height())
         max_height = m_workspace_theme->font().height();
diff --git a/src/ToolFactory.hh b/src/ToolFactory.hh
index c1ce511..98124e3 100644
--- a/src/ToolFactory.hh
+++ b/src/ToolFactory.hh
@@ -55,7 +55,7 @@ private:
     std::auto_ptr<ToolTheme> m_button_theme;
     std::auto_ptr<ToolTheme> m_workspace_theme;
     std::auto_ptr<ToolTheme> m_systray_theme;
-    IconbarTheme m_iconbar_theme;
+    IconbarTheme m_focused_iconbar_theme, m_unfocused_iconbar_theme;
 };
 
 #endif // TOOLFACTORY_HH
diff --git a/src/Window.cc b/src/Window.cc
index a2a256e..5c6043d 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -4128,8 +4128,11 @@ void FluxboxWindow::ungrabPointer(Time time) {
 }
 
 void FluxboxWindow::associateClient(WinClient &client) {
-
-    IconButton *btn = frame().createTab(client);
+    IconButton *btn = new IconButton(frame().tabcontainer(),
+                                     frame().theme()->focusedIconbarTheme(),
+                                     frame().theme()->unfocusedIconbarTheme(),
+                                     client);
+    frame().createTab(*btn);
 
     FbTk::RefCount<FbTk::Command> setcmd(new SetClientCmd(client));
     btn->setOnClick(setcmd, 1);
-- 
cgit v0.11.2