~cairo-dock-team/ubuntu/oneiric/cairo-dock/2.3.0-3

« back to all changes in this revision

Viewing changes to src/cairo-dock-applications-manager.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
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.
11
 
*
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/>.
18
 
*/
19
 
 
20
 
#include <math.h>
21
 
#include <string.h>
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#define __USE_POSIX
25
 
#include <signal.h>
26
 
 
27
 
#include <cairo.h>
28
 
#include <X11/Xlib.h>
29
 
#include <X11/Xatom.h>
30
 
#include <X11/Xutil.h>
31
 
#ifdef HAVE_XEXTEND
32
 
#include <X11/extensions/Xcomposite.h>
33
 
//#include <X11/extensions/Xdamage.h>
34
 
#endif
35
 
 
36
 
#include "cairo-dock-icons.h"
37
 
#include "cairo-dock-draw.h"
38
 
#include "cairo-dock-animations.h"
39
 
#include "cairo-dock-load.h"
40
 
#include "cairo-dock-application-factory.h"
41
 
#include "cairo-dock-separator-factory.h"
42
 
#include "cairo-dock-dock-factory.h"
43
 
#include "cairo-dock-dock-facility.h"
44
 
#include "cairo-dock-container.h"
45
 
#include "cairo-dock-notifications.h"
46
 
#include "cairo-dock-callbacks.h"
47
 
#include "cairo-dock-log.h"
48
 
#include "cairo-dock-X-utilities.h"
49
 
#include "cairo-dock-config.h"
50
 
#include "cairo-dock-dock-manager.h"
51
 
#include "cairo-dock-class-manager.h"
52
 
#include "cairo-dock-dialogs.h"
53
 
#include "cairo-dock-draw-opengl.h"
54
 
#include "cairo-dock-animations.h"
55
 
#include "cairo-dock-internal-taskbar.h"
56
 
#include "cairo-dock-internal-icons.h"
57
 
#include "cairo-dock-internal-accessibility.h"
58
 
#include "cairo-dock-internal-labels.h"
59
 
#include "cairo-dock-application-facility.h"
60
 
#include "cairo-dock-applications-manager.h"
61
 
 
62
 
#define CAIRO_DOCK_TASKBAR_CHECK_INTERVAL 200
63
 
 
64
 
extern CairoDock *g_pMainDock;
65
 
 
66
 
extern int g_iXScreenWidth[2], g_iXScreenHeight[2];
67
 
 
68
 
extern int g_iNbDesktops;
69
 
extern int g_iNbViewportX,g_iNbViewportY ;
70
 
extern gboolean g_bUseOpenGL;
71
 
//extern int g_iDamageEvent;
72
 
 
73
 
static GHashTable *s_hXWindowTable = NULL;  // table des fenetres X affichees dans le dock.
74
 
static Display *s_XDisplay = NULL;
75
 
static int s_iSidUpdateAppliList = 0;
76
 
static int s_bAppliManagerIsRunning = FALSE;
77
 
static int s_iTime = 1;  // on peut aller jusqu'a 2^31, soit 17 ans a 4Hz.
78
 
static Window s_iCurrentActiveWindow = 0;
79
 
static int s_iCurrentDesktop = 0;
80
 
static int s_iCurrentViewportX = 0;
81
 
static int s_iCurrentViewportY = 0;
82
 
static Atom s_aNetClientList;
83
 
static Atom s_aNetActiveWindow;
84
 
static Atom s_aNetCurrentDesktop;
85
 
static Atom s_aNetDesktopViewport;
86
 
static Atom s_aNetDesktopGeometry;
87
 
static Atom s_aNetWmState;
88
 
static Atom s_aNetWmDesktop;
89
 
static Atom s_aNetShowingDesktop;
90
 
static Atom s_aRootMapID;
91
 
static Atom s_aNetNbDesktops;
92
 
static Atom s_aXKlavierState;
93
 
static Atom s_aNetWmName;
94
 
static Atom s_aUtf8String;
95
 
static Atom s_aWmName;
96
 
static Atom s_aString;
97
 
static Atom s_aNetWmIcon;
98
 
static Atom s_aWmHints;
99
 
 
100
 
static gboolean _cairo_dock_window_is_on_our_way (Window *Xid, Icon *icon, gpointer *data);
101
 
 
102
 
  ///////////////////////
103
 
 // X listener : core //
104
 
///////////////////////
105
 
 
106
 
static inline void _cairo_dock_retrieve_current_desktop_and_viewport (void)
107
 
{
108
 
        s_iCurrentDesktop = cairo_dock_get_current_desktop ();
109
 
        cairo_dock_get_current_viewport (&s_iCurrentViewportX, &s_iCurrentViewportY);
110
 
        s_iCurrentViewportX /= g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
111
 
        s_iCurrentViewportY /= g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
112
 
}
113
 
 
114
 
static void _cairo_dock_hide_show_windows_on_other_desktops (Window *Xid, Icon *icon, CairoDock *pMainDock)
115
 
