/**
* This file is a part of the Cairo-Dock project
*
* Copyright : (C) see the 'copyright' file.
* E-mail : see the 'copyright' file.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include
#include
#include "cairo-dock-icon-facility.h" // cairo_dock_compute_icon_area
#include "cairo-dock-dock-facility.h" // cairo_dock_is_hidden
#include "cairo-dock-module-factory.h" // cairo_dock_search_container_from_icon
#include "cairo-dock-dock-manager.h" // cairo_dock_search_dock_from_name
#include "cairo-dock-desklet-factory.h" // cairo_dock_search_container_from_icon
#include "cairo-dock-dialog-manager.h"
#include "cairo-dock-log.h"
#include "cairo-dock-config.h"
#include "cairo-dock-opengl.h"
#include "cairo-dock-notifications.h"
#include "cairo-dock-animations.h" // cairo_dock_animation_will_be_visible
#include "cairo-dock-X-manager.h" // g_desktopGeometry
#define _MANAGER_DEF_
#include "cairo-dock-container.h"
// public (manager, config, data)
CairoContainersParam myContainersParam;
CairoContainersManager myContainersMgr;
CairoContainer *g_pPrimaryContainer = NULL;
CairoDockDesktopBackground *g_pFakeTransparencyDesktopBg = NULL;
gboolean g_bUseGlitz = FALSE;
// dependancies
extern CairoDockGLConfig g_openglConfig;
extern gboolean g_bUseOpenGL;
extern CairoDockHidingEffect *g_pHidingBackend; // cairo_dock_is_hidden
extern CairoDockDesktopGeometry g_desktopGeometry; // _place_menu_on_icon
// private
static gboolean s_bSticky = TRUE;
void cairo_dock_set_containers_non_sticky (void)
{
if (g_pPrimaryContainer != NULL)
{
cd_warning ("this function has to be called before any container is created.");
return;
}
s_bSticky = FALSE;
}
static gboolean _prevent_delete (GtkWidget *pWidget, GdkEvent *event, gpointer data)
{
cd_debug ("pas de alt+f4");
return TRUE; // on empeche les ALT+F4 malheureux.
}
static void cairo_dock_set_default_rgba_visual (GtkWidget *pWidget)
{
GdkScreen* pScreen = gtk_widget_get_screen (pWidget);
#if (GTK_MAJOR_VERSION < 3)
GdkColormap* pColormap = gdk_screen_get_rgba_colormap (pScreen);
if (!pColormap)
pColormap = gdk_screen_get_rgb_colormap (pScreen);
gtk_widget_set_colormap (pWidget, pColormap);
#else
GdkVisual *pGdkVisual = gdk_screen_get_rgba_visual (pScreen);
if (pGdkVisual == NULL)
pGdkVisual = gdk_screen_get_system_visual (pScreen);
gtk_widget_set_visual (pWidget, pGdkVisual);
#endif
}
GtkWidget *cairo_dock_init_container_full (CairoContainer *pContainer, gboolean bOpenGLWindow)
{
GtkWidget* pWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
pContainer->pWidget = pWindow;
if (g_bUseOpenGL && bOpenGLWindow)
{
gldi_glx_init_container (pContainer);
pContainer->iAnimationDeltaT = myContainersParam.iGLAnimationDeltaT;
}
else
{
cairo_dock_set_default_rgba_visual (pWindow);
pContainer->iAnimationDeltaT = myContainersParam.iCairoAnimationDeltaT;
}
if (pContainer->iAnimationDeltaT == 0)
pContainer->iAnimationDeltaT = 30;
g_signal_connect (G_OBJECT (pWindow),
"delete-event",
G_CALLBACK (_prevent_delete),
NULL);
gtk_widget_set_app_paintable (pWindow, TRUE);
gtk_window_set_decorated (GTK_WINDOW (pWindow), FALSE);
gtk_window_set_skip_pager_hint (GTK_WINDOW(pWindow), TRUE);
gtk_window_set_skip_taskbar_hint (GTK_WINDOW(pWindow), TRUE);
if (s_bSticky)
gtk_window_stick (GTK_WINDOW (pWindow));
// needed since gtk+-3.0 but it's possible that this resize grip has been backported to gtk+-2.0 (e.g. in Ubuntu Natty...)
#if (GTK_MAJOR_VERSION >= 3 || ENABLE_GTK_GRIP == 1)
gtk_window_set_has_resize_grip (GTK_WINDOW(pWindow), FALSE);
#endif
cairo_dock_install_notifications_on_object (pContainer, NB_NOTIFICATIONS_CONTAINER); // l'implementation du container installera par-dessus ses notifications.
if (g_pPrimaryContainer == NULL)
{
g_pPrimaryContainer = pContainer;
}
return pWindow;
}
void cairo_dock_finish_container (CairoContainer *pContainer)
{
gldi_glx_finish_container (pContainer);
gtk_widget_destroy (pContainer->pWidget); // enleve les signaux.
pContainer->pWidget = NULL;
if (pContainer->iSidGLAnimation != 0)
{
g_source_remove (pContainer->iSidGLAnimation);
pContainer->iSidGLAnimation = 0;
}
cairo_dock_clear_notifications_on_object (pContainer);
pContainer->pNotificationsTab = NULL;
if (g_pPrimaryContainer == pContainer)
g_pPrimaryContainer = NULL;
}
void cairo_dock_redraw_container (CairoContainer *pContainer)
{
g_return_if_fail (pContainer != NULL);
GdkRectangle rect = {0, 0, pContainer->iWidth, pContainer->iHeight};
if (! pContainer->bIsHorizontal)
{
rect.width = pContainer->iHeight;
rect.height = pContainer->iWidth;
}
cairo_dock_redraw_container_area (pContainer, &rect);
}
static inline void _redraw_container_area (CairoContainer *pContainer, GdkRectangle *pArea)
{
g_return_if_fail (pContainer != NULL);
if (! gldi_container_is_visible (pContainer))
return ;
if (pArea->y < 0)
pArea->y = 0;
if (pContainer->bIsHorizontal && pArea->y + pArea->height > pContainer->iHeight)
pArea->height = pContainer->iHeight - pArea->y;
else if (! pContainer->bIsHorizontal && pArea->x + pArea->width > pContainer->iHeight)
pArea->width = pContainer->iHeight - pArea->x;
if (pArea->width > 0 && pArea->height > 0)
gdk_window_invalidate_rect (gldi_container_get_gdk_window (pContainer), pArea, FALSE);
}
void cairo_dock_redraw_container_area (CairoContainer *pContainer, GdkRectangle *pArea)
{
if (CAIRO_DOCK_IS_DOCK (pContainer) && ! cairo_dock_animation_will_be_visible (CAIRO_DOCK (pContainer))) // inutile de redessiner.
return ;
_redraw_container_area (pContainer, pArea);
}
void cairo_dock_redraw_icon (Icon *icon, CairoContainer *pContainer)
{
g_return_if_fail (icon != NULL && pContainer != NULL);
GdkRectangle rect;
cairo_dock_compute_icon_area (icon, pContainer, &rect);
if (CAIRO_DOCK_IS_DOCK (pContainer) &&
( (cairo_dock_is_hidden (CAIRO_DOCK (pContainer)) && ! icon->bIsDemandingAttention && ! icon->bAlwaysVisible)
|| (CAIRO_DOCK (pContainer)->iRefCount != 0 && ! gldi_container_is_visible (pContainer)) ) ) // inutile de redessiner.
return ;
_redraw_container_area (pContainer, &rect);
}
static gboolean _cairo_dock_search_icon_in_desklet (CairoDesklet *pDesklet, Icon *icon)
{
if (pDesklet->icons != NULL)
{
Icon *pIcon;
GList *ic;
for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
{
pIcon = ic->data;
if (pIcon == icon)
return TRUE;
}
}
return FALSE;
}
CairoContainer *cairo_dock_search_container_from_icon (Icon *icon)
{
g_return_val_if_fail (icon != NULL, NULL);
if (CAIRO_DOCK_IS_APPLET (icon))
{
return icon->pModuleInstance->pContainer;
}
else if (icon->cParentDockName != NULL)
{
return CAIRO_CONTAINER (cairo_dock_search_dock_from_name (icon->cParentDockName));
}
else
{
CairoDesklet *pDesklet = cairo_dock_foreach_desklet ((CairoDockForeachDeskletFunc)_cairo_dock_search_icon_in_desklet, icon);
return CAIRO_CONTAINER (pDesklet);
}
}
void cairo_dock_allow_widget_to_receive_data (GtkWidget *pWidget, GCallback pCallBack, gpointer data)
{
/*GtkTargetEntry pTargetEntry[6] = {0};
pTargetEntry[0].target = (gchar*)"text/*";
pTargetEntry[0].flags = (GtkTargetFlags) 0;
pTargetEntry[0].info = 0;
pTargetEntry[1].target = (gchar*)"text/uri-list";
pTargetEntry[2].target = (gchar*)"text/plain";
pTargetEntry[3].target = (gchar*)"text/plain;charset=UTF-8";
pTargetEntry[4].target = (gchar*)"text/directory";
pTargetEntry[5].target = (gchar*)"text/html";
gtk_drag_dest_set (pWidget,
GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_MOTION, // GTK_DEST_DEFAULT_HIGHLIGHT ne rend pas joli je trouve.
pTargetEntry,
6,
GDK_ACTION_COPY | GDK_ACTION_MOVE); // le 'GDK_ACTION_MOVE' c'est pour KDE.*/
gtk_drag_dest_set (pWidget,
GTK_DEST_DEFAULT_DROP | GTK_DEST_DEFAULT_MOTION, // GTK_DEST_DEFAULT_HIGHLIGHT ne rend pas joli je trouve.
NULL,
0,
GDK_ACTION_COPY | GDK_ACTION_MOVE); // le 'GDK_ACTION_MOVE' c'est pour KDE.
gtk_drag_dest_add_text_targets (pWidget);
gtk_drag_dest_add_uri_targets (pWidget);
g_signal_connect (G_OBJECT (pWidget),
"drag_data_received",
pCallBack,
data);
}
void gldi_container_disable_drop (CairoContainer *pContainer)
{
gtk_drag_dest_set_target_list (pContainer->pWidget, NULL);
}
gboolean cairo_dock_string_is_adress (const gchar *cString)
{
gchar *protocole = g_strstr_len (cString, -1, "://");
if (protocole == NULL || protocole == cString)
{
if (strncmp (cString, "www", 3) == 0)
return TRUE;
return FALSE;
}
const gchar *str = cString;
while (*str == ' ')
str ++;
while (str < protocole)
{
if (! g_ascii_isalnum (*str) && *str != '-') // x-nautilus-desktop://
return FALSE;
str ++;
}
return TRUE;
}
void cairo_dock_notify_drop_data (gchar *cReceivedData, Icon *pPointedIcon, double fOrder, CairoContainer *pContainer)
{
g_return_if_fail (cReceivedData != NULL);
gchar *cData = NULL;
gchar **cStringList = g_strsplit (cReceivedData, "\n", -1);
GString *sArg = g_string_new ("");
int i=0, j;
while (cStringList[i] != NULL)
{
g_string_assign (sArg, cStringList[i]);
if (! cairo_dock_string_is_adress (cStringList[i]))
{
j = i + 1;
while (cStringList[j] != NULL)
{
if (cairo_dock_string_is_adress (cStringList[j]))
break ;
g_string_append_printf (sArg, "\n%s", cStringList[j]);
j ++;
}
i = j;
}
else
{
cd_debug (" + adresse");
if (sArg->str[sArg->len-1] == '\r')
{
cd_debug ("retour charriot");
sArg->str[sArg->len-1] = '\0';
}
i ++;
}
cData = sArg->str;
cd_debug (" notification de drop '%s'", cData);
cairo_dock_notify_on_object (&myContainersMgr, NOTIFICATION_DROP_DATA, cData, pPointedIcon, fOrder, pContainer);
cairo_dock_notify_on_object (pContainer, NOTIFICATION_DROP_DATA, cData, pPointedIcon, fOrder, pContainer);
}
g_strfreev (cStringList);
g_string_free (sArg, TRUE);
}
gboolean cairo_dock_emit_signal_on_container (CairoContainer *pContainer, const gchar *cSignal)
{
static gboolean bReturn;
g_signal_emit_by_name (pContainer->pWidget, cSignal, NULL, &bReturn);
return FALSE;
}
gboolean cairo_dock_emit_leave_signal (CairoContainer *pContainer)
{
// actualize the coordinates of the pointer, since they are most probably out-dated (because the mouse has left the dock, or because a right-click generates an event with (0;0) coordinates)
if (pContainer->bIsHorizontal)
gdk_window_get_pointer (gldi_container_get_gdk_window (pContainer), &pContainer->iMouseX, &pContainer->iMouseY, NULL);
else
gdk_window_get_pointer (gldi_container_get_gdk_window (pContainer), &pContainer->iMouseY, &pContainer->iMouseX, NULL);
return cairo_dock_emit_signal_on_container (pContainer, "leave-notify-event");
}
gboolean cairo_dock_emit_enter_signal (CairoContainer *pContainer)
{
return cairo_dock_emit_signal_on_container (pContainer, "enter-notify-event");
}
static void _cairo_dock_delete_menu (GtkMenuShell *menu, CairoDock *pDock)
{
g_return_if_fail (CAIRO_DOCK_IS_DOCK (pDock));
pDock->bMenuVisible = FALSE;
///pDock->container.bInside = TRUE;
cairo_dock_emit_leave_signal (CAIRO_CONTAINER (pDock));
}
static void _place_menu_on_icon (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer *data)
{
*push_in = TRUE;
Icon *pIcon = data[0];
CairoContainer *pContainer = data[1];
int x0 = pContainer->iWindowPositionX + pIcon->fDrawX;
int y0 = pContainer->iWindowPositionY + pIcon->fDrawY;
int w, h; // taille menu
GtkRequisition requisition;
#if (GTK_MAJOR_VERSION < 3)
gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
#else
gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
#endif
w = requisition.width;
h = requisition.height;
//g_print ("%d;%d %dx%d\n", x0, y0, w, h);
if (pContainer->bIsHorizontal)
{
*x = x0;
if (y0 > g_desktopGeometry.iXScreenHeight[pContainer->bIsHorizontal]/2) // pContainer->bDirectionUp
*y = y0 - h;
else
*y = y0 + pIcon->fHeight * pIcon->fScale;
}
else
{
*y = MIN (x0, g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - h);
if (y0 > g_desktopGeometry.iXScreenHeight[pContainer->bIsHorizontal]/2) // pContainer->bDirectionUp
*x = y0 - w;
else
*x = y0 + pIcon->fHeight * pIcon->fScale;
}
}
void cairo_dock_popup_menu_on_icon (GtkWidget *menu, Icon *pIcon, CairoContainer *pContainer)
{
static gpointer *data = NULL; // 1 seul menu a la fois, donc on peut la faire statique.
if (menu == NULL)
return;
GtkMenuPositionFunc place_menu = NULL;
if (pIcon != NULL && pContainer != NULL)
{
place_menu = (GtkMenuPositionFunc)_place_menu_on_icon;
if (data == NULL)
data = g_new0 (gpointer, 2);
data[0] = pIcon;
data[1] = pContainer;
}
if (CAIRO_DOCK_IS_DOCK (pContainer))
{
if (g_signal_handler_find (menu,
G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
0,
0,
NULL,
_cairo_dock_delete_menu,
pContainer) == 0) // on evite de connecter 2 fois ce signal, donc la fonction est appelable plusieurs fois sur un meme menu.
{
g_signal_connect (G_OBJECT (menu),
"deactivate",
G_CALLBACK (_cairo_dock_delete_menu),
pContainer);
}
CAIRO_DOCK (pContainer)->bMenuVisible = TRUE;
}
gtk_widget_show_all (GTK_WIDGET (menu));
gtk_menu_popup (GTK_MENU (menu),
NULL,
NULL,
place_menu,
data,
1,
gtk_get_current_event_time ());
}
GtkWidget *cairo_dock_add_in_menu_with_stock_and_data (const gchar *cLabel, const gchar *gtkStock, GCallback pFunction, GtkWidget *pMenu, gpointer pData)
{
GtkWidget *pMenuItem = gtk_image_menu_item_new_with_label (cLabel);
if (gtkStock)
{
GtkWidget *image = NULL;
if (*gtkStock == '/')
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (gtkStock, 16, 16, NULL);
image = gtk_image_new_from_pixbuf (pixbuf);
g_object_unref (pixbuf);
}
else
{
image = gtk_image_new_from_stock (gtkStock, GTK_ICON_SIZE_MENU);
}
#if (GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION >= 16)
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (pMenuItem), TRUE);
#endif
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (pMenuItem), image);
}
gtk_menu_shell_append (GTK_MENU_SHELL (pMenu), pMenuItem);
if (pFunction)
g_signal_connect (G_OBJECT (pMenuItem), "activate", G_CALLBACK (pFunction), pData);
return pMenuItem;
}
GtkWidget *cairo_dock_create_sub_menu (const gchar *cLabel, GtkWidget *pMenu, const gchar *cImage)
{
GtkWidget *pMenuItem, *image, *pSubMenu = gtk_menu_new ();
if (cImage == NULL)
{
pMenuItem = gtk_menu_item_new_with_label (cLabel);
}
else
{
pMenuItem = gtk_image_menu_item_new_with_label (cLabel);
if (*cImage == '/')
{
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (cImage, 24, 24, NULL);
image = gtk_image_new_from_pixbuf (pixbuf);
g_object_unref (pixbuf);
}
else
{
image = gtk_image_new_from_stock (cImage, GTK_ICON_SIZE_MENU);
}
#if (GTK_MAJOR_VERSION > 2 || GTK_MINOR_VERSION >= 16)
gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (pMenuItem), TRUE);
#endif
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (pMenuItem), image);
}
gtk_menu_shell_append (GTK_MENU_SHELL (pMenu), pMenuItem);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (pMenuItem), pSubMenu);
return pSubMenu;
}
static GtkWidget *s_pMenu = NULL;
static gboolean _on_destroy_menu (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
cd_debug ("*** menu destroyed");
s_pMenu = NULL;
return FALSE;
}
GtkWidget *cairo_dock_build_menu (Icon *icon, CairoContainer *pContainer)
{
if (s_pMenu != NULL)
{
cd_debug ("previous menu still alive");
gtk_widget_destroy (GTK_WIDGET (s_pMenu));
s_pMenu = NULL;
}
g_return_val_if_fail (pContainer != NULL, NULL);
//\_________________________ On construit le menu.
GtkWidget *menu = gtk_menu_new ();
//\_________________________ On passe la main a ceux qui veulent y rajouter des choses.
gboolean bDiscardMenu = FALSE;
cairo_dock_notify_on_object (&myContainersMgr, NOTIFICATION_BUILD_CONTAINER_MENU, icon, pContainer, menu, &bDiscardMenu);
cairo_dock_notify_on_object (pContainer, NOTIFICATION_BUILD_CONTAINER_MENU, icon, pContainer, menu, &bDiscardMenu);
if (bDiscardMenu)
{
gtk_widget_destroy (menu);
return NULL;
}
cairo_dock_notify_on_object (&myContainersMgr, NOTIFICATION_BUILD_ICON_MENU, icon, pContainer, menu);
cairo_dock_notify_on_object (pContainer, NOTIFICATION_BUILD_ICON_MENU, icon, pContainer, menu);
g_signal_connect (G_OBJECT (menu), "destroy", G_CALLBACK (_on_destroy_menu), NULL); // apparemment inutile.
s_pMenu = menu;
return menu;
}
GldiShape *gldi_container_create_input_shape (CairoContainer *pContainer, int x, int y, int w, int h)
{
if (pContainer->iWidth == 0 || pContainer->iHeight == 0) // very unlikely to happen, but anyway avoid this case.
return NULL;
#if (GTK_MAJOR_VERSION < 3)
int W, H;
if (pContainer->bIsHorizontal)
{
W = pContainer->iWidth;
H = pContainer->iHeight;
}
else
{
W = pContainer->iHeight;
H = pContainer->iWidth;
}
GdkBitmap *pShapeBitmap = (GdkBitmap*) gdk_pixmap_new (NULL,
W,
H,
1);
cairo_t *pCairoContext = gdk_cairo_create (pShapeBitmap);
g_return_val_if_fail (pCairoContext != NULL, NULL); // if no context, abort (https://bugs.launchpad.net/cairo-dock-plug-ins/+bug/861725)
cairo_set_source_rgba (pCairoContext, 0.0f, 0.0f, 0.0f, 0.0f);
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
cairo_paint (pCairoContext);
cairo_set_source_rgba (pCairoContext, 1., 1., 1., 1.);
cairo_rectangle (pCairoContext,
x,
y,
w,
h);
cairo_fill (pCairoContext);
cairo_destroy (pCairoContext);
#else
cairo_rectangle_int_t rect = {x, y, w, h};
cairo_region_t *pShapeBitmap = cairo_region_create_rectangle (&rect); // for a more complex shape, we would need to draw it on a cairo_surface_t, and then make it a region with gdk_cairo_region_from_surface().
#endif
return pShapeBitmap;
}
//////////////////
/// GET CONFIG ///
//////////////////
static gboolean get_config (GKeyFile *pKeyFile, CairoContainersParam *pContainersParam)
{
gboolean bFlushConfFileNeeded = FALSE;
pContainersParam->bUseFakeTransparency = cairo_dock_get_boolean_key_value (pKeyFile, "System", "fake transparency", &bFlushConfFileNeeded, FALSE, NULL, NULL);
if (g_bUseOpenGL && ! g_openglConfig.bAlphaAvailable)
pContainersParam->bUseFakeTransparency = TRUE;
int iRefreshFrequency = cairo_dock_get_integer_key_value (pKeyFile, "System", "opengl anim freq", &bFlushConfFileNeeded, 33, NULL, NULL);
pContainersParam->iGLAnimationDeltaT = 1000. / iRefreshFrequency;
iRefreshFrequency = cairo_dock_get_integer_key_value (pKeyFile, "System", "cairo anim freq", &bFlushConfFileNeeded, 25, NULL, NULL);
pContainersParam->iCairoAnimationDeltaT = 1000. / iRefreshFrequency;
//g_print ("iGLAnimationDeltaT: %d\n", pContainersParam->iGLAnimationDeltaT);
//pContainersParam->bConfigPanelTransparency = cairo_dock_get_boolean_key_value (pKeyFile, "System", "config transparency", &bFlushConfFileNeeded, TRUE, NULL, NULL);
return bFlushConfFileNeeded;
}
////////////
/// LOAD ///
////////////
static void load (void)
{
if (myContainersParam.bUseFakeTransparency)
{
g_pFakeTransparencyDesktopBg = cairo_dock_get_desktop_background (g_bUseOpenGL);
}
}
//////////////
/// RELOAD ///
//////////////
static void _set_below (CairoDock *pDock, gpointer data)
{
gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), GPOINTER_TO_INT (data));
}
static void reload (CairoContainersParam *pPrevContainers, CairoContainersParam *pContainers)
{
//\_______________ Fake Transparency.
if (pContainers->bUseFakeTransparency && ! pPrevContainers->bUseFakeTransparency)
{
cairo_dock_foreach_root_docks ((GFunc)_set_below, GINT_TO_POINTER (TRUE));
g_pFakeTransparencyDesktopBg = cairo_dock_get_desktop_background (g_bUseOpenGL);
}
else if (! pContainers->bUseFakeTransparency && pPrevContainers->bUseFakeTransparency)
{
cairo_dock_foreach_root_docks ((GFunc)_set_below, GINT_TO_POINTER (FALSE));
cairo_dock_destroy_desktop_background (g_pFakeTransparencyDesktopBg);
g_pFakeTransparencyDesktopBg = NULL;
}
}
//////////////
/// UNLOAD ///
//////////////
static void unload (void)
{
g_pFakeTransparencyDesktopBg = NULL; // no need to unref it, since everything is going to be unloaded, including the desktop_bg.
}
///////////////
/// MANAGER ///
///////////////
void gldi_register_containers_manager (void)
{
// Manager
memset (&myContainersMgr, 0, sizeof (CairoContainersManager));
myContainersMgr.mgr.cModuleName = "Containers";
myContainersMgr.mgr.init = NULL;
myContainersMgr.mgr.load = load;
myContainersMgr.mgr.unload = unload;
myContainersMgr.mgr.reload = (GldiManagerReloadFunc)reload;
myContainersMgr.mgr.get_config = (GldiManagerGetConfigFunc)get_config;
myContainersMgr.mgr.reset_config = (GldiManagerResetConfigFunc)NULL;
// Config
myContainersMgr.mgr.pConfig = (GldiManagerConfigPtr)&myContainersParam;
myContainersMgr.mgr.iSizeOfConfig = sizeof (CairoContainersParam);
// data
myContainersMgr.mgr.pData = (GldiManagerDataPtr)NULL;
myContainersMgr.mgr.iSizeOfData = 0;
// signals
cairo_dock_install_notifications_on_object (&myContainersMgr, NB_NOTIFICATIONS_CONTAINER);
// register
gldi_register_manager (GLDI_MANAGER(&myContainersMgr));
}