1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail : see the 'copyright' file.
6 *
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.
11 *
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/>.
18 */
19
20 #include <math.h>
21 #include <string.h>
22 #include <stdlib.h>
23
24 #include <gtk/gtk.h>
25
26 #include "gldi-config.h"
27 #include "cairo-dock-icon-factory.h"
28 #include "cairo-dock-module-instance-manager.h" // gldi_module_instance_reload
29 #include "cairo-dock-desklet-manager.h" // gldi_desklets_foreach_icons
30 #include "cairo-dock-log.h"
31 #include "cairo-dock-config.h"
32 #include "cairo-dock-class-manager.h" // cairo_dock_deinhibite_class
33 #include "cairo-dock-draw.h" // cairo_dock_render_icon_notification
34 #include "cairo-dock-draw-opengl.h" // cairo_dock_destroy_icon_fbo
35 #include "cairo-dock-container.h"
36 #include "cairo-dock-dock-manager.h" // gldi_icons_foreach_in_docks
37 #include "cairo-dock-dialog-manager.h" // cairo_dock_remove_dialog_if_any
38 #include "cairo-dock-data-renderer.h" // cairo_dock_remove_data_renderer_on_icon
39 #include "cairo-dock-animations.h" // cairo_dock_animation_will_be_visible
40 #include "cairo-dock-dock-facility.h" // cairo_dock_update_dock_size
41 #include "cairo-dock-icon-facility.h" // gldi_icons_foreach_of_type
42 #include "cairo-dock-keyfile-utilities.h" // cairo_dock_open_key_file
43 #include "cairo-dock-indicator-manager.h" // cairo_dock_unload_indicator_textures
44 #include "cairo-dock-desktop-manager.h" // gldi_desktop_get_current
45 #include "cairo-dock-user-icon-manager.h" // GLDI_OBJECT_IS_USER_ICON
46 #include "cairo-dock-separator-manager.h" // GLDI_OBJECT_IS_SEPARATOR_ICON
47 #include "cairo-dock-applications-manager.h" // GLDI_OBJECT_IS_APPLI_ICON
48 #include "cairo-dock-launcher-manager.h" // GLDI_OBJECT_IS_LAUNCHER_ICON
49 #include "cairo-dock-applet-manager.h" // GLDI_OBJECT_IS_APPLET_ICON
50 #include "cairo-dock-backends-manager.h" // cairo_dock_foreach_icon_container_renderer
51 #include "cairo-dock-style-manager.h"
52 #define _MANAGER_DEF_
53 #include "cairo-dock-icon-manager.h"
54
55 // public (manager, config, data)
56 CairoIconsParam myIconsParam;
57 GldiManager myIconsMgr;
58 GldiObjectManager myIconObjectMgr;
59 CairoDockImageBuffer g_pIconBackgroundBuffer;
60 GLuint g_pGradationTexture[2]={0, 0};
61
62 // dependencies
63 extern CairoDock *g_pMainDock;
64 extern gchar *g_cCurrentThemePath;
65 extern gboolean g_bUseOpenGL;
66 extern gchar *g_cCurrentIconsPath;
67
68 // private
69 static GList *s_pFloatingIconsList = NULL;
70 static int s_iNbNonStickyLaunchers = 0;
71 static GtkIconTheme *s_pIconTheme = NULL;
72 static gboolean s_bUseLocalIcons = FALSE;
73 static gboolean s_bUseDefaultTheme = TRUE;
74 static guint s_iSidReloadTheme = 0;
75
76 static void _cairo_dock_unload_icon_textures (void);
77 static void _cairo_dock_unload_icon_theme (void);
78 static void _on_icon_theme_changed (GtkIconTheme *pIconTheme, gpointer data);
79
80
gldi_icons_foreach(GldiIconFunc pFunction,gpointer pUserData)81 void gldi_icons_foreach (GldiIconFunc pFunction, gpointer pUserData)
82 {
83 gldi_icons_foreach_in_docks (pFunction, pUserData);
84 gldi_desklets_foreach_icons (pFunction, pUserData);
85 }
86
87 /////////////////////////
88 /// ICONS PER DESKTOP ///
89 /////////////////////////
90
91 #define _is_invisible_on_this_desktop(icon, index) (icon->iSpecificDesktop != 0 /*specific desktop is defined*/ \
92 && icon->iSpecificDesktop != index /*specific desktop is not the current one*/ \
93 && icon->iSpecificDesktop <= g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY) /*specific desktop is reachable*/
94
_cairo_dock_detach_launcher(Icon * pIcon)95 static void _cairo_dock_detach_launcher (Icon *pIcon)
96 {
97 gchar *cParentDockName = g_strdup (pIcon->cParentDockName);
98 gldi_icon_detach (pIcon); // this will set cParentDockName to NULL
99
100 pIcon->cParentDockName = cParentDockName; // put it back !
101 }
_hide_launcher_on_other_desktops(Icon * icon,int index)102 static void _hide_launcher_on_other_desktops (Icon *icon, int index)
103 {
104 cd_debug ("%s (%s, iNumViewport=%d)", __func__, icon->cName, icon->iSpecificDesktop);
105 if (_is_invisible_on_this_desktop (icon, index))
106 {
107 if (! g_list_find (s_pFloatingIconsList, icon)) // paranoia
108 {
109 cd_debug ("launcher %s is not present on this desktop", icon->cName);
110 _cairo_dock_detach_launcher (icon);
111 s_pFloatingIconsList = g_list_prepend (s_pFloatingIconsList, icon);
112 }
113 }
114 }
_hide_icon_on_other_desktops(Icon * icon,gpointer data)115 static void _hide_icon_on_other_desktops (Icon *icon, gpointer data)
116 {
117 if (GLDI_OBJECT_IS_USER_ICON (icon))
118 {
119 int index = GPOINTER_TO_INT (data);
120 _hide_launcher_on_other_desktops (icon, index);
121 }
122 }
_show_launcher_on_this_desktop(Icon * icon,int index)123 static void _show_launcher_on_this_desktop (Icon *icon, int index)
124 {
125 if (! _is_invisible_on_this_desktop (icon, index))
126 {
127 cd_debug (" => est visible sur ce viewport (iSpecificDesktop = %d).",icon->iSpecificDesktop);
128 s_pFloatingIconsList = g_list_remove (s_pFloatingIconsList, icon);
129
130 CairoDock *pParentDock = gldi_dock_get (icon->cParentDockName);
131 if (pParentDock != NULL)
132 {
133 gldi_icon_insert_in_container (icon, CAIRO_CONTAINER(pParentDock), ! CAIRO_DOCK_ANIMATE_ICON);
134 }
135 else // the dock doesn't exist any more -> free the icon
136 {
137 icon->iSpecificDesktop = 0; // pour ne pas qu'elle soit enlevee de la liste en parallele.
138 gldi_object_delete (GLDI_OBJECT (icon));
139 }
140 }
141 }
142
cairo_dock_hide_show_launchers_on_other_desktops(void)143 void cairo_dock_hide_show_launchers_on_other_desktops (void ) /// TODO: add a mechanism to hide an icon in a dock (or even in a container ?) without detaching it...
144 {
145 if (s_iNbNonStickyLaunchers <= 0)
146 return ;
147
148 // calculate the index of the current desktop
149 int iCurrentDesktop = 0, iCurrentViewportX = 0, iCurrentViewportY = 0;
150 gldi_desktop_get_current (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
151 int index = iCurrentDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportY + 1; // +1 car on commence a compter a partir de 1.
152
153 // first detach what shouldn't be shown on this desktop
154 gldi_icons_foreach_in_docks ((GldiIconFunc)_hide_icon_on_other_desktops, GINT_TO_POINTER (index));
155
156 // then reattach what was eventually missing
157 Icon *icon;
158 GList *ic = s_pFloatingIconsList, *next_ic;
159 while (ic != NULL)
160 {
161 next_ic = ic->next; // get the next element now, because '_show_launcher_on_this_desktop' might remove 'ic' from the list.
162 icon = ic->data;
163 _show_launcher_on_this_desktop (icon, index);
164 ic = next_ic;
165 }
166 }
167
_on_change_current_desktop_viewport_notification(G_GNUC_UNUSED gpointer data)168 static gboolean _on_change_current_desktop_viewport_notification (G_GNUC_UNUSED gpointer data)
169 {
170 cairo_dock_hide_show_launchers_on_other_desktops ();
171 return GLDI_NOTIFICATION_LET_PASS;
172 }
173
_cairo_dock_delete_floating_icons(void)174 static void _cairo_dock_delete_floating_icons (void)
175 {
176 Icon *icon;
177 GList *ic;
178 for (ic = s_pFloatingIconsList; ic != NULL; ic = ic->next)
179 {
180 icon = ic->data;
181 icon->iSpecificDesktop = 0; // pour ne pas qu'elle soit enlevee de la liste en parallele.
182 gldi_object_unref (GLDI_OBJECT (icon));
183 }
184 g_list_free (s_pFloatingIconsList);
185 s_pFloatingIconsList = NULL;
186 s_iNbNonStickyLaunchers = 0;
187 }
188
cairo_dock_set_specified_desktop_for_icon(Icon * pIcon,int iSpecificDesktop)189 void cairo_dock_set_specified_desktop_for_icon (Icon *pIcon, int iSpecificDesktop)
190 {
191 if (iSpecificDesktop != 0 && pIcon->iSpecificDesktop == 0)
192 {
193 s_iNbNonStickyLaunchers ++;
194 }
195 else if (iSpecificDesktop == 0 && pIcon->iSpecificDesktop != 0)
196 {
197 s_iNbNonStickyLaunchers --;
198 }
199 pIcon->iSpecificDesktop = iSpecificDesktop;
200 }
201
202
203 //////////////////
204 /// ICON THEME ///
205 //////////////////
206
207 /*
208 * GTK_ICON_SIZE_MENU: 16
209 * GTK_ICON_SIZE_SMALL_TOOLBAR: 18
210 * GTK_ICON_SIZE_BUTTON: 20
211 * GTK_ICON_SIZE_LARGE_TOOLBAR: 24
212 * GTK_ICON_SIZE_DND: 32
213 * GTK_ICON_SIZE_DIALOG: 48
214 */
cairo_dock_search_icon_size(GtkIconSize iIconSize)215 gint cairo_dock_search_icon_size (GtkIconSize iIconSize)
216 {
217 gint iWidth, iHeight;
218 if (! gtk_icon_size_lookup (iIconSize, &iWidth, &iHeight))
219 return CAIRO_DOCK_DEFAULT_ICON_SIZE;
220
221 return MAX (iWidth, iHeight);
222 }
223
cairo_dock_search_icon_s_path(const gchar * cFileName,gint iDesiredIconSize)224 gchar *cairo_dock_search_icon_s_path (const gchar *cFileName, gint iDesiredIconSize)
225 {
226 g_return_val_if_fail (cFileName != NULL, NULL);
227
228 //\_______________________ easy cases: we receive a path.
229 if (*cFileName == '~')
230 {
231 return g_strdup_printf ("%s%s", g_getenv ("HOME"), cFileName+1);
232 }
233
234 if (*cFileName == '/')
235 {
236 return g_strdup (cFileName);
237 }
238
239 //\_______________________ check for the presence of suffix and version number.
240 g_return_val_if_fail (s_pIconTheme != NULL, NULL);
241
242 GString *sIconPath = g_string_new ("");
243 const gchar *cSuffixTab[4] = {".svg", ".png", ".xpm", NULL};
244 gboolean bHasSuffix=FALSE, bFileFound=FALSE, bHasVersion=FALSE;
245 GtkIconInfo* pIconInfo = NULL;
246 gchar *str = strrchr (cFileName, '.');
247 bHasSuffix = (str != NULL && g_ascii_isalpha (*(str+1))); // exemple : "firefox.svg", but not "firefox-3.0"
248 bHasVersion = (str != NULL && g_ascii_isdigit (*(str+1)) && g_ascii_isdigit (*(str-1)) && str-1 != cFileName); // doit finir par x.y, x et y ayant autant de chiffres que l'on veut.
249
250 //\_______________________ search in the local icons folder if enabled.
251 if (s_bUseLocalIcons)
252 {
253 if (! bHasSuffix) // test all the suffix one by one.
254 {
255 int j = 0;
256 while (cSuffixTab[j] != NULL)
257 {
258 g_string_printf (sIconPath, "%s/%s%s", g_cCurrentIconsPath, cFileName, cSuffixTab[j]);
259 if ( g_file_test (sIconPath->str, G_FILE_TEST_EXISTS) )
260 {
261 bFileFound = TRUE;
262 break;
263 }
264 j ++;
265 }
266 }
267 else // just test the file.
268 {
269 g_string_printf (sIconPath, "%s/%s", g_cCurrentIconsPath, cFileName);
270 bFileFound = g_file_test (sIconPath->str, G_FILE_TEST_EXISTS);
271 }
272 }
273
274 //\_______________________ search in the icon theme
275 if (! bFileFound) // didn't found/search in the local icons, so try the icon theme.
276 {
277 g_string_assign (sIconPath, cFileName);
278 if (bHasSuffix) // on vire le suffixe pour chercher tous les formats dans le theme d'icones.
279 {
280 gchar *str = strrchr (sIconPath->str, '.');
281 if (str != NULL)
282 *str = '\0';
283 }
284
285 pIconInfo = gtk_icon_theme_lookup_icon (s_pIconTheme,
286 sIconPath->str,
287 iDesiredIconSize, // GTK_ICON_LOOKUP_FORCE_SIZE if size < 30 ?? -> icons can be different // a lot of themes now use only svg files.
288 GTK_ICON_LOOKUP_FORCE_SVG);
289 if (pIconInfo == NULL && ! s_bUseLocalIcons && ! bHasVersion) // if we were not using the default theme and didn't find any icon, let's try with the default theme (for instance gvfs will give us names from the default theme, and they might not exist in our current theme); if it has a version, we'll retry without it.
290 {
291 pIconInfo = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), // the default theme is mapped in shared memory so it's available at any time.
292 sIconPath->str,
293 iDesiredIconSize,
294 GTK_ICON_LOOKUP_FORCE_SVG);
295 }
296 if (pIconInfo != NULL)
297 {
298 g_string_assign (sIconPath, gtk_icon_info_get_filename (pIconInfo));
299 bFileFound = TRUE;
300 #if GTK_CHECK_VERSION (3, 8, 0)
301 g_object_unref (G_OBJECT (pIconInfo));
302 #else
303 gtk_icon_info_free (pIconInfo);
304 #endif
305 }
306 }
307
308
309 //\_______________________ si rien trouve, on cherche sans le numero de version.
310 if (! bFileFound && bHasVersion)
311 {
312 cd_debug ("on cherche sans le numero de version...");
313 g_string_assign (sIconPath, cFileName);
314 gchar *str = strrchr (sIconPath->str, '.');
315 str --; // on sait que c'est un digit.
316 str --;
317 while ((g_ascii_isdigit (*str) || *str == '.' || *str == '-') && (str != sIconPath->str))
318 str --;
319 if (str != sIconPath->str)
320 {
321 *(str+1) = '\0';
322 cd_debug (" on cherche '%s'...", sIconPath->str);
323 gchar *cPath = cairo_dock_search_icon_s_path (sIconPath->str, iDesiredIconSize);
324 if (cPath != NULL)
325 {
326 bFileFound = TRUE;
327 g_string_assign (sIconPath, cPath);
328 g_free (cPath);
329 }
330 }
331 }
332
333 if (! bFileFound)
334 {
335 g_string_free (sIconPath, TRUE);
336 return NULL;
337 }
338
339 gchar *cIconPath = sIconPath->str;
340 g_string_free (sIconPath, FALSE);
341 return cIconPath;
342 }
343
cairo_dock_add_path_to_icon_theme(const gchar * cThemePath)344 void cairo_dock_add_path_to_icon_theme (const gchar *cThemePath)
345 {
346 if (s_bUseDefaultTheme)
347 {
348 g_signal_handlers_block_matched (s_pIconTheme,
349 (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
350 0, 0, NULL, _on_icon_theme_changed, NULL);
351 }
352 gtk_icon_theme_append_search_path (s_pIconTheme,
353 cThemePath); /// TODO: does it check for unicity ?...
354 gtk_icon_theme_rescan_if_needed (s_pIconTheme);
355 if (s_bUseDefaultTheme)
356 {
357 g_signal_handlers_unblock_matched (s_pIconTheme,
358 (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
359 0, 0, NULL, _on_icon_theme_changed, NULL); // will do nothing if the callback has not been connected
360 }
361 }
362
cairo_dock_remove_path_from_icon_theme(const gchar * cThemePath)363 void cairo_dock_remove_path_from_icon_theme (const gchar *cThemePath)
364 {
365 if (! GTK_IS_ICON_THEME (s_pIconTheme))
366 return;
367 g_signal_handlers_block_matched (s_pIconTheme,
368 (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
369 0, 0, NULL, _on_icon_theme_changed, NULL);
370
371 gchar **paths = NULL;
372 gint iNbPaths = 0;
373 gtk_icon_theme_get_search_path (s_pIconTheme, &paths, &iNbPaths);
374 int i;
375 for (i = 0; i < iNbPaths; i++) // on cherche sa position dans le tableau.
376 {
377 if (strcmp (paths[i], cThemePath))
378 break;
379 }
380 if (i < iNbPaths) // trouve
381 {
382 g_free (paths[i]);
383 for (i = i+1; i < iNbPaths; i++) // on decale tous les suivants vers l'arriere.
384 {
385 paths[i-1] = paths[i];
386 }
387 paths[i-1] = NULL;
388 gtk_icon_theme_set_search_path (s_pIconTheme, (const gchar **)paths, iNbPaths - 1);
389 }
390 g_strfreev (paths);
391
392 g_signal_handlers_unblock_matched (s_pIconTheme,
393 (GSignalMatchType) G_SIGNAL_MATCH_FUNC,
394 0, 0, NULL, _on_icon_theme_changed, NULL); // will do nothing if the callback has not been connected
395 }
396
397
398 //////////////////
399 /// GET CONFIG ///
400 //////////////////
401
get_config(GKeyFile * pKeyFile,CairoIconsParam * pIcons)402 static gboolean get_config (GKeyFile *pKeyFile, CairoIconsParam *pIcons)
403 {
404 gboolean bFlushConfFileNeeded = FALSE;
405
406 //\___________________ Reflets.
407 pIcons->fReflectHeightRatio = cairo_dock_get_double_key_value (pKeyFile, "Icons", "field depth", &bFlushConfFileNeeded, 0.7, NULL, NULL);
408
409 pIcons->fAlbedo = cairo_dock_get_double_key_value (pKeyFile, "Icons", "albedo", &bFlushConfFileNeeded, .6, NULL, NULL);
410
411 #ifndef AVOID_PATENT_CRAP
412 double fMaxScale = cairo_dock_get_double_key_value (pKeyFile, "Icons", "zoom max", &bFlushConfFileNeeded, 0., NULL, NULL);
413 if (fMaxScale == 0)
414 {
415 pIcons->fAmplitude = g_key_file_get_double (pKeyFile, "Icons", "amplitude", NULL);
416 fMaxScale = 1 + pIcons->fAmplitude;
417 g_key_file_set_double (pKeyFile, "Icons", "zoom max", fMaxScale);
418 }
419 else
420 pIcons->fAmplitude = fMaxScale - 1;
421 #else
422 pIcons->fAmplitude = 0.;
423 #endif
424
425 pIcons->iSinusoidWidth = cairo_dock_get_integer_key_value (pKeyFile, "Icons", "sinusoid width", &bFlushConfFileNeeded, 250, NULL, NULL);
426 pIcons->iSinusoidWidth = MAX (1, pIcons->iSinusoidWidth);
427
428 pIcons->iIconGap = cairo_dock_get_integer_key_value (pKeyFile, "Icons", "icon gap", &bFlushConfFileNeeded, 0, NULL, NULL);
429
430 //\___________________ Ficelle.
431 pIcons->iStringLineWidth = cairo_dock_get_integer_key_value (pKeyFile, "Icons", "string width", &bFlushConfFileNeeded, 0, NULL, NULL);
432
433 gdouble couleur[4];
434 cairo_dock_get_double_list_key_value (pKeyFile, "Icons", "string color", &bFlushConfFileNeeded, pIcons->fStringColor, 4, couleur, NULL, NULL);
435
436 pIcons->fAlphaAtRest = cairo_dock_get_double_key_value (pKeyFile, "Icons", "alpha at rest", &bFlushConfFileNeeded, 1., NULL, NULL);
437
438 //\___________________ Theme d'icone.
439 pIcons->cIconTheme = cairo_dock_get_string_key_value (pKeyFile, "Icons", "default icon directory", &bFlushConfFileNeeded, NULL, "Launchers", NULL);
440 if (g_key_file_has_key (pKeyFile, "Icons", "local icons", NULL)) // anciens parametres.
441 {
442 bFlushConfFileNeeded = TRUE;
443 gboolean bUseLocalIcons = g_key_file_get_boolean (pKeyFile, "Icons", "local icons", NULL);
444 if (bUseLocalIcons)
445 {
446 g_free (pIcons->cIconTheme);
447 pIcons->cIconTheme = g_strdup ("_Custom Icons_");
448 g_key_file_set_string (pKeyFile, "Icons", "default icon directory", pIcons->cIconTheme);
449 }
450 }
451
452 gchar *cLauncherBackgroundImageName = cairo_dock_get_string_key_value (pKeyFile, "Icons", "icons bg", &bFlushConfFileNeeded, NULL, NULL, NULL);
453 if (cLauncherBackgroundImageName != NULL)
454 {
455 pIcons->cBackgroundImagePath = cairo_dock_search_image_s_path (cLauncherBackgroundImageName);
456 g_free (cLauncherBackgroundImageName);
457 }
458
459 //\___________________ icons size
460 cairo_dock_get_size_key_value_helper (pKeyFile, "Icons", "launcher ", bFlushConfFileNeeded, pIcons->iIconWidth, pIcons->iIconHeight);
461 if (pIcons->iIconWidth == 0)
462 pIcons->iIconWidth = 48;
463 if (pIcons->iIconHeight == 0)
464 pIcons->iIconHeight = 48;
465
466 //\___________________ Parametres des separateurs.
467 cairo_dock_get_size_key_value_helper (pKeyFile, "Icons", "separator ", bFlushConfFileNeeded, pIcons->iSeparatorWidth, pIcons->iSeparatorHeight);
468 if (pIcons->iSeparatorWidth == 0)
469 pIcons->iSeparatorWidth = pIcons->iIconWidth;
470 if (pIcons->iSeparatorHeight == 0)
471 pIcons->iSeparatorHeight = pIcons->iIconHeight;
472 if (pIcons->iSeparatorHeight > pIcons->iIconHeight)
473 pIcons->iSeparatorHeight = pIcons->iIconHeight;
474
475 pIcons->iSeparatorType = cairo_dock_get_integer_key_value (pKeyFile, "Icons", "separator type", &bFlushConfFileNeeded, -1, NULL, NULL);
476 if (pIcons->iSeparatorType >= CAIRO_DOCK_NB_SEPARATOR_TYPES) // nouveau parametre, avant il etait dans dock-rendering.
477 {
478 pIcons->iSeparatorType = CAIRO_DOCK_NORMAL_SEPARATOR; // ce qui suit est tres moche, mais c'est pour eviter d'avoir a repasser derriere tous les themes.
479 gchar *cMainDockDefaultRendererName = g_key_file_get_string (pKeyFile, "Views", "main dock view", NULL);
480 if (cMainDockDefaultRendererName && (strcmp (cMainDockDefaultRendererName, "3D plane") == 0 || strcmp (cMainDockDefaultRendererName, "Curve") == 0))
481 {
482 gchar *cRenderingConfFile = g_strdup_printf ("%s/plug-ins/rendering/rendering.conf", g_cCurrentThemePath);
483 GKeyFile *keyfile = cairo_dock_open_key_file (cRenderingConfFile);
484 g_free (cRenderingConfFile);
485 if (keyfile == NULL)
486 pIcons->iSeparatorType = CAIRO_DOCK_NORMAL_SEPARATOR;
487 else
488 {
489 if (strcmp (cMainDockDefaultRendererName, "3D plane") == 0)
490 {
491 pIcons->iSeparatorType = g_key_file_get_integer (keyfile, "Inclinated Plane", "draw separator", NULL);
492 }
493 else
494 {
495 pIcons->iSeparatorType = g_key_file_get_integer (keyfile, "Curve", "draw curve separator", NULL);
496 }
497 cairo_dock_get_color_key_value (keyfile, "Inclinated Plane", "separator color", &bFlushConfFileNeeded, &pIcons->fSeparatorColor, NULL, NULL, NULL);
498 g_key_file_free (keyfile);
499 }
500 }
501 g_key_file_set_integer (pKeyFile, "Icons", "separator type", pIcons->iSeparatorType);
502 g_key_file_set_double_list (pKeyFile, "Icons", "separator color", (double*)&pIcons->fSeparatorColor.rgba, 4);
503 g_free (cMainDockDefaultRendererName);
504 }
505 else
506 {
507 GldiColor couleur = {{0.9,0.9,1.0,1.0}};
508 cairo_dock_get_color_key_value (pKeyFile, "Icons", "separator color", &bFlushConfFileNeeded, &pIcons->fSeparatorColor, &couleur, NULL, NULL);
509 }
510
511 pIcons->bSeparatorUseDefaultColors = (cairo_dock_get_integer_key_value (pKeyFile, "Icons", "separator_style", &bFlushConfFileNeeded, 1, NULL, NULL) == 0);
512
513 if (pIcons->iSeparatorType == CAIRO_DOCK_NORMAL_SEPARATOR)
514 pIcons->cSeparatorImage = cairo_dock_get_string_key_value (pKeyFile, "Icons", "separator image", &bFlushConfFileNeeded, NULL, "Separators", NULL);
515
516 pIcons->bRevolveSeparator = cairo_dock_get_boolean_key_value (pKeyFile, "Icons", "revolve separator image", &bFlushConfFileNeeded, TRUE, "Separators", NULL);
517
518 pIcons->bConstantSeparatorSize = cairo_dock_get_boolean_key_value (pKeyFile, "Icons", "force size", &bFlushConfFileNeeded, TRUE, "Separators", NULL);
519
520 //\___________________ labels font
521 CairoIconsParam *pLabels = pIcons;
522 gboolean bCustomFont = cairo_dock_get_boolean_key_value (pKeyFile, "Labels", "custom", &bFlushConfFileNeeded, TRUE, NULL, NULL);
523
524 gchar *cFont = (bCustomFont ? cairo_dock_get_string_key_value (pKeyFile, "Labels", "police", &bFlushConfFileNeeded, NULL, "Icons", NULL) : NULL);
525 gldi_text_description_set_font (&pLabels->iconTextDescription, cFont);
526
527 cd_debug ("label font: %s, %d\n", pLabels->iconTextDescription.cFont, pLabels->iconTextDescription.iSize);
528
529 //\___________________ labels text color
530 pLabels->iconTextDescription.bOutlined = cairo_dock_get_boolean_key_value (pKeyFile, "Labels", "text oulined", &bFlushConfFileNeeded, TRUE, NULL, NULL);
531
532 GldiColor couleur_backlabel = {{0., 0., 0., 0.85}};
533 GldiColor couleur_label = {{1., 1., 1., 1.}};
534 gboolean bDefaultColors = (cairo_dock_get_integer_key_value (pKeyFile, "Labels", "style", &bFlushConfFileNeeded, 0, NULL, NULL) == 0);
535 pLabels->iconTextDescription.bUseDefaultColors = bDefaultColors;
536 if (bDefaultColors)
537 {
538 pLabels->iconTextDescription.bOutlined = FALSE;
539 }
540 else
541 {
542 cairo_dock_get_color_key_value (pKeyFile, "Labels", "text color", &bFlushConfFileNeeded, &pLabels->iconTextDescription.fColorStart, &couleur_label, "Labels", "text color start");
543
544 GldiColor couleur_linelabel = {{0., 0., 0., 1}};
545 cairo_dock_get_color_key_value (pKeyFile, "Labels", "text line color", &bFlushConfFileNeeded, &pLabels->iconTextDescription.fLineColor, &couleur_linelabel, NULL, NULL);
546
547 cairo_dock_get_color_key_value (pKeyFile, "Labels", "text bg color", &bFlushConfFileNeeded, &pLabels->iconTextDescription.fBackgroundColor, &couleur_backlabel, "Icons", "text background color");
548 if (!g_key_file_has_key (pKeyFile, "Labels", "qi same", NULL)) // old params
549 {
550 gboolean bUseBackgroundForLabel = cairo_dock_get_boolean_key_value (pKeyFile, "Labels", "background for label", &bFlushConfFileNeeded, FALSE, "Icons", NULL);
551 if (! bUseBackgroundForLabel)
552 {
553 pLabels->iconTextDescription.fBackgroundColor.rgba.alpha = 0; // ne sera pas dessine.
554 g_key_file_set_double_list (pKeyFile, "Icons", "text background color", (double*)&pLabels->iconTextDescription.fBackgroundColor.rgba, 4);
555 }
556 }
557 }
558
559 pLabels->iconTextDescription.iMargin = cairo_dock_get_integer_key_value (pKeyFile, "Labels", "text margin", &bFlushConfFileNeeded, 4, NULL, NULL);
560
561 //\___________________ quick-info
562 gldi_text_description_copy (&pLabels->quickInfoTextDescription, &pLabels->iconTextDescription);
563 pLabels->quickInfoTextDescription.iMargin = 1; // to minimize the surface of the quick-info (0 would be too much).
564 pLabels->quickInfoTextDescription.iSize = 12; // no need to update the fd, it will be done when loading the text buffer
565
566 gboolean bQuickInfoSameLook = cairo_dock_get_boolean_key_value (pKeyFile, "Labels", "qi same", &bFlushConfFileNeeded, TRUE, NULL, NULL);
567 if ( !bQuickInfoSameLook)
568 {
569 cairo_dock_get_color_key_value (pKeyFile, "Labels", "qi bg color", &bFlushConfFileNeeded, &pLabels->quickInfoTextDescription.fBackgroundColor, &couleur_backlabel, NULL, NULL);
570 cairo_dock_get_color_key_value (pKeyFile, "Labels", "qi text color", &bFlushConfFileNeeded, &pLabels->quickInfoTextDescription.fColorStart, &couleur_label, NULL, NULL);
571 pLabels->quickInfoTextDescription.bUseDefaultColors = FALSE;
572 }
573
574 pLabels->iLabelSize = (pLabels->iconTextDescription.iSize != 0 ?
575 pLabels->iconTextDescription.iSize +
576 (pLabels->iconTextDescription.bOutlined ? 2 : 0) +
577 2 * pLabels->iconTextDescription.iMargin +
578 6 // 2px linewidth + 3px to take into account the y offset of the characters + 1 px to take into account the gap between icon and label
579 : 0);
580 cd_debug ("iLabelSize: %d (%d)\n", pLabels->iLabelSize, pLabels->iconTextDescription.iSize);
581
582 //\___________________ labels visibility
583 int iShowLabel = cairo_dock_get_integer_key_value (pKeyFile, "Labels", "show_labels", &bFlushConfFileNeeded, -1, NULL, NULL);
584 gboolean bShow, bLabelForPointedIconOnly;
585 if (iShowLabel == -1) // nouveau parametre
586 {
587 if (g_key_file_has_key (pKeyFile, "Labels", "show labels", NULL))
588 bShow = g_key_file_get_boolean (pKeyFile, "Labels", "show labels", NULL);
589 else
590 bShow = TRUE;
591 bLabelForPointedIconOnly = g_key_file_get_boolean (pKeyFile, "System", "pointed icon only", NULL);
592 iShowLabel = (! bShow ? 0 : (bLabelForPointedIconOnly ? 1 : 2));
593 g_key_file_set_integer (pKeyFile, "Labels", "show_labels", iShowLabel);
594 }
595 else
596 {
597 bShow = (iShowLabel != 0);
598 bLabelForPointedIconOnly = (iShowLabel == 1);
599 }
600 if (! bShow)
601 pLabels->iconTextDescription.iSize = 0;
602
603 pLabels->bLabelForPointedIconOnly = bLabelForPointedIconOnly;
604
605 pLabels->fLabelAlphaThreshold = cairo_dock_get_double_key_value (pKeyFile, "Labels", "alpha threshold", &bFlushConfFileNeeded, 10., "System", NULL);
606 pLabels->fLabelAlphaThreshold = (pLabels->fLabelAlphaThreshold + 10.) / 10.; // [0;50] -> [1;6]
607
608 return bFlushConfFileNeeded;
609 }
610
611
612 ////////////////////
613 /// RESET CONFIG ///
614 ////////////////////
615
reset_config(CairoIconsParam * pIcons)616 static void reset_config (CairoIconsParam *pIcons)
617 {
618 g_free (pIcons->cSeparatorImage);
619 g_free (pIcons->cBackgroundImagePath);
620 g_free (pIcons->cIconTheme);
621
622 // labels
623 CairoIconsParam *pLabels = pIcons;
624 gldi_text_description_reset (&pLabels->iconTextDescription);
625 gldi_text_description_reset (&pLabels->quickInfoTextDescription);
626 }
627
628
629 ////////////
630 /// LOAD ///
631 ////////////
632
_cairo_dock_load_icons_background_surface(const gchar * cImagePath)633 static void _cairo_dock_load_icons_background_surface (const gchar *cImagePath)
634 {
635 cairo_dock_unload_image_buffer (&g_pIconBackgroundBuffer);
636
637 int iSizeWidth = myIconsParam.iIconWidth * (1 + myIconsParam.fAmplitude);
638 int iSizeHeight = myIconsParam.iIconHeight * (1 + myIconsParam.fAmplitude);
639
640 cairo_dock_load_image_buffer (&g_pIconBackgroundBuffer,
641 cImagePath,
642 iSizeWidth,
643 iSizeHeight,
644 CAIRO_DOCK_FILL_SPACE);
645 }
646
_load_renderer(G_GNUC_UNUSED const gchar * cRenderername,CairoIconContainerRenderer * pRenderer,G_GNUC_UNUSED gpointer data)647 static void _load_renderer (G_GNUC_UNUSED const gchar *cRenderername, CairoIconContainerRenderer *pRenderer, G_GNUC_UNUSED gpointer data)
648 {
649 if (pRenderer && pRenderer->load)
650 pRenderer->load ();
651 }
_cairo_dock_load_icon_textures(void)652 static void _cairo_dock_load_icon_textures (void)
653 {
654 _cairo_dock_load_icons_background_surface (myIconsParam.cBackgroundImagePath);
655
656 cairo_dock_foreach_icon_container_renderer ((GHFunc)_load_renderer, NULL);
657 }
_reload_in_desklet(CairoDesklet * pDesklet,G_GNUC_UNUSED gpointer data)658 static void _reload_in_desklet (CairoDesklet *pDesklet, G_GNUC_UNUSED gpointer data)
659 {
660 if (CAIRO_DOCK_IS_APPLET (pDesklet->pIcon))
661 {
662 gldi_object_reload (GLDI_OBJECT(pDesklet->pIcon->pModuleInstance), FALSE);
663 }
664 }
_on_icon_theme_changed_idle(G_GNUC_UNUSED gpointer data)665 static gboolean _on_icon_theme_changed_idle (G_GNUC_UNUSED gpointer data)
666 {
667 cd_debug ("");
668 gldi_desklets_foreach ((GldiDeskletForeachFunc) _reload_in_desklet, NULL);
669 cairo_dock_reload_buffers_in_all_docks (FALSE);
670 s_iSidReloadTheme = 0;
671 return FALSE;
672 }
_on_icon_theme_changed(G_GNUC_UNUSED GtkIconTheme * pIconTheme,G_GNUC_UNUSED gpointer data)673 static void _on_icon_theme_changed (G_GNUC_UNUSED GtkIconTheme *pIconTheme, G_GNUC_UNUSED gpointer data)
674 {
675 cd_message ("theme has changed");
676 // Reload the icons in idle, because this signal is triggered directly by 'gtk_icon_theme_set_search_path()'; so we may end reloading an applet in the middle of its work (ex.: Status-Notifier when the watcher terminates)
677 if (s_iSidReloadTheme == 0)
678 s_iSidReloadTheme = g_idle_add (_on_icon_theme_changed_idle, NULL);
679 }
_cairo_dock_load_icon_theme(void)680 static void _cairo_dock_load_icon_theme (void)
681 {
682 g_return_if_fail (s_pIconTheme == NULL);
683 if (myIconsParam.cIconTheme == NULL // no icon theme defined => use the default one.
684 || strcmp (myIconsParam.cIconTheme, "_Custom Icons_") == 0) // use custom icons and default theme as fallback
685 {
686 s_pIconTheme = gtk_icon_theme_get_default ();
687 g_signal_connect (G_OBJECT (s_pIconTheme), "changed", G_CALLBACK (_on_icon_theme_changed), NULL);
688 s_bUseDefaultTheme = TRUE;
689 s_bUseLocalIcons = (myIconsParam.cIconTheme != NULL);
690 }
691 else // use the given icon theme
692 {
693 s_pIconTheme = gtk_icon_theme_new ();
694 gtk_icon_theme_set_custom_theme (s_pIconTheme, myIconsParam.cIconTheme);
695 s_bUseLocalIcons = FALSE;
696 s_bUseDefaultTheme = FALSE;
697 }
698 }
699
load(void)700 static void load (void)
701 {
702 cairo_dock_create_icon_fbo ();
703
704 _cairo_dock_load_icon_theme ();
705
706 _cairo_dock_load_icon_textures ();
707 }
708
709
710 //////////////
711 /// RELOAD ///
712 //////////////
713
_reload_separators(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,gpointer data)714 static void _reload_separators (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, gpointer data)
715 {
716 ///cairo_dock_remove_automatic_separators (pDock);
717 gboolean bSeparatorsNeedReload = GPOINTER_TO_INT(data);
718 gboolean bHasSeparator = FALSE;
719 Icon *icon;
720 GList *ic;
721 for (ic = pDock->icons; ic != NULL; ic = ic->next)
722 {
723 icon = ic->data;
724 if (GLDI_OBJECT_IS_SEPARATOR_ICON (icon))
725 {
726 if (bSeparatorsNeedReload)
727 {
728 cairo_dock_icon_set_requested_size (icon, 0, 0);
729 cairo_dock_set_icon_size_in_dock (pDock, icon);
730 }
731 cairo_dock_load_icon_image (icon, icon->pContainer);
732 bHasSeparator = TRUE;
733 }
734 }
735 if (bHasSeparator)
736 {
737 if (bSeparatorsNeedReload)
738 cairo_dock_update_dock_size (pDock); // either to trigger the loading of the separator rendering, or to take into account the change in the separators size
739 gtk_widget_queue_draw (pDock->container.pWidget); // in any case, refresh the drawing
740 }
741 }
742
_calculate_icons(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,G_GNUC_UNUSED gpointer data)743 static void _calculate_icons (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, G_GNUC_UNUSED gpointer data)
744 {
745 cairo_dock_calculate_dock_icons (pDock);
746 }
747
_cairo_dock_resize_one_dock(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,G_GNUC_UNUSED gpointer data)748 static void _cairo_dock_resize_one_dock (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, G_GNUC_UNUSED gpointer data)
749 {
750 cairo_dock_update_dock_size (pDock);
751 }
752
_reload_one_label(Icon * pIcon,G_GNUC_UNUSED gpointer data)753 static void _reload_one_label (Icon *pIcon, G_GNUC_UNUSED gpointer data)
754 {
755 cairo_dock_load_icon_text (pIcon);
756 cairo_dock_load_icon_quickinfo (pIcon);
757 }
758
reload(CairoIconsParam * pPrevIcons,CairoIconsParam * pIcons)759 static void reload (CairoIconsParam *pPrevIcons, CairoIconsParam *pIcons)
760 {
761 // if the separator size has changed, we need to re-allocate it, reload the image, and update the dock size
762 // if the separator rendering has changed (type or color), we need to load the new rendering, which is done by the View (during the compute_size)
763 // otherwise, we just need to redraw
764 gboolean bSeparatorsNeedReload = (pPrevIcons->iSeparatorWidth != pIcons->iSeparatorWidth
765 || pPrevIcons->iSeparatorHeight != pIcons->iSeparatorHeight
766 || pPrevIcons->iSeparatorType != pIcons->iSeparatorType
767 || gldi_color_compare (&pPrevIcons->fSeparatorColor, &pIcons->fSeparatorColor)); // same if color has changed (for the flat separator rendering)
768 gboolean bSeparatorNeedRedraw = (g_strcmp0 (pPrevIcons->cSeparatorImage, pIcons->cSeparatorImage) != 0
769 || pPrevIcons->bRevolveSeparator != pIcons->bRevolveSeparator);
770
771 if (bSeparatorsNeedReload || bSeparatorNeedRedraw)
772 {
773 gldi_docks_foreach ((GHFunc)_reload_separators, GINT_TO_POINTER(bSeparatorsNeedReload));
774 }
775
776 gboolean bThemeChanged = (g_strcmp0 (pIcons->cIconTheme, pPrevIcons->cIconTheme) != 0);
777 if (bThemeChanged)
778 {
779 _cairo_dock_unload_icon_theme ();
780
781 _cairo_dock_load_icon_theme ();
782 }
783
784 gboolean bIconBackgroundImagesChanged = FALSE;
785 // if background images are different, reload them and trigger the reload of all icons
786 if (g_strcmp0 (pPrevIcons->cBackgroundImagePath, pIcons->cBackgroundImagePath) != 0
787 || pPrevIcons->fAmplitude != pIcons->fAmplitude)
788 {
789 bIconBackgroundImagesChanged = TRUE;
790 _cairo_dock_load_icons_background_surface (pIcons->cBackgroundImagePath);
791 }
792
793 ///cairo_dock_create_icon_pbuffer ();
794 cairo_dock_destroy_icon_fbo ();
795 cairo_dock_create_icon_fbo ();
796
797 if (pPrevIcons->iIconWidth != pIcons->iIconWidth ||
798 pPrevIcons->iIconHeight != pIcons->iIconHeight ||
799 pPrevIcons->iSeparatorWidth != pIcons->iSeparatorWidth ||
800 pPrevIcons->iSeparatorHeight != pIcons->iSeparatorHeight ||
801 pPrevIcons->fAmplitude != pIcons->fAmplitude ||
802 (!g_bUseOpenGL && pPrevIcons->fReflectHeightRatio != pIcons->fReflectHeightRatio) ||
803 (!g_bUseOpenGL && pPrevIcons->fAlbedo != pIcons->fAlbedo) ||
804 bThemeChanged ||
805 bIconBackgroundImagesChanged) // oui on ne fait pas dans la finesse.
806 {
807 cairo_dock_reload_buffers_in_all_docks (TRUE);
808 }
809
810 if (pPrevIcons->iIconWidth != pIcons->iIconWidth ||
811 pPrevIcons->iIconHeight != pIcons->iIconHeight ||
812 pPrevIcons->fAmplitude != pIcons->fAmplitude)
813 {
814 _cairo_dock_unload_icon_textures ();
815 myIndicatorsMgr.unload ();
816 _cairo_dock_load_icon_textures ();
817 myIndicatorsMgr.load ();
818 }
819
820 cairo_dock_set_all_views_to_default (0); // met a jour la taille (decorations incluses) de tous les docks; le chargement des separateurs plats se fait dans le calcul de max dock size.
821 gldi_docks_foreach ((GHFunc)_calculate_icons, NULL);
822 gldi_docks_redraw_all_root ();
823
824 // labels
825 CairoIconsParam *pLabels = pIcons;
826 CairoIconsParam *pPrevLabels = pPrevIcons;
827 gldi_icons_foreach ((GldiIconFunc) _reload_one_label, NULL);
828
829 if (pPrevLabels->iLabelSize != pLabels->iLabelSize)
830 {
831 gldi_docks_foreach ((GHFunc) _cairo_dock_resize_one_dock, NULL);
832 }
833 }
834
835
836 //////////////
837 /// UNLOAD ///
838 //////////////
839
_unload_renderer(G_GNUC_UNUSED const gchar * cRenderername,CairoIconContainerRenderer * pRenderer,G_GNUC_UNUSED gpointer data)840 static void _unload_renderer (G_GNUC_UNUSED const gchar *cRenderername, CairoIconContainerRenderer *pRenderer, G_GNUC_UNUSED gpointer data)
841 {
842 if (pRenderer && pRenderer->unload)
843 pRenderer->unload ();
844 }
_cairo_dock_unload_icon_textures(void)845 static void _cairo_dock_unload_icon_textures (void)
846 {
847 cairo_dock_unload_image_buffer (&g_pIconBackgroundBuffer);
848
849 cairo_dock_foreach_icon_container_renderer ((GHFunc)_unload_renderer, NULL);
850 }
_cairo_dock_unload_icon_theme(void)851 static void _cairo_dock_unload_icon_theme (void)
852 {
853 if (s_bUseDefaultTheme)
854 g_signal_handlers_disconnect_by_func (G_OBJECT(s_pIconTheme), G_CALLBACK(_on_icon_theme_changed), NULL);
855 else
856 g_object_unref (s_pIconTheme);
857 s_pIconTheme = NULL;
858 }
unload(void)859 static void unload (void)
860 {
861 _cairo_dock_unload_icon_textures ();
862
863 cairo_dock_destroy_icon_fbo ();
864
865 _cairo_dock_delete_floating_icons ();
866
867 if (g_pGradationTexture[0] != 0)
868 {
869 _cairo_dock_delete_texture (g_pGradationTexture[0]);
870 g_pGradationTexture[0] = 0;
871 }
872 if (g_pGradationTexture[1] != 0)
873 {
874 _cairo_dock_delete_texture (g_pGradationTexture[1]);
875 g_pGradationTexture[1] = 0;
876 }
877
878 _cairo_dock_unload_icon_theme ();
879 }
880
881
882 ////////////
883 /// INIT ///
884 ////////////
885
on_style_changed(G_GNUC_UNUSED gpointer data)886 static gboolean on_style_changed (G_GNUC_UNUSED gpointer data)
887 {
888 cd_debug ("Icons: style changed to %d", myIconsParam.iconTextDescription.bUseDefaultColors);
889
890 if (myIconsParam.iconTextDescription.cFont == NULL) // default font -> reload our text description
891 {
892 gldi_text_description_set_font (&myIconsParam.iconTextDescription, NULL);
893 myIconsParam.quickInfoTextDescription.fd = pango_font_description_copy (myIconsParam.iconTextDescription.fd);
894 }
895
896 if (myIconsParam.iconTextDescription.bUseDefaultColors || myIconsParam.iconTextDescription.cFont == NULL) // reload labels and quick-info
897 {
898 cd_debug ("reload labels...");
899 gldi_icons_foreach ((GldiIconFunc) _reload_one_label, NULL);
900 }
901
902 // if label size changed, reload docks views
903 int iLabelSize = (myIconsParam.iconTextDescription.iSize != 0 ?
904 myIconsParam.iconTextDescription.iSize +
905 (myIconsParam.iconTextDescription.bOutlined ? 2 : 0) +
906 2 * myIconsParam.iconTextDescription.iMargin +
907 6 // 2px linewidth + 3px to take into account the y offset of the characters + 1 px to take into account the gap between icon and label
908 : 0);
909 if (iLabelSize != myIconsParam.iLabelSize)
910 {
911 cd_debug ("myIconsParam.iLabelSize: %d -> %d (%d)", myIconsParam.iLabelSize, iLabelSize, myIconsParam.iconTextDescription.iSize);
912 myIconsParam.iLabelSize = iLabelSize;
913 gldi_docks_foreach ((GHFunc) _cairo_dock_resize_one_dock, NULL);
914 }
915 return GLDI_NOTIFICATION_LET_PASS;
916 }
917
init(void)918 static void init (void)
919 {
920 gldi_object_register_notification (&myDesktopMgr,
921 NOTIFICATION_DESKTOP_CHANGED,
922 (GldiNotificationFunc) _on_change_current_desktop_viewport_notification,
923 GLDI_RUN_AFTER, NULL);
924 gldi_object_register_notification (&myIconObjectMgr,
925 NOTIFICATION_RENDER_ICON,
926 (GldiNotificationFunc) cairo_dock_render_icon_notification,
927 GLDI_RUN_FIRST, NULL);
928 gldi_object_register_notification (&myStyleMgr,
929 NOTIFICATION_STYLE_CHANGED,
930 (GldiNotificationFunc) on_style_changed,
931 GLDI_RUN_AFTER, NULL);
932 }
933
934 ///////////////
935 /// MANAGER ///
936 ///////////////
937
_load_image(Icon * icon)938 static void _load_image (Icon *icon)
939 {
940 int iWidth = cairo_dock_icon_get_allocated_width (icon);
941 int iHeight = cairo_dock_icon_get_allocated_height (icon);
942 cairo_surface_t *pSurface = NULL;
943
944 if (icon->cFileName)
945 {
946 gchar *cIconPath = cairo_dock_search_icon_s_path (icon->cFileName, MAX (iWidth, iHeight));
947 if (cIconPath != NULL && *cIconPath != '\0')
948 pSurface = cairo_dock_create_surface_from_image_simple (cIconPath,
949 iWidth,
950 iHeight);
951 g_free (cIconPath);
952 }
953 cairo_dock_load_image_buffer_from_surface (&icon->image, pSurface, iWidth, iHeight);
954 }
init_object(GldiObject * obj,G_GNUC_UNUSED gpointer attr)955 static void init_object (GldiObject *obj, G_GNUC_UNUSED gpointer attr)
956 {
957 Icon *icon = (Icon*)obj;
958 icon->iface.load_image = _load_image;
959 }
960
reset_object(GldiObject * obj)961 static void reset_object (GldiObject *obj)
962 {
963 Icon *icon = (Icon*)obj;
964 cd_debug ("%s (%s , %s, %s)", __func__, icon->cName, icon->cClass, gldi_object_get_type(icon));
965
966 GldiContainer *pContainer = cairo_dock_get_icon_container (icon);
967 if (pContainer != NULL)
968 {
969 gldi_icon_detach (icon);
970 }
971
972 if (icon->cClass != NULL && (GLDI_OBJECT_IS_LAUNCHER_ICON (icon) || GLDI_OBJECT_IS_APPLET_ICON (icon))) // c'est un inhibiteur.
973 cairo_dock_deinhibite_class (icon->cClass, icon); // unset the appli if it had any
974
975 gldi_object_notify (icon, NOTIFICATION_STOP_ICON, icon);
976 cairo_dock_remove_transition_on_icon (icon);
977 cairo_dock_remove_data_renderer_on_icon (icon);
978
979 if (icon->pSubDock != NULL)
980 gldi_object_unref (GLDI_OBJECT(icon->pSubDock));
981
982 if (icon->iSpecificDesktop != 0)
983 {
984 s_iNbNonStickyLaunchers --;
985 s_pFloatingIconsList = g_list_remove(s_pFloatingIconsList, icon);
986 }
987
988 if (icon->iSidRedrawSubdockContent != 0)
989 g_source_remove (icon->iSidRedrawSubdockContent);
990 if (icon->iSidLoadImage != 0) // remove timers after any function that could trigger one (for instance, cairo_dock_deinhibite_class calls cairo_dock_trigger_load_icon_buffers)
991 g_source_remove (icon->iSidLoadImage);
992 if (icon->iSidDoubleClickDelay != 0)
993 g_source_remove (icon->iSidDoubleClickDelay);
994
995 // free data
996 g_free (icon->cDesktopFileName);
997 g_free (icon->cFileName);
998 g_free (icon->cName);
999 g_free (icon->cInitialName);
1000 g_free (icon->cCommand);
1001 g_free (icon->cWorkingDirectory);
1002 g_free (icon->cBaseURI);
1003 g_free (icon->cParentDockName); // on ne liberera pas le sous-dock ici sous peine de se mordre la queue, donc il faut l'avoir fait avant.
1004 g_free (icon->cClass);
1005 g_free (icon->cWmClass);
1006 g_free (icon->cQuickInfo);
1007 ///g_free (icon->cLastAttentionDemand);
1008 g_free (icon->pHiddenBgColor);
1009 if (icon->pMimeTypes)
1010 g_strfreev (icon->pMimeTypes);
1011
1012 cairo_dock_unload_image_buffer (&icon->image);
1013
1014 cairo_dock_unload_image_buffer (&icon->label);
1015
1016 cairo_dock_destroy_icon_overlays (icon);
1017 }
1018
gldi_register_icons_manager(void)1019 void gldi_register_icons_manager (void)
1020 {
1021 // Manager
1022 memset (&myIconsMgr, 0, sizeof (GldiManager));
1023 gldi_object_init (GLDI_OBJECT(&myIconsMgr), &myManagerObjectMgr, NULL);
1024 myIconsMgr.cModuleName = "Icons";
1025 // interface
1026 myIconsMgr.init = init;
1027 myIconsMgr.load = load;
1028 myIconsMgr.unload = unload;
1029 myIconsMgr.reload = (GldiManagerReloadFunc)reload;
1030 myIconsMgr.get_config = (GldiManagerGetConfigFunc)get_config;
1031 myIconsMgr.reset_config = (GldiManagerResetConfigFunc)reset_config;
1032 // Config
1033 memset (&myIconsParam, 0, sizeof (CairoIconsParam));
1034 myIconsMgr.pConfig = (GldiManagerConfigPtr)&myIconsParam;
1035 myIconsMgr.iSizeOfConfig = sizeof (CairoIconsParam);
1036 // data
1037 memset (&g_pIconBackgroundBuffer, 0, sizeof (CairoDockImageBuffer));
1038 myIconsMgr.pData = (GldiManagerDataPtr)NULL;
1039 myIconsMgr.iSizeOfData = 0;
1040
1041 // ObjectManager
1042 memset (&myIconObjectMgr, 0, sizeof (GldiObjectManager));
1043 myIconObjectMgr.cName = "Icon";
1044 myIconObjectMgr.iObjectSize = sizeof (Icon);
1045 // interface
1046 myIconObjectMgr.init_object = init_object;
1047 myIconObjectMgr.reset_object = reset_object;
1048 // signals
1049 gldi_object_install_notifications (&myIconObjectMgr, NB_NOTIFICATIONS_ICON);
1050 }
1051