Changed Focusable::focusSig() to new signal system. The focus signal emits the window that had the focus status changed.
@@ -28,6 +28,7 @@ #include "FbTk/STLUtil.hh"
#include "FbTk/Subject.hh" #include "FbTk/Timer.hh" #include "FbTk/Resource.hh" +#include "FbTk/MemFun.hh" namespace { class ToggleFrameFocusCmd: public FbTk::Command<void> {@@ -91,30 +92,41 @@
m_attentions[&client] = timer; // attach signals that will make notice go away client.dieSig().attach(this); - client.focusSig().attach(this); + + client.focusSig().connect(MemFun(*this, &AttentionNoticeHandler::windowFocusChanged)); // update _NET_WM_STATE atom if (client.fbwindow()) client.fbwindow()->stateSig().notify(); } -void AttentionNoticeHandler::update(FbTk::Subject *subj) { +void AttentionNoticeHandler::windowFocusChanged(Focusable& win) { + updateWindow(win, false); +} +void AttentionNoticeHandler::removeWindow(Focusable& win) { + updateWindow(win, true); +} +void AttentionNoticeHandler::update(FbTk::Subject* subj) { // we need to be able to get the window if (!subj || typeid(*subj) != typeid(Focusable::FocusSubject)) return; + Focusable::FocusSubject *winsubj = + static_cast<Focusable::FocusSubject *>(subj); + + removeWindow(winsubj->win()); +} +void AttentionNoticeHandler::updateWindow(Focusable& win, bool died) { // all signals results in destruction of the notice - Focusable::FocusSubject *winsubj = - static_cast<Focusable::FocusSubject *>(subj); - delete m_attentions[&winsubj->win()]; - m_attentions.erase(&winsubj->win()); - winsubj->win().setAttentionState(false); + delete m_attentions[&win]; + m_attentions.erase(&win); + win.setAttentionState(false); - // update _NET_WM_STATE atom - FluxboxWindow *fbwin = winsubj->win().fbwindow(); - if (fbwin && winsubj != &winsubj->win().dieSig()) + // update _NET_WM_STATE atom if the window is not dead + FluxboxWindow *fbwin = win.fbwindow(); + if (fbwin && ! died) fbwin->stateSig().notify(); }
@@ -48,8 +48,16 @@ /// removes the client from the attention map
void update(FbTk::Subject *subj); bool isDemandingAttention(const Focusable &client); - + + /// Called when window focus changes. + void windowFocusChanged(Focusable& win); + /// Remove window from attentionHandler. + void removeWindow(Focusable& win); + private: + /// updates the windows state in this instance. + void updateWindow(Focusable& win, bool died); + NoticeMap m_attentions; };
@@ -1358,8 +1358,7 @@ } else if (state == m_net->wm_state_demands_attention) {
if (value) { // if add attention Fluxbox::instance()->attentionHandler().addAttention(client); } else { // erase it - Fluxbox::instance()->attentionHandler(). - update(&client.focusSig()); + Fluxbox::instance()->attentionHandler().removeWindow(client); } } else if (state == m_net->wm_state_modal) { client.setStateModal(value);
@@ -25,6 +25,7 @@
#include "FbTk/PixmapWithMask.hh" #include "FbTk/ITypeAheadable.hh" #include "FbTk/Subject.hh" +#include "FbTk/Signal.hh" #include <string>@@ -41,8 +42,9 @@ Focusable(BScreen &scr, FluxboxWindow *fbwin = 0):
m_screen(scr), m_fbwin(fbwin), m_instance_name("fluxbox"), m_class_name("fluxbox"), m_focused(false), m_attention_state(false), - m_titlesig(*this), m_focussig(*this), m_diesig(*this), - m_attentionsig(*this) { } + m_titlesig(*this), m_diesig(*this), + m_attentionsig(*this), + m_focussig() { } virtual ~Focusable() { } /**@@ -118,14 +120,19 @@ // Used for both title and icon changes.
FbTk::Subject &titleSig() { return m_titlesig; } // Used for both title and icon changes. const FbTk::Subject &titleSig() const { return m_titlesig; } - FbTk::Subject &focusSig() { return m_focussig; } - const FbTk::Subject &focusSig() const { return m_focussig; } + FbTk::Signal<void, Focusable&> &focusSig() { return m_focussig; } + const FbTk::Signal<void, Focusable&> &focusSig() const { return m_focussig; } FbTk::Subject &dieSig() { return m_diesig; } const FbTk::Subject &dieSig() const { return m_diesig; } FbTk::Subject &attentionSig() { return m_attentionsig; } const FbTk::Subject &attentionSig() const { return m_attentionsig; } /** @} */ // end group signals + /// Notify any listeners that the focus changed for this window. + void notifyFocusChanged() { + m_focussig.emit(*this); + } + protected: BScreen &m_screen; //< the screen in which it works FluxboxWindow *m_fbwin; //< the working fluxbox window@@ -136,7 +143,10 @@ bool m_attention_state; //< state of icon button while demanding attention
FbTk::PixmapWithMask m_icon; //< icon pixmap with mask // state and hint signals - FocusSubject m_titlesig, m_focussig, m_diesig, m_attentionsig; + FocusSubject m_titlesig, m_diesig, m_attentionsig; + +private: + FbTk::Signal<void, Focusable&> m_focussig; }; #endif // FOCUSABLE_HH
@@ -25,6 +25,7 @@
#include "Focusable.hh" #include "FbTk/Observer.hh" #include "FbTk/Theme.hh" +#include "FbTk/RelaySignal.hh" template <typename BaseTheme> class FocusableTheme: public FbTk::ThemeProxy<BaseTheme>,@@ -33,7 +34,9 @@ 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); + // relay focus signal to reconfig signal + FbTk::relaySignal(m_signals, m_win.focusSig(), m_reconfig_sig); + m_win.attentionSig().attach(this); m_focused_theme.reconfigSig().attach(this); m_unfocused_theme.reconfigSig().attach(this);@@ -66,6 +69,7 @@
Focusable &m_win; FbTk::ThemeProxy<BaseTheme> &m_focused_theme, &m_unfocused_theme; FbTk::Subject m_reconfig_sig; + FbTk::SignalTracker m_signals; }; #endif // FOCUSABLETHEME_HH
@@ -60,7 +60,8 @@ m_theme(win, focused_theme, unfocused_theme),
m_pm(win.screen().imageControl()) { m_win.titleSig().attach(this); - m_win.focusSig().attach(this); + m_signals.join(m_win.focusSig(), + MemFunIgnoreArgs(*this, &IconButton::reconfigAndClear)); m_win.attentionSig().attach(this); FbTk::EventManager::instance()->add(*this, m_icon_window);@@ -169,11 +170,15 @@ updateBackground(false);
} +void IconButton::reconfigAndClear() { + reconfigTheme(); + clear(); +} + void IconButton::update(FbTk::Subject *subj) { // if the window's focus state changed, we need to update the background - if (subj == &m_win.focusSig() || subj == &m_win.attentionSig()) { - reconfigTheme(); - clear(); + if (subj == &m_win.attentionSig()) { + reconfigAndClear(); return; }
@@ -29,6 +29,7 @@ #include "FbTk/CachedPixmap.hh"
#include "FbTk/FbPixmap.hh" #include "FbTk/Observer.hh" #include "FbTk/TextButton.hh" +#include "FbTk/Signal.hh" class IconbarTheme;@@ -68,6 +69,7 @@
protected: void drawText(int x, int y, FbTk::FbDrawable *drawable_override); private: + void reconfigAndClear(); void setupWindow(); void showTooltip();@@ -82,6 +84,7 @@ bool m_has_tooltip;
FocusableTheme<IconbarTheme> m_theme; // cached pixmaps FbTk::CachedPixmap m_pm; + FbTk::SignalTracker m_signals; }; #endif // ICONBUTTON_HH
@@ -433,8 +433,7 @@ if (fbwindow()) {
if (wmhint->flags & XUrgencyHint) { Fluxbox::instance()->attentionHandler().addAttention(*this); } else { - Fluxbox::instance()->attentionHandler(). - update(&m_focussig); + Fluxbox::instance()->attentionHandler().windowFocusChanged(*this); } }
@@ -979,9 +979,9 @@ }
m_client->raise(); if (m_focused) { - m_client->focusSig().notify(); + m_client->notifyFocusChanged(); if (old) - old->focusSig().notify(); + old->notifyFocusChanged(); } fbdbg<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<<@@ -1777,9 +1777,9 @@
// did focus change? notify listeners if (was_focused != focus) { m_attention_state = false; - m_focussig.notify(); + notifyFocusChanged(); if (m_client) - m_client->focusSig().notify(); + m_client->notifyFocusChanged(); Fluxbox::instance()->keys()->doAction(focus ? FocusIn : FocusOut, 0, 0, Keys::ON_WINDOW, m_client); }