{
116
 
        if (CAIRO_DOCK_IS_APPLI (icon) && (! myTaskBar.bHideVisibleApplis || icon->bIsHidden))
117
 
        {
118
 
                cd_debug ("%s (%d)", __func__, *Xid);
119
 
                CairoDock *pParentDock = NULL;
120
 
                if (cairo_dock_appli_is_on_current_desktop (icon))
121
 
                {
122
 
                        cd_debug (" => est sur le bureau actuel.");
123
 
                        if (icon->cParentDockName == NULL)
124
 
                        {
125
 
                                pParentDock = cairo_dock_insert_appli_in_dock (icon, pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
126
 
                        }
127
 
                }
128
 
                else
129
 
                {
130
 
                        cd_debug (" => n'est pas sur le bureau actuel.");
131
 
                        pParentDock = cairo_dock_detach_appli (icon);
132
 
                }
133
 
                if (pParentDock != NULL)
134
 
                        gtk_widget_queue_draw (pParentDock->container.pWidget);
135
 
        }
136
 
}
137
 
 
138
 
static gboolean _cairo_dock_remove_old_applis (Window *Xid, Icon *icon, gpointer iTimePtr)
139
 
{
140
 
        if (icon == NULL)
141
 
                return FALSE;
142
 
        gint iTime = GPOINTER_TO_INT (iTimePtr);
143
 
        
144
 
        //g_print ("%s (%s(%ld) %d / %d)\n", __func__, icon->cName, icon->Xid, icon->iLastCheckTime, iTime);
145
 
        if (icon->iLastCheckTime >= 0 && icon->iLastCheckTime < iTime && ! cairo_dock_icon_is_being_removed (icon))
146
 
        {
147
 
                cd_message ("cette fenetre (%ld(%ld), %s) est trop vieille (%d / %d)", *Xid, icon->Xid, icon->cName, icon->iLastCheckTime, iTime);
148
 
                if (CAIRO_DOCK_IS_APPLI (icon))
149
 
                {
150
 
                        CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
151
 
                        if (pParentDock != NULL)
152
 
                        {
153
 
                                cd_message ("  va etre supprimee");
154
 
                                cairo_dock_trigger_icon_removal_from_dock (icon);
155
 
                                
156
 
                                icon->iLastCheckTime = -1;  // inutile de chercher a la desenregistrer par la suite, puisque ce sera fait ici. Cela sert aussi a bien supprimer l'icone en fin d'animation.
157
 
                                ///cairo_dock_unregister_appli (icon);
158
 
                                cairo_dock_remove_appli_from_class (icon);  // elle reste une icone d'appli, et de la meme classe, mais devient invisible aux autres icones de sa classe. Inutile de tester les inhibiteurs, puisqu'elle est dans un dock.
159
 
                        }
160
 
                        else  // n'etait pas dans un dock, on la detruit donc immediatement.
161
 
                        {
162
 
                                cd_message ("  pas dans un container, on la detruit donc immediatement");
163
 
                                cairo_dock_update_name_on_inhibators (icon->cClass, *Xid, NULL);
164
 
                                icon->iLastCheckTime = -1;  // pour ne pas la desenregistrer de la HashTable lors du 'free' puisqu'on est en train de parcourir la table.
165
 
                                cairo_dock_free_icon (icon);
166
 
                                /// redessiner les inhibiteurs ?...
167
 
                        }
168
 
                        
169
 
                        if (cairo_dock_quick_hide_is_activated () && ((icon->bIsFullScreen && ! icon->bIsHidden && myAccessibility.bAutoHideOnFullScreen) || (icon->bIsMaximized && ! icon->bIsHidden && myAccessibility.bAutoHideOnMaximized)))  // cette fenetre peut avoir gene.
170
 
                        {
171
 
                                /// le faire pour tous les docks principaux ...
172
 
                                if (cairo_dock_search_window_on_our_way (g_pMainDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)  // on regarde si une autre gene encore.
173
 
                                {
174
 
                                        cd_message (" => plus aucune fenetre genante");
175
 
                                        cairo_dock_deactivate_temporary_auto_hide ();
176
 
                                }
177
 
                        }
178
 
                }
179
 
                else
180
 
                {
181
 
                        g_free (icon);
182
 
                }
183
 
                return TRUE;
184
 
        }
185
 
        return FALSE;
186
 
}
187
 
static void on_update_applis_list (CairoDock *pDock, gint iTime)
188
 
{
189
 
        gulong i, iNbWindows = 0;
190
 
        Window *pXWindowsList = cairo_dock_get_windows_list (&iNbWindows, TRUE);
191
 
        
192
 
        Window Xid;
193
 
        Icon *icon;
194
 
        int iStackOrder = 0;
195
 
        gpointer pOriginalXid;
196
 
        gboolean bAppliAlreadyRegistered;
197
 
        gboolean bUpdateMainDockSize = FALSE;
198
 
        CairoDock *pParentDock;
199
 
        cairo_t *pCairoContext = NULL;
200
 
        
201
 
        for (i = 0; i < iNbWindows; i ++)
202
 
        {
203
 
                Xid = pXWindowsList[i];
204
 
                
205
 
                bAppliAlreadyRegistered = g_hash_table_lookup_extended (s_hXWindowTable, &Xid, &pOriginalXid, (gpointer *) &icon);
206
 
                if (! bAppliAlreadyRegistered)
207
 
                {
208
 
                        cd_message (" cette fenetre (%ld) de la pile n'est pas dans la liste", Xid);
209
 
                        if (pCairoContext == NULL)
210
 
                                pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDock));
211
 
                        if (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS)
212
 
                                icon = cairo_dock_create_icon_from_xwindow (pCairoContext, Xid, pDock);
213
 
                        else
214
 
                                cd_warning ("couldn't create a cairo context => this window (%ld) will not have an icon", Xid);
215
 
                        if (icon != NULL)
216
 
                        {
217
 
                                icon->iLastCheckTime = iTime;
218
 
                                icon->iStackOrder = iStackOrder ++;
219
 
                                if (/*(icon->bIsHidden || ! myTaskBar.bHideVisibleApplis) && */(! myTaskBar.bAppliOnCurrentDesktopOnly || cairo_dock_xwindow_is_on_current_desktop (Xid)))
220
 
                                {
221
 
                                        cd_message (" insertion de %s ... (%d)", icon->cName, icon->iLastCheckTime);
222
 
                                        pParentDock = cairo_dock_insert_appli_in_dock (icon, pDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
223
 
                                        if (pParentDock != NULL)
224
 
                                        {
225
 
                                                if (pParentDock->bIsMainDock)
226
 
                                                        bUpdateMainDockSize = TRUE;
227
 
                                                else
228
 
                                                        cairo_dock_update_dock_size (pParentDock);
229
 
                                        }
230
 
                                }
231
 
                                else if (myTaskBar.bMixLauncherAppli)  // on met tout de meme l'indicateur sur le lanceur.
232
 
                                {
233
 
                                        cairo_dock_prevent_inhibated_class (icon);
234
 
                                }
235
 
                                if ((myAccessibility.bAutoHideOnMaximized && icon->bIsMaximized && ! icon->bIsHidden) || (myAccessibility.bAutoHideOnFullScreen && icon->bIsFullScreen && ! icon->bIsHidden))
236
 
                                {
237
 
                                        if (! cairo_dock_quick_hide_is_activated ())
238
 
                                        {
239
 
                                                if (cairo_dock_xwindow_is_on_this_desktop (Xid, s_iCurrentDesktop) && cairo_dock_appli_hovers_dock (icon, pDock))
240
 
                                                {
241
 
                                                        cd_message (" cette nouvelle fenetre empiete sur notre dock");
242
 
                                                        cairo_dock_activate_temporary_auto_hide ();
243
 
                                                }
244
 
                                        }
245
 
                                }
246
 
                        }
247
 
                        else
248
 
                                cairo_dock_blacklist_appli (Xid);
249
 
                }
250
 
                else if (icon != NULL)
251
 
                {
252
 
                        icon->iLastCheckTime = iTime;
253
 
                        if (CAIRO_DOCK_IS_APPLI (icon))
254
 
                                icon->iStackOrder = iStackOrder ++;
255
 
                }
256
 
        }
257
 
        if (pCairoContext != NULL)
258
 
                cairo_destroy (pCairoContext);
259
 
        
260
 
        g_hash_table_foreach_remove (s_hXWindowTable, (GHRFunc) _cairo_dock_remove_old_applis, GINT_TO_POINTER (iTime));
261
 
        
262
 
        if (bUpdateMainDockSize)
263
 
                cairo_dock_update_dock_size (pDock);
264
 
 
265
 
        XFree (pXWindowsList);
266
 
}
267
 
 
268
 
static void _on_change_active_window (void)
269
 
{
270
 
        Window XActiveWindow = cairo_dock_get_active_xwindow ();
271
 
        //g_print ("%d devient active (%d)\n", XActiveWindow, root);
272
 
        if (s_iCurrentActiveWindow != XActiveWindow)  // la fenetre courante a change.
273
 
        {
274
 
                Icon *icon = g_hash_table_lookup (s_hXWindowTable, &XActiveWindow);
275
 
                CairoDock *pParentDock = NULL;
276
 
                if (CAIRO_DOCK_IS_APPLI (icon))
277
 
                {
278
 
                        if (icon->bIsDemandingAttention)  // on force ici, car il semble qu'on ne recoive pas toujours le retour a la normale.
279
 
                                cairo_dock_appli_stops_demanding_attention (icon);
280
 
                        
281
 
                        pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
282
 
                        if (pParentDock == NULL)  // elle est soit inhibee, soit pas dans un dock.
283
 
                        {
284
 
                                cairo_dock_update_activity_on_inhibators (icon->cClass, icon->Xid);
285
 
                        }
286
 
                        else
287
 
                        {
288
 
                                cairo_dock_animate_icon_on_active (icon, pParentDock);
289
 
                        }
290
 
                }
291
 
                
292
 
                gboolean bForceKbdStateRefresh = FALSE;
293
 
                Icon *pLastActiveIcon = g_hash_table_lookup (s_hXWindowTable, &s_iCurrentActiveWindow);
294
 
                if (CAIRO_DOCK_IS_APPLI (pLastActiveIcon))
295
 
                {
296
 
                        CairoDock *pLastActiveParentDock = cairo_dock_search_dock_from_name (pLastActiveIcon->cParentDockName);
297
 
                        if (pLastActiveParentDock == NULL)  // elle est soit inhibee, soit pas dans un dock.
298
 
                        {
299
 
                                cairo_dock_update_inactivity_on_inhibators (pLastActiveIcon->cClass, pLastActiveIcon->Xid);
300
 
                        }
301
 
                        else
302
 
                        {
303
 
                                cairo_dock_redraw_icon (pLastActiveIcon, CAIRO_CONTAINER (pLastActiveParentDock));
304
 
                                if (pLastActiveParentDock->iRefCount != 0)  // l'icone est dans un sous-dock, comme l'indicateur est aussi dessine sur l'icone pointant sur ce sous-dock, il faut la redessiner sans l'indicateur.
305
 
                                {
306
 
                                        CairoDock *pMainDock = NULL;
307
 
                                        Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pLastActiveParentDock, &pMainDock);
308
 
                                        if (pPointingIcon && pMainDock)
309
 
                                        {
310
 
                                                cairo_dock_redraw_icon (pPointingIcon, CAIRO_CONTAINER (pMainDock));
311
 
                                        }
312
 
                                }
313
 
                        }
314
 
                }
315
 
                else  // il n'y avait pas de fenetre active avant.
316
 
                        bForceKbdStateRefresh = TRUE;
317
 
                s_iCurrentActiveWindow = XActiveWindow;
318
 
                cairo_dock_notify (CAIRO_DOCK_WINDOW_ACTIVATED, &XActiveWindow);
319
 
                if (bForceKbdStateRefresh)  // si on active une fenetre n'ayant pas de focus clavier, on n'aura pas d'evenement kbd_changed, pourtant en interne le clavier changera. du coup si apres on revient sur une fenetre qui a un focus clavier, il risque de ne pas y avoir de changement de clavier, et donc encore une fois pas d'evenement ! pour palier a ce, on considere que les fenetres avec focus clavier sont celles presentes en barre des taches. On decide de generer un evenement lorsqu'on revient sur une fenetre avec focus, a partir d'une fenetre sans focus (mettre a jour le clavier pour une fenetre sans focus n'a pas grand interet, autant le laisser inchange).
320
 
                        cairo_dock_notify (CAIRO_DOCK_KBD_STATE_CHANGED, &XActiveWindow);
321
 
        }
322
 
}
323
 
 
324
 
static gboolean _on_change_current_desktop_viewport (void)
325
 
