diff options
-rw-r--r-- | src/Ewmh.cc | 146 |
1 files changed, 128 insertions, 18 deletions
diff --git a/src/Ewmh.cc b/src/Ewmh.cc index f715ccc..3f5bd86 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc | |||
@@ -19,12 +19,13 @@ | |||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
20 | // DEALINGS IN THE SOFTWARE. | 20 | // DEALINGS IN THE SOFTWARE. |
21 | 21 | ||
22 | // $Id: Ewmh.cc,v 1.2 2002/10/11 10:20:33 fluxgen Exp $ | 22 | // $Id: Ewmh.cc,v 1.3 2002/10/16 19:03:57 fluxgen Exp $ |
23 | 23 | ||
24 | #include "Ewmh.hh" | 24 | #include "Ewmh.hh" |
25 | 25 | ||
26 | #include "Screen.hh" | 26 | #include "Screen.hh" |
27 | #include "Window.hh" | 27 | #include "Window.hh" |
28 | #include "fluxbox.hh" | ||
28 | 29 | ||
29 | #include <iostream> | 30 | #include <iostream> |
30 | using namespace std; | 31 | using namespace std; |
@@ -62,14 +63,21 @@ void Ewmh::initForScreen(const BScreen &screen) { | |||
62 | 63 | ||
63 | //set supported atoms | 64 | //set supported atoms |
64 | Atom atomsupported[] = { | 65 | Atom atomsupported[] = { |
66 | // window properties | ||
65 | m_net_wm_state, | 67 | m_net_wm_state, |
66 | // states that we support: | 68 | // states that we support: |
67 | m_net_wm_state_sticky, | 69 | m_net_wm_state_sticky, |
68 | m_net_wm_state_shaded, | 70 | m_net_wm_state_shaded, |
69 | 71 | ||
72 | m_net_wm_desktop, | ||
73 | |||
74 | // root properties | ||
70 | m_net_client_list, | 75 | m_net_client_list, |
71 | m_net_number_of_desktops, | 76 | m_net_number_of_desktops, |
72 | m_net_current_desktop, | 77 | m_net_current_desktop, |
78 | m_net_active_window, | ||
79 | m_net_close_window, | ||
80 | m_net_moveresize_window, | ||
73 | m_net_desktop_names, | 81 | m_net_desktop_names, |
74 | m_net_supporting_wm_check | 82 | m_net_supporting_wm_check |
75 | }; | 83 | }; |
@@ -80,23 +88,36 @@ void Ewmh::initForScreen(const BScreen &screen) { | |||
80 | 88 | ||
81 | 89 | ||
82 | } | 90 | } |
91 | |||
83 | void Ewmh::setupWindow(FluxboxWindow &win) { | 92 | void Ewmh::setupWindow(FluxboxWindow &win) { |
84 | /* | 93 | |
85 | Display *disp = BaseDisplay::getXDisplay(); | 94 | Display *disp = BaseDisplay::getXDisplay(); |
86 | Atom ret_type; | 95 | Atom ret_type; |
87 | int fmt; | 96 | int fmt; |
88 | unsigned long nitems, bytes_after; | 97 | unsigned long nitems, bytes_after; |
89 | long flags, *data = 0; | 98 | long *data = 0; |
90 | 99 | /* | |
91 | if (XGetWindowProperty(disp, win.getClientWindow(), | 100 | if (XGetWindowProperty(disp, win.getClientWindow(), |
92 | m_net_wm_state, 0, 1, False, XA_CARDINAL, | 101 | m_net_wm_state, 0, 1, False, XA_CARDINAL, |
93 | &ret_type, &fmt, &nitems, &bytes_after, | 102 | &ret_type, &fmt, &nitems, &bytes_after, |
94 | (unsigned char **) &data) == Success && data) { | 103 | (unsigned char **) &data) == Success && data) { |
95 | flags = *data; | 104 | flags = *data; |
96 | setState(win, flags); | 105 | setState(win, flags); |
97 | XFree (data); | 106 | XFree(data); |
98 | } | 107 | } |
99 | */ | 108 | */ |
109 | if (XGetWindowProperty(disp, win.getClientWindow(), | ||
110 | m_net_wm_desktop, 0, 1, False, XA_CARDINAL, | ||
111 | &ret_type, &fmt, &nitems, &bytes_after, | ||
112 | (unsigned char **) &data) == Success && data) { | ||
113 | unsigned int desktop = static_cast<unsigned int>(*data); | ||
114 | if (desktop == 0xFFFFFFFF && !win.isStuck()) | ||
115 | win.stick(); | ||
116 | else if (win.getScreen()) | ||
117 | win.getScreen()->sendToWorkspace(desktop, &win, false); | ||
118 | |||
119 | XFree(data); | ||
120 | } | ||
100 | } | 121 | } |
101 | 122 | ||
102 | void Ewmh::updateClientList(const BScreen &screen) { | 123 | void Ewmh::updateClientList(const BScreen &screen) { |
@@ -134,7 +155,7 @@ void Ewmh::updateClientList(const BScreen &screen) { | |||
134 | XA_CARDINAL, 32, | 155 | XA_CARDINAL, 32, |
135 | PropModeReplace, (unsigned char *)wl, num); | 156 | PropModeReplace, (unsigned char *)wl, num); |
136 | 157 | ||
137 | delete wl; | 158 | delete [] wl; |
138 | } | 159 | } |
139 | 160 | ||
140 | void Ewmh::updateWorkspaceNames(const BScreen &screen) { | 161 | void Ewmh::updateWorkspaceNames(const BScreen &screen) { |
@@ -183,24 +204,113 @@ void Ewmh::updateHints(FluxboxWindow &win) { | |||
183 | } | 204 | } |
184 | 205 | ||
185 | void Ewmh::updateWorkspace(FluxboxWindow &win) { | 206 | void Ewmh::updateWorkspace(FluxboxWindow &win) { |
207 | int workspace = win.getWorkspaceNumber(); | ||
208 | if (win.isStuck()) | ||
209 | workspace = 0xFFFFFFFF; // appear on all desktops/workspaces | ||
186 | 210 | ||
211 | XChangeProperty(BaseDisplay::getXDisplay(), win.getClientWindow(), | ||
212 | m_net_wm_desktop, XA_CARDINAL, 32, PropModeReplace, | ||
213 | (unsigned char *)&workspace, 1); | ||
187 | } | 214 | } |
188 | 215 | ||
189 | bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen *screen, FluxboxWindow *win) { | 216 | // return true if we did handle the atom here |
190 | if (win != 0) { | 217 | bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * const screen, FluxboxWindow * const win) { |
191 | if (ce.message_type == m_net_wm_state) { | 218 | |
192 | if (ce.data.l[0] == STATE_REMOVE) { | 219 | if (ce.message_type == m_net_wm_desktop) { |
193 | setState(*win, ce.data.l[1], false); | 220 | if (screen == 0) |
194 | setState(*win, ce.data.l[2], false); | 221 | return true; |
195 | } else if (ce.data.l[0] == STATE_ADD) { | 222 | // ce.data.l[0] = workspace number |
196 | setState(*win, ce.data.l[1], true); | 223 | // valid window and workspace number? |
197 | setState(*win, ce.data.l[2], true); | 224 | if (win == 0 || static_cast<unsigned int>(ce.data.l[0]) >= screen->getCount()) |
198 | } else if (ce.data.l[0] == STATE_TOGGLE) { | 225 | return true; |
199 | toggleState(*win, ce.data.l[1]); | 226 | |
200 | toggleState(*win, ce.data.l[2]); | 227 | screen->sendToWorkspace(ce.data.l[0], win, false); |
228 | return true; | ||
229 | } else if (ce.message_type == m_net_wm_state) { | ||
230 | if (win == 0) | ||
231 | return true; | ||
232 | // ce.data.l[0] = the action (remove, add or toggle) | ||
233 | // ce.data.l[1] = the first property to alter | ||
234 | // ce.data.l[2] = second property to alter (can be zero) | ||
235 | if (ce.data.l[0] == STATE_REMOVE) { | ||
236 | setState(*win, ce.data.l[1], false); | ||
237 | setState(*win, ce.data.l[2], false); | ||
238 | } else if (ce.data.l[0] == STATE_ADD) { | ||
239 | setState(*win, ce.data.l[1], true); | ||
240 | setState(*win, ce.data.l[2], true); | ||
241 | } else if (ce.data.l[0] == STATE_TOGGLE) { | ||
242 | toggleState(*win, ce.data.l[1]); | ||
243 | toggleState(*win, ce.data.l[2]); | ||
244 | } | ||
245 | return true; | ||
246 | } else if (ce.message_type == m_net_number_of_desktops) { | ||
247 | if (screen == 0) | ||
248 | return true; | ||
249 | // ce.data.l[0] = number of workspaces | ||
250 | |||
251 | // no need to alter number of desktops if they are the same | ||
252 | // or if requested number of workspace is less than zero | ||
253 | if (screen->getCount() == static_cast<unsigned int>(ce.data.l[0]) || | ||
254 | ce.data.l[0] < 0) | ||
255 | return true; | ||
256 | |||
257 | if (screen->getCount() > static_cast<unsigned int>(ce.data.l[0])) { | ||
258 | // remove last workspace until we have | ||
259 | // the same number of workspaces | ||
260 | while (screen->getCount() != static_cast<unsigned int>(ce.data.l[0])) { | ||
261 | screen->removeLastWorkspace(); | ||
262 | if (screen->getCount() == 1) // must have at least one workspace | ||
263 | break; | ||
264 | } | ||
265 | } else { // add workspaces to screen until workspace count match the requested size | ||
266 | while (screen->getCount() != static_cast<unsigned int>(ce.data.l[0])) { | ||
267 | screen->addWorkspace(); | ||
201 | } | 268 | } |
202 | } | 269 | } |
270 | |||
271 | return true; | ||
272 | } else if (ce.message_type == m_net_current_desktop) { | ||
273 | if (screen == 0) | ||
274 | return true; | ||
275 | // ce.data.l[0] = workspace number | ||
276 | |||
277 | // prevent out of range value | ||
278 | if (static_cast<unsigned int>(ce.data.l[0]) >= screen->getCount()) | ||
279 | return true; | ||
280 | screen->changeWorkspaceID(ce.data.l[0]); | ||
281 | return true; | ||
282 | } else if (ce.message_type == m_net_active_window) { | ||
283 | |||
284 | // make sure we have a valid window | ||
285 | if (win == 0) | ||
286 | return true; | ||
287 | // ce.window = window to focus | ||
288 | |||
289 | // should move set focus somewhere else | ||
290 | // so we don't need fluxbox depedencies here | ||
291 | Fluxbox::instance()->setFocusedWindow(win); | ||
292 | return true; | ||
293 | } else if (ce.message_type == m_net_close_window) { | ||
294 | if (win == 0) | ||
295 | return true; | ||
296 | // ce.window = window to close (which in this case is the win argument) | ||
297 | win->close(); | ||
298 | return true; | ||
299 | } else if (ce.message_type == m_net_moveresize_window) { | ||
300 | if (win == 0) | ||
301 | return true; | ||
302 | // ce.data.l[0] = gravity and flags | ||
303 | // ce.data.l[1] = x | ||
304 | // ce.data.l[2] = y | ||
305 | // ce.data.l[3] = width | ||
306 | // ce.data.l[4] = height | ||
307 | // TODO: gravity and flags | ||
308 | win->configure(ce.data.l[1], ce.data.l[2], | ||
309 | ce.data.l[3], ce.data.l[4]); | ||
310 | return true; | ||
203 | } | 311 | } |
312 | |||
313 | // we didn't handle the ce.message_type here | ||
204 | return false; | 314 | return false; |
205 | } | 315 | } |
206 | 316 | ||