summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/AttentionNoticeHandler.cc32
-rw-r--r--src/AttentionNoticeHandler.hh10
-rw-r--r--src/Ewmh.cc3
-rw-r--r--src/Focusable.hh20
-rw-r--r--src/FocusableTheme.hh6
-rw-r--r--src/IconButton.cc13
-rw-r--r--src/IconButton.hh3
-rw-r--r--src/WinClient.cc3
-rw-r--r--src/Window.cc8
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 @@
28#include "FbTk/Subject.hh" 28#include "FbTk/Subject.hh"
29#include "FbTk/Timer.hh" 29#include "FbTk/Timer.hh"
30#include "FbTk/Resource.hh" 30#include "FbTk/Resource.hh"
31#include "FbTk/MemFun.hh"
31 32
32namespace { 33namespace {
33class ToggleFrameFocusCmd: public FbTk::Command<void> { 34class ToggleFrameFocusCmd: public FbTk::Command<void> {
@@ -91,30 +92,41 @@ void AttentionNoticeHandler::addAttention(Focusable &client) {
91 m_attentions[&client] = timer; 92 m_attentions[&client] = timer;
92 // attach signals that will make notice go away 93 // attach signals that will make notice go away
93 client.dieSig().attach(this); 94 client.dieSig().attach(this);
94 client.focusSig().attach(this); 95
96 client.focusSig().connect(MemFun(*this, &AttentionNoticeHandler::windowFocusChanged));
95 97
96 // update _NET_WM_STATE atom 98 // update _NET_WM_STATE atom
97 if (client.fbwindow()) 99 if (client.fbwindow())
98 client.fbwindow()->stateSig().notify(); 100 client.fbwindow()->stateSig().notify();
99} 101}
100 102
101void AttentionNoticeHandler::update(FbTk::Subject *subj) { 103void AttentionNoticeHandler::windowFocusChanged(Focusable& win) {
104 updateWindow(win, false);
105}
106void AttentionNoticeHandler::removeWindow(Focusable& win) {
107 updateWindow(win, true);
108}
102 109
110void AttentionNoticeHandler::update(FbTk::Subject* subj) {
103 // we need to be able to get the window 111 // we need to be able to get the window
104 if (!subj || typeid(*subj) != typeid(Focusable::FocusSubject)) 112 if (!subj || typeid(*subj) != typeid(Focusable::FocusSubject))
105 return; 113 return;
114 Focusable::FocusSubject *winsubj =
115 static_cast<Focusable::FocusSubject *>(subj);
106 116
117 removeWindow(winsubj->win());
118}
119
120void AttentionNoticeHandler::updateWindow(Focusable& win, bool died) {
107 // all signals results in destruction of the notice 121 // all signals results in destruction of the notice
108 122
109 Focusable::FocusSubject *winsubj = 123 delete m_attentions[&win];
110 static_cast<Focusable::FocusSubject *>(subj); 124 m_attentions.erase(&win);
111 delete m_attentions[&winsubj->win()]; 125 win.setAttentionState(false);
112 m_attentions.erase(&winsubj->win());
113 winsubj->win().setAttentionState(false);
114 126
115 // update _NET_WM_STATE atom 127 // update _NET_WM_STATE atom if the window is not dead
116 FluxboxWindow *fbwin = winsubj->win().fbwindow(); 128 FluxboxWindow *fbwin = win.fbwindow();
117 if (fbwin && winsubj != &winsubj->win().dieSig()) 129 if (fbwin && ! died)
118 fbwin->stateSig().notify(); 130 fbwin->stateSig().notify();
119 131
120} 132}
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:
48 void update(FbTk::Subject *subj); 48 void update(FbTk::Subject *subj);
49 49
50 bool isDemandingAttention(const Focusable &client); 50 bool isDemandingAttention(const Focusable &client);
51 51
52 /// Called when window focus changes.
53 void windowFocusChanged(Focusable& win);
54 /// Remove window from attentionHandler.
55 void removeWindow(Focusable& win);
56
52private: 57private:
58 /// updates the windows state in this instance.
59 void updateWindow(Focusable& win, bool died);
60
53 NoticeMap m_attentions; 61 NoticeMap m_attentions;
54}; 62};
55 63
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,
1358 if (value) { // if add attention 1358 if (value) { // if add attention
1359 Fluxbox::instance()->attentionHandler().addAttention(client); 1359 Fluxbox::instance()->attentionHandler().addAttention(client);
1360 } else { // erase it 1360 } else { // erase it
1361 Fluxbox::instance()->attentionHandler(). 1361 Fluxbox::instance()->attentionHandler().removeWindow(client);
1362 update(&client.focusSig());
1363 } 1362 }
1364 } else if (state == m_net->wm_state_modal) { 1363 } else if (state == m_net->wm_state_modal) {
1365 client.setStateModal(value); 1364 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 @@
25#include "FbTk/PixmapWithMask.hh" 25#include "FbTk/PixmapWithMask.hh"
26#include "FbTk/ITypeAheadable.hh" 26#include "FbTk/ITypeAheadable.hh"
27#include "FbTk/Subject.hh" 27#include "FbTk/Subject.hh"
28#include "FbTk/Signal.hh"
28 29
29#include <string> 30#include <string>
30 31
@@ -41,8 +42,9 @@ public:
41 m_screen(scr), m_fbwin(fbwin), 42 m_screen(scr), m_fbwin(fbwin),
42 m_instance_name("fluxbox"), m_class_name("fluxbox"), 43 m_instance_name("fluxbox"), m_class_name("fluxbox"),
43 m_focused(false), m_attention_state(false), 44 m_focused(false), m_attention_state(false),
44 m_titlesig(*this), m_focussig(*this), m_diesig(*this), 45 m_titlesig(*this), m_diesig(*this),
45 m_attentionsig(*this) { } 46 m_attentionsig(*this),
47 m_focussig() { }
46 virtual ~Focusable() { } 48 virtual ~Focusable() { }
47 49
48 /** 50 /**
@@ -118,14 +120,19 @@ public:
118 FbTk::Subject &titleSig() { return m_titlesig; } 120 FbTk::Subject &titleSig() { return m_titlesig; }
119 // Used for both title and icon changes. 121 // Used for both title and icon changes.
120 const FbTk::Subject &titleSig() const { return m_titlesig; } 122 const FbTk::Subject &titleSig() const { return m_titlesig; }
121 FbTk::Subject &focusSig() { return m_focussig; } 123 FbTk::Signal<void, Focusable&> &focusSig() { return m_focussig; }
122 const FbTk::Subject &focusSig() const { return m_focussig; } 124 const FbTk::Signal<void, Focusable&> &focusSig() const { return m_focussig; }
123 FbTk::Subject &dieSig() { return m_diesig; } 125 FbTk::Subject &dieSig() { return m_diesig; }
124 const FbTk::Subject &dieSig() const { return m_diesig; } 126 const FbTk::Subject &dieSig() const { return m_diesig; }
125 FbTk::Subject &attentionSig() { return m_attentionsig; } 127 FbTk::Subject &attentionSig() { return m_attentionsig; }
126 const FbTk::Subject &attentionSig() const { return m_attentionsig; } 128 const FbTk::Subject &attentionSig() const { return m_attentionsig; }
127 /** @} */ // end group signals 129 /** @} */ // end group signals
128 130
131 /// Notify any listeners that the focus changed for this window.
132 void notifyFocusChanged() {
133 m_focussig.emit(*this);
134 }
135
129protected: 136protected:
130 BScreen &m_screen; //< the screen in which it works 137 BScreen &m_screen; //< the screen in which it works
131 FluxboxWindow *m_fbwin; //< the working fluxbox window 138 FluxboxWindow *m_fbwin; //< the working fluxbox window
@@ -136,7 +143,10 @@ protected:
136 FbTk::PixmapWithMask m_icon; //< icon pixmap with mask 143 FbTk::PixmapWithMask m_icon; //< icon pixmap with mask
137 144
138 // state and hint signals 145 // state and hint signals
139 FocusSubject m_titlesig, m_focussig, m_diesig, m_attentionsig; 146 FocusSubject m_titlesig, m_diesig, m_attentionsig;
147
148private:
149 FbTk::Signal<void, Focusable&> m_focussig;
140}; 150};
141 151
142#endif // FOCUSABLE_HH 152#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 @@
25#include "Focusable.hh" 25#include "Focusable.hh"
26#include "FbTk/Observer.hh" 26#include "FbTk/Observer.hh"
27#include "FbTk/Theme.hh" 27#include "FbTk/Theme.hh"
28#include "FbTk/RelaySignal.hh"
28 29
29template <typename BaseTheme> 30template <typename BaseTheme>
30class FocusableTheme: public FbTk::ThemeProxy<BaseTheme>, 31class FocusableTheme: public FbTk::ThemeProxy<BaseTheme>,
@@ -33,7 +34,9 @@ public:
33 FocusableTheme(Focusable &win, FbTk::ThemeProxy<BaseTheme> &focused, 34 FocusableTheme(Focusable &win, FbTk::ThemeProxy<BaseTheme> &focused,
34 FbTk::ThemeProxy<BaseTheme> &unfocused): 35 FbTk::ThemeProxy<BaseTheme> &unfocused):
35 m_win(win), m_focused_theme(focused), m_unfocused_theme(unfocused) { 36 m_win(win), m_focused_theme(focused), m_unfocused_theme(unfocused) {
36 m_win.focusSig().attach(this); 37 // relay focus signal to reconfig signal
38 FbTk::relaySignal(m_signals, m_win.focusSig(), m_reconfig_sig);
39
37 m_win.attentionSig().attach(this); 40 m_win.attentionSig().attach(this);
38 m_focused_theme.reconfigSig().attach(this); 41 m_focused_theme.reconfigSig().attach(this);
39 m_unfocused_theme.reconfigSig().attach(this); 42 m_unfocused_theme.reconfigSig().attach(this);
@@ -66,6 +69,7 @@ private:
66 Focusable &m_win; 69 Focusable &m_win;
67 FbTk::ThemeProxy<BaseTheme> &m_focused_theme, &m_unfocused_theme; 70 FbTk::ThemeProxy<BaseTheme> &m_focused_theme, &m_unfocused_theme;
68 FbTk::Subject m_reconfig_sig; 71 FbTk::Subject m_reconfig_sig;
72 FbTk::SignalTracker m_signals;
69}; 73};
70 74
71#endif // FOCUSABLETHEME_HH 75#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,
60 m_pm(win.screen().imageControl()) { 60 m_pm(win.screen().imageControl()) {
61 61
62 m_win.titleSig().attach(this); 62 m_win.titleSig().attach(this);
63 m_win.focusSig().attach(this); 63 m_signals.join(m_win.focusSig(),
64 MemFunIgnoreArgs(*this, &IconButton::reconfigAndClear));
64 m_win.attentionSig().attach(this); 65 m_win.attentionSig().attach(this);
65 66
66 FbTk::EventManager::instance()->add(*this, m_icon_window); 67 FbTk::EventManager::instance()->add(*this, m_icon_window);
@@ -169,11 +170,15 @@ void IconButton::reconfigTheme() {
169 170
170} 171}
171 172
173void IconButton::reconfigAndClear() {
174 reconfigTheme();
175 clear();
176}
177
172void IconButton::update(FbTk::Subject *subj) { 178void IconButton::update(FbTk::Subject *subj) {
173 // if the window's focus state changed, we need to update the background 179 // if the window's focus state changed, we need to update the background
174 if (subj == &m_win.focusSig() || subj == &m_win.attentionSig()) { 180 if (subj == &m_win.attentionSig()) {
175 reconfigTheme(); 181 reconfigAndClear();
176 clear();
177 return; 182 return;
178 } 183 }
179 184
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 @@
29#include "FbTk/FbPixmap.hh" 29#include "FbTk/FbPixmap.hh"
30#include "FbTk/Observer.hh" 30#include "FbTk/Observer.hh"
31#include "FbTk/TextButton.hh" 31#include "FbTk/TextButton.hh"
32#include "FbTk/Signal.hh"
32 33
33class IconbarTheme; 34class IconbarTheme;
34 35
@@ -68,6 +69,7 @@ public:
68protected: 69protected:
69 void drawText(int x, int y, FbTk::FbDrawable *drawable_override); 70 void drawText(int x, int y, FbTk::FbDrawable *drawable_override);
70private: 71private:
72 void reconfigAndClear();
71 void setupWindow(); 73 void setupWindow();
72 void showTooltip(); 74 void showTooltip();
73 75
@@ -82,6 +84,7 @@ private:
82 FocusableTheme<IconbarTheme> m_theme; 84 FocusableTheme<IconbarTheme> m_theme;
83 // cached pixmaps 85 // cached pixmaps
84 FbTk::CachedPixmap m_pm; 86 FbTk::CachedPixmap m_pm;
87 FbTk::SignalTracker m_signals;
85}; 88};
86 89
87#endif // ICONBUTTON_HH 90#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() {
433 if (wmhint->flags & XUrgencyHint) { 433 if (wmhint->flags & XUrgencyHint) {
434 Fluxbox::instance()->attentionHandler().addAttention(*this); 434 Fluxbox::instance()->attentionHandler().addAttention(*this);
435 } else { 435 } else {
436 Fluxbox::instance()->attentionHandler(). 436 Fluxbox::instance()->attentionHandler().windowFocusChanged(*this);
437 update(&m_focussig);
438 } 437 }
439 } 438 }
440 439
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) {
979 979
980 m_client->raise(); 980 m_client->raise();
981 if (m_focused) { 981 if (m_focused) {
982 m_client->focusSig().notify(); 982 m_client->notifyFocusChanged();
983 if (old) 983 if (old)
984 old->focusSig().notify(); 984 old->notifyFocusChanged();
985 } 985 }
986 986
987 fbdbg<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<< 987 fbdbg<<"FluxboxWindow::"<<__FUNCTION__<<": labelbutton[client] = "<<
@@ -1777,9 +1777,9 @@ void FluxboxWindow::setFocusFlag(bool focus) {
1777 // did focus change? notify listeners 1777 // did focus change? notify listeners
1778 if (was_focused != focus) { 1778 if (was_focused != focus) {
1779 m_attention_state = false; 1779 m_attention_state = false;
1780 m_focussig.notify(); 1780 notifyFocusChanged();
1781 if (m_client) 1781 if (m_client)
1782 m_client->focusSig().notify(); 1782 m_client->notifyFocusChanged();
1783 Fluxbox::instance()->keys()->doAction(focus ? FocusIn : FocusOut, 0, 0, 1783 Fluxbox::instance()->keys()->doAction(focus ? FocusIn : FocusOut, 0, 0,
1784 Keys::ON_WINDOW, m_client); 1784 Keys::ON_WINDOW, m_client);
1785 } 1785 }