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/>.
27
#include "cairo-dock-icons.h"
28
#include "cairo-dock-surface-factory.h"
29
#include "cairo-dock-log.h"
30
#include "cairo-dock-dock-manager.h"
31
#include "cairo-dock-dock-factory.h"
32
#include "cairo-dock-dock-facility.h"
33
#include "cairo-dock-config.h"
34
#include "cairo-dock-applications-manager.h"
35
#include "cairo-dock-draw.h"
36
#include "cairo-dock-load.h"
37
#include "cairo-dock-launcher-factory.h"
38
#include "cairo-dock-internal-taskbar.h"
39
#include "cairo-dock-internal-icons.h"
40
#include "cairo-dock-container.h"
41
#include "cairo-dock-animations.h"
42
#include "cairo-dock-application-facility.h"
43
#include "cairo-dock-class-manager.h"
45
extern CairoDock *g_pMainDock;
47
static GHashTable *s_hClassTable = NULL;
50
void cairo_dock_initialize_class_manager (void)
52
if (s_hClassTable == NULL)
53
s_hClassTable = g_hash_table_new_full (g_str_hash,
56
(GDestroyNotify) cairo_dock_free_class_appli);
60
static CairoDockClassAppli *cairo_dock_find_class_appli (const gchar *cClass)
62
return (cClass != NULL ? g_hash_table_lookup (s_hClassTable, cClass) : NULL);
65
const GList *cairo_dock_list_existing_appli_with_class (const gchar *cClass)
67
g_return_val_if_fail (cClass != NULL, NULL);
69
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (cClass);
70
return (pClassAppli != NULL ? pClassAppli->pAppliOfClass : NULL);
74
static void _cairo_dock_set_same_indicator_on_sub_dock (Icon *pInhibhatorIcon)
76
CairoDock *pInhibhatorDock = cairo_dock_search_dock_from_name (pInhibhatorIcon->cParentDockName);
77
if (pInhibhatorDock != NULL && pInhibhatorDock->iRefCount > 0) // l'inhibiteur est dans un sous-dock.
79
gboolean bSubDockHasIndicator = FALSE;
80
if (pInhibhatorIcon->bHasIndicator)
82
bSubDockHasIndicator = TRUE;
88
for (ic =pInhibhatorDock->icons ; ic != NULL; ic = ic->next)
91
if (icon->bHasIndicator)
93
bSubDockHasIndicator = TRUE;
98
CairoDock *pParentDock = NULL;
99
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pInhibhatorDock, &pParentDock);
100
if (pPointingIcon != NULL && pPointingIcon->bHasIndicator != bSubDockHasIndicator)
102
cd_message (" pour le sous-dock %s : indicateur <- %d", pPointingIcon->cName, bSubDockHasIndicator);
103
pPointingIcon->bHasIndicator = bSubDockHasIndicator;
104
if (pParentDock != NULL)
105
cairo_dock_redraw_icon (pPointingIcon, CAIRO_CONTAINER (pParentDock));
110
void cairo_dock_free_class_appli (CairoDockClassAppli *pClassAppli)
113
Icon *pInhibatorIcon;
114
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
116
pInhibatorIcon = pElement->data;
117
cd_message ("%s perd sa mana", pInhibatorIcon->cName);
118
pInhibatorIcon->Xid = 0;
119
pInhibatorIcon->bHasIndicator = FALSE;
120
_cairo_dock_set_same_indicator_on_sub_dock (pInhibatorIcon);
122
g_list_free (pClassAppli->pIconsOfClass);
123
g_list_free (pClassAppli->pAppliOfClass);
124
g_free (pClassAppli);
127
static CairoDockClassAppli *cairo_dock_get_class (const gchar *cClass)
129
g_return_val_if_fail (cClass != NULL, NULL);
131
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (cClass);
132
if (pClassAppli == NULL)
134
pClassAppli = g_new0 (CairoDockClassAppli, 1);
135
g_hash_table_insert (s_hClassTable, g_strdup (cClass), pClassAppli);
140
gboolean cairo_dock_add_inhibator_to_class (const gchar *cClass, Icon *pIcon)
142
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
143
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
145
g_return_val_if_fail (g_list_find (pClassAppli->pIconsOfClass, pIcon) == NULL, TRUE);
146
pClassAppli->pIconsOfClass = g_list_prepend (pClassAppli->pIconsOfClass, pIcon);
151
gboolean cairo_dock_add_appli_to_class (Icon *pIcon)
153
g_return_val_if_fail (pIcon!= NULL, FALSE);
154
cd_message ("%s (%s)", __func__, pIcon->cClass);
156
if (pIcon->cClass == NULL)
158
cd_message (" %s n'a pas de classe, c'est po bien", pIcon->cName);
161
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
162
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
164
g_return_val_if_fail (g_list_find (pClassAppli->pAppliOfClass, pIcon) == NULL, TRUE);
165
pClassAppli->pAppliOfClass = g_list_prepend (pClassAppli->pAppliOfClass, pIcon);
170
gboolean cairo_dock_remove_appli_from_class (Icon *pIcon)
172
g_return_val_if_fail (pIcon!= NULL, FALSE);
173
cd_message ("%s (%s, %s)", __func__, pIcon->cClass, pIcon->cName);
175
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
176
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
178
pClassAppli->pAppliOfClass = g_list_remove (pClassAppli->pAppliOfClass, pIcon);
183
gboolean cairo_dock_set_class_use_xicon (const gchar *cClass, gboolean bUseXIcon)
185
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
186
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
188
if (pClassAppli->bUseXIcon == bUseXIcon) // rien a faire.
194
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (g_pMainDock));
195
for (pElement = pClassAppli->pAppliOfClass; pElement != NULL; pElement = pElement->next)
197
pAppliIcon = pElement->data;
200
cd_message ("%s prend l'icone de X", pAppliIcon->cName);
204
cd_message ("%s n'utilise plus l'icone de X", pAppliIcon->cName);
207
pDock = cairo_dock_search_dock_from_name (pAppliIcon->cParentDockName);
210
cairo_dock_reload_one_icon_buffer_in_dock_full (pAppliIcon, pDock, pCairoContext);
214
cairo_dock_fill_one_icon_buffer (pAppliIcon, pCairoContext, (1 + myIcons.fAmplitude), g_pMainDock->container.bIsHorizontal, g_pMainDock->container.bDirectionUp);
217
cairo_destroy (pCairoContext);
223
static Window _cairo_dock_detach_appli_of_class (const gchar *cClass, gboolean bDetachAll)
225
g_return_val_if_fail (cClass != NULL, 0);
227
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
229
const GList *pElement;
230
gboolean bNeedsRedraw = FALSE, bDetached;
231
CairoDock *pParentDock;
232
Window XFirstFoundId = 0;
233
for (pElement = pList; pElement != NULL; pElement = pElement->next)
235
pIcon = pElement->data;
236
pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
237
if (pParentDock == NULL) // pas dans un dock => rien a faire.
240
cd_debug ("detachement de l'icone %s (%d;%d)", pIcon->cName, bDetachAll, XFirstFoundId);
241
gchar *cParentDockName = pIcon->cParentDockName;
242
pIcon->cParentDockName = NULL; // astuce.
243
bDetached = cairo_dock_detach_icon_from_dock (pIcon, pParentDock, myIcons.iSeparateIcons);
244
if (bDetached) // detachee => on met a jour son dock.
246
if (! pParentDock->bIsMainDock) // sous-dock de classe => on le met a jour / detruit.
248
if (pParentDock->icons == NULL) // devient vide => on le detruit.
250
if (pParentDock->iRefCount != 0) // on vire l'icone de paille qui pointe sur ce sous-dock.
252
CairoDock *pMainDock=NULL;
253
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pParentDock, &pMainDock);
254
if (pMainDock && pPointingIcon && pPointingIcon->cDesktopFileName == NULL)
256
cairo_dock_remove_icon_from_dock (pMainDock, pPointingIcon);
257
bNeedsRedraw |= pMainDock->bIsMainDock;
258
cairo_dock_free_icon (pPointingIcon);
261
cairo_dock_destroy_dock (pParentDock, cParentDockName, NULL, NULL);
263
else // non vide => on le met a jour.
264
cairo_dock_update_dock_size (pParentDock);
266
else // main dock => on le met a jour a la fin.
269
g_free (cParentDockName);
271
if (XFirstFoundId == 0) // on recupere la 1ere appli de la classe.
273
XFirstFoundId = pIcon->Xid;
278
if (! cairo_dock_is_loading () && bNeedsRedraw) // mise a jour du main dock en 1 coup.
280
cairo_dock_update_dock_size (g_pMainDock);
281
cairo_dock_calculate_dock_icons (g_pMainDock);
282
gtk_widget_queue_draw (g_pMainDock->container.pWidget);
284
return XFirstFoundId;
286
gboolean cairo_dock_inhibate_class (const gchar *cClass, Icon *pInhibatorIcon)
288
g_return_val_if_fail (cClass != NULL, FALSE);
289
cd_message ("%s (%s)", __func__, cClass);
291
if (! cairo_dock_add_inhibator_to_class (cClass, pInhibatorIcon)) // on l'insere avant pour que les icones des applis puissent le trouver et prendre sa surface si necessaire.
294
Window XFirstFoundId = _cairo_dock_detach_appli_of_class (cClass, (TRUE));
295
if (pInhibatorIcon != NULL)
297
pInhibatorIcon->Xid = XFirstFoundId;
298
pInhibatorIcon->bHasIndicator = (XFirstFoundId > 0);
299
_cairo_dock_set_same_indicator_on_sub_dock (pInhibatorIcon);
300
if (pInhibatorIcon->cClass != cClass)
302
g_free (pInhibatorIcon->cClass);
303
pInhibatorIcon->cClass = g_strdup (cClass);
306
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
308
const GList *pElement;
309
for (pElement = pList; pElement != NULL; pElement = pElement->next)
311
pIcon = pElement->data;
312
cd_debug ("une appli detachee (%s)", pIcon->cParentDockName);
313
if (pIcon->Xid != XFirstFoundId && pIcon->cParentDockName == NULL) // s'est faite detacher et doit etre rattacher.
314
cairo_dock_insert_appli_in_dock (pIcon, g_pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
321
gboolean cairo_dock_class_is_inhibated (const gchar *cClass)
323
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (cClass);
324
return (pClassAppli != NULL && pClassAppli->pIconsOfClass != NULL);
327
gboolean cairo_dock_class_is_using_xicon (const gchar *cClass)
329
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (cClass);
330
return (pClassAppli != NULL && pClassAppli->bUseXIcon); // si pClassAppli == NULL, il n'y a pas de lanceur pouvant lui filer son icone, mais on peut en trouver une dans le theme d'icones systeme.
333
gboolean cairo_dock_class_is_expanded (const gchar *cClass)
335
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (cClass);
336
return (pClassAppli != NULL && pClassAppli->bExpand);
339
gboolean cairo_dock_prevent_inhibated_class (Icon *pIcon)
341
g_return_val_if_fail (pIcon != NULL, FALSE);
342
//g_print ("%s (%s)\n", __func__, pIcon->cClass);
344
gboolean bToBeInhibited = FALSE;
345
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (pIcon->cClass);
346
if (pClassAppli != NULL)
348
Icon *pInhibatorIcon;
350
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
352
pInhibatorIcon = pElement->data;
353
if (pInhibatorIcon != NULL) // un inhibiteur est present.
355
if (pInhibatorIcon->Xid == 0 && pInhibatorIcon->pSubDock == NULL) // cette icone inhibe cette classe mais ne controle encore aucune appli, on s'y asservit.
357
pInhibatorIcon->Xid = pIcon->Xid;
358
pInhibatorIcon->bIsHidden = pIcon->bIsHidden;
359
cd_message (">>> %s prendra un indicateur au prochain redraw ! (Xid : %d)", pInhibatorIcon->cName, pInhibatorIcon->Xid);
360
pInhibatorIcon->bHasIndicator = TRUE;
361
_cairo_dock_set_same_indicator_on_sub_dock (pInhibatorIcon);
364
if (pInhibatorIcon->Xid == pIcon->Xid) // cette icone nous controle.
366
CairoDock *pInhibhatorDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
367
//\______________ On place l'icone pour X.
368
if (! bToBeInhibited) // on ne met le thumbnail que sur la 1ere.
370
if (pInhibhatorDock != NULL)
372
//g_print ("on positionne la miniature sur l'inhibiteur %s\n", pInhibatorIcon->cName);
373
cairo_dock_set_one_icon_geometry_for_window_manager (pInhibatorIcon, pInhibhatorDock);
375
bToBeInhibited = TRUE;
377
//\______________ On met a jour l'etiquette de l'inhibiteur.
378
if (pInhibhatorDock != NULL && pIcon->cName != NULL)
380
if (pInhibatorIcon->cInitialName == NULL)
381
pInhibatorIcon->cInitialName = pInhibatorIcon->cName;
383
g_free (pInhibatorIcon->cName);
384
pInhibatorIcon->cName = NULL;
385
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pInhibhatorDock));
386
cairo_dock_set_icon_name (pCairoContext, pIcon->cName, pInhibatorIcon, CAIRO_CONTAINER (pInhibhatorDock));
387
cairo_destroy (pCairoContext);
393
return bToBeInhibited;
397
gboolean cairo_dock_remove_icon_from_class (Icon *pInhibatorIcon)
399
g_return_val_if_fail (pInhibatorIcon != NULL, FALSE);
400
cd_message ("%s (%s)", __func__, pInhibatorIcon->cClass);
402
gboolean bStillInhibated = FALSE;
403
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (pInhibatorIcon->cClass);
404
if (pClassAppli != NULL)
406
pClassAppli->pIconsOfClass = g_list_remove (pClassAppli->pIconsOfClass, pInhibatorIcon);
407
if (pClassAppli->pIconsOfClass == NULL && pClassAppli->pAppliOfClass == NULL && ! pClassAppli->bUseXIcon) // cette classe ne sert plus a rien.
409
cd_message (" cette classe n'a plus d'interet");
410
g_hash_table_remove (s_hClassTable, pInhibatorIcon->cClass); // detruit pClassAppli.
411
bStillInhibated = FALSE;
414
bStillInhibated = (pClassAppli->pIconsOfClass != NULL);
416
return bStillInhibated;
419
void cairo_dock_deinhibate_class (const gchar *cClass, Icon *pInhibatorIcon)
421
cd_message ("%s (%s)", __func__, cClass);
422
gboolean bStillInhibated = cairo_dock_remove_icon_from_class (pInhibatorIcon);
423
cd_debug (" bStillInhibated : %d", bStillInhibated);
424
///if (! bStillInhibated) // il n'y a plus personne dans cette classe.
427
if (pInhibatorIcon == NULL || pInhibatorIcon->Xid != 0)
429
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (g_pMainDock));
430
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
432
gboolean bNeedsRedraw = FALSE;
433
CairoDock *pParentDock;
434
const GList *pElement;
435
for (pElement = pList; pElement != NULL; pElement = pElement->next)
437
pIcon = pElement->data;
438
if (pInhibatorIcon == NULL || pIcon->Xid == pInhibatorIcon->Xid)
440
cd_message ("rajout de l'icone precedemment inhibee (Xid:%d)", pIcon->Xid);
441
pIcon->fInsertRemoveFactor = 0;
443
pParentDock = cairo_dock_insert_appli_in_dock (pIcon, g_pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
444
bNeedsRedraw = (pParentDock != NULL && pParentDock->bIsMainDock);
445
//if (pInhibatorIcon != NULL)
448
pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
449
if (pParentDock != NULL)
451
cd_message ("on recharge l'icone de l'appli %s", pIcon->cName);
452
cairo_dock_reload_one_icon_buffer_in_dock_full (pIcon, pParentDock, pCairoContext);
456
cairo_dock_reload_one_icon_buffer_in_dock_full (pIcon, g_pMainDock, pCairoContext);
459
cairo_destroy (pCairoContext);
461
gtk_widget_queue_draw (g_pMainDock->container.pWidget); /// pDock->pRenderer->calculate_icons (pDock); ?...
463
if (pInhibatorIcon != NULL)
465
cd_message (" l'inhibiteur a perdu toute sa mana");
466
pInhibatorIcon->Xid = 0;
467
pInhibatorIcon->bHasIndicator = FALSE;
468
g_free (pInhibatorIcon->cClass);
469
pInhibatorIcon->cClass = NULL;
470
cd_debug (" plus de classe");
475
void cairo_dock_update_Xid_on_inhibators (Window Xid, const gchar *cClass)
477
cd_message ("%s (%s)", __func__, cClass);
478
CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (cClass);
479
if (pClassAppli != NULL)
482
Icon *pSameClassIcon = NULL;
485
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
487
pIcon = pElement->data;
488
if (pIcon->Xid == Xid)
490
if (iNextXid == -1) // on prend la 1ere appli de meme classe.
492
GList *pList = pClassAppli->pAppliOfClass;
495
for (ic = pList; ic != NULL; ic = ic->next)
498
if (pOneIcon != NULL && ! cairo_dock_icon_is_being_removed (pOneIcon) && pOneIcon->Xid != Xid) // la 2eme condition est a priori toujours vraie.
500
pSameClassIcon = pOneIcon;
504
iNextXid = (pSameClassIcon != NULL ? pSameClassIcon->Xid : 0);
505
if (pSameClassIcon != NULL)
507
cd_message (" c'est %s qui va la remplacer", pSameClassIcon->cName);
508
CairoDock *pClassSubDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
509
if (pClassSubDock != NULL)
511
cairo_dock_detach_icon_from_dock (pSameClassIcon, pClassSubDock, myIcons.iSeparateIcons);
512
if (pClassSubDock->icons == NULL && pClassSubDock == cairo_dock_search_dock_from_name (cClass)) // le sous-dock de la classe devient vide.
513
cairo_dock_destroy_dock (pClassSubDock, cClass, NULL, NULL);
515
cairo_dock_update_dock_size (pClassSubDock);
519
pIcon->Xid = iNextXid;
520
pIcon->bHasIndicator = (iNextXid != 0);
521
_cairo_dock_set_same_indicator_on_sub_dock (pIcon);
522
cd_message (" %s : bHasIndicator <- %d, Xid <- %d", pIcon->cName, pIcon->bHasIndicator, pIcon->Xid);
528
static void _cairo_dock_remove_all_applis_from_class (gchar *cClass, CairoDockClassAppli *pClassAppli, gpointer data)
530
g_list_free (pClassAppli->pAppliOfClass);
531
pClassAppli->pAppliOfClass = NULL;
533
Icon *pInhibatorIcon;
535
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
537
pInhibatorIcon = pElement->data;
538
pInhibatorIcon->bHasIndicator = FALSE;
539
pInhibatorIcon->Xid = 0;
540
_cairo_dock_set_same_indicator_on_sub_dock (pInhibatorIcon);
543
void cairo_dock_remove_all_applis_from_class_table (void)
545
g_hash_table_foreach (s_hClassTable, (GHFunc) _cairo_dock_remove_all_applis_from_class, NULL);
548
void cairo_dock_reset_class_table (void)
550
g_hash_table_remove_all (s_hClassTable);
555
cairo_surface_t *cairo_dock_duplicate_inhibator_surface_for_appli (cairo_t *pSourceContext, Icon *pInhibatorIcon, double fMaxScale, double *fWidth, double *fHeight)
557
*fWidth = myIcons.tIconAuthorizedWidth[CAIRO_DOCK_APPLI];
558
*fHeight = myIcons.tIconAuthorizedHeight[CAIRO_DOCK_APPLI];
560
CairoContainer *pInhibhatorContainer = cairo_dock_search_container_from_icon (pInhibatorIcon);
561
double fInhibatorMaxScale = (CAIRO_DOCK_IS_DOCK (pInhibhatorContainer) ? fMaxScale : 1);
563
cairo_surface_t *pSurface = cairo_dock_duplicate_surface (pInhibatorIcon->pIconBuffer,
565
pInhibatorIcon->fWidth * fInhibatorMaxScale / (pInhibhatorContainer ? pInhibhatorContainer->fRatio : 1.),
566
pInhibatorIcon->fHeight * fInhibatorMaxScale / (pInhibhatorContainer ? pInhibhatorContainer->fRatio : 1.),
568
*fHeight * fMaxScale);
571
cairo_surface_t *cairo_dock_create_surface_from_class (const gchar *cClass, cairo_t *pSourceContext, double fMaxScale, double *fWidth, double *fHeight)
573
cd_debug ("%s (%s)", __func__, cClass);
574
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
575
if (pClassAppli != NULL)
577
cd_debug ("bUseXIcon:%d", pClassAppli->bUseXIcon);
578
if (pClassAppli->bUseXIcon)
582
Icon *pInhibatorIcon;
583
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
585
pInhibatorIcon = pElement->data;
586
cd_debug (" %s", pInhibatorIcon->cName);
587
if (! CAIRO_DOCK_IS_APPLET (pInhibatorIcon))
589
cd_message ("%s va fournir genereusement sa surface", pInhibatorIcon->cName);
590
return cairo_dock_duplicate_inhibator_surface_for_appli (pSourceContext, pInhibatorIcon, fMaxScale, fWidth, fHeight);
595
gchar *cIconFilePath = cairo_dock_search_icon_s_path (cClass);
596
if (cIconFilePath != NULL)
598
cd_debug ("on remplace l'icone X par %s", cIconFilePath);
599
cairo_surface_t *pSurface = cairo_dock_create_surface_from_image (cIconFilePath,
601
1 + myIcons.fAmplitude,
602
myIcons.tIconAuthorizedWidth[CAIRO_DOCK_APPLI],
603
myIcons.tIconAuthorizedHeight[CAIRO_DOCK_APPLI],
604
CAIRO_DOCK_FILL_SPACE,
607
g_free (cIconFilePath);
611
cd_debug ("classe %s prend l'icone X", cClass);
617
void cairo_dock_update_visibility_on_inhibators (const gchar *cClass, Window Xid, gboolean bIsHidden)
619
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
620
if (pClassAppli != NULL)
623
Icon *pInhibatorIcon;
624
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
626
pInhibatorIcon = pElement->data;
628
if (pInhibatorIcon->Xid == Xid)
630
cd_message (" %s aussi se %s", pInhibatorIcon->cName, (bIsHidden ? "cache" : "montre"));
631
pInhibatorIcon->bIsHidden = bIsHidden;
632
if (! CAIRO_DOCK_IS_APPLET (pInhibatorIcon) && myTaskBar.fVisibleAppliAlpha != 0)
634
CairoDock *pInhibhatorDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
635
pInhibatorIcon->fAlpha = 1; // on triche un peu.
636
cairo_dock_redraw_icon (pInhibatorIcon, CAIRO_CONTAINER (pInhibhatorDock));
643
void cairo_dock_update_activity_on_inhibators (const gchar *cClass, Window Xid)
645
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
646
if (pClassAppli != NULL)
649
Icon *pInhibatorIcon;
650
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
652
pInhibatorIcon = pElement->data;
654
if (pInhibatorIcon->Xid == Xid)
656
cd_message (" %s aussi devient active", pInhibatorIcon->cName);
657
///pInhibatorIcon->bIsActive = TRUE;
658
CairoDock *pParentDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
659
if (pParentDock != NULL)
660
cairo_dock_animate_icon_on_active (pInhibatorIcon, pParentDock);
666
void cairo_dock_update_inactivity_on_inhibators (const gchar *cClass, Window Xid)
668
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
669
if (pClassAppli != NULL)
672
Icon *pInhibatorIcon;
673
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
675
pInhibatorIcon = pElement->data;
677
if (pInhibatorIcon->Xid == Xid)
679
cd_message (" %s aussi devient inactive", pInhibatorIcon->cName);
680
///pInhibatorIcon->bIsActive = FALSE;
681
CairoDock *pParentDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
682
if (pParentDock != NULL && ! pParentDock->bIsShrinkingDown)
683
cairo_dock_redraw_icon (pInhibatorIcon, CAIRO_CONTAINER (pParentDock));
689
void cairo_dock_update_name_on_inhibators (const gchar *cClass, Window Xid, gchar *cNewName)
691
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
692
if (pClassAppli != NULL)
695
Icon *pInhibatorIcon;
696
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
698
pInhibatorIcon = pElement->data;
700
if (pInhibatorIcon->Xid == Xid)
702
CairoDock *pParentDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
703
if (pParentDock != NULL)
705
if (! CAIRO_DOCK_IS_APPLET (pInhibatorIcon))
707
cd_message (" %s change son nom en %s", pInhibatorIcon->cName, cNewName);
708
if (pInhibatorIcon->cInitialName == NULL)
710
pInhibatorIcon->cInitialName = pInhibatorIcon->cName;
711
cd_debug ("pInhibatorIcon->cInitialName <- %s", pInhibatorIcon->cInitialName);
714
g_free (pInhibatorIcon->cName);
715
pInhibatorIcon->cName = NULL;
717
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pParentDock));
718
cairo_dock_set_icon_name (pCairoContext, (cNewName != NULL ? cNewName : pInhibatorIcon->cInitialName), pInhibatorIcon, CAIRO_CONTAINER (pParentDock));
719
cairo_destroy (pCairoContext);
721
if (! pParentDock->bIsShrinkingDown)
722
cairo_dock_redraw_icon (pInhibatorIcon, CAIRO_CONTAINER (pParentDock));
729
Icon *cairo_dock_get_classmate (Icon *pIcon)
731
cd_debug ("%s (%s)", __func__, pIcon->cClass);
732
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
733
if (pClassAppli == NULL)
736
Icon *pFriendIcon = NULL;
738
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
740
pFriendIcon = pElement->data;
741
if (pFriendIcon == NULL || pFriendIcon->cParentDockName == NULL) // on ne prend pas les inhibiteurs situes dans un desklet.
743
cd_debug (" friend : %s (%d)", pFriendIcon->cName, pFriendIcon->Xid);
744
if (pFriendIcon->Xid != 0 || pFriendIcon->pSubDock != NULL)
748
for (pElement = pClassAppli->pAppliOfClass; pElement != NULL; pElement = pElement->next)
750
pFriendIcon = pElement->data;
751
if (pFriendIcon != pIcon && pFriendIcon->cParentDockName != NULL && strcmp (pFriendIcon->cParentDockName, CAIRO_DOCK_MAIN_DOCK_NAME) == 0)
761
gboolean cairo_dock_check_class_subdock_is_empty (CairoDock *pDock, const gchar *cClass)
763
cd_debug ("%s (%s, %d)", __func__, cClass, g_list_length (pDock->icons));
764
if (pDock->iRefCount == 0)
766
if (pDock->icons == NULL) // ne devrait plus arriver.
768
cd_warning ("the %s class sub-dock has no element, which is probably an error !\nit will be destroyed.", cClass);
769
CairoDock *pFakeParentDock = NULL;
770
Icon *pFakeClassIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pFakeParentDock);
771
cairo_dock_destroy_dock (pDock, cClass, NULL, NULL);
772
pFakeClassIcon->pSubDock = NULL;
773
cairo_dock_remove_icon_from_dock (pFakeParentDock, pFakeClassIcon);
774
cairo_dock_free_icon (pFakeClassIcon);
775
cairo_dock_update_dock_size (pFakeParentDock);
776
cairo_dock_calculate_dock_icons (pFakeParentDock);
779
else if (pDock->icons->next == NULL)
781
cd_debug (" le sous-dock de la classe %s n'a plus que 1 element et va etre vide puis detruit", cClass);
782
Icon *pLastClassIcon = pDock->icons->data;
784
CairoDock *pFakeParentDock = NULL;
785
Icon *pFakeClassIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pFakeParentDock);
786
g_return_val_if_fail (pFakeClassIcon != NULL, TRUE);
787
if (CAIRO_DOCK_IS_FAKE_LAUNCHER (pFakeClassIcon)) // le sous-dock est pointe par une icone de paille.
789
cd_debug ("trouve l'icone en papier (%x;%x)", pFakeClassIcon, pFakeParentDock);
790
cairo_dock_detach_icon_from_dock (pLastClassIcon, pDock, FALSE);
791
g_free (pLastClassIcon->cParentDockName);
792
pLastClassIcon->cParentDockName = g_strdup (pFakeClassIcon->cParentDockName);
793
pLastClassIcon->fOrder = pFakeClassIcon->fOrder;
795
cd_debug ("on enleve l'icone de paille");
796
cairo_dock_remove_icon_from_dock (pFakeParentDock, pFakeClassIcon); // a faire avant que l'icone n'ait plus de sous-dock, sinon elle est consideree comme un separateur auto, et du coup le separateur n'est pas enleve.
798
cd_debug (" on detruit le sous-dock...");
799
cairo_dock_destroy_dock (pDock, cClass, NULL, NULL);
800
pFakeClassIcon->pSubDock = NULL;
802
cd_debug ("on detruit l'icone de paille");
803
cairo_dock_free_icon (pFakeClassIcon);
805
cd_debug (" puis on re-insere l'appli restante");
806
if (! cairo_dock_icon_is_being_removed (pLastClassIcon))
808
cairo_dock_insert_icon_in_dock (pLastClassIcon, pFakeParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
809
cairo_dock_calculate_dock_icons (pFakeParentDock);
810
cairo_dock_redraw_icon (pLastClassIcon, CAIRO_CONTAINER (pFakeParentDock)); // on suppose que les tailles des 2 icones sont identiques.
812
else // la derniere icone est en cours de suppression, inutile de la re-inserer. (c'est souvent lorsqu'on ferme toutes une classe d'un coup. donc les animations sont pratiquement dans le meme etat, donc la derniere icone en est aussi a la fin, donc on ne verrait de toute facon aucune animation.
814
g_print ("inutile de re-inserer l'icone restante\n");
815
cairo_dock_free_icon (pLastClassIcon);
816
cairo_dock_update_dock_size (pFakeParentDock);
817
cairo_dock_calculate_dock_icons (pFakeParentDock);
818
cairo_dock_redraw_container (CAIRO_CONTAINER (pFakeParentDock));
821
else // le sous-dock est pointe par un inhibiteur (normal launcher ou applet).
823
cairo_dock_detach_icon_from_dock (pLastClassIcon, pDock, FALSE);
824
g_free (pLastClassIcon->cParentDockName);
825
pLastClassIcon->cParentDockName = NULL;
827
cairo_dock_destroy_dock (pDock, cClass, NULL, NULL);
828
pFakeClassIcon->pSubDock = NULL;
829
cd_debug ("sanity check : pFakeClassIcon->Xid : %d", pFakeClassIcon->Xid);
830
if (! cairo_dock_icon_is_being_removed (pLastClassIcon))
832
cairo_dock_insert_appli_in_dock (pLastClassIcon, g_pMainDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON); // a priori inutile.
833
cairo_dock_update_name_on_inhibators (cClass, pLastClassIcon->Xid, pLastClassIcon->cName);
835
else // la derniere icone est en cours de suppression, inutile de la re-inserer
837
pFakeClassIcon->bHasIndicator = FALSE;
838
cairo_dock_free_icon (pLastClassIcon);
840
cairo_dock_redraw_icon (pFakeClassIcon, CAIRO_CONTAINER (g_pMainDock));
848
static void _cairo_dock_reset_overwrite_exceptions (gchar *cClass, CairoDockClassAppli *pClassAppli, gpointer data)
850
pClassAppli->bUseXIcon = FALSE;
852
void cairo_dock_set_overwrite_exceptions (const gchar *cExceptions)
854
g_hash_table_foreach (s_hClassTable, (GHFunc) _cairo_dock_reset_overwrite_exceptions, NULL);
855
if (cExceptions == NULL)
858
gchar **cClassList = g_strsplit (cExceptions, ";", -1);
859
if (cClassList == NULL || cClassList[0] == NULL || *cClassList[0] == '\0')
861
g_strfreev (cClassList);
864
CairoDockClassAppli *pClassAppli;
866
for (i = 0; cClassList[i] != NULL; i ++)
868
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClassList[i]);
869
pClassAppli->bUseXIcon = TRUE;
872
g_strfreev (cClassList);
875
static void _cairo_dock_reset_group_exceptions (gchar *cClass, CairoDockClassAppli *pClassAppli, gpointer data)
877
pClassAppli->bExpand = FALSE;
879
void cairo_dock_set_group_exceptions (const gchar *cExceptions)
881
g_hash_table_foreach (s_hClassTable, (GHFunc) _cairo_dock_reset_group_exceptions, NULL);
882
if (cExceptions == NULL)
885
gchar **cClassList = g_strsplit (cExceptions, ";", -1);
886
if (cClassList == NULL || cClassList[0] == NULL || *cClassList[0] == '\0')
888
g_strfreev (cClassList);
891
CairoDockClassAppli *pClassAppli;
893
for (i = 0; cClassList[i] != NULL; i ++)
895
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClassList[i]);
896
pClassAppli->bExpand = TRUE;
899
g_strfreev (cClassList);
903
Icon *cairo_dock_get_prev_next_classmate_icon (Icon *pIcon, gboolean bNext)
905
cd_debug ("%s (%s, %s)", __func__, pIcon->cClass, pIcon->cName);
906
g_return_val_if_fail (pIcon->cClass != NULL, NULL);
908
Icon *pActiveIcon = cairo_dock_get_current_active_icon ();
909
if (pActiveIcon == NULL || pActiveIcon->cClass == NULL || strcmp (pActiveIcon->cClass, pIcon->cClass) != 0) // la fenetre active n'est pas de notre classe, on active l'icone fournies en entree.
911
cd_debug ("on active la classe %s", pIcon->cClass);
915
//\________________ on va chercher dans la classe la fenetre active, et prendre la suivante ou la precedente.
916
Icon *pNextIcon = NULL;
917
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
918
if (pClassAppli == NULL)
921
//\________________ On cherche dans les icones d'applis.
922
Icon *pClassmateIcon;
923
GList *pElement, *ic;
924
for (pElement = pClassAppli->pAppliOfClass; pElement != NULL && pNextIcon == NULL; pElement = pElement->next)
926
pClassmateIcon = pElement->data;
927
cd_debug (" %s est-elle active ?", pClassmateIcon->cName);
928
if (pClassmateIcon->Xid == pActiveIcon->Xid) // on a trouve la fenetre active.
930
cd_debug (" fenetre active trouvee (%s; %d)", pClassmateIcon->cName, pClassmateIcon->Xid);
931
if (bNext) // on prend la 1ere non nulle qui suit.
936
ic = cairo_dock_get_next_element (ic, pClassAppli->pAppliOfClass);
939
cd_debug (" on a fait le tour sans rien trouve");
942
pClassmateIcon = ic->data;
943
if (pClassmateIcon != NULL && pClassmateIcon->Xid != 0)
945
cd_debug (" ok on prend celle-la (%s; %d)", pClassmateIcon->cName, pClassmateIcon->Xid);
946
pNextIcon = pClassmateIcon;
949
cd_debug ("un coup pour rien");
953
else // on prend la 1ere non nulle qui precede.
958
ic = cairo_dock_get_previous_element (ic, pClassAppli->pAppliOfClass);
961
pClassmateIcon = ic->data;
962
if (pClassmateIcon != NULL && pClassmateIcon->Xid != 0)
964
pNextIcon = pClassmateIcon;
978
Icon *cairo_dock_get_inhibator (Icon *pIcon, gboolean bOnlyInDock)
980
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
981
if (pClassAppli != NULL)
984
Icon *pInhibatorIcon;
985
for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
987
pInhibatorIcon = pElement->data;
989
if (pInhibatorIcon->Xid == pIcon->Xid)
991
if (! bOnlyInDock || pInhibatorIcon->cParentDockName != NULL)
992
return pInhibatorIcon;
999
void cairo_dock_set_class_order (Icon *pIcon)
1001
double fOrder = CAIRO_DOCK_LAST_ORDER;
1002
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
1003
if (pClassAppli != NULL) // on va chercher une icone de meme classe dans le dock principal
1005
// on cherche un inhibiteur de cette classe, de preference un lanceur.
1006
Icon *pSameClassIcon = NULL;
1008
Icon *pInhibatorIcon;
1010
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
1012
pInhibatorIcon = ic->data;
1013
if (CAIRO_DOCK_IS_APPLET (pInhibatorIcon) && myIcons.iSeparateIcons)
1015
pDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
1016
if (!pDock || !pDock->bIsMainDock)
1017
pInhibatorIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
1018
pSameClassIcon = pInhibatorIcon;
1019
if (CAIRO_DOCK_IS_LAUNCHER (pSameClassIcon)) // on prend les lanceurs de preference.
1023
// si aucun trouve, on cherche une autre appli de cette classe.
1024
if (pSameClassIcon == NULL)
1026
Icon *pAppliIcon = NULL;
1027
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
1029
pAppliIcon = ic->data;
1030
if (pAppliIcon == pIcon)
1032
pDock = cairo_dock_search_dock_from_name (pAppliIcon->cParentDockName);
1033
if (pDock && pDock->bIsMainDock)
1035
pSameClassIcon = pAppliIcon;
1041
// on se place entre l'icone trouvee et la suivante de classe differente.
1042
if (pSameClassIcon != NULL) // une icone de meme classe existe dans le main dock, on va se placer apres.
1044
Icon *pNextIcon = NULL;
1045
ic = g_list_find (g_pMainDock->icons, pSameClassIcon);
1046
if (ic && ic->next != NULL) // on remonte vers la droite toutes les icones de meme classe, et on cherche l'icone suivante.
1049
for (;ic != NULL; ic = ic->next)
1051
pNextIcon = ic->data;
1052
if (!pNextIcon->cClass || strcmp (pNextIcon->cClass, pIcon->cClass) != 0)
1054
pSameClassIcon = pNextIcon;
1058
//g_print ("on se place apres la derniere icone de cette classe\n");
1059
if (pNextIcon != NULL && cairo_dock_get_icon_order (pNextIcon) == cairo_dock_get_icon_order (pSameClassIcon)) // l'icone suivante est dans le meme groupe que nous, on s'intercalle entre elle et pSameClassIcon.
1060
fOrder = (pNextIcon->fOrder + pSameClassIcon->fOrder) / 2;
1061
else // aucune icone apres notre classe, ou alors dans un groupe different, on se place juste apres pSameClassIcon.
1062
fOrder = pSameClassIcon->fOrder + 1;
1066
if (fOrder == CAIRO_DOCK_LAST_ORDER) // cette classe n'existe pas encore ou est vide ou n'a aucune icone dans le main dock => on va se positionner par rapport a la derniere appli.
1070
for (ic = g_list_last (g_pMainDock->icons); ic != NULL; ic = ic->prev)
1073
if (icon->iType == CAIRO_DOCK_APPLI && ! cairo_dock_class_is_inhibated (icon->cClass)) // on verifie qu'elle n'est pas placé a cote de son lanceur, sinon cela cree des incoherences suivants que l'appli est lancee 2 fois ou pas.
1078
if (ic != NULL) // on a trouve une icone d'appli.
1080
//g_print ("on se place apres la derniere appli\n");
1082
Icon *next_icon = (ic ? ic->data : NULL);
1083
if (next_icon != NULL && cairo_dock_get_icon_order (next_icon) == cairo_dock_get_icon_order (icon))
1084
fOrder = (icon->fOrder + next_icon->fOrder) / 2;
1086
fOrder = icon->fOrder + 1;
1088
else if (myTaskBar.bMixLauncherAppli) // on decide de la placer apres le dernier lanceur dans le cas ou les lanceurs peuvent faire appli.
1090
for (ic = g_list_last (g_pMainDock->icons); ic != NULL; ic = ic->prev)
1093
if (icon->iType == CAIRO_DOCK_LAUNCHER)
1096
if (ic != NULL) // on a trouve une icone de lanceur.
1098
//g_print ("on se place apres le dernier lanceur\n");
1100
Icon *next_icon = (ic ? ic->data : NULL);
1101
if (next_icon != NULL && cairo_dock_get_icon_order (next_icon) == cairo_dock_get_icon_order (icon))
1102
fOrder = (icon->fOrder + next_icon->fOrder) / 2;
1104
fOrder = icon->fOrder + 1;
1108
pIcon->fOrder = fOrder;
1111
static void _cairo_dock_reorder_one_class (gchar *cClass, CairoDockClassAppli *pClassAppli, int *iMaxOrder)
1113
// on touve un inhibiteur par rapport auquel se placer.
1114
Icon *pSameClassIcon = NULL;
1115
Icon *pInhibatorIcon;
1116
CairoDock *pParentDock;
1118
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
1120
pInhibatorIcon = ic->data;
1121
if (CAIRO_DOCK_IS_APPLET (pInhibatorIcon) && myIcons.iSeparateIcons)
1124
pParentDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
1126
while (pParentDock && pParentDock->iRefCount != 0)
1128
pDock = pParentDock;
1129
pInhibatorIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
1131
if (!pParentDock || !pParentDock->bIsMainDock) // on place les icones d'applis dans le main dock.
1133
pSameClassIcon = pInhibatorIcon;
1134
if (CAIRO_DOCK_IS_LAUNCHER (pSameClassIcon)) // on prend les lanceurs de preference aux applets.
1138
// on cherche une icone qui nous borne a droite.
1139
Icon *pNextIcon = NULL;
1140
if (pSameClassIcon != NULL) // on se place apres l'icone trouve.
1142
ic = g_list_find (g_pMainDock->icons, pSameClassIcon);
1143
if (ic != NULL && ic->next != NULL) // on remonte vers la droite jusqu'a trouver une icone de classe differente.
1145
for (ic = ic->next; ic != NULL; ic = ic->next)
1147
pNextIcon = ic->data;
1148
if (!pNextIcon->cClass || strcmp (pNextIcon->cClass, cClass) != 0) // icone d'une autre classe. (pSameClassIcon->cClass peut etre NULL dans le cas d'un inhibiteur place dans un sous-dock, car alors pSameClassIcon est l'icone pointant sur le sous-dock.)
1150
pSameClassIcon = pNextIcon;
1156
// on se place entre les 2 icones, ou a la fin si aucune icone trouvee.
1159
if (pNextIcon != NULL) // on se place entre les 2.
1161
int i=1, iNbIcons = g_list_length (pClassAppli->pAppliOfClass); // majorant.
1162
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
1164
pAppliIcon = ic->data;
1165
pDock = cairo_dock_search_dock_from_name (pAppliIcon->cParentDockName);
1166
if (pDock && pDock->iRefCount == 0)
1168
pAppliIcon->fOrder = pSameClassIcon->fOrder + (pNextIcon->fOrder - pSameClassIcon->fOrder) * i / (iNbIcons + 1);
1173
else // on se place a la fin.
1175
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
1177
pAppliIcon = ic->data;
1178
pDock = cairo_dock_search_dock_from_name (pAppliIcon->cParentDockName);
1179
if (pDock && pDock->iRefCount == 0)
1181
pAppliIcon->fOrder = *iMaxOrder;
1187
void cairo_dock_reorder_classes (void)
1189
Icon *pLastIcon = cairo_dock_get_last_icon (g_pMainDock->icons);
1190
int iMaxOrder = (pLastIcon ? pLastIcon->fOrder + 1 : 1);
1191
g_hash_table_foreach (s_hClassTable, (GHFunc) _cairo_dock_reorder_one_class, &iMaxOrder);