2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
28
#include <glitz-glx.h>
29
#include <cairo-glitz.h>
32
#include "cairo-dock-icons.h"
33
#include "cairo-dock-dock-factory.h"
34
#include "cairo-dock-dock-facility.h"
35
#include "cairo-dock-callbacks.h"
36
#include "cairo-dock-draw.h"
37
#include "cairo-dock-draw-opengl.h"
38
#include "cairo-dock-dialog-manager.h"
39
#include "cairo-dock-applications-manager.h"
40
#include "cairo-dock-dock-manager.h"
41
#include "cairo-dock-log.h"
42
#include "cairo-dock-gui-manager.h"
43
#include "cairo-dock-notifications.h"
44
#include "cairo-dock-internal-accessibility.h"
45
#include "cairo-dock-internal-system.h"
46
#include "cairo-dock-internal-icons.h"
47
#include "cairo-dock-internal-taskbar.h"
48
#include "cairo-dock-backends-manager.h"
49
#include "cairo-dock-class-manager.h"
50
#include "cairo-dock-desklet-factory.h"
51
#include "cairo-dock-container.h"
52
#include "cairo-dock-flying-container.h"
53
#include "cairo-dock-load.h"
54
#include "cairo-dock-application-facility.h"
55
#include "cairo-dock-animations.h"
57
CairoDockHidingEffect *g_pHidingBackend = NULL;
58
CairoDockHidingEffect *g_pKeepingBelowBackend = NULL;
60
extern gboolean g_bUseOpenGL;
61
extern CairoDockGLConfig g_openglConfig;
63
static gboolean _update_fade_out_dock (gpointer pUserData, CairoDock *pDock, gboolean *bContinueAnimation)
65
pDock->iFadeCounter += (pDock->bFadeInOut ? 1 : -1); // fade out, puis fade in.
67
if (pDock->iFadeCounter >= mySystem.iHideNbSteps)
69
pDock->bFadeInOut = FALSE;
70
//g_print ("set below\n");
71
gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), TRUE);
72
// si fenetre maximisee, on met direct iFadeCounter a 0. // malheureusement X met du temps a faire passer le dock derriere, et ca donne un "sursaut" :-/
73
///if (cairo_dock_search_window_covering_dock (pDock, FALSE, FALSE) != NULL)
74
/// pDock->iFadeCounter = 0;
77
//g_print ("pDock->iFadeCounter : %d\n", pDock->iFadeCounter);
78
if (pDock->iFadeCounter > 0)
80
*bContinueAnimation = TRUE;
84
cairo_dock_remove_notification_func_on_container (CAIRO_CONTAINER (pDock),
85
CAIRO_DOCK_UPDATE_DOCK,
86
(CairoDockNotificationFunc) _update_fade_out_dock,
90
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
91
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
94
void cairo_dock_pop_up (CairoDock *pDock)
96
//g_print ("%s (%d)\n", __func__, pDock->bIsBelow);
99
cairo_dock_remove_notification_func_on_container (CAIRO_CONTAINER (pDock),
100
CAIRO_DOCK_UPDATE_DOCK,
101
(CairoDockNotificationFunc) _update_fade_out_dock,
103
pDock->iFadeCounter = 0;
104
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
105
//g_print ("set above\n");
106
gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), FALSE); // keep above
107
pDock->bIsBelow = FALSE;
111
void cairo_dock_pop_down (CairoDock *pDock)
113
//g_print ("%s (%d, %d)\n", __func__, pDock->bIsBelow, pDock->container.bInside);
114
/**if (pDock->bIsMainDock && cairo_dock_get_nb_dialog_windows () != 0)
116
if (! pDock->bIsBelow && pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->container.bInside)
118
if (cairo_dock_search_window_overlapping_dock (pDock) != NULL)
120
pDock->iFadeCounter = 0;
121
pDock->bFadeInOut = TRUE;
122
cairo_dock_register_notification_on_container (CAIRO_CONTAINER (pDock),
123
CAIRO_DOCK_UPDATE_DOCK,
124
(CairoDockNotificationFunc) _update_fade_out_dock,
125
CAIRO_DOCK_RUN_FIRST, NULL);
126
if (g_pKeepingBelowBackend != NULL && g_pKeepingBelowBackend->init)
127
g_pKeepingBelowBackend->init (pDock);
128
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
132
//g_print ("set below\n");
133
gtk_window_set_keep_below (GTK_WINDOW (pDock->container.pWidget), TRUE);
135
pDock->bIsBelow = TRUE;
137
///pDock->iSidPopDown = 0;
142
gfloat cairo_dock_calculate_magnitude (gint iMagnitudeIndex) // merci a Robrob pour le patch !
144
gfloat tmp= ((gfloat)iMagnitudeIndex)/CAIRO_DOCK_NB_MAX_ITERATIONS;
147
tmp=1.0f-(1.0f-tmp)*(1.0f-tmp)*(1.0f-tmp)*4.0f;
149
tmp=tmp*tmp*tmp*4.0f;
160
static gboolean _cairo_dock_grow_up (CairoDock *pDock)
162
//g_print ("%s (%d ; %2f ; bInside:%d)\n", __func__, pDock->iMagnitudeIndex, pDock->fFoldingFactor, pDock->container.bInside);
163
if (pDock->bIsShrinkingDown)
164
return TRUE; // on se met en attente de fin d'animation.
166
pDock->iMagnitudeIndex += mySystem.iGrowUpInterval;
167
if (pDock->iMagnitudeIndex > CAIRO_DOCK_NB_MAX_ITERATIONS)
168
pDock->iMagnitudeIndex = CAIRO_DOCK_NB_MAX_ITERATIONS;
170
if (pDock->fFoldingFactor != 0)
172
int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
173
if (iAnimationDeltaT == 0) // precaution.
175
cairo_dock_set_default_animation_delta_t (pDock);
176
iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
178
pDock->fFoldingFactor -= (double) iAnimationDeltaT / mySystem.iUnfoldingDuration;
179
if (pDock->fFoldingFactor < 0)
180
pDock->fFoldingFactor = 0;
183
if (pDock->container.bIsHorizontal)
184
gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
186
gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
188
Icon *pLastPointedIcon = cairo_dock_get_pointed_icon (pDock->icons);
189
Icon *pPointedIcon = cairo_dock_calculate_dock_icons (pDock);
190
if (! pDock->bIsGrowingUp)
193
if (pLastPointedIcon != pPointedIcon && pDock->container.bInside)
194
cairo_dock_on_change_icon (pLastPointedIcon, pPointedIcon, pDock);
196
if (pDock->iMagnitudeIndex == CAIRO_DOCK_NB_MAX_ITERATIONS && pDock->fFoldingFactor == 0) // fin de grossissement et de depliage.
198
if (pDock->bWMIconsNeedUpdate)
200
cairo_dock_trigger_set_WM_icons_geometry (pDock);
201
pDock->bWMIconsNeedUpdate = FALSE;
204
cairo_dock_replace_all_dialogs ();
211
static gboolean _cairo_dock_shrink_down (CairoDock *pDock)
213
//g_print ("%s (%d, %f, %f)\n", __func__, pDock->iMagnitudeIndex, pDock->fFoldingFactor, pDock->fDecorationsOffsetX);
214
//\_________________ On fait decroitre la magnitude du dock.
215
int iPrevMagnitudeIndex = pDock->iMagnitudeIndex;
216
pDock->iMagnitudeIndex -= mySystem.iShrinkDownInterval;
217
if (pDock->iMagnitudeIndex < 0)
218
pDock->iMagnitudeIndex = 0;
220
//\_________________ On replie le dock.
221
if (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)
223
int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
224
if (iAnimationDeltaT == 0) // precaution.
226
cairo_dock_set_default_animation_delta_t (pDock);
227
iAnimationDeltaT = cairo_dock_get_animation_delta_t (pDock);
229
pDock->fFoldingFactor += (double) iAnimationDeltaT / mySystem.iUnfoldingDuration;
230
if (pDock->fFoldingFactor > 1)
231
pDock->fFoldingFactor = 1;
234
//\_________________ On remet les decorations a l'equilibre.
235
pDock->fDecorationsOffsetX *= .8;
236
if (fabs (pDock->fDecorationsOffsetX) < 3)
237
pDock->fDecorationsOffsetX = 0.;
239
//\_________________ On recupere la position de la souris manuellement (car a priori on est hors du dock).
240
if (pDock->container.bIsHorizontal) // 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. ^_^
241
gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
243
gdk_window_get_pointer (pDock->container.pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
245
//\_________________ On recalcule les icones.
246
///if (iPrevMagnitudeIndex != 0)
248
cairo_dock_calculate_dock_icons (pDock);
249
if (! pDock->bIsShrinkingDown)
252
///cairo_dock_replace_all_dialogs ();
255
if (pDock->iMagnitudeIndex == 0 && (pDock->fFoldingFactor == 0 || pDock->fFoldingFactor == 1)) // on est arrive en bas.
257
//g_print ("equilibre atteint (%d)\n", pDock->container.bInside);
258
///if (iPrevMagnitudeIndex != 0 || (pDock->fDecorationsOffsetX == 0 && (pDock->fFoldingFactor == 0 || pDock->fFoldingFactor == 1))) // on vient d'arriver en bas OU l'animation de depliage est finie.
260
if (! pDock->container.bInside) // on peut etre hors des icones sans etre hors de la fenetre.
262
//g_print ("rideau !\n");
264
//\__________________ On repasse derriere si on etait devant.
265
if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->bIsBelow)
266
cairo_dock_pop_down (pDock);
268
//\__________________ On se redimensionne en taille normale.
269
if (! pDock->bAutoHide && pDock->iRefCount == 0 && ! pDock->bMenuVisible) // fin de shrink sans auto-hide => taille normale.
271
//g_print ("taille normale (%x; %d)\n", pDock->pShapeBitmap , pDock->iInputState);
272
if (pDock->pShapeBitmap && pDock->iInputState != CAIRO_DOCK_INPUT_AT_REST)
274
//g_print ("+++ input shape at rest on end shrinking\n");
275
cairo_dock_set_input_shape_at_rest (pDock);
276
pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST;
277
///cairo_dock_replace_all_dialogs ();
280
/**else if (pDock->bAutoHide && pDock->iRefCount == 0 && pDock->fFoldingFactor != 0) // si le dock se replie, inutile de rester en taille grande avec une fenetre transparente, ca perturbe.
282
if (pDock->pHiddenShapeBitmap && pDock->iInputState != CAIRO_DOCK_INPUT_HIDDEN)
284
//g_print ("+++ input shape hidden on end shrinking\n");
285
gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
289
gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
290
pDock->pHiddenShapeBitmap,
293
pDock->iInputState = CAIRO_DOCK_INPUT_HIDDEN;
297
//\__________________ On se cache si sous-dock.
298
if (pDock->iRefCount > 0)
300
//g_print ("on cache ce sous-dock en sortant par lui\n");
301
gtk_widget_hide (pDock->container.pWidget);
302
cairo_dock_hide_parent_dock (pDock);
304
cairo_dock_hide_after_shortcut ();
308
cairo_dock_calculate_dock_icons (pDock); // relance le grossissement si on est dedans.
311
else if (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)
313
cairo_dock_calculate_dock_icons (pDock);
315
if (!pDock->bIsGrowingUp)
316
cairo_dock_replace_all_dialogs ();
317
return (!pDock->bIsGrowingUp && (pDock->fDecorationsOffsetX != 0 || (pDock->fFoldingFactor != 0 && pDock->fFoldingFactor != 1)));
321
return (!pDock->bIsGrowingUp);
325
static gboolean _cairo_dock_hide (CairoDock *pDock)
327
if (pDock->iMagnitudeIndex > 0) // on retarde le cachage du dock pour apercevoir les effets.
330
if (pDock->fHideOffset < 1)
332
pDock->fHideOffset += 1./mySystem.iHideNbSteps;
333
if (pDock->fHideOffset > .99) // fin d'anim.
335
pDock->fHideOffset = 1;
337
//g_print ("on arrete le cachage\n");
338
gboolean bVisibleIconsPresent = FALSE;
341
for (ic = pDock->icons; ic != NULL; ic = ic->next)
344
if (pIcon->fInsertRemoveFactor != 0) // on accelere l'animation d'apparition/disparition.
346
if (pIcon->fInsertRemoveFactor > 0)
347
pIcon->fInsertRemoveFactor = 0.05;
349
pIcon->fInsertRemoveFactor = - 0.05;
352
if (! pIcon->bIsDemandingAttention && ! pIcon->bAlwaysVisible)
353
cairo_dock_stop_icon_animation (pIcon); // s'il y'a une autre animation en cours, on l'arrete.
355
bVisibleIconsPresent = TRUE;
358
pDock->pRenderer->calculate_icons (pDock);
359
///pDock->fFoldingFactor = (mySystem.bAnimateOnAutoHide ? .99 : 0.); // on arme le depliage.
360
cairo_dock_allow_entrance (pDock);
362
cairo_dock_replace_all_dialogs ();
364
if (bVisibleIconsPresent) // il y'a des icones a montrer progressivement, on reste dans la boucle.
366
pDock->fPostHideOffset = 0.05;
371
pDock->fPostHideOffset = 1; // pour que les icones demandant l'attention plus tard soient visibles.
376
else if (pDock->fPostHideOffset > 0 && pDock->fPostHideOffset < 1)
378
pDock->fPostHideOffset += 1./mySystem.iHideNbSteps;
379
if (pDock->fPostHideOffset > .99)
381
pDock->fPostHideOffset = 1.;
388
static gboolean _cairo_dock_show (CairoDock *pDock)
390
pDock->fHideOffset -= 1./mySystem.iUnhideNbSteps;
391
if (pDock->fHideOffset < 0.01)
393
pDock->fHideOffset = 0;
394
cairo_dock_allow_entrance (pDock);
401
static gboolean _cairo_dock_handle_inserting_removing_icons (CairoDock *pDock)
403
gboolean bRecalculateIcons = FALSE;
404
GList* ic = pDock->icons, *next_ic;
410
if (pIcon->fInsertRemoveFactor == (gdouble)0.05)
412
gboolean bIsAppli = CAIRO_DOCK_IS_NORMAL_APPLI (pIcon);
413
if (bIsAppli && pIcon->iLastCheckTime != -1) // c'est une icone d'appli non vieille qui disparait, elle s'est probablement cachee => on la detache juste.
415
cd_message ("cette (%s) appli est toujours valide, on la detache juste", pIcon->cName);
416
pIcon->fInsertRemoveFactor = 0.; // on le fait avant le reload, sinon l'icone n'est pas rechargee.
417
if (!pIcon->bIsHidden && myTaskBar.bHideVisibleApplis) // on lui remet l'image normale qui servira d'embleme lorsque l'icone sera inseree a nouveau dans le dock.
418
cairo_dock_reload_icon_image (pIcon, CAIRO_CONTAINER (pDock));
419
cairo_dock_detach_appli (pIcon);
423
cd_message (" - %s va etre supprimee", pIcon->cName);
424
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.
426
if (pIcon->cClass != NULL && pDock == cairo_dock_search_dock_from_name (pIcon->cClass))
428
gboolean bEmptyClassSubDock = cairo_dock_check_class_subdock_is_empty (pDock, pIcon->cClass);
429
if (bEmptyClassSubDock)
431
cairo_dock_free_icon (pIcon);
436
cairo_dock_free_icon (pIcon);
437
cairo_dock_update_dock_size (pDock); // si on le fait avant le free, le dock se fige (mais continue a tourner)...
440
else if (pIcon->fInsertRemoveFactor == (gdouble)-0.05)
442
pIcon->fInsertRemoveFactor = 0; // cela n'arrete pas l'animation, qui peut se poursuivre meme apres que l'icone ait atteint sa taille maximale.
443
bRecalculateIcons = TRUE;
445
else if (pIcon->fInsertRemoveFactor != 0)
447
bRecalculateIcons = TRUE;
452
if (bRecalculateIcons)
453
cairo_dock_calculate_dock_icons (pDock);
457
static gboolean _cairo_dock_dock_animation_loop (CairoDock *pDock)
459
//g_print ("%s (%d, %d, %d)\n", __func__, pDock->iRefCount, pDock->bIsShrinkingDown, pDock->bIsGrowingUp);
460
gboolean bContinue = FALSE;
461
if (pDock->bIsShrinkingDown)
463
pDock->bIsShrinkingDown = _cairo_dock_shrink_down (pDock);
464
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
465
bContinue |= pDock->bIsShrinkingDown;
467
if (pDock->bIsGrowingUp)
469
pDock->bIsGrowingUp = _cairo_dock_grow_up (pDock);
470
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
471
bContinue |= pDock->bIsGrowingUp;
473
if (pDock->bIsHiding)
475
//g_print ("le dock se cache\n");
476
pDock->bIsHiding = _cairo_dock_hide (pDock);
477
gtk_widget_queue_draw (pDock->container.pWidget); // on n'utilise pas cairo_dock_redraw_container, sinon a la derniere iteration, le dock etant cache, la fonction ne le redessine pas.
478
bContinue |= pDock->bIsHiding;
480
if (pDock->bIsShowing)
482
pDock->bIsShowing = _cairo_dock_show (pDock);
483
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
484
bContinue |= pDock->bIsShowing;
486
//g_print (" => %d, %d\n", pDock->bIsShrinkingDown, pDock->bIsGrowingUp);
488
gboolean bUpdateSlowAnimation = FALSE;
489
pDock->container.iAnimationStep ++;
490
if (pDock->container.iAnimationStep * pDock->container.iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
492
bUpdateSlowAnimation = TRUE;
493
pDock->container.iAnimationStep = 0;
494
pDock->container.bKeepSlowAnimation = FALSE;
496
double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
497
gboolean bIconIsAnimating;
498
gboolean bNoMoreDemandingAttention = FALSE;
501
for (ic = pDock->icons; ic != NULL; ic = ic->next)
505
icon->fDeltaYReflection = 0;
506
if (myIcons.fAlphaAtRest != 1)
507
icon->fAlpha = fDockMagnitude + myIcons.fAlphaAtRest * (1 - fDockMagnitude);
509
bIconIsAnimating = FALSE;
510
if (bUpdateSlowAnimation)
512
cairo_dock_notify_on_icon (icon, CAIRO_DOCK_UPDATE_ICON_SLOW, icon, pDock, &bIconIsAnimating);
513
pDock->container.bKeepSlowAnimation |= bIconIsAnimating;
515
cairo_dock_notify_on_icon (icon, CAIRO_DOCK_UPDATE_ICON, icon, pDock, &bIconIsAnimating);
517
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.
519
gtk_widget_queue_draw (pDock->container.pWidget);
522
bContinue |= bIconIsAnimating;
523
if (! bIconIsAnimating)
525
icon->iAnimationState = CAIRO_DOCK_STATE_REST;
526
if (icon->bIsDemandingAttention)
528
icon->bIsDemandingAttention = FALSE;
529
bNoMoreDemandingAttention = TRUE;
533
bContinue |= pDock->container.bKeepSlowAnimation;
535
if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && bNoMoreDemandingAttention && ! pDock->bIsBelow && ! pDock->container.bInside)
537
//g_print ("plus de raison d'etre devant\n");
538
cairo_dock_pop_down (pDock);
541
if (! _cairo_dock_handle_inserting_removing_icons (pDock))
543
cd_debug ("ce dock n'a plus de raison d'etre");
547
if (bUpdateSlowAnimation)
549
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_UPDATE_DOCK_SLOW, pDock, &pDock->container.bKeepSlowAnimation);
551
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_UPDATE_DOCK, pDock, &bContinue);
553
if (! bContinue && ! pDock->container.bKeepSlowAnimation)
555
pDock->container.iSidGLAnimation = 0;
561
static gboolean _cairo_desklet_animation_loop (CairoDesklet *pDesklet)
563
gboolean bContinue = FALSE;
565
gboolean bUpdateSlowAnimation = FALSE;
566
pDesklet->container.iAnimationStep ++;
567
if (pDesklet->container.iAnimationStep * pDesklet->container.iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
569
bUpdateSlowAnimation = TRUE;
570
pDesklet->container.iAnimationStep = 0;
571
pDesklet->container.bKeepSlowAnimation = FALSE;
574
if (pDesklet->pIcon != NULL)
576
gboolean bIconIsAnimating = FALSE;
578
if (bUpdateSlowAnimation)
580
cairo_dock_notify_on_icon (pDesklet->pIcon, CAIRO_DOCK_UPDATE_ICON_SLOW, pDesklet->pIcon, pDesklet, &bIconIsAnimating);
581
pDesklet->container.bKeepSlowAnimation |= bIconIsAnimating;
584
cairo_dock_notify_on_icon (pDesklet->pIcon, CAIRO_DOCK_UPDATE_ICON, pDesklet->pIcon, pDesklet, &bIconIsAnimating);
585
if (! bIconIsAnimating)
586
pDesklet->pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
591
if (bUpdateSlowAnimation)
593
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_UPDATE_DESKLET_SLOW, pDesklet, &pDesklet->container.bKeepSlowAnimation);
596
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_UPDATE_DESKLET, pDesklet, &bContinue);
598
if (! bContinue && ! pDesklet->container.bKeepSlowAnimation)
600
pDesklet->container.iSidGLAnimation = 0;
607
static gboolean _cairo_flying_container_animation_loop (CairoFlyingContainer *pFlyingContainer)
609
gboolean bContinue = FALSE;
611
if (pFlyingContainer->pIcon != NULL)
613
gboolean bIconIsAnimating = FALSE;
615
cairo_dock_notify_on_icon (pFlyingContainer->pIcon, CAIRO_DOCK_UPDATE_ICON, pFlyingContainer->pIcon, pFlyingContainer, &bIconIsAnimating);
616
if (! bIconIsAnimating)
617
pFlyingContainer->pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
622
cairo_dock_notify (CAIRO_DOCK_UPDATE_FLYING_CONTAINER, pFlyingContainer, &bContinue);
626
cairo_dock_free_flying_container (pFlyingContainer);
633
static gboolean _cairo_dialog_animation_loop (CairoDialog *pDialog)
635
gboolean bContinue = FALSE;
637
gboolean bUpdateSlowAnimation = FALSE;
638
pDialog->container.iAnimationStep ++;
639
if (pDialog->container.iAnimationStep * pDialog->container.iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
641
bUpdateSlowAnimation = TRUE;
642
pDialog->container.iAnimationStep = 0;
643
pDialog->container.bKeepSlowAnimation = FALSE;
646
if (pDialog->fAppearanceCounter < 1)
648
pDialog->fAppearanceCounter += .08;
649
if (pDialog->fAppearanceCounter > .99)
651
pDialog->fAppearanceCounter = 1.;
659
if (bUpdateSlowAnimation)
661
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDialog), CAIRO_DOCK_UPDATE_DIALOG_SLOW, pDialog, &pDialog->container.bKeepSlowAnimation);
664
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDialog), CAIRO_DOCK_UPDATE_DIALOG, pDialog, &bContinue);
666
cairo_dock_redraw_container (CAIRO_CONTAINER (pDialog));
667
if (! bContinue && ! pDialog->container.bKeepSlowAnimation)
669
pDialog->container.iSidGLAnimation = 0;
676
static gboolean _cairo_default_container_animation_loop (CairoContainer *pContainer)
678
gboolean bContinue = FALSE;
680
gboolean bUpdateSlowAnimation = FALSE;
681
pContainer->iAnimationStep ++;
682
if (pContainer->iAnimationStep * pContainer->iAnimationDeltaT >= CAIRO_DOCK_MIN_SLOW_DELTA_T)
684
bUpdateSlowAnimation = TRUE;
685
pContainer->iAnimationStep = 0;
686
pContainer->bKeepSlowAnimation = FALSE;
689
if (bUpdateSlowAnimation)
691
cairo_dock_notify_on_container (pContainer, CAIRO_DOCK_UPDATE_DEFAULT_CONTAINER_SLOW, pContainer, &pContainer->bKeepSlowAnimation);
694
cairo_dock_notify_on_container (pContainer, CAIRO_DOCK_UPDATE_DEFAULT_CONTAINER, pContainer, &bContinue);
696
if (! bContinue && ! pContainer->bKeepSlowAnimation)
698
pContainer->iSidGLAnimation = 0;
705
void cairo_dock_launch_animation (CairoContainer *pContainer)
707
if (pContainer->iSidGLAnimation == 0)
709
int iAnimationDeltaT = cairo_dock_get_animation_delta_t (pContainer);
710
if (iAnimationDeltaT == 0) // precaution.
712
cairo_dock_set_default_animation_delta_t (pContainer);
713
iAnimationDeltaT = cairo_dock_get_animation_delta_t (pContainer);
715
pContainer->bKeepSlowAnimation = TRUE;
716
switch (pContainer->iType)
718
case CAIRO_DOCK_TYPE_DOCK :
719
pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_dock_dock_animation_loop, pContainer);
721
case CAIRO_DOCK_TYPE_DESKLET :
722
pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc) _cairo_desklet_animation_loop, pContainer);
724
case CAIRO_DOCK_TYPE_FLYING_CONTAINER :
725
pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_flying_container_animation_loop, pContainer);
727
case CAIRO_DOCK_TYPE_DIALOG:
728
pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_dialog_animation_loop, pContainer);
731
pContainer->iSidGLAnimation = g_timeout_add (iAnimationDeltaT, (GSourceFunc)_cairo_default_container_animation_loop, pContainer);
737
void cairo_dock_start_shrinking (CairoDock *pDock)
739
if (! pDock->bIsShrinkingDown) // on lance l'animation.
741
pDock->bIsGrowingUp = FALSE;
742
pDock->bIsShrinkingDown = TRUE;
744
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
748
void cairo_dock_start_growing (CairoDock *pDock)
750
//g_print ("%s (%d)\n", __func__, pDock->bIsGrowingUp);
751
if (! pDock->bIsGrowingUp) // on lance l'animation.
753
pDock->bIsShrinkingDown = FALSE;
754
pDock->bIsGrowingUp = TRUE;
756
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
760
void cairo_dock_start_hiding (CairoDock *pDock)
762
//g_print ("%s (%d)\n", __func__, pDock->bIsHiding);
763
if (! pDock->bIsHiding && ! pDock->container.bInside) // rien de plus desagreable que le dock qui se cache quand on est dedans.
765
pDock->bIsShowing = FALSE;
766
pDock->bIsHiding = TRUE;
768
if (pDock->pHiddenShapeBitmap && pDock->iInputState != CAIRO_DOCK_INPUT_HIDDEN)
770
//g_print ("+++ input shape hidden on start hiding\n");
771
cairo_dock_set_input_shape_hidden (pDock);
772
pDock->iInputState = CAIRO_DOCK_INPUT_HIDDEN;
775
if (g_pHidingBackend != NULL && g_pHidingBackend->init)
776
g_pHidingBackend->init (pDock);
778
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
782
void cairo_dock_start_showing (CairoDock *pDock)
784
//g_print ("%s (%d)\n", __func__, pDock->bIsShowing);
785
if (! pDock->bIsShowing) // on lance l'animation.
787
pDock->bIsShowing = TRUE;
788
pDock->bIsHiding = FALSE;
790
if (pDock->pShapeBitmap && pDock->iInputState == CAIRO_DOCK_INPUT_HIDDEN)
792
//g_print ("+++ input shape at rest on start showing\n");
793
cairo_dock_set_input_shape_at_rest (pDock);
794
pDock->iInputState = CAIRO_DOCK_INPUT_AT_REST;
797
if (g_pHidingBackend != NULL && g_pHidingBackend->init)
798
g_pHidingBackend->init (pDock);
800
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
805
void cairo_dock_start_icon_animation (Icon *pIcon, CairoDock *pDock)
807
g_return_if_fail (pIcon != NULL && pDock != NULL);
808
cd_message ("%s (%s, %d)", __func__, pIcon->cName, pIcon->iAnimationState);
810
if (pIcon->iAnimationState != CAIRO_DOCK_STATE_REST &&
811
(cairo_dock_icon_is_being_inserted_or_removed (pIcon) || pIcon->bIsDemandingAttention || cairo_dock_animation_will_be_visible (pDock)))
813
//g_print (" c'est parti\n");
814
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
818
void cairo_dock_request_icon_animation (Icon *pIcon, CairoDock *pDock, const gchar *cAnimation, int iNbRounds)
820
//cd_debug ("%s (%s, state:%d)", __func__, pIcon->cName, pIcon->iAnimationState);
821
if (pIcon->iAnimationState != CAIRO_DOCK_STATE_REST) // on le fait avant de changer d'animation, pour le cas ou l'icone ne serait plus placee au meme endroit (rebond).
822
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
823
cairo_dock_stop_icon_animation (pIcon);
825
if (cAnimation == NULL || iNbRounds == 0 || pIcon->iAnimationState != CAIRO_DOCK_STATE_REST)
827
cairo_dock_notify (CAIRO_DOCK_REQUEST_ICON_ANIMATION, pIcon, pDock, cAnimation, iNbRounds);
828
cairo_dock_start_icon_animation (pIcon, pDock);
831
void cairo_dock_request_icon_attention (Icon *pIcon, CairoDock *pDock, const gchar *cAnimation, int iNbRounds)
833
cairo_dock_stop_icon_animation (pIcon);
834
pIcon->bIsDemandingAttention = TRUE;
838
if (cAnimation == NULL || *cAnimation == '\0' || strcmp (cAnimation, "default") == 0)
840
if (myTaskBar.cAnimationOnDemandsAttention != NULL)
841
cAnimation = myTaskBar.cAnimationOnDemandsAttention;
843
cAnimation = "rotate";
846
cairo_dock_request_icon_animation (pIcon, pDock, cAnimation, iNbRounds);
847
cairo_dock_mark_icon_as_clicked (pIcon); // pour eviter qu'un simple survol ne stoppe l'animation.
849
// on reporte la demande d'attention recursivement vers le bas.
850
if (pDock->iRefCount > 0)
852
CairoDock *pParentDock = NULL;
853
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
854
if (pPointingIcon != NULL)
856
cairo_dock_request_icon_attention (pPointingIcon, pParentDock, cAnimation, iNbRounds);
859
else if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && pDock->bIsBelow)
860
cairo_dock_pop_up (pDock);
863
void cairo_dock_stop_icon_attention (Icon *pIcon, CairoDock *pDock)
865
cairo_dock_stop_icon_animation (pIcon);
866
cairo_dock_redraw_icon (pIcon, CAIRO_CONTAINER (pDock)); // a faire avant, lorsque l'icone est encore en mode demande d'attention.
867
pIcon->bIsDemandingAttention = FALSE;
869
// on stoppe la demande d'attention recursivement vers le bas.
870
if (pDock->iRefCount > 0)
873
for (ic = pDock->icons; ic != NULL; ic = ic->next)
876
if (pIcon->bIsDemandingAttention)
879
if (ic == NULL) // plus aucune animation dans ce dock.
881
CairoDock *pParentDock = NULL;
882
Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
883
if (pPointingIcon != NULL)
885
cairo_dock_stop_icon_attention (pPointingIcon, pParentDock);
889
else if (pDock->iVisibility == CAIRO_DOCK_VISI_KEEP_BELOW && ! pDock->bIsBelow && ! pDock->container.bInside)
891
cairo_dock_pop_down (pDock);
896
void cairo_dock_trigger_icon_removal_from_dock (Icon *pIcon)
898
CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
901
cairo_dock_stop_icon_animation (pIcon);
902
if (cairo_dock_animation_will_be_visible (pDock)) // sinon inutile de se taper toute l'animation.
903
pIcon->fInsertRemoveFactor = 1.0;
905
pIcon->fInsertRemoveFactor = 0.05;
906
cairo_dock_notify (CAIRO_DOCK_REMOVE_ICON, pIcon, pDock);
907
cairo_dock_start_icon_animation (pIcon, pDock);
912
void cairo_dock_mark_icon_animation_as (Icon *pIcon, CairoDockAnimationState iAnimationState)
914
if (pIcon->iAnimationState < iAnimationState)
916
pIcon->iAnimationState = iAnimationState;
919
void cairo_dock_stop_marking_icon_animation_as (Icon *pIcon, CairoDockAnimationState iAnimationState)
921
if (pIcon->iAnimationState == iAnimationState)
923
pIcon->iAnimationState = CAIRO_DOCK_STATE_REST;
928
void cairo_dock_update_removing_inserting_icon_size_default (Icon *icon)
930
icon->fInsertRemoveFactor *= .85;
931
if (icon->fInsertRemoveFactor > 0)
933
if (icon->fInsertRemoveFactor < 0.05)
934
icon->fInsertRemoveFactor = 0.05;
936
else if (icon->fInsertRemoveFactor < 0)
938
if (icon->fInsertRemoveFactor > -0.05)
939
icon->fInsertRemoveFactor = -0.05;
944
gboolean cairo_dock_update_inserting_removing_icon_notification (gpointer pUserData, Icon *pIcon, CairoDock *pDock, gboolean *bContinueAnimation)
946
if (pIcon->iGlideDirection != 0)
948
pIcon->fGlideOffset += pIcon->iGlideDirection * .1;
949
if (fabs (pIcon->fGlideOffset) > .99)
951
pIcon->fGlideOffset = pIcon->iGlideDirection;
952
pIcon->iGlideDirection = 0;
954
else if (fabs (pIcon->fGlideOffset) < .01)
956
pIcon->fGlideOffset = 0;
957
pIcon->iGlideDirection = 0;
959
*bContinueAnimation = TRUE;
960
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
963
if (pIcon->fInsertRemoveFactor == 0 || ! pIcon->bBeingRemovedByCairo)
964
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
966
cairo_dock_update_removing_inserting_icon_size_default (pIcon);
968
if (fabs (pIcon->fInsertRemoveFactor) > 0.05)
970
cairo_dock_mark_icon_as_inserting_removing (pIcon);
971
*bContinueAnimation = TRUE;
973
cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));
974
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
977
gboolean cairo_dock_on_insert_remove_icon_notification (gpointer pUserData, Icon *pIcon, CairoDock *pDock)
979
if (pIcon->iAnimationState == CAIRO_DOCK_STATE_REMOVE_INSERT)
980
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
982
pIcon->bBeingRemovedByCairo = TRUE;
983
cairo_dock_mark_icon_as_inserting_removing (pIcon); // On prend en charge le dessin de l'icone pendant sa phase d'insertion/suppression.
985
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
988
gboolean cairo_dock_stop_inserting_removing_icon_notification (gpointer pUserData, Icon *pIcon)
990
pIcon->fGlideOffset = 0;
991
pIcon->iGlideDirection = 0;
992
pIcon->bBeingRemovedByCairo = FALSE;
993
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
998
#define cairo_dock_get_transition(pIcon) (pIcon)->pTransition
1000
#define cairo_dock_set_transition(pIcon, transition) (pIcon)->pTransition = transition
1002
static gboolean _cairo_dock_transition_step (gpointer pUserData, Icon *pIcon, CairoContainer *pContainer, gboolean *bContinueAnimation)
1004
CairoDockTransition *pTransition = cairo_dock_get_transition (pIcon);
1005
if (pTransition == NULL)
1006
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1008
pTransition->iCount ++;
1009
int iDetlaT = (pTransition->bFastPace ? cairo_dock_get_animation_delta_t (pContainer) : cairo_dock_get_slow_animation_delta_t (pContainer));
1010
//int iNbSteps = 1.*pTransition->iDuration / iDetlaT;
1011
pTransition->iElapsedTime += iDetlaT;
1013
if (! pTransition->bRemoveWhenFinished && pTransition->iDuration != 0 && pTransition->iElapsedTime > pTransition->iDuration) // skip
1014
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1016
gboolean bContinue = FALSE;
1017
if (CAIRO_CONTAINER_IS_OPENGL (pTransition->pContainer))
1019
if (pTransition->render_opengl)
1021
if (! cairo_dock_begin_draw_icon (pIcon, pContainer, 0))
1022
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1023
bContinue = pTransition->render_opengl (pIcon, pTransition->pUserData);
1024
cairo_dock_end_draw_icon (pIcon, pContainer);
1026
else if (pTransition->pIconContext != NULL)
1028
cairo_dock_erase_cairo_context (pTransition->pIconContext);
1029
bContinue = pTransition->render (pIcon, pTransition->pUserData, pTransition->pIconContext);
1030
cairo_dock_update_icon_texture (pIcon);
1033
else if (pTransition->render && pTransition->pIconContext != NULL)
1035
cairo_dock_erase_cairo_context (pTransition->pIconContext);
1036
bContinue = pTransition->render (pIcon, pTransition->pUserData, pTransition->pIconContext);
1037
if (pContainer->bUseReflect)
1038
cairo_dock_add_reflection_to_icon (pIcon, pContainer);
1041
cairo_dock_redraw_icon (pIcon, pContainer);
1043
if (pTransition->iDuration != 0 && pTransition->iElapsedTime >= pTransition->iDuration)
1048
if (pTransition->bRemoveWhenFinished)
1049
cairo_dock_remove_transition_on_icon (pIcon);
1053
*bContinueAnimation = TRUE;
1055
return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1057
void cairo_dock_set_transition_on_icon (Icon *pIcon, CairoContainer *pContainer, cairo_t *pIconContext, CairoDockTransitionRenderFunc render_step_cairo, CairoDockTransitionGLRenderFunc render_step_opengl, gboolean bFastPace, gint iDuration, gboolean bRemoveWhenFinished, gpointer pUserData, GFreeFunc pFreeUserDataFunc)
1059
cairo_dock_remove_transition_on_icon (pIcon);
1061
CairoDockTransition *pTransition = g_new0 (CairoDockTransition, 1);
1062
pTransition->render = render_step_cairo;
1063
pTransition->render_opengl = render_step_opengl;
1064
pTransition->bFastPace = bFastPace;
1065
pTransition->iDuration = iDuration;
1066
pTransition->bRemoveWhenFinished = bRemoveWhenFinished;
1067
pTransition->pContainer = pContainer;
1068
pTransition->pIconContext = pIconContext;
1069
pTransition->pUserData = pUserData;
1070
pTransition->pFreeUserDataFunc = pFreeUserDataFunc;
1071
cairo_dock_set_transition (pIcon, pTransition);
1073
cairo_dock_register_notification_on_icon (pIcon, bFastPace ? CAIRO_DOCK_UPDATE_ICON : CAIRO_DOCK_UPDATE_ICON_SLOW,
1074
(CairoDockNotificationFunc) _cairo_dock_transition_step, CAIRO_DOCK_RUN_AFTER, pUserData);
1076
cairo_dock_launch_animation (pContainer);
1079
void cairo_dock_remove_transition_on_icon (Icon *pIcon)
1081
CairoDockTransition *pTransition = cairo_dock_get_transition (pIcon);
1082
if (pTransition == NULL)
1085
cairo_dock_remove_notification_func_on_icon (pIcon, pTransition->bFastPace ? CAIRO_DOCK_UPDATE_ICON : CAIRO_DOCK_UPDATE_ICON_SLOW,
1086
(CairoDockNotificationFunc) _cairo_dock_transition_step,
1087
pTransition->pUserData);
1089
if (pTransition->pFreeUserDataFunc != NULL)
1090
pTransition->pFreeUserDataFunc (pTransition->pUserData);
1091
g_free (pTransition);
1092
cairo_dock_set_transition (pIcon, NULL);