From 6ed8369d57e8d3144805235fb7aeca63993742af Mon Sep 17 00:00:00 2001 From: Henrik Kinnunen Date: Thu, 18 Mar 2010 19:41:35 +0100 Subject: Changed Focusable::focusSig() to new signal system. The focus signal emits the window that had the focus status changed. --- src/AttentionNoticeHandler.cc | 32 ++++++++++++++++++++++---------- src/AttentionNoticeHandler.hh | 10 +++++++++- src/Ewmh.cc | 3 +-- src/Focusable.hh | 20 +++++++++++++++----- src/FocusableTheme.hh | 6 +++++- src/IconButton.cc | 13 +++++++++---- src/IconButton.hh | 3 +++ src/WinClient.cc | 3 +-- src/Window.cc | 8 ++++---- 9 files changed, 69 insertions(+), 29 deletions(-) diff --git a/src/AttentionNoticeHandler.cc b/src/AttentionNoticeHandler.cc index 26dd4b5..393e566 100644 --- a/src/AttentionNoticeHandler.cc +++ b/src/AttentionNoticeHandler.cc @@ -28,6 +28,7 @@ #include "FbTk/Subject.hh" #include "FbTk/Timer.hh" #include "FbTk/Resource.hh" +#include "FbTk/MemFun.hh" namespace { class ToggleFrameFocusCmd: public FbTk::Command { @@ -91,30 +92,41 @@ void AttentionNoticeHandler::addAttention(Focusable &client) { 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(subj); + removeWindow(winsubj->win()); +} + +void AttentionNoticeHandler::updateWindow(Focusable& win, bool died) { // all signals results in destruction of the notice - Focusable::FocusSubject *winsubj = - static_cast(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(); } diff --git a/src/AttentionNoticeHandler.hh b/src/AttentionNoticeHandler.hh index 3a98b09..27d3b43 100644 --- a/src/AttentionNoticeHandler.hh +++ b/src/AttentionNoticeHandler.hh @@ -48,8 +48,16 @@ public: 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; }; diff --git a/src/Ewmh.cc b/src/Ewmh.cc index b4fafc3..3b4ea51 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc @@ -1358,8 +1358,7 @@ void Ewmh::setState(FluxboxWindow &win, Atom state, bool value, 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); diff --git a/src/Focusable.hh b/src/Focusable.hh index 453a114..6108ed9 100644 --- a/src/Focusable.hh +++ b/src/Focusable.hh @@ -25,6 +25,7 @@ #include "FbTk/PixmapWithMask.hh" #include "FbTk/ITypeAheadable.hh" #include "FbTk/Subject.hh" +#include "FbTk/Signal.hh" #include @@ -41,8 +42,9 @@ public: 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 @@ public: 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 &focusSig() { return m_focussig; } + const FbTk::Signal &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 @@ protected: 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 m_focussig; }; #endif // FOCUSABLE_HH diff --git a/src/FocusableTheme.hh b/src/FocusableTheme.hh index d0f5d9e..cc14e62 100644 --- a/src/FocusableTheme.hh +++ b/src/FocusableTheme.hh @@ -25,6 +25,7 @@ #include "Focusable.hh" #include "FbTk/Observer.hh" #include "FbTk/Theme.hh" +#include "FbTk/RelaySignal.hh" template class FocusableTheme: public FbTk::ThemeProxy, @@ -33,7 +34,9 @@ public: FocusableTheme(Focusable &win, FbTk::ThemeProxy &focused, FbTk::ThemeProxy &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 @@ private: Focusable &m_win; FbTk::ThemeProxy &m_focused_theme, &m_unfocused_theme; FbTk::Subject m_reconfig_sig; + FbTk::SignalTracker m_signals; }; #endif // FOCUSABLETHEME_HH diff --git a/src/IconButton.cc b/src/IconButton.cc index 5e42e9f..ce89651 100644 --- a/src/IconButton.cc +++ b/src/IconButton.cc @@ -60,7 +60,8 @@ IconButton::IconButton(const FbTk::FbWindow &parent, 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 @@ void IconButton::reconfigTheme() { } +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; } diff --git a/src/IconButton.hh b/src/IconButton.hh index 2a81c85..5a6af0d 100644 --- a/src/IconButton.hh +++ b/src/IconButton.hh @@ -29,6 +29,7 @@ #include "FbTk/FbPixmap.hh" #include "FbTk/Observer.hh" #include "FbTk/TextButton.hh" +#include "FbTk/Signal.hh" class IconbarTheme; @@ -68,6 +69,7 @@ public: protected: void drawText(int x, int y, FbTk::FbDrawable *drawable_override); private: + void reconfigAndClear(); void setupWindow(); void showTooltip(); @@ -82,6 +84,7 @@ private: FocusableTheme m_theme; // cached pixmaps FbTk::CachedPixmap m_pm; + FbTk::SignalTracker m_signals; }; #endif // ICONBUTTON_HH diff --git a/src/WinClient.cc b/src/WinClient.cc index 0787382..6ec15f3 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc @@ -433,8 +433,7 @@ void WinClient::updateWMHints() { if (wmhint->flags & XUrgencyHint) { Fluxbox::instance()->attentionHandler().addAttention(*this); } else { - Fluxbox::instance()->attentionHandler(). - update(&m_focussig); + Fluxbox::instance()->attentionHandler().windowFocusChanged(*this); } } diff --git a/src/Window.cc b/src/Window.cc index a76beff..34b5d0c 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -979,9 +979,9 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { 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 @@ void FluxboxWindow::setFocusFlag(bool focus) { // 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); } -- cgit v0.11.2