39
39
#include "cairo-dock-internal-icons.h"
40
40
#include "cairo-dock-container.h"
41
41
#include "cairo-dock-animations.h"
42
#include "cairo-dock-application-facility.h"
42
43
#include "cairo-dock-class-manager.h"
44
45
extern CairoDock *g_pMainDock;
69
70
return (pClassAppli != NULL ? pClassAppli->pAppliOfClass : NULL);
72
static Window cairo_dock_detach_appli_of_class (const gchar *cClass, gboolean bDetachAll)
74
g_return_val_if_fail (cClass != NULL, 0);
76
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
78
const GList *pElement;
79
gboolean bNeedsRedraw = FALSE, bDetached;
80
CairoDock *pParentDock;
81
Window XFirstFoundId = 0;
82
for (pElement = pList; pElement != NULL; pElement = pElement->next)
84
pIcon = pElement->data;
85
cd_debug ("detachement de l'icone %s (%d;%d)", pIcon->cName, bDetachAll, XFirstFoundId);
86
CairoContainer *pContainer = cairo_dock_search_container_from_icon (pIcon);
87
if (CAIRO_DOCK_IS_DOCK (pContainer))
89
pParentDock = CAIRO_DOCK (pContainer);
91
if (bDetachAll || XFirstFoundId == 0)
93
gchar *cParentDockName = pIcon->cParentDockName;
94
pIcon->cParentDockName = NULL; // astuce.
95
bDetached = cairo_dock_detach_icon_from_dock (pIcon, pParentDock, myIcons.bUseSeparator); // on la garde, elle pourra servir car elle contient l'Xid.
96
if (! pParentDock->bIsMainDock)
98
if (pParentDock->icons == NULL)
99
cairo_dock_destroy_dock (pParentDock, cParentDockName, NULL, NULL);
101
cairo_dock_update_dock_size (pParentDock);
104
bNeedsRedraw |= (bDetached);
105
g_free (cParentDockName);
107
if (bDetached && XFirstFoundId == 0)
108
XFirstFoundId = pIcon->Xid;
111
/**cairo_t *pCairoContext = cairo_dock_create_context_from_window (CAIRO_CONTAINER (pContainer));
112
cd_messge (" on recharge l'icone de l'appli detachee %s", pIcon->cName);
113
cairo_dock_fill_one_icon_buffer (pIcon, pCairoContext, 1 + myIcons.fAmplitude, pParentDock->container.bIsHorizontal, TRUE, pParentDock->container.bDirectionUp);
114
cairo_destroy (pCairoContext);*/
115
bNeedsRedraw |= pParentDock->bIsMainDock;
119
if (! cairo_dock_is_loading () && bNeedsRedraw)
121
cairo_dock_update_dock_size (g_pMainDock);
122
cairo_dock_calculate_dock_icons (g_pMainDock);
123
gtk_widget_queue_draw (g_pMainDock->container.pWidget);
125
return XFirstFoundId;
128
74
static void _cairo_dock_set_same_indicator_on_sub_dock (Icon *pInhibhatorIcon)
191
137
return pClassAppli;
194
static gboolean cairo_dock_add_inhibator_to_class (const gchar *cClass, Icon *pIcon)
140
gboolean cairo_dock_add_inhibator_to_class (const gchar *cClass, Icon *pIcon)
196
142
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (cClass);
197
143
g_return_val_if_fail (pClassAppli!= NULL, FALSE);
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;
277
286
gboolean cairo_dock_inhibate_class (const gchar *cClass, Icon *pInhibatorIcon)
279
288
g_return_val_if_fail (cClass != NULL, FALSE);
282
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.
285
Window XFirstFoundId = cairo_dock_detach_appli_of_class (cClass, (TRUE));
294
Window XFirstFoundId = _cairo_dock_detach_appli_of_class (cClass, (TRUE));
286
295
if (pInhibatorIcon != NULL)
288
297
pInhibatorIcon->Xid = XFirstFoundId;
375
383
g_free (pInhibatorIcon->cName);
376
384
pInhibatorIcon->cName = NULL;
377
cairo_t *pCairoContext = cairo_dock_create_context_from_window (CAIRO_CONTAINER (pInhibhatorDock));
385
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pInhibhatorDock));
378
386
cairo_dock_set_icon_name (pCairoContext, pIcon->cName, pInhibatorIcon, CAIRO_CONTAINER (pInhibhatorDock));
379
387
cairo_destroy (pCairoContext);
419
427
if (pInhibatorIcon == NULL || pInhibatorIcon->Xid != 0)
421
cairo_t *pCairoContext = cairo_dock_create_context_from_window (CAIRO_CONTAINER (g_pMainDock));
429
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (g_pMainDock));
422
430
const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
424
432
gboolean bNeedsRedraw = FALSE;
430
438
if (pInhibatorIcon == NULL || pIcon->Xid == pInhibatorIcon->Xid)
432
440
cd_message ("rajout de l'icone precedemment inhibee (Xid:%d)", pIcon->Xid);
433
pIcon->fPersonnalScale = 0;
441
pIcon->fInsertRemoveFactor = 0;
434
442
pIcon->fScale = 1.;
435
443
pParentDock = cairo_dock_insert_appli_in_dock (pIcon, g_pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
436
444
bNeedsRedraw = (pParentDock != NULL && pParentDock->bIsMainDock);
448
cairo_dock_fill_one_icon_buffer (pIcon, pCairoContext, (1 + myIcons.fAmplitude), g_pMainDock->container.bIsHorizontal, g_pMainDock->container.bDirectionUp);
456
cairo_dock_reload_one_icon_buffer_in_dock_full (pIcon, g_pMainDock, pCairoContext);
451
459
cairo_destroy (pCairoContext);
500
508
CairoDock *pClassSubDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
501
509
if (pClassSubDock != NULL)
503
cairo_dock_detach_icon_from_dock (pSameClassIcon, pClassSubDock, myIcons.bUseSeparator);
511
cairo_dock_detach_icon_from_dock (pSameClassIcon, pClassSubDock, myIcons.iSeparateIcons);
504
512
if (pClassSubDock->icons == NULL && pClassSubDock == cairo_dock_search_dock_from_name (cClass)) // le sous-dock de la classe devient vide.
505
513
cairo_dock_destroy_dock (pClassSubDock, cClass, NULL, NULL);
555
563
cairo_surface_t *pSurface = cairo_dock_duplicate_surface (pInhibatorIcon->pIconBuffer,
557
pInhibatorIcon->fWidth * fInhibatorMaxScale / pInhibhatorContainer->fRatio,
558
pInhibatorIcon->fHeight * fInhibatorMaxScale / pInhibhatorContainer->fRatio,
565
pInhibatorIcon->fWidth * fInhibatorMaxScale / (pInhibhatorContainer ? pInhibhatorContainer->fRatio : 1.),
566
pInhibatorIcon->fHeight * fInhibatorMaxScale / (pInhibhatorContainer ? pInhibhatorContainer->fRatio : 1.),
559
567
*fWidth * fMaxScale,
560
568
*fHeight * fMaxScale);
706
714
g_free (pInhibatorIcon->cName);
707
715
pInhibatorIcon->cName = NULL;
709
cairo_t *pCairoContext = cairo_dock_create_context_from_window (CAIRO_CONTAINER (pParentDock));
717
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pParentDock));
710
718
cairo_dock_set_icon_name (pCairoContext, (cNewName != NULL ? cNewName : pInhibatorIcon->cInitialName), pInhibatorIcon, CAIRO_CONTAINER (pParentDock));
711
719
cairo_destroy (pCairoContext);
784
792
pLastClassIcon->cParentDockName = g_strdup (pFakeClassIcon->cParentDockName);
785
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.
787
798
cd_debug (" on detruit le sous-dock...");
788
799
cairo_dock_destroy_dock (pDock, cClass, NULL, NULL);
789
800
pFakeClassIcon->pSubDock = NULL;
791
cd_debug (" et l'icone de paille");
792
cairo_dock_remove_icon_from_dock (pFakeParentDock, pFakeClassIcon);
802
cd_debug ("on detruit l'icone de paille");
793
803
cairo_dock_free_icon (pFakeClassIcon);
795
805
cd_debug (" puis on re-insere l'appli restante");
797
if (pLastClassIcon->fPersonnalScale <= 0)
806
if (! cairo_dock_icon_is_being_removed (pLastClassIcon))
799
cairo_dock_insert_icon_in_dock_full (pLastClassIcon, pFakeParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, ! CAIRO_DOCK_INSERT_SEPARATOR, NULL);
808
cairo_dock_insert_icon_in_dock (pLastClassIcon, pFakeParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
800
809
cairo_dock_calculate_dock_icons (pFakeParentDock);
801
810
cairo_dock_redraw_icon (pLastClassIcon, CAIRO_CONTAINER (pFakeParentDock)); // on suppose que les tailles des 2 icones sont identiques.
803
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");
805
815
cairo_dock_free_icon (pLastClassIcon);
806
816
cairo_dock_update_dock_size (pFakeParentDock);
807
817
cairo_dock_calculate_dock_icons (pFakeParentDock);
817
827
cairo_dock_destroy_dock (pDock, cClass, NULL, NULL);
818
828
pFakeClassIcon->pSubDock = NULL;
819
829
cd_debug ("sanity check : pFakeClassIcon->Xid : %d", pFakeClassIcon->Xid);
820
if (pLastClassIcon->fPersonnalScale <= 0)
830
if (! cairo_dock_icon_is_being_removed (pLastClassIcon))
822
832
cairo_dock_insert_appli_in_dock (pLastClassIcon, g_pMainDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON); // a priori inutile.
823
833
cairo_dock_update_name_on_inhibators (cClass, pLastClassIcon->Xid, pLastClassIcon->cName);
991
1001
double fOrder = CAIRO_DOCK_LAST_ORDER;
992
1002
CairoDockClassAppli *pClassAppli = cairo_dock_get_class (pIcon->cClass);
993
if (pClassAppli != NULL)
1003
if (pClassAppli != NULL) // on va chercher une icone de meme classe dans le dock principal
995
// on charche une icone de meme classe dans le dock principal, de preference un inhibiteur, et de preference un lanceur.
1005
// on cherche un inhibiteur de cette classe, de preference un lanceur.
996
1006
Icon *pSameClassIcon = NULL;
997
1007
CairoDock *pDock;
998
1008
Icon *pInhibatorIcon;
1000
1010
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
1002
1012
pInhibatorIcon = ic->data;
1003
if (CAIRO_DOCK_IS_APPLET (pInhibatorIcon) && ! myIcons.bMixAppletsAndLaunchers)
1013
if (CAIRO_DOCK_IS_APPLET (pInhibatorIcon) && myIcons.iSeparateIcons)
1005
1015
pDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
1006
if (!pDock->bIsMainDock)
1016
if (!pDock || !pDock->bIsMainDock)
1007
1017
pInhibatorIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
1008
1018
pSameClassIcon = pInhibatorIcon;
1009
1019
if (CAIRO_DOCK_IS_LAUNCHER (pSameClassIcon)) // on prend les lanceurs de preference.
1013
if (pSameClassIcon == NULL) // alors on se place par rapport a une autre appli.
1023
// si aucun trouve, on cherche une autre appli de cette classe.
1024
if (pSameClassIcon == NULL)
1015
1026
Icon *pAppliIcon = NULL;
1016
1027
for (ic = pClassAppli->pAppliOfClass; ic != NULL; ic = ic->next)
1030
// on se place entre l'icone trouvee et la suivante de clase differente.
1041
// on se place entre l'icone trouvee et la suivante de classe differente.
1031
1042
if (pSameClassIcon != NULL) // une icone de meme classe existe dans le main dock, on va se placer apres.
1044
Icon *pNextIcon = NULL;
1033
1045
ic = g_list_find (g_pMainDock->icons, pSameClassIcon);
1034
if (ic != NULL && ic->next != NULL) // on remonte vers la droite toutes les icones de meme classe.
1046
if (ic && ic->next != NULL) // on remonte vers la droite toutes les icones de meme classe, et on cherche l'icone suivante.
1036
Icon *pNextIcon = NULL;
1038
1049
for (;ic != NULL; ic = ic->next)
1043
1054
pSameClassIcon = pNextIcon;
1044
1055
pNextIcon = NULL;
1046
fOrder = (pNextIcon ? (pNextIcon->fOrder + pSameClassIcon->fOrder) / 2 : pSameClassIcon->fOrder + 1);
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.
1050
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;
1064
1118
for (ic = pClassAppli->pIconsOfClass; ic != NULL; ic = ic->next)
1066
1120
pInhibatorIcon = ic->data;
1067
if (CAIRO_DOCK_IS_APPLET (pInhibatorIcon) && ! myIcons.bMixAppletsAndLaunchers)
1121
if (CAIRO_DOCK_IS_APPLET (pInhibatorIcon) && myIcons.iSeparateIcons)
1070
1124
pParentDock = cairo_dock_search_dock_from_name (pInhibatorIcon->cParentDockName);
1091
1145
for (ic = ic->next; ic != NULL; ic = ic->next)
1093
1147
pNextIcon = ic->data;
1094
if (!pNextIcon->cClass || strcmp (pNextIcon->cClass, pSameClassIcon->cClass) != 0) // icone d'une autre classe.
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.)
1096
1150
pSameClassIcon = pNextIcon;
1097
1151
pNextIcon = NULL;