diff options
author | fluxgen <fluxgen> | 2004-01-19 18:21:51 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2004-01-19 18:21:51 (GMT) |
commit | ece17362370e5b9ef5e6e9677e896c8609587106 (patch) | |
tree | 10e82ac5c9d8d54d92b28f2190d9f76929f6515d /src/Ewmh.cc | |
parent | a977ddf68f4409abe4ca4d604572ae2a633bb465 (diff) | |
download | fluxbox-ece17362370e5b9ef5e6e9677e896c8609587106.zip fluxbox-ece17362370e5b9ef5e6e9677e896c8609587106.tar.bz2 |
support for _NET_WM_CLIENT_LIST_STACKING, _NET_WM_DESKTOP_VIEWPORT, _NET_WM_DESKTOP_GEOMETRY, _NET_WORKAREA, _NET_ACTIVE_WINDOW
Diffstat (limited to 'src/Ewmh.cc')
-rw-r--r-- | src/Ewmh.cc | 210 |
1 files changed, 198 insertions, 12 deletions
diff --git a/src/Ewmh.cc b/src/Ewmh.cc index 7b761d1..67a3520 100644 --- a/src/Ewmh.cc +++ b/src/Ewmh.cc | |||
@@ -19,7 +19,7 @@ | |||
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.37 2004/01/18 19:12:11 fluxgen Exp $ | 22 | // $Id: Ewmh.cc,v 1.38 2004/01/19 18:21:51 fluxgen Exp $ |
23 | 23 | ||
24 | #include "Ewmh.hh" | 24 | #include "Ewmh.hh" |
25 | 25 | ||
@@ -29,6 +29,8 @@ | |||
29 | #include "Workspace.hh" | 29 | #include "Workspace.hh" |
30 | #include "fluxbox.hh" | 30 | #include "fluxbox.hh" |
31 | 31 | ||
32 | #include "FbTk/FbWindow.hh" | ||
33 | |||
32 | #include <iostream> | 34 | #include <iostream> |
33 | #include <algorithm> | 35 | #include <algorithm> |
34 | #include <new> | 36 | #include <new> |
@@ -36,7 +38,6 @@ using namespace std; | |||
36 | 38 | ||
37 | Ewmh::Ewmh() { | 39 | Ewmh::Ewmh() { |
38 | createAtoms(); | 40 | createAtoms(); |
39 | enableUpdate(); | ||
40 | } | 41 | } |
41 | 42 | ||
42 | Ewmh::~Ewmh() { | 43 | Ewmh::~Ewmh() { |
@@ -81,30 +82,56 @@ void Ewmh::initForScreen(BScreen &screen) { | |||
81 | m_net_wm_state_hidden, | 82 | m_net_wm_state_hidden, |
82 | m_net_wm_state_skip_taskbar, | 83 | m_net_wm_state_skip_taskbar, |
83 | 84 | ||
84 | m_net_wm_desktop, | ||
85 | |||
86 | // root properties | 85 | // root properties |
87 | m_net_client_list, | 86 | m_net_client_list, |
87 | m_net_client_list_stacking, | ||
88 | m_net_number_of_desktops, | 88 | m_net_number_of_desktops, |
89 | m_net_current_desktop, | 89 | m_net_current_desktop, |
90 | m_net_active_window, | 90 | m_net_active_window, |
91 | m_net_close_window, | 91 | m_net_close_window, |
92 | m_net_moveresize_window, | 92 | m_net_moveresize_window, |
93 | m_net_workarea, | ||
94 | |||
95 | // desktop properties | ||
96 | m_net_wm_desktop, | ||
93 | m_net_desktop_names, | 97 | m_net_desktop_names, |
98 | m_net_desktop_viewport, | ||
99 | m_net_desktop_geometry, | ||
100 | |||
94 | m_net_supporting_wm_check | 101 | m_net_supporting_wm_check |
95 | }; | 102 | }; |
96 | 103 | /* From Extended Window Manager Hints, draft 1.3: | |
104 | * | ||
105 | * _NET_SUPPORTED, ATOM[]/32 | ||
106 | * | ||
107 | * This property MUST be set by the Window Manager | ||
108 | * to indicate which hints it supports. For | ||
109 | * example: considering _NET_WM_STATE both this | ||
110 | * atom and all supported states | ||
111 | * e.g. _NET_WM_STATE_MODAL, _NET_WM_STATE_STICKY, | ||
112 | * would be listed. This assumes that backwards | ||
113 | * incompatible changes will not be made to the | ||
114 | * hints (without being renamed). | ||
115 | */ | ||
97 | screen.rootWindow().changeProperty(m_net_supported, XA_ATOM, 32, | 116 | screen.rootWindow().changeProperty(m_net_supported, XA_ATOM, 32, |
98 | PropModeReplace, | 117 | PropModeReplace, |
99 | (unsigned char *) &atomsupported, | 118 | (unsigned char *) &atomsupported, |
100 | (sizeof atomsupported)/sizeof atomsupported[0]); | 119 | (sizeof atomsupported)/sizeof atomsupported[0]); |
101 | 120 | ||
102 | 121 | // update atoms | |
122 | |||
123 | updateWorkspaceCount(screen); | ||
124 | updateCurrentWorkspace(screen); | ||
125 | updateWorkspaceNames(screen); | ||
126 | updateClientList(screen); | ||
127 | updateViewPort(screen); | ||
128 | updateGeometry(screen); | ||
129 | updateWorkarea(screen); | ||
130 | |||
103 | } | 131 | } |
104 | 132 | ||
105 | void Ewmh::setupClient(WinClient &winclient) { | 133 | void Ewmh::setupClient(WinClient &winclient) { |
106 | updateStrut(winclient); | 134 | updateStrut(winclient); |
107 | |||
108 | } | 135 | } |
109 | 136 | ||
110 | void Ewmh::setupFrame(FluxboxWindow &win) { | 137 | void Ewmh::setupFrame(FluxboxWindow &win) { |
@@ -119,7 +146,7 @@ void Ewmh::setupFrame(FluxboxWindow &win) { | |||
119 | if (data) { | 146 | if (data) { |
120 | // we must convert to long | 147 | // we must convert to long |
121 | unsigned long *real = (unsigned long *)data; | 148 | unsigned long *real = (unsigned long *)data; |
122 | for (int i=0; i<nitems; ++i) | 149 | for (unsigned long i=0; i<nitems; ++i) |
123 | setState(win, real[i], true); | 150 | setState(win, real[i], true); |
124 | XFree(data); | 151 | XFree(data); |
125 | } | 152 | } |
@@ -136,12 +163,29 @@ void Ewmh::setupFrame(FluxboxWindow &win) { | |||
136 | XFree(data); | 163 | XFree(data); |
137 | } | 164 | } |
138 | 165 | ||
166 | updateWorkspace(win); | ||
139 | } | 167 | } |
140 | 168 | ||
141 | void Ewmh::updateFrameClose(FluxboxWindow &win) { | 169 | void Ewmh::updateFrameClose(FluxboxWindow &win) { |
142 | clearState(win); | 170 | clearState(win); |
143 | } | 171 | } |
144 | 172 | ||
173 | void Ewmh::updateFocusedWindow(BScreen &screen, Window win) { | ||
174 | /* From Extended Window Manager Hints, draft 1.3: | ||
175 | * | ||
176 | * _NET_ACTIVE_WINDOW, WINDOW/32 | ||
177 | * | ||
178 | * The window ID of the currently active window or None | ||
179 | * if no window has the focus. This is a read-only | ||
180 | * property set by the Window Manager. | ||
181 | * | ||
182 | */ | ||
183 | screen.rootWindow().changeProperty(m_net_active_window, | ||
184 | XA_WINDOW, 32, | ||
185 | PropModeReplace, | ||
186 | (unsigned char *)&win, 1); | ||
187 | } | ||
188 | |||
145 | void Ewmh::updateClientList(BScreen &screen) { | 189 | void Ewmh::updateClientList(BScreen &screen) { |
146 | size_t num=0; | 190 | size_t num=0; |
147 | 191 | ||
@@ -207,14 +251,57 @@ void Ewmh::updateClientList(BScreen &screen) { | |||
207 | } | 251 | } |
208 | //number of windows to show in client list | 252 | //number of windows to show in client list |
209 | num = win; | 253 | num = win; |
254 | |||
255 | /* From Extended Window Manager Hints, draft 1.3: | ||
256 | * | ||
257 | * _NET_CLIENT_LIST, WINDOW[]/32 | ||
258 | * _NET_CLIENT_LIST_STACKING, WINDOW[]/32 | ||
259 | * | ||
260 | * These arrays contain all X Windows managed by | ||
261 | * the Window Manager. _NET_CLIENT_LIST has | ||
262 | * initial mapping order, starting with the oldest | ||
263 | * window. _NET_CLIENT_LIST_STACKING has | ||
264 | * bottom-to-top stacking order. These properties | ||
265 | * SHOULD be set and updated by the Window | ||
266 | * Manager. | ||
267 | */ | ||
210 | screen.rootWindow().changeProperty(m_net_client_list, | 268 | screen.rootWindow().changeProperty(m_net_client_list, |
211 | XA_WINDOW, 32, | 269 | XA_WINDOW, 32, |
212 | PropModeReplace, (unsigned char *)wl, num); | 270 | PropModeReplace, (unsigned char *)wl, num); |
271 | screen.rootWindow().changeProperty(m_net_client_list_stacking, | ||
272 | XA_WINDOW, 32, | ||
273 | PropModeReplace, (unsigned char *)wl, num); | ||
213 | 274 | ||
214 | delete [] wl; | 275 | delete [] wl; |
215 | } | 276 | } |
216 | 277 | ||
217 | void Ewmh::updateWorkspaceNames(BScreen &screen) { | 278 | void Ewmh::updateWorkspaceNames(BScreen &screen) { |
279 | /* From Extended Window Manager Hints, draft 1.3: | ||
280 | * | ||
281 | * _NET_DESKTOP_NAMES, UTF8_STRING[] | ||
282 | * | ||
283 | * The names of all virtual desktops. | ||
284 | * This is a list of NULL-terminated strings in UTF-8 | ||
285 | * encoding [UTF8]. This property MAY be changed by a | ||
286 | * Pager or the Window Manager at any time. | ||
287 | * | ||
288 | * Note: The number of names could be different from | ||
289 | * _NET_NUMBER_OF_DESKTOPS. If it is less than | ||
290 | * _NET_NUMBER_OF_DESKTOPS, then the desktops with high | ||
291 | * numbers are unnamed. If it is larger than | ||
292 | * _NET_NUMBER_OF_DESKTOPS, then the excess names outside | ||
293 | * of the _NET_NUMBER_OF_DESKTOPS are considered to be | ||
294 | * reserved in case the number of desktops is increased. | ||
295 | * | ||
296 | * Rationale: The name is not a necessary attribute of a | ||
297 | * virtual desktop. Thus the availability or unavailability | ||
298 | * of names has no impact on virtual desktop functionality. | ||
299 | * Since names are set by users and users are likely to | ||
300 | * preset names for a fixed number of desktops, it | ||
301 | * doesn't make sense to shrink or grow this list when the | ||
302 | * number of available desktops changes. | ||
303 | * | ||
304 | */ | ||
218 | XTextProperty text; | 305 | XTextProperty text; |
219 | const BScreen::WorkspaceNames &workspacenames = screen.getWorkspaceNames(); | 306 | const BScreen::WorkspaceNames &workspacenames = screen.getWorkspaceNames(); |
220 | const size_t number_of_desks = workspacenames.size(); | 307 | const size_t number_of_desks = workspacenames.size(); |
@@ -238,18 +325,114 @@ void Ewmh::updateWorkspaceNames(BScreen &screen) { | |||
238 | } | 325 | } |
239 | 326 | ||
240 | void Ewmh::updateCurrentWorkspace(BScreen &screen) { | 327 | void Ewmh::updateCurrentWorkspace(BScreen &screen) { |
241 | size_t workspace = screen.currentWorkspaceID(); | 328 | /* From Extended Window Manager Hints, draft 1.3: |
242 | screen.rootWindow().changeProperty(m_net_current_desktop, XA_CARDINAL, 32, PropModeReplace, | 329 | * |
330 | * _NET_CURRENT_DESKTOP desktop, CARDINAL/32 | ||
331 | * | ||
332 | * The index of the current desktop. This is always | ||
333 | * an integer between 0 and _NET_NUMBER_OF_DESKTOPS - 1. | ||
334 | * This MUST be set and updated by the Window Manager. | ||
335 | * | ||
336 | */ | ||
337 | unsigned int workspace = screen.currentWorkspaceID(); | ||
338 | screen.rootWindow().changeProperty(m_net_current_desktop, | ||
339 | XA_CARDINAL, 32, | ||
340 | PropModeReplace, | ||
243 | (unsigned char *)&workspace, 1); | 341 | (unsigned char *)&workspace, 1); |
244 | 342 | ||
245 | } | 343 | } |
246 | 344 | ||
247 | void Ewmh::updateWorkspaceCount(BScreen &screen) { | 345 | void Ewmh::updateWorkspaceCount(BScreen &screen) { |
248 | size_t numworkspaces = screen.getCount(); | 346 | /* From Extended Window Manager Hints, draft 1.3: |
249 | screen.rootWindow().changeProperty(m_net_number_of_desktops, XA_CARDINAL, 32, PropModeReplace, | 347 | * |
348 | * _NET_NUMBER_OF_DESKTOPS, CARDINAL/32 | ||
349 | * | ||
350 | * This property SHOULD be set and updated by the | ||
351 | * Window Manager to indicate the number of virtual | ||
352 | * desktops. | ||
353 | */ | ||
354 | unsigned int numworkspaces = screen.getCount(); | ||
355 | screen.rootWindow().changeProperty(m_net_number_of_desktops, | ||
356 | XA_CARDINAL, 32, | ||
357 | PropModeReplace, | ||
250 | (unsigned char *)&numworkspaces, 1); | 358 | (unsigned char *)&numworkspaces, 1); |
251 | } | 359 | } |
252 | 360 | ||
361 | void Ewmh::updateViewPort(BScreen &screen) { | ||
362 | /* From Extended Window Manager Hints, draft 1.3: | ||
363 | * | ||
364 | * _NET_DESKTOP_VIEWPORT x, y, CARDINAL[][2]/32 | ||
365 | * | ||
366 | * Array of pairs of cardinals that define the | ||
367 | * top left corner of each desktop's viewport. | ||
368 | * For Window Managers that don't support large | ||
369 | * desktops, this MUST always be set to (0,0). | ||
370 | * | ||
371 | */ | ||
372 | int value[2] = {0, 0}; // we dont support large desktops | ||
373 | screen.rootWindow().changeProperty(m_net_desktop_viewport, | ||
374 | XA_CARDINAL, 32, | ||
375 | PropModeReplace, | ||
376 | (unsigned char *)value, 2); | ||
377 | } | ||
378 | |||
379 | void Ewmh::updateGeometry(BScreen &screen) { | ||
380 | /* From Extended Window Manager Hints, draft 1.3: | ||
381 | * | ||
382 | * _NET_DESKTOP_GEOMETRY width, height, CARDINAL[2]/32 | ||
383 | * | ||
384 | * Array of two cardinals that defines the common size | ||
385 | * of all desktops (this is equal to the screen size | ||
386 | * if the Window Manager doesn't support large | ||
387 | * desktops, otherwise it's equal to the virtual size | ||
388 | * of the desktop). This property SHOULD be set by the | ||
389 | * Window Manager. | ||
390 | * | ||
391 | */ | ||
392 | int value[2] = {screen.width(), screen.height()}; | ||
393 | screen.rootWindow().changeProperty(m_net_desktop_geometry, | ||
394 | XA_CARDINAL, 32, | ||
395 | PropModeReplace, | ||
396 | (unsigned char *)value, 2); | ||
397 | |||
398 | } | ||
399 | |||
400 | void Ewmh::updateWorkarea(BScreen &screen) { | ||
401 | /* From Extended Window Manager Hints, draft 1.3: | ||
402 | * | ||
403 | * _NET_WORKAREA, x, y, width, height CARDINAL[][4]/32 | ||
404 | * | ||
405 | * This property MUST be set by the Window Manager upon | ||
406 | * calculating the work area for each desktop. Contains a | ||
407 | * geometry for each desktop. These geometries are | ||
408 | * specified relative to the viewport on each desktop and | ||
409 | * specify an area that is completely contained within the | ||
410 | * viewport. Work area SHOULD be used by desktop applications | ||
411 | * to place desktop icons appropriately. | ||
412 | * | ||
413 | */ | ||
414 | |||
415 | /* !!TODO | ||
416 | * Not sure how to handle xinerama stuff here. | ||
417 | * So i'm just doing this on the first head. | ||
418 | */ | ||
419 | unsigned int *coords = new unsigned int[4*screen.getCount()]; | ||
420 | for (unsigned int i=0; i<screen.getCount()*4; i+=4) { | ||
421 | // x, y | ||
422 | coords[i] = screen.maxLeft(0); | ||
423 | coords[i + 1] = screen.maxTop(0); | ||
424 | // width, height | ||
425 | coords[i + 2] = screen.maxRight(0) - screen.maxLeft(0); | ||
426 | coords[i + 3] = screen.maxBottom(0) - screen.maxTop(0); | ||
427 | |||
428 | } | ||
429 | screen.rootWindow().changeProperty(m_net_workarea, | ||
430 | XA_CARDINAL, 32, | ||
431 | PropModeReplace, | ||
432 | (unsigned char *)coords, | ||
433 | 4*screen.getCount()); | ||
434 | } | ||
435 | |||
253 | void Ewmh::updateState(FluxboxWindow &win) { | 436 | void Ewmh::updateState(FluxboxWindow &win) { |
254 | //!! TODO | 437 | //!! TODO |
255 | } | 438 | } |
@@ -352,6 +535,9 @@ bool Ewmh::checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, W | |||
352 | // ce.window = window to focus | 535 | // ce.window = window to focus |
353 | 536 | ||
354 | winclient->focus(); | 537 | winclient->focus(); |
538 | if (winclient->fbwindow()) | ||
539 | winclient->fbwindow()->raise(); | ||
540 | |||
355 | return true; | 541 | return true; |
356 | } else if (ce.message_type == m_net_close_window) { | 542 | } else if (ce.message_type == m_net_close_window) { |
357 | if (winclient == 0) | 543 | if (winclient == 0) |