aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--src/Ewmh.cc17
-rw-r--r--src/Ewmh.hh1
-rw-r--r--src/WinClient.cc33
-rw-r--r--src/WinClient.hh16
-rw-r--r--src/Window.cc5
6 files changed, 51 insertions, 23 deletions
diff --git a/ChangeLog b/ChangeLog
index 0ea1318..71bd0c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,8 @@
1 (Format: Year/Month/Day) 1 (Format: Year/Month/Day)
2Changes for 1.0.0: 2Changes for 1.0.0:
3*07/06/30: 3*07/06/30:
4 * Fixed implementation of _NET_WM_STATE_MODAL (Mark)
5 Ewmh.cc/hh WinClient.cc/hh Window.cc
4 * Fixed the groups file, even though it's deprecated (Mark) 6 * Fixed the groups file, even though it's deprecated (Mark)
5 Workspace.cc Screen.cc 7 Workspace.cc Screen.cc
6 * Fix _NET_WM_STATE_DEMANDS_ATTENTION with tabbed windows, #1732392 (Mark) 8 * Fix _NET_WM_STATE_DEMANDS_ATTENTION with tabbed windows, #1732392 (Mark)
diff --git a/src/Ewmh.cc b/src/Ewmh.cc
index b4e831d..ef2fc09 100644
--- a/src/Ewmh.cc
+++ b/src/Ewmh.cc
@@ -629,7 +629,7 @@ void Ewmh::updateState(FluxboxWindow &win) {
629 state.push_back(m_net_wm_state_skip_taskbar); 629 state.push_back(m_net_wm_state_skip_taskbar);
630 if (win.isFullscreen()) 630 if (win.isFullscreen())
631 state.push_back(m_net_wm_state_fullscreen); 631 state.push_back(m_net_wm_state_fullscreen);
632 if (win.winClient().isModal()) 632 if (win.winClient().isStateModal())
633 state.push_back(m_net_wm_state_modal); 633 state.push_back(m_net_wm_state_modal);
634 634
635 FluxboxWindow::ClientList::iterator it = win.clientList().begin(); 635 FluxboxWindow::ClientList::iterator it = win.clientList().begin();
@@ -1031,12 +1031,16 @@ void Ewmh::createAtoms() {
1031 utf8_string = XInternAtom(disp, "UTF8_STRING", False); 1031 utf8_string = XInternAtom(disp, "UTF8_STRING", False);
1032} 1032}
1033 1033
1034// wrapper for avoiding changing every AtomHandler to include an unnecessary 1034// wrapper for real setState, since most operations don't need the client
1035// parameter, although we need it for _NET_WM_STATE_DEMANDS_ATTENTION
1036void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) { 1035void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) {
1037 setState(win, state, value, win.winClient()); 1036 setState(win, state, value, win.winClient());
1038} 1037}
1039 1038
1039// wrapper for real toggleState, since most operations don't need the client
1040void Ewmh::toggleState(FluxboxWindow &win, Atom state) {
1041 toggleState(win, state, win.winClient());
1042}
1043
1040// set window state 1044// set window state
1041void Ewmh::setState(FluxboxWindow &win, Atom state, bool value, 1045void Ewmh::setState(FluxboxWindow &win, Atom state, bool value,
1042 WinClient &client) { 1046 WinClient &client) {
@@ -1084,13 +1088,14 @@ void Ewmh::setState(FluxboxWindow &win, Atom state, bool value,
1084 Fluxbox::instance()->attentionHandler(). 1088 Fluxbox::instance()->attentionHandler().
1085 update(&client.focusSig()); 1089 update(&client.focusSig());
1086 } 1090 }
1091 } else if (state == m_net_wm_state_modal) {
1092 client.setStateModal(value);
1087 } 1093 }
1088 1094
1089 // Note: state == net_wm_state_modal, We should not change it
1090} 1095}
1091 1096
1092// toggle window state 1097// toggle window state
1093void Ewmh::toggleState(FluxboxWindow &win, Atom state) { 1098void Ewmh::toggleState(FluxboxWindow &win, Atom state, WinClient &client) {
1094 if (state == m_net_wm_state_sticky) { // sticky 1099 if (state == m_net_wm_state_sticky) { // sticky
1095 win.stick(); 1100 win.stick();
1096 } else if (state == m_net_wm_state_shaded){ // shaded 1101 } else if (state == m_net_wm_state_shaded){ // shaded
@@ -1119,6 +1124,8 @@ void Ewmh::toggleState(FluxboxWindow &win, Atom state) {
1119 win.moveToLayer(Layer::NORMAL); 1124 win.moveToLayer(Layer::NORMAL);
1120 else 1125 else
1121 win.moveToLayer(Layer::ABOVE_DOCK); 1126 win.moveToLayer(Layer::ABOVE_DOCK);
1127 } else if (state == m_net_wm_state_modal) { // modal
1128 client.setStateModal(!client.isStateModal());
1122 } 1129 }
1123 1130
1124} 1131}
diff --git a/src/Ewmh.hh b/src/Ewmh.hh
index c1a6868..00979a1 100644
--- a/src/Ewmh.hh
+++ b/src/Ewmh.hh
@@ -70,6 +70,7 @@ private:
70 void setState(FluxboxWindow &win, Atom state, bool value, 70 void setState(FluxboxWindow &win, Atom state, bool value,
71 WinClient &client); 71 WinClient &client);
72 void toggleState(FluxboxWindow &win, Atom state); 72 void toggleState(FluxboxWindow &win, Atom state);
73 void toggleState(FluxboxWindow &win, Atom state, WinClient &client);
73 void createAtoms(); 74 void createAtoms();
74 void updateStrut(WinClient &winclient); 75 void updateStrut(WinClient &winclient);
75 void updateActions(FluxboxWindow &win); 76 void updateActions(FluxboxWindow &win);
diff --git a/src/WinClient.cc b/src/WinClient.cc
index 250a0b8..fd1944b 100644
--- a/src/WinClient.cc
+++ b/src/WinClient.cc
@@ -76,7 +76,8 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):FbTk::Fb
76 normal_hint_flags(0), 76 normal_hint_flags(0),
77 wm_hint_flags(0), 77 wm_hint_flags(0),
78 m_win(fbwin), 78 m_win(fbwin),
79 m_modal(0), 79 m_modal_count(0),
80 m_modal(false),
80 send_focus_message(false), 81 send_focus_message(false),
81 send_close_message(false), 82 send_close_message(false),
82 m_win_gravity(0), 83 m_win_gravity(0),
@@ -136,13 +137,14 @@ WinClient::~WinClient() {
136 137
137 Fluxbox *fluxbox = Fluxbox::instance(); 138 Fluxbox *fluxbox = Fluxbox::instance();
138 139
139
140 // 140 //
141 // clear transients and transient_for 141 // clear transients and transient_for
142 // 142 //
143 if (transient_for != 0) { 143 if (transient_for != 0) {
144 assert(transient_for != this); 144 assert(transient_for != this);
145 transient_for->transientList().remove(this); 145 transient_for->transientList().remove(this);
146 if (m_modal)
147 transient_for->removeModal();
146 transient_for = 0; 148 transient_for = 0;
147 } 149 }
148 150
@@ -276,6 +278,8 @@ void WinClient::updateTransientInfo() {
276 // remove this from parent 278 // remove this from parent
277 if (transientFor() != 0) { 279 if (transientFor() != 0) {
278 transientFor()->transientList().remove(this); 280 transientFor()->transientList().remove(this);
281 if (m_modal)
282 transientFor()->removeModal();
279 } 283 }
280 284
281 transient_for = 0; 285 transient_for = 0;
@@ -337,6 +341,8 @@ void WinClient::updateTransientInfo() {
337 // we need to add ourself to the right client in 341 // we need to add ourself to the right client in
338 // the transientFor() window so we search client 342 // the transientFor() window so we search client
339 transient_for->transientList().push_back(this); 343 transient_for->transientList().push_back(this);
344 if (m_modal)
345 transient_for->addModal();
340 } 346 }
341 347
342} 348}
@@ -663,16 +669,21 @@ bool WinClient::hasGroupLeftWindow() const {
663 return false; 669 return false;
664} 670}
665 671
666void WinClient::addModal() { 672void WinClient::setStateModal(bool state) {
667 ++m_modal; 673 if (state == m_modal)
668 if (transient_for) 674 return;
669 transient_for->addModal(); 675
670} 676 m_modal = state;
677 if (transient_for) {
678 if (state)
679 transient_for->addModal();
680 else
681 transient_for->removeModal();
682 }
671 683
672void WinClient::removeModal() { 684 // TODO: we're not implementing the following part of EWMH spec:
673 --m_modal; 685 // "if WM_TRANSIENT_FOR is not set or set to the root window the dialog is
674 if (transient_for) 686 // modal for its window group."
675 transient_for->removeModal();
676} 687}
677 688
678bool WinClient::validateClient() const { 689bool WinClient::validateClient() const {
diff --git a/src/WinClient.hh b/src/WinClient.hh
index 40daa8e..01517c2 100644
--- a/src/WinClient.hh
+++ b/src/WinClient.hh
@@ -57,9 +57,6 @@ public:
57 // not aware of anything that makes this false at present 57 // not aware of anything that makes this false at present
58 inline bool isClosable() const { return true; } 58 inline bool isClosable() const { return true; }
59 59
60 void addModal(); // some transient of ours (or us) is modal
61 void removeModal(); // some transient (or us) is no longer modal
62
63 /// updates from wm class hints 60 /// updates from wm class hints
64 void updateWMClassHint(); 61 void updateWMClassHint();
65 void updateWMProtocols(); 62 void updateWMProtocols();
@@ -127,7 +124,9 @@ public:
127 inline const TransientList &transientList() const { return transients; } 124 inline const TransientList &transientList() const { return transients; }
128 inline bool isTransient() const { return transient_for != 0; } 125 inline bool isTransient() const { return transient_for != 0; }
129 126
130 inline bool isModal() const { return m_modal > 0; } 127 inline bool isModal() const { return m_modal_count > 0; }
128 inline bool isStateModal() const { return m_modal; }
129 void setStateModal(bool state);
131 130
132 const FbTk::FbPixmap &iconPixmap() const { return m_icon_pixmap; } 131 const FbTk::FbPixmap &iconPixmap() const { return m_icon_pixmap; }
133 const FbTk::FbPixmap &iconMask() const { return m_icon_mask; } 132 const FbTk::FbPixmap &iconMask() const { return m_icon_mask; }
@@ -188,11 +187,16 @@ private:
188 /// removes client from any waiting list and clears empty waiting lists 187 /// removes client from any waiting list and clears empty waiting lists
189 void removeTransientFromWaitingList(); 188 void removeTransientFromWaitingList();
190 189
190 // some transient of ours (or us) is modal
191 void addModal() { ++m_modal_count; }
192 // some transient (or us) is no longer modal
193 void removeModal() { --m_modal_count; }
194
191 FluxboxWindow *m_win; 195 FluxboxWindow *m_win;
192 196
193 // number of transients which we are modal for 197 // number of transients which we are modal for
194 // or indicates that we are modal if don't have any transients 198 int m_modal_count;
195 int m_modal; 199 bool m_modal;
196 bool send_focus_message, send_close_message; 200 bool send_focus_message, send_close_message;
197 201
198 int m_win_gravity; 202 int m_win_gravity;
diff --git a/src/Window.cc b/src/Window.cc
index 1c839f6..b44f9f7 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -1372,11 +1372,14 @@ bool FluxboxWindow::setInputFocus() {
1372#ifdef DEBUG 1372#ifdef DEBUG
1373 cerr<<__FUNCTION__<<": transient 0x"<<(*it)<<endl; 1373 cerr<<__FUNCTION__<<": transient 0x"<<(*it)<<endl;
1374#endif // DEBUG 1374#endif // DEBUG
1375 if ((*it)->isModal()) 1375 if ((*it)->isStateModal())
1376 return (*it)->focus(); 1376 return (*it)->focus();
1377 } 1377 }
1378 } 1378 }
1379 1379
1380 if (m_client->isModal())
1381 return false;
1382
1380 bool ret = false; 1383 bool ret = false;
1381 1384
1382 if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || 1385 if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE ||