From c31638038aabd93c74373c7ee00fbefbc68d28ae Mon Sep 17 00:00:00 2001
From: Henrik Kinnunen <fluxgen@fluxbox.org>
Date: Fri, 9 May 2008 19:39:02 +0200
Subject: Fixed so tooltip window in the iconbar when the title changes.

---
 ChangeLog            |  5 ++++-
 src/IconButton.cc    | 29 +++++++++++++++++++++-------
 src/IconButton.hh    |  5 ++++-
 src/OSDWindow.hh     |  9 ++++++++-
 src/Screen.cc        | 28 +++++++++++++--------------
 src/Screen.hh        | 13 ++++++++++---
 src/TooltipWindow.cc | 53 +++++++++++++++++++++++++++++-----------------------
 src/TooltipWindow.hh | 40 +++++++++++++++++++++++++--------------
 8 files changed, 118 insertions(+), 64 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1d2854c..690212b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
  (Format: Year/Month/Day)
-Changes for 1.0.1:
+Changes for 1.1
+*08/05/09:
+   * Made tooltip in toolbar update when the title changes (Henrik)
+     Tooltip.cc/hh, Screen.cc/cc, OSDWindow.hh
 *08/05/05:
    * Add tooltips for iconbar buttons (thanks Matteo Galiazzo)
      TooltipWindow.cc/hh
diff --git a/src/IconButton.cc b/src/IconButton.cc
index 6b8118e..0511a06 100644
--- a/src/IconButton.cc
+++ b/src/IconButton.cc
@@ -55,6 +55,7 @@ IconButton::IconButton(const FbTk::FbWindow &parent,
                   ExposureMask |EnterWindowMask | LeaveWindowMask |
                   ButtonPressMask | ButtonReleaseMask),
     m_use_pixmap(true),
+    m_has_tooltip(false),
     m_theme(win, focused_theme, unfocused_theme),
     m_pm(win.screen().imageControl()) {
 
@@ -81,16 +82,12 @@ void IconButton::exposeEvent(XExposeEvent &event) {
 }
 
 void IconButton::enterNotifyEvent(XCrossingEvent &ev) {
-
-   int xoffset = 1;
-   if (m_icon_pixmap.drawable() != 0)
-       xoffset = m_icon_window.x() + m_icon_window.width() + 1;
-    
-    if (FbTk::TextButton::textExceeds(xoffset))
-        m_win.screen().showTooltip(m_win.title());
+    m_has_tooltip = true;
+    showTooltip();
 }
 
 void IconButton::leaveNotifyEvent(XCrossingEvent &ev) {
+    m_has_tooltip = false;
     m_win.screen().hideTooltip();
 }
 
@@ -113,6 +110,15 @@ void IconButton::resize(unsigned int width, unsigned int height) {
     }
 }
 
+void IconButton::showTooltip() {
+   int xoffset = 1;
+   if (m_icon_pixmap.drawable() != 0)
+       xoffset = m_icon_window.x() + m_icon_window.width() + 1;
+
+    if (FbTk::TextButton::textExceeds(xoffset))
+        m_win.screen().showTooltip(m_win.title());
+}
+
 void IconButton::clear() {
     setupWindow();
 }
@@ -230,6 +236,15 @@ void IconButton::update(FbTk::Subject *subj) {
     } else {
         m_icon_window.clear();
     }
