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/Timer.hh"
#include "FbTk/Resource.hh"
#include "FbTk/MemFun.hh"
namespace {
class ToggleFrameFocusCmd: public FbTk::Command<void> {
@ -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<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();
}

View file

@ -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;
};

View file

@ -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);

View file

@ -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 @@ 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<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 @@ 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<void, Focusable&> m_focussig;
};
#endif // FOCUSABLE_HH

View file

@ -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 @@ private:
Focusable &m_win;
FbTk::ThemeProxy<BaseTheme> &m_focused_theme, &m_unfocused_theme;
FbTk::Subject m_reconfig_sig;
FbTk::SignalTracker m_signals;
};
#endif // FOCUSABLETHEME_HH

View file

@ -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;
}

View file

@ -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<IconbarTheme> m_theme;
// cached pixmaps
FbTk::CachedPixmap m_pm;
FbTk::SignalTracker m_signals;
};
#endif // ICONBUTTON_HH

View file

@ -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);
}
}

View file

@ -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);
}