Changed Focusable::focusSig() to new signal system.

The focus signal emits the window that had the focus status changed.
This commit is contained in:
Henrik Kinnunen 2010-03-18 19:41:35 +01:00
parent 02bb93590c
commit 6ed8369d57
9 changed files with 69 additions and 29 deletions

View file

@ -28,6 +28,7 @@
#include "FbTk/Subject.hh" #include "FbTk/Subject.hh"
#include "FbTk/Timer.hh" #include "FbTk/Timer.hh"
#include "FbTk/Resource.hh" #include "FbTk/Resource.hh"
#include "FbTk/MemFun.hh"
namespace { namespace {
class ToggleFrameFocusCmd: public FbTk::Command<void> { class ToggleFrameFocusCmd: public FbTk::Command<void> {
@ -91,30 +92,41 @@ void AttentionNoticeHandler::addAttention(Focusable &client) {
m_attentions[&client] = timer; m_attentions[&client] = timer;
// attach signals that will make notice go away // attach signals that will make notice go away
client.dieSig().attach(this); client.dieSig().attach(this);
client.focusSig().attach(this);
client.focusSig().connect(MemFun(*this, &AttentionNoticeHandler::windowFocusChanged));
// update _NET_WM_STATE atom // update _NET_WM_STATE atom
if (client.fbwindow()) if (client.fbwindow())
client.fbwindow()->stateSig().notify(); 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 // we need to be able to get the window
if (!subj || typeid(*subj) != typeid(Focusable::FocusSubject)) if (!subj || typeid(*subj) != typeid(Focusable::FocusSubject))
return; 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 // all signals results in destruction of the notice
Focusable::FocusSubject *winsubj = delete m_attentions[&win];
static_cast<Focusable::FocusSubject *>(subj); m_attentions.erase(&win);
delete m_attentions[&winsubj->win()]; win.setAttentionState(false);
m_attentions.erase(&winsubj->win());
winsubj->win().setAttentionState(false);
// update _NET_WM_STATE atom // update _NET_WM_STATE atom if the window is not dead
FluxboxWindow *fbwin = winsubj->win().fbwindow(); FluxboxWindow *fbwin = win.fbwindow();
if (fbwin && winsubj != &winsubj->win().dieSig()) if (fbwin && ! died)
fbwin->stateSig().notify(); fbwin->stateSig().notify();
} }

View file

@ -48,8 +48,16 @@ public:
void update(FbTk::Subject *subj); void update(FbTk::Subject *subj);
bool isDemandingAttention(const Focusable &client); bool isDemandingAttention(const Focusable &client);
/// Called when window focus changes.
void windowFocusChanged(Focusable& win);
/// Remove window from attentionHandler.
void removeWindow(Focusable& win);
private: private:
/// updates the windows state in this instance.
void updateWindow(Focusable& win, bool died);
NoticeMap m_attentions; NoticeMap m_attentions;
}; };

View file

@ -1358,8 +1358,7 @@ void Ewmh::setState(FluxboxWindow &win, Atom state, bool value,
if (value) { // if add attention if (value) { // if add attention
Fluxbox::instance()->attentionHandler().addAttention(client); Fluxbox::instance()->attentionHandler().addAttention(client);
} else { // erase it } else { // erase it
Fluxbox::instance()->attentionHandler(). Fluxbox::instance()->attentionHandler().removeWindow(client);
update(&client.focusSig());
} }
} else if (state == m_net->wm_state_modal) { } else if (state == m_net->wm_state_modal) {
client.setStateModal(value); client.setStateModal(value);

View file

@ -25,6 +25,7 @@
#include "FbTk/PixmapWithMask.hh" #include "FbTk/PixmapWithMask.hh"
#include "FbTk/ITypeAheadable.hh" #include "FbTk/ITypeAheadable.hh"
#include "FbTk/Subject.hh" #include "FbTk/Subject.hh"
#include "FbTk/Signal.hh"
#include <string> #include <string>
@ -41,8 +42,9 @@ public:
m_screen(scr), m_fbwin(fbwin), m_screen(scr), m_fbwin(fbwin),
m_instance_name("fluxbox"), m_class_name("fluxbox"), m_instance_name("fluxbox"), m_class_name("fluxbox"),
m_focused(false), m_attention_state(false), m_focused(false), m_attention_state(false),
m_titlesig(*this), m_focussig(*this), m_diesig(*this), m_titlesig(*this), m_diesig(*this),
m_attentionsig(*this) { } m_attentionsig(*this),
m_focussig() { }
virtual ~Focusable() { } virtual ~Focusable() { }
/** /**
@ -118,14 +120,19 @@ public:
FbTk::Subject &titleSig() { return m_titlesig; } FbTk::Subject &titleSig() { return m_titlesig; }
// Used for both title and icon changes. // Used for both title and icon changes.
const FbTk::Subject &titleSig() const { return m_titlesig; } const FbTk::Subject &titleSig() const { return m_titlesig; }
FbTk::Subject &focusSig() { return m_focussig; } FbTk::Signal<void, Focusable&> &focusSig() { return m_focussig; }
const FbTk::Subject &focusSig() const { return m_focussig; } const FbTk::Signal<void, Focusable&> &focusSig() const { return m_focussig; }
FbTk::Subject &dieSig() { return m_diesig; } FbTk::Subject &dieSig() { return m_diesig; }
const FbTk::Subject &dieSig() const { return m_diesig; } const FbTk::Subject &dieSig() const { return m_diesig; }
FbTk::Subject &attentionSig() { return m_attentionsig; } FbTk::Subject &attentionSig() { return m_attentionsig; }
const FbTk::Subject &attentionSig() const { return m_attentionsig; } const FbTk::Subject &attentionSig() const { return m_attentionsig; }
/** @} */ // end group signals /** @} */ // end group signals
/// Notify any listeners that the focus changed for this window.
void notifyFocusChanged() {
m_focussig.emit(*this);
}
protected: protected:
BScreen &m_screen; //< the screen in which it works BScreen &m_screen; //< the screen in which it works
FluxboxWindow *m_fbwin; //< the working fluxbox window FluxboxWindow *m_fbwin; //< the working fluxbox window
@ -136,7 +143,10 @@ protected:
FbTk::PixmapWithMask m_icon; //< icon pixmap with mask FbTk::PixmapWithMask m_icon; //< icon pixmap with mask
// state and hint signals // 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 #endif // FOCUSABLE_HH

View file

@ -25,6 +25,7 @@
#include "Focusable.hh" #include "Focusable.hh"
#include "FbTk/Observer.hh" #include "FbTk/Observer.hh"
#include "FbTk/Theme.hh" #include "FbTk/Theme.hh"
#include "FbTk/RelaySignal.hh"
template <typename BaseTheme> template <typename BaseTheme>
class FocusableTheme: public FbTk::ThemeProxy<BaseTheme>, class FocusableTheme: public FbTk::ThemeProxy<BaseTheme>,
@ -33,7 +34,9 @@ public:
FocusableTheme(Focusable &win, FbTk::ThemeProxy<BaseTheme> &focused, FocusableTheme(Focusable &win, FbTk::ThemeProxy<BaseTheme> &focused,
FbTk::ThemeProxy<BaseTheme> &unfocused): FbTk::ThemeProxy<BaseTheme> &unfocused):
m_win(win), m_focused_theme(focused), m_unfocused_theme(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_win.attentionSig().attach(this);
m_focused_theme.reconfigSig().attach(this); m_focused_theme.reconfigSig().attach(this);
m_unfocused_theme.reconfigSig().attach(this); m_unfocused_theme.reconfigSig().attach(this);
@ -66,6 +69,7 @@ private:
Focusable &m_win; Focusable &m_win;
FbTk::ThemeProxy<BaseTheme> &m_focused_theme, &m_unfocused_theme; FbTk::ThemeProxy<BaseTheme> &m_focused_theme, &m_unfocused_theme;
FbTk::Subject m_reconfig_sig; FbTk::Subject m_reconfig_sig;
FbTk::SignalTracker m_signals;
}; };
#endif // FOCUSABLETHEME_HH #endif // FOCUSABLETHEME_HH

