Changed Focusable::focusSig() to new signal system.
The focus signal emits the window that had the focus status changed.
This commit is contained in:
parent
02bb93590c
commit
6ed8369d57
9 changed files with 69 additions and 29 deletions
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue