~cairo-dock-team/ubuntu/precise/cairo-dock/3.0.0.0rc1

« back to all changes in this revision

Viewing changes to src/gldit/cairo-dock-dock-factory.c

  • Committer: Package Import Robot
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2012-02-16 01:08:11 UTC
  • mfrom: (1.1.21)
  • Revision ID: package-import@ubuntu.com-20120216010811-yhscmns26s6ngil8
Tags: 3.0.0.0beta1-0ubuntu1
* New upstream release. (LP: #932041)
* Upstream (short) ChangeLog:
 - The taskbar has been greatly enhanced.
 - The control of the dock from the keyboard is now very powerful:
  - many shortkeys have been added in different applets
  - you can activate a launcher by pressing a shortkey + its number
  - all shortkeys can now be managed in a single place
     in the configuration window.
 - A new Twitter applet lets you tweet in one click.
 - A new applet to inhibit the screensaver in one click.
 - Cairo-Dock now uses GTK3, for a better integration in a Gnome desktop
 - It's possible to donate to support the project!
 - (...)
* debian/patches:
 - Removed all previous patches (now in upstream)
* debian/rules and debian/control:
 - Added multiarch support
* debian/control:
 - libgtk-3-dev is now needed instead of libgtk2.0-dev
 - libgtkglext1-dev is no longer needed
    (replaced by libgl, libglu and libpango)
 - cairo-dock: increase the version of plug-ins packages
    and added: cairo-dock-plug-ins-dbus-interface-python
 - cairo-dock-dev has been replaced by libgldi-dev
    and dependences have been updated
 - Added a new package (libgldi3) in order to support multiarch
    and to fix this lintian error: package-name-doesnt-match-sonames
* debian/cairo-dock-core.install and debian/libgldi3.install:
 - libgldi3 package has been added
 - It contains the library used by cairo-dock
 - MultiArch is supported
* debian/cairo-dock-dev.install and debian/libgldi-dev.install:
 - cairo-dock-dev has been replaced by libgldi-dev
* Updated debian/watch

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#include <gdk/gdkx.h>
28
28
 
29
29
#include <cairo.h>
30
 
#include <pango/pango.h>
31
 
#include <librsvg/rsvg.h>
32
 
#include <librsvg/rsvg-cairo.h>
33
 
 
34
 
#ifdef HAVE_GLITZ
35
 
#include <glitz-glx.h>
36
 
#include <cairo-glitz.h>
37
 
#endif
38
 
 
39
 
#include <gtk/gtkgl.h>
 
30
 
40
31
#include <X11/extensions/Xrender.h>
41
32
#include <X11/extensions/shape.h>
42
33
#include <GL/gl.h> 
43
34
#include <GL/glu.h> 
44
35
#include <GL/glx.h> 
45
 
#include <gdk/x11/gdkglx.h>
46
36
 
47
37
#include "cairo-dock-draw.h"
48
38
#include "cairo-dock-applications-manager.h"
49
39
#include "cairo-dock-image-buffer.h"
50
 
#include "cairo-dock-config.h"
51
40
#include "cairo-dock-module-factory.h"
52
41
#include "cairo-dock-callbacks.h"
53
42
#include "cairo-dock-icon-factory.h"
57
46
#include "cairo-dock-backends-manager.h"  // myBackendsParam.fSubDockSizeRatio
58
47
#include "cairo-dock-X-utilities.h"
59
48
#include "cairo-dock-log.h"
 
49
#include "cairo-dock-application-facility.h"  // cairo_dock_detach_appli
 
50
#include "cairo-dock-dialog-manager.h"  // cairo_dock_replace_all_dialogs
60
51
#include "cairo-dock-keyfile-utilities.h"
61
52
#include "cairo-dock-dock-manager.h"
62
53
#include "cairo-dock-notifications.h"
68
59
#include "cairo-dock-gui-manager.h"
69
60
#include "cairo-dock-dock-facility.h"
70
61
#include "cairo-dock-desktop-file-factory.h"
71
 
#include "cairo-dock-emblem.h"
72
62
#include "cairo-dock-draw-opengl.h"
73
63
#include "cairo-dock-opengl.h"
74
64
#include "cairo-dock-dock-factory.h"
76
66
extern gchar *g_cCurrentLaunchersPath;
77
67
 
78
68
extern CairoDockGLConfig g_openglConfig;
 
69
extern CairoDockHidingEffect *g_pHidingBackend;
79
70
extern gboolean g_bUseOpenGL;
80
 
#ifdef HAVE_GLITZ
81
 
extern gboolean g_bUseGlitz;
82
 
#endif
83
 
 
84
 
 
85
 
static void _cairo_dock_set_icon_size (CairoContainer *pDock, Icon *icon)
86
 
{
87
 
        CairoDockIconGroup iType = cairo_dock_get_icon_type (icon);
88
 
        if (CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon))  // une applet peut definir la taille de son icone elle-meme.
89
 
        {
90
 
                if (icon->fWidth == 0)
91
 
                        icon->fWidth = myIconsParam.tIconAuthorizedWidth[iType];
92
 
                if (icon->fHeight == 0)
93
 
                        icon->fHeight = myIconsParam.tIconAuthorizedHeight[iType];
94
 
        }
95
 
        else
96
 
        {
97
 
                icon->fWidth = myIconsParam.tIconAuthorizedWidth[iType];
98
 
                icon->fHeight = myIconsParam.tIconAuthorizedHeight[iType];
99
 
        }
100
 
}
101
 
 
102
 
CairoDock *cairo_dock_new_dock (const gchar *cRendererName)
 
71
 
 
72
 
 
73
static gboolean _cairo_dock_grow_up (CairoDock *pDock)
 
74
{
 
75
        //g_print ("%s (%d ; %2f ; bInside:%d)\n", __func__, pDock->iMagnitudeIndex, pDock->fFoldingFactor, pDock->container.bInside);
 
76
        
 
77
        pDock->iMagnitudeIndex += myBackendsParam.iGrowUpInterval;
 
78
        if (pDock->iMagnitudeIndex > CAIRO_DOCK_NB_MAX_ITERATIONS)
 
79
                pDock->iMagnitudeIndex = CAIRO_DOCK_NB_MAX_ITERATIONS;
 
80
 
 
81
        if (pDock->fFoldingFactor != 0)
 
82
        {
 
83
                int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
 
84
                pDock->fFoldingFactor -= (double) iAnimationDeltaT / myBackendsParam.iUnfoldingDuration;
 
85
                if (pDock->fFoldingFactor < 0)
 
86
                        pDock->fFoldingFactor = 0;
 
87
        }
 
88
        
 
89
        gldi_container_update_mouse_position (CAIRO_CONTAINER (pDock));
 
90
        
 
91
        Icon *pLastPointedIcon = cairo_dock_get_pointed_icon (pDock->icons);
 
92
        Icon *pPointedIcon = cairo_dock_calculate_dock_icons (pDock);
 
93
        if (! pDock->bIsGrowingUp)
 
94
                return FALSE;
 
95
        
 
96
        if (pLastPointedIcon != pPointedIcon && pDock->container.bInside)
 
97
                cairo_dock_on_change_icon (pLastPointedIcon, pPointedIcon, pDock);
 
98
 
 
99
        if (pDock->iMagnitudeIndex == CAIRO_DOCK_NB_MAX_ITERATIONS && pDock->fFoldingFactor == 0)  // fin de grossissement et de depliage.
 
100
        {
 
101
                /// TODO: check doing this in update_dock_size directly...
 
102
                /**if (pDock->bWMIconsNeedUpdate)
 
103
                {
 
104
                        cairo_dock_trigger_set_WM_icons_geometry (pDock);
 
105
                        pDock->bWMIconsNeedUpdate = FALSE;
 
106
                }*/
 
107
                
 
108
                cairo_dock_replace_all_dialogs ();
 
109
                return FALSE;
 
110
        }
 
111
        else
 
112
                return TRUE;
 
113
}
 
114
 
 
115
static gboolean _cairo_dock_shrink_down (CairoDock *pDock)
 
116
{
 
117
        //g_print ("%s (%d, %f, %f)\n", __func__, pDock->iMagnitudeIndex, pDock->fFoldingFactor, pDock->fDecorationsOffsetX);
 
118
        //\_________________ On fait decroitre la magnitude du dock.
 
119
        int iPrevMagnitudeIndex = pDock->iMagnitudeIndex;
 
120
        pDock->iMagnitudeIndex -= myBackendsParam.iShrinkDownInterval;
 
121
        if (pDock->iMagnitudeIndex < 0)
 
122
                pDock->iMagnitudeIndex = 0;
 
123
        
 
124
        //\_________________ On replie le dock.
 
125
        if (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)
 
126
        {
 
127
                int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
 
128
                pDock->fFoldingFactor += (double) iAnimationDeltaT / myBackendsParam.iUnfoldingDuration;
 
129
                if (pDock->fFoldingFactor > 1)
 
130
                        pDock->fFoldingFactor = 1;
 
131
        }
 
132
        
 
133
        //\_________________ On remet les decorations a l'equilibre.
 
134
        pDock->fDecorationsOffsetX *= .8;
 
135
        if (fabs (pDock->fDecorationsOffsetX) < 3)
 
136
                pDock->fDecorationsOffsetX = 0.;
 
137
        
 
138
        //\_________________ On recupere la position de la souris manuellement (car a priori on est hors du dock).
 
139
        gldi_container_update_mouse_position (CAIRO_CONTAINER (pDock));  // ce n'est pas le motion_notify qui va nous donner des coordonnees en dehors du dock, et donc le fait d'etre dedans va nous faire interrompre le shrink_down et re-grossir, du coup il faut le faire ici. L'inconvenient, c'est que quand on sort par les cotes, il n'y a soudain plus d'icone pointee, et donc le dock devient tout plat subitement au lieu de le faire doucement. Heureusement j'ai trouve une astuce. ^_^
 
140
        
 
141
        //\_________________ On recalcule les icones.
 
142
        ///if (iPrevMagnitudeIndex != 0)
 
143
        {
 
144
                cairo_dock_calculate_dock_icons (pDock);
 
145
                if (! pDock->bIsShrinkingDown)
 
146
                        return FALSE;
 
147
                
 
148
                ///cairo_dock_replace_all_dialogs ();
 
149
        }
 
150
 
 
151
        if (pDock->iMagnitudeIndex == 0 && (pDock->fFoldingFactor == 0 || pDock->fFoldingFactor == 1))  // on est arrive en bas.
 
152
        {
 
153
                //g_print ("equilibre atteint (%d)\n", pDock->container.bInside);
 
154
                if (! pDock->container.bInside)  // on peut etre hors des icones sans etre hors de la fenetre.
 
155
                {
 
156
                        //g_print ("rideau !\n");
 
157
                        
 
158
                        //\__________________ On repasse derriere si on etait devant.
 
159
                        if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->bIsBelow)
 
160
                                cairo_dock_pop_down (pDock);
 
161
                        
 
162
                        //\__________________ On se redimensionne en taille normale.
 
163
                        if (! pDock->bAutoHide && pDock->iRefCount == 0 && ! pDock->bMenuVisible)  // fin de shrink sans auto-hide => taille normale.
 
164
                        {
 
165
                                //g_print ("taille normale (%x; %d)\n", pDock->pShapeBitmap , pDock->iInputState);
 
166
                                if (pDock->pShapeBitmap && pDock->iInputState != CAIRO_DOCK_INPUT_AT_REST)
 
167
                                {
 
168
                                        //g_print ("+++ input shape at rest on end shrinking\n");
 
169
                                        cairo_dock_set_input_shape_at_rest (pDock);
 
170
                                        pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST;
 
171
                                        ///cairo_dock_replace_all_dialogs ();
 
172
                                }
 
173
                        }
 
174
                        
 
175
                        //\__________________ On se cache si sous-dock.
 
176
                        if (pDock->iRefCount > 0)
 
177
                        {
 
178
                                //g_print ("on cache ce sous-dock en sortant par lui\n");
 
179
                                gtk_widget_hide (pDock->container.pWidget);
 
180
                                cairo_dock_hide_parent_dock (pDock);
 
181
                        }
 
182
                        cairo_dock_hide_after_shortcut ();
 
183
                }
 
184
                else
 
185
                {
 
186
                        cairo_dock_calculate_dock_icons (pDock);  // relance le grossissement si on est dedans.
 
187
                }
 
188
                if (!pDock->bIsGrowingUp)
 
189
                        cairo_dock_replace_all_dialogs ();
 
190
                return (!pDock->bIsGrowingUp && (pDock->fDecorationsOffsetX != 0 || (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)));
 
191
        }
 
192
        else
 
193
        {
 
194
                return (!pDock->bIsGrowingUp);
 
195
        }
 
196
}
 
197
 
 
198
static gboolean _cairo_dock_hide (CairoDock *pDock)
 
199
{
 
200
        //g_print ("%s (%d, %.2f, %.2f)\n", __func__, pDock->iMagnitudeIndex, pDock->fHideOffset, pDock->fPostHideOffset);
 
201
        
 
202
        if (pDock->fHideOffset < 1)  // the hiding animation is running.
 
203
        {
 
204
                pDock->fHideOffset += 1./myBackendsParam.iHideNbSteps;
 
205
                if (pDock->fHideOffset > .99)  // fin d'anim.
 
206
                {
 
207
                        pDock->fHideOffset = 1;
 
208
                        
 
209
                        //g_print ("on arrete le cachage\n");
 
210
                        gboolean bVisibleIconsPresent = FALSE;
 
211
                        Icon *pIcon;
 
212
                        GList *ic;
 
213
                        for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
214
                        {
 
215
                                pIcon = ic->data;
 
216
                                if (pIcon->fInsertRemoveFactor != 0)  // on accelere l'animation d'apparition/disparition.
 
217
                                {
 
218
                                        if (pIcon->fInsertRemoveFactor > 0)
 
219
                                                pIcon->fInsertRemoveFactor = 0.05;
 
220
                                        else
 
221
                                                pIcon->fInsertRemoveFactor = - 0.05;
 
222
                                }
 
223
                                
 
224
                                if (! pIcon->bIsDemandingAttention && ! pIcon->bAlwaysVisible)
 
225
                                        cairo_dock_stop_icon_animation (pIcon);  // s'il y'a une autre animation en cours, on l'arrete.
 
226
                                else
 
227
                                        bVisibleIconsPresent = TRUE;
 
228
                        }
 
229
                        
 
230
                        pDock->pRenderer->calculate_icons (pDock);
 
231
                        ///pDock->fFoldingFactor = (myBackendsParam.bAnimateOnAutoHide ? .99 : 0.);  // on arme le depliage.
 
232
                        cairo_dock_allow_entrance (pDock);
 
233
                        
 
234
                        cairo_dock_replace_all_dialogs ();
 
235
                        
 
236
                        if (bVisibleIconsPresent)  // il y'a des icones a montrer progressivement, on reste dans la boucle.
 
237
                        {
 
238
                                pDock->fPostHideOffset = 0.05;
 
239
                                return TRUE;
 
240
                        }
 
241
                        else
 
242
                        {
 
243
                                pDock->fPostHideOffset = 1;  // pour que les icones demandant l'attention plus tard soient visibles.
 
244
                                return FALSE;
 
245
                        }
 
246
                }
 
247
        }
 
248
        else if (pDock->fPostHideOffset > 0 && pDock->fPostHideOffset < 1)  // the post-hiding animation is running.
 
249
        {
 
250
                pDock->fPostHideOffset += 1./myBackendsParam.iHideNbSteps;
 
251
                if (pDock->fPostHideOffset > .99)
 
252
                {
 
253
                        pDock->fPostHideOffset = 1.;
 
254
                        return FALSE;
 
255
                }
 
256
        }
 
257
        else  // else no hiding animation is running.
 
258
                return FALSE;
 
259
        return TRUE;
 
260
}
 
261
 
 
262
static gboolean _cairo_dock_show (CairoDock *pDock)
 
263
{
 
264
        pDock->fHideOffset -= 1./myBackendsParam.iUnhideNbSteps;
 
265
        if (pDock->fHideOffset < 0.01)
 
266
        {
 
267
                pDock->fHideOffset = 0;
 
268
                cairo_dock_allow_entrance (pDock);
 
269
                cairo_dock_replace_all_dialogs ();  // we need it here so that a modal dialog is replaced when the dock unhides (else it would stay behind).
 
270
                return FALSE;
 
271
        }
 
272
        return TRUE;
 
273
}
 
274
 
 
275
static gboolean _cairo_dock_handle_inserting_removing_icons (CairoDock *pDock)
 
276
{
 
277
        gboolean bRecalculateIcons = FALSE;
 
278
        GList* ic = pDock->icons, *next_ic;
 
279
        Icon *pIcon;
 
280
        while (ic != NULL)
 
281
        {
 
282
                pIcon = ic->data;
 
283
                next_ic = ic->next;
 
284
                if (pIcon->fInsertRemoveFactor == (gdouble)0.05)
 
285
                {
 
286
                        gboolean bIsAppli = CAIRO_DOCK_IS_NORMAL_APPLI (pIcon);
 
287
                        if (bIsAppli && pIcon->iLastCheckTime != -1)  // c'est une icone d'appli non vieille qui disparait, elle s'est probablement cachee => on la detache juste.
 
288
                        {
 
289
                                cd_message ("cette (%s) appli est toujours valide, on la detache juste", pIcon->cName);
 
290
                                pIcon->fInsertRemoveFactor = 0.;  // on le fait avant le reload, sinon l'icone n'est pas rechargee.
 
291
                                if (!pIcon->bIsHidden && myTaskbarParam.bHideVisibleApplis)  // on lui remet l'image normale qui servira d'embleme lorsque l'icone sera inseree a nouveau dans le dock.
 
292
                                        cairo_dock_reload_icon_image (pIcon, CAIRO_CONTAINER (pDock));
 
293
                                pDock = cairo_dock_detach_appli (pIcon);
 
294
                                if (pDock == NULL)  // the dock has been destroyed (empty class sub-dock).
 
295
                                {
 
296
                                        cairo_dock_free_icon (pIcon);
 
297
                                        return FALSE;
 
298
                                }
 
299
                        }
 
300
                        else
 
301
                        {
 
302
                                cd_message (" - %s va etre supprimee", pIcon->cName);
 
303
                                cairo_dock_remove_icon_from_dock (pDock, pIcon);  // enleve le separateur automatique avec; supprime le .desktop et le sous-dock des lanceurs; stoppe les applets; marque le theme.
 
304
                                
 
305
                                if (pIcon->cClass != NULL && pDock == cairo_dock_get_class_subdock (pIcon->cClass))
 
306
                                {
 
307
                                        gboolean bEmptyClassSubDock = cairo_dock_check_class_subdock_is_empty (pDock, pIcon->cClass);
 
308
                                        if (bEmptyClassSubDock)
 
309
                                        {
 
310
                                                cairo_dock_free_icon (pIcon);
 
311
                                                return FALSE;
 
312
                                        }
 
313
                                }
 
314
                                
 
315
                                cairo_dock_free_icon (pIcon);
 
316
                        }
 
317
                }
 
318
                else if (pIcon->fInsertRemoveFactor == (gdouble)-0.05)
 
319
                {
 
320
                        pIcon->fInsertRemoveFactor = 0;  // cela n'arrete pas l'animation, qui peut se poursuivre meme apres que l'icone ait atteint sa taille maximale.
 
321
                        bRecalculateIcons = TRUE;
 
322
                }
 
323
                else if (pIcon->fInsertRemoveFactor != 0)
 
324
                {
 
325
                        bRecalculateIcons = TRUE;
 
326
                }
 
327
                ic = next_ic;
 
328
        }
 
329
        
 
330
        if (bRecalculateIcons)
 
331
                cairo_dock_calculate_dock_icons (pDock);
 
332
        return TRUE;
 
333
}
 
334
 
 
335
static gboolean _cairo_dock_dock_animation_loop (CairoContainer *pContainer)
 
336
{
 
337
        CairoDock *pDock = CAIRO_DOCK (pContainer);
 
338
        gboolean bContinue = FALSE;
 
339
        gboolean bUpdateSlowAnimation = FALSE;
 
340
        pContainer->iAnimationStep ++;
 
341
        if (pContainer->iAnimationStep * pContainer->iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
 
342
        {
 
343
                bUpdateSlowAnimation = TRUE;
 
344
                pContainer->iAnimationStep = 0;
 
345
                pContainer->bKeepSlowAnimation = FALSE;
 
346
        }
 
347
        
 
348
        if (pDock->bIsShrinkingDown)
 
349
        {
 
350
                pDock->bIsShrinkingDown = _cairo_dock_shrink_down (pDock);
 
351
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
352
                bContinue |= pDock->bIsShrinkingDown;
 
353
        }
 
354
        if (pDock->bIsGrowingUp)
 
355
        {
 
356
                pDock->bIsGrowingUp = _cairo_dock_grow_up (pDock);
 
357
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
358
                bContinue |= pDock->bIsGrowingUp;
 
359
        }
 
360
        if (pDock->bIsHiding)
 
361
        {
 
362
                //g_print ("le dock se cache\n");
 
363
                pDock->bIsHiding = _cairo_dock_hide (pDock);
 
364
                gtk_widget_queue_draw (pContainer->pWidget);  // on n'utilise pas cairo_dock_redraw_container, sinon a la derniere iteration, le dock etant cache, la fonction ne le redessine pas.
 
365
                bContinue |= pDock->bIsHiding;
 
366
        }
 
367
        if (pDock->bIsShowing)
 
368
        {
 
369
                pDock->bIsShowing = _cairo_dock_show (pDock);
 
370
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
 
371
                bContinue |= pDock->bIsShowing;
 
372
        }
 
373
        //g_print (" => %d, %d\n", pDock->bIsShrinkingDown, pDock->bIsGrowingUp);
 
374
        
 
375
        double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
 
376
        gboolean bIconIsAnimating;
 
377
        gboolean bNoMoreDemandingAttention = FALSE;
 
378
        Icon *icon;
 
379
        GList *ic;
 
380
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
381
        {
 
382
                icon = ic->data;
 
383
                
 
384
                icon->fDeltaYReflection = 0;
 
385
                if (myIconsParam.fAlphaAtRest != 1)
 
386
                        icon->fAlpha = fDockMagnitude + myIconsParam.fAlphaAtRest * (1 - fDockMagnitude);
 
387
                
 
388
                bIconIsAnimating = FALSE;
 
389
                if (bUpdateSlowAnimation)
 
390
                {
 
391
                        cairo_dock_notify_on_object (icon, NOTIFICATION_UPDATE_ICON_SLOW, icon, pDock, &bIconIsAnimating);
 
392
                        pContainer->bKeepSlowAnimation |= bIconIsAnimating;
 
393
                }
 
394
                cairo_dock_notify_on_object (icon, NOTIFICATION_UPDATE_ICON, icon, pDock, &bIconIsAnimating);
 
395
                
 
396
                if ((icon->bIsDemandingAttention || icon->bAlwaysVisible) && cairo_dock_is_hidden (pDock))  // animation d'une icone demandant l'attention dans un dock cache => on force le dessin qui normalement ne se fait pas.
 
397
                {
 
398
                        gtk_widget_queue_draw (pContainer->pWidget);
 
399
                }
 
400
                
 
401
                bContinue |= bIconIsAnimating;
 
402
                if (! bIconIsAnimating)
 
403
                {
 
404
                        icon->iAnimationState = CAIRO_DOCK_STATE_REST;
 
405
                        if (icon->bIsDemandingAttention)
 
406
                        {
 
407
                                icon->bIsDemandingAttention = FALSE;
 
408
                                bNoMoreDemandingAttention = TRUE;
 
409
                        }
 
410
                }
 
411
        }
 
412
        bContinue |= pContainer->bKeepSlowAnimation;
 
413
        
 
414
        if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && bNoMoreDemandingAttention && ! pDock->bIsBelow && ! pContainer->bInside)
 
415
        {
 
416
                //g_print ("plus de raison d'etre devant\n");
 
417
                cairo_dock_pop_down (pDock);
 
418
        }
 
419
        
 
420
        if (! _cairo_dock_handle_inserting_removing_icons (pDock))
 
421
        {
 
422
                cd_debug ("ce dock n'a plus de raison d'etre");
 
423
                return FALSE;
 
424
        }
 
425
        
 
426
        if (bUpdateSlowAnimation)
 
427
        {
 
428
                cairo_dock_notify_on_object (pDock, NOTIFICATION_UPDATE_SLOW, pDock, &pContainer->bKeepSlowAnimation);
 
429
        }
 
430
        cairo_dock_notify_on_object (pDock, NOTIFICATION_UPDATE, pDock, &bContinue);
 
431
        
 
432
        if (! bContinue && ! pContainer->bKeepSlowAnimation)
 
433
        {
 
434
                pContainer->iSidGLAnimation = 0;
 
435
                return FALSE;
 
436
        }
 
437
        else
 
438
                return TRUE;
 
439
}
 