+    // if the title was changed AND the tooltip window is visible AND
+    // we have had an enter notify event ( without the leave notify )
+    // update the text inside it
+    if (subj == &m_win.titleSig() &&
+        m_has_tooltip &&
+        m_win.screen().tooltipWindow().isVisible()) {
+        m_win.screen().tooltipWindow().updateText(m_win.title());
+    }
+
 }
 
 void IconButton::setupWindow() {
diff --git a/src/IconButton.hh b/src/IconButton.hh
index bb41b8b..2a81c85 100644
--- a/src/IconButton.hh
+++ b/src/IconButton.hh
@@ -69,13 +69,16 @@ protected:
     void drawText(int x, int y, FbTk::FbDrawable *drawable_override);
 private:
     void setupWindow();
+    void showTooltip();
 
     Focusable &m_win;
     FbTk::FbWindow m_icon_window;
     FbTk::FbPixmap m_icon_pixmap;
     FbTk::FbPixmap m_icon_mask;
     bool m_use_pixmap;
-
+    /// whether or not this instance has the tooltip attention 
+    /// i.e if it got enter notify
+    bool m_has_tooltip;
     FocusableTheme<IconbarTheme> m_theme;
     // cached pixmaps
     FbTk::CachedPixmap m_pm;
diff --git a/src/OSDWindow.hh b/src/OSDWindow.hh
index e11a531..4a070a2 100644
--- a/src/OSDWindow.hh
+++ b/src/OSDWindow.hh
@@ -46,8 +46,15 @@ public:
     void hide();
 
     bool isVisible() const { return m_visible; }
-
+    BScreen &screen() const { return m_screen; }
+    FbTk::ThemeProxy<FbWinFrameTheme> &theme() { return m_theme; }
 protected:
+    /// Force visible status, use with care.
+    void setVisible(bool visible) {
+        m_visible = visible;
+    }
+
+private:
     void show();
 
     BScreen &m_screen;
diff --git a/src/Screen.cc b/src/Screen.cc
index 48a5c10..1ae5fbc 100644
--- a/src/Screen.cc
+++ b/src/Screen.cc
@@ -342,9 +342,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
     m_pressed_winbutton_theme(new WinButtonTheme(scrn, ".pressed", ".Pressed", *m_focused_windowtheme)),
     m_menutheme(new FbTk::MenuTheme(scrn)),
     m_root_window(scrn),
-    m_geom_window(m_root_window, *this, *m_focused_windowtheme),
-    m_pos_window(m_root_window, *this, *m_focused_windowtheme),
-    m_tooltip_window(m_root_window, *this, *m_focused_windowtheme),
+    m_geom_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
+    m_pos_window(new OSDWindow(m_root_window, *this, *m_focused_windowtheme)),
+    m_tooltip_window(new TooltipWindow(m_root_window, *this, *m_focused_windowtheme)),
     m_dummy_window(scrn, -1, -1, 1, 1, 0, true, false, CopyFromParent,
                    InputOnly),
     resource(rm, screenname, altscreenname),
@@ -486,7 +486,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
 
     renderGeomWindow();
     renderPosWindow();
-    m_tooltip_window.setDelay(*resource.tooltip_delay);
+    m_tooltip_window->setDelay(*resource.tooltip_delay);
 
     // setup workspaces and workspace menu
     int nr_ws = *resource.workspaces;
@@ -1827,12 +1827,12 @@ void BScreen::showPosition(int x, int y) {
 
     char label[256];
     sprintf(label, "X:%5d x Y:%5d", x, y);
-    m_pos_window.showText(label);
+    m_pos_window->showText(label);
 }
 
 
 void BScreen::hidePosition() {
-    m_pos_window.hide();
+    m_pos_window->hide();
 }
 
 // can be negative when base_width/height > min_width/height
@@ -1848,23 +1848,23 @@ void BScreen::showGeometry(int gx, int gy) {
                     "W: %4d x H: %4d",
                     "Format for width and height window, %4d for width, and %4d for height").c_str(),
             gx, gy);
