aboutsummaryrefslogtreecommitdiff
path: root/src/Ewmh.cc
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2004-01-19 18:21:51 (GMT)
committerfluxgen <fluxgen>2004-01-19 18:21:51 (GMT)
commitece17362370e5b9ef5e6e9677e896c8609587106 (patch)
tree10e82ac5c9d8d54d92b28f2190d9f76929f6515d /src/Ewmh.cc
parenta977ddf68f4409abe4ca4d604572ae2a633bb465 (diff)
downloadfluxbox_pavel-ece17362370e5b9ef5e6e9677e896c8609587106.zip
fluxbox_pavel-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.cc210
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
37Ewmh::Ewmh() { 39Ewmh::Ewmh() {
38 createAtoms(); 40 createAtoms();
39 enableUpdate();
40} 41}
41 42
42Ewmh::~Ewmh() { 43Ewmh::~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
105void Ewmh::setupClient(WinClient &winclient) { 133void Ewmh::setupClient(WinClient &winclient) {
106 updateStrut(winclient); 134 updateStrut(winclient);
107
108} 135}
109 136
110void Ewmh::setupFrame(FluxboxWindow &win) { 137void 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
141void Ewmh::updateFrameClose(FluxboxWindow &win) { 169void Ewmh::updateFrameClose(FluxboxWindow &win) {
142 clearState(win); 170 clearState(win);
143} 171}
144 172
173void 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
145void Ewmh::updateClientList(BScreen &screen) { 189void 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
217void Ewmh::updateWorkspaceNames(BScreen &screen) { 278void 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
240void Ewmh::updateCurrentWorkspace(BScreen &screen) { 327void 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
247void Ewmh::updateWorkspaceCount(BScreen &screen) { 345void 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
361void 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
379void 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
400void 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
253void Ewmh::updateState(FluxboxWindow &win) { 436void 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)