440
 
 
441
static gboolean _on_dock_destroyed (GtkWidget *menu, CairoContainer *pContainer);
 
442
static void _on_menu_deactivated (GtkMenuShell *menu, CairoDock *pDock)
 
443
{
 
444
        //g_print ("\n+++ %s ()\n\n", __func__);
 
445
        g_return_if_fail (CAIRO_DOCK_IS_DOCK (pDock));
 
446
        pDock->bMenuVisible = FALSE;
 
447
        cairo_dock_emit_leave_signal (CAIRO_CONTAINER (pDock));
 
448
}
 
449
static void _on_menu_destroyed (GtkWidget *menu, CairoDock *pDock)
 
450
{
 
451
        //g_print ("\n+++ %s ()\n\n", __func__);
 
452
        cairo_dock_remove_notification_func_on_object (pDock,
 
453
                NOTIFICATION_DESTROY,
 
454
                (CairoDockNotificationFunc) _on_dock_destroyed,
 
455
                menu);
 
456
}
 
457
static gboolean _on_dock_destroyed (GtkWidget *menu, CairoContainer *pContainer)
 
458
{
 
459
        //g_print ("\n+++ %s ()\n\n", __func__);
 
460
        g_signal_handlers_disconnect_matched
 
461
                (menu,
 
462
                G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
 
463
                0,
 
464
                0,
 
465
                NULL,
 
466
                _on_menu_deactivated,
 
467
                pContainer);
 
468
        g_signal_handlers_disconnect_matched
 
469
                (menu,
 
470
                G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
 
471
                0,
 
472
                0,
 
473
                NULL,
 
474
                _on_menu_destroyed,
 
475
                pContainer);
 
476
}
 
477
static void _setup_menu (CairoContainer *pContainer, Icon *pIcon, GtkWidget *pMenu)
 
478
{
 
479
        // keep the dock visible
 
480
        CAIRO_DOCK (pContainer)->bMenuVisible = TRUE;
 
481
        
 
482
        // connect signals
 
483
        if (g_signal_handler_find (pMenu,
 
484
                G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
 
485
                0,
 
486
                0,
 
487
                NULL,
 
488
                _on_menu_deactivated,
 
489
                pContainer) == 0)  // on evite de connecter 2 fois ce signal, donc la fonction est appelable plusieurs fois sur un meme menu.
 
490
        {
 
491
                // when the menu is deactivated, hide the dock back if necessary.
 
492
                g_signal_connect (G_OBJECT (pMenu),
 
493
                        "deactivate",
 
494
                        G_CALLBACK (_on_menu_deactivated),
 
495
                        pContainer);
 
496
                // when the menu is destroyed, remove the 'destroyed' notification on the dock.
 
497
                g_signal_connect (G_OBJECT (pMenu),
 
498
                        "destroy",
 
499
                        G_CALLBACK (_on_menu_destroyed),
 
500
                        pContainer);
 
501
                // when the dock is destroyed, remove the 2 signals on the menu.
 
502
                cairo_dock_register_notification_on_object (pContainer,
 
503
                        NOTIFICATION_DESTROY,
 
504
                        (CairoDockNotificationFunc) _on_dock_destroyed,
 
505
                        CAIRO_DOCK_RUN_AFTER, pMenu);  // the menu can stay alive even if the container disappear, so we need to ensure we won't call the callbacks then.
 
506
        }
 
507
}
 
508
 
 
509
CairoDock *cairo_dock_new_dock (void)
103
510
{
104
511
        //\__________________ On cree un dock.
105
512
        CairoDock *pDock = g_new0 (CairoDock, 1);
106
513
        pDock->container.iType = CAIRO_DOCK_TYPE_DOCK;
107
514
        
108
515
        pDock->iRefCount = 0;  // c'est un dock racine par defaut.
109
 
        pDock->container.fRatio = 1.;
110
516
        pDock->iAvoidingMouseIconType = -1;
111
517
        pDock->fFlatDockWidth = - myIconsParam.iIconGap;
112
 
        pDock->container.iMouseX = -1; // utile ?
113
 
        pDock->container.iMouseY = -1;
 
518
        ///pDock->container.iMouseX = -1; // utile ?
 
519
        ///pDock->container.iMouseY = -1;
114
520
        pDock->fMagnitudeMax = 1.;
115
521
        pDock->fPostHideOffset = 1.;
116
522
        pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST;  // le dock est cree au repos. La zone d'input sera mis en place lors du configure.
117
523
        
118
 
        pDock->container.iface.set_icon_size = _cairo_dock_set_icon_size; // warning: assignment from incompatible pointer type
 
524
        pDock->container.iface.animation_loop = _cairo_dock_dock_animation_loop;
 
525
        pDock->container.iface.setup_menu = _setup_menu;
119
526
        
120
527
        //\__________________ On cree la fenetre GTK.
121
528
        GtkWidget *pWindow = cairo_dock_init_container (CAIRO_CONTAINER (pDock));
122
 
        cairo_dock_install_notifications_on_object (pDock, NB_NOTIFICATIONS_DOCKS);
 
529
        ///cairo_dock_install_notifications_on_object (pDock, NB_NOTIFICATIONS_DOCKS);
 
530
        gldi_object_set_manager (GLDI_OBJECT (pDock), GLDI_MANAGER (&myDocksMgr));
123
531
        gtk_container_set_border_width (GTK_CONTAINER (pWindow), 0);
124
532
        gtk_window_set_gravity (GTK_WINDOW (pWindow), GDK_GRAVITY_STATIC);
125
533
        gtk_window_set_type_hint (GTK_WINDOW (pWindow), GDK_WINDOW_TYPE_HINT_DOCK);
126
534
        gtk_window_set_title (GTK_WINDOW (pWindow), "cairo-dock");
127
535
        
128
 
        //\__________________ On associe un renderer.
129
 
        cairo_dock_set_renderer (pDock, cRendererName);
130
 
        
131
536
        //\__________________ On connecte les evenements a la fenetre.
132
537
        gtk_widget_add_events (pWindow,
133
538
                GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
134
539
                GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
135
540
        
136
541
        g_signal_connect (G_OBJECT (pWindow),
 
542
                #if (GTK_MAJOR_VERSION < 3)
137
543
                "expose-event",
 
544
                #else
 
545
                "draw",
 
546
                #endif
138
547
                G_CALLBACK (cairo_dock_on_expose),
139
548
                pDock);
140
549
        g_signal_connect (G_OBJECT (pWindow),
173
582
                "leave-notify-event",
174
583
                G_CALLBACK (cairo_dock_on_leave_notify),
175
584
                pDock);
176
 
        cairo_dock_allow_widget_to_receive_data (pWindow,
 
585
        gldi_container_enable_drop (CAIRO_CONTAINER (pDock),
177
586
                G_CALLBACK (cairo_dock_on_drag_data_received),
178
587
                pDock);
179
588
        g_signal_connect (G_OBJECT (pWindow),
191
600
 
192
601
        gtk_window_get_size (GTK_WINDOW (pWindow), &pDock->container.iWidth, &pDock->container.iHeight);  // ca n'est que la taille initiale allouee par GTK.
193
602
        gtk_widget_show_all (pWindow);
194
 
        gdk_window_set_back_pixmap (pWindow->window, NULL, FALSE);  // vraiment plus rapide ?
195
 
        
196
 
#ifdef HAVE_GLITZ
197
 
        if (g_bUseGlitz && pDock->container.pDrawFormat != NULL)
198
 
        {
199
 
                glitz_format_t templ;
200
 
                GdkDisplay         *gdkdisplay;
201
 
                Display    *XDisplay;
202
 
                Window     xid;
203
 
 
204
 
                gdkdisplay = gdk_display_get_default ();
205
 
                XDisplay   = gdk_x11_display_get_xdisplay (gdkdisplay);
206
 
                xid = gdk_x11_drawable_get_xid (GDK_DRAWABLE (pWindow->window));
207
 
                pDock->container.pGlitzDrawable = glitz_glx_create_drawable_for_window (XDisplay,
208
 
                        0,
209
 
                        pDock->container.pDrawFormat,
210
 
                        xid,
211
 
                        pDock->container.iWidth,
212
 
                        pDock->container.iHeight);
213
 
                if (! pDock->container.pGlitzDrawable)
214
 
                {
215
 
                        cd_warning ("failed to create glitz drawable");
216
 
                }
217
 
                else
218
 
                {
219
 
                        templ.color        = pDock->container.pDrawFormat->color;
220
 
                        templ.color.fourcc = GLITZ_FOURCC_RGB;
221
 
                        pDock->container.pGlitzFormat = glitz_find_format (pDock->container.pGlitzDrawable,
222
 
                                GLITZ_FORMAT_RED_SIZE_MASK   |
223
 
                                GLITZ_FORMAT_GREEN_SIZE_MASK |
224
 
                                GLITZ_FORMAT_BLUE_SIZE_MASK  |
225
 
                                GLITZ_FORMAT_ALPHA_SIZE_MASK |
226
 
                                GLITZ_FORMAT_FOURCC_MASK,
227
 
                                &templ,
228
 
                                0);
229
 
                        if (! pDock->container.pGlitzFormat)
230
 
                        {
231
 
                                cd_warning ("couldn't find glitz surface format");
232
 
                        }
233
 
                }
234
 
        }
235
 
#endif
236
 
        
 
603
        #if (GTK_MAJOR_VERSION < 3)
 
604
        gdk_window_set_back_pixmap (pWindow->window, NULL, FALSE);
 
605
        #else
 
606
        gdk_window_set_background_pattern (gldi_container_get_gdk_window (CAIRO_CONTAINER (pDock)), NULL);
 
607
        #endif
237
608
        return pDock;
238
609
}
239
610
 
255
626
                g_source_remove (pDock->iSidDestroyEmptyDock);
256
627
        if (pDock->iSidTestMouseOutside != 0)
257
628
                g_source_remove (pDock->iSidTestMouseOutside);
258
 
        cairo_dock_notify_on_object (&myDocksMgr, NOTIFICATION_STOP_DOCK, pDock);
259
 
        cairo_dock_notify_on_object (pDock, NOTIFICATION_STOP_DOCK, pDock);
 
629
        if (pDock->iSidUpdateDockSize != 0)
 
630
                g_source_remove (pDock->iSidUpdateDockSize);
260
631
        
261
632
        g_list_foreach (pDock->icons, (GFunc) cairo_dock_free_icon, NULL);
262
633
        g_list_free (pDock->icons);
263
634
        pDock->icons = NULL;
264
635
        
265
636
        if (pDock->pShapeBitmap != NULL)
266
 
                g_object_unref ((gpointer) pDock->pShapeBitmap);
 
637
                gldi_shape_destroy (pDock->pShapeBitmap);
267
638
        
268
639
        if (pDock->pHiddenShapeBitmap != NULL)
269
 
                g_object_unref ((gpointer) pDock->pHiddenShapeBitmap);
 
640
                gldi_shape_destroy (pDock->pHiddenShapeBitmap);
270
641
        
271
642
        if (pDock->pActiveShapeBitmap != NULL)
272
 
                g_object_unref ((gpointer) pDock->pActiveShapeBitmap);
 
643
                gldi_shape_destroy (pDock->pActiveShapeBitmap);
273
644
        
274
645
        if (pDock->pRenderer != NULL && pDock->pRenderer->free_data != NULL)
275
646
        {
286
657
        if (pDock->iRedirectedTexture != 0)
287
658
                _cairo_dock_delete_texture (pDock->iRedirectedTexture);
288
659
        
289
 
        cairo_dock_finish_container (CAIRO_CONTAINER (pDock));
 
660
        cairo_dock_finish_container (CAIRO_CONTAINER (pDock));  // -> NOTIFICATION_DESTROY
290
661
        
291
662
        g_free (pDock);
292
663
}
293
664
 
294
 
void cairo_dock_make_sub_dock (CairoDock *pDock, CairoDock *pParentDock)
 
665
void cairo_dock_make_sub_dock (CairoDock *pDock, CairoDock *pParentDock, const gchar *cRendererName)
295
666
{
296
 
        CairoDockPositionType iScreenBorder = ((! pDock->container.bIsHorizontal) << 1) | (! pDock->container.bDirectionUp);
297
 
        cd_debug ("sub-dock's position : %d/%d", pDock->container.bIsHorizontal, pDock->container.bDirectionUp);
 
667
        //\__________________ set sub-dock flag
 
668
        pDock->iRefCount = 1;
 
669
        gtk_window_set_title (GTK_WINDOW (pDock->container.pWidget), "cairo-dock-sub");
 
670
        
 
671
        //\__________________ set the orientation relatively to the parent dock
298
672
        pDock->container.bIsHorizontal = pParentDock->container.bIsHorizontal;
299
673
        pDock->container.bDirectionUp = pParentDock->container.bDirectionUp;
300
 
        if (iScreenBorder != (((! pDock->container.bIsHorizontal) << 1) | (! pDock->container.bDirectionUp)))
301
 
        {
302
 
                cd_debug ("changement de position -> %d/%d", pDock->container.bIsHorizontal, pDock->container.bDirectionUp);
303
 
                cairo_dock_reload_reflects_in_dock (pDock);
304
 
        }
305
674
        pDock->iScreenOffsetX = pParentDock->iScreenOffsetX;
306
675
        pDock->iScreenOffsetY = pParentDock->iScreenOffsetY;
307
 
        gtk_window_set_title (GTK_WINDOW (pDock->container.pWidget), "cairo-dock-sub");
308
 
        
309
 
        pDock->bAutoHide = FALSE;
 
676
        
 
677
        //\__________________ set a renderer
 
678
        cairo_dock_set_renderer (pDock, cRendererName);
 
679
        
 
680
        //\__________________ update the icons size and the ratio.
310
681
        double fPrevRatio = pDock->container.fRatio;
311
682
        pDock->container.fRatio = MIN (pDock->container.fRatio, myBackendsParam.fSubDockSizeRatio);
 
683
        pDock->iIconSize = pParentDock->iIconSize;
312
684
        
313
685
        Icon *icon;
314
686
        GList *ic;
316
688
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
317
689
        {
318
690
                icon = ic->data;
319
 
                icon->fWidth *= pDock->container.fRatio / fPrevRatio;
320
 
                icon->fHeight *= pDock->container.fRatio / fPrevRatio;
 
691
                icon->fWidth = icon->fHeight = icon->iImageWidth = icon->iImageHeight = 0;  // no request
 
692
                cairo_dock_set_icon_size_in_dock (pDock, icon);
 
693
                icon->fWidth *= pDock->container.fRatio;
 
694
                icon->fHeight *= pDock->container.fRatio;
321
695
                pDock->fFlatDockWidth += icon->fWidth + myIconsParam.iIconGap;
322
696
        }
323
697
        pDock->iMaxIconHeight *= pDock->container.fRatio / fPrevRatio;
324
 
 
325
 
        cairo_dock_set_default_renderer (pDock);
326
698
        
 
699
        //\__________________ remove any input shape
327
700
        if (pDock->pShapeBitmap != NULL)
328
701
        {
329
 
                g_object_unref ((gpointer) pDock->pShapeBitmap);
 
702
                gldi_shape_destroy (pDock->pShapeBitmap);
330
703
                pDock->pShapeBitmap = NULL;
331
704
                if (pDock->iInputState != CAIRO_DOCK_INPUT_ACTIVE)
332
705
                {
334
707
                        pDock->iInputState = CAIRO_DOCK_INPUT_ACTIVE;
335
708
                }
336
709
        }
 
710
        
 
711
        //\__________________ hide the dock
 
712
        pDock->bAutoHide = FALSE;
337
713
        gtk_widget_hide (pDock->container.pWidget);
 
714
        
338
715
        cairo_dock_update_dock_size (pDock);
339
716
}
340
717
 
341
718
 
342
 
void cairo_dock_insert_icon_in_dock_full (Icon *icon, CairoDock *pDock, gboolean bUpdateSize, gboolean bAnimated, gboolean bInsertSeparator, GCompareFunc pCompareFunc)
 
719
void cairo_dock_insert_icon_in_dock_full (Icon *icon, CairoDock *pDock, gboolean bAnimated, gboolean bInsertSeparator, GCompareFunc pCompareFunc)
343
720
{
 
721
        g_print ("%s (%s)\n", __func__, icon->cName);
344
722
        g_return_if_fail (icon != NULL);
345
723
        if (g_list_find (pDock->icons, icon) != NULL)  // elle est deja dans ce dock.
346
724
                return ;
347
725
 
348
 
        ///int iPreviousMinWidth = pDock->fFlatDockWidth;
349
 
        ///int iPreviousMaxIconHeight = pDock->iMaxIconHeight;
350
 
 
351
726
        //\______________ On regarde si on doit inserer un separateur.
352
727
        gboolean bSeparatorNeeded = FALSE;
353
728
        if (bInsertSeparator && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
354
729
        {
355
 
                Icon *pSameTypeIcon = cairo_dock_get_first_icon_of_order (pDock->icons, icon->iGroup);
 
730
                Icon *pSameTypeIcon = cairo_dock_get_first_icon_of_group (pDock->icons, icon->iGroup);
356
731
                if (pSameTypeIcon == NULL && pDock->icons != NULL)
357
732
                {
358
733
                        bSeparatorNeeded = TRUE;
359
 
                        //g_print ("separateur necessaire\n");
 
734
                        g_print ("separateur necessaire\n");
360
735
                }
361
736
        }
362
737
 
375
750
        pDock->icons = g_list_insert_sorted (pDock->icons,
376
751
                icon,
377
752
                pCompareFunc);
378
 
        icon->pContainerForLoad = CAIRO_CONTAINER (pDock);
379
 
        
380
 
        if (icon->fWidth == 0)
381
 
        {
382
 
                cairo_dock_set_icon_size (CAIRO_CONTAINER (pDock), icon);
383
 
        }
384
 
        
 
753
        cairo_dock_set_icon_container (icon, pDock);
 
754
        
 
755
        //\______________ set the icon size, now that it's inside a container.
 
756
        int wi = icon->iImageWidth, hi = icon->iImageHeight;
 
757
        cairo_dock_set_icon_size_in_dock (pDock, icon);
385
758
        icon->fWidth *= pDock->container.fRatio;
386
759
        icon->fHeight *= pDock->container.fRatio;
387
 
 
 
760
        
 
761
        if (wi != icon->iImageWidth || hi != icon->iImageHeight)  // if size has changed, reload the buffers
 
762
                cairo_dock_trigger_load_icon_buffers (icon);
 
763
        
388
764
        pDock->fFlatDockWidth += myIconsParam.iIconGap + icon->fWidth;
389
765
        if (! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
390
766
                pDock->iMaxIconHeight = MAX (pDock->iMaxIconHeight, icon->fHeight);
392
768
        //\______________ On insere un separateur si necessaire.
393
769
        if (bSeparatorNeeded)
394
770
        {
395
 
                int iOrder = cairo_dock_get_icon_order (icon);
396
 
                if (iOrder + 1 < CAIRO_DOCK_NB_GROUPS)
 
771
                // insert a separator after if needed
 
772
                Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
 
773
                if (pNextIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pNextIcon))
397
774
                {
398
 
                        Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon);
399
 
                        if (pNextIcon != NULL && ((cairo_dock_get_icon_order (pNextIcon) - cairo_dock_get_icon_order (icon)) % 2 == 0) && (cairo_dock_get_icon_order (pNextIcon) != cairo_dock_get_icon_order (icon)))
400
 
                        {
401
 
                                int iSeparatorType = iOrder + 1;
402
 
                                cd_debug ("+ insertion de %s avant %s -> iSeparatorType : %d\n", icon->cName, pNextIcon->cName, iSeparatorType);
403
 
                                cairo_dock_insert_automatic_separator_in_dock (iSeparatorType, pNextIcon->cParentDockName, pDock);
404
 
                        }
 
775
                        int iSeparatorGroup = cairo_dock_get_icon_order (icon) +
 
776
                                (cairo_dock_get_icon_order (icon) == cairo_dock_get_icon_order (pNextIcon) ? 0 : 1);  // for separators, group = order.
 
777
                        double fOrder = (cairo_dock_get_icon_order (icon) == cairo_dock_get_icon_order (pNextIcon) ? (icon->fOrder + pNextIcon->fOrder) / 2 : 0);
 
778
                        cairo_dock_insert_automatic_separator_in_dock (iSeparatorGroup, fOrder, pNextIcon->cParentDockName, pDock);
405
779
                }
406
 
                if (iOrder > 1)
 
780
                
 
781
                // insert a separator before if needed
 
782
                Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
 
783
                if (pPrevIcon != NULL && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pPrevIcon))
407
784
                {
408
 
                        Icon *pPrevIcon = cairo_dock_get_previous_icon (pDock->icons, icon);
409
 
                        if (pPrevIcon != NULL && ((cairo_dock_get_icon_order (pPrevIcon) - cairo_dock_get_icon_order (icon)) % 2 == 0) && (cairo_dock_get_icon_order (pPrevIcon) != cairo_dock_get_icon_order (icon)))
410
 
                        {
411
 
                                int iSeparatorType = iOrder - 1;
412
 
                                cd_debug ("+ insertion de %s (%d) apres %s -> iSeparatorType : %d\n", icon->cName, icon->pModuleInstance != NULL, pPrevIcon->cName, iSeparatorType);
413
 
                                cairo_dock_insert_automatic_separator_in_dock (iSeparatorType, pPrevIcon->cParentDockName, pDock);
414
 
                        }
 
785
                        int iSeparatorGroup = cairo_dock_get_icon_order (icon) -
 
786
                                (cairo_dock_get_icon_order (icon) == cairo_dock_get_icon_order (pPrevIcon) ? 0 : 1);  // for separators, group = order.
 
787
                        double fOrder = (cairo_dock_get_icon_order (icon) == cairo_dock_get_icon_order (pPrevIcon) ? (icon->fOrder + pPrevIcon->fOrder) / 2 : 0);
 
788
                        cairo_dock_insert_automatic_separator_in_dock (iSeparatorGroup, fOrder, pPrevIcon->cParentDockName, pDock);
415
789
                }
416
790
        }
417
791
        
422
796
                        icon->fInsertRemoveFactor = - 0.95;
423
797
                else
424
798
                        icon->fInsertRemoveFactor = - 0.05;
 
799
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
425
800
        }
426
801
        else
427
802
                icon->fInsertRemoveFactor = 0.;
428
 
        if (bUpdateSize)
429
 
                cairo_dock_update_dock_size (pDock);
430
803
        
431
 
        ///if (pDock->iRefCount == 0 && pDock->iVisibility == CAIRO_DOCK_VISI_RESERVE && bUpdateSize && ! pDock->bAutoHide && (pDock->fFlatDockWidth != iPreviousMinWidth || pDock->iMaxIconHeight != iPreviousMaxIconHeight))
432
 
        ///     cairo_dock_reserve_space_for_dock (pDock, TRUE);
 
804
        cairo_dock_trigger_update_dock_size (pDock);
433
805
        
434
806
        if (pDock->iRefCount != 0 && ! CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))  // on prevoit le redessin de l'icone pointant sur le sous-dock.
435
807
        {
436
808
                cairo_dock_trigger_redraw_subdock_content (pDock);
437
809
        }
438
810
        
 
811
        if (icon->pSubDock != NULL)
 
812
                cairo_dock_synchronize_one_sub_dock_orientation (icon->pSubDock, pDock, TRUE);
 
813
        
439
814
        //\______________ Notify everybody.
440
 
        cairo_dock_notify_on_object (&myDocksMgr, NOTIFICATION_INSERT_ICON, icon, pDock);
441
815
        cairo_dock_notify_on_object (pDock, NOTIFICATION_INSERT_ICON, icon, pDock);
442
816
}
443
817
 
457
831
        }
458
832
        return FALSE;
459
833
}
460
 
gboolean cairo_dock_detach_icon_from_dock (Icon *icon, CairoDock *pDock, gboolean bCheckUnusedSeparator)
 
834
gboolean cairo_dock_detach_icon_from_dock_full (Icon *icon, CairoDock *pDock, gboolean bCheckUnusedSeparator)
461
835
{
462
836
        if (pDock == NULL)
463
837
                return FALSE;
484
858
        cd_message ("%s (%s)", __func__, icon->cName);
485
859
        g_free (icon->cParentDockName);
486
860
        icon->cParentDockName = NULL;
487
 
        icon->pContainerForLoad = NULL;
 
861
        cairo_dock_set_icon_container (icon, NULL);
488
862
        
489
863
        //\___________________ On stoppe ses animations.
490
864
        cairo_dock_stop_icon_animation (icon);
497
871
        }
498
872
        
499
873
        //\___________________ On l'enleve de la liste.
500
 
        if (pDock->pFirstDrawnElement != NULL && pDock->pFirstDrawnElement->data == icon)
501
 
        {
502
 
                if (pDock->pFirstDrawnElement->next != NULL)
503
 
                        pDock->pFirstDrawnElement = pDock->pFirstDrawnElement->next;
504
 
                else
505
 
                {
506
 
                        if (pDock->icons != NULL && pDock->icons->next != NULL)  // la liste n'a pas qu'un seul element.
507
 
                                pDock->pFirstDrawnElement = pDock->icons;
508
 
                        else
509
 
                                pDock->pFirstDrawnElement = NULL;
510
 
                }
511
 
        }