{
326
 
        CairoDock *pDock = g_pMainDock;
327
 
        
328
 
        _cairo_dock_retrieve_current_desktop_and_viewport ();
329
 
        
330
 
        // applis du bureau courant seulement.
331
 
        if (myTaskBar.bAppliOnCurrentDesktopOnly)
332
 
        {
333
 
                int data[2] = {s_iCurrentDesktop, GPOINTER_TO_INT (pDock)};
334
 
                g_hash_table_foreach (s_hXWindowTable, (GHFunc) _cairo_dock_hide_show_windows_on_other_desktops, pDock);
335
 
        }
336
 
 
337
 
        cairo_dock_hide_show_launchers_on_other_desktops(pDock);
338
 
 
339
 
        // auto-hide sur appli maximisee/plein-ecran
340
 
        if (myAccessibility.bAutoHideOnFullScreen || myAccessibility.bAutoHideOnMaximized)
341
 
        {
342
 
                //g_print ("%s (%d)\n", __func__, cairo_dock_quick_hide_is_activated ());
343
 
                if (cairo_dock_quick_hide_is_activated ())
344
 
                {
345
 
                        if (cairo_dock_search_window_on_our_way (pDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
346
 
                        {
347
 
                                cd_message (" => plus aucune fenetre genante");
348
 
                                cairo_dock_deactivate_temporary_auto_hide ();
349
 
                        }
350
 
                }
351
 
                else
352
 
                {
353
 
                        if (cairo_dock_search_window_on_our_way (pDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) != NULL)
354
 
                        {
355
 
                                cd_message (" => une fenetre est genante");
356
 
                                cairo_dock_activate_temporary_auto_hide ();
357
 
                        }
358
 
                }
359
 
        }
360
 
        
361
 
        // on propage la notification.
362
 
        cairo_dock_notify (CAIRO_DOCK_DESKTOP_CHANGED);
363
 
        
364
 
        // on gere le cas delicat de X qui nous fait sortir du dock.
365
 
        if (! pDock->bIsShrinkingDown && ! pDock->bIsGrowingUp)
366
 
        {
367
 
                if (pDock->container.bIsHorizontal)
368
 
                        gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
369
 
                else
370
 
                        gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
371
 
                //g_print ("on met a jour de force\n");
372
 
                cairo_dock_calculate_dock_icons (pDock);  // pour faire retrecir le dock si on n'est pas dedans, merci X de nous faire sortir du dock alors que la souris est toujours dedans :-/
373
 
                if (pDock->container.bInside)
374
 
                        return TRUE;
375
 
                //g_print (">>> %d;%d, %dx%d\n", pDock->container.iMouseX, pDock->container.iMouseY,pDock->container.iWidth,  pDock->container.iHeight);
376
 
        }
377
 
        return FALSE;
378
 
}
379
 
 
380
 
static void _on_change_nb_desktops (void)
381
 
{
382
 
        g_iNbDesktops = cairo_dock_get_nb_desktops ();
383
 
        _cairo_dock_retrieve_current_desktop_and_viewport ();  // au cas ou on enleve le bureau courant.
384
 
        
385
 
        cairo_dock_notify (CAIRO_DOCK_SCREEN_GEOMETRY_ALTERED);
386
 
}
387
 
 
388
 
static void _on_change_desktop_geometry (void)
389
 
{
390
 
        if (cairo_dock_update_screen_geometry ())  // modification de la resolution.
391
 
        {
392
 
                cd_message ("resolution alteree");
393
 
                cairo_dock_reposition_root_docks (FALSE);  // main dock compris.
394
 
        }
395
 
        
396
 
        cairo_dock_get_nb_viewports (&g_iNbViewportX, &g_iNbViewportY);
397
 
        _cairo_dock_retrieve_current_desktop_and_viewport ();  // au cas ou on enleve le viewport courant.
398
 
        
399
 
        cairo_dock_notify (CAIRO_DOCK_SCREEN_GEOMETRY_ALTERED);
400
 
}
401
 
 
402
 
static void _on_change_window_state (Icon *icon)
403
 
{
404
 
        Window Xid = icon->Xid;
405
 
        gboolean bIsFullScreen, bIsHidden, bIsMaximized, bDemandsAttention, bPrevHidden = icon->bIsHidden;
406
 
        if (! cairo_dock_xwindow_is_fullscreen_or_hidden_or_maximized (Xid, &bIsFullScreen, &bIsHidden, &bIsMaximized, &bDemandsAttention))
407
 
        {
408
 
                g_print ("Special case : this appli (%s, %ld) should be ignored from now !\n", icon->cName, Xid);
409
 
                CairoDock *pParentDock = cairo_dock_detach_appli (icon);
410
 
                if (pParentDock != NULL)
411
 
                        gtk_widget_queue_draw (pParentDock->container.pWidget);
412
 
                cairo_dock_free_icon (icon);
413
 
                cairo_dock_blacklist_appli (Xid);
414
 
                return ;
415
 
        }
416
 
        
417
 
        // demande d'attention.
418
 
        if (bDemandsAttention && (myTaskBar.bDemandsAttentionWithDialog || myTaskBar.cAnimationOnDemandsAttention))  // elle peut demander l'attention plusieurs fois de suite.
419
 
        {
420
 
                cd_debug ("%s demande votre attention %s !", icon->cName, icon->bIsDemandingAttention?"encore une fois":"");
421
 
                cairo_dock_appli_demands_attention (icon);
422
 
        }
423
 
        else if (! bDemandsAttention)
424
 
        {
425
 
                if (icon->bIsDemandingAttention)
426
 
                {
427
 
                        cd_debug ("%s se tait", icon->cName);
428
 
                        cairo_dock_appli_stops_demanding_attention (icon);  // ca c'est plus une precaution qu'autre chose.
429
 
                }
430
 
        }
431
 
        
432
 
        // auto-hide on maximised/fullscreen windows.
433
 
        if (myAccessibility.bAutoHideOnMaximized || myAccessibility.bAutoHideOnFullScreen)
434
 
        {
435
 
                if ((bIsMaximized != icon->bIsMaximized) ||
436
 
                        ((bIsMaximized || bIsFullScreen) && bIsHidden != icon->bIsHidden) ||
437
 
                        (bIsFullScreen != icon->bIsFullScreen))  // changement dans l'etat.
438
 
                {
439
 
                        icon->bIsMaximized = bIsMaximized;
440
 
                        icon->bIsFullScreen = bIsFullScreen;
441
 
                        icon->bIsHidden = bIsHidden;
442
 
                        
443
 
                        if ( ((bIsMaximized && ! bIsHidden && myAccessibility.bAutoHideOnMaximized) || (bIsFullScreen && ! bIsHidden && myAccessibility.bAutoHideOnFullScreen)) && ! cairo_dock_quick_hide_is_activated ())
444
 
                        {
445
 
                                cd_message (" => %s devient genante", CAIRO_DOCK_IS_APPLI (icon) ? icon->cName : "une fenetre");
446
 
                                if (CAIRO_DOCK_IS_APPLI (icon) && cairo_dock_appli_hovers_dock (icon, g_pMainDock))
447
 
                                        cairo_dock_activate_temporary_auto_hide ();
448
 
                        }
449
 
                        else if ((! bIsMaximized || ! myAccessibility.bAutoHideOnMaximized || bIsHidden) && (! bIsFullScreen || ! myAccessibility.bAutoHideOnFullScreen || bIsHidden) && cairo_dock_quick_hide_is_activated ())
450
 
                        {
451
 
                                if (cairo_dock_search_window_on_our_way (g_pMainDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
452
 
                                {
453
 
                                        cd_message (" => plus aucune fenetre genante");
454
 
                                        cairo_dock_deactivate_temporary_auto_hide ();
455
 
                                }
456
 
                        }
457
 
                }
458
 
        }
459
 
        icon->bIsMaximized = bIsMaximized;
460
 
        icon->bIsFullScreen = bIsFullScreen;
461
 
        
462
 
        // on gere le cachage/apparition de l'icone (transparence ou miniature, applis minimisees seulement).
463
 
        CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
464
 
        if (bIsHidden != bPrevHidden)
465
 
        {
466
 
                cd_message ("  changement de visibilite -> %d", bIsHidden);
467
 
                icon->bIsHidden = bIsHidden;
468
 
                
469
 
                // affichage des applis minimisees.
470
 
                if (g_bUseOpenGL && myTaskBar.iMinimizedWindowRenderType == 2)
471
 
                {
472
 
                        CairoDock *pDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
473
 
                        if (pDock != NULL)
474
 
                        {
475
 
                                cairo_dock_draw_hidden_appli_icon (icon, CAIRO_CONTAINER (pDock), TRUE);
476
 
                        }
477
 
                }
478
 
                else if (myTaskBar.iMinimizedWindowRenderType == 0)
479
 
                {
480
 
                        // transparence sur les inhibiteurs.
481
 
                        cairo_dock_update_visibility_on_inhibators (icon->cClass, icon->Xid, icon->bIsHidden);
482
 
                }
483
 
                
484
 
                // applis minimisees seulement
485
 
                if (myTaskBar.bHideVisibleApplis)  // on insere/detache l'icone selon la visibilite de la fenetre, avec une animation.
486
 
                {
487
 
                        if (bIsHidden)  // se cache => on insere son icone.
488
 
                        {
489
 
                                cd_message (" => se cache");
490
 
                                if (! myTaskBar.bAppliOnCurrentDesktopOnly || cairo_dock_appli_is_on_current_desktop (icon))
491
 
                                {
492
 
                                        pParentDock = cairo_dock_insert_appli_in_dock (icon, g_pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
493
 
                                        if (pParentDock != NULL)
494
 
                                        {
495
 
                                                if (g_bUseOpenGL && myTaskBar.iMinimizedWindowRenderType == 2)  // quand on est passe dans ce cas tout a l'heure l'icone n'etait pas encore dans son dock.
496
 
                                                        cairo_dock_draw_hidden_appli_icon (icon, CAIRO_CONTAINER (pParentDock), TRUE);
497
 
                                                gtk_widget_queue_draw (pParentDock->container.pWidget);
498
 
                                        }
499
 
                                }
500
 
                        }
501
 
                        else  // se montre => on detache l'icone.
502
 
                        {
503
 
                                cd_message (" => re-apparait");
504
 
                                cairo_dock_trigger_icon_removal_from_dock (icon);
505
 
                        }
506
 
                }
507
 
                else if (myTaskBar.fVisibleAppliAlpha != 0)  // transparence
508
 
                {
509
 
                        icon->fAlpha = 1;  // on triche un peu.
510
 
                        if (pParentDock != NULL)
511
 
                                cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pParentDock));
512
 
                }
513
 
                
514
 
                // miniature (on le fait apres l'avoir inseree/detachee, car comme ļæ½a dans le cas ou on l'enleve du dock apres l'avoir deminimisee, l'icone est marquee comme en cours de suppression, et donc on ne recharge pas son icone. Sinon l'image change pendant la transition, ce qui est pas top. Comme ca ne change pas la taille de l'icone dans le dock, on peut faire ca apres l'avoir inseree.
515
 
                #ifdef HAVE_XEXTEND
516
 
                if (myTaskBar.iMinimizedWindowRenderType == 1 && (pParentDock != NULL || myTaskBar.bHideVisibleApplis))  // on recupere la miniature ou au contraire on remet l'icone.
517
 
                {
518
 
                        if (! icon->bIsHidden)  // fenetre mappee => BackingPixmap disponible.
519
 
                        {
520
 
                                if (icon->iBackingPixmap != 0)
521
 
                                        XFreePixmap (s_XDisplay, icon->iBackingPixmap);
522
 
                                if (myTaskBar.iMinimizedWindowRenderType == 1)
523
 
                                        icon->iBackingPixmap = XCompositeNameWindowPixmap (s_XDisplay, Xid);
524
 
                                else
525
 
                                        icon->iBackingPixmap = 0;
526
 
                                cd_message ("new backing pixmap (bis) : %d", icon->iBackingPixmap);
527
 
                        }
528
 
                        // on redessine avec ou sans la miniature.
529
 
                        cairo_dock_reload_one_icon_buffer_in_dock (icon, pParentDock ? pParentDock : g_pMainDock);
530
 
                        if (pParentDock)
531
 
                                cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pParentDock));
532
 
                }
533
 
                #endif
534
 
        }
535
 
}
536
 
 
537
 
static void _on_change_window_desktop (Icon *icon)
538
 
{
539
 
        Window Xid = icon->Xid;
540
 
        icon->iNumDesktop = cairo_dock_get_xwindow_desktop (Xid);
541
 
        
542
 
        // applis du bureau courant seulement.
543
 
        if (myTaskBar.bAppliOnCurrentDesktopOnly)
544
 
        {
545
 
                _cairo_dock_hide_show_windows_on_other_desktops (&Xid, icon, g_pMainDock);  // si elle vient sur notre bureau, elle n'est pas forcement sur le meme viewport, donc il faut le verifier.
546
 
        }
547
 
        
548
 
        // auto-hide sur appli maximisee/plein-ecran
549
 
        if ((myAccessibility.bAutoHideOnMaximized && icon->bIsMaximized && ! icon->bIsHidden) || (myAccessibility.bAutoHideOnFullScreen && icon->bIsFullScreen && ! icon->bIsHidden))  // cette fenetre peut provoquer l'auto-hide.
550
 
        {
551
 
                if (! cairo_dock_quick_hide_is_activated () && (icon->iNumDesktop == -1 || icon->iNumDesktop == s_iCurrentDesktop))  // l'appli arrive sur le bureau courant.
552
 
                {
553
 
                        gpointer data[3] = {GINT_TO_POINTER (myAccessibility.bAutoHideOnMaximized), GINT_TO_POINTER (myAccessibility.bAutoHideOnFullScreen), g_pMainDock};
554
 
                        if (_cairo_dock_window_is_on_our_way (&Xid, icon, data))  // on s'assure qu'en plus d'etre sur le bureau courant, elle est aussi sur le viewport courant.
555
 
                        {
556
 
                                cd_message (" => cela nous gene");
557
 
                                cairo_dock_activate_temporary_auto_hide ();
558
 
                        }
559
 
                }
560
 
                else if (cairo_dock_quick_hide_is_activated () && (icon->iNumDesktop != -1 && icon->iNumDesktop != s_iCurrentDesktop))  // l'appli quitte sur le bureau courant.
561
 
                {
562
 
                        if (cairo_dock_search_window_on_our_way (g_pMainDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
563
 
                        {
564
 
                                cd_message (" => plus aucune fenetre genante");
565
 
                                cairo_dock_deactivate_temporary_auto_hide ();
566
 
                        }
567
 
                }
568
 
        }
569
 
}
570
 
 
571
 
static void _on_change_window_size_position (Icon *icon, XConfigureEvent *e)
572
 
{
573
 
        Window Xid = icon->Xid;
574
 
        
575
 
        #ifdef HAVE_XEXTEND
576
 
        if (e->width != icon->windowGeometry.width || e->height != icon->windowGeometry.height)
577
 
        {
578
 
                if (icon->iBackingPixmap != 0)
579
 
                        XFreePixmap (s_XDisplay, icon->iBackingPixmap);
580
 
                if (myTaskBar.iMinimizedWindowRenderType == 1)
581
 
                {
582
 
                        icon->iBackingPixmap = XCompositeNameWindowPixmap (s_XDisplay, Xid);
583
 
                        cd_message ("new backing pixmap : %d", icon->iBackingPixmap);
584
 
                }
585
 
                else
586
 
                        icon->iBackingPixmap = 0;
587
 
        }
588
 
        #endif
589
 
        icon->windowGeometry.width = e->width;
590
 
        icon->windowGeometry.height = e->height;
591
 
        icon->windowGeometry.x = e->x;
592
 
        icon->windowGeometry.y = e->y;
593
 
        
594
 
        // on regarde si l'appli a change de viewport.
595
 
        if (e->x + e->width <= 0 || e->x >= g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] || e->y + e->height <= 0 || e->y >= g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])  // en fait il faudrait faire ca modulo le nombre de viewports * la largeur d'un bureau, car avec une fenetre a droite, elle peut revenir sur le bureau par la gauche si elle est tres large...
596
 
        {
597
 
                // applis du bureau courant seulement.
598
 
                if (myTaskBar.bAppliOnCurrentDesktopOnly && icon->cParentDockName != NULL)
599
 
                {
600
 
                        CairoDock *pParentDock = cairo_dock_detach_appli (icon);
601
 
                        if (pParentDock)
602
 
                                gtk_widget_queue_draw (pParentDock->container.pWidget);
603
 
                }
604
 
                
605
 
                // auto-hide sur appli maximisee/plein-ecran
606
 
                if ((myAccessibility.bAutoHideOnMaximized && icon->bIsMaximized && ! icon->bIsHidden) || (myAccessibility.bAutoHideOnFullScreen && icon->bIsFullScreen && ! icon->bIsHidden))  // cette fenetre peut provoquer l'auto-hide.
607
 
                {
608
 
                        if (cairo_dock_quick_hide_is_activated ())
609
 
                        {
610
 
                                if (cairo_dock_search_window_on_our_way (g_pMainDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
611
 
                                {
612
 
                                        cd_message (" chgt de viewport => plus aucune fenetre genante");
613
 
                                        cairo_dock_deactivate_temporary_auto_hide ();
614
 
                                }
615
 
                        }
616
 
                }
617
 
        }
618
 
        else  // elle est sur le bureau.
619
 
        {
620
 
                // applis du bureau courant seulement.
621
 
                if (myTaskBar.bAppliOnCurrentDesktopOnly && icon->cParentDockName == NULL)
622
 
                {
623
 
                        cd_message ("cette fenetre est sur le bureau courant (%d;%d)", e->x, e->y);
624
 
                        gboolean bInsideDock = (icon->cParentDockName != NULL);  // jamais verifie mais ca devrait etre bon.
625
 
                        if (! bInsideDock)
626
 
                                cairo_dock_insert_appli_in_dock (icon, g_pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
627
 
                }
628
 
                
629
 
                // auto-hide sur appli maximisee/plein-ecran
630
 
                if ((myAccessibility.bAutoHideOnMaximized && icon->bIsMaximized && ! icon->bIsHidden) || (myAccessibility.bAutoHideOnFullScreen && icon->bIsFullScreen && ! icon->bIsHidden))  // cette fenetre peut provoquer l'auto-hide.
631
 
                {
632
 
                        if (! cairo_dock_quick_hide_is_activated ())
633
 
                        {
634
 
                                cd_message (" sur le viewport courant => cela nous gene");
635
 
                                cairo_dock_activate_temporary_auto_hide ();
636
 
                        }
637
 
                }
638
 
        }
639
 
        
640
 
        cairo_dock_notify (CAIRO_DOCK_WINDOW_CONFIGURED, e);
641
 
}
642
 
 
643
 
static void _on_change_window_name (Icon *icon, CairoDock *pDock, gboolean bSearchWmName)
644
 
{
645
 
        gchar *cName = cairo_dock_get_xwindow_name (icon->Xid, bSearchWmName);
646
 
        if (cName != NULL)
647
 
        {
648
 
                if (icon->cName == NULL || strcmp (icon->cName, cName) != 0)
649
 
                {
650
 
                        g_free (icon->cName);
651
 
                        icon->cName = cName;
652
 
                        
653
 
                        cairo_t* pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDock));
654
 
                        cairo_dock_fill_one_text_buffer (icon, pCairoContext, &myLabels.iconTextDescription);
655
 
                        cairo_destroy (pCairoContext);
656
 
                        
657
 
                        cairo_dock_update_name_on_inhibators (icon->cClass, icon->Xid, icon->cName);
658
 
                }
659
 
                else
660
 
                        g_free (cName);
661
 
        }
662
 
}
663
 
 
664
 
static void _on_change_window_icon (Icon *icon, CairoDock *pDock)
665
 
{
666
 
        if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons)
667
 
        {
668
 
                cairo_dock_reload_one_icon_buffer_in_dock (icon, pDock);
669
 
                if (pDock->iRefCount != 0)
670
 
                        cairo_dock_trigger_redraw_subdock_content (pDock);
671
 
                cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pDock));
672
 
        }
