aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
5 files changed, 49 insertions, 23 deletions
diff --git a/src/Ewmh.cc b/src/Ewmh.cc
index 99a8759..3ff4e76 100644
--- a/src/Ewmh.cc
+++ b/src/Ewmh.cc
@@ -622,7 +622,7 @@ void Ewmh::updateState(FluxboxWindow &win) {
622 state.push_back(m_net_wm_state_skip_taskbar); 622 state.push_back(m_net_wm_state_skip_taskbar);
623 if (win.isFullscreen()) 623 if (win.isFullscreen())
624 state.push_back(m_net_wm_state_fullscreen); 624 state.push_back(m_net_wm_state_fullscreen);
625 if (win.winClient().isModal()) 625 if (win.winClient().isStateModal())
626 state.push_back(m_net_wm_state_modal); 626 state.push_back(m_net_wm_state_modal);
627 627
628 FluxboxWindow::ClientList::iterator it = win.clientList().begin(); 628 FluxboxWindow::ClientList::iterator it = win.clientList().begin();
@@ -1004,12 +1004,16 @@ void Ewmh::createAtoms() {
1004 utf8_string = XInternAtom(disp, "UTF8_STRING", False); 1004 utf8_string = XInternAtom(disp, "UTF8_STRING", False);
1005} 1005}
1006 1006
1007// wrapper for avoiding changing every AtomHandler to include an unnecessary 1007// wrapper for real setState, since most operations don't need the client
1008// parameter, although we need it for _NET_WM_STATE_DEMANDS_ATTENTION
1009void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) { 1008void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) {
1010 setState(win, state, value, win.winClient()); 1009 setState(win, state, value, win.winClient());
1011} 1010}
1012 1011
1012// wrapper for real toggleState, since most operations don't need the client
1013void Ewmh::toggleState(FluxboxWindow &win, Atom state) {
1014 toggleState(win, state, win.winClient());
1015}
1016
1013// set window state 1017// set window state
1014void Ewmh::setState(FluxboxWindow &win, Atom state, bool value, 1018void Ewmh::setState(FluxboxWindow &win, Atom state, bool value,
1015 WinClient &client) { 1019 WinClient &client) {
@@ -1057,13 +1061,14 @@ void Ewmh::setState(FluxboxWindow &win, Atom state, bool value,
1057 Fluxbox::instance()->attentionHandler(). 1061 Fluxbox::instance()->attentionHandler().
1058 update(&client.focusSig()); 1062 update(&client.focusSig());
1059 } 1063 }
1064 } else if (state == m_net_wm_state_modal) {
1065 client.setStateModal(value);
1060 } 1066 }
1061 1067
1062 // Note: state == net_wm_state_modal, We should not change it
1063} 1068}
1064 1069
1065// toggle window state 1070// toggle window state
1066void Ewmh::toggleState(FluxboxWindow &win, Atom state) { 1071void Ewmh::toggleState(FluxboxWindow &win, Atom state, WinClient &client) {
1067 if (state == m_net_wm_state_sticky) { // sticky 1072 if (state == m_net_wm_state_sticky) { // sticky
1068 win.stick(); 1073 win.stick();
1069 } else if (state == m_net_wm_state_shaded){ // shaded 1074 } else if (state == m_net_wm_state_shaded){ // shaded
@@ -1092,6 +1097,8 @@ void Ewmh::toggleState(FluxboxWindow &win, Atom state) {
1092 win.moveToLayer(Layer::NORMAL); 1097 win.moveToLayer(Layer::NORMAL);
1093 else 1098 else
1094 win.moveToLayer(Layer::ABOVE_DOCK); 1099 win.moveToLayer(Layer::ABOVE_DOCK);
1100 } else if (state == m_net_wm_state_modal) { // modal
1101 client.setStateModal(!client.isStateModal());
1095 } 1102 }
1096 1103
1097} 1104}
diff --git a/src/Ewmh.hh b/src/Ewmh.hh
index 8d5d986..cc33eff 100644
--- a/src/Ewmh.hh
+++ b/src/Ewmh.hh
@@ -69,6 +69,7 @@ private:
69 void setState(FluxboxWindow &win, Atom state, bool value, 69 void setState(FluxboxWindow &win, Atom state, bool value,
70 WinClient &client); 70 WinClient &client);
71 void toggleState(FluxboxWindow &win, Atom state); 71 void toggleState(FluxboxWindow &win, Atom state);
72 void toggleState(FluxboxWindow &win, Atom state, WinClient &client);
72 void createAtoms(); 73 void createAtoms();
73 void updateStrut(WinClient &winclient); 74 void updateStrut(WinClient &winclient);
74 void updateActions(FluxboxWindow &win); 75 void updateActions(FluxboxWindow &win);
diff --git a/src/WinClient.cc b/src/WinClient.cc
index 3f048d0..b731c34 100644
--- a/src/WinClient.cc
+++ b/src/WinClient.cc
@@ -77,7 +77,8 @@ WinClient::WinClient(Window win, BScreen &screen, FluxboxWindow *fbwin):
77 initial_state(0), 77 initial_state(0),
78 normal_hint_flags(0), 78 normal_hint_flags(0),
79 wm_hint_flags(0), 79 wm_hint_flags(0),
80 m_modal(0), 80 m_modal_count(0),
81 m_modal(false),
81 send_focus_message(false), 82 send_focus_message(false),
82 send_close_message(false), 83 send_close_message(false),
83 m_win_gravity(0), 84 m_win_gravity(0),
@@ -133,13 +134,14 @@ WinClient::~WinClient() {
133 134
134 Fluxbox *fluxbox = Fluxbox::instance(); 135 Fluxbox *fluxbox = Fluxbox::instance();
135 136
136
137 // 137 //
138 // clear transients and transient_for 138 // clear transients and transient_for
139 // 139 //
140 if (transient_for != 0) { 140 if (transient_for != 0) {
141 assert(transient_for != this); 141 assert(transient_for != this);
142 transient_for->transientList().remove(this); 142 transient_for->transientList().remove(this);
143 if (m_modal)
144 transient_for->removeModal();
143 transient_for = 0; 145 transient_for = 0;
144 } 146 }
145 147
@@ -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}
@@ -672,16 +678,21 @@ bool WinClient::hasGroupLeftWindow() const {
672 return false; 678 return false;
673} 679}
674 680
675void WinClient::addModal() { 681void WinClient::setStateModal(bool state) {
676 ++m_modal; 682 if (state == m_modal)
677 if (transient_for) 683 return;
678 transient_for->addModal(); 684
679} 685 m_modal = state;
686 if (transient_for) {
687 if (state)
688 transient_for->addModal();
689 else
690 transient_for->removeModal();
691 }
680 692
681void WinClient::removeModal() { 693 // TODO: we're not implementing the following part of EWMH spec:
682 --m_modal; 694 // "if WM_TRANSIENT_FOR is not set or set to the root window the dialog is
683 if (transient_for) 695 // modal for its window group."
684 transient_for->removeModal();
685} 696}
686 697
687bool WinClient::validateClient() const { 698bool WinClient::validateClient() const {
diff --git a/src/WinClient.hh b/src/WinClient.hh
index 4395f63..d3555d1 100644
--- a/src/WinClient.hh
+++ b/src/WinClient.hh
@@ -58,9 +58,6 @@ public:
58 // not aware of anything that makes this false at present 58 // not aware of anything that makes this false at present
59 inline bool isClosable() const { return true; } 59 inline bool isClosable() const { return true; }
60 60
61 void addModal(); // some transient of ours (or us) is modal
62 void removeModal(); // some transient (or us) is no longer modal
63
64 /// updates from wm class hints 61 /// updates from wm class hints
65 void updateWMClassHint(); 62 void updateWMClassHint();
66 void updateWMProtocols(); 63 void updateWMProtocols();
@@ -121,7 +118,9 @@ public:
121 inline const TransientList &transientList() const { return transients; } 118 inline const TransientList &transientList() const { return transients; }
122 inline bool isTransient() const { return transient_for != 0; } 119 inline bool isTransient() const { return transient_for != 0; }
123 120
124 inline bool isModal() const { return m_modal > 0; } 121 inline bool isModal() const { return m_modal_count > 0; }
122 inline bool isStateModal() const { return m_modal; }
123 void setStateModal(bool state);
125 124
126 inline int gravity() const { return m_win_gravity; } 125 inline int gravity() const { return m_win_gravity; }
127 126
@@ -163,9 +162,14 @@ private:
163 /// removes client from any waiting list and clears empty waiting lists 162 /// removes client from any waiting list and clears empty waiting lists
164 void removeTransientFromWaitingList(); 163 void removeTransientFromWaitingList();
165 164
165 // some transient of ours (or us) is modal
166 void addModal() { ++m_modal_count; }
167 // some transient (or us) is no longer modal
168 void removeModal() { --m_modal_count; }
169
166 // number of transients which we are modal for 170 // number of transients which we are modal for
167 // or indicates that we are modal if don't have any transients 171 int m_modal_count;
168 int m_modal; 172 bool m_modal;
169 bool send_focus_message, send_close_message; 173 bool send_focus_message, send_close_message;
170 174
171 int m_win_gravity; 175 int m_win_gravity;
diff --git a/src/Window.cc b/src/Window.cc
index 8b92999..5c27c45 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -1418,11 +1418,14 @@ bool FluxboxWindow::focus() {
1418#ifdef DEBUG 1418#ifdef DEBUG
1419 cerr<<__FUNCTION__<<": transient 0x"<<(*it)<<endl; 1419 cerr<<__FUNCTION__<<": transient 0x"<<(*it)<<endl;
1420#endif // DEBUG 1420#endif // DEBUG
1421 if ((*it)->isModal()) 1421 if ((*it)->isStateModal())
1422 return (*it)->focus(); 1422 return (*it)->focus();
1423 } 1423 }
1424 } 1424 }
1425 1425
1426 if (m_client->isModal())
1427 return false;
1428
1426 bool ret = false; 1429 bool ret = false;
1427 1430
1428 if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || 1431 if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE ||