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 <stdio.h>
23 #include <stdlib.h>
24
25 #include <glib/gstdio.h>
26 #include <gtk/gtk.h>
27
28 #include <cairo.h>
29
30 #include "gldi-config.h"
31 #include "cairo-dock-image-buffer.h"
32 #include "cairo-dock-config.h"
33 #include "cairo-dock-icon-factory.h"
34 #include "cairo-dock-icon-facility.h"
35 #include "cairo-dock-separator-manager.h" // gldi_automatic_separators_add_in_list
36 #include "cairo-dock-launcher-manager.h"
37 #include "cairo-dock-applet-manager.h"
38 #include "cairo-dock-stack-icon-manager.h"
39 #include "cairo-dock-class-icon-manager.h"
40 #include "cairo-dock-backends-manager.h"
41 #include "cairo-dock-desktop-manager.h"
42 #include "cairo-dock-log.h"
43 #include "cairo-dock-keyfile-utilities.h"
44 #include "cairo-dock-themes-manager.h" // cairo_dock_add_conf_file
45 #include "cairo-dock-dock-factory.h"
46 #include "cairo-dock-dock-facility.h"
47 #include "cairo-dock-draw.h"
48 #include "cairo-dock-draw-opengl.h"
49 #include "cairo-dock-animations.h"
50 #include "cairo-dock-container.h"
51 #include "cairo-dock-keybinder.h"
52 #include "cairo-dock-indicator-manager.h" // myIndicatorsParam.bUseClassIndic
53 #include "cairo-dock-style-manager.h"
54 #include "cairo-dock-opengl.h"
55 #include "cairo-dock-dock-visibility.h"
56 #include "cairo-dock-dock-manager.h"
57
58 // public (manager, config, data)
59 CairoDocksParam myDocksParam;
60 GldiManager myDocksMgr;
61 GldiObjectManager myDockObjectMgr;
62 CairoDockImageBuffer g_pVisibleZoneBuffer;
63 CairoDock *g_pMainDock = NULL; // pointeur sur le dock principal.
64 CairoDockHidingEffect *g_pHidingBackend = NULL;
65 CairoDockHidingEffect *g_pKeepingBelowBackend = NULL;
66
67 // dependancies
68 extern gchar *g_cConfFile;
69 extern gchar *g_cCurrentThemePath;
70 extern gboolean g_bUseOpenGL;
71 extern CairoDockGLConfig g_openglConfig;
72
73 // private
74 static GHashTable *s_hDocksTable = NULL; // table des docks existant.
75 static GList *s_pRootDockList = NULL;
76 static guint s_iSidPollScreenEdge = 0;
77 static int s_iNbPolls = 0;
78 static gboolean s_bQuickHide = FALSE;
79 static gboolean s_bKeepAbove = FALSE;
80 static GldiShortkey *s_pPopupBinding = NULL; // option 'pop up on shortkey'
81 static gboolean s_bResetAll = FALSE;
82
83 #define MOUSE_POLLING_DT 150 // mouse polling delay in ms
84
85 static gboolean _get_root_dock_config (CairoDock *pDock);
86 static void _start_polling_screen_edge (void);
87 static void _stop_polling_screen_edge (void);
88 static void _synchronize_sub_docks_orientation (CairoDock *pDock, gboolean bUpdateDockSize);
89 static void _set_dock_orientation (CairoDock *pDock, CairoDockPositionType iScreenBorder);
90 static void _remove_root_dock_config (const gchar *cDockName);
91
92 typedef struct {
93 gboolean bUpToDate;
94 gint x;
95 gint y;
96 gboolean bNoMove;
97 gdouble dx;
98 gdouble dy;
99 } CDMousePolling;
100
101 /////////////
102 // MANAGER //
103 /////////////
104
105
cairo_dock_force_docks_above(void)106 void cairo_dock_force_docks_above (void)
107 {
108 if (g_pMainDock != NULL)
109 {
110 cd_warning ("this function must be called before any dock is created.");
111 return;
112 }
113 s_bKeepAbove = TRUE;
114 }
115
116
117 // UNLOAD //
_free_one_dock(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,G_GNUC_UNUSED gpointer data)118 static gboolean _free_one_dock (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, G_GNUC_UNUSED gpointer data)
119 {
120 g_free (pDock->cDockName);
121 pDock->cDockName = NULL; // to not remove it from the table/list
122 gldi_object_unref (GLDI_OBJECT(pDock));
123 return TRUE;
124 }
cairo_dock_reset_docks_table(void)125 void cairo_dock_reset_docks_table (void)
126 {
127 s_bResetAll = TRUE;
128 g_hash_table_foreach_remove (s_hDocksTable, (GHRFunc) _free_one_dock, NULL);
129 g_pMainDock = NULL;
130
131 g_list_free (s_pRootDockList);
132 s_pRootDockList = NULL;
133 s_bResetAll = FALSE;
134 }
135
136
_make_sub_dock(CairoDock * pDock,CairoDock * pParentDock,const gchar * cRendererName)137 static void _make_sub_dock (CairoDock *pDock, CairoDock *pParentDock, const gchar *cRendererName)
138 {
139 //\__________________ set sub-dock flag
140 pDock->iRefCount = 1;
141 gtk_window_set_title (GTK_WINDOW (pDock->container.pWidget), "cairo-dock-sub");
142
143 //\__________________ set the orientation relatively to the parent dock
144 pDock->container.bIsHorizontal = pParentDock->container.bIsHorizontal;
145 pDock->container.bDirectionUp = pParentDock->container.bDirectionUp;
146 pDock->iNumScreen = pParentDock->iNumScreen;
147
148 //\__________________ set a renderer
149 cairo_dock_set_renderer (pDock, cRendererName);
150
151 //\__________________ update the icons size and the ratio.
152 double fPrevRatio = pDock->container.fRatio;
153 pDock->container.fRatio = MIN (pDock->container.fRatio, myBackendsParam.fSubDockSizeRatio);
154 pDock->iIconSize = pParentDock->iIconSize;
155
156 Icon *icon;
157 GList *ic;
158 pDock->fFlatDockWidth = - myIconsParam.iIconGap;
159 for (ic = pDock->icons; ic != NULL; ic = ic->next)
160 {
161 icon = ic->data;
162 cairo_dock_icon_set_requested_size (icon, 0, 0); // no request
163 icon->fWidth = icon->fHeight = 0; /// useful ?...
164 cairo_dock_set_icon_size_in_dock (pDock, icon);
165 pDock->fFlatDockWidth += icon->fWidth + myIconsParam.iIconGap;
166 }
167 pDock->iMaxIconHeight *= pDock->container.fRatio / fPrevRatio;
168
169 //\__________________ remove any input shape
170 if (pDock->pShapeBitmap != NULL)
171 {
172 cairo_region_destroy (pDock->pShapeBitmap);
173 pDock->pShapeBitmap = NULL;
174 if (pDock->iInputState != CAIRO_DOCK_INPUT_ACTIVE)
175 {
176 cairo_dock_set_input_shape_active (pDock);
177 pDock->iInputState = CAIRO_DOCK_INPUT_ACTIVE;
178 }
179 }
180
181 //\__________________ hide the dock
182 pDock->bAutoHide = FALSE;
183 gtk_widget_hide (pDock->container.pWidget);
184 }
gldi_dock_make_subdock(CairoDock * pDock,CairoDock * pParentDock,const gchar * cRendererName)185 void gldi_dock_make_subdock (CairoDock *pDock, CairoDock *pParentDock, const gchar *cRendererName)
186 {
187 //g_print ("%s (%s)\n", __func__, cRendererName);
188 if (pDock->iRefCount == 0) // il devient un sous-dock.
189 {
190 //\__________________ make it a sub-dock.
191 if (pParentDock == NULL)
192 pParentDock = g_pMainDock;
193 _make_sub_dock (pDock, pParentDock, cRendererName);
194 cairo_dock_update_dock_size (pDock);
195
196 //\__________________ remove from main-dock land
197 _remove_root_dock_config (pDock->cDockName); // just in case.
198
199 s_pRootDockList = g_list_remove (s_pRootDockList, pDock);
200
201 gldi_dock_set_visibility (pDock, CAIRO_DOCK_VISI_KEEP_ABOVE); // si la visibilite n'avait pas ete mise (sub-dock), ne fera rien (vu que la visibilite par defaut est KEEP_ABOVE).
202 }
203 }
204
205
206
_find_similar_root_dock(CairoDock * pDock,gpointer * data)207 static void _find_similar_root_dock (CairoDock *pDock, gpointer *data)
208 {
209 CairoDock *pDock0 = data[0];
210 if (pDock == pDock0)
211 data[2] = GINT_TO_POINTER (TRUE);
212 if (data[2])
213 return;
214 if (pDock->container.bIsHorizontal == pDock0->container.bIsHorizontal
215 && pDock->container.bDirectionUp == pDock0->container.bDirectionUp)
216 {
217 int *i = data[1];
218 *i = *i + 1;
219 }
220 }
gldi_dock_get_readable_name(CairoDock * pDock)221 gchar *gldi_dock_get_readable_name (CairoDock *pDock)
222 {
223 g_return_val_if_fail (pDock != NULL, NULL);
224 gchar *cUserName = NULL;
225 if (pDock->iRefCount == 0)
226 {
227 int i = 0;
228 gpointer data[3] = {pDock, &i, NULL};
229 GList *d = g_list_last (s_pRootDockList);
230 for (;d != NULL; d = d->prev) // parse the list from the end to get the main dock first (docks are prepended).
231 _find_similar_root_dock (d->data, data);
232 const gchar *cPosition;
233 if (pDock->container.bIsHorizontal)
234 {
235 if (pDock->container.bDirectionUp)
236 cPosition = _("Bottom dock");
237 else
238 cPosition = _("Top dock");
239 }
240 else
241 {
242 if (pDock->container.bDirectionUp)
243 cPosition = _("Right dock");
244 else
245 cPosition = _("Left dock");
246 }
247 if (i > 0)
248 cUserName = g_strdup_printf ("%s (%d)", cPosition, i+1);
249 else
250 cUserName = g_strdup (cPosition);
251 }
252
253 return cUserName;
254 }
255
gldi_dock_get(const gchar * cDockName)256 CairoDock *gldi_dock_get (const gchar *cDockName)
257 {
258 if (cDockName == NULL)
259 return NULL;
260 return g_hash_table_lookup (s_hDocksTable, cDockName);
261 }
262
_cairo_dock_search_icon_from_subdock(G_GNUC_UNUSED gchar * cDockName,CairoDock * pDock,gpointer * data)263 static gboolean _cairo_dock_search_icon_from_subdock (G_GNUC_UNUSED gchar *cDockName, CairoDock *pDock, gpointer *data)
264 {
265 if (pDock == data[0])
266 return FALSE;
267 Icon **pIconFound = data[1];
268 CairoDock **pDockFound = data[2];
269 Icon *icon = cairo_dock_get_icon_with_subdock (pDock->icons, data[0]);
270 if (icon != NULL)
271 {
272 *pIconFound = icon;
273 if (pDockFound != NULL)
274 *pDockFound = pDock;
275 return TRUE;
276 }
277 else
278 return FALSE;
279 }
cairo_dock_search_icon_pointing_on_dock(CairoDock * pDock,CairoDock ** pParentDock)280 Icon *cairo_dock_search_icon_pointing_on_dock (CairoDock *pDock, CairoDock **pParentDock) // pParentDock peut etre NULL.
281 {
282 if (pDock == NULL || pDock->bIsMainDock) // par definition. On n'utilise pas iRefCount, car si on est en train de detruire un dock, sa reference est deja decrementee. C'est dommage mais c'est comme ca.
283 return NULL;
284 Icon *pPointingIcon = NULL;
285 gpointer data[3] = {pDock, &pPointingIcon, pParentDock};
286 g_hash_table_find (s_hDocksTable, (GHRFunc)_cairo_dock_search_icon_from_subdock, data);
287 return pPointingIcon;
288 }
289
cairo_dock_get_unique_dock_name(const gchar * cPrefix)290 gchar *cairo_dock_get_unique_dock_name (const gchar *cPrefix)
291 {
292 const gchar *cNamepattern = (cPrefix != NULL && *cPrefix != '\0' && strcmp (cPrefix, "cairo-dock") != 0 ? cPrefix : "dock");
293 GString *sNameString = g_string_new (cNamepattern);
294
295 int i = 2;
296 while (g_hash_table_lookup (s_hDocksTable, sNameString->str) != NULL)
297 {
298 g_string_printf (sNameString, "%s-%d", cNamepattern, i);
299 i ++;
300 }
301
302 gchar *cUniqueName = sNameString->str;
303 g_string_free (sNameString, FALSE);
304 return cUniqueName;
305 }
306
cairo_dock_check_unique_subdock_name(Icon * pIcon)307 gboolean cairo_dock_check_unique_subdock_name (Icon *pIcon)
308 {
309 cd_debug ("%s (%s)", __func__, pIcon->cName);
310 gchar *cUniqueName = cairo_dock_get_unique_dock_name (pIcon->cName);
311 if (pIcon->cName == NULL || strcmp (pIcon->cName, cUniqueName) != 0)
312 {
313 g_free (pIcon->cName);
314 pIcon->cName = cUniqueName;
315 cd_debug (" cName <- %s", cUniqueName);
316 return TRUE;
317 }
318 return FALSE;
319 }
320
321
gldi_dock_rename(CairoDock * pDock,const gchar * cNewName)322 void gldi_dock_rename (CairoDock *pDock, const gchar *cNewName)
323 {
324 // ensure everything is ok
325 g_return_if_fail (pDock != NULL && cNewName != NULL);
326 g_return_if_fail (g_hash_table_lookup (s_hDocksTable, cNewName) == NULL);
327
328 // rename in the hash table
329 g_hash_table_remove (s_hDocksTable, pDock->cDockName);
330 g_free (pDock->cDockName);
331 pDock->cDockName = g_strdup (cNewName);
332 g_hash_table_insert (s_hDocksTable, pDock->cDockName, pDock);
333
334 // rename in each icons
335 GList* ic;
336 Icon *icon;
337 for (ic = pDock->icons; ic != NULL; ic = ic->next)
338 {
339 icon = ic->data;
340 gldi_theme_icon_write_container_name_in_conf_file (icon, cNewName);
341 g_free (icon->cParentDockName);
342 icon->cParentDockName = g_strdup (cNewName);
343 }
344 }
345
346
gldi_docks_foreach(GHFunc pFunction,gpointer data)347 void gldi_docks_foreach (GHFunc pFunction, gpointer data)
348 {
349 g_hash_table_foreach (s_hDocksTable, pFunction, data);
350 }
351
gldi_docks_foreach_root(GFunc pFunction,gpointer data)352 void gldi_docks_foreach_root (GFunc pFunction, gpointer data)
353 {
354 g_list_foreach (s_pRootDockList, pFunction, data);
355 }
356
_gldi_icons_foreach_in_dock(G_GNUC_UNUSED gchar * cDockName,CairoDock * pDock,gpointer * data)357 static void _gldi_icons_foreach_in_dock (G_GNUC_UNUSED gchar *cDockName, CairoDock *pDock, gpointer *data)
358 {
359 GldiIconFunc pFunction = data[0];
360 gpointer pUserData = data[1];
361 GList *ic = pDock->icons, *next_ic;
362 while (ic != NULL)
363 {
364 next_ic = ic->next; // the function below may remove the current icon
365 pFunction ((Icon*)ic->data, pUserData);
366 ic = next_ic;
367 }
368 }
gldi_icons_foreach_in_docks(GldiIconFunc pFunction,gpointer pUserData)369 void gldi_icons_foreach_in_docks (GldiIconFunc pFunction, gpointer pUserData)
370 {
371 gpointer data[2] = {pFunction, pUserData};
372 g_hash_table_foreach (s_hDocksTable, (GHFunc) _gldi_icons_foreach_in_dock, data);
373 }
374
375
376
_reload_buffer_in_one_dock(CairoDock * pDock,gpointer data)377 static void _reload_buffer_in_one_dock (/**const gchar *cDockName, */CairoDock *pDock, gpointer data)
378 {
379 cairo_dock_reload_buffers_in_dock (pDock, TRUE, GPOINTER_TO_INT (data));
380 }
_cairo_dock_draw_one_subdock_icon(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,G_GNUC_UNUSED gpointer data)381 static void _cairo_dock_draw_one_subdock_icon (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, G_GNUC_UNUSED gpointer data)
382 {
383 Icon *icon;
384 GList *ic;
385 for (ic = pDock->icons; ic != NULL; ic = ic->next)
386 {
387 icon = ic->data;
388 if (icon->pSubDock != NULL
389 && (GLDI_OBJECT_IS_STACK_ICON (icon) || CAIRO_DOCK_IS_MULTI_APPLI (icon) || GLDI_OBJECT_IS_APPLET_ICON (icon))
390 && (icon->iSubdockViewType != 0
391 || (CAIRO_DOCK_IS_MULTI_APPLI (icon) && !myIndicatorsParam.bUseClassIndic))
392 /**&& icon->iSidRedrawSubdockContent == 0*/) // icone de sous-dock ou de classe ou d'applets.
393 {
394 cairo_dock_trigger_redraw_subdock_content_on_icon (icon);
395 }
396 }
397 }
cairo_dock_reload_buffers_in_all_docks(gboolean bUpdateIconSize)398 void cairo_dock_reload_buffers_in_all_docks (gboolean bUpdateIconSize)
399 {
400 g_list_foreach (s_pRootDockList, (GFunc)_reload_buffer_in_one_dock, GINT_TO_POINTER (bUpdateIconSize)); // we load the root docks first, so that sub-docks can have the correct icon size.
401
402 // now that all icons in sub-docks are drawn, redraw icons pointing to a sub-dock
403 g_hash_table_foreach (s_hDocksTable, (GHFunc)_cairo_dock_draw_one_subdock_icon, NULL);
404 }
405
406
407
_cairo_dock_set_one_dock_view_to_default(G_GNUC_UNUSED gchar * cDockName,CairoDock * pDock,gpointer data)408 static void _cairo_dock_set_one_dock_view_to_default (G_GNUC_UNUSED gchar *cDockName, CairoDock *pDock, gpointer data)
409 {
410 //g_print ("%s (%s)\n", __func__, cDockName);
411 int iDockType = GPOINTER_TO_INT (data);
412 if (iDockType == 0 || (iDockType == 1 && pDock->iRefCount == 0) || (iDockType == 2 && pDock->iRefCount != 0))
413 {
414 cairo_dock_set_default_renderer (pDock);
415 cairo_dock_update_dock_size (pDock);
416 }
417 }
cairo_dock_set_all_views_to_default(int iDockType)418 void cairo_dock_set_all_views_to_default (int iDockType)
419 {
420 //g_print ("%s ()\n", __func__);
421 g_hash_table_foreach (s_hDocksTable, (GHFunc) _cairo_dock_set_one_dock_view_to_default, GINT_TO_POINTER (iDockType));
422 }
423
424
425 //////////////////////
426 // ROOT DOCK CONFIG //
427 //////////////////////
428
gldi_rootdock_write_gaps(CairoDock * pDock)429 void gldi_rootdock_write_gaps (CairoDock *pDock)
430 {
431 if (pDock->iRefCount > 0)
432 return;
433
434 cairo_dock_prevent_dock_from_out_of_screen (pDock);
435 if (pDock->bIsMainDock)
436 {
437 cairo_dock_update_conf_file (g_cConfFile,
438 G_TYPE_INT, "Position", "x gap", pDock->iGapX,
439 G_TYPE_INT, "Position", "y gap", pDock->iGapY,
440 G_TYPE_INVALID);
441 }
442 else
443 {
444 const gchar *cDockName = gldi_dock_get_name (pDock);
445 gchar *cConfFilePath = g_strdup_printf ("%s/%s.conf", g_cCurrentThemePath, cDockName);
446 if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS)) // shouldn't happen
447 {
448 cairo_dock_add_conf_file (GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_MAIN_DOCK_CONF_FILE, cConfFilePath);
449 }
450
451 cairo_dock_update_conf_file (cConfFilePath,
452 G_TYPE_INT, "Behavior", "x gap", pDock->iGapX,
453 G_TYPE_INT, "Behavior", "y gap", pDock->iGapY,
454 G_TYPE_INVALID);
455 g_free (cConfFilePath);
456 }
457 }
458
cairo_dock_convert_icon_size_to_pixels(GldiIconSizeEnum s,double * fMaxScale,double * fReflectSize,int * iIconGap)459 int cairo_dock_convert_icon_size_to_pixels (GldiIconSizeEnum s, double *fMaxScale, double *fReflectSize, int *iIconGap)
460 {
461 int iIconSize;
462 switch (s)
463 {
464 case ICON_DEFAULT:
465 default:
466 iIconSize = myIconsParam.iIconWidth;
467 *fMaxScale = 1 + myIconsParam.fAmplitude;
468 *iIconGap = myIconsParam.iIconGap;
469 *fReflectSize = myIconsParam.fReflectHeightRatio;
470 break;
471 case ICON_TINY:
472 iIconSize = ICON_SIZE_TINY;
473 *fMaxScale = 2;
474 *iIconGap = 4;
475 *fReflectSize = .4;
476 break;
477 case ICON_VERY_SMALL:
478 iIconSize = ICON_SIZE_VERY_SMALL;
479 *fMaxScale = 1.8;
480 *iIconGap = 4;
481 *fReflectSize = .4;
482 break;
483 case ICON_SMALL:
484 iIconSize = ICON_SIZE_SMALL;
485 *fMaxScale = 1.8;
486 *iIconGap = 4;
487 *fReflectSize = .4;
488 break;
489 case ICON_MEDIUM:
490 iIconSize = ICON_SIZE_MEDIUM;
491 *fMaxScale = 1.6;
492 *iIconGap = 3;
493 *fReflectSize = .5;
494 break;
495 case ICON_BIG:
496 iIconSize = ICON_SIZE_BIG;
497 *fMaxScale = 1.5;
498 *iIconGap = 2;
499 *fReflectSize = .6;
500 break;
501 case ICON_HUGE:
502 iIconSize = ICON_SIZE_HUGE;
503 *fMaxScale = 1.3;
504 *iIconGap = 2;
505 *fReflectSize = .6;
506 break;
507 }
508 return iIconSize;
509 }
510
cairo_dock_convert_icon_size_to_enum(int iIconSize)511 GldiIconSizeEnum cairo_dock_convert_icon_size_to_enum (int iIconSize)
512 {
513 GldiIconSizeEnum s = ICON_DEFAULT;
514 if (iIconSize <= ICON_SIZE_TINY+2)
515 s = ICON_TINY;
516 else if (iIconSize <= ICON_SIZE_VERY_SMALL+2)
517 s = ICON_VERY_SMALL;
518 else if (iIconSize >= ICON_SIZE_HUGE-2)
519 s = ICON_HUGE;
520 else if (iIconSize > ICON_SIZE_MEDIUM)
521 s = ICON_BIG;
522 else
523 {
524 if (myIconsParam.fAmplitude >= 2 || iIconSize <= ICON_SIZE_SMALL)
525 s = ICON_SMALL;
526 else
527 s = ICON_MEDIUM; // moyennes.
528 }
529 return s;
530 }
531
_get_root_dock_config(CairoDock * pDock)532 static gboolean _get_root_dock_config (CairoDock *pDock)
533 {
534 g_return_val_if_fail (pDock != NULL, FALSE);
535 if (pDock->iRefCount > 0)
536 return FALSE;
537
538 if (pDock->bIsMainDock) // the main dock doesn't have a config file, it uses the global params (that we already got from the Dock-manager)
539 {
540 pDock->iGapX = myDocksParam.iGapX;
541 pDock->iGapY = myDocksParam.iGapY;
542
543 pDock->fAlign = myDocksParam.fAlign;
544
545 pDock->iNumScreen = myDocksParam.iNumScreen;
546
547 _set_dock_orientation (pDock, myDocksParam.iScreenBorder); // do it after all position parameters have been set; it sets the sub-docks orientation too.
548
549 gldi_dock_set_visibility (pDock, myDocksParam.iVisibility);
550
551 pDock->bGlobalIconSize = TRUE; // default icon size
552
553 pDock->bGlobalBg = TRUE; // default background
554 // pDock->cRendererName and pDock->iIconSize stay at 0
555
556 pDock->bExtendedMode = myDocksParam.bExtendedMode;
557
558 return TRUE;
559 }
560
561 //\______________ On verifie la presence du fichier de conf associe.
562 //g_print ("%s (%s)\n", __func__, pDock->cDockName);
563 gchar *cConfFilePath = g_strdup_printf ("%s/%s.conf", g_cCurrentThemePath, pDock->cDockName);
564 if (! g_file_test (cConfFilePath, G_FILE_TEST_EXISTS)) // pas encore de fichier de conf pour ce dock.
565 {
566 pDock->container.bIsHorizontal = g_pMainDock->container.bIsHorizontal;
567 pDock->container.bDirectionUp = g_pMainDock->container.bDirectionUp;
568 pDock->fAlign = g_pMainDock->fAlign;
569
570 g_free (cConfFilePath);
571 return FALSE;
572 }
573
574 //\______________ On ouvre le fichier de conf.
575 GKeyFile *pKeyFile = cairo_dock_open_key_file (cConfFilePath);
576 if (pKeyFile == NULL)
577 {
578 cd_warning ("wrong conf file (%s) !", cConfFilePath);
579 g_free (cConfFilePath);
580 return FALSE;
581 }
582
583 //\______________ Position.
584 gboolean bFlushConfFileNeeded = FALSE;
585 pDock->iGapX = cairo_dock_get_integer_key_value (pKeyFile, "Behavior", "x gap", &bFlushConfFileNeeded, 0, "Position", NULL);
586 pDock->iGapY = cairo_dock_get_integer_key_value (pKeyFile, "Behavior", "y gap", &bFlushConfFileNeeded, 0, "Position", NULL);
587
588 pDock->fAlign = cairo_dock_get_double_key_value (pKeyFile, "Behavior", "alignment", &bFlushConfFileNeeded, 0.5, "Position", NULL);
589
590 pDock->iNumScreen = cairo_dock_get_integer_key_value (pKeyFile, "Behavior", "num_screen", &bFlushConfFileNeeded, GLDI_DEFAULT_SCREEN, "Position", NULL);
591
592 CairoDockPositionType iScreenBorder = cairo_dock_get_integer_key_value (pKeyFile, "Behavior", "screen border", &bFlushConfFileNeeded, 0, "Position", NULL);
593 _set_dock_orientation (pDock, iScreenBorder); // do it after all position parameters have been set; it sets the sub-docks orientation too.
594
595 //\______________ Visibility.
596 CairoDockVisibility iVisibility = cairo_dock_get_integer_key_value (pKeyFile, "Behavior", "visibility", &bFlushConfFileNeeded, FALSE, "Position", NULL);
597 gldi_dock_set_visibility (pDock, iVisibility);
598
599 //\______________ Icons size.
600 int s = cairo_dock_get_integer_key_value (pKeyFile, "Appearance", "icon size", &bFlushConfFileNeeded, ICON_DEFAULT, NULL, NULL); // ICON_DEFAULT <=> same as main dock
601 double fMaxScale, fReflectSize;
602 int iIconGap;
603 pDock->iIconSize = cairo_dock_convert_icon_size_to_pixels (s, &fMaxScale, &fReflectSize, &iIconGap);
604 pDock->bGlobalIconSize = (s == ICON_DEFAULT);
605
606 //\______________ View.
607 g_free (pDock->cRendererName);
608 pDock->cRendererName = cairo_dock_get_string_key_value (pKeyFile, "Appearance", "main dock view", &bFlushConfFileNeeded, NULL, "Views", NULL);
609
610 //\______________ Background.
611 int iBgType = cairo_dock_get_integer_key_value (pKeyFile, "Appearance", "fill bg", &bFlushConfFileNeeded, 0, NULL, NULL);
612
613 pDock->bGlobalBg = (iBgType == 0);
614
615 if (!pDock->bGlobalBg)
616 {
617 if (iBgType == 1)
618 {
619 gchar *cBgImage = cairo_dock_get_string_key_value (pKeyFile, "Appearance", "background image", &bFlushConfFileNeeded, NULL, NULL, NULL);
620 g_free (pDock->cBgImagePath);
621 if (cBgImage != NULL)
622 {
623 pDock->cBgImagePath = cairo_dock_search_image_s_path (cBgImage);
624 g_free (cBgImage);
625 }
626 else
627 pDock->cBgImagePath = NULL;
628
629 pDock->bBgImageRepeat = cairo_dock_get_boolean_key_value (pKeyFile, "Appearance", "repeat image", &bFlushConfFileNeeded, FALSE, NULL, NULL);
630 }
631 // on recupere la couleur tout le temps pour avoir un plan B.
632 GldiColor couleur = {{.7, .7, 1., .7}};
633 cairo_dock_get_color_key_value (pKeyFile, "Appearance", "stripes color dark", &bFlushConfFileNeeded, &pDock->fBgColorDark, &couleur, NULL, NULL);
634
635 GldiColor couleur2 = {{.7, .9, .7, .4}};
636 cairo_dock_get_color_key_value (pKeyFile, "Appearance", "stripes color bright", &bFlushConfFileNeeded, &pDock->fBgColorBright, &couleur2, NULL, NULL);
637 }
638
639 pDock->bExtendedMode = cairo_dock_get_boolean_key_value (pKeyFile, "Appearance", "extended", &bFlushConfFileNeeded, FALSE, NULL, NULL);
640
641 //\______________ On met a jour le fichier de conf.
642 if (! bFlushConfFileNeeded)
643 bFlushConfFileNeeded = cairo_dock_conf_file_needs_update (pKeyFile, GLDI_VERSION);
644 if (bFlushConfFileNeeded)
645 {
646 //g_print ("update %s conf file\n", pDock->cDockName);
647 cairo_dock_upgrade_conf_file (cConfFilePath, pKeyFile, GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_MAIN_DOCK_CONF_FILE);
648 }
649
650 g_key_file_free (pKeyFile);
651 g_free (cConfFilePath);
652 return TRUE;
653 }
654
_remove_root_dock_config(const gchar * cDockName)655 static void _remove_root_dock_config (const gchar *cDockName)
656 {
657 if (! cDockName || strcmp (cDockName, "cairo-dock") == 0)
658 return ;
659 gchar *cConfFilePath = g_strdup_printf ("%s/%s.conf", g_cCurrentThemePath, cDockName);
660 if (g_file_test (cConfFilePath, G_FILE_TEST_EXISTS))
661 {
662 cairo_dock_delete_conf_file (cConfFilePath);
663 }
664 g_free (cConfFilePath);
665 }
666
gldi_dock_add_conf_file_for_name(const gchar * cDockName)667 void gldi_dock_add_conf_file_for_name (const gchar *cDockName)
668 {
669 // on cree le fichier de conf a partir du template.
670 cd_debug ("%s (%s)", __func__, cDockName);
671 gchar *cConfFilePath = g_strdup_printf ("%s/%s.conf", g_cCurrentThemePath, cDockName);
672 cairo_dock_add_conf_file (GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_MAIN_DOCK_CONF_FILE, cConfFilePath);
673
674 // on placera le nouveau dock a l'oppose du main dock, meme ecran et meme visibilite.
675 cairo_dock_update_conf_file (cConfFilePath,
676 G_TYPE_INT, "Behavior", "screen border",
677 (g_pMainDock->container.bIsHorizontal ?
678 (g_pMainDock->container.bDirectionUp ? 1 : 0) :
679 (g_pMainDock->container.bDirectionUp ? 3 : 2)),
680 G_TYPE_INT, "Behavior", "visibility",
681 g_pMainDock->iVisibility,
682 G_TYPE_INT, "Behavior", "num_screen",
683 g_pMainDock->iNumScreen,
684 G_TYPE_INVALID);
685 g_free (cConfFilePath);
686 }
687
gldi_dock_add_conf_file(void)688 gchar *gldi_dock_add_conf_file (void)
689 {
690 // on genere un nom unique.
691 gchar *cValidDockName = cairo_dock_get_unique_dock_name (CAIRO_DOCK_MAIN_DOCK_NAME); // meme nom que le main dock avec un numero en plus, plus facile pour les reperer.
692
693 // on genere un fichier de conf pour ce nom.
694 gldi_dock_add_conf_file_for_name (cValidDockName);
695
696 return cValidDockName;
697 }
698
699
gldi_docks_redraw_all_root(void)700 void gldi_docks_redraw_all_root (void)
701 {
702 gldi_docks_foreach_root ((GFunc)cairo_dock_redraw_container, NULL);
703 }
704
705
_reposition_one_root_dock(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,gpointer data)706 static void _reposition_one_root_dock (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, gpointer data)
707 {
708 if (pDock->iRefCount == 0 && ! (data && pDock->bIsMainDock))
709 {
710 if (!pDock->bIsMainDock)
711 _get_root_dock_config (pDock); // relit toute la conf.
712
713 cairo_dock_update_dock_size (pDock); // la taille max du dock depend de la taille de l'ecran, donc on recalcule son ratio.
714 cairo_dock_move_resize_dock (pDock);
715 gtk_widget_show (pDock->container.pWidget);
716 gtk_widget_queue_draw (pDock->container.pWidget);
717 _synchronize_sub_docks_orientation (pDock, TRUE);
718 }
719 }
_reposition_root_docks(gboolean bExceptMainDock)720 static void _reposition_root_docks (gboolean bExceptMainDock)
721 {
722 g_hash_table_foreach (s_hDocksTable, (GHFunc)_reposition_one_root_dock, GINT_TO_POINTER (bExceptMainDock));
723 }
724
gldi_subdock_synchronize_orientation(CairoDock * pSubDock,CairoDock * pDock,gboolean bUpdateDockSize)725 void gldi_subdock_synchronize_orientation (CairoDock *pSubDock, CairoDock *pDock, gboolean bUpdateDockSize)
726 {
727 if (pSubDock->container.bDirectionUp != pDock->container.bDirectionUp)
728 {
729 pSubDock->container.bDirectionUp = pDock->container.bDirectionUp;
730 bUpdateDockSize = TRUE;
731 }
732 if (pSubDock->container.bIsHorizontal != pDock->container.bIsHorizontal)
733 {
734 pSubDock->container.bIsHorizontal = pDock->container.bIsHorizontal;
735 bUpdateDockSize = TRUE;
736 }
737 if (pSubDock->iNumScreen != pDock->iNumScreen)
738 {
739 pSubDock->iNumScreen = pDock->iNumScreen;
740 bUpdateDockSize = TRUE;
741 }
742
743 if (bUpdateDockSize)
744 {
745 cairo_dock_update_dock_size (pSubDock);
746 }
747
748 _synchronize_sub_docks_orientation (pSubDock, bUpdateDockSize);
749 }
750
_synchronize_sub_docks_orientation(CairoDock * pDock,gboolean bUpdateDockSize)751 static void _synchronize_sub_docks_orientation (CairoDock *pDock, gboolean bUpdateDockSize)
752 {
753 GList* ic;
754 Icon *icon;
755 for (ic = pDock->icons; ic != NULL; ic = ic->next)
756 {
757 icon = ic->data;
758 if (icon->pSubDock != NULL)
759 {
760 gldi_subdock_synchronize_orientation (icon->pSubDock, pDock, bUpdateDockSize); // recursively synchronize all children (no need to check for loops, as it shouldn't occur... if it does, then the problem is to fix upstream).
761 }
762 }
763 }
764
_set_dock_orientation(CairoDock * pDock,CairoDockPositionType iScreenBorder)765 static void _set_dock_orientation (CairoDock *pDock, CairoDockPositionType iScreenBorder)
766 {
767 switch (iScreenBorder)
768 {
769 case CAIRO_DOCK_BOTTOM :
770 pDock->container.bIsHorizontal = CAIRO_DOCK_HORIZONTAL;
771 pDock->container.bDirectionUp = TRUE;
772 break;
773 case CAIRO_DOCK_TOP :
774 pDock->container.bIsHorizontal = CAIRO_DOCK_HORIZONTAL;
775 pDock->container.bDirectionUp = FALSE;
776 break;
777 case CAIRO_DOCK_RIGHT :
778 pDock->container.bIsHorizontal = CAIRO_DOCK_VERTICAL;
779 pDock->container.bDirectionUp = TRUE;
780 break;
781 case CAIRO_DOCK_LEFT :
782 pDock->container.bIsHorizontal = CAIRO_DOCK_VERTICAL;
783 pDock->container.bDirectionUp = FALSE;
784 break;
785 case CAIRO_DOCK_INSIDE_SCREEN :
786 case CAIRO_DOCK_NB_POSITIONS :
787 break;
788 }
789 _synchronize_sub_docks_orientation (pDock, FALSE);
790 }
791
792
793 ////////////////
794 // VISIBILITY //
795 ////////////////
796
_cairo_dock_quick_hide_one_root_dock(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,G_GNUC_UNUSED gpointer data)797 static void _cairo_dock_quick_hide_one_root_dock (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, G_GNUC_UNUSED gpointer data)
798 {
799 if (pDock->iRefCount == 0)
800 {
801 pDock->bAutoHide = TRUE;
802 cairo_dock_emit_leave_signal (CAIRO_CONTAINER (pDock));
803 }
804 }
cairo_dock_quick_hide_all_docks(void)805 void cairo_dock_quick_hide_all_docks (void)
806 {
807 if (! s_bQuickHide)
808 {
809 s_bQuickHide = TRUE;
810 g_hash_table_foreach (s_hDocksTable, (GHFunc) _cairo_dock_quick_hide_one_root_dock, NULL);
811 _start_polling_screen_edge ();
812 }
813 }
814
_cairo_dock_stop_quick_hide_one_root_dock(G_GNUC_UNUSED const gchar * cDockName,CairoDock * pDock,G_GNUC_UNUSED gpointer data)815 static void _cairo_dock_stop_quick_hide_one_root_dock (G_GNUC_UNUSED const gchar *cDockName, CairoDock *pDock, G_GNUC_UNUSED gpointer data)
816 {
817 if (pDock->iRefCount == 0 && ! pDock->bTemporaryHidden && pDock->bAutoHide && pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE)
818 {
819 pDock->bAutoHide = FALSE;
820
821 if (! pDock->container.bInside) // on le fait re-apparaitre.
822 {
823 cairo_dock_start_showing (pDock); // l'input shape sera mise lors du configure.
824 }
825 }
826 }
cairo_dock_stop_quick_hide(void)827 void cairo_dock_stop_quick_hide (void)
828 {
829 if (s_bQuickHide)
830 {
831 s_bQuickHide = FALSE;
832 _stop_polling_screen_edge ();
833
834 g_hash_table_foreach (s_hDocksTable, (GHFunc) _cairo_dock_stop_quick_hide_one_root_dock, NULL);
835 }
836 }
837
cairo_dock_allow_entrance(CairoDock * pDock)838 void cairo_dock_allow_entrance (CairoDock *pDock)
839 {
840 pDock->bEntranceDisabled = FALSE;
841 }
842
cairo_dock_disable_entrance(CairoDock * pDock)843 void cairo_dock_disable_entrance (CairoDock *pDock)
844 {
845 pDock->bEntranceDisabled = TRUE;
846 }
847
cairo_dock_entrance_is_allowed(CairoDock * pDock)848 gboolean cairo_dock_entrance_is_allowed (CairoDock *pDock)
849 {
850 return (! pDock->bEntranceDisabled);
851 }
852
cairo_dock_activate_temporary_auto_hide(CairoDock * pDock)853 void cairo_dock_activate_temporary_auto_hide (CairoDock *pDock)
854 {
855 if (pDock->iRefCount == 0 && ! pDock->bTemporaryHidden && pDock->iVisibility != CAIRO_DOCK_VISI_AUTO_HIDE)
856 {
857 pDock->bAutoHide = TRUE;
858 pDock->bTemporaryHidden = TRUE;
859 if (!pDock->container.bInside) // on ne declenche pas le cachage lorsque l'on change par exemple de bureau via le switcher ou un clic sur une appli.
860 {
861 cairo_dock_emit_leave_signal (CAIRO_CONTAINER (pDock)); // un cairo_dock_start_hiding ne cacherait pas les sous-docks.
862 }
863 }
864 }
865
cairo_dock_deactivate_temporary_auto_hide(CairoDock * pDock)866 void cairo_dock_deactivate_temporary_auto_hide (CairoDock *pDock)
867 {
868 //g_print ("%s ()\n", __func__);
869 if (pDock->iRefCount == 0 && pDock->bTemporaryHidden && ! s_bQuickHide)
870 {
871 pDock->bTemporaryHidden = FALSE;
872 pDock->bAutoHide = FALSE;
873
874 if (! pDock->container.bInside) // on le fait re-apparaitre.
875 {
876 cairo_dock_start_showing (pDock);
877 }
878 }
879 }
880
881
_cairo_dock_hide_back_dock(CairoDock * pDock)882 static gboolean _cairo_dock_hide_back_dock (CairoDock *pDock)
883 {
884 //g_print ("hide back\n");
885 if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->container.bInside)
886 cairo_dock_pop_down (pDock);
887 else if (pDock->bAutoHide)
888 cairo_dock_start_hiding (pDock);
889 pDock->iSidHideBack = 0;
890 return FALSE;
891 }
_cairo_dock_unhide_dock_delayed(CairoDock * pDock)892 static gboolean _cairo_dock_unhide_dock_delayed (CairoDock *pDock)
893 {
894 //g_print ("%s (%d, %d)\n", __func__, pDock->container.bInside, pDock->iInputState);
895 if (pDock->container.bInside && pDock->iInputState != CAIRO_DOCK_INPUT_HIDDEN && !pDock->bIsBelow) // already inside and reachable (caution) => no need to show it again.
896 {
897 pDock->iSidUnhideDelayed = 0;
898 return FALSE;
899 }
900
901 //g_print ("let's show this dock (%d)\n", pDock->bIsMainDock);
902 if (pDock->bAutoHide)
903 cairo_dock_start_showing (pDock);
904 if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW)
905 cairo_dock_pop_up (pDock);
906
907 if (pDock->iSidHideBack == 0) // on se recachera dans 2s si on n'est pas entre dans le dock entre-temps.
908 pDock->iSidHideBack = g_timeout_add (2000, (GSourceFunc) _cairo_dock_hide_back_dock, (gpointer) pDock);
909 pDock->iSidUnhideDelayed = 0;
910 return FALSE;
911 }
_cairo_dock_unhide_root_dock_on_mouse_hit(CairoDock * pDock,CDMousePolling * pMouse)912 static void _cairo_dock_unhide_root_dock_on_mouse_hit (CairoDock *pDock, CDMousePolling *pMouse)
913 {
914 if (! pDock->bAutoHide && pDock->iVisibility != CAIRO_DOCK_VISI_KEEP_BELOW)
915 return;
916
917 int iScreenWidth = gldi_dock_get_screen_width (pDock);
918 int iScreenHeight = gldi_dock_get_screen_height (pDock);
919 int iScreenX = gldi_dock_get_screen_offset_x (pDock);
920 int iScreenY = gldi_dock_get_screen_offset_y (pDock);
921
922 //\________________ On recupere la position du pointeur.
923 gint x, y;
924 if (! pMouse->bUpToDate) // pas encore recupere le pointeur.
925 {
926 pMouse->bUpToDate = TRUE;
927 gldi_display_get_pointer (&x, &y);
928 if (x == pMouse->x && y == pMouse->y) // le pointeur n'a pas bouge, on quitte.
929 {
930 pMouse->bNoMove = TRUE;
931 return ;
932 }
933 pMouse->bNoMove = FALSE;
934 pMouse->dx = (x - pMouse->x);
935 pMouse->dy = (y - pMouse->y);
936 double d = sqrt (pMouse->dx * pMouse->dx + pMouse->dy * pMouse->dy);
937 pMouse->dx /= d;
938 pMouse->dy /= d;
939 pMouse->x = x;
940 pMouse->y = y;
941 }
942 else // le pointeur a ete recupere auparavant.
943 {
944 if (pMouse->bNoMove) // position inchangee.
945 return;
946 x = pMouse->x;
947 y = pMouse->y;
948 }
949
950 if (!pDock->container.bIsHorizontal)
951 {
952 x = pMouse->y;
953 y = pMouse->x;
954 }
955 y -= iScreenY; // relative to the border of the dock's screen.
956 if (pDock->container.bDirectionUp)
957 {
958 y = iScreenHeight - 1 - y;
959
960 }
961
962 //\________________ On verifie les conditions.
963 int x1, x2; // coordinates range on the X screen edge.
964 gboolean bShow = FALSE;
965 int Ws = (pDock->container.bIsHorizontal ? gldi_desktop_get_width() : gldi_desktop_get_height());
966 switch (myDocksParam.iCallbackMethod)
967 {
968 case CAIRO_HIT_SCREEN_BORDER:
969 default:
970 if (y != 0)
971 break;
972 if (x < iScreenX || x > iScreenX + iScreenWidth - 1) // only check the border of the dock's screen.
973 break ;
974 bShow = TRUE;
975 break;
976 case CAIRO_HIT_DOCK_PLACE:
977
978 if (y != 0)
979 break;
980 x1 = pDock->container.iWindowPositionX + (pDock->container.iWidth - pDock->iActiveWidth) * pDock->fAlign;
981 x2 = x1 + pDock->iActiveWidth;
982 if (x1 < 8) // avoid corners, since this is actually the purpose of this option (corners can be used by the WM to trigger actions).
983 x1 = 8;
984 if (x2 > Ws - 8)
985 x2 = Ws - 8;
986 if (x < x1 || x > x2)
987 break;
988 bShow = TRUE;
989 break;
990 case CAIRO_HIT_SCREEN_CORNER:
991 if (y != 0)
992 break;
993 if (x > 0 && x < Ws - 1) // avoid the corners of the X screen (since we can't actually hit the corner of a screen that would be inside the X screen).
994 break ;
995 bShow = TRUE;
996 break;
997 case CAIRO_HIT_ZONE:
998 if (y > myDocksParam.iZoneHeight)
999 break;
1000 x1 = pDock->container.iWindowPositionX + (pDock->container.iWidth - myDocksParam.iZoneWidth) * pDock->fAlign;
1001 x2 = x1 + myDocksParam.iZoneWidth;
1002 if (x < x1 || x > x2)
1003 break;
1004 bShow = TRUE;
1005 break;
1006 }
1007 if (! bShow)
1008 {
1009 if (pDock->iSidUnhideDelayed != 0)
1010 {
1011 g_source_remove (pDock->iSidUnhideDelayed);
1012 pDock->iSidUnhideDelayed = 0;
1013 }
1014 return;
1015 }
1016
1017 //\________________ On montre ou on programme le montrage du dock.
1018 int nx, ny; // normal vector to the screen edge.
1019 double cost; // cos (teta), where teta = angle between mouse vector and dock's normal
1020 double f = 1.; // delay factor
1021 if (pDock->container.bIsHorizontal)
1022 {
1023 nx = 0;
1024 ny = (pDock->container.bDirectionUp ? -1 : 1);
1025 }
1026 else
1027 {
1028 ny = 0;
1029 nx = (pDock->container.bDirectionUp ? -1 : 1);
1030 }
1031 cost = nx * pMouse->dx + ny * pMouse->dy;
1032 f = 2 + cost; // so if cost = -1, we arrive straight onto the screen edge, and f = 1, => normal delay. if cost = 0, f = 2 and we have a bigger delay.
1033
1034 int iDelay = f * myDocksParam.iUnhideDockDelay;
1035 //g_print (" dock will be shown in %dms (%.2f, %d)\n", iDelay, f, pDock->bIsMainDock);
1036 if (iDelay != 0) // on programme une apparition.
1037 {
1038 if (pDock->iSidUnhideDelayed == 0)
1039 pDock->iSidUnhideDelayed = g_timeout_add (iDelay, (GSourceFunc) _cairo_dock_unhide_dock_delayed, (gpointer) pDock);
1040 }
1041 else // on montre le dock tout de suite.
1042 {
1043 _cairo_dock_unhide_dock_delayed (pDock);
1044 }
1045 }
1046
_cairo_dock_poll_screen_edge(G_GNUC_UNUSED gpointer data)1047 static gboolean _cairo_dock_poll_screen_edge (G_GNUC_UNUSED gpointer data) // thanks to Smidgey for the pop-up patch !
1048 {
1049 static CDMousePolling mouse;
1050
1051 mouse.bUpToDate = FALSE; // mouse position will be updated by the first hidden dock.
1052 g_list_foreach (s_pRootDockList, (GFunc) _cairo_dock_unhide_root_dock_on_mouse_hit, &mouse);
1053
1054 return TRUE;
1055 }
_start_polling_screen_edge(void)1056 static void _start_polling_screen_edge (void)
1057 {
1058 s_iNbPolls ++;
1059 cd_debug ("%s (%d)", __func__, s_iNbPolls);
1060 if (s_iSidPollScreenEdge == 0)
1061 s_iSidPollScreenEdge = g_timeout_add (MOUSE_POLLING_DT, (GSourceFunc) _cairo_dock_poll_screen_edge, NULL);
1062 }
1063
_stop_polling_screen_edge_now(void)1064 static void _stop_polling_screen_edge_now (void)
1065 {
1066 if (s_iSidPollScreenEdge != 0)
1067 {
1068 g_source_remove (s_iSidPollScreenEdge);
1069 s_iSidPollScreenEdge = 0;
1070 }
1071 s_iNbPolls = 0;
1072 }
_stop_polling_screen_edge(void)1073 static void _stop_polling_screen_edge (void)
1074 {
1075 cd_debug ("%s (%d)", __func__, s_iNbPolls);
1076 s_iNbPolls --;
1077 if (s_iNbPolls <= 0)
1078 {
1079 _stop_polling_screen_edge_now (); // remet tout a 0.
1080 }
1081 }
1082
gldi_dock_set_visibility(CairoDock * pDock,CairoDockVisibility iVisibility)1083 void gldi_dock_set_visibility (CairoDock *pDock, CairoDockVisibility iVisibility)
1084 {
1085 //\_______________ jeu de parametres.
1086 gboolean bReserveSpace = (iVisibility == CAIRO_DOCK_VISI_RESERVE);
1087 gboolean bKeepBelow = (iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW);
1088 gboolean bAutoHideOnOverlap = (iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP);
1089 gboolean bAutoHideOnAnyOverlap = (iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY);
1090 gboolean bAutoHide = (iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE);
1091 gboolean bShortKey = (iVisibility == CAIRO_DOCK_VISI_SHORTKEY);
1092
1093 gboolean bReserveSpace0 = (pDock->iVisibility == CAIRO_DOCK_VISI_RESERVE);
1094 gboolean bKeepBelow0 = (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW);
1095 gboolean bAutoHideOnOverlap0 = (pDock->iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP);
1096 gboolean bAutoHideOnAnyOverlap0 = (pDock->iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY);
1097 gboolean bAutoHide0 = (pDock->iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE);
1098 gboolean bShortKey0 = (pDock->iVisibility == CAIRO_DOCK_VISI_SHORTKEY);
1099
1100 pDock->iVisibility = iVisibility;
1101
1102 //\_______________ changement dans le Reserve Space.
1103 if (bReserveSpace != bReserveSpace0)
1104 cairo_dock_reserve_space_for_dock (pDock, bReserveSpace);
1105
1106 //\_______________ changement dans le Keep below.
1107 if (bKeepBelow != bKeepBelow0)
1108 {
1109 if (bKeepBelow)
1110 cairo_dock_pop_down (pDock);
1111 else
1112 cairo_dock_pop_up (pDock);
1113 }
1114
1115 //\_______________ changement dans l'Auto-Hide
1116 if (bAutoHideOnOverlap != bAutoHideOnOverlap0 ||
1117 bAutoHideOnAnyOverlap != bAutoHideOnAnyOverlap0 ||
1118 bAutoHide != bAutoHide0)
1119 {
1120 if (bAutoHide)
1121 {
1122 pDock->bTemporaryHidden = FALSE;
1123 pDock->bAutoHide = TRUE;
1124 cairo_dock_start_hiding (pDock);
1125 }
1126 else if (bAutoHideOnAnyOverlap)
1127 {
1128 pDock->bTemporaryHidden = pDock->bAutoHide; // needed to use the following function
1129 gldi_dock_hide_if_any_window_overlap_or_show (pDock);
1130 }
1131 else
1132 {
1133 if (! bAutoHideOnOverlap)
1134 {
1135 pDock->bTemporaryHidden = FALSE;
1136 pDock->bAutoHide = FALSE;
1137 cairo_dock_start_showing (pDock);
1138 }
1139 if (bAutoHideOnOverlap)
1140 {
1141 pDock->bTemporaryHidden = pDock->bAutoHide; // needed to use the following function
1142 gldi_dock_hide_show_if_current_window_is_on_our_way (pDock);
1143 }
1144 }
1145 }
1146
1147 //\_______________ shortkey
1148 if (pDock->bIsMainDock)
1149 {
1150 if (bShortKey) // option is enabled.
1151 {
1152 if (s_pPopupBinding && gldi_shortkey_could_grab (s_pPopupBinding)) // a shortkey has been registered and grabbed to show/hide the dock => hide the dock.
1153 {
1154 gtk_widget_hide (pDock->container.pWidget);
1155 }
1156 else // bind couldn't be done (no shortkey or couldn't grab it).
1157 {
1158 // g_print ("bind couldn't be done (no shortkey or couldn't grab it).\n");
1159 pDock->iVisibility = CAIRO_DOCK_VISI_KEEP_ABOVE;
1160 }
1161 }
1162 else if (bShortKey0) // option is now disabled => show the dock.
1163 {
1164 _reposition_root_docks (FALSE); // FALSE => tous.
1165 }
1166 }
1167
1168 //\_______________ on arrete/demarre la scrutation des bords.
1169 gboolean bIsPolling = (bAutoHide0 || bAutoHideOnOverlap0 || bAutoHideOnAnyOverlap0 || bKeepBelow0);
1170 gboolean bShouldPoll = (bAutoHide || bAutoHideOnOverlap || bAutoHideOnAnyOverlap || bKeepBelow);
1171 if (bIsPolling && ! bShouldPoll)
1172 _stop_polling_screen_edge ();
1173 else if (!bIsPolling && bShouldPoll)
1174 _start_polling_screen_edge ();
1175 }
1176
1177
1178 /////////////////
1179 /// CALLBACKS ///
1180 /////////////////
1181
_autohide_after_shortkey(CairoDock * pDock)1182 static gboolean _autohide_after_shortkey (CairoDock *pDock)
1183 {
1184 if (pDock->iVisibility == CAIRO_DOCK_VISI_SHORTKEY && gldi_container_is_visible (CAIRO_CONTAINER (pDock)) && ! pDock->container.bInside)
1185 gtk_widget_hide (pDock->container.pWidget);
1186 pDock->iSidHideBack = 0;
1187 return FALSE;
1188 }
_show_dock_at_mouse(CairoDock * pDock,G_GNUC_UNUSED gpointer data)1189 static void _show_dock_at_mouse (CairoDock *pDock, G_GNUC_UNUSED gpointer data)
1190 {
1191 if (pDock->iVisibility != CAIRO_DOCK_VISI_SHORTKEY)
1192 return;
1193
1194 if (gldi_container_is_visible (CAIRO_CONTAINER (pDock))) // already visible -> hide (toggle)
1195 {
1196 gtk_widget_hide (pDock->container.pWidget);
1197 }
1198 else // invisible -> show
1199 {
1200 // calculate the position where the dock will be shown (under the mouse)
1201 gldi_container_update_mouse_position (CAIRO_CONTAINER (pDock));
1202
1203 int W = gldi_dock_get_screen_width (pDock), H = gldi_dock_get_screen_height (pDock);
1204 int iScreenOffsetX = gldi_dock_get_screen_offset_x (pDock), iScreenOffsetY = gldi_dock_get_screen_offset_y (pDock);
1205 ///pDock->iGapX = pDock->container.iWindowPositionX + iMouseX - g_desktopGeometry.iScreenWidth[pDock->container.bIsHorizontal] * pDock->fAlign;
1206 ///pDock->iGapY = (pDock->container.bDirectionUp ? g_desktopGeometry.iScreenHeight[pDock->container.bIsHorizontal] - (pDock->container.iWindowPositionY + iMouseY) : pDock->container.iWindowPositionY + iMouseY);
1207 pDock->iGapX = pDock->container.iWindowPositionX + pDock->container.iMouseX - (W - pDock->container.iWidth) * pDock->fAlign - pDock->container.iWidth/2 - iScreenOffsetX;
1208 pDock->iGapY = (pDock->container.bDirectionUp ? H - (pDock->container.iWindowPositionY + pDock->container.iMouseY) : pDock->container.iWindowPositionY + pDock->container.iMouseY) - iScreenOffsetY;
1209 cd_debug (" => %d;%d", g_pMainDock->iGapX, g_pMainDock->iGapY);
1210
1211 int iNewPositionX, iNewPositionY;
1212 cairo_dock_get_window_position_at_balance (pDock,
1213 pDock->container.iWidth, pDock->container.iHeight,
1214 &iNewPositionX, &iNewPositionY);
1215 cd_debug (" ==> %d;%d", iNewPositionX, iNewPositionY);
1216 if (iNewPositionX < 0)
1217 iNewPositionX = 0;
1218 else if (iNewPositionX + pDock->container.iWidth > W)
1219 iNewPositionX = W - pDock->container.iWidth;
1220
1221 if (iNewPositionY < 0)
1222 iNewPositionY = 0;
1223 else if (iNewPositionY + pDock->container.iHeight > H)
1224 iNewPositionY = H - pDock->container.iHeight;
1225
1226 // show the dock
1227 gtk_window_move (GTK_WINDOW (pDock->container.pWidget),
1228 (pDock->container.bIsHorizontal ? iNewPositionX : iNewPositionY),
1229 (pDock->container.bIsHorizontal ? iNewPositionY : iNewPositionX));
1230 gtk_widget_show (pDock->container.pWidget);
1231
1232 // schedule a hiding in a few seconds
1233 if (pDock->iSidHideBack != 0)
1234 g_source_remove (pDock->iSidHideBack);
1235 pDock->iSidHideBack = g_timeout_add (3000, (GSourceFunc) _autohide_after_shortkey, (gpointer) pDock);
1236 }
1237 }
_raise_from_shortcut(G_GNUC_UNUSED const char * cKeyShortcut,G_GNUC_UNUSED gpointer data)1238 static void _raise_from_shortcut (G_GNUC_UNUSED const char *cKeyShortcut, G_GNUC_UNUSED gpointer data)
1239 {
1240 // g_print ("shortkey\n");
1241 gldi_docks_foreach_root ((GFunc)_show_dock_at_mouse, NULL);
1242 }
1243
_on_screen_geometry_changed(G_GNUC_UNUSED gpointer data,gboolean bSizeHasChanged)1244 static gboolean _on_screen_geometry_changed (G_GNUC_UNUSED gpointer data, gboolean bSizeHasChanged)
1245 {
1246 if (bSizeHasChanged)
1247 _reposition_root_docks (FALSE); // FALSE <=> main dock included
1248 return GLDI_NOTIFICATION_LET_PASS;
1249 }
1250
_on_new_dialog(G_GNUC_UNUSED gpointer data,CairoDialog * pDialog)1251 static gboolean _on_new_dialog (G_GNUC_UNUSED gpointer data, CairoDialog *pDialog)
1252 {
1253 //\________________ hide sub-dock or label that would overlap it
1254 Icon *pIcon = pDialog->pIcon;
1255 if (! pIcon)
1256 return GLDI_NOTIFICATION_LET_PASS;
1257
1258 if (pIcon->pSubDock) // un sous-dock par-dessus le dialogue est tres genant.
1259 {
1260 cairo_dock_emit_leave_signal (CAIRO_CONTAINER (pIcon->pSubDock));
1261 }
1262
1263 GldiContainer *pContainer = cairo_dock_get_icon_container (pIcon);
1264 if (CAIRO_DOCK_IS_DOCK (pContainer) && cairo_dock_get_icon_max_scale (pIcon) < 1.01) // view without zoom, the dialog is stuck to the icon, and therefore is under the label, so hide this one.
1265 {
1266 if (pIcon->iHideLabel == 0)
1267 gtk_widget_queue_draw (pContainer->pWidget);
1268 pIcon->iHideLabel ++;
1269 }
1270
1271 return GLDI_NOTIFICATION_LET_PASS;
1272 }
1273
_render_dock_notification(G_GNUC_UNUSED gpointer pUserData,CairoDock * pDock,cairo_t * pCairoContext)1274 static gboolean _render_dock_notification (G_GNUC_UNUSED gpointer pUserData, CairoDock *pDock, cairo_t *pCairoContext)
1275 {
1276 if (pCairoContext) // cairo
1277 {
1278 if (pDock->fHideOffset != 0 && g_pHidingBackend != NULL && g_pHidingBackend->pre_render)
1279 g_pHidingBackend->pre_render (pDock, pDock->fHideOffset, pCairoContext);
1280
1281 if (pDock->iFadeCounter != 0 && g_pKeepingBelowBackend != NULL && g_pKeepingBelowBackend->pre_render)
1282 g_pKeepingBelowBackend->pre_render (pDock, (double) pDock->iFadeCounter / myBackendsParam.iHideNbSteps, pCairoContext);
1283
1284 /// TODO: see if it's ok to not use the optimized rendering any more...
1285 /// if not, we can probably get the clip on the cairo context
1286 pDock->pRenderer->render (pCairoContext, pDock);
1287
1288 if (pDock->fHideOffset != 0 && g_pHidingBackend != NULL && g_pHidingBackend->post_render)
1289 g_pHidingBackend->post_render (pDock, pDock->fHideOffset, pCairoContext);
1290
1291 if (pDock->iFadeCounter != 0 && g_pKeepingBelowBackend != NULL && g_pKeepingBelowBackend->post_render)
1292 g_pKeepingBelowBackend->post_render (pDock, (double) pDock->iFadeCounter / myBackendsParam.iHideNbSteps, pCairoContext);
1293 }
1294 else // opengl
1295 {
1296 if (pDock->fHideOffset != 0 && g_pHidingBackend != NULL && g_pHidingBackend->pre_render_opengl)
1297 g_pHidingBackend->pre_render_opengl (pDock, pDock->fHideOffset);
1298
1299 if (pDock->iFadeCounter != 0 && g_pKeepingBelowBackend != NULL && g_pKeepingBelowBackend->pre_render_opengl)
1300 g_pKeepingBelowBackend->pre_render_opengl (pDock, (double) pDock->iFadeCounter / myBackendsParam.iHideNbSteps);
1301
1302 pDock->pRenderer->render_opengl (pDock);
1303
1304 if (pDock->fHideOffset != 0 && g_pHidingBackend != NULL && g_pHidingBackend->post_render_opengl)
1305 g_pHidingBackend->post_render_opengl (pDock, pDock->fHideOffset);
1306
1307 if (pDock->iFadeCounter != 0 && g_pKeepingBelowBackend != NULL && g_pKeepingBelowBackend->post_render_opengl)
1308 g_pKeepingBelowBackend->post_render_opengl (pDock, (double) pDock->iFadeCounter / myBackendsParam.iHideNbSteps);
1309 }
1310 return GLDI_NOTIFICATION_LET_PASS;
1311 }
1312
_on_leave_dock(G_GNUC_UNUSED gpointer data,CairoDock * pDock,G_GNUC_UNUSED gboolean * bStartAnimation)1313 static gboolean _on_leave_dock (G_GNUC_UNUSED gpointer data, CairoDock *pDock, G_GNUC_UNUSED gboolean *bStartAnimation)
1314 {
1315 //g_print ("%s (%d, %d)\n", __func__, pDock->iRefCount, pDock->bHasModalWindow);
1316
1317 //\_______________ On lance l'animation du dock.
1318 if (pDock->iRefCount == 0)
1319 {
1320 //g_print ("%s (auto-hide:%d)\n", __func__, pDock->bAutoHide);
1321 if (pDock->bAutoHide)
1322 {
1323 ///pDock->fFoldingFactor = (myBackendsParam.bAnimateOnAutoHide ? 0.001 : 0.);
1324 cairo_dock_start_hiding (pDock);
1325 }
1326 }
1327 else if (pDock->icons != NULL)
1328 {
1329 pDock->fFoldingFactor = (myDocksParam.bAnimateSubDock ? 0.001 : 0.);
1330 Icon *pIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
1331 //g_print ("'%s' se replie\n", pIcon?pIcon->cName:"none");
1332 gldi_object_notify (pIcon, NOTIFICATION_UNFOLD_SUBDOCK, pIcon);
1333 }
1334 //g_print ("start shrinking\n");
1335 cairo_dock_start_shrinking (pDock); // on commence a faire diminuer la taille des icones.
1336 return GLDI_NOTIFICATION_LET_PASS;
1337 }
1338
_update_removing_inserting_icon_size(Icon * icon)1339 static void _update_removing_inserting_icon_size (Icon *icon)
1340 {
1341 icon->fInsertRemoveFactor *= .85;
1342 if (icon->fInsertRemoveFactor > 0)
1343 {
1344 if (icon->fInsertRemoveFactor < 0.05)
1345 icon->fInsertRemoveFactor = 0.05;
1346 }
1347 else if (icon->fInsertRemoveFactor < 0)
1348 {
1349 if (icon->fInsertRemoveFactor > -0.05)
1350 icon->fInsertRemoveFactor = -0.05;
1351 }
1352 }
1353
on_update_inserting_removing_icon(G_GNUC_UNUSED gpointer pUserData,Icon * pIcon,CairoDock * pDock,gboolean * bContinueAnimation)1354 static gboolean on_update_inserting_removing_icon (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, CairoDock *pDock, gboolean *bContinueAnimation)
1355 {
1356 if (pIcon->iGlideDirection != 0)
1357 {
1358 pIcon->fGlideOffset += pIcon->iGlideDirection * .1;
1359 if (fabs (pIcon->fGlideOffset) > .99)
1360 {
1361 pIcon->fGlideOffset = pIcon->iGlideDirection;
1362 pIcon->iGlideDirection = 0;
1363 }
1364 else if (fabs (pIcon->fGlideOffset) < .01)
1365 {
1366 pIcon->fGlideOffset = 0;
1367 pIcon->iGlideDirection = 0;
1368 }
1369 *bContinueAnimation = TRUE;
1370 cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
1371 }
1372
1373 if (pIcon->fInsertRemoveFactor != 0) // the icon is being inserted/removed
1374 {
1375 _update_removing_inserting_icon_size (pIcon);
1376 if (fabs (pIcon->fInsertRemoveFactor) > 0.05) // the animation is not yet finished
1377 {
1378 cairo_dock_mark_icon_as_inserting_removing (pIcon);
1379 *bContinueAnimation = TRUE;
1380 }
1381 cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
1382 }
1383 return GLDI_NOTIFICATION_LET_PASS;
1384 }
1385
on_insert_remove_icon(G_GNUC_UNUSED gpointer pUserData,Icon * pIcon,G_GNUC_UNUSED CairoDock * pDock)1386 static gboolean on_insert_remove_icon (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon, G_GNUC_UNUSED CairoDock *pDock)
1387 {
1388 if (pIcon->fInsertRemoveFactor == 0) // animation not needed.
1389 return GLDI_NOTIFICATION_LET_PASS;
1390
1391 cairo_dock_mark_icon_as_inserting_removing (pIcon); // On prend en charge le dessin de l'icone pendant sa phase d'insertion/suppression.
1392
1393 return GLDI_NOTIFICATION_LET_PASS;
1394 }
1395
on_stop_inserting_removing_icon(G_GNUC_UNUSED gpointer pUserData,Icon * pIcon)1396 static gboolean on_stop_inserting_removing_icon (G_GNUC_UNUSED gpointer pUserData, Icon *pIcon)
1397 {
1398 pIcon->fGlideOffset = 0;
1399 pIcon->iGlideDirection = 0;
1400 return GLDI_NOTIFICATION_LET_PASS;
1401 }
1402
1403
1404 //////////////////
1405 /// GET CONFIG ///
1406 //////////////////
1407
get_config(GKeyFile * pKeyFile,CairoDocksParam * pDocksParam)1408 static gboolean get_config (GKeyFile *pKeyFile, CairoDocksParam *pDocksParam)
1409 {
1410 gboolean bFlushConfFileNeeded = FALSE;
1411
1412 CairoDocksParam *pBackground = pDocksParam;
1413 CairoDocksParam *pPosition = pDocksParam;
1414 CairoDocksParam *pAccessibility = pDocksParam;
1415 CairoDocksParam *pSystem = pDocksParam;
1416
1417 // frame
1418 pBackground->iDockRadius = cairo_dock_get_integer_key_value (pKeyFile, "Background", "corner radius", &bFlushConfFileNeeded, 12, NULL, NULL);
1419
1420 pBackground->iDockLineWidth = cairo_dock_get_integer_key_value (pKeyFile, "Background", "line width", &bFlushConfFileNeeded, 2, NULL, NULL);
1421
1422 pBackground->iFrameMargin = cairo_dock_get_integer_key_value (pKeyFile, "Background", "frame margin", &bFlushConfFileNeeded, 2, NULL, NULL);
1423
1424 GldiColor couleur = {{0., 0., 0.6, 0.4}};
1425 cairo_dock_get_color_key_value (pKeyFile, "Background", "line color", &bFlushConfFileNeeded, &pBackground->fLineColor, &couleur, NULL, NULL);
1426
1427 pBackground->bRoundedBottomCorner = cairo_dock_get_boolean_key_value (pKeyFile, "Background", "rounded bottom corner", &bFlushConfFileNeeded, TRUE, NULL, NULL);
1428
1429 // background image
1430 int iStyle = cairo_dock_get_integer_key_value (pKeyFile, "Background", "style", &bFlushConfFileNeeded, -1, NULL, NULL); // -1 pour intercepter le cas ou la cle n'existe pas.
1431 if (iStyle == -1) // old params < 3.4
1432 {
1433 iStyle = g_key_file_get_integer (pKeyFile, "Background", "fill bg", NULL);
1434 iStyle ++;
1435 g_key_file_set_integer (pKeyFile, "Background", "style", iStyle);
1436 }
1437
1438 if (iStyle == 0)
1439 {
1440 pBackground->bUseDefaultColors = TRUE;
1441 pBackground->iDockRadius = myStyleParam.iCornerRadius;
1442 pBackground->iDockLineWidth = myStyleParam.iLineWidth;
1443 }
1444 else if (iStyle == 1)
1445 {
1446 gchar *cBgImage = (iStyle == 1 ? cairo_dock_get_string_key_value (pKeyFile, "Background", "background image", &bFlushConfFileNeeded, NULL, NULL, NULL) : NULL);
1447 if (cBgImage != NULL)
1448 {
1449 pBackground->cBackgroundImageFile = cairo_dock_search_image_s_path (cBgImage);
1450 g_free (cBgImage);
1451 pBackground->fBackgroundImageAlpha = cairo_dock_get_double_key_value (pKeyFile, "Background", "image alpha", &bFlushConfFileNeeded, 0.5, NULL, NULL);
1452 pBackground->bBackgroundImageRepeat = cairo_dock_get_boolean_key_value (pKeyFile, "Background", "repeat image", &bFlushConfFileNeeded, FALSE, NULL, NULL);
1453 }
1454 }
1455
1456 // background gradation
1457 if (iStyle != 0 && pBackground->cBackgroundImageFile == NULL)
1458 {
1459 pBackground->iNbStripes = cairo_dock_get_integer_key_value (pKeyFile, "Background", "number of stripes", &bFlushConfFileNeeded, 10, NULL, NULL);
1460
1461 if (pBackground->iNbStripes != 0)
1462 {
1463 pBackground->fStripesWidth = MAX (.01, MIN (.99, cairo_dock_get_double_key_value (pKeyFile, "Background", "stripes width", &bFlushConfFileNeeded, 0.2, NULL, NULL))) / pBackground->iNbStripes;
1464 }
1465 GldiColor couleur3 = {{.7, .7, 1., .7}};
1466 cairo_dock_get_color_key_value (pKeyFile, "Background", "stripes color dark", &bFlushConfFileNeeded, &pBackground->fStripesColorDark, &couleur3, NULL, NULL);
1467
1468 GldiColor couleur2 = {{.7, .9, .7, .4}};
1469 cairo_dock_get_color_key_value (pKeyFile, "Background", "stripes color bright", &bFlushConfFileNeeded, &pBackground->fStripesColorBright, &couleur2, NULL, NULL);
1470
1471 pBackground->fStripesAngle = cairo_dock_get_double_key_value (pKeyFile, "Background", "stripes angle", &bFlushConfFileNeeded, 90., NULL, NULL);
1472 }
1473
1474 pAccessibility->bExtendedMode = cairo_dock_get_boolean_key_value (pKeyFile, "Background", "extended", &bFlushConfFileNeeded, FALSE, "Accessibility", NULL);
1475
1476 // hidden bg
1477 GldiColor hcolor = {{.8, .8, .8, .5}};
1478 cairo_dock_get_color_key_value (pKeyFile, "Background", "hidden bg color", &bFlushConfFileNeeded, &pBackground->fHiddenBg, &hcolor, NULL, NULL);
1479
1480 // position
1481 pPosition->iGapX = cairo_dock_get_integer_key_value (pKeyFile, "Position", "x gap", &bFlushConfFileNeeded, 0, NULL, NULL);
1482 pPosition->iGapY = cairo_dock_get_integer_key_value (pKeyFile, "Position", "y gap", &bFlushConfFileNeeded, 0, NULL, NULL);
1483
1484 pPosition->iScreenBorder = cairo_dock_get_integer_key_value (pKeyFile, "Position", "screen border", &bFlushConfFileNeeded, 0, NULL, NULL);
1485 if (pPosition->iScreenBorder >= CAIRO_DOCK_NB_POSITIONS)
1486 pPosition->iScreenBorder = 0;
1487
1488 pPosition->fAlign = cairo_dock_get_double_key_value (pKeyFile, "Position", "alignment", &bFlushConfFileNeeded, 0.5, NULL, NULL);
1489
1490 pPosition->iNumScreen = cairo_dock_get_integer_key_value (pKeyFile, "Position", "num_screen", &bFlushConfFileNeeded, GLDI_DEFAULT_SCREEN, NULL, NULL); // Note: if this screen doesn't exist at this time, we keep this number anyway, in case it is plugged later. Until then, it will point on the X screen.
1491 if (g_key_file_has_key (pKeyFile, "Position", "xinerama", NULL)) // "xinerama" and "num screen" old keys
1492 {
1493 if (g_key_file_get_boolean (pKeyFile," Position", "xinerama", NULL)) // xinerama was used -> set num-screen back
1494 {
1495 pPosition->iNumScreen = g_key_file_get_integer (pKeyFile, "Position", "num screen", NULL); // "num screen" was the old key
1496 g_key_file_set_integer (pKeyFile, "Position", "num_screen", pPosition->iNumScreen);
1497 }
1498 }
1499
1500 //\____________________ Visibilite
1501 int iVisibility = cairo_dock_get_integer_key_value (pKeyFile, "Accessibility", "visibility", &bFlushConfFileNeeded, -1, NULL, NULL); // -1 pour pouvoir intercepter le cas ou la cle n'existe pas.
1502
1503 gchar *cShortkey = cairo_dock_get_string_key_value (pKeyFile, "Accessibility", "raise shortcut", &bFlushConfFileNeeded, NULL, "Position", NULL);
1504
1505 pAccessibility->cHideEffect = cairo_dock_get_string_key_value (pKeyFile, "Accessibility", "hide effect", &bFlushConfFileNeeded, NULL, NULL, NULL);
1506
1507 if (iVisibility == -1) // option nouvelle 2.1.3
1508 {
1509 if (g_key_file_get_boolean (pKeyFile, "Accessibility", "reserve space", NULL))
1510 iVisibility = CAIRO_DOCK_VISI_KEEP_ABOVE;
1511 else if (g_key_file_get_boolean (pKeyFile, "Accessibility", "pop-up", NULL)) // on force au nouveau mode.
1512 {
1513 iVisibility = CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY;
1514 pAccessibility->cHideEffect = g_strdup_printf ("Fade out"); // on force a "fade out" pour garder le meme effet.
1515 g_key_file_set_string (pKeyFile, "Accessibility", "hide effect", pAccessibility->cHideEffect);
1516 }
1517 else if (g_key_file_get_boolean (pKeyFile, "Accessibility", "auto-hide", NULL))
1518 iVisibility = CAIRO_DOCK_VISI_AUTO_HIDE;
1519 else if (g_key_file_get_boolean (pKeyFile, "Accessibility", "auto quick hide on max", NULL))
1520 iVisibility = CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY;
1521 else if (cShortkey)
1522 {
1523 iVisibility = CAIRO_DOCK_VISI_SHORTKEY;
1524 pAccessibility->cRaiseDockShortcut = cShortkey;
1525 cShortkey = NULL;
1526 }
1527 else
1528 iVisibility = CAIRO_DOCK_VISI_KEEP_ABOVE;
1529
1530 g_key_file_set_integer (pKeyFile, "Accessibility", "visibility", iVisibility);
1531 }
1532 else
1533 {
1534 if (pAccessibility->cHideEffect == NULL) // nouvelle option 2.2.0, cela a change l'ordre du menu.
1535 {
1536 // avant c'etait : KEEP_ABOVE, RESERVE, KEEP_BELOW, AUTO_HIDE, HIDE_ON_MAXIMIZED, SHORTKEY
1537 // mtn c'est : KEEP_ABOVE, RESERVE, KEEP_BELOW, HIDE_ON_OVERLAP, HIDE_ON_OVERLAP_ANY, AUTO_HIDE, VISI_SHORTKEY,
1538 if (iVisibility == 2) // on force au nouveau mode.
1539 {
1540 iVisibility = CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY;
1541 pAccessibility->cHideEffect = g_strdup_printf ("Fade out"); // on force a "fade out" pour garder le meme effet.
1542 g_key_file_set_integer (pKeyFile, "Accessibility", "visibility", iVisibility);
1543 g_key_file_set_string (pKeyFile, "Accessibility", "hide effect", pAccessibility->cHideEffect);
1544 }
1545 else if (iVisibility == 3)
1546 {
1547 iVisibility = CAIRO_DOCK_VISI_AUTO_HIDE;
1548 g_key_file_set_integer (pKeyFile, "Accessibility", "visibility", iVisibility);
1549 }
1550 else if (iVisibility == 4)
1551 {
1552 iVisibility = CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY;
1553 g_key_file_set_integer (pKeyFile, "Accessibility", "visibility", iVisibility);
1554 }
1555 else if (iVisibility == 5)
1556 {
1557 iVisibility = CAIRO_DOCK_VISI_SHORTKEY;
1558 g_key_file_set_integer (pKeyFile, "Accessibility", "visibility", iVisibility);
1559 }
1560 }
1561 if (iVisibility == CAIRO_DOCK_VISI_SHORTKEY)
1562 {
1563 pAccessibility->cRaiseDockShortcut = cShortkey;
1564 cShortkey = NULL;
1565 }
1566 }
1567 pAccessibility->iVisibility = iVisibility;
1568 g_free (cShortkey);
1569 if (pAccessibility->cHideEffect == NULL)
1570 {
1571 pAccessibility->cHideEffect = g_strdup_printf ("Move down");
1572 g_key_file_set_string (pKeyFile, "Accessibility", "hide effect", pAccessibility->cHideEffect);
1573 }
1574
1575 pAccessibility->iCallbackMethod = cairo_dock_get_integer_key_value (pKeyFile, "Accessibility", "callback", &bFlushConfFileNeeded, CAIRO_HIT_DOCK_PLACE, NULL, NULL);
1576
1577 if (pAccessibility->iCallbackMethod == CAIRO_HIT_ZONE)
1578 {
1579 if (! g_key_file_has_key (pKeyFile, "Accessibility", "zone size", NULL))
1580 {
1581 pAccessibility->iZoneWidth = 100;
1582 pAccessibility->iZoneHeight = 10;
1583 int list[2] = {pAccessibility->iZoneWidth, pAccessibility->iZoneHeight};
1584 g_key_file_set_integer_list (pKeyFile, "Accessibility", "zone size", list, 2);
1585 }
1586 cairo_dock_get_size_key_value_helper (pKeyFile, "Accessibility", "zone ", bFlushConfFileNeeded, pAccessibility->iZoneWidth, pAccessibility->iZoneHeight);
1587 if (pAccessibility->iZoneWidth < 20)
1588 pAccessibility->iZoneWidth = 20;
1589 if (pAccessibility->iZoneHeight < 2)
1590 pAccessibility->iZoneHeight = 2;
1591 pAccessibility->cZoneImage = cairo_dock_get_string_key_value (pKeyFile, "Accessibility", "callback image", &bFlushConfFileNeeded, 0, "Background", NULL);
1592 pAccessibility->fZoneAlpha = 1.; // on laisse l'utilisateur definir la transparence qu'il souhaite directement dans l'image.
1593 }
1594
1595 //\____________________ Autres parametres.
1596 double fSensitivity = cairo_dock_get_double_key_value (pKeyFile, "Accessibility", "edge sensitivity", &bFlushConfFileNeeded, -1, NULL, NULL); // replace "unhide delay"
1597 if (fSensitivity < 0) // old param
1598 {
1599 int iUnhideDockDelay = g_key_file_get_integer (pKeyFile, "Accessibility", "unhide delay", NULL);
1600 fSensitivity = iUnhideDockDelay / 1500.; // 0 -> 0 = sensitive, 1500 -> 1 = not sensitive
1601 g_key_file_set_double (pKeyFile, "Accessibility", "edge sensitivity", fSensitivity);
1602 }
1603 pAccessibility->iUnhideDockDelay = fSensitivity * 1000; // so we decreased the old delay by 1.5, since we handle mouse movements better.
1604
1605 //\____________________ sous-docks.
1606 pAccessibility->iLeaveSubDockDelay = cairo_dock_get_integer_key_value (pKeyFile, "Accessibility", "leaving delay", &bFlushConfFileNeeded, 330, "System", NULL);
1607 pAccessibility->iShowSubDockDelay = cairo_dock_get_integer_key_value (pKeyFile, "Accessibility", "show delay", &bFlushConfFileNeeded, 300, "System", NULL);
1608 if (!g_key_file_has_key (pKeyFile, "Accessibility", "show_on_click", NULL))
1609 {
1610 pAccessibility->bShowSubDockOnClick = cairo_dock_get_boolean_key_value (pKeyFile, "Accessibility", "show on click", &bFlushConfFileNeeded, FALSE, "System", NULL);
1611 g_key_file_set_integer (pKeyFile, "Accessibility", "show_on_click", pAccessibility->bShowSubDockOnClick ? 1 : 0);
1612 bFlushConfFileNeeded = TRUE;
1613 }
1614 else
1615 pAccessibility->bShowSubDockOnClick = (cairo_dock_get_integer_key_value (pKeyFile, "Accessibility", "show_on_click", &bFlushConfFileNeeded, 0, NULL, NULL) == 1);
1616
1617 //\____________________ lock
1618 ///pAccessibility->bLockAll = cairo_dock_get_boolean_key_value (pKeyFile, "Accessibility", "lock all", &bFlushConfFileNeeded, FALSE, NULL, NULL);
1619 pAccessibility->bLockIcons = pAccessibility->bLockAll || cairo_dock_get_boolean_key_value (pKeyFile, "Accessibility", "lock icons", &bFlushConfFileNeeded, FALSE, NULL, NULL);
1620
1621 // system
1622 pSystem->bAnimateSubDock = cairo_dock_get_boolean_key_value (pKeyFile, "System", "animate subdocks", &bFlushConfFileNeeded, TRUE, "Sub-Docks", NULL);
1623
1624 return bFlushConfFileNeeded;
1625 }
1626
1627
1628 ////////////////////
1629 /// RESET CONFIG ///
1630 ////////////////////
1631
reset_config(CairoDocksParam * pDocksParam)1632 static void reset_config (CairoDocksParam *pDocksParam)
1633 {
1634 CairoDocksParam *pBackground = pDocksParam;
1635 CairoDocksParam *pAccessibility = pDocksParam;
1636
1637 // background
1638 g_free (pBackground->cBackgroundImageFile);
1639
1640 // accessibility
1641 g_free (pAccessibility->cRaiseDockShortcut);
1642 g_free (pAccessibility->cHideEffect);
1643 g_free (pAccessibility->cZoneImage);
1644 }
1645
1646
1647 ////////////
1648 /// LOAD ///
1649 ////////////
1650
_load_visible_zone(const gchar * cVisibleZoneImageFile,int iVisibleZoneWidth,int iVisibleZoneHeight,double fVisibleZoneAlpha)1651 static void _load_visible_zone (const gchar *cVisibleZoneImageFile, int iVisibleZoneWidth, int iVisibleZoneHeight, double fVisibleZoneAlpha)
1652 {
1653 cairo_dock_unload_image_buffer (&g_pVisibleZoneBuffer);
1654
1655 cairo_dock_load_image_buffer_full (&g_pVisibleZoneBuffer,
1656 cVisibleZoneImageFile,
1657 iVisibleZoneWidth,
1658 iVisibleZoneHeight,
1659 CAIRO_DOCK_FILL_SPACE,
1660 fVisibleZoneAlpha);
1661 }
load(void)1662 static void load (void)
1663 {
1664 _load_visible_zone (myDocksParam.cZoneImage, myDocksParam.iZoneWidth, myDocksParam.iZoneHeight, myDocksParam.fZoneAlpha);
1665
1666 g_pHidingBackend = cairo_dock_get_hiding_effect (myDocksParam.cHideEffect);
1667
1668 if (g_pKeepingBelowBackend == NULL) // pas d'option en config pour ca.
1669 g_pKeepingBelowBackend = cairo_dock_get_hiding_effect ("Fade out");
1670
1671 // the first main dock doesn't have a config file, its parameters are the global ones.
1672 if (g_pMainDock)
1673 {
1674 g_pMainDock->iGapX = myDocksParam.iGapX;
1675 g_pMainDock->iGapY = myDocksParam.iGapY;
1676 g_pMainDock->fAlign = myDocksParam.fAlign;
1677 g_pMainDock->iNumScreen = myDocksParam.iNumScreen;
1678 g_pMainDock->bExtendedMode = myDocksParam.bExtendedMode;
1679
1680 _set_dock_orientation (g_pMainDock, myDocksParam.iScreenBorder);
1681 cairo_dock_move_resize_dock (g_pMainDock);
1682
1683 g_pMainDock->fFlatDockWidth = - myIconsParam.iIconGap; // car on ne le connaissait pas encore au moment de sa creation.
1684
1685 // register a key binding
1686 if (myDocksParam.iVisibility == CAIRO_DOCK_VISI_SHORTKEY) // register a key binding
1687 {
1688 if (s_pPopupBinding == NULL)
1689 {
1690 s_pPopupBinding = gldi_shortkey_new (myDocksParam.cRaiseDockShortcut,
1691 "Cairo-Dock",
1692 _("Pop up the main dock"),
1693 GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON,
1694 g_cConfFile,
1695 "Accessibility",
1696 "raise shortcut",
1697 (CDBindkeyHandler) _raise_from_shortcut,
1698 NULL);
1699 }
1700 else
1701 {
1702 gldi_shortkey_rebind (s_pPopupBinding, myDocksParam.cRaiseDockShortcut, NULL);
1703 }
1704 }
1705
1706 gldi_dock_set_visibility (g_pMainDock, myDocksParam.iVisibility);
1707 }
1708 }
1709
1710
1711 //////////////
1712 /// RELOAD ///
1713 //////////////
1714
_reload_bg(CairoDock * pDock,G_GNUC_UNUSED gpointer data)1715 static void _reload_bg (CairoDock *pDock, G_GNUC_UNUSED gpointer data)
1716 {
1717 pDock->backgroundBuffer.iWidth ++; // force the reload
1718 cairo_dock_trigger_load_dock_background (pDock);
1719 }
_init_hiding(CairoDock * pDock,G_GNUC_UNUSED gpointer data)1720 static void _init_hiding (CairoDock *pDock, G_GNUC_UNUSED gpointer data)
1721 {
1722 if (pDock->bIsShowing || pDock->bIsHiding)
1723 {
1724 g_pHidingBackend->init (pDock);
1725 }
1726 }
reload(CairoDocksParam * pPrevDocksParam,CairoDocksParam * pDocksParam)1727 static void reload (CairoDocksParam *pPrevDocksParam, CairoDocksParam *pDocksParam)
1728 {
1729 CairoDocksParam *pBackground = pDocksParam;
1730 CairoDocksParam *pPosition = pDocksParam;
1731 CairoDocksParam *pAccessibility = pDocksParam;
1732 // CairoDocksParam *pViews = pDocksParam;
1733 // CairoDocksParam *pSystem = pDocksParam;
1734 CairoDocksParam *pPrevBackground = pPrevDocksParam;
1735 CairoDocksParam *pPrevPosition = pPrevDocksParam;
1736 CairoDocksParam *pPrevAccessibility = pPrevDocksParam;
1737 // CairoDocksParam *pPrevViews = pPrevDocksParam;
1738 // CairoDocksParam *pPrevSystem = pPrevDocksParam;
1739 CairoDock *pDock = g_pMainDock;
1740
1741 // background
1742 gldi_docks_foreach_root ((GFunc)_reload_bg, NULL);
1743
1744 // position
1745 pDock->iNumScreen = pPosition->iNumScreen;
1746
1747 if (pPosition->iNumScreen != pPrevPosition->iNumScreen)
1748 {
1749 _reposition_root_docks (TRUE); // on replace tous les docks racines sauf le main dock, puisque c'est fait apres.
1750 }
1751
1752 CairoDockTypeHorizontality bWasHorizontal = pDock->container.bIsHorizontal;
1753 if (pPosition->iScreenBorder != pPrevPosition->iScreenBorder)
1754 {
1755 _set_dock_orientation (pDock, pPosition->iScreenBorder);
1756 cairo_dock_reload_buffers_in_dock (pDock, TRUE, FALSE); // icons may have a different width and height, so changing the orientation will affect them. also, stack-icons may be drawn differently according to the orientation (ex.: box).
1757 }
1758 pDock->bExtendedMode = pBackground->bExtendedMode;
1759 pDock->iGapX = pPosition->iGapX;
1760 pDock->iGapY = pPosition->iGapY;
1761 pDock->fAlign = pPosition->fAlign;
1762
1763 if (pPosition->iNumScreen != pPrevPosition->iNumScreen
1764 || pPosition->iScreenBorder != pPrevPosition->iScreenBorder // if the orientation or the screen has changed, the available size may have changed too
1765 || pPosition->iGapX != pPrevPosition->iGapX
1766 || pPosition->iGapY != pPrevPosition->iGapY)
1767 {
1768 cairo_dock_update_dock_size (pDock);
1769 cairo_dock_move_resize_dock (pDock);
1770 if (bWasHorizontal != pDock->container.bIsHorizontal)
1771 pDock->container.iWidth --; // la taille dans le referentiel du dock ne change pas meme si on change d'horizontalite, par contre la taille de la fenetre change. On introduit donc un biais ici pour forcer le configure-event a faire son travail, sinon ca fausse le redraw.
1772 }
1773 else if (pPosition->fAlign != pPrevPosition->fAlign // need to update the input zone
1774 || pPrevBackground->iDockLineWidth != pBackground->iDockLineWidth // frame size has changed
1775 || pPrevBackground->iFrameMargin != pBackground->iFrameMargin) // idem
1776 {
1777 cairo_dock_update_dock_size (pDock);
1778 }
1779
1780 ///cairo_dock_calculate_dock_icons (pDock);
1781
1782 gldi_docks_redraw_all_root (); // the background is a global parameter
1783
1784 // accessibility
1785 //\_______________ Shortkey.
1786 if (pAccessibility->iVisibility == CAIRO_DOCK_VISI_SHORTKEY)
1787 {
1788 if (s_pPopupBinding == NULL)
1789 {
1790 s_pPopupBinding = gldi_shortkey_new (myDocksParam.cRaiseDockShortcut,
1791 "Cairo-Dock",
1792 _("Pop up the main dock"),
1793 GLDI_SHARE_DATA_DIR"/"CAIRO_DOCK_ICON,
1794 g_cCurrentThemePath,
1795 "Accessibility",
1796 "raise shortcut",
1797 (CDBindkeyHandler) _raise_from_shortcut,
1798 NULL);
1799 }
1800 else
1801 {
1802 gldi_shortkey_rebind (s_pPopupBinding, myDocksParam.cRaiseDockShortcut, NULL);
1803 }
1804 }
1805 else
1806 {
1807 gldi_object_unref (GLDI_OBJECT(s_pPopupBinding));
1808 s_pPopupBinding = NULL;
1809 }
1810
1811 //\_______________ Hiding effect.
1812 if (g_strcmp0 (pAccessibility->cHideEffect, pPrevAccessibility->cHideEffect) != 0)
1813 {
1814 g_pHidingBackend = cairo_dock_get_hiding_effect (pAccessibility->cHideEffect);
1815 if (g_pHidingBackend && g_pHidingBackend->init)
1816 {
1817 gldi_docks_foreach_root ((GFunc)_init_hiding, NULL); // si le dock est en cours d'animation, comme le backend est nouveau, il n'a donc pas ete initialise au debut de l'animation => on le fait ici.
1818 }
1819 }
1820
1821 //\_______________ Callback zone.
1822 if (g_strcmp0 (pAccessibility->cZoneImage, pPrevAccessibility->cZoneImage) != 0
1823 || pAccessibility->iZoneWidth != pPrevAccessibility->iZoneWidth
1824 || pAccessibility->iZoneHeight != pPrevAccessibility->iZoneHeight
1825 || pAccessibility->fZoneAlpha != pPrevAccessibility->fZoneAlpha)
1826 {
1827 _load_visible_zone (pAccessibility->cZoneImage, pAccessibility->iZoneWidth, pAccessibility->iZoneHeight, pAccessibility->fZoneAlpha);
1828
1829 gldi_docks_redraw_all_root ();
1830 }
1831
1832 gldi_dock_set_visibility (pDock, pAccessibility->iVisibility);
1833 }
1834
1835
1836 //////////////
1837 /// UNLOAD ///
1838 //////////////
1839
unload(void)1840 static void unload (void)
1841 {
1842 cairo_dock_unload_image_buffer (&g_pVisibleZoneBuffer);
1843
1844 _stop_polling_screen_edge_now ();
1845 s_bQuickHide = FALSE;
1846
1847 gldi_object_unref (GLDI_OBJECT(s_pPopupBinding));
1848 s_pPopupBinding = NULL;
1849 }
1850
1851
1852 ////////////
1853 /// INIT ///
1854 ////////////
1855
on_style_changed(G_GNUC_UNUSED gpointer data)1856 static gboolean on_style_changed (G_GNUC_UNUSED gpointer data)
1857 {
1858 cd_debug ("Docks: style change to %d", myDocksParam.bUseDefaultColors);
1859 if (myDocksParam.bUseDefaultColors) // reload bg
1860 {
1861 cd_debug (" reload dock's bg...");
1862
1863 gboolean bNeedUpdateSize = (myDocksParam.iDockLineWidth != myStyleParam.iLineWidth); // frame size changed
1864 myDocksParam.iDockRadius = myStyleParam.iCornerRadius;
1865 myDocksParam.iDockLineWidth = myStyleParam.iLineWidth;
1866
1867 if (bNeedUpdateSize) // update docks size and background
1868 gldi_docks_foreach_root ((GFunc)cairo_dock_update_dock_size, NULL);
1869 else // update docks background for color change
1870 gldi_docks_foreach_root ((GFunc)_reload_bg, NULL);
1871 }
1872 return GLDI_NOTIFICATION_LET_PASS;
1873 }
1874
init(void)1875 static void init (void)
1876 {
1877 s_hDocksTable = g_hash_table_new_full (g_str_hash,
1878 g_str_equal,
1879 NULL, // name of the dock (points directly to the dock)
1880 NULL); // dock
1881
1882 /**gldi_object_register_notification (&myDockObjectMgr,
1883 NOTIFICATION_RENDER,
1884 (GldiNotificationFunc) _render_dock_notification,
1885 GLDI_RUN_FIRST, NULL);*/
1886 gldi_object_register_notification (&myDockObjectMgr,
1887 NOTIFICATION_LEAVE_DOCK,
1888 (GldiNotificationFunc) _on_leave_dock, // is a notification so that others can prevent a dock from hiding (ex Slide view)
1889 GLDI_RUN_FIRST, NULL);
1890 gldi_object_register_notification (&myDockObjectMgr,
1891 NOTIFICATION_INSERT_ICON,
1892 (GldiNotificationFunc) on_insert_remove_icon,
1893 GLDI_RUN_AFTER, NULL);
1894 gldi_object_register_notification (&myDockObjectMgr,
1895 NOTIFICATION_REMOVE_ICON,
1896 (GldiNotificationFunc) on_insert_remove_icon,
1897 GLDI_RUN_AFTER, NULL);
1898 gldi_object_register_notification (&myIconObjectMgr,
1899 NOTIFICATION_UPDATE_ICON,
1900 (GldiNotificationFunc) on_update_inserting_removing_icon,
1901 GLDI_RUN_AFTER, NULL);
1902 gldi_object_register_notification (&myIconObjectMgr,
1903 NOTIFICATION_STOP_ICON,
1904 (GldiNotificationFunc) on_stop_inserting_removing_icon,
1905 GLDI_RUN_AFTER, NULL);
1906 gldi_object_register_notification (&myDesktopMgr,
1907 NOTIFICATION_DESKTOP_GEOMETRY_CHANGED,
1908 (GldiNotificationFunc) _on_screen_geometry_changed,
1909 GLDI_RUN_FIRST, NULL);
1910 gldi_object_register_notification (&myDialogObjectMgr,
1911 NOTIFICATION_NEW,
1912 (GldiNotificationFunc) _on_new_dialog,
1913 GLDI_RUN_AFTER, NULL);
1914 gldi_object_register_notification (&myStyleMgr,
1915 NOTIFICATION_STYLE_CHANGED,
1916 (GldiNotificationFunc) on_style_changed,
1917 GLDI_RUN_AFTER, NULL);
1918
1919 gldi_docks_visibility_start ();
1920 }
1921
1922
1923 ///////////////
1924 /// MANAGER ///
1925 ///////////////
1926
init_object(GldiObject * obj,gpointer attr)1927 static void init_object (GldiObject *obj, gpointer attr)
1928 {
1929 CairoDock *pDock = (CairoDock*)obj;
1930 CairoDockAttr *dattr = (CairoDockAttr*)attr;
1931
1932 // check everything is ok
1933 g_return_if_fail (dattr != NULL && dattr->cDockName != NULL);
1934
1935 if (g_hash_table_lookup (s_hDocksTable, dattr->cDockName) != NULL)
1936 {
1937 cd_warning ("a dock with the name '%s' is already registered", dattr->cDockName);
1938 return;
1939 }
1940
1941 //\__________________ init internals
1942 gldi_dock_init_internals (pDock);
1943 if (s_bKeepAbove)
1944 gtk_window_set_keep_above (GTK_WINDOW (pDock->container.pWidget), s_bKeepAbove);
1945
1946 //\__________________ initialize its parameters (it's a root dock by default)
1947 pDock->cDockName = g_strdup (dattr->cDockName);
1948 pDock->iAvoidingMouseIconType = -1;
1949 pDock->fFlatDockWidth = - myIconsParam.iIconGap;
1950 pDock->fMagnitudeMax = 1.;
1951 pDock->fPostHideOffset = 1.;
1952 pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST; // le dock est cree au repos. La zone d'input sera mis en place lors du configure.
1953 pDock->iIconSize = myIconsParam.iIconWidth; // by default
1954
1955 gldi_object_register_notification (pDock,
1956 NOTIFICATION_RENDER,
1957 (GldiNotificationFunc) _render_dock_notification,
1958 GLDI_RUN_FIRST, NULL); /// we connect here, to pass before the manager... try to avoid this hack...
1959
1960 //\__________________ register the dock
1961 if (g_hash_table_size (s_hDocksTable) == 0) // c'est le 1er.
1962 {
1963 pDock->bIsMainDock = TRUE;
1964 g_pMainDock = pDock;
1965 }
1966 g_hash_table_insert (s_hDocksTable, pDock->cDockName, pDock);
1967
1968 //\__________________ set the icons.
1969 GList *pIconList = dattr->pIconList;
1970
1971 gldi_automatic_separators_add_in_list (pIconList);
1972
1973 pDock->icons = pIconList; // set icons now, before we set the ratio and the renderer.
1974 Icon *icon;
1975 GList *ic;
1976 for (ic = pIconList; ic != NULL; ic = ic->next)
1977 {
1978 icon = ic->data;
1979 if (icon->cParentDockName == NULL)
1980 icon->cParentDockName = g_strdup (pDock->cDockName);
1981 cairo_dock_set_icon_container (icon, pDock);
1982 }
1983
1984 //\__________________
1985 if (! dattr->bSubDock)
1986 {
1987 gtk_window_set_title (GTK_WINDOW (pDock->container.pWidget), "cairo-dock");
1988
1989 //\__________________ register it as a main dock
1990 s_pRootDockList = g_list_prepend (s_pRootDockList, pDock);
1991
1992 //\__________________ set additional params from its config file
1993 _get_root_dock_config (pDock);
1994 }
1995 else
1996 {
1997 gtk_window_set_title (GTK_WINDOW (pDock->container.pWidget), "cairo-dock-sub");
1998 pDock->iRefCount = 1;
1999
2000 //\__________________ set additional params from its parent dock.
2001 CairoDock *pParentDock = dattr->pParentDock;
2002 if (pParentDock == NULL)
2003 pParentDock = g_pMainDock;
2004
2005 pDock->container.bIsHorizontal = pParentDock->container.bIsHorizontal;
2006 pDock->container.bDirectionUp = pParentDock->container.bDirectionUp;
2007 pDock->iNumScreen = pParentDock->iNumScreen;
2008 pDock->iIconSize = pParentDock->iIconSize;
2009
2010 pDock->container.fRatio = myBackendsParam.fSubDockSizeRatio;
2011
2012 //\__________________ hide the dock
2013 gtk_widget_hide (pDock->container.pWidget);
2014 }
2015
2016 //\__________________ set a renderer (got from the conf, or the default one).
2017 if (dattr->cRendererName)
2018 cairo_dock_set_renderer (pDock, dattr->cRendererName); /// merge both functions ?...
2019 else
2020 cairo_dock_set_default_renderer (pDock);
2021
2022 //\__________________ load the icons.
2023 if (pIconList != NULL)
2024 {
2025 cairo_dock_reload_buffers_in_dock (pDock, FALSE, TRUE); // idle reload; FALSE = not recursively, TRUE = compute icons size
2026 }
2027
2028 cairo_dock_update_dock_size (pDock);
2029 }
2030
reset_object(GldiObject * obj)2031 static void reset_object (GldiObject *obj)
2032 {
2033 CairoDock *pDock = (CairoDock*)obj;
2034
2035 // stop timers
2036 if (pDock->iSidUnhideDelayed != 0)
2037 g_source_remove (pDock->iSidUnhideDelayed);
2038 if (pDock->iSidHideBack != 0)
2039 g_source_remove (pDock->iSidHideBack);
2040 if (pDock->iSidMoveResize != 0)
2041 g_source_remove (pDock->iSidMoveResize);
2042 if (pDock->iSidLeaveDemand != 0)
2043 g_source_remove (pDock->iSidLeaveDemand);
2044 if (pDock->iSidUpdateWMIcons != 0)
2045 g_source_remove (pDock->iSidUpdateWMIcons);
2046 if (pDock->iSidLoadBg != 0)
2047 g_source_remove (pDock->iSidLoadBg);
2048 if (pDock->iSidDestroyEmptyDock != 0)
2049 g_source_remove (pDock->iSidDestroyEmptyDock);
2050 if (pDock->iSidTestMouseOutside != 0)
2051 g_source_remove (pDock->iSidTestMouseOutside);
2052 if (pDock->iSidUpdateDockSize != 0)
2053 g_source_remove (pDock->iSidUpdateDockSize);
2054
2055 // free icons that are still present
2056 GList *icons = pDock->icons;
2057 pDock->icons = NULL; // remove the icons first, to avoid any use of 'icons' in the 'destroy' callbacks.
2058 GList *ic;
2059 for (ic = icons; ic != NULL; ic = ic->next)
2060 {
2061 Icon *pIcon = ic->data;
2062 cairo_dock_set_icon_container (pIcon, NULL); // optimisation, to avoid detaching the icon from the container (it also prevents from auto-destroying the dock when it becomes empty)
2063 if (pIcon->pSubDock != NULL && s_bResetAll) // if we're deleting the whole table, we don't want the icon to destroy its sub-dock
2064 pIcon->pSubDock = NULL;
2065 gldi_object_unref (GLDI_OBJECT(pIcon));
2066 }
2067 ///g_list_foreach (icons, (GFunc)gldi_object_unref, NULL);
2068 g_list_free (icons);
2069
2070 // if it's a sub-dock, ensure the main icon looses its sub-dock
2071 if (pDock->iRefCount > 0)
2072 {
2073 Icon *pPointedIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
2074 if (pPointedIcon != NULL)
2075 pPointedIcon->pSubDock = NULL;
2076 }
2077
2078 // unregister it
2079 if (pDock->cDockName)
2080 {
2081 g_hash_table_remove (s_hDocksTable, pDock->cDockName);
2082 s_pRootDockList = g_list_remove (s_pRootDockList, pDock);
2083 }
2084
2085 // stop the mouse scrutation
2086 if (pDock->iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP
2087 || pDock->iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE_ON_OVERLAP_ANY
2088 || pDock->iVisibility == CAIRO_DOCK_VISI_AUTO_HIDE
2089 || pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW)
2090 {
2091 _stop_polling_screen_edge ();
2092 }
2093
2094 // free data
2095 if (pDock->pShapeBitmap != NULL)
2096 cairo_region_destroy (pDock->pShapeBitmap);
2097
2098 if (pDock->pHiddenShapeBitmap != NULL)
2099 cairo_region_destroy (pDock->pHiddenShapeBitmap);
2100
2101 if (pDock->pActiveShapeBitmap != NULL)
2102 cairo_region_destroy (pDock->pActiveShapeBitmap);
2103
2104 if (pDock->pRenderer != NULL && pDock->pRenderer->free_data != NULL)
2105 {
2106 pDock->pRenderer->free_data (pDock);
2107 }
2108
2109 g_free (pDock->cRendererName);
2110 g_free (pDock->cBgImagePath);
2111 cairo_dock_unload_image_buffer (&pDock->backgroundBuffer);
2112 if (pDock->iFboId != 0)
2113 glDeleteFramebuffersEXT (1, &pDock->iFboId);
2114 if (pDock->iRedirectedTexture != 0)
2115 _cairo_dock_delete_texture (pDock->iRedirectedTexture);
2116 g_free (pDock->cDockName);
2117 }
2118
delete_object(GldiObject * obj)2119 static gboolean delete_object (GldiObject *obj)
2120 {
2121 CairoDock *pDock = (CairoDock*)obj;
2122 if (pDock->bIsMainDock) // can't delete the main dock
2123 {
2124 return FALSE;
2125 }
2126
2127 // remove the conf file
2128 _remove_root_dock_config (pDock->cDockName);
2129
2130 // delete all the icons
2131 GList *icons = pDock->icons;
2132 pDock->icons = NULL; // remove the icons first, to avoid any use of 'icons' in the 'destroy' callbacks.
2133 GList *ic;
2134 for (ic = icons; ic != NULL; ic = ic->next)
2135 {
2136 Icon *pIcon = ic->data;
2137 cairo_dock_set_icon_container (pIcon, NULL); // optimisation, to avoid detaching the icon from the container.
2138 gldi_object_delete (GLDI_OBJECT(pIcon));
2139 }
2140 ///g_list_foreach (icons, (GFunc)gldi_object_delete, NULL);
2141 g_list_free (icons);
2142
2143 return TRUE;
2144 }
2145
reload_object(GldiObject * obj,gboolean bReloadConf,G_GNUC_UNUSED GKeyFile * pKeyFile)2146 static GKeyFile* reload_object (GldiObject *obj, gboolean bReloadConf, G_GNUC_UNUSED GKeyFile *pKeyFile)
2147 {
2148 CairoDock *pDock = (CairoDock*)obj;
2149
2150 if (bReloadConf) // maybe we should update the parameters that have the global value ?...
2151 _get_root_dock_config (pDock);
2152
2153 cairo_dock_set_default_renderer (pDock);
2154
2155 pDock->backgroundBuffer.iWidth ++; // pour forcer le chargement du fond.
2156 cairo_dock_reload_buffers_in_dock (pDock, TRUE, TRUE);
2157
2158 _cairo_dock_draw_one_subdock_icon (NULL, pDock, NULL); // container-icons may be drawn differently according to the orientation (ex.: box). must be done after sub-docks are reloaded.
2159
2160 gtk_widget_queue_draw (pDock->container.pWidget);
2161 return NULL;
2162 }
2163
gldi_register_docks_manager(void)2164 void gldi_register_docks_manager (void)
2165 {
2166 // Manager
2167 memset (&myDocksMgr, 0, sizeof (GldiManager));
2168 gldi_object_init (GLDI_OBJECT(&myDocksMgr), &myManagerObjectMgr, NULL);
2169 myDocksMgr.cModuleName = "Docks";
2170 // interface
2171 myDocksMgr.init = init;
2172 myDocksMgr.load = load;
2173 myDocksMgr.unload = unload;
2174 myDocksMgr.reload = (GldiManagerReloadFunc)reload;
2175 myDocksMgr.get_config = (GldiManagerGetConfigFunc)get_config;
2176 myDocksMgr.reset_config = (GldiManagerResetConfigFunc)reset_config;
2177 // Config
2178 memset (&myDocksParam, 0, sizeof (CairoDocksParam));
2179 myDocksMgr.pConfig = (GldiManagerConfigPtr)&myDocksParam;
2180 myDocksMgr.iSizeOfConfig = sizeof (CairoDocksParam);
2181 // data
2182 memset (&g_pVisibleZoneBuffer, 0, sizeof (CairoDockImageBuffer));
2183 myDocksMgr.pData = (GldiManagerDataPtr)NULL;
2184 myDocksMgr.iSizeOfData = 0;
2185
2186 // Object Manager
2187 memset (&myDockObjectMgr, 0, sizeof (GldiObjectManager));
2188 myDockObjectMgr.cName = "Dock";
2189 myDockObjectMgr.iObjectSize = sizeof (CairoDock);
2190 // interface
2191 myDockObjectMgr.init_object = init_object;
2192 myDockObjectMgr.reset_object = reset_object;
2193 myDockObjectMgr.delete_object = delete_object;
2194 myDockObjectMgr.reload_object = reload_object;
2195 // signals
2196 gldi_object_install_notifications (&myDockObjectMgr, NB_NOTIFICATIONS_DOCKS);
2197 // parent object
2198 gldi_object_set_manager (GLDI_OBJECT (&myDockObjectMgr), &myContainerObjectMgr);
2199 }
2200