changed indentation to use spaces only
[wmaker-crm.git] / src / gnome.c
blob0d15cc25e180fb7aa4d448158c7203da6faaf307
1 /* gnome.c-- support for the GNOME Hints
3 * Window Maker window manager
5 * Copyright (c) 1998-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
24 * According to the author of this thing, it should not be taken seriously.
25 * IMHO, there are lot's of weirdnesses and it's quite unelegant. I'd
26 * rather not support it, but here it goes anyway.
29 #include "wconfig.h"
31 #ifdef GNOME_STUFF
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
35 #include <X11/Xatom.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
42 #include "WindowMaker.h"
43 #include "screen.h"
44 #include "wcore.h"
45 #include "framewin.h"
46 #include "window.h"
47 #include "workspace.h"
48 #include "funcs.h"
49 #include "actions.h"
50 #include "stacking.h"
51 #include "client.h"
52 #include "xinerama.h"
54 #include "gnome.h"
61 #define WIN_HINTS_SKIP_FOCUS (1<<0) /*"alt-tab" skips this win*/
62 #define WIN_HINTS_SKIP_WINLIST (1<<1) /*do not show in window list*/
63 #define WIN_HINTS_SKIP_TASKBAR (1<<2) /*do not show on taskbar*/
64 #define WIN_HINTS_GROUP_TRANSIENT (1<<3) /*Reserved - definition is unclear*/
65 #define WIN_HINTS_FOCUS_ON_CLICK (1<<4) /*app only accepts focus if clicked*/
66 #define WIN_HINTS_DO_NOT_COVER (1<<5) /* attempt to not cover this window */
69 #define WIN_STATE_STICKY (1<<0) /*everyone knows sticky*/
70 #define WIN_STATE_MINIMIZED (1<<1) /*Reserved - definition is unclear*/
71 #define WIN_STATE_MAXIMIZED_VERT (1<<2) /*window in maximized V state*/
72 #define WIN_STATE_MAXIMIZED_HORIZ (1<<3) /*window in maximized H state*/
73 #define WIN_STATE_HIDDEN (1<<4) /*not on taskbar but window visible*/
74 #define WIN_STATE_SHADED (1<<5) /*shaded (MacOS / Afterstep style)*/
75 /* these are bogus states defined in "the spec" */
76 #define WIN_STATE_HID_WORKSPACE (1<<6) /*not on current desktop*/
77 #define WIN_STATE_HID_TRANSIENT (1<<7) /*owner of transient is hidden*/
78 #define WIN_STATE_FIXED_POSITION (1<<8) /*window is fixed in position even*/
79 #define WIN_STATE_ARRANGE_IGNORE (1<<9) /*ignore for auto arranging*/
82 #define WIN_LAYER_DESKTOP 0
83 #define WIN_LAYER_BELOW 2
84 #define WIN_LAYER_NORMAL 4
85 #define WIN_LAYER_ONTOP 6
86 #define WIN_LAYER_DOCK 8
87 #define WIN_LAYER_ABOVE_DOCK 10
88 #define WIN_LAYER_MENU 12
92 static Atom _XA_WIN_SUPPORTING_WM_CHECK = 0;
93 static Atom _XA_WIN_PROTOCOLS;
94 static Atom _XA_WIN_LAYER;
95 static Atom _XA_WIN_STATE;
96 static Atom _XA_WIN_HINTS;
97 static Atom _XA_WIN_APP_STATE;
98 static Atom _XA_WIN_EXPANDED_SIZE;
99 static Atom _XA_WIN_ICONS;
100 static Atom _XA_WIN_WORKSPACE;
101 static Atom _XA_WIN_WORKSPACE_COUNT;
102 static Atom _XA_WIN_WORKSPACE_NAMES;
103 static Atom _XA_WIN_CLIENT_LIST;
104 static Atom _XA_WIN_DESKTOP_BUTTON_PROXY;
107 static void observer(void *self, WMNotification *notif);
108 static void wsobserver(void *self, WMNotification *notif);
111 void
112 wGNOMEInitStuff(WScreen *scr)
114 Atom supportedStuff[10];
115 int count;
117 if (!_XA_WIN_SUPPORTING_WM_CHECK) {
119 _XA_WIN_SUPPORTING_WM_CHECK =
120 XInternAtom(dpy, "_WIN_SUPPORTING_WM_CHECK", False);
122 _XA_WIN_PROTOCOLS = XInternAtom(dpy, "_WIN_PROTOCOLS", False);
124 _XA_WIN_LAYER = XInternAtom(dpy, "_WIN_LAYER", False);
126 _XA_WIN_STATE = XInternAtom(dpy, "_WIN_STATE", False);
128 _XA_WIN_HINTS = XInternAtom(dpy, "_WIN_HINTS", False);
130 _XA_WIN_APP_STATE = XInternAtom(dpy, "_WIN_APP_STATE", False);
132 _XA_WIN_EXPANDED_SIZE = XInternAtom(dpy, "_WIN_EXPANDED_SIZE", False);
134 _XA_WIN_ICONS = XInternAtom(dpy, "_WIN_ICONS", False);
136 _XA_WIN_WORKSPACE = XInternAtom(dpy, "_WIN_WORKSPACE", False);
138 _XA_WIN_WORKSPACE_COUNT =
139 XInternAtom(dpy, "_WIN_WORKSPACE_COUNT", False);
141 _XA_WIN_WORKSPACE_NAMES =
142 XInternAtom(dpy, "_WIN_WORKSPACE_NAMES", False);
144 _XA_WIN_CLIENT_LIST = XInternAtom(dpy, "_WIN_CLIENT_LIST", False);
146 _XA_WIN_DESKTOP_BUTTON_PROXY =
147 XInternAtom(dpy, "_WIN_DESKTOP_BUTTON_PROXY", False);
150 /* I'd rather use the ICCCM 2.0 mechanisms, but
151 * since some people prefer to reinvent the wheel instead of
152 * conforming to standards... */
154 /* setup the "We're compliant, you idiot!" hint */
156 /* why XA_CARDINAL instead of XA_WINDOW? */
157 XChangeProperty(dpy, scr->root_win, _XA_WIN_SUPPORTING_WM_CHECK,
158 XA_CARDINAL, 32, PropModeReplace,
159 (unsigned char*)&scr->no_focus_win, 1);
161 XChangeProperty(dpy, scr->no_focus_win, _XA_WIN_SUPPORTING_WM_CHECK,
162 XA_CARDINAL, 32, PropModeReplace,
163 (unsigned char*)&scr->no_focus_win, 1);
166 /* setup the "desktop button proxy" thing */
167 XChangeProperty(dpy, scr->root_win, _XA_WIN_DESKTOP_BUTTON_PROXY,
168 XA_CARDINAL, 32, PropModeReplace,
169 (unsigned char*)&scr->no_focus_win, 1);
170 XChangeProperty(dpy, scr->no_focus_win, _XA_WIN_DESKTOP_BUTTON_PROXY,
171 XA_CARDINAL, 32, PropModeReplace,
172 (unsigned char*)&scr->no_focus_win, 1);
175 /* setup the list of supported protocols */
176 count = 0;
177 supportedStuff[count++] = _XA_WIN_LAYER;
178 supportedStuff[count++] = _XA_WIN_STATE;
179 supportedStuff[count++] = _XA_WIN_HINTS;
180 supportedStuff[count++] = _XA_WIN_APP_STATE;
181 supportedStuff[count++] = _XA_WIN_EXPANDED_SIZE;
182 supportedStuff[count++] = _XA_WIN_ICONS;
183 supportedStuff[count++] = _XA_WIN_WORKSPACE;
184 supportedStuff[count++] = _XA_WIN_WORKSPACE_COUNT;
185 supportedStuff[count++] = _XA_WIN_WORKSPACE_NAMES;
186 supportedStuff[count++] = _XA_WIN_CLIENT_LIST;
188 XChangeProperty(dpy, scr->root_win, _XA_WIN_PROTOCOLS, XA_ATOM, 32,
189 PropModeReplace, (unsigned char*)supportedStuff, count);
191 XFlush(dpy);
193 WMAddNotificationObserver(observer, NULL, WMNManaged, NULL);
194 WMAddNotificationObserver(observer, NULL, WMNUnmanaged, NULL);
195 WMAddNotificationObserver(observer, NULL, WMNChangedWorkspace, NULL);
196 WMAddNotificationObserver(observer, NULL, WMNChangedState, NULL);
197 WMAddNotificationObserver(observer, NULL, WMNChangedFocus, NULL);
198 WMAddNotificationObserver(observer, NULL, WMNChangedStacking, NULL);
199 WMAddNotificationObserver(observer, NULL, WMNChangedName, NULL);
201 WMAddNotificationObserver(wsobserver, NULL, WMNWorkspaceCreated, NULL);
202 WMAddNotificationObserver(wsobserver, NULL, WMNWorkspaceDestroyed, NULL);
203 WMAddNotificationObserver(wsobserver, NULL, WMNWorkspaceChanged, NULL);
204 WMAddNotificationObserver(wsobserver, NULL, WMNWorkspaceNameChanged, NULL);
208 void
209 wGNOMEUpdateClientListHint(WScreen *scr)
211 WWindow *wwin;
212 Window *windows;
213 int count;
215 windows = malloc(sizeof(Window)*scr->window_count);
216 if (!windows) {
217 wwarning(_("out of memory while updating GNOME hints"));
218 return;
221 count = 0;
222 wwin = scr->focused_window;
223 while (wwin) {
224 if (!wwin->flags.internal_window &&
225 !wwin->client_flags.skip_window_list) {
227 windows[count++] = wwin->client_win;
230 wwin = wwin->prev;
233 XChangeProperty(dpy, scr->root_win, _XA_WIN_CLIENT_LIST, XA_CARDINAL, 32,
234 PropModeReplace, (unsigned char *)windows, count);
236 wfree(windows);
237 XFlush(dpy);
241 void
242 wGNOMEUpdateWorkspaceHints(WScreen *scr)
244 long val;
246 val = scr->workspace_count;
248 XChangeProperty(dpy, scr->root_win, _XA_WIN_WORKSPACE_COUNT, XA_CARDINAL,
249 32, PropModeReplace, (unsigned char*)&val, 1);
251 wGNOMEUpdateWorkspaceNamesHint(scr);
255 void
256 wGNOMEUpdateWorkspaceNamesHint(WScreen *scr)
258 char *wsNames[MAX_WORKSPACES];
259 XTextProperty textProp;
260 int i;
262 for (i = 0; i < scr->workspace_count; i++) {
263 wsNames[i] = scr->workspaces[i]->name;
266 if (XStringListToTextProperty(wsNames, scr->workspace_count, &textProp)) {
267 XSetTextProperty(dpy, scr->root_win, &textProp,
268 _XA_WIN_WORKSPACE_NAMES);
269 XFree(textProp.value);
274 void
275 wGNOMEUpdateCurrentWorkspaceHint(WScreen *scr)
277 long val;
279 val = scr->current_workspace;
281 XChangeProperty(dpy, scr->root_win, _XA_WIN_WORKSPACE, XA_CARDINAL,
282 32, PropModeReplace, (unsigned char*)&val, 1);
286 static int
287 getWindowLevel(int layer)
289 int level;
291 if (layer <= WIN_LAYER_DESKTOP)
292 level = WMDesktopLevel;
293 else if (layer <= WIN_LAYER_BELOW)
294 level = WMSunkenLevel;
295 else if (layer <= WIN_LAYER_NORMAL)
296 level = WMNormalLevel;
297 else if (layer <= WIN_LAYER_ONTOP)
298 level = WMFloatingLevel;
299 else if (layer <= WIN_LAYER_DOCK)
300 level = WMDockLevel;
301 else if (layer <= WIN_LAYER_ABOVE_DOCK)
302 level = WMSubmenuLevel;
303 else if (layer <= WIN_LAYER_MENU)
304 level = WMMainMenuLevel;
305 else
306 level = WMOuterSpaceLevel;
308 return level;
312 Bool
313 wGNOMECheckClientHints(WWindow *wwin, int *layer, int *workspace)
315 Atom type_ret;
316 int fmt_ret;
317 unsigned long nitems_ret;
318 unsigned long bytes_after_ret;
319 long flags, val, *data = 0;
320 Bool hasHints = False;
322 /* hints */
324 if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_HINTS, 0, 1, False,
325 /* should be XA_INTEGER, but spec is broken */
326 XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret,
327 &bytes_after_ret,
328 (unsigned char**)&data)==Success && data) {
329 flags = *data;
331 XFree(data);
333 if (flags & (WIN_HINTS_SKIP_FOCUS|WIN_HINTS_SKIP_WINLIST
334 |WIN_HINTS_SKIP_TASKBAR)) {
335 wwin->client_flags.skip_window_list = 1;
338 /* client reserved area, for the panel */
339 if (flags & (WIN_HINTS_DO_NOT_COVER)) {
340 WReservedArea *area;
342 area = malloc(sizeof(WReservedArea));
343 if (!area) {
344 wwarning(_("out of memory while updating GNOME hints"));
345 } else {
346 XWindowAttributes wattribs;
348 XGetWindowAttributes(dpy, wwin->client_win, &wattribs);
349 wClientGetNormalHints(wwin, &wattribs, False,
350 &area->area.x1, &area->area.y1,
351 &area->area.x2, &area->area.y2);
352 area->area.x2 = area->area.x2 + area->area.x1;
353 area->area.y2 = area->area.y2 + area->area.y1;
355 area->window = wwin->client_win;
357 area->next = wwin->screen_ptr->reservedAreas;
358 wwin->screen_ptr->reservedAreas = area;
360 wScreenUpdateUsableArea(wwin->screen_ptr);
363 hasHints = True;
366 /* layer */
367 if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_LAYER, 0, 1, False,
368 XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret,
369 &bytes_after_ret,
370 (unsigned char**)&data)==Success && data) {
371 val = *data;
373 XFree(data);
375 *layer = getWindowLevel(val);
376 hasHints = True;
379 /* workspace */
380 if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_WORKSPACE, 0, 1,
381 False, XA_CARDINAL, &type_ret, &fmt_ret,
382 &nitems_ret, &bytes_after_ret,
383 (unsigned char**)&data)==Success && data) {
384 val = *data;
386 XFree(data);
388 if (val > 0)
389 *workspace = val;
390 hasHints = True;
393 /* reserved area */
394 if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_EXPANDED_SIZE, 0, 1,
395 False, XA_CARDINAL, &type_ret, &fmt_ret,
396 &nitems_ret, &bytes_after_ret,
397 (unsigned char**)&data)==Success && data) {
398 WReservedArea *area;
400 area = malloc(sizeof(WReservedArea));
401 if (!area) {
402 wwarning(_("out of memory while updating GNOME hints"));
403 } else {
404 area->area.x1 = data[0];
405 area->area.y1 = data[1];
406 area->area.x2 = data[2] - data[0];
407 area->area.y2 = data[3] - data[1];
408 XFree(data);
410 area->window = wwin->client_win;
413 area->next = wwin->screen_ptr->reservedAreas;
414 wwin->screen_ptr->reservedAreas = area;
416 wScreenUpdateUsableArea(wwin->screen_ptr);
417 hasHints = True;
420 return hasHints;
424 Bool
425 wGNOMEGetUsableArea(WScreen *scr, int head, WArea *area)
427 WReservedArea *cur;
428 WMRect rect;
430 if(!scr->reservedAreas)
431 return False;
433 area->x1 = area->y1 = area->x2 = area->y2 = 0;
435 for(cur = scr->reservedAreas ; cur ; cur = cur->next) {
436 WWindow * wwin = wWindowFor(cur->window);
437 if (wWindowTouchesHead(wwin, head)) {
438 if(cur->area.x1 > area->x1)
439 area->x1 = cur->area.x1;
440 if(cur->area.y1 > area->y1)
441 area->y1 = cur->area.y1;
442 if(cur->area.x2 > area->x2)
443 area->x2 = cur->area.x2;
444 if(cur->area.y2 > area->y2)
445 area->y2 = cur->area.y2;
449 if (area->x1==0 && area->x2==0 &&
450 area->y1==0 && area->y2==0) return False;
452 rect = wGetRectForHead(scr, head);
454 area->x1 = rect.pos.x + area->x1;
455 area->x2 = rect.pos.x + rect.size.width - area->x2;
456 area->y1 = rect.pos.y + area->y1;
457 area->y2 = rect.pos.y + rect.size.height - area->y2;
459 return True;
463 Bool
464 wGNOMECheckInitialClientState(WWindow *wwin)
466 Atom type_ret;
467 int fmt_ret;
468 unsigned long nitems_ret;
469 unsigned long bytes_after_ret;
470 long flags, *data = 0;
472 if (XGetWindowProperty(dpy, wwin->client_win, _XA_WIN_STATE, 0, 1, False,
473 XA_CARDINAL, &type_ret, &fmt_ret, &nitems_ret,
474 &bytes_after_ret,
475 (unsigned char**)&data)!=Success || !data)
476 return False;
478 flags = *data;
480 XFree(data);
482 if (flags & WIN_STATE_STICKY)
483 wwin->client_flags.omnipresent = 1;
485 if (flags & (WIN_STATE_MAXIMIZED_VERT|WIN_STATE_MAXIMIZED_HORIZ)) {
487 if (flags & WIN_STATE_MAXIMIZED_VERT)
488 wwin->flags.maximized |= MAX_VERTICAL;
490 if (flags & WIN_STATE_MAXIMIZED_HORIZ)
491 wwin->flags.maximized |= MAX_HORIZONTAL;
494 if (flags & WIN_STATE_SHADED)
495 wwin->flags.shaded = 1;
497 return True;
501 void
502 wGNOMEUpdateClientStateHint(WWindow *wwin, Bool changedWorkspace)
504 long val;
505 long flags = 0;
507 if (changedWorkspace) {
508 val = wwin->frame->workspace;
510 XChangeProperty(dpy, wwin->client_win, _XA_WIN_WORKSPACE, XA_CARDINAL,
511 32, PropModeReplace, (unsigned char*)&val, 1);
513 if (val != wwin->screen_ptr->current_workspace)
514 flags |= WIN_STATE_HID_WORKSPACE;
517 if (IS_OMNIPRESENT(wwin))
518 flags |= WIN_STATE_STICKY;
520 if (wwin->flags.miniaturized)
521 flags |= WIN_STATE_MINIMIZED;
523 if (wwin->flags.maximized & MAX_VERTICAL)
524 flags |= WIN_STATE_MAXIMIZED_VERT;
526 if (wwin->flags.maximized & MAX_HORIZONTAL)
527 flags |= WIN_STATE_MAXIMIZED_HORIZ;
529 if (wwin->flags.shaded)
530 flags |= WIN_STATE_SHADED;
532 if (wwin->transient_for != None) {
533 WWindow *owner = wWindowFor(wwin->transient_for);
535 if (owner && !owner->flags.mapped)
536 flags |= WIN_STATE_HID_TRANSIENT;
539 /* ? */
540 if (wwin->flags.hidden)
541 flags |= WIN_STATE_HIDDEN;
543 XChangeProperty(dpy, wwin->client_win, _XA_WIN_STATE, XA_CARDINAL,
544 32, PropModeReplace, (unsigned char*)&flags, 1);
548 Bool
549 wGNOMEProcessClientMessage(XClientMessageEvent *event)
551 WScreen *scr;
552 WWindow *wwin;
553 Bool done = True;
555 scr = wScreenForWindow(event->window);
556 if (scr) {
557 /* generic client messages */
558 if (event->message_type == _XA_WIN_WORKSPACE) {
559 wWorkspaceChange(scr, event->data.l[0]);
560 } else {
561 done = False;
564 if (done)
565 return True;
568 /* window specific client messages */
570 wwin = wWindowFor(event->window);
571 if (!wwin)
572 return False;
574 if (event->message_type == _XA_WIN_LAYER) {
575 int level = getWindowLevel(event->data.l[0]);
577 if (WINDOW_LEVEL(wwin) != level) {
578 ChangeStackingLevel(wwin->frame->core, level);
580 } else if (event->message_type == _XA_WIN_STATE) {
581 int flags, mask;
582 int maximize = 0;
584 mask = event->data.l[0];
585 flags = event->data.l[1];
587 if (mask & WIN_STATE_STICKY) {
588 if ((flags & WIN_STATE_STICKY) != WFLAGP(wwin, omnipresent)) {
589 wWindowSetOmnipresent(wwin, (flags & WIN_STATE_STICKY)!=0);
593 if (mask & WIN_STATE_MAXIMIZED_VERT) {
594 if (flags & WIN_STATE_MAXIMIZED_VERT)
595 maximize = MAX_VERTICAL;
596 else
597 maximize = 0;
598 } else {
599 maximize = wwin->flags.maximized & MAX_VERTICAL;
602 if (mask & WIN_STATE_MAXIMIZED_HORIZ) {
603 if (flags & WIN_STATE_MAXIMIZED_HORIZ)
604 maximize |= MAX_HORIZONTAL;
605 else
606 maximize |= 0;
607 } else {
608 maximize |= wwin->flags.maximized & MAX_HORIZONTAL;
611 if (maximize != wwin->flags.maximized) {
612 if (maximize) {
613 wMaximizeWindow(wwin, maximize);
614 } else {
615 wUnmaximizeWindow(wwin);
619 if (mask & WIN_STATE_SHADED) {
620 if ((flags & WIN_STATE_SHADED) != wwin->flags.shaded) {
621 if (wwin->flags.shaded)
622 wUnshadeWindow(wwin);
623 else
624 wShadeWindow(wwin);
627 } else if (event->message_type == _XA_WIN_WORKSPACE) {
629 if (event->data.l[0] != wwin->frame->workspace) {
630 wWindowChangeWorkspace(wwin, event->data.l[0]);
632 } else {
633 done = False;
636 return done;
640 Bool
641 wGNOMEProxyizeButtonEvent(WScreen *scr, XEvent *event)
643 if (event->type == ButtonPress)
644 XUngrabPointer(dpy, CurrentTime);
645 XSendEvent(dpy, scr->no_focus_win, False, SubstructureNotifyMask, event);
647 return True;
651 void
652 wGNOMERemoveClient(WWindow *wwin)
654 int flag = 0;
655 WReservedArea *area;
657 wGNOMEUpdateClientListHint(wwin->screen_ptr);
659 area = wwin->screen_ptr->reservedAreas;
661 if (area) {
662 if (area->window == wwin->client_win) {
663 wwin->screen_ptr->reservedAreas = area->next;
664 wfree(area);
665 flag = 1;
666 } else {
667 while (area->next && area->next->window != wwin->client_win)
668 area = area->next;
670 if (area->next) {
671 WReservedArea *next;
673 next = area->next->next;
674 wfree(area->next);
675 area->next = next;
677 flag = 1;
682 if (flag) {
683 wScreenUpdateUsableArea(wwin->screen_ptr);
690 static void
691 observer(void *self, WMNotification *notif)
693 WWindow *wwin = (WWindow*)WMGetNotificationObject(notif);
694 const char *name = WMGetNotificationName(notif);
696 if (strcmp(name, WMNManaged) == 0 && wwin) {
697 wGNOMEUpdateClientStateHint(wwin, True);
699 wGNOMEUpdateClientListHint(wwin->screen_ptr);
700 } else if (strcmp(name, WMNUnmanaged) == 0 && wwin) {
701 wGNOMERemoveClient(wwin);
702 } else if (strcmp(name, WMNChangedWorkspace) == 0 && wwin) {
703 wGNOMEUpdateClientStateHint(wwin, True);
704 } else if (strcmp(name, WMNChangedState) == 0 && wwin) {
705 wGNOMEUpdateClientStateHint(wwin, False);
710 static void
711 wsobserver(void *self, WMNotification *notif)
713 WScreen *scr = (WScreen*)WMGetNotificationObject(notif);
714 const char *name = WMGetNotificationName(notif);
716 if (strcmp(name, WMNWorkspaceCreated) == 0) {
717 wGNOMEUpdateWorkspaceHints(scr);
718 } else if (strcmp(name, WMNWorkspaceDestroyed) == 0) {
719 wGNOMEUpdateWorkspaceHints(scr);
720 } else if (strcmp(name, WMNWorkspaceNameChanged) == 0) {
721 wGNOMEUpdateWorkspaceNamesHint(scr);
722 } else if (strcmp(name, WMNWorkspaceChanged) == 0) {
723 wGNOMEUpdateCurrentWorkspaceHint(scr);
724 } else if (strcmp(name, WMNResetStacking) == 0) {
730 #endif /* GNOME_STUFF */