673
 
}
674
 
 
675
 
static void _on_change_window_hints (Icon *icon, CairoDock *pDock, int iState)
676
 
{
677
 
        XWMHints *pWMHints = XGetWMHints (s_XDisplay, icon->Xid);
678
 
        if (pWMHints != NULL)
679
 
        {
680
 
                if ((pWMHints->flags & XUrgencyHint) && (myTaskBar.bDemandsAttentionWithDialog || myTaskBar.cAnimationOnDemandsAttention))
681
 
                {
682
 
                        if (iState == PropertyNewValue)
683
 
                        {
684
 
                                cd_debug ("%s vous interpelle !", icon->cName);
685
 
                                cairo_dock_appli_demands_attention (icon);
686
 
                        }
687
 
                        else if (iState == PropertyDelete)
688
 
                        {
689
 
                                cd_debug ("%s arrette de vous interpeler.", icon->cName);
690
 
                                cairo_dock_appli_stops_demanding_attention (icon);
691
 
                        }
692
 
                        else
693
 
                                cd_warning ("  etat du changement d'urgence inconnu sur %s !", icon->cName);
694
 
                }
695
 
                if (iState == PropertyNewValue && (pWMHints->flags & (IconPixmapHint | IconMaskHint | IconWindowHint)))
696
 
                {
697
 
                        //g_print ("%s change son icone\n", icon->cName);
698
 
                        if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons)
699
 
                        {
700
 
                                cairo_dock_reload_one_icon_buffer_in_dock (icon, pDock);
701
 
                                if (pDock->iRefCount != 0)
702
 
                                        cairo_dock_trigger_redraw_subdock_content (pDock);
703
 
                                cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pDock));
704
 
                        }
