Better error message when defaults file is missing.
[xfwm4.git] / src / netwm.c
blobd3f03254910d45d4e1d4f3facf5e30e1eb2b10c6
1 /* $Id$
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 xfwm4 - (c) 2002-2007 Olivier Fourdan
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <X11/Xatom.h>
28 #include <glib.h>
29 #include <gdk/gdk.h>
30 #include <gdk/gdkx.h>
31 #include <gtk/gtk.h>
32 #include <libxfce4util/libxfce4util.h>
34 #include "client.h"
35 #include "compositor.h"
36 #include "display.h"
37 #include "frame.h"
38 #include "focus.h"
39 #include "hints.h"
40 #include "misc.h"
41 #include "netwm.h"
42 #include "screen.h"
43 #include "stacking.h"
44 #include "transients.h"
45 #include "workspaces.h"
47 void
48 clientSetNetState (Client * c)
50 ScreenInfo *screen_info;
51 DisplayInfo *display_info;
52 Atom data[16];
53 int i;
55 g_return_if_fail (c != NULL);
56 TRACE ("entering clientSetNetState");
57 TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
59 screen_info = c->screen_info;
60 display_info = screen_info->display_info;
62 i = 0;
63 if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
65 TRACE ("clientSetNetState : shaded");
66 data[i++] = display_info->atoms[NET_WM_STATE_SHADED];
68 if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
70 TRACE ("clientSetNetState : sticky");
71 data[i++] = display_info->atoms[NET_WM_STATE_STICKY];
73 if (FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL))
75 TRACE ("clientSetNetState : modal");
76 data[i++] = display_info->atoms[NET_WM_STATE_MODAL];
78 if (FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_PAGER))
80 TRACE ("clientSetNetState : skip_pager");
81 data[i++] = display_info->atoms[NET_WM_STATE_SKIP_PAGER];
83 if (FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_TASKBAR))
85 TRACE ("clientSetNetState : skip_taskbar");
86 data[i++] = display_info->atoms[NET_WM_STATE_SKIP_TASKBAR];
88 if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
90 TRACE ("clientSetNetState : maximize vert + horiz");
91 data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ];
92 data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT];
94 else if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
96 TRACE ("clientSetNetState : maximize horiz");
97 data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ];
99 else if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
101 TRACE ("clientSetNetState : vert");
102 data[i++] = display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT];
104 if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
106 TRACE ("clientSetNetState : fullscreen");
107 data[i++] = display_info->atoms[NET_WM_STATE_FULLSCREEN];
109 else if (FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
111 TRACE ("clientSetNetState : above");
112 data[i++] = display_info->atoms[NET_WM_STATE_ABOVE];
114 else if (FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
116 TRACE ("clientSetNetState : below");
117 data[i++] = display_info->atoms[NET_WM_STATE_BELOW];
119 if (FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED))
121 TRACE ("clientSetNetState : hidden");
122 data[i++] = display_info->atoms[NET_WM_STATE_HIDDEN];
124 if (FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
126 TRACE ("clientSetNetState : demands_attention");
127 data[i++] = display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION];
129 XChangeProperty (display_info->dpy, c->window,
130 display_info->atoms[NET_WM_STATE], XA_ATOM, 32,
131 PropModeReplace, (unsigned char *) data, i);
133 We also set GNOME hint here for consistency and convenience,
134 although the meaning of net_wm_state and win_state aren't the same.
136 setHint (display_info, c->window, WIN_STATE, c->win_state);
139 void
140 clientGetNetState (Client * c)
142 ScreenInfo *screen_info;
143 DisplayInfo *display_info;
144 int n_atoms;
145 Atom *atoms;
147 g_return_if_fail (c != NULL);
148 TRACE ("entering clientGetNetState");
149 TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
151 screen_info = c->screen_info;
152 display_info = screen_info->display_info;
153 atoms = NULL;
154 n_atoms = 0;
156 if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED))
158 if (FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
160 TRACE ("clientGetNetState : shaded from session management");
161 c->win_state |= WIN_STATE_SHADED;
162 FLAG_SET (c->flags, CLIENT_FLAG_SHADED);
164 if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
166 TRACE ("clientGetNetState : sticky from session management");
167 c->win_state |= WIN_STATE_STICKY;
168 FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
170 if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
172 TRACE ("clientGetNetState : maximized horiz from session management");
173 c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;
174 FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
176 if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
178 TRACE ("clientGetNetState : maximized vert from session management");
179 c->win_state |= WIN_STATE_MAXIMIZED_VERT;
180 FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
184 if (getAtomList (display_info, c->window, NET_WM_STATE, &atoms, &n_atoms))
186 int i;
187 TRACE ("clientGetNetState: %i atoms detected", n_atoms);
189 i = 0;
190 while (i < n_atoms)
192 if ((atoms[i] == display_info->atoms[NET_WM_STATE_SHADED]))
194 TRACE ("clientGetNetState : shaded");
195 c->win_state |= WIN_STATE_SHADED;
196 FLAG_SET (c->flags, CLIENT_FLAG_SHADED);
198 else if ((atoms[i] == display_info->atoms[NET_WM_STATE_STICKY]))
200 TRACE ("clientGetNetState : sticky");
201 c->win_state |= WIN_STATE_STICKY;
202 FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
204 else if ((atoms[i] == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
206 TRACE ("clientGetNetState : maximized horiz");
207 c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;
208 FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
210 else if ((atoms[i] == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
212 TRACE ("clientGetNetState : maximized vert");
213 c->win_state |= WIN_STATE_MAXIMIZED_VERT;
214 FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
216 else if ((atoms[i] == display_info->atoms[NET_WM_STATE_FULLSCREEN]))
218 if (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_ABOVE | CLIENT_FLAG_BELOW))
220 TRACE ("clientGetNetState : fullscreen");
221 FLAG_SET (c->flags, CLIENT_FLAG_FULLSCREEN);
224 else if ((atoms[i] == display_info->atoms[NET_WM_STATE_ABOVE]))
226 if (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_FULLSCREEN | CLIENT_FLAG_BELOW))
228 TRACE ("clientGetNetState : above");
229 FLAG_SET (c->flags, CLIENT_FLAG_ABOVE);
232 else if ((atoms[i] == display_info->atoms[NET_WM_STATE_BELOW]))
234 if (!FLAG_TEST_ALL (c->flags, CLIENT_FLAG_ABOVE | CLIENT_FLAG_FULLSCREEN))
236 TRACE ("clientGetNetState : below");
237 FLAG_SET (c->flags, CLIENT_FLAG_BELOW);
240 else if (atoms[i] == display_info->atoms[NET_WM_STATE_MODAL])
242 TRACE ("clientGetNetState : modal");
243 FLAG_SET (c->flags, CLIENT_FLAG_STATE_MODAL);
245 else if (atoms[i] == display_info->atoms[NET_WM_STATE_SKIP_PAGER])
247 TRACE ("clientGetNetState : skip_pager");
248 FLAG_SET (c->flags, CLIENT_FLAG_SKIP_PAGER);
250 else if (atoms[i] == display_info->atoms[NET_WM_STATE_SKIP_TASKBAR])
252 TRACE ("clientGetNetState : skip_taskbar");
253 FLAG_SET (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
255 else if (atoms[i] == display_info->atoms[NET_WM_STATE_HIDDEN])
257 TRACE ("clientGetNetState : state_hidden");
258 FLAG_SET (c->flags, CLIENT_FLAG_ICONIFIED);
260 else if (atoms[i] == display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION])
262 TRACE ("clientGetNetState : demands_attention");
263 FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
265 else
267 g_warning ("Unmanaged net_wm_state (window 0x%lx)", c->window);
270 ++i;
272 if (atoms)
274 XFree (atoms);
279 void
280 clientUpdateNetState (Client * c, XClientMessageEvent * ev)
282 ScreenInfo *screen_info;
283 DisplayInfo *display_info;
284 unsigned long action, mode;
285 Atom first;
286 Atom second;
288 g_return_if_fail (c != NULL);
289 TRACE ("entering clientUpdateNetState");
290 TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
292 screen_info = c->screen_info;
293 display_info = screen_info->display_info;
295 action = ev->data.l[0];
296 first = ev->data.l[1];
297 second = ev->data.l[2];
298 mode = 0;
300 if ((first == display_info->atoms[NET_WM_STATE_SHADED]) ||
301 (second == display_info->atoms[NET_WM_STATE_SHADED]))
303 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
305 clientShade (c);
307 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_SHADED))
309 clientUnshade (c);
311 else if (action == NET_WM_STATE_TOGGLE)
313 clientToggleShaded (c);
317 if ((first == display_info->atoms[NET_WM_STATE_STICKY]) ||
318 (second == display_info->atoms[NET_WM_STATE_STICKY]))
320 if (!clientIsValidTransientOrModal (c) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK))
322 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
324 clientStick (c, TRUE);
326 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
328 clientUnstick (c, TRUE);
330 else if (action == NET_WM_STATE_TOGGLE)
332 clientToggleSticky (c, TRUE);
334 frameDraw (c, FALSE);
338 if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
339 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
340 (first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
341 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
343 if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MAXIMIZE))
345 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
347 mode = 0;
348 if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
349 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
351 mode |= !FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) ? WIN_STATE_MAXIMIZED_HORIZ : 0;
353 if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
354 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
356 mode |= !FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) ? WIN_STATE_MAXIMIZED_VERT : 0;
358 clientToggleMaximized (c, mode, TRUE);
360 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
362 mode = 0;
363 if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
364 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
366 mode |= FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ) ? WIN_STATE_MAXIMIZED_HORIZ : 0;
368 if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
369 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
371 mode |= FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT) ? WIN_STATE_MAXIMIZED_VERT : 0;
373 clientToggleMaximized (c, mode, TRUE);
375 else if (action == NET_WM_STATE_TOGGLE)
377 mode = 0;
378 if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]) ||
379 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_HORZ]))
381 mode |= WIN_STATE_MAXIMIZED_HORIZ;
383 if ((first == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]) ||
384 (second == display_info->atoms[NET_WM_STATE_MAXIMIZED_VERT]))
386 mode |= WIN_STATE_MAXIMIZED_VERT;
388 clientToggleMaximized (c, mode, TRUE);
393 if ((first == display_info->atoms[NET_WM_STATE_MODAL]) ||
394 (second == display_info->atoms[NET_WM_STATE_MODAL]))
396 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL))
398 FLAG_SET (c->flags, CLIENT_FLAG_STATE_MODAL);
399 clientSetNetState (c);
400 clientWindowType (c);
402 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_STATE_MODAL))
404 FLAG_UNSET (c->flags, CLIENT_FLAG_STATE_MODAL);
405 clientSetNetState (c);
406 clientWindowType (c);
408 else if (action == NET_WM_STATE_TOGGLE)
410 FLAG_TOGGLE (c->flags, CLIENT_FLAG_STATE_MODAL);
411 clientSetNetState (c);
412 clientWindowType (c);
414 frameDraw (c, TRUE);
417 if ((first == display_info->atoms[NET_WM_STATE_FULLSCREEN]) ||
418 (second == display_info->atoms[NET_WM_STATE_FULLSCREEN]))
420 if (!clientIsValidTransientOrModal (c))
422 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
424 FLAG_SET (c->flags, CLIENT_FLAG_FULLSCREEN);
425 clientUpdateFullscreenState (c);
427 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
429 FLAG_UNSET (c->flags, CLIENT_FLAG_FULLSCREEN);
430 clientUpdateFullscreenState (c);
432 else if (action == NET_WM_STATE_TOGGLE)
434 FLAG_TOGGLE (c->flags, CLIENT_FLAG_FULLSCREEN);
435 clientUpdateFullscreenState (c);
440 if ((first == display_info->atoms[NET_WM_STATE_ABOVE]) ||
441 (second == display_info->atoms[NET_WM_STATE_ABOVE]))
443 if (!FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
445 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
447 FLAG_SET (c->flags, CLIENT_FLAG_ABOVE);
448 clientUpdateAboveState (c);
450 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
452 FLAG_UNSET (c->flags, CLIENT_FLAG_ABOVE);
453 clientUpdateAboveState (c);
455 else if (action == NET_WM_STATE_TOGGLE)
457 FLAG_TOGGLE (c->flags, CLIENT_FLAG_ABOVE);
458 clientUpdateAboveState (c);
463 if ((first == display_info->atoms[NET_WM_STATE_BELOW]) ||
464 (second == display_info->atoms[NET_WM_STATE_BELOW]))
466 if (!FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
468 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
470 compositorDamageWindow (display_info, c->frame);
471 FLAG_SET (c->flags, CLIENT_FLAG_BELOW);
472 clientUpdateBelowState (c);
474 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
476 compositorDamageWindow (display_info, c->frame);
477 FLAG_UNSET (c->flags, CLIENT_FLAG_BELOW);
478 clientUpdateBelowState (c);
480 else if (action == NET_WM_STATE_TOGGLE)
482 compositorDamageWindow (display_info, c->frame);
483 FLAG_TOGGLE (c->flags, CLIENT_FLAG_BELOW);
484 clientUpdateBelowState (c);
489 if ((first == display_info->atoms[NET_WM_STATE_SKIP_PAGER]) ||
490 (second == display_info->atoms[NET_WM_STATE_SKIP_PAGER]))
492 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_PAGER))
494 FLAG_SET (c->flags, CLIENT_FLAG_SKIP_PAGER);
495 clientSetNetState (c);
497 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_PAGER))
499 FLAG_UNSET (c->flags, CLIENT_FLAG_SKIP_PAGER);
500 clientSetNetState (c);
502 else if (action == NET_WM_STATE_TOGGLE)
504 FLAG_TOGGLE (c->flags, CLIENT_FLAG_SKIP_PAGER);
505 clientSetNetState (c);
509 if ((first == display_info->atoms[NET_WM_STATE_SKIP_TASKBAR]) ||
510 (second == display_info->atoms[NET_WM_STATE_SKIP_TASKBAR]))
512 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_TASKBAR))
514 FLAG_SET (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
515 clientSetNetState (c);
517 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_SKIP_TASKBAR))
519 FLAG_UNSET (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
520 clientSetNetState (c);
522 else if (action == NET_WM_STATE_TOGGLE)
524 FLAG_TOGGLE (c->flags, CLIENT_FLAG_SKIP_TASKBAR);
525 clientSetNetState (c);
527 frameDraw (c, TRUE);
530 if ((first == display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION]) ||
531 (second == display_info->atoms[NET_WM_STATE_DEMANDS_ATTENTION]))
533 if ((action == NET_WM_STATE_ADD) && !FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
535 /* Do not apply NET_WM_STATE_DEMANDS_ATTENTION if client is already focused */
536 if (c != clientGetFocusOrPending ())
538 FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
539 clientSetNetState (c);
542 else if ((action == NET_WM_STATE_REMOVE) && FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
544 FLAG_UNSET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
545 clientSetNetState (c);
547 else if (action == NET_WM_STATE_TOGGLE)
549 /* Do not apply NET_WM_STATE_DEMANDS_ATTENTION if client is already focused */
550 if (c != clientGetFocusOrPending () || !FLAG_TEST (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION))
552 FLAG_TOGGLE (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION);
553 clientSetNetState (c);
559 void
560 clientNetMoveResize (Client * c, XClientMessageEvent * ev)
562 ScreenInfo *screen_info;
563 DisplayInfo *display_info;
564 unsigned int button_mask;
565 int x_root, y_root, dx, dy, action, button;
566 int corner;
567 gboolean resize; /* true == resize, false == move */
568 XEvent *event;
570 g_return_if_fail (c != NULL);
571 TRACE ("entering clientNetMoveResize");
572 TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
574 screen_info = c->screen_info;
575 display_info = screen_info->display_info;
577 x_root = (int) ev->data.l[0];
578 y_root = (int) ev->data.l[1];
579 action = (int) ev->data.l[2];
580 button = (int) ev->data.l[3];
581 event = (XEvent *) ev;
583 if (button == 0)
585 button_mask = getMouseXY (screen_info, c->window, &dx, &dy);
586 if (button_mask & Button1Mask)
588 button = Button1;
590 else if (button_mask & Button2Mask)
592 button = Button2;
594 else if (button_mask & Button3Mask)
596 button = Button3;
598 else
600 g_warning ("Could not determine the mouse button used");
601 return;
605 corner = CORNER_BOTTOM_RIGHT;
606 resize = TRUE;
608 event->xbutton.button = button;
609 event->xbutton.x_root = event->xkey.x_root = x_root;
610 event->xbutton.y_root = event->xkey.y_root = y_root;
611 event->xbutton.time = event->xkey.time = myDisplayGetCurrentTime (display_info);
613 switch (action)
615 /* Keyboard */
616 case NET_WM_MOVERESIZE_SIZE_KEYBOARD:
617 event->type = KeyPress;
618 corner = CORNER_BOTTOM_RIGHT;
619 resize = TRUE; /* Resize */
620 break;
621 case NET_WM_MOVERESIZE_MOVE_KEYBOARD:
622 event->type = KeyPress;
623 resize = FALSE; /* Move */
624 break;
626 /* Sides */
627 case NET_WM_MOVERESIZE_SIZE_TOP:
628 event->type = ButtonPress;
629 corner = CORNER_COUNT + SIDE_TOP;
630 resize = TRUE; /* Resize */
631 break;
632 case NET_WM_MOVERESIZE_SIZE_BOTTOM:
633 event->type = ButtonPress;
634 corner = CORNER_COUNT + SIDE_BOTTOM;
635 resize = TRUE; /* Resize */
636 break;
637 case NET_WM_MOVERESIZE_SIZE_RIGHT:
638 event->type = ButtonPress;
639 corner = CORNER_COUNT + SIDE_RIGHT;
640 resize = TRUE; /* Resize */
641 break;
642 case NET_WM_MOVERESIZE_SIZE_LEFT:
643 event->type = ButtonPress;
644 corner = CORNER_COUNT + SIDE_LEFT;
645 resize = TRUE; /* Resize */
646 break;
648 /* Corners */
649 case NET_WM_MOVERESIZE_SIZE_TOPLEFT:
650 event->type = ButtonPress;
651 corner = CORNER_TOP_LEFT;
652 resize = TRUE; /* Resize */
653 break;
654 case NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
655 event->type = ButtonPress;
656 corner = CORNER_TOP_RIGHT;
657 resize = TRUE; /* Resize */
658 break;
659 case NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
660 event->type = ButtonPress;
661 corner = CORNER_BOTTOM_LEFT;
662 resize = TRUE; /* Resize */
663 break;
664 case NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
665 event->type = ButtonPress;
666 corner = CORNER_BOTTOM_RIGHT;
667 resize = TRUE; /* Resize */
668 break;
669 case NET_WM_MOVERESIZE_MOVE:
670 default:
671 event->type = ButtonPress;
672 resize = FALSE; /* Move */
673 break;
676 if (!FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
678 if (resize && FLAG_TEST_ALL (c->xfwm_flags, XFWM_FLAG_HAS_RESIZE | XFWM_FLAG_IS_RESIZABLE))
680 clientResize (c, corner, event);
682 else if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_MOVE))
684 clientMove (c, event);
689 void
690 clientUpdateFullscreenState (Client * c)
692 ScreenInfo *screen_info;
693 DisplayInfo *display_info;
694 XWindowChanges wc;
695 int layer;
697 g_return_if_fail (c != NULL);
698 TRACE ("entering clientUpdateFullscreenState");
699 TRACE ("Update fullscreen state for client \"%s\" (0x%lx)", c->name, c->window);
701 screen_info = c->screen_info;
702 display_info = screen_info->display_info;
704 if (FLAG_TEST (c->flags, CLIENT_FLAG_FULLSCREEN))
706 GdkRectangle rect;
707 gint monitor_nbr;
708 int cx, cy;
710 cx = frameX (c) + (frameWidth (c) / 2);
711 cy = frameY (c) + (frameHeight (c) / 2);
713 monitor_nbr = find_monitor_at_point (c->screen_info->gscr, cx, cy);
714 gdk_screen_get_monitor_geometry (c->screen_info->gscr, monitor_nbr, &rect);
716 c->fullscreen_old_x = c->x;
717 c->fullscreen_old_y = c->y;
718 c->fullscreen_old_width = c->width;
719 c->fullscreen_old_height = c->height;
720 c->fullscreen_old_layer = c->win_layer;
722 wc.x = rect.x;
723 wc.y = rect.y;
724 wc.width = rect.width;
725 wc.height = rect.height;
726 layer = WIN_LAYER_ABOVE_DOCK;
728 else
730 wc.x = c->fullscreen_old_x;
731 wc.y = c->fullscreen_old_y;
732 wc.width = c->fullscreen_old_width;
733 wc.height = c->fullscreen_old_height;
734 layer = c->fullscreen_old_layer;
736 clientSetNetState (c);
737 if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
740 For some reason, the configure can generate EnterNotify events
741 on lower windows, causing a nasty race cond with apps trying to
742 grab focus in focus follow mouse mode. Grab the pointer to
743 avoid these effects
745 myScreenGrabPointer (c->screen_info, EnterWindowMask, None, myDisplayGetCurrentTime (display_info));
746 clientConfigure (c, &wc, CWX | CWY | CWWidth | CWHeight, CFG_FORCE_REDRAW);
747 myScreenUngrabPointer (c->screen_info);
749 else
751 c->x = wc.x;
752 c->y = wc.y;
753 c->height = wc.height;
754 c->width = wc.width;
756 clientSetLayer (c, layer);
758 /* Fullscreen has no decoration at all, update NET_FRAME_EXTENTS accordingly */
759 setNetFrameExtents (display_info,
760 c->window,
761 frameTop (c),
762 frameLeft (c),
763 frameRight (c),
764 frameBottom (c));
768 void
769 clientGetNetWmType (Client * c)
771 ScreenInfo *screen_info;
772 DisplayInfo *display_info;
773 int n_atoms;
774 Atom *atoms;
775 int i;
777 g_return_if_fail (c != NULL);
778 TRACE ("entering clientGetNetWmType");
779 TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
781 screen_info = c->screen_info;
782 display_info = screen_info->display_info;
783 n_atoms = 0;
784 atoms = NULL;
786 if (!getAtomList (display_info, c->window, NET_WM_WINDOW_TYPE, &atoms, &n_atoms))
788 switch (c->win_layer)
790 case WIN_LAYER_DESKTOP:
791 c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_DESKTOP];
792 break;
793 case WIN_LAYER_DOCK:
794 c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_DOCK];
795 break;
796 case WIN_LAYER_NORMAL:
797 c->type_atom = display_info->atoms[NET_WM_WINDOW_TYPE_NORMAL];
798 break;
799 default:
800 c->type_atom = None;
801 break;
804 else
806 i = 0;
807 while (i < n_atoms)
809 if ((atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_DESKTOP]) ||
810 (atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_DOCK]) ||
811 (atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_TOOLBAR]) ||
812 (atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_MENU]) ||
813 (atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_DIALOG]) ||
814 (atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_NORMAL]) ||
815 (atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_UTILITY]) ||
816 (atoms[i] == display_info->atoms[NET_WM_WINDOW_TYPE_SPLASH]))
818 c->type_atom = atoms[i];
819 break;
821 ++i;
823 if (atoms)
825 XFree (atoms);
828 clientWindowType (c);
831 void
832 clientGetInitialNetWmDesktop (Client * c)
834 ScreenInfo *screen_info;
835 DisplayInfo *display_info;
836 Client *c2;
837 long val;
839 g_return_if_fail (c != NULL);
840 TRACE ("entering clientGetInitialNetWmDesktop");
841 TRACE ("client \"%s\" (0x%lx)", c->name, c->window);
843 screen_info = c->screen_info;
844 display_info = screen_info->display_info;
845 val = 0;
847 if (!FLAG_TEST (c->xfwm_flags, XFWM_FLAG_SESSION_MANAGED)
848 && !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET))
850 FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
851 c->win_workspace = c->screen_info->current_ws;
853 if (getHint (display_info, c->window, NET_WM_DESKTOP, &val))
855 TRACE ("atom net_wm_desktop detected");
856 if (val == (int) ALL_WORKSPACES)
858 if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
860 TRACE ("atom net_wm_desktop specifies window \"%s\" is sticky", c->name);
861 FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
862 c->win_state |= WIN_STATE_STICKY;
864 c->win_workspace = c->screen_info->current_ws;
866 else
868 TRACE ("atom net_wm_desktop specifies window \"%s\" is on desk %i", c->name, (int) val);
869 c->win_workspace = (int) val;
871 FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
873 else if (getHint (display_info, c->window, WIN_WORKSPACE, &val))
875 TRACE ("atom win_workspace specifies window \"%s\" is on desk %i", c->name, (int) val);
876 c->win_workspace = (int) val;
877 FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
880 /* This is to make sure that transient are shown with their "ancestor" window */
881 if (!FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
883 c2 = clientGetTransient (c);
884 if (c2)
886 FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
887 c->win_workspace = c2->win_workspace;
888 if (FLAG_TEST (c2->flags, CLIENT_FLAG_STICKY))
890 FLAG_SET (c->flags, CLIENT_FLAG_STICKY);
891 c->win_state |= WIN_STATE_STICKY;
892 c->win_workspace = c->screen_info->current_ws;
897 TRACE ("initial desktop for window \"%s\" is %i", c->name, c->win_workspace);
898 if (c->win_workspace > c->screen_info->workspace_count - 1)
900 TRACE ("value off limits, using %i instead", c->screen_info->workspace_count - 1);
901 c->win_workspace = c->screen_info->workspace_count - 1;
902 FLAG_SET (c->xfwm_flags, XFWM_FLAG_WORKSPACE_SET);
904 TRACE ("initial desktop for window \"%s\" is %i", c->name, c->win_workspace);
905 setHint (display_info, c->window, WIN_WORKSPACE, c->win_workspace);
906 if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY))
908 setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) ALL_WORKSPACES);
910 else
912 setHint (display_info, c->window, NET_WM_DESKTOP, (unsigned long) c->win_workspace);
916 void
917 clientSetNetClientList (ScreenInfo * screen_info, Atom a, GList * list)
919 Window *listw;
920 Window *index_dest;
921 GList *index_src;
922 gint size, i;
924 TRACE ("entering clientSetNetClientList");
926 size = g_list_length (list);
927 if (size < 1)
929 XDeleteProperty (myScreenGetXDisplay (screen_info), screen_info->xroot, a);
930 return;
933 listw = g_new (Window, size + 1);
934 if (listw)
936 TRACE ("%i windows in list for %i clients", size, screen_info->client_count);
937 for (i = 0, index_dest = listw, index_src = list; i < size;
938 i++, index_dest++, index_src = g_list_next (index_src))
940 Client *c = (Client *) index_src->data;
941 *index_dest = c->window;
943 XChangeProperty (myScreenGetXDisplay (screen_info), screen_info->xroot, a, XA_WINDOW, 32, PropModeReplace,
944 (unsigned char *) listw, size);
945 g_free (listw);
949 gboolean
950 clientValidateNetStrut (Client * c)
952 ScreenInfo *screen_info;
953 gboolean valid;
954 int max_value;
955 int i;
957 g_return_val_if_fail (c != NULL, TRUE);
958 TRACE ("entering clientValidateNetStrut for \"%s\" (0x%lx)", c->name, c->window);
959 screen_info = c->screen_info;
960 max_value = MIN (screen_info->width, screen_info->height) / 4;
961 valid = TRUE;
963 for (i = 0; i < 4; i++)
965 if (c->struts[i] > max_value)
967 g_warning ("Strut value for application window 0x%lx changed from %d to %d", c->window, c->struts[i], max_value);
968 c->struts[i] = max_value;
969 valid = FALSE;
973 return valid;
976 gboolean
977 clientGetNetStruts (Client * c)
979 ScreenInfo *screen_info;
980 DisplayInfo *display_info;
981 unsigned long old_flags, new_flags;
982 int old_struts[STRUTS_SIZE];
983 gulong *struts;
984 int nitems;
985 int i;
987 g_return_val_if_fail (c != NULL, FALSE);
988 TRACE ("entering clientGetNetStruts for \"%s\" (0x%lx)", c->name, c->window);
990 screen_info = c->screen_info;
991 display_info = screen_info->display_info;
992 struts = NULL;
994 /* Save old values */
995 old_flags = c->flags & (CLIENT_FLAG_HAS_STRUT | CLIENT_FLAG_HAS_STRUT_PARTIAL);
996 for (i = 0; i < STRUTS_SIZE; i++)
998 old_struts[i] = c->struts[i];
999 c->struts[i] = 0;
1001 FLAG_UNSET (c->flags, CLIENT_FLAG_HAS_STRUT);
1002 FLAG_UNSET (c->flags, CLIENT_FLAG_HAS_STRUT_PARTIAL);
1004 if (getCardinalList (display_info, c->window, NET_WM_STRUT_PARTIAL, &struts, &nitems))
1006 if (nitems != STRUTS_SIZE)
1008 if (struts)
1010 XFree (struts);
1012 /* Restore old values */
1013 if (old_flags)
1015 FLAG_SET (c->flags, old_flags);
1016 for (i = 0; i < STRUTS_SIZE; i++)
1018 c->struts[i] = old_struts[i];
1021 return FALSE;
1024 FLAG_SET (c->flags, CLIENT_FLAG_HAS_STRUT);
1025 FLAG_SET (c->flags, CLIENT_FLAG_HAS_STRUT_PARTIAL);
1026 for (i = 0; i < STRUTS_SIZE; i++)
1028 c->struts[i] = (int) struts[i];
1031 XFree (struts);
1033 else if (getCardinalList (display_info, c->window, NET_WM_STRUT, &struts, &nitems))
1035 if (nitems != 4)
1037 if (struts)
1039 XFree (struts);
1041 /* Restore old values */
1042 if (old_flags)
1044 FLAG_SET (c->flags, old_flags);
1045 for (i = 0; i < STRUTS_SIZE; i++)
1047 c->struts[i] = old_struts[i];
1050 return FALSE;
1053 FLAG_SET (c->flags, CLIENT_FLAG_HAS_STRUT);
1054 for (i = 0; i < 4; i++)
1056 c->struts[i] = (int) struts[i];
1058 for (i = 4; i < STRUTS_SIZE; i++)
1060 c->struts[i] = 0;
1062 /* Fill(in values as for partial struts */
1063 c->struts[STRUTS_TOP_START_X] = c->struts[STRUTS_BOTTOM_START_X] = 0;
1064 c->struts[STRUTS_TOP_END_X] = c->struts[STRUTS_BOTTOM_END_X] =
1065 c->screen_info->width;
1066 c->struts[STRUTS_LEFT_START_Y] = c->struts[STRUTS_RIGHT_START_Y] = 0;
1067 c->struts[STRUTS_LEFT_END_Y] = c->struts[STRUTS_RIGHT_END_Y] =
1068 c->screen_info->height;
1070 XFree (struts);
1073 if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STRUT))
1075 clientValidateNetStrut (c);
1078 /* check for a change in struts flags */
1079 new_flags = c->flags & (CLIENT_FLAG_HAS_STRUT | CLIENT_FLAG_HAS_STRUT_PARTIAL);
1080 if (old_flags != new_flags)
1082 return TRUE;
1085 /* Flags haven't changed, check values */
1086 if (new_flags)
1088 for (i = 0; i < STRUTS_SIZE; i++)
1090 if (old_struts[i] != c->struts[i])
1092 return TRUE;
1097 return FALSE;
1100 void
1101 clientSetNetActions (Client * c)
1103 ScreenInfo *screen_info;
1104 DisplayInfo *display_info;
1105 Atom atoms[6];
1106 int i;
1108 g_return_if_fail (c != NULL);
1109 TRACE ("entering clientSetNetActions");
1111 screen_info = c->screen_info;
1112 display_info = screen_info->display_info;
1113 i = 0;
1115 atoms[i++] = display_info->atoms[NET_WM_ACTION_CLOSE];
1116 if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
1118 atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_HORZ];
1119 atoms[i++] = display_info->atoms[NET_WM_ACTION_MAXIMIZE_VERT];
1121 if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_STICK))
1123 atoms[i++] = display_info->atoms[NET_WM_ACTION_CHANGE_DESKTOP];
1124 atoms[i++] = display_info->atoms[NET_WM_ACTION_STICK];
1126 if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_HAS_BORDER))
1128 atoms[i++] = display_info->atoms[NET_WM_ACTION_SHADE];
1130 XChangeProperty (clientGetXDisplay (c), c->window, display_info->atoms[NET_WM_ALLOWED_ACTIONS],
1131 XA_ATOM, 32, PropModeReplace, (unsigned char *) atoms, i);
1134 void
1135 clientWindowType (Client * c)
1137 ScreenInfo *screen_info;
1138 DisplayInfo *display_info;
1139 netWindowType old_type;
1141 g_return_if_fail (c != NULL);
1142 TRACE ("entering clientWindowType");
1143 TRACE ("type for client \"%s\" (0x%lx)", c->name, c->window);
1145 screen_info = c->screen_info;
1146 display_info = screen_info->display_info;
1148 old_type = c->type;
1149 c->initial_layer = c->win_layer;
1150 if (c->type_atom != None)
1152 if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_DESKTOP])
1154 TRACE ("atom net_wm_window_type_desktop detected");
1155 c->type = WINDOW_DESKTOP;
1156 c->initial_layer = WIN_LAYER_DESKTOP;
1157 c->win_state |= WIN_STATE_STICKY;
1158 FLAG_SET (c->flags,
1159 CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_STICKY |
1160 CLIENT_FLAG_SKIP_TASKBAR);
1161 FLAG_UNSET (c->xfwm_flags,
1162 XFWM_FLAG_HAS_RESIZE | XFWM_FLAG_HAS_MOVE |
1163 XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE |
1164 XFWM_FLAG_HAS_MENU | XFWM_FLAG_HAS_STICK |
1165 XFWM_FLAG_HAS_BORDER);
1167 else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_DOCK])
1169 TRACE ("atom net_wm_window_type_dock detected");
1170 c->type = WINDOW_DOCK;
1171 c->initial_layer = WIN_LAYER_DOCK;
1172 FLAG_SET (c->flags,
1173 CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
1174 FLAG_UNSET (c->xfwm_flags,
1175 XFWM_FLAG_HAS_BORDER | XFWM_FLAG_HAS_MOVE |
1176 XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE |
1177 XFWM_FLAG_HAS_MENU);
1179 else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_TOOLBAR])
1181 TRACE ("atom net_wm_window_type_toolbar detected");
1182 c->type = WINDOW_TOOLBAR;
1183 c->initial_layer = WIN_LAYER_NORMAL;
1184 FLAG_SET (c->flags,
1185 CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
1186 FLAG_UNSET (c->xfwm_flags,
1187 XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE);
1189 else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_MENU])
1191 TRACE ("atom net_wm_window_type_menu detected");
1192 c->type = WINDOW_MENU;
1193 c->initial_layer = WIN_LAYER_NORMAL;
1194 /* The policy here is unclear :
1195 http://mail.gnome.org/archives/wm-spec-list/2002-May/msg00001.html
1196 As it seems, GNOME and KDE don't treat menu the same way...
1198 FLAG_SET (c->flags,
1199 CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
1200 FLAG_UNSET (c->xfwm_flags,
1201 XFWM_FLAG_HAS_HIDE | XFWM_FLAG_HAS_MAXIMIZE);
1203 else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_DIALOG])
1205 TRACE ("atom net_wm_window_type_dialog detected");
1206 c->type = WINDOW_DIALOG;
1207 c->initial_layer = WIN_LAYER_NORMAL;
1208 /* Treat DIALOG without transient_for set as transient for group */
1209 if (c->transient_for == None)
1211 c->transient_for = c->screen_info->xroot;
1214 else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_NORMAL])
1216 TRACE ("atom net_wm_window_type_normal detected");
1217 c->type = WINDOW_NORMAL;
1218 c->initial_layer = WIN_LAYER_NORMAL;
1220 else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_UTILITY])
1222 TRACE ("atom net_wm_window_type_utility detected");
1223 FLAG_SET (c->flags,
1224 CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
1225 c->type = WINDOW_UTILITY;
1226 c->initial_layer = WIN_LAYER_NORMAL;
1227 /* Treat UTILITY without transient_for set as transient for group */
1228 if (c->transient_for == None)
1230 c->transient_for = c->screen_info->xroot;
1233 else if (c->type_atom == display_info->atoms[NET_WM_WINDOW_TYPE_SPLASH])
1235 TRACE ("atom net_wm_window_type_splash detected");
1236 c->type = WINDOW_SPLASHSCREEN;
1237 c->initial_layer = WIN_LAYER_NORMAL;
1238 FLAG_SET (c->flags,
1239 CLIENT_FLAG_SKIP_PAGER | CLIENT_FLAG_SKIP_TASKBAR);
1240 FLAG_UNSET (c->xfwm_flags,
1241 XFWM_FLAG_HAS_BORDER | XFWM_FLAG_HAS_HIDE |
1242 XFWM_FLAG_HAS_MENU | XFWM_FLAG_HAS_MOVE |
1243 XFWM_FLAG_HAS_RESIZE);
1246 else
1248 TRACE ("no \"net\" atom detected");
1249 c->type = UNSET;
1250 c->initial_layer = c->win_layer;
1253 if (clientIsValidTransientOrModal (c))
1255 Client *c2;
1257 TRACE ("Window \"%s\" is a transient or a modal", c->name);
1259 c2 = clientGetHighestTransientOrModalFor (c);
1260 if ((c2) && (c->initial_layer < c2->win_layer))
1262 c->initial_layer = c2->win_layer;
1263 TRACE ("Applied layer is %i", c->initial_layer);
1265 FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_HAS_HIDE);
1267 if ((old_type != c->type) || (c->initial_layer != c->win_layer))
1269 TRACE ("setting layer %i", c->initial_layer);
1270 clientSetNetState (c);
1271 clientSetLayer (c, c->initial_layer);
1275 void
1276 clientUpdateAboveState (Client * c)
1278 int layer;
1280 g_return_if_fail (c != NULL);
1281 TRACE ("entering clientUpdateAboveState");
1282 TRACE ("Update above state for client \"%s\" (0x%lx)", c->name, c->window);
1284 if (FLAG_TEST (c->flags, CLIENT_FLAG_ABOVE))
1286 layer = WIN_LAYER_ABOVE_DOCK;
1288 else
1290 layer = c->initial_layer;
1292 clientSetNetState (c);
1293 clientSetLayer (c, layer);
1296 void
1297 clientUpdateBelowState (Client * c)
1299 int layer;
1301 g_return_if_fail (c != NULL);
1302 TRACE ("entering clientUpdateBelowState");
1303 TRACE ("Update below state for client \"%s\" (0x%lx)", c->name, c->window);
1305 if (FLAG_TEST (c->flags, CLIENT_FLAG_BELOW))
1307 layer = WIN_LAYER_BELOW;
1309 else
1311 layer = c->initial_layer;
1313 clientSetNetState (c);
1314 clientSetLayer (c, layer);