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/>.
29
#include <X11/Xatom.h>
30
#include <X11/Xutil.h>
32
#include <X11/extensions/Xcomposite.h>
33
//#include <X11/extensions/Xdamage.h>
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"
62
#define CAIRO_DOCK_TASKBAR_CHECK_INTERVAL 200
64
extern CairoDock *g_pMainDock;
66
extern int g_iXScreenWidth[2], g_iXScreenHeight[2];
68
extern int g_iNbDesktops;
69
extern int g_iNbViewportX,g_iNbViewportY ;
70
extern gboolean g_bUseOpenGL;
71
//extern int g_iDamageEvent;
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;
100
static gboolean _cairo_dock_window_is_on_our_way (Window *Xid, Icon *icon, gpointer *data);
102
///////////////////////
103
// X listener : core //
104
///////////////////////
106
static inline void _cairo_dock_retrieve_current_desktop_and_viewport (void)
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];
114
static void _cairo_dock_hide_show_windows_on_other_desktops (Window *Xid, Icon *icon, CairoDock *pMainDock)
116
if (CAIRO_DOCK_IS_APPLI (icon) && (! myTaskBar.bHideVisibleApplis || icon->bIsHidden))
118
cd_debug ("%s (%d)", __func__, *Xid);
119
CairoDock *pParentDock = NULL;
120
if (cairo_dock_appli_is_on_current_desktop (icon))
122
cd_debug (" => est sur le bureau actuel.");
123
if (icon->cParentDockName == NULL)
125
pParentDock = cairo_dock_insert_appli_in_dock (icon, pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
130
cd_debug (" => n'est pas sur le bureau actuel.");
131
pParentDock = cairo_dock_detach_appli (icon);
133
if (pParentDock != NULL)
134
gtk_widget_queue_draw (pParentDock->container.pWidget);
138
static gboolean _cairo_dock_remove_old_applis (Window *Xid, Icon *icon, gpointer iTimePtr)
142
gint iTime = GPOINTER_TO_INT (iTimePtr);
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))
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))
150
CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
151
if (pParentDock != NULL)
153
cd_message (" va etre supprimee");
154
cairo_dock_trigger_icon_removal_from_dock (icon);
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.
160
else // n'etait pas dans un dock, on la detruit donc immediatement.
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 ?...
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.
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.
174
cd_message (" => plus aucune fenetre genante");
175
cairo_dock_deactivate_temporary_auto_hide ();
187
static void on_update_applis_list (CairoDock *pDock, gint iTime)
189
gulong i, iNbWindows = 0;
190
Window *pXWindowsList = cairo_dock_get_windows_list (&iNbWindows, TRUE);
195
gpointer pOriginalXid;
196
gboolean bAppliAlreadyRegistered;
197
gboolean bUpdateMainDockSize = FALSE;
198
CairoDock *pParentDock;
199
cairo_t *pCairoContext = NULL;
201
for (i = 0; i < iNbWindows; i ++)
203
Xid = pXWindowsList[i];
205
bAppliAlreadyRegistered = g_hash_table_lookup_extended (s_hXWindowTable, &Xid, &pOriginalXid, (gpointer *) &icon);
206
if (! bAppliAlreadyRegistered)
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);
214
cd_warning ("couldn't create a cairo context => this window (%ld) will not have an icon", Xid);
217
icon->iLastCheckTime = iTime;
218
icon->iStackOrder = iStackOrder ++;
219
if (/*(icon->bIsHidden || ! myTaskBar.bHideVisibleApplis) && */(! myTaskBar.bAppliOnCurrentDesktopOnly || cairo_dock_xwindow_is_on_current_desktop (Xid)))
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)
225
if (pParentDock->bIsMainDock)
226
bUpdateMainDockSize = TRUE;
228
cairo_dock_update_dock_size (pParentDock);
231
else if (myTaskBar.bMixLauncherAppli) // on met tout de meme l'indicateur sur le lanceur.
233
cairo_dock_prevent_inhibated_class (icon);
235
if ((myAccessibility.bAutoHideOnMaximized && icon->bIsMaximized && ! icon->bIsHidden) || (myAccessibility.bAutoHideOnFullScreen && icon->bIsFullScreen && ! icon->bIsHidden))
237
if (! cairo_dock_quick_hide_is_activated ())
239
if (cairo_dock_xwindow_is_on_this_desktop (Xid, s_iCurrentDesktop) && cairo_dock_appli_hovers_dock (icon, pDock))
241
cd_message (" cette nouvelle fenetre empiete sur notre dock");
242
cairo_dock_activate_temporary_auto_hide ();
248
cairo_dock_blacklist_appli (Xid);
250
else if (icon != NULL)
252
icon->iLastCheckTime = iTime;
253
if (CAIRO_DOCK_IS_APPLI (icon))
254
icon->iStackOrder = iStackOrder ++;
257
if (pCairoContext != NULL)
258
cairo_destroy (pCairoContext);
260
g_hash_table_foreach_remove (s_hXWindowTable, (GHRFunc) _cairo_dock_remove_old_applis, GINT_TO_POINTER (iTime));
262
if (bUpdateMainDockSize)
263
cairo_dock_update_dock_size (pDock);
265
XFree (pXWindowsList);
268
static void _on_change_active_window (void)
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.
274
Icon *icon = g_hash_table_lookup (s_hXWindowTable, &XActiveWindow);
275
CairoDock *pParentDock = NULL;
276
if (CAIRO_DOCK_IS_APPLI (icon))
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);
281
pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
282
if (pParentDock == NULL) // elle est soit inhibee, soit pas dans un dock.
284
cairo_dock_update_activity_on_inhibators (icon->cClass, icon->Xid);
288
cairo_dock_animate_icon_on_active (icon, pParentDock);
292
gboolean bForceKbdStateRefresh = FALSE;
293
Icon *pLastActiveIcon = g_hash_table_lookup (s_hXWindowTable, &s_iCurrentActiveWindow);
294
if (CAIRO_DOCK_IS_APPLI (pLastActiveIcon))
296
CairoDock *pLastActiveParentDock = cairo_dock_search_dock_from_name (pLastActiveIcon->cParentDockName);
297
if (pLastActiveParentDock == NULL) // elle est soit inhibee, soit pas dans un dock.
299
cairo_dock_update_inactivity_on_inhibators (pLastActiveIcon->cClass, pLastActiveIcon->Xid);
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.
306
CairoDock *pMainDock = NULL;
307
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pLastActiveParentDock, &pMainDock);
308
if (pPointingIcon && pMainDock)
310
cairo_dock_redraw_icon (pPointingIcon, CAIRO_CONTAINER (pMainDock));
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);
324
static gboolean _on_change_current_desktop_viewport (void)
326
CairoDock *pDock = g_pMainDock;
328
_cairo_dock_retrieve_current_desktop_and_viewport ();
330
// applis du bureau courant seulement.
331
if (myTaskBar.bAppliOnCurrentDesktopOnly)
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);
337
cairo_dock_hide_show_launchers_on_other_desktops(pDock);
339
// auto-hide sur appli maximisee/plein-ecran
340
if (myAccessibility.bAutoHideOnFullScreen || myAccessibility.bAutoHideOnMaximized)
342
//g_print ("%s (%d)\n", __func__, cairo_dock_quick_hide_is_activated ());
343
if (cairo_dock_quick_hide_is_activated ())
345
if (cairo_dock_search_window_on_our_way (pDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
347
cd_message (" => plus aucune fenetre genante");
348
cairo_dock_deactivate_temporary_auto_hide ();
353
if (cairo_dock_search_window_on_our_way (pDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) != NULL)
355
cd_message (" => une fenetre est genante");
356
cairo_dock_activate_temporary_auto_hide ();
361
// on propage la notification.
362
cairo_dock_notify (CAIRO_DOCK_DESKTOP_CHANGED);
364
// on gere le cas delicat de X qui nous fait sortir du dock.
365
if (! pDock->bIsShrinkingDown && ! pDock->bIsGrowingUp)
367
if (pDock->container.bIsHorizontal)
368
gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
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)
375
//g_print (">>> %d;%d, %dx%d\n", pDock->container.iMouseX, pDock->container.iMouseY,pDock->container.iWidth, pDock->container.iHeight);
380
static void _on_change_nb_desktops (void)
382
g_iNbDesktops = cairo_dock_get_nb_desktops ();
383
_cairo_dock_retrieve_current_desktop_and_viewport (); // au cas ou on enleve le bureau courant.
385
cairo_dock_notify (CAIRO_DOCK_SCREEN_GEOMETRY_ALTERED);
388
static void _on_change_desktop_geometry (void)
390
if (cairo_dock_update_screen_geometry ()) // modification de la resolution.
392
cd_message ("resolution alteree");
393
cairo_dock_reposition_root_docks (FALSE); // main dock compris.
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.
399
cairo_dock_notify (CAIRO_DOCK_SCREEN_GEOMETRY_ALTERED);
402
static void _on_change_window_state (Icon *icon)
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))
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);
417
// demande d'attention.
418
if (bDemandsAttention && (myTaskBar.bDemandsAttentionWithDialog || myTaskBar.cAnimationOnDemandsAttention)) // elle peut demander l'attention plusieurs fois de suite.
420
cd_debug ("%s demande votre attention %s !", icon->cName, icon->bIsDemandingAttention?"encore une fois":"");
421
cairo_dock_appli_demands_attention (icon);
423
else if (! bDemandsAttention)
425
if (icon->bIsDemandingAttention)
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.
432
// auto-hide on maximised/fullscreen windows.
433
if (myAccessibility.bAutoHideOnMaximized || myAccessibility.bAutoHideOnFullScreen)
435
if ((bIsMaximized != icon->bIsMaximized) ||
436
((bIsMaximized || bIsFullScreen) && bIsHidden != icon->bIsHidden) ||
437
(bIsFullScreen != icon->bIsFullScreen)) // changement dans l'etat.
439
icon->bIsMaximized = bIsMaximized;
440
icon->bIsFullScreen = bIsFullScreen;
441
icon->bIsHidden = bIsHidden;
443
if ( ((bIsMaximized && ! bIsHidden && myAccessibility.bAutoHideOnMaximized) || (bIsFullScreen && ! bIsHidden && myAccessibility.bAutoHideOnFullScreen)) && ! cairo_dock_quick_hide_is_activated ())
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 ();
449
else if ((! bIsMaximized || ! myAccessibility.bAutoHideOnMaximized || bIsHidden) && (! bIsFullScreen || ! myAccessibility.bAutoHideOnFullScreen || bIsHidden) && cairo_dock_quick_hide_is_activated ())
451
if (cairo_dock_search_window_on_our_way (g_pMainDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
453
cd_message (" => plus aucune fenetre genante");
454
cairo_dock_deactivate_temporary_auto_hide ();
459
icon->bIsMaximized = bIsMaximized;
460
icon->bIsFullScreen = bIsFullScreen;
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)
466
cd_message (" changement de visibilite -> %d", bIsHidden);
467
icon->bIsHidden = bIsHidden;
469
// affichage des applis minimisees.
470
if (g_bUseOpenGL && myTaskBar.iMinimizedWindowRenderType == 2)
472
CairoDock *pDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
475
cairo_dock_draw_hidden_appli_icon (icon, CAIRO_CONTAINER (pDock), TRUE);
478
else if (myTaskBar.iMinimizedWindowRenderType == 0)
480
// transparence sur les inhibiteurs.
481
cairo_dock_update_visibility_on_inhibators (icon->cClass, icon->Xid, icon->bIsHidden);
484
// applis minimisees seulement
485
if (myTaskBar.bHideVisibleApplis) // on insere/detache l'icone selon la visibilite de la fenetre, avec une animation.
487
if (bIsHidden) // se cache => on insere son icone.
489
cd_message (" => se cache");
490
if (! myTaskBar.bAppliOnCurrentDesktopOnly || cairo_dock_appli_is_on_current_desktop (icon))
492
pParentDock = cairo_dock_insert_appli_in_dock (icon, g_pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
493
if (pParentDock != NULL)
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);
501
else // se montre => on detache l'icone.
503
cd_message (" => re-apparait");
504
cairo_dock_trigger_icon_removal_from_dock (icon);
507
else if (myTaskBar.fVisibleAppliAlpha != 0) // transparence
509
icon->fAlpha = 1; // on triche un peu.
510
if (pParentDock != NULL)
511
cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pParentDock));
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.
516
if (myTaskBar.iMinimizedWindowRenderType == 1 && (pParentDock != NULL || myTaskBar.bHideVisibleApplis)) // on recupere la miniature ou au contraire on remet l'icone.
518
if (! icon->bIsHidden) // fenetre mappee => BackingPixmap disponible.
520
if (icon->iBackingPixmap != 0)
521
XFreePixmap (s_XDisplay, icon->iBackingPixmap);
522
if (myTaskBar.iMinimizedWindowRenderType == 1)
523
icon->iBackingPixmap = XCompositeNameWindowPixmap (s_XDisplay, Xid);
525
icon->iBackingPixmap = 0;
526
cd_message ("new backing pixmap (bis) : %d", icon->iBackingPixmap);
528
// on redessine avec ou sans la miniature.
529
cairo_dock_reload_one_icon_buffer_in_dock (icon, pParentDock ? pParentDock : g_pMainDock);
531
cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pParentDock));
537
static void _on_change_window_desktop (Icon *icon)
539
Window Xid = icon->Xid;
540
icon->iNumDesktop = cairo_dock_get_xwindow_desktop (Xid);
542
// applis du bureau courant seulement.
543
if (myTaskBar.bAppliOnCurrentDesktopOnly)
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.
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.
551
if (! cairo_dock_quick_hide_is_activated () && (icon->iNumDesktop == -1 || icon->iNumDesktop == s_iCurrentDesktop)) // l'appli arrive sur le bureau courant.
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.
556
cd_message (" => cela nous gene");
557
cairo_dock_activate_temporary_auto_hide ();
560
else if (cairo_dock_quick_hide_is_activated () && (icon->iNumDesktop != -1 && icon->iNumDesktop != s_iCurrentDesktop)) // l'appli quitte sur le bureau courant.
562
if (cairo_dock_search_window_on_our_way (g_pMainDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
564
cd_message (" => plus aucune fenetre genante");
565
cairo_dock_deactivate_temporary_auto_hide ();
571
static void _on_change_window_size_position (Icon *icon, XConfigureEvent *e)
573
Window Xid = icon->Xid;
576
if (e->width != icon->windowGeometry.width || e->height != icon->windowGeometry.height)
578
if (icon->iBackingPixmap != 0)
579
XFreePixmap (s_XDisplay, icon->iBackingPixmap);
580
if (myTaskBar.iMinimizedWindowRenderType == 1)
582
icon->iBackingPixmap = XCompositeNameWindowPixmap (s_XDisplay, Xid);
583
cd_message ("new backing pixmap : %d", icon->iBackingPixmap);
586
icon->iBackingPixmap = 0;
589
icon->windowGeometry.width = e->width;
590
icon->windowGeometry.height = e->height;
591
icon->windowGeometry.x = e->x;
592
icon->windowGeometry.y = e->y;
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...
597
// applis du bureau courant seulement.
598
if (myTaskBar.bAppliOnCurrentDesktopOnly && icon->cParentDockName != NULL)
600
CairoDock *pParentDock = cairo_dock_detach_appli (icon);
602
gtk_widget_queue_draw (pParentDock->container.pWidget);
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.
608
if (cairo_dock_quick_hide_is_activated ())
610
if (cairo_dock_search_window_on_our_way (g_pMainDock, myAccessibility.bAutoHideOnMaximized, myAccessibility.bAutoHideOnFullScreen) == NULL)
612
cd_message (" chgt de viewport => plus aucune fenetre genante");
613
cairo_dock_deactivate_temporary_auto_hide ();
618
else // elle est sur le bureau.
620
// applis du bureau courant seulement.
621
if (myTaskBar.bAppliOnCurrentDesktopOnly && icon->cParentDockName == NULL)
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.
626
cairo_dock_insert_appli_in_dock (icon, g_pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
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.
632
if (! cairo_dock_quick_hide_is_activated ())
634
cd_message (" sur le viewport courant => cela nous gene");
635
cairo_dock_activate_temporary_auto_hide ();
640
cairo_dock_notify (CAIRO_DOCK_WINDOW_CONFIGURED, e);
643
static void _on_change_window_name (Icon *icon, CairoDock *pDock, gboolean bSearchWmName)
645
gchar *cName = cairo_dock_get_xwindow_name (icon->Xid, bSearchWmName);
648
if (icon->cName == NULL || strcmp (icon->cName, cName) != 0)
650
g_free (icon->cName);
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);
657
cairo_dock_update_name_on_inhibators (icon->cClass, icon->Xid, icon->cName);
664
static void _on_change_window_icon (Icon *icon, CairoDock *pDock)
666
if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons)
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));
675
static void _on_change_window_hints (Icon *icon, CairoDock *pDock, int iState)
677
XWMHints *pWMHints = XGetWMHints (s_XDisplay, icon->Xid);
678
if (pWMHints != NULL)
680
if ((pWMHints->flags & XUrgencyHint) && (myTaskBar.bDemandsAttentionWithDialog || myTaskBar.cAnimationOnDemandsAttention))
682
if (iState == PropertyNewValue)
684
cd_debug ("%s vous interpelle !", icon->cName);
685
cairo_dock_appli_demands_attention (icon);
687
else if (iState == PropertyDelete)
689
cd_debug ("%s arrette de vous interpeler.", icon->cName);
690
cairo_dock_appli_stops_demanding_attention (icon);
693
cd_warning (" etat du changement d'urgence inconnu sur %s !", icon->cName);
695
if (iState == PropertyNewValue && (pWMHints->flags & (IconPixmapHint | IconMaskHint | IconWindowHint)))
697
//g_print ("%s change son icone\n", icon->cName);
698
if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons)
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));
709
static gboolean _cairo_dock_unstack_Xevents (gpointer data)
712
static gboolean bCheckMouseIsOutside = FALSE;
714
CairoDock *pDock = g_pMainDock;
715
if (!pDock) // peut arriver en cours de chargement d'un theme.
718
long event_mask = 0xFFFFFFFF; // on les recupere tous, ca vide la pile au fur et a mesure plutot que tout a la fin.
720
Window root = DefaultRootWindow (s_XDisplay);
722
if (bCheckMouseIsOutside)
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);
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 :-/
733
while (XCheckMaskEvent (s_XDisplay, event_mask, &event))
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);
742
if (event.type == PropertyNotify) // PropertyNotify sur root
744
if (event.xproperty.atom == s_aNetClientList && myTaskBar.bShowAppli)
747
on_update_applis_list (pDock, s_iTime);
748
cairo_dock_notify (CAIRO_DOCK_WINDOW_CONFIGURED, NULL);
750
else if (event.xproperty.atom == s_aNetActiveWindow)
752
_on_change_active_window ();
754
else if (event.xproperty.atom == s_aNetCurrentDesktop || event.xproperty.atom == s_aNetDesktopViewport)
756
bCheckMouseIsOutside = _on_change_current_desktop_viewport ();
758
else if (event.xproperty.atom == s_aNetNbDesktops)
760
_on_change_nb_desktops ();
762
else if (event.xproperty.atom == s_aNetDesktopGeometry)
764
_on_change_desktop_geometry ();
766
else if (event.xproperty.atom == s_aRootMapID)
768
cd_debug ("change wallpaper");
769
cairo_dock_reload_desktop_background ();
770
cairo_dock_notify (CAIRO_DOCK_SCREEN_GEOMETRY_ALTERED);
772
else if (event.xproperty.atom == s_aNetShowingDesktop)
774
cd_debug ("change desktop visibility");
775
cairo_dock_notify (CAIRO_DOCK_DESKTOP_VISIBILITY_CHANGED);
777
else if (event.xproperty.atom == s_aXKlavierState)
779
cairo_dock_notify (CAIRO_DOCK_KBD_STATE_CHANGED, NULL);
781
} // fin de PropertyNotify sur root.
783
else if (myTaskBar.bShowAppli) // evenement sur une fenetre.
785
icon = g_hash_table_lookup (s_hXWindowTable, &Xid);
786
if (! CAIRO_DOCK_IS_APPLI (icon)) // appli blacklistee
788
if (! cairo_dock_xwindow_skip_taskbar (Xid))
790
g_print ("Special case : this appli (%ld) should not be ignored any more!\n", Xid);
791
g_hash_table_remove (s_hXWindowTable, &Xid);
796
/**else if (icon->fInsertRemoveFactor > 0) // pour une icone en cours de supression, on ne fait rien.
800
if (event.type == PropertyNotify) // PropertyNotify sur une fenetre
802
if (event.xproperty.atom == s_aNetWmState) // changement d'etat (hidden, maximized, fullscreen, demands attention)
804
_on_change_window_state (icon);
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.
808
_on_change_window_desktop (icon);
810
else if (event.xproperty.atom == s_aXKlavierState)
812
cairo_dock_notify (CAIRO_DOCK_KBD_STATE_CHANGED, &Xid);
816
CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
817
if (pParentDock == NULL)
819
int iState = event.xproperty.state;
820
Atom aProperty = event.xproperty.atom;
821
if (iState == PropertyNewValue && (aProperty == s_aNetWmName || aProperty == s_aWmName))
823
_on_change_window_name (icon, pParentDock, aProperty == s_aWmName);
825
else if (iState == PropertyNewValue && aProperty == s_aNetWmIcon)
827
_on_change_window_icon (icon, pParentDock);
829
else if (aProperty == s_aWmHints)
831
_on_change_window_hints (icon, pParentDock, iState);
835
else if (event.type == ConfigureNotify && ! cairo_dock_icon_is_being_removed (icon)) // ConfigureNotify sur une fenetre.
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);
841
/*else if (event.type == g_iDamageEvent + XDamageNotify)
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);
853
g_print (" type : %d (%d); window : %d\n", event.type, XDamageNotify, Xid);*/
854
} // fin d'evenement sur une fenetre.
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
863
void cairo_dock_start_listening_X_events (void)
865
g_return_if_fail (s_iSidUpdateAppliList == 0);
867
//\__________________ On recupere le bureau courant.
868
_cairo_dock_retrieve_current_desktop_and_viewport ();
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*/);
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 ! :-/
878
void cairo_dock_stop_listening_X_events (void) // le met seulement en pause.
880
g_return_if_fail (s_iSidUpdateAppliList != 0);
882
//\__________________ On arrete l'ecoute.
883
g_source_remove (s_iSidUpdateAppliList);
884
s_iSidUpdateAppliList = 0;
887
/////////////////////////
888
// X listener : access //
889
/////////////////////////
891
void cairo_dock_get_current_desktop_and_viewport (int *iCurrentDesktop, int *iCurrentViewportX, int *iCurrentViewportY)
893
*iCurrentDesktop = s_iCurrentDesktop;
894
*iCurrentViewportX = s_iCurrentViewportX;
895
*iCurrentViewportY = s_iCurrentViewportY;
899
///////////////////////////
900
// Applis manager : core //
901
///////////////////////////
903
void cairo_dock_initialize_application_manager (Display *pDisplay)
905
s_XDisplay = pDisplay;
907
s_hXWindowTable = g_hash_table_new_full (g_int_hash,
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);
931
void cairo_dock_register_appli (Icon *icon)
933
if (CAIRO_DOCK_IS_APPLI (icon))
935
cd_debug ("%s (%ld ; %s)", __func__, icon->Xid, icon->cName);
936
Window *pXid = g_new (Window, 1);
938
g_hash_table_insert (s_hXWindowTable, pXid, icon);
940
cairo_dock_add_appli_to_class (icon);
944
void cairo_dock_blacklist_appli (Window Xid)
948
cd_debug ("%s (%ld)", __func__, Xid);
949
Window *pXid = g_new (Window, 1);
951
Icon *pNullIcon = g_new0 (Icon, 1);
952
pNullIcon->iLastCheckTime = s_iTime;
953
g_hash_table_insert (s_hXWindowTable, pXid, pNullIcon); // NULL
957
void cairo_dock_unregister_appli (Icon *icon)
959
if (CAIRO_DOCK_IS_APPLI (icon))
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);
965
if (icon->iBackingPixmap != 0)
967
XFreePixmap (s_XDisplay, icon->iBackingPixmap);
968
icon->iBackingPixmap = 0;
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);
974
icon->Xid = 0; // hop, elle n'est plus une appli.
979
void cairo_dock_start_application_manager (CairoDock *pDock)
981
g_return_if_fail (!s_bAppliManagerIsRunning && myTaskBar.bShowAppli);
983
cairo_dock_set_overwrite_exceptions (myTaskBar.cOverwriteException);
984
cairo_dock_set_group_exceptions (myTaskBar.cGroupException);
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.
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);
994
CairoDock *pParentDock;
995
gboolean bUpdateMainDockSize = FALSE;
996
///int iStackOrder = 0;
999
for (i = 0; i < iNbWindows; i ++)
1001
Xid = pXWindowsList[i];
1002
pIcon = cairo_dock_create_icon_from_xwindow (pCairoContext, Xid, pDock);
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)))
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)
1014
if (pParentDock->bIsMainDock)
1015
bUpdateMainDockSize = TRUE;
1017
cairo_dock_update_dock_size (pParentDock);
1020
else if (myTaskBar.bMixLauncherAppli) // on met tout de meme l'indicateur sur le lanceur.
1022
cairo_dock_prevent_inhibated_class (pIcon);
1024
if ((myAccessibility.bAutoHideOnMaximized && pIcon->bIsMaximized) || (myAccessibility.bAutoHideOnFullScreen && pIcon->bIsFullScreen))
1026
if (! cairo_dock_quick_hide_is_activated () && cairo_dock_appli_is_on_current_desktop (pIcon))
1028
if (cairo_dock_appli_hovers_dock (pIcon, pDock))
1030
cd_message (" elle empiete sur notre dock");
1031
cairo_dock_activate_temporary_auto_hide ();
1037
cairo_dock_blacklist_appli (Xid);
1039
cairo_destroy (pCairoContext);
1040
if (pXWindowsList != NULL)
1041
XFree (pXWindowsList);
1043
if (bUpdateMainDockSize)
1044
cairo_dock_update_dock_size (pDock);
1046
s_bAppliManagerIsRunning = TRUE;
1048
if (s_iCurrentActiveWindow == 0)
1049
s_iCurrentActiveWindow = cairo_dock_get_active_xwindow ();
1052
static gboolean _cairo_dock_reset_appli_table_iter (Window *pXid, Icon *pIcon, gpointer data)
1056
if (pIcon->Xid == 0)
1062
CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
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.
1070
if (pDock->icons == NULL) // le dock degage, le fake aussi.
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.
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);
1084
cairo_dock_destroy_dock (pDock, cParentDockName, NULL, NULL);
1087
cairo_dock_update_dock_size (pDock);
1089
g_free (cParentDockName);
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);
1098
void cairo_dock_stop_application_manager (void)
1100
s_bAppliManagerIsRunning = FALSE;
1102
cairo_dock_remove_all_applis_from_class_table (); // enleve aussi les indicateurs.
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);
1107
if (cairo_dock_quick_hide_is_activated ())
1108
cairo_dock_deactivate_temporary_auto_hide ();
1111
gboolean cairo_dock_application_manager_is_running (void)
1113
return s_bAppliManagerIsRunning;
1118
/////////////////////////////
1119
// Applis manager : access //
1120
/////////////////////////////
1122
static gboolean _cairo_dock_window_is_on_our_way (Window *Xid, Icon *icon, gpointer *data)
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)
1129
if ((data[0] && icon->bIsMaximized && ! icon->bIsHidden) || (data[1] && icon->bIsFullScreen && ! icon->bIsHidden) || (!data[0] && ! data[1] && ! icon->bIsHidden))
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))
1134
cd_debug (" et en plus elle empiete sur notre dock");
1141
Icon * cairo_dock_search_window_on_our_way (CairoDock *pDock, gboolean bMaximizedWindow, gboolean bFullScreenWindow)
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);
1149
GList *cairo_dock_get_current_applis_list (void)
1151
return g_hash_table_get_values (s_hXWindowTable);
1154
Window cairo_dock_get_current_active_window (void)
1156
return s_iCurrentActiveWindow;
1159
Icon *cairo_dock_get_current_active_icon (void)
1161
Icon *pIcon = g_hash_table_lookup (s_hXWindowTable, &s_iCurrentActiveWindow);
1162
if (CAIRO_DOCK_IS_APPLI (pIcon))
1168
Icon *cairo_dock_get_icon_with_Xid (Window Xid)
1170
Icon *pIcon = g_hash_table_lookup (s_hXWindowTable, &Xid);
1171
if (CAIRO_DOCK_IS_APPLI (pIcon))
1178
static void _cairo_dock_for_one_appli (Window *Xid, Icon *icon, gpointer *data)
1180
if (! CAIRO_DOCK_IS_APPLI (icon) || cairo_dock_icon_is_being_removed (icon))
1182
CairoDockForeachIconFunc pFunction = data[0];
1183
gpointer pUserData = data[1];
1184
gboolean bOutsideDockOnly = GPOINTER_TO_INT (data[2]);
1186
if ((bOutsideDockOnly && icon->cParentDockName == NULL) || ! bOutsideDockOnly)
1188
CairoDock *pParentDock = NULL;
1189
if (icon->cParentDockName != NULL)
1190
pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
1192
pParentDock = g_pMainDock;
1193
pFunction (icon, CAIRO_CONTAINER (pParentDock), pUserData);
1196
void cairo_dock_foreach_applis (CairoDockForeachIconFunc pFunction, gboolean bOutsideDockOnly, gpointer pUserData)
1198
gpointer data[3] = {pFunction, pUserData, GINT_TO_POINTER (bOutsideDockOnly)};
1199
g_hash_table_foreach (s_hXWindowTable, (GHFunc) _cairo_dock_for_one_appli, data);
1203
static void _cairo_dock_for_one_appli_on_viewport (Icon *pIcon, CairoContainer *pContainer, gpointer *data)
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];
1211
if (! cairo_dock_appli_is_on_desktop (pIcon, iNumDesktop, iNumViewportX, iNumViewportY))
1214
pFunction (pIcon, pContainer, pUserData);
1216
void cairo_dock_foreach_applis_on_viewport (CairoDockForeachIconFunc pFunction, int iNumDesktop, int iNumViewportX, int iNumViewportY, gpointer pUserData)
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);
1223
/////////////////////
1224
// Applis facility //
1225
/////////////////////
1227
void cairo_dock_set_icons_geometry_for_window_manager (CairoDock *pDock)
1229
if (! s_bAppliManagerIsRunning)
1231
cd_debug ("%s (main:%d)", __func__, pDock->bIsMainDock);
1235
for (ic = pDock->icons; ic != NULL; ic = ic->next)
1238
if (CAIRO_DOCK_IS_APPLI (icon))
1240
cairo_dock_set_one_icon_geometry_for_window_manager (icon, pDock);
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.
1246
g_hash_table_foreach (s_hXWindowTable, (GHFunc) cairo_dock_reserve_one_icon_geometry_for_window_manager, pDock);
1251
gboolean cairo_dock_appli_is_on_desktop (Icon *pIcon, int iNumDesktop, int iNumViewportX, int iNumViewportY)
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
1257
x += g_iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
1258
int y = pIcon->windowGeometry.y;
1259
y += s_iCurrentViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1261
y += g_iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
1262
int w = pIcon->windowGeometry.width, h = pIcon->windowGeometry.height;
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]);
1272
gboolean cairo_dock_appli_is_on_current_desktop (Icon *pIcon)
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;
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.