705
 
                }
706
 
        }
707
 
}
708
 
 
709
 
static gboolean _cairo_dock_unstack_Xevents (gpointer data)
710
 
{
711
 
        static XEvent event;
712
 
        static gboolean bCheckMouseIsOutside = FALSE;
713
 
        
714
 
        CairoDock *pDock = g_pMainDock;
715
 
        if (!pDock)  // peut arriver en cours de chargement d'un theme.
716
 
                return TRUE;
717
 
        
718
 
        long event_mask = 0xFFFFFFFF;  // on les recupere tous, ca vide la pile au fur et a mesure plutot que tout a la fin.
719
 
        Window Xid;
720
 
        Window root = DefaultRootWindow (s_XDisplay);
721
 
        Icon *icon;
722
 
        if (bCheckMouseIsOutside)
723
 
        {
724
 
                //g_print ("bCheckMouseIsOutside\n");
725
 
                bCheckMouseIsOutside = FALSE;
726
 
                if (pDock->container.bIsHorizontal)
727
 
                        gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
728
 
                else
729
 
                        gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
730
 
                cairo_dock_calculate_dock_icons (pDock);  // pour faire retrecir le dock si on n'est pas dedans, merci X de nous faire sortir du dock alors que la souris est toujours dedans :-/
731
 
        }
732
 
        
733
 
        while (XCheckMaskEvent (s_XDisplay, event_mask, &event))
734
 
        {
735
 
                icon = NULL;
736
 
                Xid = event.xany.window;
737
 
                //g_print ("  type : %d; atom : %s; window : %d\n", event.type, gdk_x11_get_xatom_name (event.xproperty.atom), Xid);
738
 
                //if (event.type == ClientMessage)
739
 
                //cd_message ("\n\n\n >>>>>>>>>>>< event.type : %d\n\n", event.type);
740
 
                if (Xid == root)
741
 
                {
742
 
                        if (event.type == PropertyNotify)  // PropertyNotify sur root
743
 
                        {
744
 
                                if (event.xproperty.atom == s_aNetClientList && myTaskBar.bShowAppli)
745
 
                                {
746
 
                                        s_iTime ++;
747
 
                                        on_update_applis_list (pDock, s_iTime);
748
 
                                        cairo_dock_notify (CAIRO_DOCK_WINDOW_CONFIGURED, NULL);
749
 
                                }
750
 
                                else if (event.xproperty.atom == s_aNetActiveWindow)
751
 
                                {
752
 
                                        _on_change_active_window ();
753
 
                                }
754
 
                                else if (event.xproperty.atom == s_aNetCurrentDesktop || event.xproperty.atom == s_aNetDesktopViewport)
755
 
                                {
756
 
                                        bCheckMouseIsOutside = _on_change_current_desktop_viewport ();
757
 
                                }
758
 
                                else if (event.xproperty.atom == s_aNetNbDesktops)
759
 
                                {
760
 
                                        _on_change_nb_desktops ();
761
 
                                }
762
 
                                else if (event.xproperty.atom == s_aNetDesktopGeometry)
763
 
                                {
764
 
                                        _on_change_desktop_geometry ();
765
 
                                }
766
 
                                else if (event.xproperty.atom == s_aRootMapID)
767
 
                                {
768
 
                                        cd_debug ("change wallpaper");
769
 
                                        cairo_dock_reload_desktop_background ();
770
 
                                        cairo_dock_notify (CAIRO_DOCK_SCREEN_GEOMETRY_ALTERED);
771
 
                                }
772
 
                                else if (event.xproperty.atom == s_aNetShowingDesktop)
773
 
                                {
774
 
                                        cd_debug ("change desktop visibility");
775
 
                                        cairo_dock_notify (CAIRO_DOCK_DESKTOP_VISIBILITY_CHANGED);
776
 
                                }
777
 
                                else if (event.xproperty.atom == s_aXKlavierState)
778
 
                                {
779
 
                                        cairo_dock_notify (CAIRO_DOCK_KBD_STATE_CHANGED, NULL);
780
 
                                }
781
 
                        }  // fin de PropertyNotify sur root.
782
 
                }
783
 
                else if (myTaskBar.bShowAppli)  // evenement sur une fenetre.
784
 
                {
785
 
                        icon = g_hash_table_lookup (s_hXWindowTable, &Xid);
786
 
                        if (! CAIRO_DOCK_IS_APPLI (icon))  // appli blacklistee
787
 
                        {
788
 
                                if (! cairo_dock_xwindow_skip_taskbar (Xid))
789
 
                                {
790
 
                                        g_print ("Special case : this appli (%ld) should not be ignored any more!\n", Xid);
791
 
                                        g_hash_table_remove (s_hXWindowTable, &Xid);
792
 
                                        g_free (icon);
793
 
                                }
794
 
                                continue;
795
 
                        }
796
 
                        /**else if (icon->fInsertRemoveFactor > 0)  // pour une icone en cours de supression, on ne fait rien.
797
 
                        {
798
 
                                continue;
799
 
                        }*/
800
 
                        if (event.type == PropertyNotify)  // PropertyNotify sur une fenetre
801
 
                        {
802
 
                                if (event.xproperty.atom == s_aNetWmState)  // changement d'etat (hidden, maximized, fullscreen, demands attention)
803
 
                                {
804
 
                                        _on_change_window_state (icon);
805
 
                                }
806
 
                                else if (event.xproperty.atom == s_aNetWmDesktop)  // cela ne gere pas les changements de viewports, qui eux se font en changeant les coordonnees. Il faut donc recueillir les ConfigureNotify, qui donnent les redimensionnements et les deplacements.
807
 
                                {
808
 
                                        _on_change_window_desktop (icon);
809
 
                                }
810
 
                                else if (event.xproperty.atom == s_aXKlavierState)
811
 
                                {
812
 
                                        cairo_dock_notify (CAIRO_DOCK_KBD_STATE_CHANGED, &Xid);
813
 
                                }
814
 
                                else
815
 
                                {
816
 
                                        CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
817
 
                                        if (pParentDock == NULL)
818
 
                                                pParentDock = pDock;
819
 
                                        int iState = event.xproperty.state;
820
 
                                        Atom aProperty = event.xproperty.atom;
821
 
                                        if (iState == PropertyNewValue && (aProperty == s_aNetWmName || aProperty == s_aWmName))
822
 
                                        {
823
 
                                                _on_change_window_name (icon, pParentDock, aProperty == s_aWmName);
824
 
                                        }
825
 
                                        else if (iState == PropertyNewValue && aProperty == s_aNetWmIcon)
826
 
                                        {
827
 
                                                _on_change_window_icon (icon, pParentDock);
828
 
                                        }
829
 
                                        else if (aProperty == s_aWmHints)
830
 
                                        {
831
 
                                                _on_change_window_hints (icon, pParentDock, iState);
832
 
                                        }
833
 
                                }
834
 
                        }
835
 
                        else if (event.type == ConfigureNotify && ! cairo_dock_icon_is_being_removed (icon))  // ConfigureNotify sur une fenetre.
836
 
                        {
837
 
                                //g_print ("  type : %d; (%d;%d) %dx%d window : %d\n", e->type, e->x, e->y, e->width, e->height, Xid);
838
 
                                // On met a jour la taille du backing pixmap.
839
 
                                _on_change_window_size_position (icon, &event.xconfigure);
840
 
                        }
841
 
                        /*else if (event.type == g_iDamageEvent + XDamageNotify)
842
 
                        {
843
 
                                XDamageNotifyEvent *e = (XDamageNotifyEvent *) &event;
844
 
                                g_print ("window %s has been damaged (%d;%d %dx%d)\n", e->drawable, e->area.x, e->area.y, e->area.width, e->area.height);
845
 
                                // e->drawable is the window ID of the damaged window
846
 
                                // e->geometry is the geometry of the damaged window    
847
 
                                // e->area     is the bounding rect for the damaged area        
848
 
                                // e->damage   is the damage handle returned by XDamageCreate()
849
 
                                // Subtract all the damage, repairing the window.
850
 
                                XDamageSubtract (s_XDisplay, e->damage, None, None);
851
 
                        }
852
 
                        else
853
 
                                g_print ("  type : %d (%d); window : %d\n", event.type, XDamageNotify, Xid);*/
854
 
                }  // fin d'evenement sur une fenetre.
855
 
        }
856
 
        if (XEventsQueued (s_XDisplay, QueuedAlready) != 0)
857
 
                XSync (s_XDisplay, True);  // True <=> discard.
858
 
        //g_print ("XEventsQueued : %d\n", XEventsQueued (s_XDisplay, QueuedAfterFlush));  // QueuedAlready, QueuedAfterReading, QueuedAfterFlush
859
 
        
860
 
        return TRUE;
861
 
}
862
 
 
863
 