512
874
        pDock->icons = g_list_delete_link (pDock->icons, ic);
513
875
        ic = NULL;
514
876
        pDock->fFlatDockWidth -= icon->fWidth + myIconsParam.iIconGap;
516
878
        //\___________________ On enleve le separateur si c'est la derniere icone de son type.
517
879
        if (bCheckUnusedSeparator && ! CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (icon))
518
880
        {
519
 
                if ((pPrevIcon == NULL || CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (pPrevIcon)) && CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (pNextIcon))
 
881
                if ((pPrevIcon == NULL || CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pPrevIcon)) && CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (pNextIcon))
520
882
                {
521
883
                        pDock->icons = g_list_delete_link (pDock->icons, next_ic);
522
884
                        next_ic = NULL;
524
886
                        cairo_dock_free_icon (pNextIcon);
525
887
                        pNextIcon = NULL;
526
888
                }
527
 
                else if (pNextIcon == NULL && CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (pPrevIcon))
 
889
                if ((pNextIcon == NULL || CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pNextIcon)) && CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (pPrevIcon))
528
890
                {
529
891
                        pDock->icons = g_list_delete_link (pDock->icons, prev_ic);
530
892
                        prev_ic = NULL;
567
929
                if (pDock->iSidDestroyEmptyDock == 0)
568
930
                        pDock->iSidDestroyEmptyDock = g_idle_add ((GSourceFunc) _destroy_empty_dock, pDock);  // on ne passe pas le nom du dock en parametre, car le dock peut se faire renommer (improbable, mais bon).
569
931
        }
 
932
        else
 
933
        {
 
934
                cairo_dock_trigger_update_dock_size (pDock);
 
935
        }
570
936
        
571
937
        //\___________________ Notify everybody.
572
938
        icon->fInsertRemoveFactor = 0.;
573
 
        cairo_dock_notify_on_object (&myDocksMgr, NOTIFICATION_REMOVE_ICON, icon, pDock);
574
939
        cairo_dock_notify_on_object (pDock, NOTIFICATION_REMOVE_ICON, icon, pDock);
575
940
        
576
941
        return TRUE;
581
946
        
582
947
        //\___________________ On detache l'icone du dock.
583
948
        if (pDock != NULL)
584
 
                cairo_dock_detach_icon_from_dock (icon, pDock, bCheckUnusedSeparator);  // on le fait maintenant, pour que l'icone ait son type correct, et ne soit pas confondue avec un separateur
 
949
                cairo_dock_detach_icon_from_dock_full (icon, pDock, bCheckUnusedSeparator);  // on le fait maintenant, pour que l'icone ait son type correct, et ne soit pas confondue avec un separateur
585
950
        
586
951
        //\___________________ On supprime l'icone du theme courant.
587
952
        if (icon->iface.on_delete)
604
969
                next_ic = ic->next;  // si l'icone se fait enlever, on perdrait le fil.
605
970
                if (CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (icon))
606
971
                {
607
 
                        //g_print ("un separateur en moins (apres %s)\n", ((Icon*)ic->data)->cName);
608
972
                        cairo_dock_remove_one_icon_from_dock (pDock, icon);
609
973
                        cairo_dock_free_icon (icon);
610
974
                }
612
976
        }
613
977
}
614
978
 
615
 
void cairo_dock_insert_separators_in_dock (CairoDock *pDock)
 
979
void cairo_dock_insert_automatic_separators_in_dock (CairoDock *pDock)
616
980
{
617
981
        //g_print ("%s ()\n", __func__);
618
 
        Icon *icon, *next_icon;
 
982
        Icon *icon, *pNextIcon;
619
983
        GList *ic;
620
984
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
621
985
        {
624
988
                {
625
989
                        if (ic->next != NULL)
626
990
                        {
627
 
                                next_icon = ic->next->data;
628
 
                                if (! CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (next_icon) && abs (cairo_dock_get_icon_order (icon) - cairo_dock_get_icon_order (next_icon)) > 1)  // icon->iType != next_icon->iType
 
991
                                pNextIcon = ic->next->data;
 
992
                                if (! CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (pNextIcon) && icon->iGroup != pNextIcon->iGroup)
629
993
                                {
630
 
                                        ///int iSeparatorType = myIconsParam.tIconTypeOrder[next_icon->iGroup] - 1;
631
 
                                        int iSeparatorType = cairo_dock_get_icon_order (next_icon) - 1;
632
 
                                        cd_debug ("+ un separateur entre %s et %s, dans le groupe %d\n", icon->cName, next_icon->cName, iSeparatorType);
633
 
                                        cairo_dock_insert_automatic_separator_in_dock (iSeparatorType, next_icon->cParentDockName, pDock);
 
994
                                        int iSeparatorGroup = cairo_dock_get_icon_order (icon) +
 
995
                                                (cairo_dock_get_icon_order (icon) == cairo_dock_get_icon_order (pNextIcon) ? 0 : 1);  // for separators, group = order.
 
996
                                        double fOrder = (cairo_dock_get_icon_order (icon) == cairo_dock_get_icon_order (pNextIcon) ? (icon->fOrder + pNextIcon->fOrder) / 2 : 0);
 
997
                                        cairo_dock_insert_automatic_separator_in_dock (iSeparatorGroup, fOrder, icon->cParentDockName, pDock);
634
998
                                }
635
999
                        }
636
1000
                }
638
1002
}
639
1003
 
640
1004
 
641
 
Icon *cairo_dock_add_new_launcher_by_uri_or_type (const gchar *cExternDesktopFileURI, CairoDockDesktopFileType iType, CairoDock *pReceivingDock, double fOrder, CairoDockIconGroup iGroup)
 
1005
Icon *cairo_dock_add_new_launcher_by_uri_or_type (const gchar *cExternDesktopFileURI, CairoDockDesktopFileType iType, CairoDock *pReceivingDock, double fOrder)
642
1006
{
643
1007
        //\_________________ On ajoute un fichier desktop dans le repertoire des lanceurs du theme courant.
644
1008
        GError *erreur = NULL;
653
1017
        }
654
1018
        gchar *cNewDesktopFileName;
655
1019
        if (cExternDesktopFileURI != NULL)
656
 
                cNewDesktopFileName = cairo_dock_add_desktop_file_from_uri (cExternDesktopFileURI, cDockName, fOrder, iGroup, &erreur);
 
1020
                cNewDesktopFileName = cairo_dock_add_desktop_file_from_uri (cExternDesktopFileURI, cDockName, fOrder, &erreur);
657
1021
        else
658
 
                cNewDesktopFileName = cairo_dock_add_desktop_file_from_type (iType, cDockName, fOrder, iGroup, &erreur);
 
1022
                cNewDesktopFileName = cairo_dock_add_desktop_file_from_type (iType, cDockName, fOrder, &erreur);
659
1023
        if (erreur != NULL)
660
1024
        {
661
1025
                cd_warning (erreur->message);
680
1044
 
681
1045
                if (pNewIcon != NULL)
682
1046
                {
683
 
                        cairo_dock_insert_icon_in_dock (pNewIcon, pReceivingDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
 
1047
                        cairo_dock_insert_icon_in_dock (pNewIcon, pReceivingDock, CAIRO_DOCK_ANIMATE_ICON);
684
1048
                        
685
1049
                        if (pNewIcon->pSubDock != NULL)
686
1050
                                cairo_dock_trigger_redraw_subdock_content (pNewIcon->pSubDock);
687
 
                        
688
 
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pReceivingDock));
689
1051
                }
690
1052
        }
691
1053
        return pNewIcon;
722
1084
                else  // on les re-attribue au dock receveur.
