2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (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.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
28
#include <X11/Xatom.h>
29
#include <X11/Xutil.h>
30
#include "../config.h"
32
#include <X11/extensions/Xcomposite.h>
33
//#include <X11/extensions/Xdamage.h>
34
#include <X11/extensions/XTest.h>
35
#include <X11/extensions/Xinerama.h>
36
#include <X11/extensions/shape.h>
39
#include "cairo-dock-log.h"
40
#include "cairo-dock-X-manager.h"
41
#include "cairo-dock-X-utilities.h"
43
extern CairoDockDesktopGeometry g_desktopGeometry;
45
static gboolean s_bUseXComposite = TRUE;
46
static gboolean s_bUseXTest = TRUE;
47
static gboolean s_bUseXinerama = TRUE;
48
//extern int g_iDamageEvent;
50
static Display *s_XDisplay = NULL;
51
// Atoms pour le bureau
52
static Atom s_aNetWmWindowType;
53
static Atom s_aNetWmWindowTypeNormal;
54
static Atom s_aNetWmWindowTypeUtility;
55
static Atom s_aNetWmWindowTypeDock;
56
static Atom s_aNetWmIconGeometry;
57
static Atom s_aNetCurrentDesktop;
58
static Atom s_aNetDesktopViewport;
59
static Atom s_aNetDesktopGeometry;
60
static Atom s_aNetNbDesktops;
61
static Atom s_aRootMapID;
62
// Atoms pour les fenetres
63
static Atom s_aNetClientList; // z-order
64
static Atom s_aNetClientListStacking; // age-order
65
static Atom s_aNetActiveWindow;
66
static Atom s_aNetWmState;
67
static Atom s_aNetWmSticky;
68
static Atom s_aNetWmBelow;
69
static Atom s_aNetWmAbove;
70
static Atom s_aNetWmHidden;
71
static Atom s_aNetWmFullScreen;
72
static Atom s_aNetWmSkipTaskbar;
73
static Atom s_aNetWmMaximizedHoriz;
74
static Atom s_aNetWmMaximizedVert;
75
static Atom s_aNetWmDemandsAttention;
76
static Atom s_aNetWmDesktop;
77
static Atom s_aNetWmName;
78
static Atom s_aWmName;
79
static Atom s_aUtf8String;
80
static Atom s_aString;
82
static int _cairo_dock_xerror_handler (Display * pDisplay, XErrorEvent *pXError)
84
cd_debug ("Error (%d, %d, %d) during an X request on %d", pXError->error_code, pXError->request_code, pXError->minor_code, pXError->resourceid);
87
Display *cairo_dock_initialize_X_desktop_support (void)
89
if (s_XDisplay != NULL)
91
s_XDisplay = XOpenDisplay (0);
92
g_return_val_if_fail (s_XDisplay != NULL, NULL);
94
XSetErrorHandler (_cairo_dock_xerror_handler);
96
cairo_dock_support_X_extension ();
98
s_aNetWmWindowType = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE", False);
99
s_aNetWmWindowTypeNormal = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False);
100
s_aNetWmWindowTypeUtility = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_UTILITY", False);
101
s_aNetWmWindowTypeDock = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
102
s_aNetWmIconGeometry = XInternAtom (s_XDisplay, "_NET_WM_ICON_GEOMETRY", False);
103
s_aNetCurrentDesktop = XInternAtom (s_XDisplay, "_NET_CURRENT_DESKTOP", False);
104
s_aNetDesktopViewport = XInternAtom (s_XDisplay, "_NET_DESKTOP_VIEWPORT", False);
105
s_aNetDesktopGeometry = XInternAtom (s_XDisplay, "_NET_DESKTOP_GEOMETRY", False);
106
s_aNetNbDesktops = XInternAtom (s_XDisplay, "_NET_NUMBER_OF_DESKTOPS", False);
107
s_aRootMapID = XInternAtom (s_XDisplay, "_XROOTPMAP_ID", False);
109
s_aNetClientListStacking = XInternAtom (s_XDisplay, "_NET_CLIENT_LIST_STACKING", False);
110
s_aNetClientList = XInternAtom (s_XDisplay, "_NET_CLIENT_LIST", False);
111
s_aNetActiveWindow = XInternAtom (s_XDisplay, "_NET_ACTIVE_WINDOW", False);
112
s_aNetWmState = XInternAtom (s_XDisplay, "_NET_WM_STATE", False);
113
s_aNetWmFullScreen = XInternAtom (s_XDisplay, "_NET_WM_STATE_FULLSCREEN", False);
114
s_aNetWmAbove = XInternAtom (s_XDisplay, "_NET_WM_STATE_ABOVE", False);
115
s_aNetWmBelow = XInternAtom (s_XDisplay, "_NET_WM_STATE_BELOW", False);
116
s_aNetWmSticky = XInternAtom (s_XDisplay, "_NET_WM_STATE_STICKY", False);
117
s_aNetWmHidden = XInternAtom (s_XDisplay, "_NET_WM_STATE_HIDDEN", False);
118
s_aNetWmSkipTaskbar = XInternAtom (s_XDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
119
s_aNetWmMaximizedHoriz = XInternAtom (s_XDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
120
s_aNetWmMaximizedVert = XInternAtom (s_XDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", False);
121
s_aNetWmDemandsAttention = XInternAtom (s_XDisplay, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
122
s_aNetWmDesktop = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
123
s_aNetWmName = XInternAtom (s_XDisplay, "_NET_WM_NAME", False);
124
s_aWmName = XInternAtom (s_XDisplay, "WM_NAME", False);
125
s_aUtf8String = XInternAtom (s_XDisplay, "UTF8_STRING", False);
126
s_aString = XInternAtom (s_XDisplay, "STRING", False);
128
Screen *XScreen = XDefaultScreenOfDisplay (s_XDisplay);
129
g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] = WidthOfScreen (XScreen);
130
g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] = HeightOfScreen (XScreen);
131
g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
132
g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
134
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = WidthOfScreen (XScreen);
135
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = HeightOfScreen (XScreen);
136
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
137
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL];
142
Display *cairo_dock_get_Xdisplay (void)
147
guint cairo_dock_get_root_id (void)
149
return DefaultRootWindow (s_XDisplay);
153
gboolean cairo_dock_update_screen_geometry (void)
155
Window root = DefaultRootWindow (s_XDisplay);
157
int x_return=1, y_return=1;
158
unsigned int width_return, height_return, border_width_return, depth_return;
159
XGetGeometry (s_XDisplay, root,
161
&x_return, &y_return,
162
&width_return, &height_return,
163
&border_width_return, &depth_return);
164
if ((int)width_return != g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] || (int)height_return != g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]) // on n'utilise pas WidthOfScreen() et HeightOfScreen() car leurs valeurs ne sont pas mises a jour immediatement apres les changements de resolution.
166
g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] = width_return;
167
g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] = height_return;
168
g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
169
g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
171
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
172
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
173
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
174
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL]; // si on utilise Xinerama, on mettra les valeurs correctes plus tard.
176
cd_message ("new screen size : %dx%d\n", g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL], g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL]);
181
/*Atom aNetWorkArea = XInternAtom (s_XDisplay, "_NET_WORKAREA", False);
182
iBufferNbElements = 0;
183
gulong *pXWorkArea = NULL;
184
XGetWindowProperty (s_XDisplay, root, aNetWorkArea, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXWorkArea);
186
for (i = 0; i < iBufferNbElements/4; i ++)
188
cd_message ("work area : (%d;%d) %dx%d\n", pXWorkArea[4*i], pXWorkArea[4*i+1], pXWorkArea[4*i+2], pXWorkArea[4*i+3]);
190
XFree (pXWorkArea);*/
194
gboolean cairo_dock_property_is_present_on_root (const gchar *cPropertyName)
196
g_return_val_if_fail (s_XDisplay != NULL, FALSE);
197
Atom atom = XInternAtom (s_XDisplay, cPropertyName, False);
198
Window root = DefaultRootWindow (s_XDisplay);
200
Atom *pAtomList = XListProperties (s_XDisplay, root, &iNbProperties);
202
for (i = 0; i < iNbProperties; i ++)
204
if (pAtomList[i] == atom)
208
return (i != iNbProperties);
212
int cairo_dock_get_current_desktop (void)
214
Window root = DefaultRootWindow (s_XDisplay);
215
Atom aReturnedType = 0;
216
int aReturnedFormat = 0;
217
unsigned long iLeftBytes, iBufferNbElements = 0;
218
gulong *pXDesktopNumberBuffer = NULL;
219
XGetWindowProperty (s_XDisplay, root, s_aNetCurrentDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXDesktopNumberBuffer);
222
if (iBufferNbElements > 0)
223
iDesktopNumber = *pXDesktopNumberBuffer;
227
XFree (pXDesktopNumberBuffer);
228
return iDesktopNumber;
231
void cairo_dock_get_current_viewport (int *iCurrentViewPortX, int *iCurrentViewPortY)
233
Window root = DefaultRootWindow (s_XDisplay);
236
int x_return=1, y_return=1;
237
unsigned int width_return, height_return, border_width_return, depth_return;
238
XGetGeometry (s_XDisplay, root,
240
&x_return, &y_return,
241
&width_return, &height_return,
242
&border_width_return, &depth_return);
243
*iCurrentViewPortX = x_return;
244
*iCurrentViewPortY = y_return;
246
Atom aReturnedType = 0;
247
int aReturnedFormat = 0;
248
unsigned long iLeftBytes, iBufferNbElements = 0;
249
gulong *pViewportsXY = NULL;
250
XGetWindowProperty (s_XDisplay, root, s_aNetDesktopViewport, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pViewportsXY);
251
if (iBufferNbElements > 0)
253
*iCurrentViewPortX = pViewportsXY[0];
254
*iCurrentViewPortY = pViewportsXY[1];
255
XFree (pViewportsXY);
260
int cairo_dock_get_nb_desktops (void)
262
Window root = DefaultRootWindow (s_XDisplay);
263
Atom aReturnedType = 0;
264
int aReturnedFormat = 0;
265
unsigned long iLeftBytes, iBufferNbElements = 0;
266
gulong *pXDesktopNumberBuffer = NULL;
267
XGetWindowProperty (s_XDisplay, root, s_aNetNbDesktops, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXDesktopNumberBuffer);
269
int iNumberOfDesktops;
270
if (iBufferNbElements > 0)
271
iNumberOfDesktops = *pXDesktopNumberBuffer;
273
iNumberOfDesktops = 0;
275
return iNumberOfDesktops;
278
void cairo_dock_get_nb_viewports (int *iNbViewportX, int *iNbViewportY)
280
Window root = DefaultRootWindow (s_XDisplay);
281
Atom aReturnedType = 0;
282
int aReturnedFormat = 0;
283
unsigned long iLeftBytes, iBufferNbElements = 0;
284
gulong *pVirtualScreenSizeBuffer = NULL;
285
XGetWindowProperty (s_XDisplay, root, s_aNetDesktopGeometry, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pVirtualScreenSizeBuffer);
286
if (iBufferNbElements > 0)
288
Screen *scr = XDefaultScreenOfDisplay (s_XDisplay);
289
cd_debug ("pVirtualScreenSizeBuffer : %dx%d ; screen : %dx%d", pVirtualScreenSizeBuffer[0], pVirtualScreenSizeBuffer[1], g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL], g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
290
*iNbViewportX = pVirtualScreenSizeBuffer[0] / g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
291
*iNbViewportY = pVirtualScreenSizeBuffer[1] / g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
292
XFree (pVirtualScreenSizeBuffer);
298
gboolean cairo_dock_desktop_is_visible (void)
300
Atom aNetShowingDesktop = XInternAtom (s_XDisplay, "_NET_SHOWING_DESKTOP", False);
301
gulong iLeftBytes, iBufferNbElements = 0;
302
Atom aReturnedType = 0;
303
int aReturnedFormat = 0;
304
gulong *pXBuffer = NULL;
305
Window root = DefaultRootWindow (s_XDisplay);
306
XGetWindowProperty (s_XDisplay, root, aNetShowingDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXBuffer);
308
gboolean bDesktopIsShown = (iBufferNbElements > 0 && pXBuffer != NULL ? *pXBuffer : FALSE);
310
return bDesktopIsShown;
313
void cairo_dock_show_hide_desktop (gboolean bShow)
315
XEvent xClientMessage;
316
Window root = DefaultRootWindow (s_XDisplay);
318
xClientMessage.xclient.type = ClientMessage;
319
xClientMessage.xclient.serial = 0;
320
xClientMessage.xclient.send_event = True;
321
xClientMessage.xclient.display = s_XDisplay;
322
xClientMessage.xclient.window = root;
323
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_SHOWING_DESKTOP", False);
324
xClientMessage.xclient.format = 32;
325
xClientMessage.xclient.data.l[0] = bShow;
326
xClientMessage.xclient.data.l[1] = 0;
327
xClientMessage.xclient.data.l[2] = 0;
328
xClientMessage.xclient.data.l[3] = 2;
329
xClientMessage.xclient.data.l[4] = 0;
331
cd_debug ("%s (%d)\n", __func__, bShow);
332
XSendEvent (s_XDisplay,
335
SubstructureRedirectMask | SubstructureNotifyMask,
339
static void cairo_dock_move_current_viewport_to (int iDesktopViewportX, int iDesktopViewportY)
341
XEvent xClientMessage;
342
Window root = DefaultRootWindow (s_XDisplay);
344
xClientMessage.xclient.type = ClientMessage;
345
xClientMessage.xclient.serial = 0;
346
xClientMessage.xclient.send_event = True;
347
xClientMessage.xclient.display = s_XDisplay;
348
xClientMessage.xclient.window = root;
349
xClientMessage.xclient.message_type = s_aNetDesktopViewport;
350
xClientMessage.xclient.format = 32;
351
xClientMessage.xclient.data.l[0] = iDesktopViewportX;
352
xClientMessage.xclient.data.l[1] = iDesktopViewportY;
353
xClientMessage.xclient.data.l[2] = 0;
354
xClientMessage.xclient.data.l[3] = 0;
355
xClientMessage.xclient.data.l[4] = 0;
357
XSendEvent (s_XDisplay,
360
SubstructureRedirectMask | SubstructureNotifyMask,
363
void cairo_dock_set_current_viewport (int iViewportNumberX, int iViewportNumberY)
365
cairo_dock_move_current_viewport_to (iViewportNumberX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL], iViewportNumberY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
367
void cairo_dock_set_current_desktop (int iDesktopNumber)
369
Window root = DefaultRootWindow (s_XDisplay);
370
int iTimeStamp = cairo_dock_get_xwindow_timestamp (root);
371
XEvent xClientMessage;
373
xClientMessage.xclient.type = ClientMessage;
374
xClientMessage.xclient.serial = 0;
375
xClientMessage.xclient.send_event = True;
376
xClientMessage.xclient.display = s_XDisplay;
377
xClientMessage.xclient.window = root;
378
xClientMessage.xclient.message_type = s_aNetCurrentDesktop;
379
xClientMessage.xclient.format = 32;
380
xClientMessage.xclient.data.l[0] = iDesktopNumber;
381
xClientMessage.xclient.data.l[1] = iTimeStamp;
382
xClientMessage.xclient.data.l[2] = 0;
383
xClientMessage.xclient.data.l[3] = 0;
384
xClientMessage.xclient.data.l[4] = 0;
386
XSendEvent (s_XDisplay,
389
SubstructureRedirectMask | SubstructureNotifyMask,
393
Pixmap cairo_dock_get_window_background_pixmap (Window Xid)
395
g_return_val_if_fail (Xid > 0, None);
396
//cd_debug ("%s (%d)", __func__, Xid);
399
Atom aReturnedType = 0;
400
int aReturnedFormat = 0;
401
unsigned long iLeftBytes, iBufferNbElements;
402
Pixmap *pPixmapIdBuffer = NULL;
403
Pixmap iBgPixmapID = 0;
404
XGetWindowProperty (s_XDisplay, Xid, s_aRootMapID, 0, G_MAXULONG, False, XA_PIXMAP, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pPixmapIdBuffer);
405
if (iBufferNbElements != 0)
407
iBgPixmapID = *pPixmapIdBuffer;
408
XFree (pPixmapIdBuffer);
412
cd_debug (" => rootmapid : %d", iBgPixmapID);
416
GdkPixbuf *cairo_dock_get_pixbuf_from_pixmap (int XPixmapID, gboolean bAddAlpha) // cette fonction est inspiree par celle de libwnck.
418
//\__________________ On recupere la taille telle qu'elle est actuellement sur le serveur X.
419
Window root; // inutile.
420
int x, y; // inutile.
421
guint border_width; // inutile.
422
guint iWidth, iHeight, iDepth;
423
if (! XGetGeometry (s_XDisplay,
424
XPixmapID, &root, &x, &y,
425
&iWidth, &iHeight, &border_width, &iDepth))
427
cd_debug ("%s (%d) : %ux%ux%u (%d;%d)", __func__, XPixmapID, iWidth, iHeight, iDepth, x, y);
429
//\__________________ On recupere le drawable associe.
430
GdkDrawable *pGdkDrawable = gdk_xid_table_lookup (XPixmapID);
432
g_object_ref (G_OBJECT (pGdkDrawable));
435
cd_debug ("pas d'objet GDK present, on en alloue un nouveau");
436
GdkScreen* pScreen = gdk_screen_get_default ();
437
pGdkDrawable = gdk_pixmap_foreign_new_for_screen (pScreen, XPixmapID, iWidth, iHeight, iDepth);
440
//\__________________ On recupere la colormap.
441
GdkColormap* pColormap = gdk_drawable_get_colormap (pGdkDrawable);
442
if (pColormap == NULL && gdk_drawable_get_depth (pGdkDrawable) > 1) // pour les bitmaps, on laisse la colormap a NULL, ils n'en ont pas besoin.
444
GdkScreen *pScreen = gdk_drawable_get_screen (GDK_DRAWABLE (pGdkDrawable));
445
if (gdk_drawable_get_depth (pGdkDrawable) == 32)
446
pColormap = gdk_screen_get_rgba_colormap (pScreen);
448
pColormap = gdk_screen_get_rgb_colormap (pScreen); // au pire on a un colormap nul.
449
cd_debug (" pColormap : %x (pScreen:%x)", pColormap, pScreen);
452
//\__________________ On recupere le buffer dans un GdkPixbuf.
453
GdkPixbuf *pIconPixbuf = gdk_pixbuf_get_from_drawable (NULL,
462
g_object_unref (G_OBJECT (pGdkDrawable));
463
g_return_val_if_fail (pIconPixbuf != NULL, NULL);
465
//\__________________ On lui ajoute un canal alpha si necessaire.
466
if (! gdk_pixbuf_get_has_alpha (pIconPixbuf) && bAddAlpha)
468
cd_debug (" on lui ajoute de la transparence");
469
GdkPixbuf *tmp_pixbuf = gdk_pixbuf_add_alpha (pIconPixbuf, FALSE, 255, 255, 255);
470
g_object_unref (pIconPixbuf);
471
pIconPixbuf = tmp_pixbuf;
477
void cairo_dock_set_nb_viewports (int iNbViewportX, int iNbViewportY)
479
XEvent xClientMessage;
480
Window root = DefaultRootWindow (s_XDisplay);
482
xClientMessage.xclient.type = ClientMessage;
483
xClientMessage.xclient.serial = 0;
484
xClientMessage.xclient.send_event = True;
485
xClientMessage.xclient.display = s_XDisplay;
486
xClientMessage.xclient.window = root;
487
xClientMessage.xclient.message_type = s_aNetDesktopGeometry;
488
xClientMessage.xclient.format = 32;
489
xClientMessage.xclient.data.l[0] = iNbViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
490
xClientMessage.xclient.data.l[1] = iNbViewportY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
491
xClientMessage.xclient.data.l[2] = 0;
492
xClientMessage.xclient.data.l[3] = 2;
493
xClientMessage.xclient.data.l[4] = 0;
495
XSendEvent (s_XDisplay,
498
SubstructureRedirectMask | SubstructureNotifyMask,
502
void cairo_dock_set_nb_desktops (gulong iNbDesktops)
504
XEvent xClientMessage;
505
Window root = DefaultRootWindow (s_XDisplay);
507
xClientMessage.xclient.type = ClientMessage;
508
xClientMessage.xclient.serial = 0;
509
xClientMessage.xclient.send_event = True;
510
xClientMessage.xclient.display = s_XDisplay;
511
xClientMessage.xclient.window = root;
512
xClientMessage.xclient.message_type = s_aNetNbDesktops;
513
xClientMessage.xclient.format = 32;
514
xClientMessage.xclient.data.l[0] = iNbDesktops;
515
xClientMessage.xclient.data.l[1] = 0;
516
xClientMessage.xclient.data.l[2] = 0;
517
xClientMessage.xclient.data.l[3] = 2;
518
xClientMessage.xclient.data.l[4] = 0;
520
XSendEvent (s_XDisplay,
523
SubstructureRedirectMask | SubstructureNotifyMask,
528
gboolean cairo_dock_support_X_extension (void)
531
int event_base, error_base, major, minor;
532
if (! XCompositeQueryExtension (s_XDisplay, &event_base, &error_base)) // on regarde si le serveur X supporte l'extension.
534
cd_warning ("XComposite extension not available.");
535
s_bUseXComposite = FALSE;
539
major = 0, minor = 2; // La version minimale requise pour avoir XCompositeNameWindowPixmap().
540
XCompositeQueryVersion (s_XDisplay, &major, &minor); // on regarde si on est au moins dans cette version.
541
if (! (major > 0 || minor >= 2))
543
cd_warning ("XComposite extension too old.");
544
s_bUseXComposite = FALSE;
547
/*int iDamageError=0;
548
if (! XDamageQueryExtension (s_XDisplay, &g_iDamageEvent, &iDamageError))
550
cd_warning ("XDamage extension not supported");
554
major = 0, minor = 0;
555
if (! XTestQueryExtension (s_XDisplay, &event_base, &error_base, &major, &minor))
557
cd_warning ("XTest extension not available.");
561
if (! XineramaQueryExtension (s_XDisplay, &event_base, &error_base))
563
cd_warning ("Xinerama extension not supported");
564
s_bUseXinerama = FALSE;
568
major = 0, minor = 0;
569
if (XineramaQueryVersion (s_XDisplay, &major, &minor) == 0)
571
cd_warning ("Xinerama extension too old");
572
s_bUseXinerama = FALSE;
578
cd_warning ("The dock was not compiled with the X extensions (XComposite, xinerama, xtst, XDamage, etc).");
579
s_bUseXComposite = FALSE;
581
s_bUseXinerama = FALSE;
586
gboolean cairo_dock_xcomposite_is_available (void)
588
return s_bUseXComposite;
591
gboolean cairo_dock_xtest_is_available (void)
596
gboolean cairo_dock_xinerama_is_available (void)
598
return s_bUseXinerama;
602
void cairo_dock_get_screen_offsets (int iNumScreen, int *iScreenOffsetX, int *iScreenOffsetY)
605
g_return_if_fail (s_bUseXinerama);
607
XineramaScreenInfo *pScreens = XineramaQueryScreens (s_XDisplay, &iNbScreens);
608
if (pScreens != NULL)
610
if (iNumScreen >= iNbScreens)
612
cd_warning ("the number of screen where to place the dock is too big, we'll choose the last one.");
613
iNumScreen = iNbScreens - 1;
615
*iScreenOffsetX = pScreens[iNumScreen].x_org;
616
*iScreenOffsetY = pScreens[iNumScreen].y_org;
617
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = pScreens[iNumScreen].width;
618
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = pScreens[iNumScreen].height;
620
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
621
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL];
622
cd_message (" * screen %d => (%d;%d) %dx%d\n", iNumScreen, *iScreenOffsetX, *iScreenOffsetY, g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL], g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL]);
628
cd_warning ("No screen found from Xinerama, is it really active ?");
629
*iScreenOffsetX = *iScreenOffsetY = 0;
630
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
631
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL] = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
632
g_desktopGeometry.iScreenWidth[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenHeight[CAIRO_DOCK_HORIZONTAL];
633
g_desktopGeometry.iScreenHeight[CAIRO_DOCK_VERTICAL] = g_desktopGeometry.iScreenWidth[CAIRO_DOCK_HORIZONTAL];
636
cd_warning ("The dock was not compiled with the support of Xinerama.");
645
void cairo_dock_set_xwindow_timestamp (Window Xid, gulong iTimeStamp)
647
g_return_if_fail (Xid > 0);
648
Atom aNetWmUserTime = XInternAtom (s_XDisplay, "_NET_WM_USER_TIME", False);
649
XChangeProperty (s_XDisplay,
652
XA_CARDINAL, 32, PropModeReplace,
653
(guchar *)&iTimeStamp, 1);
656
void cairo_dock_set_strut_partial (int Xid, int left, int right, int top, int bottom, int left_start_y, int left_end_y, int right_start_y, int right_end_y, int top_start_x, int top_end_x, int bottom_start_x, int bottom_end_x)
658
g_return_if_fail (Xid > 0);
660
cd_debug ("%s (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", __func__, left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x);
661
gulong iGeometryStrut[12] = {left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x};
663
XChangeProperty (s_XDisplay,
665
XInternAtom (s_XDisplay, "_NET_WM_STRUT_PARTIAL", False),
666
XA_CARDINAL, 32, PropModeReplace,
667
(guchar *) iGeometryStrut, 12);
669
Window root = DefaultRootWindow (s_XDisplay);
670
cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
673
void cairo_dock_set_xwindow_mask (Window Xid, long iMask)
675
//StructureNotifyMask | /*ResizeRedirectMask*/
676
//SubstructureRedirectMask |
677
//SubstructureNotifyMask | // place sur le root, donne les evenements Map, Unmap, Destroy, Create de chaque fenetre.
679
XSelectInput (s_XDisplay, Xid, iMask); // c'est le 'event_mask' d'un XSetWindowAttributes.
682
void cairo_dock_set_xwindow_type_hint (int Xid, const gchar *cWindowTypeName)
684
g_return_if_fail (Xid > 0);
686
gulong iWindowType = XInternAtom (s_XDisplay, cWindowTypeName, False);
687
cd_debug ("%s (%d, %s=%d)", __func__, Xid, cWindowTypeName, iWindowType);
689
XChangeProperty (s_XDisplay,
692
XA_ATOM, 32, PropModeReplace,
693
(guchar *) &iWindowType, 1);
697
void cairo_dock_set_xicon_geometry (int Xid, int iX, int iY, int iWidth, int iHeight)
699
g_return_if_fail (Xid > 0);
701
gulong iIconGeometry[4] = {iX, iY, iWidth, iHeight};
703
if (iWidth == 0 || iHeight == 0)
704
XDeleteProperty (s_XDisplay,
706
s_aNetWmIconGeometry);
708
XChangeProperty (s_XDisplay,
710
s_aNetWmIconGeometry,
711
XA_CARDINAL, 32, PropModeReplace,
712
(guchar *) iIconGeometry, 4);
717
void cairo_dock_close_xwindow (Window Xid)
719
//g_print ("%s (%d)\n", __func__, Xid);
720
g_return_if_fail (Xid > 0);
722
XEvent xClientMessage;
724
xClientMessage.xclient.type = ClientMessage;
725
xClientMessage.xclient.serial = 0;
726
xClientMessage.xclient.send_event = True;
727
xClientMessage.xclient.display = s_XDisplay;
728
xClientMessage.xclient.window = Xid;
729
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_CLOSE_WINDOW", False);
730
xClientMessage.xclient.format = 32;
731
xClientMessage.xclient.data.l[0] = cairo_dock_get_xwindow_timestamp (Xid); // timestamp
732
xClientMessage.xclient.data.l[1] = 2; // 2 <=> pagers and other Clients that represent direct user actions.
733
xClientMessage.xclient.data.l[2] = 0;
734
xClientMessage.xclient.data.l[3] = 0;
735
xClientMessage.xclient.data.l[4] = 0;
737
Window root = DefaultRootWindow (s_XDisplay);
738
XSendEvent (s_XDisplay,
741
SubstructureRedirectMask | SubstructureNotifyMask,
743
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
746
void cairo_dock_kill_xwindow (Window Xid)
748
g_return_if_fail (Xid > 0);
749
XKillClient (s_XDisplay, Xid);
752
void cairo_dock_show_xwindow (Window Xid)
754
g_return_if_fail (Xid > 0);
755
XEvent xClientMessage;
756
Window root = DefaultRootWindow (s_XDisplay);
758
//\______________ On se deplace sur le bureau de la fenetre a afficher (autrement Metacity deplacera la fenetre sur le bureau actuel).
759
int iDesktopNumber = cairo_dock_get_xwindow_desktop (Xid);
760
cairo_dock_set_current_desktop (iDesktopNumber);
762
//\______________ On active la fenetre.
763
//XMapRaised (s_XDisplay, Xid); // on la mappe, pour les cas ou elle etait en zone de notification. Malheuresement, la zone de notif de gnome est bugguee, et reduit la fenetre aussitot qu'on l'a mappee :-(
764
xClientMessage.xclient.type = ClientMessage;
765
xClientMessage.xclient.serial = 0;
766
xClientMessage.xclient.send_event = True;
767
xClientMessage.xclient.display = s_XDisplay;
768
xClientMessage.xclient.window = Xid;
769
xClientMessage.xclient.message_type = s_aNetActiveWindow;
770
xClientMessage.xclient.format = 32;
771
xClientMessage.xclient.data.l[0] = 2; // source indication
772
xClientMessage.xclient.data.l[1] = 0; // timestamp
773
xClientMessage.xclient.data.l[2] = 0; // requestor's currently active window, 0 if none
774
xClientMessage.xclient.data.l[3] = 0;
775
xClientMessage.xclient.data.l[4] = 0;
777
XSendEvent (s_XDisplay,
780
SubstructureRedirectMask | SubstructureNotifyMask,
783
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
786
void cairo_dock_minimize_xwindow (Window Xid)
788
g_return_if_fail (Xid > 0);
789
XIconifyWindow (s_XDisplay, Xid, DefaultScreen (s_XDisplay));
790
//Window root = DefaultRootWindow (s_XDisplay);
791
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
796
static void _cairo_dock_change_window_state (Window Xid, gulong iNewValue, Atom iProperty1, Atom iProperty2)
798
g_return_if_fail (Xid > 0);
799
XEvent xClientMessage;
801
xClientMessage.xclient.type = ClientMessage;
802
xClientMessage.xclient.serial = 0;
803
xClientMessage.xclient.send_event = True;
804
xClientMessage.xclient.display = s_XDisplay;
805
xClientMessage.xclient.window = Xid;
806
xClientMessage.xclient.message_type = s_aNetWmState;
807
xClientMessage.xclient.format = 32;
808
xClientMessage.xclient.data.l[0] = iNewValue;
809
xClientMessage.xclient.data.l[1] = iProperty1;
810
xClientMessage.xclient.data.l[2] = iProperty2;
811
xClientMessage.xclient.data.l[3] = 2;
812
xClientMessage.xclient.data.l[4] = 0;
814
Window root = DefaultRootWindow (s_XDisplay);
815
XSendEvent (s_XDisplay,
818
SubstructureRedirectMask | SubstructureNotifyMask,
821
cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
823
void cairo_dock_maximize_xwindow (Window Xid, gboolean bMaximize)
825
_cairo_dock_change_window_state (Xid, bMaximize, s_aNetWmMaximizedVert, s_aNetWmMaximizedHoriz);
828
void cairo_dock_set_xwindow_fullscreen (Window Xid, gboolean bFullScreen)
830
_cairo_dock_change_window_state (Xid, bFullScreen, s_aNetWmFullScreen, 0);
833
void cairo_dock_set_xwindow_above (Window Xid, gboolean bAbove)
835
_cairo_dock_change_window_state (Xid, bAbove, s_aNetWmAbove, 0);
839
void cairo_dock_move_xwindow_to_absolute_position (Window Xid, int iDesktopNumber, int iPositionX, int iPositionY) // dans le referentiel du viewport courant.
841
g_return_if_fail (Xid > 0);
842
XEvent xClientMessage;
844
xClientMessage.xclient.type = ClientMessage;
845
xClientMessage.xclient.serial = 0;
846
xClientMessage.xclient.send_event = True;
847
xClientMessage.xclient.display = s_XDisplay;
848
xClientMessage.xclient.window = Xid;
849
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
850
xClientMessage.xclient.format = 32;
851
xClientMessage.xclient.data.l[0] = iDesktopNumber;
852
xClientMessage.xclient.data.l[1] = 2;
853
xClientMessage.xclient.data.l[2] = 0;
854
xClientMessage.xclient.data.l[3] = 0;
855
xClientMessage.xclient.data.l[4] = 0;
857
Window root = DefaultRootWindow (s_XDisplay);
858
XSendEvent (s_XDisplay,
861
SubstructureRedirectMask | SubstructureNotifyMask,
864
xClientMessage.xclient.type = ClientMessage;
865
xClientMessage.xclient.serial = 0;
866
xClientMessage.xclient.send_event = True;
867
xClientMessage.xclient.display = s_XDisplay;
868
xClientMessage.xclient.window = Xid;
869
xClientMessage.xclient.message_type = XInternAtom (s_XDisplay, "_NET_MOVERESIZE_WINDOW", False);
870
xClientMessage.xclient.format = 32;
871
xClientMessage.xclient.data.l[0] = StaticGravity | (1 << 8) | (1 << 9) | (0 << 10) | (0 << 11);
872
xClientMessage.xclient.data.l[1] = iPositionX; // coordonnees dans le referentiel du viewport desire.
873
xClientMessage.xclient.data.l[2] = iPositionY;
874
xClientMessage.xclient.data.l[3] = 0;
875
xClientMessage.xclient.data.l[4] = 0;
876
XSendEvent (s_XDisplay,
879
SubstructureRedirectMask | SubstructureNotifyMask,
882
//cairo_dock_set_xwindow_timestamp (Xid, cairo_dock_get_xwindow_timestamp (root));
885
void cairo_dock_move_xwindow_to_nth_desktop (Window Xid, int iDesktopNumber, int iDesktopViewportX, int iDesktopViewportY)
887
g_return_if_fail (Xid > 0);
888
int iRelativePositionX, iRelativePositionY;
889
cairo_dock_get_xwindow_position_on_its_viewport (Xid, &iRelativePositionX, &iRelativePositionY);
891
cairo_dock_move_xwindow_to_absolute_position (Xid, iDesktopNumber, iDesktopViewportX + iRelativePositionX, iDesktopViewportY + iRelativePositionY);
896
gulong cairo_dock_get_xwindow_timestamp (Window Xid)
898
g_return_val_if_fail (Xid > 0, 0);
899
Atom aNetWmUserTime = XInternAtom (s_XDisplay, "_NET_WM_USER_TIME", False);
900
gulong iLeftBytes, iBufferNbElements = 0;
901
Atom aReturnedType = 0;
902
int aReturnedFormat = 0;
903
gulong *pTimeBuffer = NULL;
904
XGetWindowProperty (s_XDisplay, Xid, aNetWmUserTime, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pTimeBuffer);
905
gulong iTimeStamp = 0;
906
if (iBufferNbElements > 0)
907
iTimeStamp = *pTimeBuffer;
912
gchar *cairo_dock_get_xwindow_name (Window Xid, gboolean bSearchWmName)
914
Atom aReturnedType = 0;
915
int aReturnedFormat = 0;
916
unsigned long iLeftBytes, iBufferNbElements=0;
917
guchar *pNameBuffer = NULL;
918
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmName, 0, G_MAXULONG, False, s_aUtf8String, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer); // on cherche en priorite le nom en UTF8, car on est notifie des 2, mais il vaut mieux eviter le WM_NAME qui, ne l'etant pas, contient des caracteres bizarres qu'on ne peut pas convertir avec g_locale_to_utf8, puisque notre locale _est_ UTF8.
919
if (iBufferNbElements == 0 && bSearchWmName)
920
XGetWindowProperty (s_XDisplay, Xid, s_aWmName, 0, G_MAXULONG, False, s_aString, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
923
if (iBufferNbElements > 0)
925
cName = g_strdup (pNameBuffer);
931
gboolean cairo_dock_xwindow_is_maximized (Window Xid)
933
g_return_val_if_fail (Xid > 0, FALSE);
935
Atom aReturnedType = 0;
936
int aReturnedFormat = 0;
937
unsigned long iLeftBytes, iBufferNbElements = 0;
938
gulong *pXStateBuffer = NULL;
939
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
940
int iIsMaximized = 0;
941
if (iBufferNbElements > 0)
944
for (i = 0; i < iBufferNbElements && iIsMaximized < 2; i ++)
946
if (pXStateBuffer[i] == s_aNetWmMaximizedVert)
948
if (pXStateBuffer[i] == s_aNetWmMaximizedHoriz)
952
XFree (pXStateBuffer);
954
return (iIsMaximized == 2);
957
static gboolean _cairo_dock_window_is_in_state (Window Xid, Atom iState)
959
g_return_val_if_fail (Xid > 0, FALSE);
960
Atom aReturnedType = 0;
961
int aReturnedFormat = 0;
962
unsigned long iLeftBytes, iBufferNbElements = 0;
963
gulong *pXStateBuffer = NULL;
964
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
966
gboolean bIsInState = FALSE;
967
if (iBufferNbElements > 0)
970
for (i = 0; i < iBufferNbElements; i ++)
972
if (pXStateBuffer[i] == iState)
980
XFree (pXStateBuffer);
984
gboolean cairo_dock_xwindow_is_fullscreen (Window Xid)
986
return _cairo_dock_window_is_in_state (Xid, s_aNetWmFullScreen);
988
gboolean cairo_dock_xwindow_skip_taskbar (Window Xid)
990
return _cairo_dock_window_is_in_state (Xid, s_aNetWmSkipTaskbar);
992
void cairo_dock_xwindow_is_above_or_below (Window Xid, gboolean *bIsAbove, gboolean *bIsBelow)
994
g_return_if_fail (Xid > 0);
995
Atom aReturnedType = 0;
996
int aReturnedFormat = 0;
997
unsigned long iLeftBytes, iBufferNbElements = 0;
998
gulong *pXStateBuffer = NULL;
999
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1001
if (iBufferNbElements > 0)
1004
//g_print ("iBufferNbElements : %d (%d;%d)\n", iBufferNbElements, s_aNetWmAbove, s_aNetWmBelow);
1005
for (i = 0; i < iBufferNbElements; i ++)
1007
//g_print (" - %d\n", pXStateBuffer[i]);
1008
if (pXStateBuffer[i] == s_aNetWmAbove)
1014
else if (pXStateBuffer[i] == s_aNetWmBelow)
1023
XFree (pXStateBuffer);
1026
gboolean cairo_dock_xwindow_is_fullscreen_or_hidden_or_maximized (Window Xid, gboolean *bIsFullScreen, gboolean *bIsHidden, gboolean *bIsMaximized, gboolean *bDemandsAttention)
1028
g_return_val_if_fail (Xid > 0, FALSE);
1029
//cd_debug ("%s (%d)", __func__, Xid);
1030
Atom aReturnedType = 0;
1031
int aReturnedFormat = 0;
1032
unsigned long iLeftBytes, iBufferNbElements = 0;
1033
gulong *pXStateBuffer = NULL;
1034
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1036
gboolean bValid = TRUE;
1037
*bIsFullScreen = FALSE;
1039
*bIsMaximized = FALSE;
1040
if (bDemandsAttention != NULL)
1041
*bDemandsAttention = FALSE;
1042
if (iBufferNbElements > 0)
1044
guint i, iNbMaximizedDimensions = 0;
1045
for (i = 0; i < iBufferNbElements; i ++)
1047
if (pXStateBuffer[i] == s_aNetWmFullScreen)
1049
*bIsFullScreen = TRUE;
1051
else if (pXStateBuffer[i] == s_aNetWmHidden)
1055
else if (pXStateBuffer[i] == s_aNetWmMaximizedVert)
1057
iNbMaximizedDimensions ++;
1058
if (iNbMaximizedDimensions == 2)
1059
*bIsMaximized = TRUE;
1061
else if (pXStateBuffer[i] == s_aNetWmMaximizedHoriz)
1063
iNbMaximizedDimensions ++;
1064
if (iNbMaximizedDimensions == 2)
1065
*bIsMaximized = TRUE;
1067
else if (pXStateBuffer[i] == s_aNetWmDemandsAttention && bDemandsAttention != NULL)
1069
*bDemandsAttention = TRUE;
1072
else if (pXStateBuffer[i] == s_aNetWmSkipTaskbar)
1074
cd_debug ("this appli should not be in taskbar anymore");
1080
XFree (pXStateBuffer);
1084
gboolean cairo_dock_xwindow_is_sticky (Window Xid)
1086
g_return_val_if_fail (Xid > 0, FALSE);
1087
Atom aReturnedType = 0;
1088
int aReturnedFormat = 0;
1089
unsigned long iLeftBytes, iBufferNbElements = 0;
1090
gulong *pXStateBuffer = NULL;
1091
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmState, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXStateBuffer);
1093
gboolean bIsSticky = FALSE;
1094
if (iBufferNbElements > 0)
1097
//g_print ("iBufferNbElements : %d (%d;%d)\n", iBufferNbElements, s_aNetWmAbove, s_aNetWmBelow);
1098
for (i = 0; i < iBufferNbElements; i ++)
1100
//g_print (" - %d\n", pXStateBuffer[i]);
1101
if (pXStateBuffer[i] == s_aNetWmSticky)
1109
XFree (pXStateBuffer);
1113
static inline gboolean _cairo_dock_window_has_type (int Xid, Atom iType)
1115
g_return_val_if_fail (Xid > 0, FALSE);
1118
Atom aReturnedType = 0;
1119
int aReturnedFormat = 0;
1120
unsigned long iLeftBytes, iBufferNbElements;
1121
gulong *pTypeBuffer = NULL;
1122
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmWindowType, 0, G_MAXULONG, False, XA_ATOM, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pTypeBuffer);
1123
if (iBufferNbElements != 0)
1125
bIsType = (*pTypeBuffer == iType);
1126
XFree (pTypeBuffer);
1132
gboolean cairo_dock_window_is_utility (int Xid)
1134
return _cairo_dock_window_has_type (Xid, s_aNetWmWindowTypeUtility);
1137
gboolean cairo_dock_window_is_dock (int Xid)
1139
return _cairo_dock_window_has_type (Xid, s_aNetWmWindowTypeDock);
1142
int cairo_dock_get_xwindow_desktop (Window Xid)
1145
gulong iLeftBytes, iBufferNbElements = 0;
1146
Atom aReturnedType = 0;
1147
int aReturnedFormat = 0;
1148
gulong *pBuffer = NULL;
1149
XGetWindowProperty (s_XDisplay, Xid, s_aNetWmDesktop, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pBuffer);
1150
if (iBufferNbElements > 0)
1151
iDesktopNumber = *pBuffer;
1156
return iDesktopNumber;
1159
void cairo_dock_get_xwindow_geometry (Window Xid, int *iLocalPositionX, int *iLocalPositionY, int *iWidthExtent, int *iHeightExtent) // renvoie les coordonnees du coin haut gauche dans le referentiel du viewport actuel. // sous KDE, x et y sont toujours nuls ! (meme avec XGetWindowAttributes).
1162
int x_return=1, y_return=1;
1163
unsigned int width_return, height_return, border_width_return, depth_return;
1164
XGetGeometry (s_XDisplay, Xid,
1166
&x_return, &y_return,
1167
&width_return, &height_return,
1168
&border_width_return, &depth_return); // renvoie les coordonnees du coin haut gauche dans le referentiel du viewport actuel.
1170
*iLocalPositionX = x_return; // on pourrait tenir compte de border_width_return...
1171
*iLocalPositionY = y_return; // idem.
1172
*iWidthExtent = width_return; // idem.
1173
*iHeightExtent = height_return; // idem.
1174
//g_print ("%s () -> %d;%d %dx%d / %d,%d\n", __func__, x_return, y_return, *iWidthExtent, *iHeightExtent, border_width_return, depth_return);
1177
void cairo_dock_get_xwindow_position_on_its_viewport (Window Xid, int *iRelativePositionX, int *iRelativePositionY)
1179
int iLocalPositionX, iLocalPositionY, iWidthExtent, iHeightExtent;
1180
cairo_dock_get_xwindow_geometry (Xid, &iLocalPositionX, &iLocalPositionY, &iWidthExtent, &iHeightExtent);
1182
while (iLocalPositionX < 0) // on passe au referentiel du viewport de la fenetre; inutile de connaitre sa position, puisqu'ils ont tous la meme taille.
1183
iLocalPositionX += g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
1184
while (iLocalPositionX >= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL])
1185
iLocalPositionX -= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
1186
while (iLocalPositionY < 0)
1187
iLocalPositionY += g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1188
while (iLocalPositionY >= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
1189
iLocalPositionY -= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1191
*iRelativePositionX = iLocalPositionX;
1192
*iRelativePositionY = iLocalPositionY;
1193
//cd_debug ("position relative : (%d;%d) taille : %dx%d", *iRelativePositionX, *iRelativePositionY, iWidthExtent, iHeightExtent);
1196
gboolean cairo_dock_xwindow_is_on_current_desktop (Window Xid)
1198
int iWindowDesktopNumber, iLocalPositionX, iLocalPositionY, iWidthExtent, iHeightExtent; // coordonnees du coin haut gauche dans le referentiel du viewport actuel.
1199
iWindowDesktopNumber = cairo_dock_get_xwindow_desktop (Xid);
1200
cairo_dock_get_xwindow_geometry (Xid, &iLocalPositionX, &iLocalPositionY, &iWidthExtent, &iHeightExtent);
1202
//cd_debug (" -> %d/%d ; (%d ; %d)", iWindowDesktopNumber, iDesktopNumber, iGlobalPositionX, iGlobalPositionY);
1203
return ( (iWindowDesktopNumber == g_desktopGeometry.iCurrentDesktop || iWindowDesktopNumber == -1) &&
1204
iLocalPositionX + iWidthExtent > 0 &&
1205
iLocalPositionX < g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] &&
1206
iLocalPositionY + iHeightExtent > 0 &&
1207
iLocalPositionY < g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] ); // -1 <=> 0xFFFFFFFF en unsigned.
1211
Window *cairo_dock_get_windows_list (gulong *iNbWindows, gboolean bStackOrder)
1213
Atom aReturnedType = 0;
1214
int aReturnedFormat = 0;
1215
Window *XidList = NULL;
1217
Window root = DefaultRootWindow (s_XDisplay);
1219
XGetWindowProperty (s_XDisplay, root, (bStackOrder ? s_aNetClientListStacking : s_aNetClientList), 0, G_MAXLONG, False, XA_WINDOW, &aReturnedType, &aReturnedFormat, iNbWindows, &iLeftBytes, (guchar **)&XidList);
1223
Window cairo_dock_get_active_xwindow (void)
1225
Atom aReturnedType = 0;
1226
int aReturnedFormat = 0;
1227
unsigned long iLeftBytes, iBufferNbElements = 0;
1228
Window *pXBuffer = NULL;
1229
Window root = DefaultRootWindow (s_XDisplay);
1230
XGetWindowProperty (s_XDisplay, root, s_aNetActiveWindow, 0, G_MAXULONG, False, XA_WINDOW, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pXBuffer);
1232
Window xActiveWindow = (iBufferNbElements > 0 && pXBuffer != NULL ? pXBuffer[0] : 0);
1234
return xActiveWindow;