void cairo_dock_start_listening_X_events (void)
864
 
{
865
 
        g_return_if_fail (s_iSidUpdateAppliList == 0);
866
 
        
867
 
        //\__________________ On recupere le bureau courant.
868
 
        _cairo_dock_retrieve_current_desktop_and_viewport ();
869
 
        
870
 
        //\__________________ On se met a l'ecoute des evenements X.
871
 
        Window root = DefaultRootWindow (s_XDisplay);
872
 
        cairo_dock_set_xwindow_mask (root, PropertyChangeMask /*| StructureNotifyMask | SubstructureNotifyMask | ResizeRedirectMask | SubstructureRedirectMask*/);
873
 
        
874
 
        //\__________________ On lance l'ecoute.
875
 
        s_iSidUpdateAppliList = g_timeout_add (CAIRO_DOCK_TASKBAR_CHECK_INTERVAL, (GSourceFunc) _cairo_dock_unstack_Xevents, (gpointer) NULL);  // un g_idle_add () consomme 90% de CPU ! :-/
876
 
}
877
 
 
878
 
void cairo_dock_stop_listening_X_events (void)  // le met seulement en pause.
879
 
{
880
 
        g_return_if_fail (s_iSidUpdateAppliList != 0);
881
 
        
882
 
        //\__________________ On arrete l'ecoute.
883
 
        g_source_remove (s_iSidUpdateAppliList);
884
 
        s_iSidUpdateAppliList = 0;
885
 
}
886
 
 
887
 
  /////////////////////////
888
 
 // X listener : access //
889
 
/////////////////////////
890
 
 
891
 
void cairo_dock_get_current_desktop_and_viewport (int *iCurrentDesktop, int *iCurrentViewportX, int *iCurrentViewportY)
892
 
{
893
 
        *iCurrentDesktop = s_iCurrentDesktop;
894
 
        *iCurrentViewportX = s_iCurrentViewportX;
895
 
        *iCurrentViewportY = s_iCurrentViewportY;
896
 
}
897
 
 
898
 
 
899
 
  ///////////////////////////
900
 
 // Applis manager : core //
901
 
///////////////////////////
902
 
 
903
 
void cairo_dock_initialize_application_manager (Display *pDisplay)
904
 
{
905
 
        s_XDisplay = pDisplay;
906
 
 
907
 
        s_hXWindowTable = g_hash_table_new_full (g_int_hash,
908
 
                g_int_equal,
909
 
                g_free,
910
 
                NULL);
911
 
        
912
 
        s_aNetClientList                = XInternAtom (s_XDisplay, "_NET_CLIENT_LIST_STACKING", False);
913
 
        s_aNetActiveWindow              = XInternAtom (s_XDisplay, "_NET_ACTIVE_WINDOW", False);
914
 
        s_aNetCurrentDesktop    = XInternAtom (s_XDisplay, "_NET_CURRENT_DESKTOP", False);
915
 
        s_aNetDesktopViewport   = XInternAtom (s_XDisplay, "_NET_DESKTOP_VIEWPORT", False);
916
 
        s_aNetDesktopGeometry   = XInternAtom (s_XDisplay, "_NET_DESKTOP_GEOMETRY", False);
917
 
        s_aNetWmState                   = XInternAtom (s_XDisplay, "_NET_WM_STATE", False);
918
 
        s_aNetWmName                    = XInternAtom (s_XDisplay, "_NET_WM_NAME", False);
919
 
        s_aUtf8String                   = XInternAtom (s_XDisplay, "UTF8_STRING", False);
920
 
        s_aWmName                               = XInternAtom (s_XDisplay, "WM_NAME", False);
921
 
        s_aString                               = XInternAtom (s_XDisplay, "STRING", False);
922
 
        s_aNetWmIcon                    = XInternAtom (s_XDisplay, "_NET_WM_ICON", False);
923
 
        s_aWmHints                              = XInternAtom (s_XDisplay, "WM_HINTS", False);
924
 
        s_aNetWmDesktop                 = XInternAtom (s_XDisplay, "_NET_WM_DESKTOP", False);
925
 
        s_aNetShowingDesktop    = XInternAtom (s_XDisplay, "_NET_SHOWING_DESKTOP", False);
926
 
        s_aRootMapID                    = XInternAtom (s_XDisplay, "_XROOTPMAP_ID", False);
927
 
        s_aNetNbDesktops                = XInternAtom (s_XDisplay, "_NET_NUMBER_OF_DESKTOPS", False);
928
 
        s_aXKlavierState                = XInternAtom (s_XDisplay, "XKLAVIER_STATE", False);
929
 
}
930
 
 
931
 
void cairo_dock_register_appli (Icon *icon)
932
 
{
933
 
        if (CAIRO_DOCK_IS_APPLI (icon))
934
 
        {
935
 
                cd_debug ("%s (%ld ; %s)", __func__, icon->Xid, icon->cName);
936
 
                Window *pXid = g_new (Window, 1);
937
 
                        *pXid = icon->Xid;
938
 
                g_hash_table_insert (s_hXWindowTable, pXid, icon);
939
 
                
940
 
                cairo_dock_add_appli_to_class (icon);
941
 
        }
942
 
}
943
 
 
944
 
void cairo_dock_blacklist_appli (Window Xid)
945
 
{
946
 
        if (Xid > 0)
947
 
        {
948
 
                cd_debug ("%s (%ld)", __func__, Xid);
949
 
                Window *pXid = g_new (Window, 1);
950
 
                        *pXid = Xid;
951
 
                Icon *pNullIcon = g_new0 (Icon, 1);
952
 
                pNullIcon->iLastCheckTime = s_iTime;
953
 
                g_hash_table_insert (s_hXWindowTable, pXid, pNullIcon);  // NULL
954
 
        }
955
 
}
956
 
 
957
 
void cairo_dock_unregister_appli (Icon *icon)
958
 
{
959
 
        if (CAIRO_DOCK_IS_APPLI (icon))
960
 
        {
961
 
                cd_message ("%s (%ld ; %s)", __func__, icon->Xid, icon->cName);
962
 
                if (icon->iLastCheckTime != -1)
963
 
                        g_hash_table_remove (s_hXWindowTable, &icon->Xid);
964
 
                
965
 
                if (icon->iBackingPixmap != 0)
966
 
                {
967
 
                        XFreePixmap (s_XDisplay, icon->iBackingPixmap);
968
 
                        icon->iBackingPixmap = 0;
969
 
                }
970
 
                
971
 
                cairo_dock_remove_appli_from_class (icon);  // n'efface pas sa classe (on peut en avoir besoin encore).
972
 
                cairo_dock_update_Xid_on_inhibators (icon->Xid, icon->cClass);
973
 
                
974
 
                icon->Xid = 0;  // hop, elle n'est plus une appli.
975
 
        }
976
 
}
977
 
 
978
 
 
979
 