723
1085
                {
724
1086
                        cairo_dock_update_icon_s_container_name (icon, cReceivingDockName);
725
 
 
726
 
                        icon->fWidth /= pDock->container.fRatio;
 
1087
                        
 
1088
                        icon->fWidth /= pDock->container.fRatio;  // optimization: no need to detach the icon, we just steal all of them.
727
1089
                        icon->fHeight /= pDock->container.fRatio;
728
1090
                        
729
1091
                        cd_debug (" on re-attribue %s au dock %s", icon->cName, icon->cParentDockName);
730
 
                        cairo_dock_insert_icon_in_dock (icon, pReceivingDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
 
1092
                        cairo_dock_insert_icon_in_dock (icon, pReceivingDock, CAIRO_DOCK_ANIMATE_ICON);
731
1093
                        
732
1094
                        if (CAIRO_DOCK_IS_APPLET (icon))
733
1095
                        {
735
1097
                                icon->pModuleInstance->pDock = pReceivingDock;
736
1098
                                cairo_dock_reload_module_instance (icon->pModuleInstance, FALSE);
737
1099
                        }
738
 
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pReceivingDock));
739
1100
                }
740
1101
        }
741
 
        if (pReceivingDock != NULL)
742
 
                cairo_dock_update_dock_size (pReceivingDock);
743
1102
 
744
1103
        g_list_free (pIconsList);
745
1104
}
746
1105
 
747
1106
 
 
1107
void cairo_dock_reload_buffers_in_dock (CairoDock *pDock, gboolean bRecursive, gboolean bUpdateIconSize)
 
1108
{
 
1109
        g_print ("************%s (%d, %d)\n", __func__, pDock->bIsMainDock, bRecursive);
 
1110
        if (bUpdateIconSize && pDock->bGlobalIconSize)
 
1111
                pDock->iIconSize = myIconsParam.iIconWidth;
 
1112
        
 
1113
        // for each icon, reload its buffer (size may change).
 
1114
        Icon* icon;
 
1115
        GList* ic;
 
1116
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
 
1117
        {
 
1118
                icon = ic->data;
 
1119
                
 
1120
                if (CAIRO_DOCK_IS_APPLET (icon))  // for an applet, we need to let the module know that the size or the theme has changed, so that it can reload its private buffers.
 
1121
                {
 
1122
                        cairo_dock_reload_module_instance (icon->pModuleInstance, FALSE);
 
1123
                }
 
1124
                else
 
1125
                {
 
1126
                        if (bUpdateIconSize)
 
1127
                        {
 
1128
                                icon->fWidth = icon->fHeight = 0;  // no request
 
1129
                                icon->iImageWidth = icon->iImageHeight = 0;
 
1130
                                cairo_dock_set_icon_size_in_dock (pDock, icon);
 
1131
                        }
 
1132
                        cairo_dock_trigger_load_icon_buffers (icon);
 
1133
                }
 
1134
                
 
1135
                if (bRecursive && icon->pSubDock != NULL)  // we handle the sub-dock for applets too, so that they don't need to care.
 
1136
                {
 
1137
                        ///cairo_dock_synchronize_one_sub_dock_orientation (icon->pSubDock, pDock, FALSE);  /// should probably not be here.
 
1138
                        if (bUpdateIconSize)
 
1139
                                icon->pSubDock->iIconSize = pDock->iIconSize;
 
1140
                        cairo_dock_reload_buffers_in_dock (icon->pSubDock, bRecursive, bUpdateIconSize);
 
1141
                }
 
1142
        }
 
1143
        
 
1144
        if (bUpdateIconSize)
 
1145
        {
 
1146
                cairo_dock_update_dock_size (pDock);
 
1147
                cairo_dock_calculate_dock_icons (pDock);
 
1148
 
 
1149
                cairo_dock_move_resize_dock (pDock);
 
1150
                if (pDock->iVisibility == CAIRO_DOCK_VISI_RESERVE)  // la position/taille a change, il faut refaire la reservation.
 
1151
                        cairo_dock_reserve_space_for_dock (pDock, TRUE);
 
1152
                gtk_widget_queue_draw (pDock->container.pWidget);
 
1153
        }
 
1154
}
 
1155
 
 
1156
 
 
1157
void cairo_dock_set_icon_size_in_dock (CairoDock *pDock, Icon *icon)
 
1158
{
 
1159
        if (pDock->pRenderer && pDock->pRenderer->set_icon_size)
 
1160
        {
 
1161
                pDock->pRenderer->set_icon_size (icon, pDock);
 
1162
        }
 
1163
        else
 
1164
        {
 
1165
                int wi, hi;
 
1166
                if (pDock->iIconSize != 0)
 
1167
                {
 
1168
                        wi = hi = pDock->iIconSize;
 
1169
                }
 
1170
                else  // same size as main dock.
 
1171
                {
 
1172
                        wi = myIconsParam.iIconWidth;
 
1173
                        hi = myIconsParam.iIconHeight;
 
1174
                }
 
1175
                g_print (" size: %d => %dx%d\n", pDock->iIconSize, wi, hi);
 
1176
                double fMaxScale = cairo_dock_get_max_scale (pDock);
 
1177
                
 
1178
                // set the visible size at rest.
 
1179
                if (CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon))  // for applets, consider (fWidth,fHeight) as a requested size, if not 0.
 
1180
                {
 
1181
                        //g_print ("%s (%s, %.1fx%.1f\n", __func__, icon->pModuleInstance->pModule->pVisitCard->cModuleName, icon->fWidth, icon->fHeight);
 
1182
                        if (icon->iImageWidth != 0)
 
1183
                        {
 
1184
                                if (pDock->container.bIsHorizontal)
 
1185
                                        icon->fWidth = icon->iImageWidth / fMaxScale;
 
1186
                                else
 
1187
                                        icon->fHeight = icon->iImageWidth / fMaxScale;
 
1188
                        }
 
1189
                        if (icon->iImageHeight != 0)
 
1190
                        {
 
1191
                                if (pDock->container.bIsHorizontal)
 
1192
                                        icon->fHeight = icon->iImageHeight / fMaxScale;
 
1193
                                else
 
1194
                                        icon->fWidth = icon->iImageHeight / fMaxScale;
 
1195
                        }
 
1196
                        if (icon->fWidth == 0)
 
1197
                                icon->fWidth = wi;
 
1198
                        if (icon->fHeight == 0 || icon->fHeight > hi)
 
1199
                                icon->fHeight = hi;
 
1200
                }
 
1201
                else if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))  // separators have their own size.
 
1202
                {
 
1203
                        icon->fWidth = myIconsParam.iSeparatorWidth;
 
1204
                        icon->fHeight = MIN (myIconsParam.iSeparatorHeight, hi);
 
1205
                }
 
1206
                else  // any other icon use the global size
 
1207
                {
 
1208
                        icon->fWidth = wi;
 
1209
                        icon->fHeight = hi;
 
1210
                }
 
1211
                
 
1212
                // texture size can be deduced then.
 
1213
                if (pDock->container.bIsHorizontal
 
1214
                || (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon) && myIconsParam.bRevolveSeparator))
 
1215
                {
 
1216
                        icon->iImageWidth = icon->fWidth * fMaxScale;
 
1217
                        icon->iImageHeight = icon->fHeight * fMaxScale;
 
1218
                }
 
1219
                else
 
1220
                {
 
1221
                        icon->iImageWidth = icon->fHeight * fMaxScale;
 
1222
                        icon->iImageHeight = icon->fWidth * fMaxScale;
 
1223
                }
 
1224
        }
 
1225
}
 
1226
 
 
1227
 
748
1228
void cairo_dock_create_redirect_texture_for_dock (CairoDock *pDock)
749
1229
{
750
1230
        if (! g_openglConfig.bFboAvailable)
751
1231
                return ;
752
 
        if (pDock->iRedirectedTexture != 0)
753
 
                return ;
754
 
        
755
 
        pDock->iRedirectedTexture = cairo_dock_load_texture_from_raw_data (NULL,
756
 
                (pDock->container.bIsHorizontal ? pDock->container.iWidth : pDock->container.iHeight),
757
 
                (pDock->container.bIsHorizontal ? pDock->container.iHeight : pDock->container.iWidth));
758
 
        
759
 
        glGenFramebuffersEXT(1, &pDock->iFboId);
 
1232
        if (pDock->iRedirectedTexture == 0)
 
1233
        {
 
1234
                pDock->iRedirectedTexture = cairo_dock_create_texture_from_raw_data (NULL,
 
1235
                        (pDock->container.bIsHorizontal ? pDock->container.iWidth : pDock->container.iHeight),
 
1236
                        (pDock->container.bIsHorizontal ? pDock->container.iHeight : pDock->container.iWidth));
 
1237
        }
 
1238
        if (pDock->iFboId == 0)
 
1239
                glGenFramebuffersEXT(1, &pDock->iFboId);
760
1240
}