static Window cairo_dock_detach_appli_of_class (const gchar *cClass, gboolean bDetachAll)
{
	g_return_val_if_fail (cClass != NULL, 0);
	
	const GList *pList = cairo_dock_list_existing_appli_with_class (cClass);
	Icon *pIcon;
	const GList *pElement;
	gboolean bNeedsRedraw = FALSE, bDetached;
	CairoDock *pParentDock;
	Window XFirstFoundId = 0;
	for (pElement = pList; pElement != NULL; pElement = pElement->next)
	{
		pIcon = pElement->data;
		cd_debug ("detachement de l'icone %s (%d;%d)", pIcon->acName, bDetachAll, XFirstFoundId);
		CairoContainer *pContainer = cairo_dock_search_container_from_icon (pIcon);
		if (CAIRO_DOCK_IS_DOCK (pContainer))
		{
			pParentDock = CAIRO_DOCK (pContainer);
			bDetached = FALSE;
			if (bDetachAll || XFirstFoundId == 0)
			{
				gchar *cParentDockName = pIcon->cParentDockName;
				pIcon->cParentDockName = NULL;  // astuce.
				bDetached = cairo_dock_detach_icon_from_dock (pIcon, pParentDock, g_bUseSeparator);  // on la garde, elle pourra servir car elle contient l'Xid.
				if (! pParentDock->bIsMainDock)
				{
					if (pParentDock->icons == NULL)
						cairo_dock_destroy_dock (pParentDock, cParentDockName, NULL, NULL);
					else
						cairo_dock_update_dock_size (pParentDock);
				}
				else
					bNeedsRedraw |= (bDetached);
				g_free (cParentDockName);
			}
			if (bDetached && XFirstFoundId == 0)
				XFirstFoundId = pIcon->Xid;
			else
			{
				/**cairo_t *pCairoContext = cairo_dock_create_context_from_window (CAIRO_CONTAINER (pContainer));
				cd_messge ("  on recharge l'icone de l'appli detachee %s", pIcon->acName);
				cairo_dock_fill_one_icon_buffer (pIcon, pCairoContext, 1 + g_fAmplitude, pParentDock->bHorizontalDock, TRUE, pParentDock->bDirectionUp);
				cairo_destroy (pCairoContext);*/
				bNeedsRedraw |= pParentDock->bIsMainDock;
			}
		}
	}
	if (! cairo_dock_is_loading () && bNeedsRedraw)
	{
		cairo_dock_update_dock_size (g_pMainDock);
		gtk_widget_queue_draw (g_pMainDock->pWidget);  /// pDock->calculate_icons (pDock); ?...
	}
	return XFirstFoundId;
}
void cairo_dock_deactivate_module_and_unload (gchar *cModuleName)
{
	if (g_pMainDock == NULL)
		return ;
	CairoDockModule *pModule = cairo_dock_find_module_from_name (cModuleName);
	Icon *pIcon = cairo_dock_find_icon_from_module (pModule, pModule->pContainer);
	
	if (CAIRO_DOCK_IS_DOCK (pModule->pContainer))
	{
		CairoDock *pDock = CAIRO_DOCK (pModule->pContainer);
		if (pIcon != NULL)
		{
			cairo_dock_remove_icon_from_dock (pDock, pIcon);  // desactive le module.
			cairo_dock_update_dock_size (pDock);
		}
		else
		{
			cairo_dock_deactivate_module (pModule);
		}
		gtk_widget_queue_draw (pDock->pWidget);
	}
	else
	{
		cairo_dock_deactivate_module (pModule);
	}
	
	cairo_dock_update_conf_file_with_active_modules2 (NULL, g_cConfFile);
	cairo_dock_free_icon (pIcon);
}
void cairo_dock_move_icon_after_icon (CairoDock *pDock, Icon *icon1, Icon *icon2)
{
	//g_print ("%s (%s, %.2f, %x)\n", __func__, icon1->acName, icon1->fOrder, icon2);
	///if ((icon2 != NULL) && (! ( (CAIRO_DOCK_IS_APPLI (icon1) && CAIRO_DOCK_IS_APPLI (icon2)) || (CAIRO_DOCK_IS_LAUNCHER (icon1) && CAIRO_DOCK_IS_LAUNCHER (icon2)) || (CAIRO_DOCK_IS_APPLET (icon1) && CAIRO_DOCK_IS_APPLET (icon2)) ) ))
	if ((icon2 != NULL) && fabs (cairo_dock_get_icon_order (icon1) - cairo_dock_get_icon_order (icon2)) > 1)
		return ;
	//\_________________ On change l'ordre de l'icone.
	gboolean bForceUpdate = FALSE;
	if (icon2 != NULL)
	{
		Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon2);
		if (pNextIcon != NULL && fabs (pNextIcon->fOrder - icon2->fOrder) < 1e-3)
		{
			bForceUpdate = TRUE;
		}
		if (pNextIcon == NULL || cairo_dock_get_icon_order (pNextIcon) != cairo_dock_get_icon_order (icon2))
			icon1->fOrder = icon2->fOrder + 1;
		else
			icon1->fOrder = (pNextIcon->fOrder - icon2->fOrder > 1 ? icon2->fOrder + 1 : (pNextIcon->fOrder + icon2->fOrder) / 2);
	}
	else
	{
		Icon *pFirstIcon = cairo_dock_get_first_icon_of_order (pDock->icons, icon1->iType);
		if (pFirstIcon != NULL)
			icon1->fOrder = pFirstIcon->fOrder - 1;
		else
			icon1->fOrder = 1;
	}
	//g_print ("icon1->fOrder:%.2f\n", icon1->fOrder);
	
	//\_________________ On change l'ordre dans le fichier du lanceur 1.
	if ((CAIRO_DOCK_IS_LAUNCHER (icon1) || CAIRO_DOCK_IS_SEPARATOR (icon1)) && icon1->acDesktopFileName != NULL)
	{
		gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, icon1->acDesktopFileName);
		cairo_dock_update_conf_file (cDesktopFilePath,
			G_TYPE_DOUBLE, "Desktop Entry", "Order", icon1->fOrder,
			G_TYPE_INVALID);
		g_free (cDesktopFilePath);
	}
	else if (CAIRO_DOCK_IS_APPLET (icon1))
		cairo_dock_update_module_instance_order (icon1->pModuleInstance, icon1->fOrder);

	//\_________________ On change sa place dans la liste.
	pDock->pFirstDrawnElement = NULL;
	pDock->icons = g_list_remove (pDock->icons, icon1);
	pDock->icons = g_list_insert_sorted (pDock->icons,
		icon1,
		(GCompareFunc) cairo_dock_compare_icons_order);

	//\_________________ On recalcule la largeur max, qui peut avoir ete influencee par le changement d'ordre.
	cairo_dock_update_dock_size (pDock);
	
	if (bForceUpdate)
		cairo_dock_normalize_icons_order (pDock->icons, icon1->iType);
}
void cairo_dock_update_Xid_on_inhibators (Window Xid, const gchar *cClass)
{
	cd_message ("%s (%s)", __func__, cClass);
	CairoDockClassAppli *pClassAppli = cairo_dock_find_class_appli (cClass);
	if (pClassAppli != NULL)
	{
		int iNextXid = -1;
		Icon *pSameClassIcon = NULL;
		Icon *pIcon;
		GList *pElement;
		for (pElement = pClassAppli->pIconsOfClass; pElement != NULL; pElement = pElement->next)
		{
			pIcon = pElement->data;
			if (pIcon->Xid == Xid)
			{
				if (iNextXid == -1)  // on prend la 1ere appli de meme classe.
				{
					GList *pList = pClassAppli->pAppliOfClass;
					if (pList != NULL)
					{
						pSameClassIcon = pList->data;
						if (pSameClassIcon->Xid == Xid)  // normalement impossible.
						{
							if (pList->next != NULL)
								pSameClassIcon = pList->next->data;
							else
								pSameClassIcon = NULL;
						}
					}
					iNextXid = (pSameClassIcon != NULL ? pSameClassIcon->Xid : 0);
					if (pSameClassIcon != NULL)
					{
						cd_message ("  c'est %s qui va la remplacer", pSameClassIcon->acName);
						CairoDock *pClassSubDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
						if (pClassSubDock != NULL)
						{
							cairo_dock_detach_icon_from_dock (pSameClassIcon, pClassSubDock, FALSE);
							if (pClassSubDock->icons == NULL && pClassSubDock == cairo_dock_search_dock_from_name (cClass))  // le sous-dock de la classe devient vide.
								cairo_dock_destroy_dock (pClassSubDock, cClass, NULL, NULL);
							else
								cairo_dock_update_dock_size (pClassSubDock);
						}
					}
				}
				pIcon->Xid = iNextXid;
				pIcon->bHasIndicator = (iNextXid != 0);
				_cairo_dock_set_same_indicator_on_sub_dock (pIcon);
				cd_message (" %s : bHasIndicator <- %d, Xid <- %d", pIcon->acName, pIcon->bHasIndicator, pIcon->Xid);
			}
		}
	}
}
void cairo_dock_activate_module_and_load (gchar *cModuleName)
{
	if (g_pMainDock == NULL)
		return ;
	gchar *list[2] = {cModuleName, NULL};
	cairo_dock_activate_modules_from_list (list, g_pMainDock, 0);
	
	CairoDockModule *pModule = cairo_dock_find_module_from_name (cModuleName);
	if (pModule != NULL && CAIRO_DOCK_IS_DOCK (pModule->pContainer))
	{
		CairoDock *pDock = CAIRO_DOCK (pModule->pContainer);
		cairo_dock_update_dock_size (pDock);
		gtk_widget_queue_draw (pDock->pWidget);
	}
	
	cairo_dock_update_conf_file_with_active_modules2 (NULL, g_cConfFile);
}
void cairo_dock_reload_module (CairoDockModule *module, gboolean bReloadAppletConf)
{
	GError *erreur = NULL;
	g_return_if_fail (module != NULL);
	CairoContainer *pActualContainer = module->pContainer;
	gboolean bContainerTypeChanged = FALSE;
	module->pContainer = NULL;
	cd_message ("%s (%s, %d)", __func__, module->pVisitCard->cModuleName, bReloadAppletConf);

	//\______________ On tente de recharger le module.
	gboolean bModuleReloaded = FALSE;
	if (module->bActive && module->reloadModule != NULL)
	{
		Icon *pIcon = cairo_dock_find_icon_from_module (module, pActualContainer);

		GKeyFile *pKeyFile = NULL;
		CairoDockMinimalAppletConfig *pMinimalConfig = NULL;
		gboolean bToBeInserted = FALSE;
		gboolean bNeedFreeDesklet = FALSE;
		CairoContainer *pNewContainer = NULL;
		if (bReloadAppletConf && module->cConfFilePath != NULL)
		{
			pMinimalConfig = g_new0 (CairoDockMinimalAppletConfig, 1);
			pKeyFile = cairo_dock_pre_read_module_config (module, pMinimalConfig);

			if (pMinimalConfig->iDesiredIconWidth > -1)  // c'est une applet.
			{
				if (pIcon != NULL)
				{
					g_free (pIcon->acName);
					pIcon->acName = pMinimalConfig->cLabel;
					pMinimalConfig->cLabel = NULL;  // astuce.
					g_free (pIcon->acFileName);
					pIcon->acFileName = pMinimalConfig->cIconFileName;
					pMinimalConfig->cIconFileName = NULL;
				}

				if (pMinimalConfig->bIsDetached)  // l'applet est maintenant dans un desklet.
				{
					CairoDesklet *pDesklet;
					if (CAIRO_DOCK_IS_DOCK (pActualContainer))  // elle etait dans un dock.
					{
						cd_message ("le container a change (%s -> desklet)", pIcon->cParentDockName);
						gchar *cOldDockName = g_strdup (pIcon->cParentDockName);
						cairo_dock_detach_icon_from_dock (pIcon, CAIRO_DOCK (pActualContainer), g_bUseSeparator);
						if (CAIRO_DOCK (pActualContainer)->icons == NULL)
							cairo_dock_destroy_dock (CAIRO_DOCK (pActualContainer), cOldDockName, NULL, NULL);
						else
							cairo_dock_update_dock_size (CAIRO_DOCK (pActualContainer));
						g_free (cOldDockName);
						pDesklet = cairo_dock_create_desklet (pIcon, NULL, pMinimalConfig->bOnWidgetLayer);
						bContainerTypeChanged = TRUE;
					}
					else
					{
						pDesklet = CAIRO_DESKLET (pActualContainer);
					}
					pNewContainer = CAIRO_CONTAINER (pDesklet);
					cairo_dock_place_desklet (pDesklet, pMinimalConfig);
				}
				else  // l'applet est maintenant dans un dock.
				{
					gchar *cDockName = (pMinimalConfig->cDockName != NULL ? pMinimalConfig->cDockName : CAIRO_DOCK_MAIN_DOCK_NAME);
					CairoDock *pDock = cairo_dock_search_dock_from_name (cDockName);
					if (pDock == NULL)  // c'est un nouveau dock.
					{
						pDock = cairo_dock_create_new_dock (g_iWmHint, cDockName, NULL);
						cairo_dock_place_root_dock (pDock);
					}
					
					if (CAIRO_DOCK_IS_DESKLET (pActualContainer))  // elle etait dans un desklet.
					{
						bNeedFreeDesklet = TRUE;  // le desklet sera detruit apres le reload.
						cairo_dock_steal_interactive_widget_from_desklet (CAIRO_DESKLET (pActualContainer));
						///cairo_dock_free_desklet (CAIRO_DESKLET (pActualContainer));
						///pActualContainer = NULL;
						bToBeInserted = TRUE;  // l'icone sera inseree dans le dock avant le reload.
						bContainerTypeChanged = TRUE;
					}
					else  // elle etait deja dans un dock.
					{
						if (pActualContainer != CAIRO_CONTAINER (pDock))  // le dock a change.
						{
							cd_message ("le dock a change (%s -> %s)", pIcon->cParentDockName, cDockName);
							gchar *cOldDockName = g_strdup (pIcon->cParentDockName);
							cairo_dock_detach_icon_from_dock (pIcon, CAIRO_DOCK (pActualContainer), g_bUseSeparator);
							if (CAIRO_DOCK (pActualContainer)->icons == NULL)
								cairo_dock_destroy_dock (CAIRO_DOCK (pActualContainer), cOldDockName, NULL, NULL);
							else
								cairo_dock_update_dock_size (CAIRO_DOCK (pActualContainer));
							g_free (cOldDockName);
							bToBeInserted = TRUE;  // l'icone sera inseree dans le dock avant le reload.
						}
					}
					pNewContainer = CAIRO_CONTAINER (pDock);
				}
			}
		}
		else
			pNewContainer = pActualContainer;

		module->pContainer = pNewContainer;
		if (CAIRO_DOCK_IS_DOCK (pNewContainer) && pIcon != NULL)
		{
			if (pMinimalConfig != NULL)
			{
				pIcon->fWidth = pMinimalConfig->iDesiredIconWidth;
				pIcon->fHeight = pMinimalConfig->iDesiredIconHeight;
			}
			cairo_dock_load_one_icon_from_scratch (pIcon, pNewContainer);

			if (bToBeInserted)
			{
				CairoDock *pDock = CAIRO_DOCK (pNewContainer);
				cairo_dock_insert_icon_in_dock (pIcon, pDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON, CAIRO_DOCK_APPLY_RATIO, g_bUseSeparator);
				pIcon->cParentDockName = g_strdup (pMinimalConfig->cDockName);
				cairo_dock_start_animation (pIcon, pDock);
			}
			else
			{
				pIcon->fWidth *= CAIRO_DOCK (pActualContainer)->fRatio;
				pIcon->fHeight *= CAIRO_DOCK (pActualContainer)->fRatio;
				
				if (bReloadAppletConf)
					cairo_dock_update_dock_size (CAIRO_DOCK (pNewContainer));
			}
		}
		
		bModuleReloaded = module->reloadModule (pKeyFile, module->cConfFilePath, pNewContainer);
		
		if (pNewContainer != pActualContainer && CAIRO_DOCK_IS_DOCK (pNewContainer) && CAIRO_DOCK_IS_DOCK (pActualContainer) && pIcon != NULL)
		{
			cairo_dock_synchronize_one_sub_dock_position (pIcon, CAIRO_DOCK (pNewContainer), TRUE);
		}
		
		cairo_dock_free_minimal_config (pMinimalConfig);
		if (pKeyFile != NULL)
			g_key_file_free (pKeyFile);
		
		if (bNeedFreeDesklet)
			cairo_dock_free_desklet (CAIRO_DESKLET (pActualContainer));
	}
}
static void _cairo_dock_resize_one_dock (gchar *cDockName, CairoDock *pDock, gpointer data)
{
	cairo_dock_update_dock_size (pDock);
}
void cairo_dock_swap_icons (CairoDock *pDock, Icon *icon1, Icon *icon2)
{
	//g_print ("%s (%s, %s) : %.2f <-> %.2f\n", __func__, icon1->acName, icon2->acName, icon1->fOrder, icon2->fOrder);
	if (! ( (CAIRO_DOCK_IS_APPLI (icon1) && CAIRO_DOCK_IS_APPLI (icon2)) || (CAIRO_DOCK_IS_LAUNCHER (icon1) && CAIRO_DOCK_IS_LAUNCHER (icon2)) || (CAIRO_DOCK_IS_APPLET (icon1) && CAIRO_DOCK_IS_APPLET (icon2)) ) )
		return ;

	//\_________________ On intervertit les ordres des 2 lanceurs.
	double fSwap = icon1->fOrder;
	icon1->fOrder = icon2->fOrder;
	icon2->fOrder = fSwap;

	//\_________________ On change l'ordre dans les fichiers des 2 lanceurs.
	if (CAIRO_DOCK_IS_LAUNCHER (icon1))  // ce sont des lanceurs.
	{
		gchar *cDesktopFilePath;
		GKeyFile* pKeyFile;

		if (icon1->acDesktopFileName != NULL)
		{
			cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, icon1->acDesktopFileName);
			pKeyFile = cairo_dock_open_key_file (cDesktopFilePath);
			if (pKeyFile == NULL)
				return ;

			g_key_file_set_double (pKeyFile, "Desktop Entry", "Order", icon1->fOrder);
			cairo_dock_write_keys_to_file (pKeyFile, cDesktopFilePath);
			g_key_file_free (pKeyFile);
			g_free (cDesktopFilePath);
		}

		if (icon2->acDesktopFileName != NULL)
		{
			cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, icon2->acDesktopFileName);
			pKeyFile = cairo_dock_open_key_file (cDesktopFilePath);
			if (pKeyFile == NULL)
				return ;

			g_key_file_set_double (pKeyFile, "Desktop Entry", "Order", icon2->fOrder);
			cairo_dock_write_keys_to_file (pKeyFile, cDesktopFilePath);
			g_key_file_free (pKeyFile);
			g_free (cDesktopFilePath);
		}
	}

	//\_________________ On les intervertit dans la liste.
	if (pDock->pFirstDrawnElement != NULL && (pDock->pFirstDrawnElement->data == icon1 || pDock->pFirstDrawnElement->data == icon2))
		pDock->pFirstDrawnElement = NULL;
	pDock->icons = g_list_remove (pDock->icons, icon1);
	pDock->icons = g_list_remove (pDock->icons, icon2);
	pDock->icons = g_list_insert_sorted (pDock->icons,
		icon1,
		(GCompareFunc) cairo_dock_compare_icons_order);
	pDock->icons = g_list_insert_sorted (pDock->icons,
		icon2,
		(GCompareFunc) cairo_dock_compare_icons_order);

	//\_________________ On recalcule la largeur max, qui peut avoir ete influencee par le changement d'ordre.
	cairo_dock_update_dock_size (pDock);

	//\_________________ On met a jour l'ordre des applets dans le fichier de conf.
	if (CAIRO_DOCK_IS_APPLET (icon1))
		cairo_dock_update_module_instance_order (icon1->pModuleInstance, icon1->fOrder);
	if (CAIRO_DOCK_IS_APPLET (icon2))
		cairo_dock_update_module_instance_order (icon2->pModuleInstance, icon2->fOrder);
	if (fabs (icon2->fOrder - icon1->fOrder) < 1e-3)
	{
		cairo_dock_normalize_icons_order (pDock->icons, icon1->iType);
	}
}
static GKeyFile* reload_object (GldiObject *obj, gboolean bReloadConf, GKeyFile *pKeyFile)
{
	Icon *icon = (Icon*)obj;
	if (bReloadConf)
		g_return_val_if_fail (pKeyFile != NULL, NULL);
	
	// get additional parameters
	g_free (icon->cFileName);
	icon->cFileName = g_key_file_get_string (pKeyFile, "Desktop Entry", "Icon", NULL);
	if (icon->cFileName != NULL && *icon->cFileName == '\0')
	{
		g_free (icon->cFileName);
		icon->cFileName = NULL;
	}
	
	gchar *cName = icon->cName;
	icon->cName = cairo_dock_get_locale_string_from_conf_file (pKeyFile, "Desktop Entry", "Name", NULL);
	if (icon->cName == NULL || *icon->cName == '\0')  // no name defined, we need one.
	{
		g_free (icon->cName);
		if (cName != NULL)
			icon->cName = g_strdup (cName);
		else
			icon->cName = cairo_dock_get_unique_dock_name ("sub-dock");
		g_key_file_set_string (pKeyFile, "Desktop Entry", "Name", icon->cName);
		gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, icon->cDesktopFileName);
		cairo_dock_write_keys_to_file (pKeyFile, cDesktopFilePath);
		g_free (cDesktopFilePath);
	}
	
	// if it has changed, ensure its unicity, and rename the sub-dock to be able to link with it again.
	if (g_strcmp0 (icon->cName, cName) != 0)  // name has changed -> rename the sub-dock.
	{
		// ensure unicity
		gchar *cUniqueName = cairo_dock_get_unique_dock_name (icon->cName);
		if (strcmp (icon->cName, cUniqueName) != 0)
		{
			g_free (icon->cName);
			icon->cName = cUniqueName;
			cUniqueName = NULL;
			g_key_file_set_string (pKeyFile, "Desktop Entry", "Name", icon->cName);
			gchar *cDesktopFilePath = g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, icon->cDesktopFileName);
			cairo_dock_write_keys_to_file (pKeyFile, cDesktopFilePath);
			g_free (cDesktopFilePath);
		}
		g_free (cUniqueName);
		
		// rename sub-dock
		cd_debug ("on renomme a l'avance le sous-dock en %s", icon->cName);
		if (icon->pSubDock != NULL)
			gldi_dock_rename (icon->pSubDock, icon->cName);  // also updates sub-icon's container name
	}
	
	icon->iSubdockViewType = g_key_file_get_integer (pKeyFile, "Desktop Entry", "render", NULL);  // on a besoin d'un entier dans le panneau de conf pour pouvoir degriser des options selon le rendu choisi. De plus c'est utile aussi pour Animated Icons...
	
	gchar *cSubDockRendererName = g_key_file_get_string (pKeyFile, "Desktop Entry", "Renderer", NULL);
	
	//\_____________ reload icon
	// redraw icon
	cairo_dock_load_icon_image (icon, icon->pContainer);
	
	// reload label
	if (g_strcmp0 (cName, icon->cName) != 0)
		cairo_dock_load_icon_text (icon);
	
	// set sub-dock renderer
	if (icon->pSubDock != NULL)
	{
		if (g_strcmp0 (cSubDockRendererName, icon->pSubDock->cRendererName) != 0)
		{
			cairo_dock_set_renderer (icon->pSubDock, cSubDockRendererName);
			cairo_dock_update_dock_size (icon->pSubDock);
		}
	}
	
	g_free (cSubDockRendererName);
	g_free (cName);
	
	return pKeyFile;
}