void cairo_dock_start_application_manager (CairoDock *pDock)
980
 
{
981
 
        g_return_if_fail (!s_bAppliManagerIsRunning && myTaskBar.bShowAppli);
982
 
        
983
 
        cairo_dock_set_overwrite_exceptions (myTaskBar.cOverwriteException);
984
 
        cairo_dock_set_group_exceptions (myTaskBar.cGroupException);
985
 
        
986
 
        //\__________________ On recupere l'ensemble des fenetres presentes.
987
 
        gulong i, iNbWindows = 0;
988
 
        Window *pXWindowsList = cairo_dock_get_windows_list (&iNbWindows, FALSE);  // on recupere les fenetres par ordre de creation, de facon a ce que si on redemarre la barre des taches, les lanceurs soient lies aux memes fenetres. Au prochain update, la liste sera recuperee par z-order, ce qui remettra le z-order de chaque icone a jour.
989
 
 
990
 
        //\__________________ On cree les icones de toutes ces applis.
991
 
        cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDock));
992
 
        g_return_if_fail (cairo_status (pCairoContext) == CAIRO_STATUS_SUCCESS);
993
 
        
994
 
        CairoDock *pParentDock;
995
 
        gboolean bUpdateMainDockSize = FALSE;
996
 
        ///int iStackOrder = 0;
997
 
        Window Xid;
998
 
        Icon *pIcon;
999
 
        for (i = 0; i < iNbWindows; i ++)
1000
 
        {
1001
 
                Xid = pXWindowsList[i];
1002
 
                pIcon = cairo_dock_create_icon_from_xwindow (pCairoContext, Xid, pDock);
1003
 
                
1004
 
                if (pIcon != NULL)
1005
 
                {
1006
 
                        ///pIcon->iStackOrder = iStackOrder ++;
1007
 
                        pIcon->iLastCheckTime = s_iTime;
1008
 
                        if (/*(pIcon->bIsHidden || ! myTaskBar.bHideVisibleApplis) && */(! myTaskBar.bAppliOnCurrentDesktopOnly || cairo_dock_appli_is_on_current_desktop (pIcon)))
1009
 
                        {
1010
 
                                pParentDock = cairo_dock_insert_appli_in_dock (pIcon, pDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
1011
 
                                //g_print (">>>>>>>>>>>> Xid : %d\n", Xid);
1012
 
                                if (pParentDock != NULL)
1013
 
                                {
1014
 
                                        if (pParentDock->bIsMainDock)
1015
 
                                                bUpdateMainDockSize = TRUE;
1016
 
                                        else
1017
 
                                                cairo_dock_update_dock_size (pParentDock);
1018
 
                                }
1019
 
                        }
1020
 
                        else if (myTaskBar.bMixLauncherAppli)  // on met tout de meme l'indicateur sur le lanceur.
1021
 
                        {
1022
 
                                cairo_dock_prevent_inhibated_class (pIcon);
1023
 
                        }
1024
 
                        if ((myAccessibility.bAutoHideOnMaximized && pIcon->bIsMaximized) || (myAccessibility.bAutoHideOnFullScreen && pIcon->bIsFullScreen))
1025
 
                        {
1026
 
                                if (! cairo_dock_quick_hide_is_activated () && cairo_dock_appli_is_on_current_desktop (pIcon))
1027
 
                                {
1028
 
                                        if (cairo_dock_appli_hovers_dock (pIcon, pDock))
1029
 
                                        {
1030
 
                                                cd_message (" elle empiete sur notre dock");
1031
 
                                                cairo_dock_activate_temporary_auto_hide ();
1032
 
                                        }
1033
 
                                }
1034
 
                        }
1035
 
                }
1036
 
                else
1037
 
                        cairo_dock_blacklist_appli (Xid);
1038
 
        }
1039
 
        cairo_destroy (pCairoContext);
1040
 
        if (pXWindowsList != NULL)
1041
 
                XFree (pXWindowsList);
1042
 
        
1043
 
        if (bUpdateMainDockSize)
1044
 
                cairo_dock_update_dock_size (pDock);
1045
 
        
1046
 
        s_bAppliManagerIsRunning = TRUE;
1047
 
        
1048
 
        if (s_iCurrentActiveWindow == 0)
1049
 
                s_iCurrentActiveWindow = cairo_dock_get_active_xwindow ();
1050
 
}
1051
 
 
1052
 
static gboolean _cairo_dock_reset_appli_table_iter (Window *pXid, Icon *pIcon, gpointer data)
1053
 
{
1054
 
        if (pIcon == NULL)
1055
 
                return TRUE;
1056
 
        if (pIcon->Xid == 0)
1057
 
        {
1058
 
                g_free (pIcon);
1059
 
                return TRUE;
1060
 
        }
1061
 
        
1062
 
        CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
1063
 
        if (pDock != NULL)
1064
 
        {
1065
 
                gchar *cParentDockName = pIcon->cParentDockName;
1066
 
                pIcon->cParentDockName = NULL;  // astuce.
1067
 
                cairo_dock_detach_icon_from_dock (pIcon, pDock, myIcons.iSeparateIcons);
1068
 
                if (! pDock->bIsMainDock)  // la taille du main dock est mis a jour 1 fois a la fin.
1069
 
                {
1070
 
                        if (pDock->icons == NULL)  // le dock degage, le fake aussi.
1071
 
                        {
1072
 
                                CairoDock *pFakeClassParentDock = NULL;
1073
 
                                Icon *pFakeClassIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pFakeClassParentDock);
1074
 
                                if (CAIRO_DOCK_IS_FAKE_LAUNCHER (pFakeClassIcon))
1075
 
                                //if (pFakeClassIcon != NULL && ! CAIRO_DOCK_IS_APPLI (pFakeClassIcon) && ! CAIRO_DOCK_IS_APPLET (pFakeClassIcon) && ! CAIRO_DOCK_IS_NORMAL_LAUNCHER (pFakeClassIcon) && pFakeClassIcon->cClass != NULL && pFakeClassIcon->cName != NULL && strcmp (pFakeClassIcon->cClass, pFakeClassIcon->cName) == 0)  // stop la parano.
1076
 
                                {
1077
 
                                        cd_debug ("on degage le fake qui pointe sur %s", cParentDockName);
1078
 
                                        cairo_dock_detach_icon_from_dock (pFakeClassIcon, pFakeClassParentDock, myIcons.iSeparateIcons);
1079
 
                                        cairo_dock_free_icon (pFakeClassIcon);
1080
 
                                        if (! pFakeClassParentDock->bIsMainDock)
1081
 
                                                cairo_dock_update_dock_size (pFakeClassParentDock);
1082
 
                                }
1083
 
                                
1084
 
                                cairo_dock_destroy_dock (pDock, cParentDockName, NULL, NULL);
1085
 
                        }
1086
 
                        else
1087
 
                                cairo_dock_update_dock_size (pDock);
1088
 
                }
1089
 
                g_free (cParentDockName);
1090
 
        }
1091
 
        
1092
 
        pIcon->Xid = 0;  // on ne veut pas passer dans le 'unregister'
1093
 
        g_free (pIcon->cClass);  // ni la gestion de la classe.
1094
 
        pIcon->cClass = NULL;
1095
 
        cairo_dock_free_icon (pIcon);
1096
 
        return TRUE;
1097
 
}
1098
 
void cairo_dock_stop_application_manager (void)
1099
 
{
1100
 
        s_bAppliManagerIsRunning = FALSE;
1101
 
        
1102
 
        cairo_dock_remove_all_applis_from_class_table ();  // enleve aussi les indicateurs.
1103
 
        
1104
 
        g_hash_table_foreach_remove (s_hXWindowTable, (GHRFunc) _cairo_dock_reset_appli_table_iter, NULL);  // libere toutes les icones d'appli.
1105
 
        cairo_dock_update_dock_size (g_pMainDock);
1106
 
        
1107
 
        if (cairo_dock_quick_hide_is_activated ())
1108
 
                cairo_dock_deactivate_temporary_auto_hide ();
1109
 
}
1110
 
 
1111
 
gboolean cairo_dock_application_manager_is_running (void)
1112
 
{
1113
 
        return s_bAppliManagerIsRunning;
1114
 
}
1115
 
 
1116
 
 
1117
 
 
1118
 
  /////////////////////////////
1119
 
 // Applis manager : access //
1120
 
/////////////////////////////
1121
 
 
1122
 
static gboolean _cairo_dock_window_is_on_our_way (Window *Xid, Icon *icon, gpointer *data)
1123
 
