aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkt <markt>2006-06-24 18:19:49 (GMT)
committermarkt <markt>2006-06-24 18:19:49 (GMT)
commita23ad6719725a0290d01ac4bba0ce1905b2069d7 (patch)
treeb3997c14a601117cc2c613e2a8bb79cc6a6a1c4b
parent0b730c76b10babe20738067ae7aec5a102d451fe (diff)
downloadfluxbox-a23ad6719725a0290d01ac4bba0ce1905b2069d7.zip
fluxbox-a23ad6719725a0290d01ac4bba0ce1905b2069d7.tar.bz2
Make Urgency Hint flash the correct WinClient's tab.
-rw-r--r--ChangeLog3
-rw-r--r--src/AttentionNoticeHandler.cc46
-rw-r--r--src/AttentionNoticeHandler.hh12
-rw-r--r--src/Ewmh.cc4
-rw-r--r--src/FbWinFrame.cc12
-rw-r--r--src/FbWinFrame.hh2
-rw-r--r--src/IconbarTool.cc2
-rw-r--r--src/WinClient.cc7
-rw-r--r--src/WinClient.hh3
-rw-r--r--src/Window.cc19
-rw-r--r--src/Window.hh4
11 files changed, 79 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 452c86d..74f46ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0rc2: 2Changes 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 @@
34namespace { 34namespace {
35class ToggleFrameFocusCmd: public FbTk::Command { 35class ToggleFrameFocusCmd: public FbTk::Command {
36public: 36public:
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 }
43private: 44private:
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
54void AttentionNoticeHandler::addAttention(FluxboxWindow &win) { 56void 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
97void AttentionNoticeHandler::update(FbTk::Subject *subj) { 99void 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
30class FluxboxWindow; 30class WinClient;
31 31
32namespace FbTk { 32namespace FbTk {
33class Timer; 33class Timer;
@@ -41,11 +41,11 @@ class AttentionNoticeHandler: public FbTk::Observer {
41public: 41public:
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
51private: 51private:
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
653void 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
653void FbWinFrame::setClientWindow(FbTk::FbWindow &win) { 665void 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
1085void 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
1093void FluxboxWindow::setAttentionState(bool value) {
1094 m_attention_state = value;
1095 m_attentionsig.notify();
1096}
1097
1084bool FluxboxWindow::isGroupable() const { 1098bool 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