-    m_geom_window.showText(label);
+    m_geom_window->showText(label);
 }
 
 
 void BScreen::showTooltip(const std::string &text) {
     if (*resource.tooltip_delay >= 0)
-        m_tooltip_window.showText(text);
+        m_tooltip_window->showText(text);
 }
 
 void BScreen::hideTooltip() {
     if (*resource.tooltip_delay >= 0)
-        m_tooltip_window.hide();
+        m_tooltip_window->hide();
 }
 
 
 void BScreen::hideGeometry() {
-    m_geom_window.hide();
+    m_geom_window->hide();
 }
 
 void BScreen::setLayer(FbTk::XLayerItem &item, int layernum) {
@@ -1912,14 +1912,14 @@ void BScreen::renderGeomWindow() {
             _FB_XTEXT(Screen, GeometrySpacing,
             "W: %04d x H: %04d", "Representative maximum sized text for width and height dialog").c_str(),
             0, 0);
-    m_geom_window.resize(label);
-    m_geom_window.reconfigTheme();
+    m_geom_window->resize(label);
+    m_geom_window->reconfigTheme();
 }
 
 
 void BScreen::renderPosWindow() {
-    m_pos_window.resize("0:00000 x 0:00000");
-    m_pos_window.reconfigTheme();
+    m_pos_window->resize("0:00000 x 0:00000");
+    m_pos_window->reconfigTheme();
 }
 
 void BScreen::updateSize() {
diff --git a/src/Screen.hh b/src/Screen.hh
index cf8bf1f..02fcc0d 100644
--- a/src/Screen.hh
+++ b/src/Screen.hh
@@ -64,6 +64,8 @@ class Toolbar;
 class HeadArea;
 class FocusControl;
 class ScreenPlacement;
+class TooltipWindow;
+class OSDWindow;
 
 namespace FbTk {
 class Menu;
@@ -73,6 +75,7 @@ class FbWindow;
 class Subject;
 }
 
+
 /// Handles screen connection, screen clients and workspaces
 /**
  Create workspaces, handles switching between workspaces and windows
@@ -389,10 +392,14 @@ public:
     /// show geomentry with "width x height"-text, not size of window
     void showGeometry(int width, int height);
     void hideGeometry();
-    
+
+    /// @param text the text to be displayed in the tooltip window
     void showTooltip(const std::string &text);
+    /// Hides the tooltip window
     void hideTooltip();
 
+    TooltipWindow& tooltipWindow() { return *m_tooltip_window; }
+
     void setLayer(FbTk::XLayerItem &item, int layernum);
     // remove? no, items are never removed from their layer until they die
 
@@ -538,8 +545,8 @@ private:
     std::auto_ptr<RootTheme> m_root_theme;
 
     FbRootWindow m_root_window;
-    OSDWindow m_geom_window, m_pos_window;
-    TooltipWindow m_tooltip_window;
+    std::auto_ptr<OSDWindow> m_geom_window, m_pos_window;
+    std::auto_ptr<TooltipWindow> m_tooltip_window;
     FbTk::FbWindow m_dummy_window;
 
     struct ScreenResource {
diff --git a/src/TooltipWindow.cc b/src/TooltipWindow.cc
index 42926d8..284f232 100644
--- a/src/TooltipWindow.cc
+++ b/src/TooltipWindow.cc
@@ -28,33 +28,35 @@
 TooltipWindow::TooltipWindow(const FbTk::FbWindow &parent, BScreen &screen,
                              FbTk::ThemeProxy<FbWinFrameTheme> &theme):
     OSDWindow(parent, screen, theme),
-    delay(-1) {
+    m_delay(-1) {
 
-    FbTk::RefCount<FbTk::Command<void> > raisecmd(new FbTk::SimpleCommand<TooltipWindow>(*this, &TooltipWindow::raiseTooltip));
-    timer.setCommand(raisecmd);
-    timer.fireOnce(true);
+    FbTk::RefCount<FbTk::Command<void> > 
+        raisecmd(new FbTk::SimpleCommand<TooltipWindow>(*this, 
+                                                        &TooltipWindow::raiseTooltip));
+    m_timer.setCommand(raisecmd);
+    m_timer.fireOnce(true);
 
 }
 
 void TooltipWindow::showText(const std::string &text) {
 
-    lastText = text.c_str();
-    if (delay == 0)
+    m_lastText = text;
+    if (m_delay == 0)
         raiseTooltip();
     else
-        timer.start();
+        m_timer.start();
 
 }
 
 void TooltipWindow::raiseTooltip() {
 
-    if (lastText.size() == 0)
+    if (m_lastText.empty())
         return;
 
-    resize(lastText);
+    resize(m_lastText);
     reconfigTheme();
-    int h = m_theme->font().height() + m_theme->bevelWidth() * 2;
-    int w = m_theme->font().textWidth(lastText, lastText.size()) + m_theme->bevelWidth() * 2;
+    int h = theme()->font().height() + theme()->bevelWidth() * 2;
+    int w = theme()->font().textWidth(m_lastText, m_lastText.size()) + theme()->bevelWidth() * 2;
 
     Window root_ret; // not used
     Window window_ret; // not used
@@ -62,13 +64,13 @@ void TooltipWindow::raiseTooltip() {
     int wx, wy; // not used
     unsigned int mask; // not used
 
-    XQueryPointer(display(), m_screen.rootWindow().window(),
+    XQueryPointer(display(), screen().rootWindow().window(),
                   &root_ret, &window_ret, &rx, &ry, &wx, &wy, &mask);
 
-    int head = m_screen.getHead(rx, ry);
-    int head_top = m_screen.getHeadY(head);
-    int head_left = m_screen.getHeadX(head);
-    int head_right = head_left + m_screen.getHeadWidth(head);
+    int head = screen().getHead(rx, ry);
+    int head_top = screen().getHeadY(head);
+    int head_left = screen().getHeadX(head);
+    int head_right = head_left + screen().getHeadWidth(head);
 
     // center the mouse horizontally
     rx -= w/2;
@@ -88,22 +90,27 @@ void TooltipWindow::raiseTooltip() {
 
     show();
     clear();
-    m_theme->font().drawText(*this, m_screen.screenNumber(),
-                             m_theme->iconbarTheme().text().textGC(), lastText,
-                             lastText.size(), m_theme->bevelWidth(),
-                             m_theme->bevelWidth() + m_theme->font().ascent());
+    theme()->font().drawText(*this, screen().screenNumber(),
+                             theme()->iconbarTheme().text().textGC(), 
+                             m_lastText, m_lastText.size(), 
+                             theme()->bevelWidth(),
+                             theme()->bevelWidth() + theme()->font().ascent());
 }
 
+void TooltipWindow::updateText(const std::string &text) {
+    m_lastText = text;
+    raiseTooltip();
+}
 
 void TooltipWindow::show() {
-    if (m_visible)
+    if (isVisible())
         return;
-    m_visible = true;
+    setVisible(true);
     raise();
     FbTk::FbWindow::show();
 }
 
 void TooltipWindow::hide() {
-    timer.stop();
+    m_timer.stop();
     OSDWindow::hide();
 }
diff --git a/src/TooltipWindow.hh b/src/TooltipWindow.hh
index 03abc1d..401e442 100644
--- a/src/TooltipWindow.hh
+++ b/src/TooltipWindow.hh
@@ -17,9 +17,10 @@
 // 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 TOOLTIPWINDOW_HH_
-#ifndef TOOLTIPWINDOW_HH_
-#define TOOLTIPWINDOW_HH_
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef TOOLTIPWINDOW_HH
+#define TOOLTIPWINDOW_HH
 
 #include "OSDWindow.hh"
 #include "FbTk/Command.hh"
@@ -27,27 +28,38 @@
 #include "FbTk/Timer.hh"
 #include "FbTk/SimpleCommand.hh"
 
-
+/**
+ * Displays a tooltip window
+ */
 class TooltipWindow : public OSDWindow  {
 public:
     TooltipWindow(const FbTk::FbWindow &parent, BScreen &screen,
                   FbTk::ThemeProxy<FbWinFrameTheme> &theme);
-
+    /**
+     * Sets the text in the window and starts the display timer.
+     * @param text the text to show in the window.
+     */
     void showText(const std::string &text);
-    void setDelay(int iDelay) { 
-        delay = iDelay; 
-        timer.setTimeout(delay);
+    /// updates the text directly without any delay
+    void updateText(const std::string &text);
+
+    /// Sets the delay before the window pops up
+    void setDelay(int delay) {
+        m_delay = delay;
+        m_timer.setTimeout(delay);
     }
-    void hide() ;    
+
+    void hide();
+
 
 private:
     void raiseTooltip();
-    void show();    
-    int delay;
-    std::string lastText;
-    FbTk::Timer timer;
+    void show();
+    int m_delay; ///< delay time for the timer
+    std::string m_lastText; ///< last text to be displayed
+    FbTk::Timer m_timer; ///< delay timer before the tooltip will show
 };
 
 
 
-#endif /*TOOLTIPWINDOW_HH_*/
+#endif // TOOLTIPWINDOW_HH_
-- 
cgit v0.11.2