{
1124
 
        gboolean bMaximizedWindow = GPOINTER_TO_INT (data[0]);
1125
 
        gboolean bFullScreenWindow = GPOINTER_TO_INT (data[1]);
1126
 
        CairoDock *pDock = data[2];
1127
 
        if (CAIRO_DOCK_IS_APPLI (icon) && cairo_dock_appli_is_on_current_desktop (icon) && ! cairo_dock_icon_is_being_removed (icon) && icon->iLastCheckTime != -1)
1128
 
        {
1129
 
                if ((data[0] && icon->bIsMaximized && ! icon->bIsHidden) || (data[1] && icon->bIsFullScreen && ! icon->bIsHidden) || (!data[0] && ! data[1] && ! icon->bIsHidden))
1130
 
                {
1131
 
                        cd_debug ("%s est genante (%d, %d) (%d;%d %dx%d)", icon->cName, icon->bIsMaximized, icon->bIsFullScreen, icon->windowGeometry.x, icon->windowGeometry.y, icon->windowGeometry.width, icon->windowGeometry.height);
1132
 
                        if (cairo_dock_appli_hovers_dock (icon, pDock))
1133
 
                        {
1134
 
                                cd_debug (" et en plus elle empiete sur notre dock");
1135
 
                                return TRUE;
1136
 
                        }
1137
 
                }
1138
 
        }
1139
 
        return FALSE;
1140
 
}
1141
 
Icon * cairo_dock_search_window_on_our_way (CairoDock *pDock, gboolean bMaximizedWindow, gboolean bFullScreenWindow)
1142
 
{
1143
 
        //cd_debug ("%s (%d, %d)", __func__, bMaximizedWindow, bFullScreenWindow);
1144
 
        gpointer data[3] = {GINT_TO_POINTER (bMaximizedWindow), GINT_TO_POINTER (bFullScreenWindow), pDock};
1145
 
        return g_hash_table_find (s_hXWindowTable, (GHRFunc) _cairo_dock_window_is_on_our_way, data);
1146
 
}
1147
 
 
1148
 
 
1149
 
GList *cairo_dock_get_current_applis_list (void)
1150
 
{
1151
 
        return g_hash_table_get_values (s_hXWindowTable);
1152
 
}
1153
 
 
1154
 
Window cairo_dock_get_current_active_window (void)
1155
 
{
1156
 
        return s_iCurrentActiveWindow;
1157
 
}
1158
 
 
1159
 
Icon *cairo_dock_get_current_active_icon (void)
1160
 
{
1161
 
        Icon *pIcon = g_hash_table_lookup (s_hXWindowTable, &s_iCurrentActiveWindow);
1162
 
        if (CAIRO_DOCK_IS_APPLI (pIcon))
1163
 
                return pIcon;
1164
 
        else
1165
 
                return NULL;
1166
 
}
1167
 
 
1168
 
Icon *cairo_dock_get_icon_with_Xid (Window Xid)
1169
 
{
1170
 
        Icon *pIcon = g_hash_table_lookup (s_hXWindowTable, &Xid);
1171
 
        if (CAIRO_DOCK_IS_APPLI (pIcon))
1172
 
                return pIcon;
1173
 
        else
1174
 
                return NULL;
1175
 
}
1176
 
 
1177
 
 
1178
 
static void _cairo_dock_for_one_appli (Window *Xid, Icon *icon, gpointer *data)
1179
 
{
1180
 
        if (! CAIRO_DOCK_IS_APPLI (icon) || cairo_dock_icon_is_being_removed (icon))
1181
 
                return ;
1182
 
        CairoDockForeachIconFunc pFunction = data[0];
1183
 
        gpointer pUserData = data[1];
1184
 
        gboolean bOutsideDockOnly =  GPOINTER_TO_INT (data[2]);
1185
 
        
1186
 
        if ((bOutsideDockOnly && icon->cParentDockName == NULL) || ! bOutsideDockOnly)
1187
 
        {
1188
 
                CairoDock *pParentDock = NULL;
1189
 
                if (icon->cParentDockName != NULL)
1190
 
                        pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
1191
 
                else
1192
 
                        pParentDock = g_pMainDock;
1193
 
                pFunction (icon, CAIRO_CONTAINER (pParentDock), pUserData);
1194
 
        }
1195
 
}
1196
 
void cairo_dock_foreach_applis (CairoDockForeachIconFunc pFunction, gboolean bOutsideDockOnly, gpointer pUserData)
1197
 
{
1198
 
        gpointer data[3] = {pFunction, pUserData, GINT_TO_POINTER (bOutsideDockOnly)};
1199
 
        g_hash_table_foreach (s_hXWindowTable, (GHFunc) _cairo_dock_for_one_appli, data);
1200
 
}
1201
 
 
1202
 
 
1203
 
static void _cairo_dock_for_one_appli_on_viewport (Icon *pIcon, CairoContainer *pContainer, gpointer *data)
1204
 
{
1205
 
        int iNumDesktop = GPOINTER_TO_INT (data[0]);
1206
 
        int iNumViewportX = GPOINTER_TO_INT (data[1]);
1207
 
        int iNumViewportY = GPOINTER_TO_INT (data[2]);
1208
 
        CairoDockForeachIconFunc pFunction = data[3];
1209
 
        gpointer pUserData = data[4];
1210
 
        
1211
 
        if (! cairo_dock_appli_is_on_desktop (pIcon, iNumDesktop, iNumViewportX, iNumViewportY))
1212
 
                return ;
1213
 
        
1214
 
        pFunction (pIcon, pContainer, pUserData);
1215
 
}
1216
 
void cairo_dock_foreach_applis_on_viewport (CairoDockForeachIconFunc pFunction, int iNumDesktop, int iNumViewportX, int iNumViewportY, gpointer pUserData)
1217
 
{
1218
 
        gpointer data[5] = {GINT_TO_POINTER (iNumDesktop), GINT_TO_POINTER (iNumViewportX), GINT_TO_POINTER (iNumViewportY), pFunction, pUserData};
1219
 
        cairo_dock_foreach_applis ((CairoDockForeachIconFunc) _cairo_dock_for_one_appli_on_viewport, FALSE, data);
1220
 
}
1221
 
 
1222
 
 
1223
 
  /////////////////////
1224
 
 // Applis facility //
1225
 
/////////////////////
1226
 
 
1227
 
void cairo_dock_set_icons_geometry_for_window_manager (CairoDock *pDock)
1228
 
{
1229
 
        if (! s_bAppliManagerIsRunning)
1230
 
                return ;
1231
 
        cd_debug ("%s (main:%d)", __func__, pDock->bIsMainDock);
1232
 
 
1233
 
        Icon *icon;
1234
 
        GList *ic;
1235
 
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
1236
 
        {
1237
 
                icon = ic->data;
1238
 
                if (CAIRO_DOCK_IS_APPLI (icon))
1239
 
                {
1240
 
                        cairo_dock_set_one_icon_geometry_for_window_manager (icon, pDock);
1241
 
                }
1242
 
        }
1243
 
        
1244
 
        if (pDock->bIsMainDock && myTaskBar.bHideVisibleApplis)  // on complete avec les applis pas dans le dock, pour que l'effet de minimisation pointe (a peu pres) au bon endroit quand on la minimisera.
1245
 
        {
1246
 
                g_hash_table_foreach (s_hXWindowTable, (GHFunc) cairo_dock_reserve_one_icon_geometry_for_window_manager, pDock);
1247
 
        }
1248
 
}
1249
 
 
1250
 
 
1251
 
gboolean cairo_dock_appli_is_on_desktop (Icon *pIcon, int iNumDesktop, int iNumViewportX, int iNumViewportY)
1252
 
{
1253
 
        // On calcule les coordonnees en repere absolu.
1254
 
        int x = pIcon->windowGeometry.x;  // par rapport au viewport courant.
1255
 
        x += s_iCurrentViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];  // repere absolu
1256
 
        if (x < 0)
1257
 
                x += g_iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
1258
 
        int y = pIcon->windowGeometry.y;
1259
 
        y += s_iCurrentViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1260
 
        if (y < 0)
1261
 
                y += g_iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1262
 
        int w = pIcon->windowGeometry.width, h = pIcon->windowGeometry.height;
1263
 
        
1264
 
        // test d'intersection avec le viewport donne.
1265
 
        return ((pIcon->iNumDesktop == -1 || pIcon->iNumDesktop == iNumDesktop) &&
1266
 
                x + w > iNumViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] &&
1267
 
                x < (iNumViewportX + 1) * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] &&
1268
 
                y + h > iNumViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] &&
1269
 
                y < (iNumViewportY + 1) * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
1270
 
}
1271
 
 
1272
 
gboolean cairo_dock_appli_is_on_current_desktop (Icon *pIcon)
1273
 
{
1274
 
        int iWindowDesktopNumber, iGlobalPositionX, iGlobalPositionY, iWidthExtent, iHeightExtent;  // coordonnees du coin haut gauche dans le referentiel du viewport actuel.
1275
 
        iWindowDesktopNumber = pIcon->iNumDesktop;
1276
 
        iGlobalPositionX = pIcon->windowGeometry.x;
1277
 
        iGlobalPositionY = pIcon->windowGeometry.y;
1278
 
        iWidthExtent = pIcon->windowGeometry.width;
1279
 
        iHeightExtent = pIcon->windowGeometry.height;
1280
 
 
1281
 
        return ( (iWindowDesktopNumber == s_iCurrentDesktop || iWindowDesktopNumber == -1) &&
1282
 
                iGlobalPositionX + iWidthExtent > 0 &&
1283
 
                iGlobalPositionX < g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] &&
1284
 
                iGlobalPositionY + iHeightExtent > 0 &&
1285
 
                iGlobalPositionY < g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] );  // -1 <=> 0xFFFFFFFF en unsigned.
1286
 
}