From 46bca62a9cd8052bd8749da8b1aa7539d5fe8c23 Mon Sep 17 00:00:00 2001
From: Mark Tiefenbruck <mark@fluxbox.org>
Date: Sat, 24 May 2008 01:03:59 -0700
Subject: move FluxboxWindow::applyDecorations() to FbWinFrame

---
 src/FbTk/FbWindow.cc |  53 ++++++++++++----------
 src/FbTk/FbWindow.hh |   2 +
 src/FbWinFrame.cc    | 125 ++++++++++++++++++++++++++++++++-------------------
 src/FbWinFrame.hh    |  28 +++++++-----
 src/Window.cc        |  73 ++++--------------------------
 src/Window.hh        |   2 +-
 6 files changed, 137 insertions(+), 146 deletions(-)

diff --git a/src/FbTk/FbWindow.cc b/src/FbTk/FbWindow.cc
index 056e2f1..fb68eb9 100644
--- a/src/FbTk/FbWindow.cc
+++ b/src/FbTk/FbWindow.cc
@@ -43,21 +43,28 @@
 
 namespace FbTk {
 
-FbWindow::FbWindow():FbDrawable(), m_parent(0), m_screen_num(0), m_window(0), m_x(0), m_y(0),
-                     m_width(0), m_height(0), m_border_width(0), m_depth(0), m_destroy(true),
-                     m_lastbg_color_set(false), m_lastbg_color(0), m_lastbg_pm(0), m_renderer(0) {
+FbWindow::FbWindow():
+    FbDrawable(),
+    m_parent(0), m_screen_num(0), m_window(0),
+    m_x(0), m_y(0), m_width(0), m_height(0),
+    m_border_width(0), m_border_color(0),
+    m_depth(0), m_destroy(true),
+    m_lastbg_color_set(false), m_lastbg_color(0), m_lastbg_pm(0),
+    m_renderer(0) {
 
 }
 
-FbWindow::FbWindow(const FbWindow& the_copy):FbDrawable(),
-                                             m_parent(the_copy.parent()),
-                                             m_screen_num(the_copy.screenNumber()), m_window(the_copy.window()),
-                                             m_x(the_copy.x()), m_y(the_copy.y()),
-                                             m_width(the_copy.width()), m_height(the_copy.height()),
-                                             m_border_width(the_copy.borderWidth()),
-                                             m_depth(the_copy.depth()), m_destroy(true),
-                                             m_lastbg_color_set(false), m_lastbg_color(0), 
-                                             m_lastbg_pm(0), m_renderer(the_copy.m_renderer) {
+FbWindow::FbWindow(const FbWindow& the_copy):
+    FbDrawable(),
+    m_parent(the_copy.parent()),
+    m_screen_num(the_copy.screenNumber()), m_window(the_copy.window()),
+    m_x(the_copy.x()), m_y(the_copy.y()),
+    m_width(the_copy.width()), m_height(the_copy.height()),
+    m_border_width(the_copy.borderWidth()),
+    m_border_color(the_copy.borderColor()),
+    m_depth(the_copy.depth()), m_destroy(true),
+    m_lastbg_color_set(false), m_lastbg_color(0), m_lastbg_pm(0),
+    m_renderer(the_copy.m_renderer) {
     the_copy.m_window = 0;
 }
 
@@ -100,17 +107,14 @@ FbWindow::FbWindow(const FbWindow &parent,
 
 };
 
-FbWindow::FbWindow(Window client):FbDrawable(), m_parent(0),
-                                  m_screen_num(0),
-                                  m_window(0),
-                                  m_x(0), m_y(0),
-                                  m_width(1), m_height(1),
-                                  m_border_width(0),
-                                  m_depth(0),
-                                  m_destroy(false),  // don't destroy this window
-                                  m_lastbg_color_set(false), m_lastbg_color(0),
-                                  m_lastbg_pm(0), m_renderer(0) {
-
+FbWindow::FbWindow(Window client):
+    FbDrawable(),
+    m_parent(0), m_screen_num(0), m_window(0),
+    m_x(0), m_y(0), m_width(1), m_height(1),
+    m_border_width(0), m_border_color(0),
+    m_depth(0), m_destroy(false), // don't destroy this window
+    m_lastbg_color_set(false), m_lastbg_color(0), m_lastbg_pm(0),
+    m_renderer(0) {
     setNew(client);
 }
 
@@ -235,6 +239,7 @@ void FbWindow::updateBackground(bool only_if_alpha) {
 
 void FbWindow::setBorderColor(const FbTk::Color &border_color) {
     XSetWindowBorder(display(), m_window, border_color.pixel());
+    m_border_color = border_color.pixel();
 }
 
 void FbWindow::setBorderWidth(unsigned int size) {
@@ -373,6 +378,7 @@ FbWindow &FbWindow::operator = (const FbWindow &win) {
     m_width = win.width();
     m_height = win.height();
     m_border_width = win.borderWidth();
+    m_border_color = win.borderColor();
     m_depth = win.depth();
     // take over this window
     win.m_window = 0;
@@ -601,6 +607,7 @@ void FbWindow::create(Window parent, int x, int y,
 
 
     m_border_width = 0;
+    m_border_color = 0;
 
     long valmask = CWEventMask;
     XSetWindowAttributes values;
diff --git a/src/FbTk/FbWindow.hh b/src/FbTk/FbWindow.hh
index e9f8e30..f212e50 100644
--- a/src/FbTk/FbWindow.hh
+++ b/src/FbTk/FbWindow.hh
@@ -177,6 +177,7 @@ public:
     unsigned int width() const { return m_width; }
     unsigned int height() const { return m_height; }
     unsigned int borderWidth() const { return m_border_width; }
+    unsigned long borderColor() const { return m_border_color; }
     unsigned int depth() const { return m_depth; }
     unsigned char alpha() const;
     int screenNumber() const;
@@ -225,6 +226,7 @@ private:
     int m_x, m_y; ///< position of window
     unsigned int m_width, m_height;  ///< size of window
     unsigned int m_border_width; ///< border size
+    unsigned long m_border_color; ///< border color
     unsigned int m_depth; ///< bit depth
     bool m_destroy; ///< wheter the x window was created before
     std::auto_ptr<FbTk::Transparent> m_transparent;
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc
index a806888..a31c327 100644
--- a/src/FbWinFrame.cc
+++ b/src/FbWinFrame.cc
@@ -487,12 +487,7 @@ void FbWinFrame::setFocus(bool newvalue) {
         }
     }
 
-    if (m_decoration_mask & DECORM_BORDER &&
-        (theme().focusedTheme()->border().width() !=
-         theme().unfocusedTheme()->border().width() ||
-         theme().focusedTheme()->border().color().pixel() !=
-         theme().unfocusedTheme()->border().color().pixel()))
-        setBorderWidth(theme()->border().width());
+    setBorderWidth();
 
     applyAll();
     clearAll();
@@ -759,28 +754,6 @@ bool FbWinFrame::showHandle() {
     return true;
 }
 
-bool FbWinFrame::hideAllDecorations() {
-    bool changed = false;
-    changed |= hideHandle();
-    changed |= hideTitlebar();
-    // resize done by hide*
-    reconfigure();
-
-    return changed;
-}
-
-bool FbWinFrame::showAllDecorations() {
-    bool changed = false;
-    if (!m_use_handle)
-        changed |= showHandle();
-    if (!m_use_titlebar)
-        changed |= showTitlebar();
-    // resize shouldn't be necessary
-    reconfigure();
-
-    return changed;
-}
-
 /**
    Set new event handler for the frame's windows
 */
@@ -871,8 +844,7 @@ void FbWinFrame::reconfigure() {
     gravityTranslate(grav_x, grav_y, -m_active_gravity, m_active_orig_client_bw, false);
 
     m_bevel = theme()->bevelWidth();
-    setBorderWidth(m_decoration_mask & DECORM_BORDER ?
-                   theme()->border().width() : 0);
+    setBorderWidth();
 
     if (m_decoration_mask & DECORM_HANDLE && theme()->handleWidth() != 0)
         showHandle();
@@ -1439,14 +1411,78 @@ void FbWinFrame::applyTabContainer() {
     }
 }
 
-void FbWinFrame::setBorderWidth(unsigned int border_width) {
-    int bw_changes = 0;
-
+void FbWinFrame::applyDecorations() {
     int grav_x=0, grav_y=0;
     // negate gravity
-    gravityTranslate(grav_x, grav_y, -m_active_gravity, m_active_orig_client_bw, false);
+    gravityTranslate(grav_x, grav_y, -m_active_gravity, m_active_orig_client_bw,
+                     false);
+
+    bool client_move = setBorderWidth(false);
+
+    // tab deocration only affects if we're external
+    // must do before the setTabMode in case it goes
+    // to external and is meant to be hidden
+    if (m_decoration_mask & DECORM_TAB)
+        client_move |= showTabs();
+    else
+        client_move |= hideTabs();
+
+    // we rely on frame not doing anything if it is already shown/hidden
+    if (m_decoration_mask & DECORM_TITLEBAR) {
+        client_move |= showTitlebar();
+        if (m_screen.getDefaultInternalTabs())
+            client_move |= setTabMode(INTERNAL);
+        else
+            client_move |= setTabMode(EXTERNAL);
+    } else {
+        client_move |= hideTitlebar();
+        if (m_decoration_mask & DECORM_TAB)
+            client_move |= setTabMode(EXTERNAL);
+    }
+
+    if (m_decoration_mask & DECORM_HANDLE)
+        client_move |= showHandle();
+    else
+        client_move |= hideHandle();
 
+    // apply gravity once more
+    gravityTranslate(grav_x, grav_y, m_active_gravity, m_active_orig_client_bw,
+                     false);
 
+    // if the location changes, shift it
+    if (grav_x != 0 || grav_y != 0) {
+        move(grav_x + x(), grav_y + y());
+        client_move = true;
+    }
+
+    reconfigure();
+    if (client_move)
+        frameExtentSig().notify();
+}
+
+bool FbWinFrame::setBorderWidth(bool do_move) {
+    unsigned int border_width = m_decoration_mask & DECORM_BORDER ?
+                                theme()->border().width() : 0;
+
+    if (border_width &&
+        theme()->border().color().pixel() != window().borderColor()) {
+        window().setBorderColor(theme()->border().color());
+        titlebar().setBorderColor(theme()->border().color());
+        handle().setBorderColor(theme()->border().color());
+        gripLeft().setBorderColor(theme()->border().color());
+        gripRight().setBorderColor(theme()->border().color());
+    }
+
+    if (border_width == window().borderWidth())
+        return false;
+
+    int grav_x=0, grav_y=0;
+    // negate gravity
+    if (do_move)
+        gravityTranslate(grav_x, grav_y, -m_active_gravity,
+                         m_active_orig_client_bw, false);
+
+    int bw_changes = 0;
     // we need to change the size of the window
     // if the border width changes...
     if (m_use_titlebar)
@@ -1455,21 +1491,13 @@ void FbWinFrame::setBorderWidth(unsigned int border_width) {
         bw_changes += static_cast<signed>(border_width - handle().borderWidth());
 
     window().setBorderWidth(border_width);
-    window().setBorderColor(theme()->border().color());
 
     setTabMode(NOTSET);
 
     titlebar().setBorderWidth(border_width);
-    titlebar().setBorderColor(theme()->border().color());
-
     handle().setBorderWidth(border_width);
-    handle().setBorderColor(theme()->border().color());
-
     gripLeft().setBorderWidth(border_width);
-    gripLeft().setBorderColor(theme()->border().color());
-
     gripRight().setBorderWidth(border_width);
-    gripRight().setBorderColor(theme()->border().color());
 
     if (bw_changes != 0)
         resize(width(), height() + bw_changes);
@@ -1477,11 +1505,16 @@ void FbWinFrame::setBorderWidth(unsigned int border_width) {
     if (m_tabmode == EXTERNAL)
         alignTabs();
 
-    gravityTranslate(grav_x, grav_y, m_active_gravity, m_active_orig_client_bw, false);
-    // if the location changes, shift it
-    if (grav_x != 0 || grav_y != 0)
-        move(grav_x + x(), grav_y + y());
+    if (do_move) {
+        frameExtentSig().notify();
+        gravityTranslate(grav_x, grav_y, m_active_gravity,
+                         m_active_orig_client_bw, false);
+        // if the location changes, shift it
+        if (grav_x != 0 || grav_y != 0)
+            move(grav_x + x(), grav_y + y());
+    }
 
+    return true;
 }
 
 // this function translates its arguments according to win_gravity
diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh
index 643fc49..f288253 100644
--- a/src/FbWinFrame.hh
+++ b/src/FbWinFrame.hh
@@ -25,7 +25,7 @@
 #include "FbTk/FbWindow.hh"
 #include "FbTk/EventHandler.hh"
 #include "FbTk/RefCount.hh"
-#include "FbTk/Observer.hh"
+#include "FbTk/Subject.hh"
 #include "FbTk/Color.hh"
 #include "FbTk/XLayerItem.hh"
 #include "FbTk/TextButton.hh"
@@ -186,21 +186,12 @@ public:
     void removeEventHandler();
 
     void setDecorationMask(unsigned int mask) { m_decoration_mask = mask; }
-    // these return true/false for if something changed
-    bool hideTitlebar();
-    bool showTitlebar();
-    bool hideTabs();
-    bool showTabs();
-    bool hideHandle();
-    bool showHandle();
-    bool hideAllDecorations();
-    bool showAllDecorations();
+    void applyDecorations();
 
     // this function translates its arguments according to win_gravity
     // if win_gravity is negative, it does an inverse translation
     void gravityTranslate(int &x, int &y, int win_gravity, unsigned int client_bw, bool move_frame = false);
     void setActiveGravity(int gravity, unsigned int orig_client_bw) { m_active_gravity = gravity; m_active_orig_client_bw = orig_client_bw; }
-    void setBorderWidth(unsigned int borderW);
 
     /**
        @name Event handlers
@@ -266,6 +257,9 @@ public:
     const FbTk::XLayerItem &layerItem() const { return m_layeritem; }
     FbTk::XLayerItem &layerItem() { return m_layeritem; }
 
+    const FbTk::Subject &frameExtentSig() const { return m_frame_extent_sig; }
+    FbTk::Subject &frameExtentSig() { return m_frame_extent_sig; }
+
     //@}
 
 private:
@@ -290,6 +284,15 @@ private:
 
     //@}
 
+    // these return true/false for if something changed
+    bool hideTitlebar();
+    bool showTitlebar();
+    bool hideTabs();
+    bool showTabs();
+    bool hideHandle();
+    bool showHandle();
+    bool setBorderWidth(bool do_move = true);
+
     /**
        @name apply pixmaps depending on focus
     */
@@ -332,6 +335,9 @@ private:
         m_grip_left; ///< left grip
     FbTk::FbWindow m_clientarea; ///< window that sits behind client window to fill gaps @see setClientWindow
     //@}
+
+    FbTk::Subject m_frame_extent_sig;
+
     typedef std::vector<FbTk::Button *> ButtonList;
     ButtonList m_buttons_left, ///< buttons to the left
         m_buttons_right; ///< buttons to the right
diff --git a/src/Window.cc b/src/Window.cc
index 8ad1762..29acd3b 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -303,6 +303,7 @@ FluxboxWindow::FluxboxWindow(WinClient &client, FbTk::XLayer &layer):
     m_resize_corner(RIGHTBOTTOM) {
 
     m_theme.reconfigSig().attach(this);
+    m_frame.frameExtentSig().attach(this);
 
     init();
 
@@ -501,7 +502,7 @@ void FluxboxWindow::init() {
         setOnHead(screen().getCurrHead());
 
     // we must do this now, or else resizing may not work properly
-    applyDecorations(true);
+    applyDecorations();
 
     Fluxbox::instance()->attachSignals(*this);
 
@@ -601,7 +602,7 @@ void FluxboxWindow::init() {
     gettimeofday(&now, NULL);
     m_creation_time = now.tv_sec;
 
-    sendConfigureNotify();
+    frame().frameExtentSig().notify();
 
     setupWindow();
 
@@ -3015,74 +3016,16 @@ void FluxboxWindow::update(FbTk::Subject *subj) {
     } else if (subj == &m_theme.reconfigSig()) {
         frame().reconfigure();
         reconfigTheme();
+    } else if (m_initialized && subj == &m_frame.frameExtentSig()) {
+        Fluxbox::instance()->updateFrameExtents(*this);
+        sendConfigureNotify();
     }
 }
 
 // commit current decoration values to actual displayed things
-void FluxboxWindow::applyDecorations(bool initial) {
-    frame().clientArea().setBorderWidth(0); // client area bordered by other things
-
-    unsigned int border_width = 0;
-    if (decorations.border)
-        border_width = frame().theme()->border().width();
-
-    bool client_move = false;
-
-    // borderWidth setting handles its own gravity
-    if (initial || frame().window().borderWidth() != border_width) {
-        client_move = true;
-        frame().setBorderWidth(border_width);
-    }
-
-    int grav_x=0, grav_y=0;
-    // negate gravity
-    frame().gravityTranslate(grav_x, grav_y, -m_client->gravity(), m_client->old_bw, false);
-
-    // tab deocration only affects if we're external
-    // must do before the setTabMode in case it goes
-    // to external and is meant to be hidden
-    if (decorations.tab)
-        client_move |= frame().showTabs();
-    else
-        client_move |= frame().hideTabs();
-
-    // we rely on frame not doing anything if it is already shown/hidden
-    if (decorations.titlebar) {
-        bool change = frame().showTitlebar();
-        client_move |= change;
-        if (screen().getDefaultInternalTabs()) {
-            client_move |= frame().setTabMode(FbWinFrame::INTERNAL);
-        } else {
-            client_move |= frame().setTabMode(FbWinFrame::EXTERNAL);
-        }
-    } else {
-        client_move |= frame().hideTitlebar();
-        if (decorations.tab)
-            client_move |= frame().setTabMode(FbWinFrame::EXTERNAL);
-    }
-
-    if (decorations.handle) {
-        client_move |= frame().showHandle();
-    } else
-        client_move |= frame().hideHandle();
-
-    // apply gravity once more
-    frame().gravityTranslate(grav_x, grav_y, m_client->gravity(), m_client->old_bw, false);
-
-    // if the location changes, shift it
-    if (grav_x != 0 || grav_y != 0) {
-        move(grav_x + frame().x(), grav_y + frame().y());
-        client_move = true;
-    }
-
+void FluxboxWindow::applyDecorations() {
     frame().setDecorationMask(decorationMask());
-    frame().reconfigure();
-    if (client_move)
-        Fluxbox::instance()->updateFrameExtents(*this);
-
-    if (!initial && client_move)
-        sendConfigureNotify();
-
+    frame().applyDecorations();
 }
 
 void FluxboxWindow::toggleDecoration() {
diff --git a/src/Window.hh b/src/Window.hh
index c05f525..3da2fb1 100644
--- a/src/Window.hh
+++ b/src/Window.hh
@@ -357,7 +357,7 @@ public:
     /// handle Subject notifications
     void update(FbTk::Subject *subj);
 
-    void applyDecorations(bool initial = false);
+    void applyDecorations();
     void toggleDecoration();
 
     unsigned int decorationMask() const;
-- 
cgit v0.11.2