diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | src/AttentionNoticeHandler.cc | 46 | ||||
-rw-r--r-- | src/AttentionNoticeHandler.hh | 12 | ||||
-rw-r--r-- | src/Ewmh.cc | 4 | ||||
-rw-r--r-- | src/FbWinFrame.cc | 12 | ||||
-rw-r--r-- | src/FbWinFrame.hh | 2 | ||||
-rw-r--r-- | src/IconbarTool.cc | 2 | ||||
-rw-r--r-- | src/WinClient.cc | 7 | ||||
-rw-r--r-- | src/WinClient.hh | 3 | ||||
-rw-r--r-- | src/Window.cc | 19 | ||||
-rw-r--r-- | src/Window.hh | 4 |
11 files changed, 79 insertions, 35 deletions
@@ -1,6 +1,9 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 1.0rc2: | 2 | Changes for 1.0rc2: |
3 | *06/06/24: | 3 | *06/06/24: |
4 | * Make Urgency Hint flash the correct tab in a group (Mark) | ||
5 | Ewmh.cc Window.cc/hh WinClient.cc/hh FbWinFrame.cc/hh IconbarTool.cc | ||
6 | AttentionNoticeHandler.cc/hh | ||
4 | * Fix some more X-errors (Simon) | 7 | * Fix some more X-errors (Simon) |
5 | - window was resized, triggering background re-render, but | 8 | - window was resized, triggering background re-render, but |
6 | background is invalid sometimes (during reconfiguring) | 9 | background is invalid sometimes (during reconfiguring) |
diff --git a/src/AttentionNoticeHandler.cc b/src/AttentionNoticeHandler.cc index 7cc2760..e2881af 100644 --- a/src/AttentionNoticeHandler.cc +++ b/src/AttentionNoticeHandler.cc | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | #include "AttentionNoticeHandler.hh" | 24 | #include "AttentionNoticeHandler.hh" |
25 | 25 | ||
26 | #include "Window.hh" | 26 | #include "WinClient.hh" |
27 | #include "Screen.hh" | 27 | #include "Screen.hh" |
28 | #include "STLUtil.hh" | 28 | #include "STLUtil.hh" |
29 | 29 | ||
@@ -34,14 +34,16 @@ | |||
34 | namespace { | 34 | namespace { |
35 | class ToggleFrameFocusCmd: public FbTk::Command { | 35 | class ToggleFrameFocusCmd: public FbTk::Command { |
36 | public: | 36 | public: |
37 | ToggleFrameFocusCmd(FluxboxWindow &win): | 37 | ToggleFrameFocusCmd(WinClient &client): |
38 | m_win(win) {} | 38 | m_client(client) {} |
39 | void execute() { | 39 | void execute() { |
40 | m_win.frame().setFocus( ! m_win.frame().focused() ); | 40 | m_state ^= true; |
41 | m_win.attentionSig().notify(); | 41 | m_client.fbwindow()->setLabelButtonFocus(m_client, m_state); |
42 | m_client.fbwindow()->setAttentionState(m_state); | ||
42 | } | 43 | } |
43 | private: | 44 | private: |
44 | FluxboxWindow& m_win; | 45 | WinClient& m_client; |
46 | bool m_state; | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | } // end anonymous namespace | 49 | } // end anonymous namespace |
@@ -51,27 +53,27 @@ AttentionNoticeHandler::~AttentionNoticeHandler() { | |||
51 | STLUtil::destroyAndClearSecond(m_attentions); | 53 | STLUtil::destroyAndClearSecond(m_attentions); |
52 | } | 54 | } |
53 | 55 | ||
54 | void AttentionNoticeHandler::addAttention(FluxboxWindow &win) { | 56 | void AttentionNoticeHandler::addAttention(WinClient &client) { |
55 | // no need to add already focused window | 57 | // no need to add already active client |
56 | if (win.isFocused()) | 58 | if (client.fbwindow()->isFocused() && &client.fbwindow()->winClient() == &client) |
57 | return; | 59 | return; |
58 | 60 | ||
59 | // Already have a notice for it? | 61 | // Already have a notice for it? |
60 | NoticeMap::iterator it = m_attentions.find(&win); | 62 | NoticeMap::iterator it = m_attentions.find(&client); |
61 | if (it != m_attentions.end()) { | 63 | if (it != m_attentions.end()) { |
62 | return; | 64 | return; |
63 | } | 65 | } |
64 | 66 | ||
65 | using namespace FbTk; | 67 | using namespace FbTk; |
66 | 68 | ||
67 | ResourceManager &res = win.screen().resourceManager(); | 69 | ResourceManager &res = client.screen().resourceManager(); |
68 | std::string res_name = win.screen().name() + ".demandsAttentionTimeout"; | 70 | std::string res_name = client.screen().name() + ".demandsAttentionTimeout"; |
69 | std::string res_alt_name = win.screen().name() + ".DemandsAttentionTimeout"; | 71 | std::string res_alt_name = client.screen().name() + ".DemandsAttentionTimeout"; |
70 | Resource<int> *timeout_res = dynamic_cast<Resource<int>* >(res.findResource(res_name)); | 72 | Resource<int> *timeout_res = dynamic_cast<Resource<int>* >(res.findResource(res_name)); |
71 | if (timeout_res == 0) { | 73 | if (timeout_res == 0) { |
72 | // no resource, create one and add it to managed resources | 74 | // no resource, create one and add it to managed resources |
73 | timeout_res = new FbTk::Resource<int>(res, 500, res_name, res_alt_name); | 75 | timeout_res = new FbTk::Resource<int>(res, 500, res_name, res_alt_name); |
74 | win.screen().addManagedResource(timeout_res); | 76 | client.screen().addManagedResource(timeout_res); |
75 | } | 77 | } |
76 | // disable if timeout is zero | 78 | // disable if timeout is zero |
77 | if (**timeout_res == 0) | 79 | if (**timeout_res == 0) |
@@ -82,25 +84,25 @@ void AttentionNoticeHandler::addAttention(FluxboxWindow &win) { | |||
82 | timeval timeout; | 84 | timeval timeout; |
83 | timeout.tv_sec = 0; | 85 | timeout.tv_sec = 0; |
84 | timeout.tv_usec = **timeout_res * 1000; | 86 | timeout.tv_usec = **timeout_res * 1000; |
85 | RefCount<Command> cmd(new ToggleFrameFocusCmd(win)); | 87 | RefCount<Command> cmd(new ToggleFrameFocusCmd(client)); |
86 | timer->setCommand(cmd); | 88 | timer->setCommand(cmd); |
87 | timer->setTimeout(timeout); | 89 | timer->setTimeout(timeout); |
88 | timer->fireOnce(false); // will repeat until window has focus | 90 | timer->fireOnce(false); // will repeat until window has focus |
89 | timer->start(); | 91 | timer->start(); |
90 | 92 | ||
91 | m_attentions[&win] = timer; | 93 | m_attentions[&client] = timer; |
92 | // attach signals that will make notice go away | 94 | // attach signals that will make notice go away |
93 | win.dieSig().attach(this); | 95 | client.dieSig().attach(this); |
94 | win.focusSig().attach(this); | 96 | client.focusSig().attach(this); |
95 | } | 97 | } |
96 | 98 | ||
97 | void AttentionNoticeHandler::update(FbTk::Subject *subj) { | 99 | void AttentionNoticeHandler::update(FbTk::Subject *subj) { |
98 | 100 | ||
99 | // all signals results in destruction of the notice | 101 | // all signals results in destruction of the notice |
100 | 102 | ||
101 | FluxboxWindow::WinSubject *winsubj = | 103 | WinClient::WinClientSubj *winsubj = |
102 | static_cast<FluxboxWindow::WinSubject*>(subj); | 104 | static_cast<WinClient::WinClientSubj *>(subj); |
103 | delete m_attentions[&winsubj->win()]; | 105 | delete m_attentions[&winsubj->winClient()]; |
104 | m_attentions.erase(&winsubj->win()); | 106 | m_attentions.erase(&winsubj->winClient()); |
105 | } | 107 | } |
106 | 108 | ||
diff --git a/src/AttentionNoticeHandler.hh b/src/AttentionNoticeHandler.hh index aa2f9f2..836a023 100644 --- a/src/AttentionNoticeHandler.hh +++ b/src/AttentionNoticeHandler.hh | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | #include <map> | 28 | #include <map> |
29 | 29 | ||
30 | class FluxboxWindow; | 30 | class WinClient; |
31 | 31 | ||
32 | namespace FbTk { | 32 | namespace FbTk { |
33 | class Timer; | 33 | class Timer; |
@@ -41,11 +41,11 @@ class AttentionNoticeHandler: public FbTk::Observer { | |||
41 | public: | 41 | public: |
42 | ~AttentionNoticeHandler(); | 42 | ~AttentionNoticeHandler(); |
43 | 43 | ||
44 | typedef std::map<FluxboxWindow*, FbTk::Timer*> NoticeMap; | 44 | typedef std::map<WinClient*, FbTk::Timer*> NoticeMap; |
45 | /// Adds a window that requires attention, | 45 | /// Adds a client that requires attention, |
46 | /// will fail if the window is already focused | 46 | /// will fail if the client is already active |
47 | void addAttention(FluxboxWindow &win); | 47 | void addAttention(WinClient &client); |
48 | /// removes the window from the attention map | 48 | /// removes the client from the attention map |
49 | void update(FbTk::Subject *subj); | 49 | void update(FbTk::Subject *subj); |
50 | 50 | ||
51 | private: | 51 | private: |
diff --git a/src/Ewmh.cc b/src/Ewmh.cc index d74092a..15caab0 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc | |||
@@ -1084,10 +1084,10 @@ void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) { | |||
1084 | win.moveToLayer(Layer::NORMAL); | 1084 | win.moveToLayer(Layer::NORMAL); |
1085 | } else if (state == m_net_wm_state_demands_attention) { | 1085 | } else if (state == m_net_wm_state_demands_attention) { |
1086 | if (value) { // if add attention | 1086 | if (value) { // if add attention |
1087 | Fluxbox::instance()->attentionHandler().addAttention(win); | 1087 | Fluxbox::instance()->attentionHandler().addAttention(win.winClient()); |
1088 | } else { // erase it | 1088 | } else { // erase it |
1089 | Fluxbox::instance()->attentionHandler(). | 1089 | Fluxbox::instance()->attentionHandler(). |
1090 | update(&win.attentionSig()); | 1090 | update(&win.winClient().focusSig()); |
1091 | } | 1091 | } |
1092 | } | 1092 | } |
1093 | 1093 | ||
diff --git a/src/FbWinFrame.cc b/src/FbWinFrame.cc index 9df9012..9e7eedf 100644 --- a/src/FbWinFrame.cc +++ b/src/FbWinFrame.cc | |||
@@ -650,6 +650,18 @@ void FbWinFrame::setLabelButtonFocus(FbTk::TextButton &btn) { | |||
650 | applyActiveLabel(*m_current_label); | 650 | applyActiveLabel(*m_current_label); |
651 | } | 651 | } |
652 | 652 | ||
653 | void FbWinFrame::setLabelButtonFocus(FbTk::TextButton &btn, bool value) { | ||
654 | if (btn.parent() != &m_tab_container) | ||
655 | return; | ||
656 | |||
657 | if (value) | ||
658 | applyFocusLabel(btn); | ||
659 | else | ||
660 | applyUnfocusLabel(btn); | ||
661 | |||
662 | btn.clear(); | ||
663 | } | ||
664 | |||
653 | void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { | 665 | void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { |
654 | 666 | ||
655 | win.setBorderWidth(0); | 667 | win.setBorderWidth(0); |
diff --git a/src/FbWinFrame.hh b/src/FbWinFrame.hh index e8003d3..6858579 100644 --- a/src/FbWinFrame.hh +++ b/src/FbWinFrame.hh | |||
@@ -150,6 +150,8 @@ public: | |||
150 | void moveLabelButtonRightOf(FbTk::TextButton &btn, const FbTk::TextButton &dest); | 150 | void moveLabelButtonRightOf(FbTk::TextButton &btn, const FbTk::TextButton &dest); |
151 | /// which button is to be rendered focused | 151 | /// which button is to be rendered focused |
152 | void setLabelButtonFocus(FbTk::TextButton &btn); | 152 | void setLabelButtonFocus(FbTk::TextButton &btn); |
153 | /// specify focus state of button | ||
154 | void setLabelButtonFocus(FbTk::TextButton &btn, bool value); | ||
153 | /// attach a client window for client area | 155 | /// attach a client window for client area |
154 | void setClientWindow(FbTk::FbWindow &win); | 156 | void setClientWindow(FbTk::FbWindow &win); |
155 | /// remove attached client window | 157 | /// remove attached client window |
diff --git a/src/IconbarTool.cc b/src/IconbarTool.cc index 4dc6d24..73817f1 100644 --- a/src/IconbarTool.cc +++ b/src/IconbarTool.cc | |||
@@ -601,7 +601,7 @@ void IconbarTool::update(FbTk::Subject *subj) { | |||
601 | IconButton *button = findButton(winsubj->win()); | 601 | IconButton *button = findButton(winsubj->win()); |
602 | if (button) { | 602 | if (button) { |
603 | renderButton(*button, true, | 603 | renderButton(*button, true, |
604 | winsubj->win().frame().focused() ? 1 : 0); | 604 | winsubj->win().getAttentionState()); |
605 | } | 605 | } |
606 | return; | 606 | return; |
607 | } else { | 607 | } else { |
diff --git a/src/WinClient.cc b/src/WinClient.cc index acb8250..1ede4d8 100644 --- a/src/WinClient.cc +++ b/src/WinClient.cc | |||
@@ -74,7 +74,8 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb | |||
74 | m_blackbox_hint(0), | 74 | m_blackbox_hint(0), |
75 | m_mwm_hint(0), | 75 | m_mwm_hint(0), |
76 | m_focus_mode(F_PASSIVE), | 76 | m_focus_mode(F_PASSIVE), |
77 | m_diesig(*this), m_screen(screen), | 77 | m_diesig(*this), m_focussig(*this), |
78 | m_screen(screen), | ||
78 | m_strut(0) { | 79 | m_strut(0) { |
79 | updateWMProtocols(); | 80 | updateWMProtocols(); |
80 | updateBlackboxHints(); | 81 | updateBlackboxHints(); |
@@ -516,10 +517,10 @@ void WinClient::updateWMHints() { | |||
516 | 517 | ||
517 | if (m_win && m_win->isInitialized()) { | 518 | if (m_win && m_win->isInitialized()) { |
518 | if (wmhint->flags & XUrgencyHint) { | 519 | if (wmhint->flags & XUrgencyHint) { |
519 | Fluxbox::instance()->attentionHandler().addAttention(*m_win); | 520 | Fluxbox::instance()->attentionHandler().addAttention(*this); |
520 | } else { | 521 | } else { |
521 | Fluxbox::instance()->attentionHandler(). | 522 | Fluxbox::instance()->attentionHandler(). |
522 | update(&(m_win->attentionSig())); | 523 | update(&m_focussig); |
523 | } | 524 | } |
524 | } | 525 | } |
525 | 526 | ||
diff --git a/src/WinClient.hh b/src/WinClient.hh index 870de6a..3a9d792 100644 --- a/src/WinClient.hh +++ b/src/WinClient.hh | |||
@@ -117,6 +117,8 @@ public: | |||
117 | const BScreen &screen() const { return m_screen; } | 117 | const BScreen &screen() const { return m_screen; } |
118 | /// notifies when this client dies | 118 | /// notifies when this client dies |
119 | FbTk::Subject &dieSig() { return m_diesig; } | 119 | FbTk::Subject &dieSig() { return m_diesig; } |
120 | /// notifies when this client becomes focused | ||
121 | FbTk::Subject &focusSig() { return m_focussig; } | ||
120 | 122 | ||
121 | inline WinClient *transientFor() { return transient_for; } | 123 | inline WinClient *transientFor() { return transient_for; } |
122 | inline const WinClient *transientFor() const { return transient_for; } | 124 | inline const WinClient *transientFor() const { return transient_for; } |
@@ -211,6 +213,7 @@ private: | |||
211 | int m_focus_mode; | 213 | int m_focus_mode; |
212 | 214 | ||
213 | WinClientSubj m_diesig; | 215 | WinClientSubj m_diesig; |
216 | WinClientSubj m_focussig; | ||
214 | BScreen &m_screen; | 217 | BScreen &m_screen; |
215 | 218 | ||
216 | Strut *m_strut; | 219 | Strut *m_strut; |
diff --git a/src/Window.cc b/src/Window.cc index 1ad789d..145dc8e 100644 --- a/src/Window.cc +++ b/src/Window.cc | |||
@@ -1065,6 +1065,7 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { | |||
1065 | 1065 | ||
1066 | m_client = &client; | 1066 | m_client = &client; |
1067 | m_client->raise(); | 1067 | m_client->raise(); |
1068 | m_client->focusSig().notify(); | ||
1068 | titleSig().notify(); | 1069 | titleSig().notify(); |
1069 | 1070 | ||
1070 | #ifdef DEBUG | 1071 | #ifdef DEBUG |
@@ -1081,6 +1082,19 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { | |||
1081 | return false; | 1082 | return false; |
1082 | } | 1083 | } |
1083 | 1084 | ||
1085 | void FluxboxWindow::setLabelButtonFocus(WinClient &client, bool value) { | ||
1086 | // make sure it's in our list | ||
1087 | if (client.fbwindow() != this) | ||
1088 | return; | ||
1089 | |||
1090 | frame().setLabelButtonFocus(*m_labelbuttons[&client], value); | ||
1091 | } | ||
1092 | |||
1093 | void FluxboxWindow::setAttentionState(bool value) { | ||
1094 | m_attention_state = value; | ||
1095 | m_attentionsig.notify(); | ||
1096 | } | ||
1097 | |||
1084 | bool FluxboxWindow::isGroupable() const { | 1098 | bool FluxboxWindow::isGroupable() const { |
1085 | if (isResizable() && isMaximizable() && !winClient().isTransient()) | 1099 | if (isResizable() && isMaximizable() && !winClient().isTransient()) |
1086 | return true; | 1100 | return true; |
@@ -2095,8 +2109,11 @@ void FluxboxWindow::setFocusFlag(bool focus) { | |||
2095 | } | 2109 | } |
2096 | 2110 | ||
2097 | // did focus change? notify listeners | 2111 | // did focus change? notify listeners |
2098 | if (was_focused != focus) | 2112 | if (was_focused != focus) { |
2099 | m_focussig.notify(); | 2113 | m_focussig.notify(); |
2114 | if (m_client) | ||
2115 | m_client->focusSig().notify(); | ||
2116 | } | ||
2100 | } | 2117 | } |
2101 | 2118 | ||
2102 | 2119 | ||
diff --git a/src/Window.hh b/src/Window.hh index 27e8138..2b4ef92 100644 --- a/src/Window.hh +++ b/src/Window.hh | |||
@@ -178,6 +178,9 @@ public: | |||
178 | bool removeClient(WinClient &client); | 178 | bool removeClient(WinClient &client); |
179 | /// set new current client and raise it | 179 | /// set new current client and raise it |
180 | bool setCurrentClient(WinClient &client, bool setinput = true); | 180 | bool setCurrentClient(WinClient &client, bool setinput = true); |
181 | void setLabelButtonFocus(WinClient &client, bool value = true); | ||
182 | void setAttentionState(bool value); | ||
183 | bool getAttentionState() { return m_attention_state; } | ||
181 | WinClient *findClient(Window win); | 184 | WinClient *findClient(Window win); |
182 | void nextClient(); | 185 | void nextClient(); |
183 | void prevClient(); | 186 | void prevClient(); |
@@ -500,6 +503,7 @@ private: | |||
500 | 503 | ||
501 | WinClient *m_attaching_tab; | 504 | WinClient *m_attaching_tab; |
502 | 505 | ||
506 | bool m_attention_state; | ||
503 | BScreen &m_screen; /// screen on which this window exist | 507 | BScreen &m_screen; /// screen on which this window exist |
504 | FbTk::Timer m_timer; | 508 | FbTk::Timer m_timer; |
505 | Display *display; /// display connection | 509 | Display *display; /// display connection |