View file

@ -60,7 +60,8 @@ IconButton::IconButton(const FbTk::FbWindow &parent,
m_pm(win.screen().imageControl()) { m_pm(win.screen().imageControl()) {
m_win.titleSig().attach(this); 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); m_win.attentionSig().attach(this);
FbTk::EventManager::instance()->add(*this, m_icon_window); 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) { void IconButton::update(FbTk::Subject *subj) {
// if the window's focus state changed, we need to update the background // if the window's focus state changed, we need to update the background
if (subj == &m_win.focusSig() || subj == &m_win.attentionSig()) { if (subj == &m_win.attentionSig()) {
reconfigTheme(); reconfigAndClear();
clear();
return; return;
} }

View file

@ -29,6 +29,7 @@
#include "FbTk/FbPixmap.hh" #include "FbTk/FbPixmap.hh"
#include "FbTk/Observer.hh" #include "FbTk/Observer.hh"
#include "FbTk/TextButton.hh" #include "FbTk/TextButton.hh"
#include "FbTk/Signal.hh"
class IconbarTheme; class IconbarTheme;
@ -68,6 +69,7 @@ public:
protected: protected:
void drawText(int x, int y, FbTk::FbDrawable *drawable_override); void drawText(int x, int y, FbTk::FbDrawable *drawable_override);
private: private:
void reconfigAndClear();
void setupWindow(); void setupWindow();
void showTooltip(); void showTooltip();
@ -82,6 +84,7 @@ private:
FocusableTheme<IconbarTheme> m_theme; FocusableTheme<IconbarTheme> m_theme;
// cached pixmaps // cached pixmaps
FbTk::CachedPixmap m_pm; FbTk::CachedPixmap m_pm;
FbTk::SignalTracker m_signals;
}; };
#endif // ICONBUTTON_HH #endif // ICONBUTTON_HH

View file

@ -433,8 +433,7 @@ void WinClient::updateWMHints() {
if (wmhint->flags & XUrgencyHint) { if (wmhint->flags & XUrgencyHint) {
Fluxbox::instance()->attentionHandler().addAttention(*this); Fluxbox::instance()->attentionHandler().addAttention(*this);
} else { } else {
Fluxbox::instance()->attentionHandler(). Fluxbox::instance()->attentionHandler().windowFocusChanged(*this);
update(&m_focussig);
} }
} }

View file

@ -979,9 +979,9 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) {
m_client->raise(); m_client->raise();
if (m_focused) { if (m_focused) {
m_client->focusSig().notify(); m_client->notifyFocusChanged();
if (old) if (old)
old->focusSig().notify(); old->notifyFocusChanged();
} }
fbdbg<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<< fbdbg<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<<
@ -1777,9 +1777,9 @@ void FluxboxWindow::setFocusFlag(bool focus) {
// did focus change? notify listeners // did focus change? notify listeners
if (was_focused != focus) { if (was_focused != focus) {
m_attention_state = false; m_attention_state = false;
m_focussig.notify(); notifyFocusChanged();
if (m_client) if (m_client)
m_client->focusSig().notify(); m_client->notifyFocusChanged();
Fluxbox::instance()->keys()->doAction(focus ? FocusIn : FocusOut, 0, 0, Fluxbox::instance()->keys()->doAction(focus ? FocusIn : FocusOut, 0, 0,
Keys::ON_WINDOW, m_client); Keys::ON_WINDOW, m_client);
} }