diff options
-rw-r--r-- | src/AttentionNoticeHandler.cc | 32 | ||||
-rw-r--r-- | src/AttentionNoticeHandler.hh | 10 | ||||
-rw-r--r-- | src/Ewmh.cc | 3 | ||||
-rw-r--r-- | src/Focusable.hh | 20 | ||||
-rw-r--r-- | src/FocusableTheme.hh | 6 | ||||
-rw-r--r-- | src/IconButton.cc | 13 | ||||
-rw-r--r-- | src/IconButton.hh | 3 | ||||
-rw-r--r-- | src/WinClient.cc | 3 | ||||
-rw-r--r-- | 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 @@ | |||
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 | ||
32 | namespace { | 33 | namespace { |
33 | class ToggleFrameFocusCmd: public FbTk::Command<void> { | 34 | class 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 | ||
101 | void AttentionNoticeHandler::update(FbTk::Subject *subj) { | 103 | void AttentionNoticeHandler::windowFocusChanged(Focusable& win) { |
104 | updateWindow(win, false); | ||
105 | } | ||
106 | void AttentionNoticeHandler::removeWindow(Focusable& win) { | ||
107 | updateWindow(win, true); | ||
108 | } | ||
102 | 109 | ||
110 | void 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 | |||
120 | void 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 | |||
52 | private: | 57 | private: |
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 | |||
129 | protected: | 136 | protected: |
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 | |||
148 | private: | ||
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 | ||
29 | template <typename BaseTheme> | 30 | template <typename BaseTheme> |
30 | class FocusableTheme: public FbTk::ThemeProxy<BaseTheme>, | 31 | class 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 | ||
173 | void IconButton::reconfigAndClear() { | ||
174 | reconfigTheme(); | ||
175 | clear(); | ||
176 | } | ||
177 | |||
172 | void IconButton::update(FbTk::Subject *subj) { | 178 | void 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 | ||
33 | class IconbarTheme; | 34 | class IconbarTheme; |
34 | 35 | ||
@@ -68,6 +69,7 @@ public: | |||
68 | protected: | 69 | protected: |
69 | void drawText(int x, int y, FbTk::FbDrawable *drawable_override); | 70 | void drawText(int x, int y, FbTk::FbDrawable *drawable_override); |
70 | private: | 71 | private: |
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 | } |