2 * Copyright (C) 2003-2009 Kim Woelders
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies of the Software, its documentation and marketing & publicity
13 * materials, and acknowledgment shall be given in the documentation, materials
14 * and software packages that this Software was used.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * Extended Window Manager Hints.
28 #include "e16-ecore_hints.h"
33 * _NET_WM_MOVERESIZE client message actions
35 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
36 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
37 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
38 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
39 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
40 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
41 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
42 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
43 #define _NET_WM_MOVERESIZE_MOVE 8
44 #define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9
45 #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10
46 #define _NET_WM_MOVERESIZE_CANCEL 11
48 /* Window state property change actions */
49 #define _NET_WM_STATE_REMOVE 0
50 #define _NET_WM_STATE_ADD 1
51 #define _NET_WM_STATE_TOGGLE 2
53 /* Source indication */
54 #define _NET_WM_SOURCE_UNKNOWN 0
55 #define _NET_WM_SOURCE_APP 1
56 #define _NET_WM_SOURCE_USER 2
58 #define OPSRC(src) (((src) == _NET_WM_SOURCE_USER) ? _NET_WM_SOURCE_USER : _NET_WM_SOURCE_APP)
61 * Set/clear Atom in list
64 atom_list_set(Ecore_X_Atom * atoms, int size, int *count, Ecore_X_Atom atom,
71 /* Check if atom is in list or not (+get index) */
72 for (i = 0; i < n; i++)
79 /* Add it (if space left) */
84 else if (!set && in_list)
87 atoms[i] = atoms[--n];
93 * Initialize EWMH stuff
96 EWMH_Init(Window win_wm_check)
98 Ecore_X_Atom atom_list[64];
102 ecore_x_netwm_init();
107 atom_list[atom_count++] = ECORE_X_ATOM_NET_SUPPORTED;
108 atom_list[atom_count++] = ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK;
110 atom_list[atom_count++] = ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS;
111 atom_list[atom_count++] = ECORE_X_ATOM_NET_DESKTOP_GEOMETRY;
112 atom_list[atom_count++] = ECORE_X_ATOM_NET_DESKTOP_NAMES;
113 atom_list[atom_count++] = ECORE_X_ATOM_NET_CURRENT_DESKTOP;
114 atom_list[atom_count++] = ECORE_X_ATOM_NET_DESKTOP_VIEWPORT;
115 atom_list[atom_count++] = ECORE_X_ATOM_NET_WORKAREA;
116 atom_list[atom_count++] = ECORE_X_ATOM_NET_VIRTUAL_ROOTS;
117 atom_list[atom_count++] = ECORE_X_ATOM_NET_SHOWING_DESKTOP;
119 atom_list[atom_count++] = ECORE_X_ATOM_NET_ACTIVE_WINDOW;
120 atom_list[atom_count++] = ECORE_X_ATOM_NET_CLIENT_LIST;
121 atom_list[atom_count++] = ECORE_X_ATOM_NET_CLIENT_LIST_STACKING;
123 atom_list[atom_count++] = ECORE_X_ATOM_NET_CLOSE_WINDOW;
124 atom_list[atom_count++] = ECORE_X_ATOM_NET_MOVERESIZE_WINDOW;
125 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_MOVERESIZE;
127 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_NAME;
128 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ICON_NAME;
129 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_DESKTOP;
131 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE;
132 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
133 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
134 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
135 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
136 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
137 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
138 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
139 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
141 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE;
142 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_MODAL;
143 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_STICKY;
144 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
145 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
146 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_SHADED;
147 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
148 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
149 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
150 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
151 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_ABOVE;
152 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_BELOW;
153 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
155 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS;
156 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_MOVE;
157 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
158 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
159 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_SHADE;
160 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_STICK;
161 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
162 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
163 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
164 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
165 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
166 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
167 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_ACTION_BELOW;
169 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STRUT_PARTIAL;
170 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_STRUT;
172 atom_list[atom_count++] = ECORE_X_ATOM_NET_FRAME_EXTENTS;
173 atom_list[atom_count++] = ECORE_X_ATOM_NET_WM_WINDOW_OPACITY;
175 ecore_x_window_prop_atom_set(WinGetXwin(VROOT),
176 ECORE_X_ATOM_NET_SUPPORTED, atom_list,
179 /* Set WM info properties */
180 ecore_x_netwm_wm_identify(WinGetXwin(VROOT), win_wm_check, e_wm_name);
188 EWMH_SetDesktopCount(void)
190 ecore_x_netwm_desk_count_set(WinGetXwin(VROOT), DesksGetNumber());
194 EWMH_SetDesktopRoots(void)
199 n_desks = DesksGetNumber();
200 wl = EMALLOC(Ecore_X_Window, n_desks);
204 for (i = 0; i < n_desks; i++)
205 wl[i] = EoGetXwin(DeskGet(i));
207 ecore_x_netwm_desk_roots_set(WinGetXwin(VROOT), wl, n_desks);
213 EWMH_SetDesktopNames(void)
215 /* Fall back to defaults */
216 ecore_x_netwm_desk_names_set(WinGetXwin(VROOT), NULL, DesksGetNumber());
220 EWMH_SetDesktopSize(void)
224 DesksGetAreaSize(&ax, &ay);
225 ecore_x_netwm_desk_size_set(WinGetXwin(VROOT), ax * WinGetW(VROOT),
226 ay * WinGetH(VROOT));
230 EWMH_SetWorkArea(void)
232 unsigned int *p_coord;
233 int n_coord, i, n_desks;
235 n_desks = DesksGetNumber();
236 n_coord = 4 * n_desks;
237 p_coord = EMALLOC(unsigned int, n_coord);
242 for (i = 0; i < n_desks; i++)
245 p_coord[4 * i + 1] = 0;
246 p_coord[4 * i + 2] = WinGetW(VROOT);
247 p_coord[4 * i + 3] = WinGetH(VROOT);
250 ecore_x_netwm_desk_workareas_set(WinGetXwin(VROOT), p_coord, n_desks);
256 EWMH_SetCurrentDesktop(void)
258 ecore_x_netwm_desk_current_set(WinGetXwin(VROOT), DesksGetCurrentNum());
262 EWMH_SetDesktopViewport(void)
264 unsigned int *p_coord;
265 int n_coord, i, ax, ay, n_desks;
267 n_desks = DesksGetNumber();
268 n_coord = 2 * n_desks;
269 p_coord = EMALLOC(unsigned int, n_coord);
274 for (i = 0; i < n_desks; i++)
276 DeskGetArea(DeskGet(i), &ax, &ay);
277 p_coord[2 * i] = ax * WinGetW(VROOT);
278 p_coord[2 * i + 1] = ay * WinGetH(VROOT);
281 ecore_x_netwm_desk_viewports_set(WinGetXwin(VROOT), p_coord, n_desks);
287 EWMH_SetShowingDesktop(int on)
289 ecore_x_netwm_showing_desktop_set(WinGetXwin(VROOT), on);
297 EWMH_SetClientList(void)
304 lst = EwinListOrderGet(&num);
307 wl = EMALLOC(Ecore_X_Window, num);
308 for (i = 0; i < num; i++)
309 wl[i] = EwinGetClientXwin(lst[i]);
310 ecore_x_netwm_client_list_set(WinGetXwin(VROOT), wl, num);
315 ecore_x_netwm_client_list_set(WinGetXwin(VROOT), NULL, 0);
320 EWMH_SetClientStacking(void)
327 lst = EwinListStackGet(&num);
330 wl = EMALLOC(Ecore_X_Window, num);
331 for (i = 0; i < num; i++)
332 wl[i] = EwinGetClientXwin(lst[num - i - 1]);
333 ecore_x_netwm_client_list_stacking_set(WinGetXwin(VROOT), wl, num);
338 ecore_x_netwm_client_list_stacking_set(WinGetXwin(VROOT), NULL, 0);
343 EWMH_SetActiveWindow(Window win)
345 static Window win_last_set = None;
347 if (win == win_last_set)
350 ecore_x_netwm_client_active_set(WinGetXwin(VROOT), win);
355 * Functions that set X11-properties from E-window internals
359 EWMH_SetWindowName(Window win, const char *name)
363 str = EstrInt2Enc(name, 1);
364 ecore_x_netwm_name_set(win, str);
365 EstrInt2EncFree(str, 1);
369 EWMH_SetWindowDesktop(const EWin * ewin)
373 if (EoIsSticky(ewin))
376 val = EoGetDeskNum(ewin);
377 ecore_x_netwm_desktop_set(EwinGetClientXwin(ewin), val);
381 EWMH_SetWindowState(const EWin * ewin)
383 Ecore_X_Atom atom_list[64];
384 int len = sizeof(atom_list) / sizeof(Ecore_X_Atom);
388 atom_list_set(atom_list, len, &atom_count, ECORE_X_ATOM_NET_WM_STATE_MODAL,
390 atom_list_set(atom_list, len, &atom_count, ECORE_X_ATOM_NET_WM_STATE_STICKY,
392 atom_list_set(atom_list, len, &atom_count, ECORE_X_ATOM_NET_WM_STATE_SHADED,
394 atom_list_set(atom_list, len, &atom_count,
395 ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR,
396 ewin->props.skip_ext_task);
397 atom_list_set(atom_list, len, &atom_count, ECORE_X_ATOM_NET_WM_STATE_HIDDEN,
398 ewin->state.iconified || ewin->state.shaded);
399 atom_list_set(atom_list, len, &atom_count,
400 ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT,
401 ewin->state.maximized_vert);
402 atom_list_set(atom_list, len, &atom_count,
403 ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ,
404 ewin->state.maximized_horz);
405 atom_list_set(atom_list, len, &atom_count,
406 ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN, ewin->state.fullscreen);
407 atom_list_set(atom_list, len, &atom_count,
408 ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER,
409 ewin->props.skip_ext_pager);
410 atom_list_set(atom_list, len, &atom_count, ECORE_X_ATOM_NET_WM_STATE_ABOVE,
411 EoGetLayer(ewin) >= 6);
412 atom_list_set(atom_list, len, &atom_count, ECORE_X_ATOM_NET_WM_STATE_BELOW,
413 EoGetLayer(ewin) <= 2);
414 atom_list_set(atom_list, len, &atom_count,
415 ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION,
416 ewin->state.attention);
418 ecore_x_window_prop_atom_set(EwinGetClientXwin(ewin),
419 ECORE_X_ATOM_NET_WM_STATE, atom_list,
424 EWMH_SetWindowBorder(const EWin * ewin)
432 EwinBorderGetSize(ewin, &bl, &br, &bt, &bb);
433 val[0] = (unsigned int)bl;
434 val[1] = (unsigned int)br;
435 val[2] = (unsigned int)bt;
436 val[3] = (unsigned int)bb;
439 val[0] = val[1] = val[2] = val[3] = 0;
441 ecore_x_window_prop_card32_set(EwinGetClientXwin(ewin),
442 ECORE_X_ATOM_NET_FRAME_EXTENTS, val, 4);
446 EWMH_SetWindowOpacity(const EWin * ewin)
448 ecore_x_netwm_opacity_set(EwinGetClientXwin(ewin), ewin->ewmh.opacity);
449 ecore_x_netwm_opacity_set(EoGetXwin(ewin), ewin->ewmh.opacity);
453 * Functions that set E-window internals from X11-properties
457 EWMH_GetWindowName(EWin * ewin)
461 _EFREE(ewin->ewmh.wm_name);
463 ecore_x_netwm_name_get(EwinGetClientXwin(ewin), &val);
466 ewin->ewmh.wm_name = EstrUtf82Int(val, 0);
469 EwinChange(ewin, EWIN_CHANGE_NAME);
473 EWMH_GetWindowIconName(EWin * ewin)
477 _EFREE(ewin->ewmh.wm_icon_name);
479 ecore_x_netwm_icon_name_get(EwinGetClientXwin(ewin), &val);
482 ewin->ewmh.wm_icon_name = EstrUtf82Int(val, 0);
485 EwinChange(ewin, EWIN_CHANGE_ICON_NAME);
489 EWMH_GetWindowDesktop(EWin * ewin)
494 num = ecore_x_netwm_desktop_get(EwinGetClientXwin(ewin), &desk);
498 if (desk == 0xFFFFFFFF)
500 /* It is possible to distinguish between "sticky" and "on all desktops". */
502 EoSetSticky(ewin, 1);
506 EoSetDesk(ewin, DeskGet(desk));
507 EoSetSticky(ewin, 0);
509 EwinChange(ewin, EWIN_CHANGE_DESKTOP);
513 EWMH_GetWindowState(EWin * ewin)
515 Ecore_X_Atom *p_atoms, atom;
518 n_atoms = ecore_x_window_prop_atom_list_get(EwinGetClientXwin(ewin),
519 ECORE_X_ATOM_NET_WM_STATE,
524 /* We must clear/set all according to not present/present */
525 /* EoSetSticky(ewin, 0); Do not override if set via _NET_WM_DESKTOP */
526 ewin->state.shaded = 0;
527 ewin->state.modal = 0;
528 ewin->props.skip_ext_task = ewin->props.skip_ext_pager = 0;
529 ewin->state.maximized_horz = ewin->state.maximized_vert = 0;
530 ewin->state.fullscreen = ewin->state.attention = 0;
531 /* ewin->layer = No ... TBD */
533 for (i = 0; i < n_atoms; i++)
536 if (atom == ECORE_X_ATOM_NET_WM_STATE_MODAL)
537 ewin->state.modal = 1;
538 else if (atom == ECORE_X_ATOM_NET_WM_STATE_STICKY)
539 EoSetSticky(ewin, 1);
540 else if (atom == ECORE_X_ATOM_NET_WM_STATE_SHADED)
541 ewin->state.shaded = 1;
542 else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
543 ewin->props.skip_ext_task = 1;
544 else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
545 ewin->props.skip_ext_pager = 1;
546 else if (atom == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
547 ; /* ewin->state.iconified = 1; No - WM_STATE does this */
548 else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
549 ewin->state.maximized_vert = 1;
550 else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
551 ewin->state.maximized_horz = 1;
552 else if (atom == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
553 ewin->state.fullscreen = 1;
554 else if (atom == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
556 else if (atom == ECORE_X_ATOM_NET_WM_STATE_BELOW)
558 else if (atom == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
559 ewin->state.attention = 1;
565 EWMH_GetWindowType(EWin * ewin)
567 Ecore_X_Atom *p_atoms, atom;
570 ewin->ewmh.type.all = 0;
572 n_atoms = ecore_x_window_prop_atom_list_get(EwinGetClientXwin(ewin),
573 ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
577 if (EwinIsTransient(ewin))
578 ewin->ewmh.type.b.dialog = 1;
580 ewin->ewmh.type.b.normal = 1;
584 for (i = 0; i < n_atoms; i++)
587 if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
588 ewin->ewmh.type.b.desktop = 1;
589 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
590 ewin->ewmh.type.b.dock = 1;
591 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
592 ewin->ewmh.type.b.utility = 1;
593 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
594 ewin->ewmh.type.b.toolbar = 1;
595 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
596 ewin->ewmh.type.b.menu = 1;
597 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
598 ewin->ewmh.type.b.splash = 1;
599 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
600 ewin->ewmh.type.b.dialog = 1;
601 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
602 ewin->ewmh.type.b.normal = 1;
609 EWMH_GetWindowIcons(EWin * ewin)
614 Efree(ewin->ewmh.wm_icon);
615 ewin->ewmh.wm_icon = NULL;
617 num = ecore_x_window_prop_card32_list_get(EwinGetClientXwin(ewin),
618 ECORE_X_ATOM_NET_WM_ICON, &val);
619 ewin->ewmh.wm_icon_len = num;
623 if (num < 2 || num < (int)(2 + val[0] * val[1]))
626 ("*** EWMH_GetWindowIcons Icon data/size mismatch (ignoring): %s: N=%d WxH=%dx%d\n",
627 EwinGetTitle(ewin), num, val[0], (num >= 2) ? val[1] : 0);
632 ewin->ewmh.wm_icon = val;
634 EwinChange(ewin, EWIN_CHANGE_ICON_PMAP);
638 EWMH_GetWindowUserTime(EWin * ewin)
644 num = ecore_x_netwm_user_time_get(EwinGetClientXwin(ewin), &ts);
648 Eprintf("EWMH_GetWindowUserTime %#x\n", ts);
655 EWMH_GetWindowStartupId(EWin * ewin)
657 #define TryGroup(e) (((e)->icccm.group != None) && ((e)->icccm.group != EwinGetClientXwin(e)))
660 if (!Conf.testing.enable_startup_id)
663 ecore_x_netwm_startup_id_get(EwinGetClientXwin(ewin), &str);
664 if (!str && TryGroup(ewin))
665 ecore_x_netwm_startup_id_get(ewin->icccm.group, &str);
666 if (str && EDebug(1))
667 Eprintf("Startup id: %s: %s\n", EwinGetTitle(ewin), str);
671 EWMH_GetWindowMisc(EWin * ewin)
676 num = ecore_x_window_prop_window_get(EwinGetClientXwin(ewin),
677 ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
682 ewin->props.vroot = 1;
683 EoSetDesk(ewin, DesksGetCurrent());
687 EWMH_GetWindowOpacity(EWin * ewin)
690 unsigned int opacity;
692 num = ecore_x_netwm_opacity_get(EwinGetClientXwin(ewin), &opacity);
696 if (ewin->ewmh.opacity == opacity)
699 ewin->ewmh.opacity = opacity;
701 EwinChange(ewin, EWIN_CHANGE_OPACITY);
705 EWMH_GetWindowStrut(EWin * ewin)
708 unsigned int val[12];
710 num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin),
711 ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, val,
715 num = ecore_x_window_prop_card32_get(EwinGetClientXwin(ewin),
716 ECORE_X_ATOM_NET_WM_STRUT, val, 4);
720 ewin->strut.left = val[0];
721 ewin->strut.right = val[1];
722 ewin->strut.top = val[2];
723 ewin->strut.bottom = val[3];
724 #if 0 /* FIXME - Handle in placement code */
727 ewin->strut.left_start_y = val[4];
728 ewin->strut.left_end_y = val[5];
729 ewin->strut.right_start_y = val[6];
730 ewin->strut.right_end_y = val[7];
731 ewin->strut.top_start_x = val[8];
732 ewin->strut.top_end_x = val[9];
733 ewin->strut.bottom_start_x = val[10];
734 ewin->strut.bottom_end_x = val[11];
739 EWMH_SetWindowActions(const EWin * ewin)
745 if (!ewin->state.inhibit_move)
746 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_MOVE;
747 if (!ewin->state.inhibit_resize)
748 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
749 if (!ewin->state.inhibit_iconify)
750 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
751 if (!ewin->state.inhibit_shade)
752 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_SHADE;
753 if (!ewin->state.inhibit_stick)
754 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_STICK;
755 if (!ewin->state.inhibit_max_hor)
756 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
757 if (!ewin->state.inhibit_max_ver)
758 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
759 if (!ewin->state.inhibit_fullscreeen)
760 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
761 if (!ewin->state.inhibit_change_desk)
762 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
763 if (!ewin->state.inhibit_close)
764 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
765 if (!ewin->state.inhibit_stacking)
766 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
767 if (!ewin->state.inhibit_stacking)
768 aa[num++] = ECORE_X_ATOM_NET_WM_ACTION_BELOW;
770 ecore_x_window_prop_atom_set(EwinGetClientXwin(ewin),
771 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, aa, num);
775 EWMH_GetWindowHints(EWin * ewin)
777 EWMH_GetWindowMisc(ewin);
778 EWMH_GetWindowOpacity(ewin);
779 EWMH_GetWindowName(ewin);
780 EWMH_GetWindowIconName(ewin);
781 EWMH_GetWindowDesktop(ewin);
782 EWMH_GetWindowState(ewin);
783 EWMH_GetWindowType(ewin);
784 EWMH_GetWindowIcons(ewin);
785 EWMH_GetWindowStrut(ewin);
786 EWMH_GetWindowUserTime(ewin);
787 EWMH_GetWindowStartupId(ewin);
791 * Delete all (_NET_...) properties set on window
794 EWMH_DelWindowHints(const EWin * ewin)
796 XDeleteProperty(disp, EwinGetClientXwin(ewin), ECORE_X_ATOM_NET_WM_DESKTOP);
797 XDeleteProperty(disp, EwinGetClientXwin(ewin), ECORE_X_ATOM_NET_WM_STATE);
801 * Process property change
804 EWMH_ProcessPropertyChange(EWin * ewin, Atom atom_change)
806 if (atom_change == ECORE_X_ATOM_NET_WM_NAME)
808 EWMH_GetWindowName(ewin);
811 if (atom_change == ECORE_X_ATOM_NET_WM_ICON_NAME)
813 EWMH_GetWindowIconName(ewin);
816 if (atom_change == ECORE_X_ATOM_NET_WM_STRUT_PARTIAL ||
817 atom_change == ECORE_X_ATOM_NET_WM_STRUT)
819 EWMH_GetWindowStrut(ewin);
822 if (atom_change == ECORE_X_ATOM_NET_WM_WINDOW_OPACITY)
824 EWMH_GetWindowOpacity(ewin);
827 if (atom_change == ECORE_X_ATOM_NET_WM_USER_TIME)
829 EWMH_GetWindowUserTime(ewin);
837 * Process configuration requests from clients
840 do_set(int is_set, int action)
844 case _NET_WM_STATE_REMOVE:
846 case _NET_WM_STATE_ADD:
848 case _NET_WM_STATE_TOGGLE:
855 EWMH_ProcessClientClientMessage(EWin * ewin, XClientMessageEvent * ev)
860 if (ev->message_type == ECORE_X_ATOM_NET_ACTIVE_WINDOW)
862 source = OPSRC(ev->data.l[0]);
864 /* cwin = ev->data.l[2]; */
865 EwinOpActivate(ewin, source, 1);
868 if (ev->message_type == ECORE_X_ATOM_NET_CLOSE_WINDOW)
870 /* ts = ev->data.l[0]; */
871 source = OPSRC(ev->data.l[1]);
872 EwinOpClose(ewin, source);
875 if (ev->message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
877 source = OPSRC(ev->data.l[1]);
878 if ((unsigned)ev->data.l[0] == 0xFFFFFFFF)
880 if (!EoIsSticky(ewin))
881 EwinOpStick(ewin, source, 1);
885 if (EoIsSticky(ewin))
886 EwinOpStick(ewin, source, 0);
888 EwinMoveToDesktop(ewin, DeskGet(ev->data.l[0]));
892 if (ev->message_type == ECORE_X_ATOM_NET_WM_STATE)
895 * It is assumed(!) that only the MAXIMIZE H/V ones can be set
901 action = ev->data.l[0];
902 atom = ev->data.l[1];
903 atom2 = ev->data.l[2];
904 source = OPSRC(ev->data.l[3]);
905 if (atom == ECORE_X_ATOM_NET_WM_STATE_MODAL)
907 action = do_set(ewin->state.modal, action);
909 ewin->state.modal = action;
911 else if (atom == ECORE_X_ATOM_NET_WM_STATE_STICKY)
913 action = do_set(EoIsSticky(ewin), action);
914 EwinOpStick(ewin, source, action);
916 else if (atom == ECORE_X_ATOM_NET_WM_STATE_SHADED)
918 action = do_set(ewin->state.shaded, action);
919 EwinOpShade(ewin, source, action);
921 else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
923 action = do_set(ewin->props.skip_ext_task, action);
924 ewin->props.skip_ext_task = action;
925 EWMH_SetWindowState(ewin);
927 else if (atom == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
929 action = do_set(ewin->props.skip_ext_pager, action);
930 ewin->props.skip_ext_pager = action;
931 EWMH_SetWindowState(ewin);
933 else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT ||
934 atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
938 maxh = ewin->state.maximized_horz;
939 maxv = ewin->state.maximized_vert;
940 if (atom2 == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT ||
941 atom2 == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
944 maxh = do_set(maxh, action);
945 maxv = do_set(maxv, action);
947 else if (atom == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
949 maxv = do_set(maxv, action);
953 maxh = do_set(maxh, action);
956 if ((ewin->state.maximized_horz != maxh) ||
957 (ewin->state.maximized_vert != maxv))
959 MaxSizeHV(ewin, "available", maxh, maxv);
960 EWMH_SetWindowState(ewin);
963 else if (atom == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
965 action = do_set(ewin->state.fullscreen, action);
966 if (ewin->state.fullscreen != action)
967 EwinOpFullscreen(ewin, source, action);
969 else if (atom == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
971 action = do_set(EoGetLayer(ewin) >= 6, action);
974 if (EoGetLayer(ewin) < 6)
975 EwinOpSetLayer(ewin, source, 6);
979 if (EoGetLayer(ewin) >= 6)
980 EwinOpSetLayer(ewin, source, 4);
983 else if (atom == ECORE_X_ATOM_NET_WM_STATE_BELOW)
985 action = do_set(EoGetLayer(ewin) <= 2, action);
988 if (EoGetLayer(ewin) > 2)
989 EwinOpSetLayer(ewin, source, 2);
993 if (EoGetLayer(ewin) <= 2)
994 EwinOpSetLayer(ewin, source, 4);
997 else if (atom == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
999 action = do_set(ewin->state.attention, action);
1000 ewin->state.attention = action;
1001 EWMH_SetWindowState(ewin);
1005 if (ev->message_type == ECORE_X_ATOM_NET_MOVERESIZE_WINDOW)
1007 int flags, grav, x, y, w, h;
1009 flags = ev->data.l[0];
1010 grav = flags & 0xf; /* 0 means use client gravity */
1011 x = (flags & 0x0100) ? ev->data.l[1] : EoGetX(ewin);
1012 y = (flags & 0x0200) ? ev->data.l[2] : EoGetY(ewin);
1013 w = (flags & 0x0400) ? ev->data.l[3] : ewin->client.w;
1014 h = (flags & 0x0800) ? ev->data.l[4] : ewin->client.h;
1015 /* source = OPSRC((flags & 0xF000) >> 12); */
1016 EwinMoveResizeWithGravity(ewin, x, y, w, h, grav);
1019 if (ev->message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE)
1021 /* source = OPSRC(ev->data.l[4]); */
1022 switch (ev->data.l[2])
1024 case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
1025 case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
1026 case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
1027 case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
1028 ActionResizeStart(ewin, 0, MODE_RESIZE);
1030 case _NET_WM_MOVERESIZE_SIZE_RIGHT:
1031 case _NET_WM_MOVERESIZE_SIZE_LEFT:
1032 ActionResizeStart(ewin, 0, MODE_RESIZE_H);
1034 case _NET_WM_MOVERESIZE_SIZE_TOP:
1035 case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
1036 ActionResizeStart(ewin, 0, MODE_RESIZE_V);
1039 case _NET_WM_MOVERESIZE_MOVE:
1040 ActionMoveStart(ewin, 0, 0, 0);
1043 case _NET_WM_MOVERESIZE_SIZE_KEYBOARD:
1044 ActionResizeStart(ewin, 1, MODE_RESIZE);
1046 case _NET_WM_MOVERESIZE_MOVE_KEYBOARD:
1047 ActionMoveStart(ewin, 1, 0, 0);
1049 case _NET_WM_MOVERESIZE_CANCEL:
1055 if (ev->message_type == ECORE_X_ATOM_NET_RESTACK_WINDOW)
1057 /* source = OPSRC(ev->data.l[0]); */
1058 /* FIXME - Implement */
1066 EWMH_ProcessRootClientMessage(XClientMessageEvent * ev)
1068 if (ev->message_type == ECORE_X_ATOM_NET_CURRENT_DESKTOP)
1070 DeskGotoNum(ev->data.l[0]);
1073 if (ev->message_type == ECORE_X_ATOM_NET_DESKTOP_VIEWPORT)
1075 DeskCurrentGotoArea(ev->data.l[0] / WinGetW(VROOT),
1076 ev->data.l[1] / WinGetH(VROOT));
1079 if (ev->message_type == ECORE_X_ATOM_NET_SHOWING_DESKTOP)
1081 EwinsShowDesktop(ev->data.l[0]);
1084 #if 0 /* These messages are sent to dedicated window */
1085 if (ev->message_type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN)
1087 Eprintf("ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN: %lx: %s\n",
1088 ev->window, (char *)ev->data.l);
1091 if (ev->message_type == ECORE_X_ATOM_NET_STARTUP_INFO)
1093 Eprintf("ECORE_X_ATOM_NET_STARTUP_INFO : %lx: %s\n",
1094 ev->window, (char *)ev->data.l);
1099 #if 0 /* Obsolete? */
1102 ewin = EwinFindByClient(ev->window);
1105 /* Some misbehaving clients go here */
1106 if (ev->message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
1108 ecore_x_netwm_desktop_set(ev->window, ev->data.l[0]);
1111 else if (ev->message_type == ECORE_X_ATOM_NET_WM_STATE)
1113 ecore_x_window_prop_atom_list_change(ev->window,
1114 ECORE_X_ATOM_NET_WM_STATE,
1115 ev->data.l[1], ev->data.l[0]);
1116 if (ev->data.l[2] ==
1117 (long)ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ ||
1119 (long)ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
1120 ecore_x_window_prop_atom_list_change(ev->window,
1121 ECORE_X_ATOM_NET_WM_STATE,