diff options
author | markt <markt> | 2007-06-30 17:06:29 (GMT) |
---|---|---|
committer | markt <markt> | 2007-06-30 17:06:29 (GMT) |
commit | 103b55e600aff58000ed09ff2b601daf97164167 (patch) | |
tree | b058cb0737654556daa95a7fcace87313c3b511f /src | |
parent | 998b23acf220f7bfa2117f8446a4f3a179b32d0a (diff) | |
download | fluxbox-103b55e600aff58000ed09ff2b601daf97164167.zip fluxbox-103b55e600aff58000ed09ff2b601daf97164167.tar.bz2 |
fix support for _NET_WM_STATE_MODAL
Diffstat (limited to 'src')
-rw-r--r-- | src/Ewmh.cc | 17 | ||||
-rw-r--r-- | src/Ewmh.hh | 1 | ||||
-rw-r--r-- | src/WinClient.cc | 33 | ||||
-rw-r--r-- | src/WinClient.hh | 16 | ||||
-rw-r--r-- | src/Window.cc | 5 |
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 | ||
1009 | void Ewmh::setState(FluxboxWindow &win, Atom state, bool value) { | 1008 | void 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 | ||
1013 | void Ewmh::toggleState(FluxboxWindow &win, Atom state) { | ||
1014 | toggleState(win, state, win.winClient()); | ||
1015 | } | ||
1016 | |||
1013 | // set window state | 1017 | // set window state |
1014 | void Ewmh::setState(FluxboxWindow &win, Atom state, bool value, | 1018 | void 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 |
1066 | void Ewmh::toggleState(FluxboxWindow &win, Atom state) { | 1071 | void 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 | ||
675 | void WinClient::addModal() { | 681 | void 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 | ||
681 | void 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 | ||
687 | bool WinClient::validateClient() const { | 698 | bool 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 || |