~cairo-dock-team/ubuntu/oneiric/cairo-dock/2.3.0-3

« back to all changes in this revision

Viewing changes to src/cairo-dock-application-facility.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
7
 
* This program is free software; you can redistribute it and/or
8
 
* modify it under the terms of the GNU General Public License
9
 
* as published by the Free Software Foundation; either version 3
10
 
* of the License, or (at your option) any later version.
11
 
*
12
 
* This program is distributed in the hope that it will be useful,
13
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
* GNU General Public License for more details.
16
 
* You should have received a copy of the GNU General Public License
17
 
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
#include <math.h>
21
 
#include <string.h>
22
 
#include <cairo.h>
23
 
#include <stdlib.h>
24
 
 
25
 
#include <X11/Xlib.h>
26
 
#include <X11/Xatom.h>
27
 
#include <X11/Xutil.h>
28
 
#include <gdk/gdkx.h>
29
 
#ifdef HAVE_XEXTEND
30
 
#include <X11/extensions/Xcomposite.h>
31
 
//#include <X11/extensions/Xdamage.h>
32
 
#endif
33
 
 
34
 
#include "cairo-dock-load.h"
35
 
#include "cairo-dock-icons.h"
36
 
#include "cairo-dock-draw.h"
37
 
#include "cairo-dock-draw-opengl.h"
38
 
#include "cairo-dock-dock-factory.h"
39
 
#include "cairo-dock-dialogs.h"
40
 
#include "cairo-dock-animations.h"
41
 
#include "cairo-dock-surface-factory.h"
42
 
#include "cairo-dock-applications-manager.h"
43
 
#include "cairo-dock-log.h"
44
 
#include "cairo-dock-dock-manager.h"
45
 
#include "cairo-dock-class-manager.h"
46
 
#include "cairo-dock-X-utilities.h"
47
 
#include "cairo-dock-internal-taskbar.h"
48
 
#include "cairo-dock-internal-icons.h"
49
 
#include "cairo-dock-notifications.h"
50
 
#include "cairo-dock-launcher-factory.h"
51
 
#include "cairo-dock-container.h"
52
 
#include "cairo-dock-dock-factory.h"
53
 
#include "cairo-dock-dock-facility.h"
54
 
#include "cairo-dock-callbacks.h"
55
 
#include "cairo-dock-application-facility.h"
56
 
 
57
 
extern CairoDock *g_pMainDock;
58
 
extern int g_iXScreenWidth[2], g_iXScreenHeight[2];
59
 
 
60
 
 
61
 
static void _cairo_dock_appli_demands_attention (Icon *icon, CairoDock *pDock, gboolean bForceDemand, Icon *pHiddenIcon)
62
 
{
63
 
        cd_debug ("%s (%s, force:%d)", __func__, icon->cName, bForceDemand);
64
 
        if (CAIRO_DOCK_IS_APPLET (icon))  // on considere qu'une applet prenant le controle d'une icone d'appli dispose de bien meilleurs moyens pour interagir avec l'appli que la barre des taches.
65
 
                return ;
66
 
        if (! pHiddenIcon)
67
 
                icon->bIsDemandingAttention = TRUE;
68
 
        //\____________________ On montre le dialogue.
69
 
        if (myTaskBar.bDemandsAttentionWithDialog)
70
 
        {
71
 
                CairoDialog *pDialog;
72
 
                if (pHiddenIcon == NULL)
73
 
                {
74
 
                        pDialog = cairo_dock_show_temporary_dialog_with_icon (icon->cName, icon, CAIRO_CONTAINER (pDock), 1000*myTaskBar.iDialogDuration, "same icon");
75
 
                }
76
 
                else
77
 
                {
78
 
                        pDialog = cairo_dock_show_temporary_dialog (pHiddenIcon->cName, icon, CAIRO_CONTAINER (pDock), 1000*myTaskBar.iDialogDuration); // mieux vaut montrer d'icone dans le dialogue que de montrer une icone qui n'a pas de rapport avec l'appli demandant l'attention.
79
 
                        g_return_if_fail (pDialog != NULL);
80
 
                        cairo_dock_set_new_dialog_icon_surface (pDialog, pHiddenIcon->pIconBuffer, pDialog->iIconSize);
81
 
                }
82
 
                if (pDialog && bForceDemand)
83
 
                {
84
 
                        cd_debug ("force dialog on top");
85
 
                        gtk_window_set_keep_above (GTK_WINDOW (pDialog->container.pWidget), TRUE);
86
 
                        Window Xid = GDK_WINDOW_XID (pDialog->container.pWidget->window);
87
 
                        cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_DOCK");  // pour passer devant les fenetres plein ecran; depend du WM.
88
 
                }
89
 
        }
90
 
        //\____________________ On montre l'icone avec une animation.
91
 
        if (myTaskBar.cAnimationOnDemandsAttention && ! pHiddenIcon)  // on ne l'anime pas si elle n'est pas dans un dock.
92
 
        {
93
 
                if (pDock->iRefCount == 0)
94
 
                {
95
 
                        if (bForceDemand || cairo_dock_search_window_on_our_way (pDock, FALSE, TRUE) == NULL)
96
 
                        {
97
 
                                if (pDock->iSidPopDown != 0)
98
 
                                {
99
 
                                        g_source_remove(pDock->iSidPopDown);
100
 
                                        pDock->iSidPopDown = 0;
101
 
                                }
102
 
                                cairo_dock_pop_up (pDock);
103
 
                        }
104
 
                        /*if (pDock->bAutoHide && bForceDemand)
105
 
                        {
106
 
                                g_print ("force dock to raise\n");
107
 
                                cairo_dock_emit_enter_signal (pDock);
108
 
                        }*/
109
 
                }
110
 
                else if (bForceDemand)
111
 
                {
112
 
                        cd_debug ("force sub-dock to raise\n");
113
 
                        CairoDock *pParentDock = NULL;
114
 
                        Icon *pPointedIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
115
 
                        if (pParentDock)
116
 
                                cairo_dock_show_subdock (pPointedIcon, pParentDock, FALSE);
117
 
                }
118
 
                cairo_dock_request_icon_animation (icon, pDock, myTaskBar.cAnimationOnDemandsAttention, 10000);
119
 
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));  // dans le au cas ou le dock ne serait pas encore visible, la fonction precedente n'a pas lance l'animation.
120
 
        }
121
 
}
122
 
void cairo_dock_appli_demands_attention (Icon *icon)
123
 
{
124
 
        cd_debug ("%s (%s / %s , %d)", __func__, icon->cName, icon->cLastAttentionDemand, icon->bIsDemandingAttention);
125
 
        if (icon->Xid == cairo_dock_get_current_active_window ())  // apparemment ce cas existe, et conduit a ne pas pouvoir stopper l'animation de demande d'attention facilement.
126
 
        {
127
 
                cd_message ("cette fenetre a deja le focus, elle ne peut demander l'attention en plus.");
128
 
                return ;
129
 
        }
130
 
        if (icon->bIsDemandingAttention &&
131
 
                /*cairo_dock_icon_has_dialog (icon) &&*/
132
 
                icon->cLastAttentionDemand && icon->cName && strcmp (icon->cLastAttentionDemand, icon->cName) == 0)  // le message n'a pas change entre les 2 demandes.
133
 
        {
134
 
                return ;
135
 
        }
136
 
        g_free (icon->cLastAttentionDemand);
137
 
        icon->cLastAttentionDemand = g_strdup (icon->cName);
138
 
        
139
 
        gboolean bForceDemand = (myTaskBar.cForceDemandsAttention && icon->cClass && g_strstr_len (myTaskBar.cForceDemandsAttention, -1, icon->cClass));
140
 
        CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
141
 
        if (pParentDock == NULL)  // appli inhibee ou non affichee.
142
 
        {
143
 
                icon->bIsDemandingAttention = TRUE;  // on met a TRUE meme si ce n'est pas reellement elle qui va prendre la demande.
144
 
                Icon *pInhibitorIcon = cairo_dock_get_inhibator (icon, TRUE);  // on cherche son inhibiteur dans un dock.
145
 
                if (pInhibitorIcon != NULL)  // appli inhibee.
146
 
                {
147
 
                        pParentDock = cairo_dock_search_dock_from_name (pInhibitorIcon->cParentDockName);
148
 
                        if (pParentDock != NULL)
149
 
                                _cairo_dock_appli_demands_attention (pInhibitorIcon, pParentDock, bForceDemand, NULL);
150
 
                }
151
 
                else if (bForceDemand)  // appli pas affichee, mais on veut tout de mļæ½me etre notifie.
152
 
                {
153
 
                        Icon *pOneIcon = cairo_dock_get_dialogless_icon ();
154
 
                        if (pOneIcon != NULL)
155
 
                                _cairo_dock_appli_demands_attention (pOneIcon, g_pMainDock, bForceDemand, icon);
156
 
                }
157
 
        }
158
 
        else  // appli dans un dock.
159
 
                _cairo_dock_appli_demands_attention (icon, pParentDock, bForceDemand, NULL);
160
 
}
161
 
 
162
 
static void _cairo_dock_appli_stops_demanding_attention (Icon *icon, CairoDock *pDock)
163
 
{
164
 
        if (CAIRO_DOCK_IS_APPLET (icon))
165
 
                return ;
166
 
        icon->bIsDemandingAttention = FALSE;
167
 
        if (myTaskBar.bDemandsAttentionWithDialog)
168
 
                cairo_dock_remove_dialog_if_any (icon);
169
 
        if (myTaskBar.cAnimationOnDemandsAttention)
170
 
        {
171
 
                cairo_dock_stop_icon_animation (icon);  // arrete l'animation precedemment lancee par la demande.
172
 
                cairo_dock_redraw_container (CAIRO_CONTAINER (pDock));  // optimisation possible : ne redessiner que l'icone en tenant compte de la zone de sa derniere animation (pulse ou rebond).
173
 
        }
174
 
        if (! pDock->container.bInside)
175
 
        {
176
 
                //g_print ("pop down the dock\n");
177
 
                cairo_dock_pop_down (pDock);
178
 
                
179
 
                if (pDock->bAutoHide)
180
 
                {
181
 
                        //g_print ("force dock to auto-hide\n");
182
 
                        cairo_dock_emit_leave_signal (pDock);
183
 
                }
184
 
        }
185
 
}
186
 
void cairo_dock_appli_stops_demanding_attention (Icon *icon)
187
 
{
188
 
        CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
189
 
        if (pParentDock == NULL)
190
 
        {
191
 
                icon->bIsDemandingAttention = FALSE;  // idem que plus haut.
192
 
                Icon *pInhibitorIcon = cairo_dock_get_inhibator (icon, TRUE);
193
 
                if (pInhibitorIcon != NULL)
194
 
                {
195
 
                        pParentDock = cairo_dock_search_dock_from_name (pInhibitorIcon->cParentDockName);
196
 
                        if (pParentDock != NULL)
197
 
                                _cairo_dock_appli_stops_demanding_attention (pInhibitorIcon, pParentDock);
198
 
                }
199
 
        }
200
 
        else
201
 
                _cairo_dock_appli_stops_demanding_attention (icon, pParentDock);
202
 
}
203
 
 
204
 
 
205
 
void cairo_dock_animate_icon_on_active (Icon *icon, CairoDock *pParentDock)
206
 
{
207
 
        g_return_if_fail (pParentDock != NULL);
208
 
        if (! cairo_dock_icon_is_being_inserted_or_removed (icon))  // sinon on laisse l'animation actuelle.
209
 
        {
210
 
                if (myTaskBar.cAnimationOnActiveWindow)
211
 
                {
212
 
                        if (cairo_dock_animation_will_be_visible (pParentDock) && icon->iAnimationState == CAIRO_DOCK_STATE_REST)
213
 
                                cairo_dock_request_icon_animation (icon, pParentDock, myTaskBar.cAnimationOnActiveWindow, 1);
214
 
                }
215
 
                else
216
 
                {
217
 
                        cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pParentDock));  // Si pas d'animation, on le fait pour redessiner l'indicateur.
218
 
                }
219
 
                if (pParentDock->iRefCount != 0)  // l'icone est dans un sous-dock, on veut que l'indicateur soit aussi dessine sur l'icone pointant sur ce sous-dock.
220
 
                {
221
 
                        CairoDock *pMainDock = NULL;
222
 
                        Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pParentDock, &pMainDock);
223
 
                        if (pPointingIcon && pMainDock)
224
 
                        {
225
 
                                cairo_dock_redraw_icon (pPointingIcon, CAIRO_CONTAINER (pMainDock));  // on se contente de redessiner cette icone sans l'animer. Une facon comme une autre de differencier ces 2 cas.
226
 
                        }
227
 
                }
228
 
        }
229
 
}
230
 
 
231
 
 
232
 
 
233
 
static inline gboolean _cairo_dock_window_hovers_dock (GtkAllocation *pWindowGeometry, CairoDock *pDock)
234
 
{
235
 
        if (pWindowGeometry->width != 0 && pWindowGeometry->height != 0)
236
 
        {
237
 
                int iDockX, iDockY, iDockWidth, iDockHeight;
238
 
                if (pDock->container.bIsHorizontal)
239
 
                {
240
 
                        iDockX = pDock->container.iWindowPositionX;
241
 
                        iDockY = pDock->container.iWindowPositionY + (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iMinDockHeight : 0);
242
 
                        iDockWidth = pDock->iMinDockWidth;
243
 
                        iDockHeight = pDock->iMinDockHeight;
244
 
                }
245
 
                else
246
 
                {
247
 
                        iDockX = pDock->container.iWindowPositionY + (pDock->container.bDirectionUp ? pDock->container.iHeight - pDock->iMinDockHeight : 0);
248
 
                        iDockY = pDock->container.iWindowPositionX;
249
 
                        iDockWidth = pDock->iMinDockHeight;
250
 
                        iDockHeight = pDock->iMinDockWidth;
251
 
                }
252
 
                
253
 
                cd_debug ("dock : (%d;%d) %dx%d", iDockX, iDockY, iDockWidth, iDockHeight);
254
 
                if ((pWindowGeometry->x < iDockX + iDockWidth && pWindowGeometry->x + pWindowGeometry->width > iDockX) && (pWindowGeometry->y < iDockY + iDockHeight && pWindowGeometry->y + pWindowGeometry->height > iDockY))
255
 
                {
256
 
                        return TRUE;
257
 
                }
258
 
        }
259
 
        else
260
 
        {
261
 
                cd_warning (" unknown window geometry");
262
 
        }
263
 
        return FALSE;
264
 
}
265
 
gboolean cairo_dock_appli_hovers_dock (Icon *pIcon, CairoDock *pDock)
266
 
{
267
 
        return _cairo_dock_window_hovers_dock (&pIcon->windowGeometry, pDock);
268
 
}
269
 
 
270
 
 
271
 
 
272
 
 
273
 
static CairoDock *_cairo_dock_set_parent_dock_name_for_appli (Icon *icon, CairoDock *pMainDock)
274
 
{
275
 
        cd_message ("%s (%s)", __func__, icon->cName);
276
 
        CairoDock *pParentDock = pMainDock;
277
 
        g_free (icon->cParentDockName);
278
 
        if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.bGroupAppliByClass && icon->cClass != NULL && ! cairo_dock_class_is_expanded (icon->cClass))
279
 
        {
280
 
                Icon *pSameClassIcon = cairo_dock_get_classmate (icon);  // un inhibiteur dans un dock OU une appli de meme classe dans le main dock.
281
 
                if (pSameClassIcon == NULL)  // aucun classmate => elle va dans le main dock.
282
 
                {
283
 
                        cd_message ("  classe %s encore vide", icon->cClass);
284
 
                        pParentDock = cairo_dock_search_dock_from_name (icon->cClass);
285
 
                        if (pParentDock == NULL)
286
 
                        {
287
 
                                pParentDock = pMainDock;
288
 
                                icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
289
 
                        }
290
 
                        else
291
 
                        {
292
 
                                icon->cParentDockName = g_strdup (icon->cClass);
293
 
                        }
294
 
                }
295
 
                else  // on la met dans le sous-dock de sa classe.
296
 
                {
297
 
                        icon->cParentDockName = g_strdup (icon->cClass);
298
 
 
299
 
                        //\____________ On cree ce sous-dock si necessaire.
300
 
                        pParentDock = cairo_dock_search_dock_from_name (icon->cClass);
301
 
                        if (pParentDock == NULL)  // alors il faut creer le sous-dock, qu'on associera soit a pSameClassIcon soit a un fake.
302
 
                        {
303
 
                                cd_message ("  creation du dock pour la classe %s", icon->cClass);
304
 
                                pParentDock = cairo_dock_create_subdock_from_scratch (NULL, icon->cClass, pMainDock);
305
 
                        }
306
 
                        else
307
 
                                cd_message ("  sous-dock de la classe %s existant", icon->cClass);
308
 
                        
309
 
                        if (CAIRO_DOCK_IS_LAUNCHER (pSameClassIcon) || CAIRO_DOCK_IS_APPLET (pSameClassIcon))  // c'est un inhibiteur.
310
 
                        {
311
 
                                if (pSameClassIcon->Xid != 0)  // actuellement l'inhibiteur inhibe 1 seule appli.
312
 
                                {
313
 
                                        cd_debug ("actuellement l'inhibiteur inhibe 1 seule appli");
314
 
                                        Icon *pInhibatedIcon = cairo_dock_get_icon_with_Xid (pSameClassIcon->Xid);
315
 
                                        pSameClassIcon->Xid = 0;  // on lui laisse par contre l'indicateur.
316
 
                                        if (pSameClassIcon->pSubDock == NULL)
317
 
                                        {
318
 
                                                if (pSameClassIcon->cInitialName != NULL)
319
 
                                                {
320
 
                                                        CairoDock *pSameClassDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
321
 
                                                        if (pSameClassDock != NULL)
322
 
                                                        {
323
 
                                                                cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pSameClassDock));
324
 
                                                                cairo_dock_set_icon_name (pCairoContext, pSameClassIcon->cInitialName, pSameClassIcon, CAIRO_CONTAINER (pSameClassDock));  // on lui remet son nom de lanceur.
325
 
                                                                cairo_destroy (pCairoContext);
326
 
                                                        }
327
 
                                                }
328
 
                                                pSameClassIcon->pSubDock = pParentDock;
329
 
                                                CairoDock *pRootDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
330
 
                                                if (pRootDock != NULL)
331
 
                                                        cairo_dock_redraw_icon (pSameClassIcon, CAIRO_CONTAINER (pRootDock));  // on la redessine car elle prend l'indicateur de classe.
332
 
                                        }
333
 
                                        else if (pSameClassIcon->pSubDock != pParentDock)
334
 
                                                cd_warning ("this launcher (%s) already has a subdock, but it's not the class's subdock !", pSameClassIcon->cName);
335
 
                                        if (pInhibatedIcon != NULL)
336
 
                                        {
337
 
                                                cd_debug (" on insere %s dans le dock de la classe", pInhibatedIcon->cName);
338
 
                                                g_free (pInhibatedIcon->cParentDockName);
339
 
                                                pInhibatedIcon->cParentDockName = g_strdup (icon->cClass);
340
 
                                                cairo_dock_insert_icon_in_dock_full (pInhibatedIcon, pParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, ! CAIRO_DOCK_INSERT_SEPARATOR, NULL);
341
 
                                        }
342
 
                                }
343
 
                                else if (pSameClassIcon->pSubDock != pParentDock)
344
 
                                        cd_warning ("this inhibator doesn't hold the class dock !");
345
 
                        }
346
 
                        else  // c'est donc une appli du main dock.
347
 
                        {
348
 
                                //\______________ On cree une icone de paille.
349
 
                                cd_debug (" on cree un fake...");
350
 
                                CairoDock *pClassMateParentDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);  // c'est en fait le main dock.
351
 
                                Icon *pFakeClassIcon = g_new0 (Icon, 1);
352
 
                                pFakeClassIcon->cName = g_strdup (pSameClassIcon->cClass);
353
 
                                pFakeClassIcon->cClass = g_strdup (pSameClassIcon->cClass);
354
 
                                pFakeClassIcon->iType = pSameClassIcon->iType;
355
 
                                pFakeClassIcon->fOrder = pSameClassIcon->fOrder;
356
 
                                pFakeClassIcon->cParentDockName = g_strdup (pSameClassIcon->cParentDockName);
357
 
                                pFakeClassIcon->fWidth = pSameClassIcon->fWidth / pClassMateParentDock->container.fRatio;
358
 
                                pFakeClassIcon->fHeight = pSameClassIcon->fHeight / pClassMateParentDock->container.fRatio;
359
 
                                pFakeClassIcon->fXMax = pSameClassIcon->fXMax;
360
 
                                pFakeClassIcon->fXMin = pSameClassIcon->fXMin;
361
 
                                pFakeClassIcon->fXAtRest = pSameClassIcon->fXAtRest;
362
 
                                pFakeClassIcon->pSubDock = pParentDock;  // grace a cela ce sera un lanceur.
363
 
                                
364
 
                                //\______________ On la charge.
365
 
                                cairo_dock_load_one_icon_from_scratch (pFakeClassIcon, CAIRO_CONTAINER (pClassMateParentDock));
366
 
                                
367
 
                                //\______________ On detache le classmate, on le place dans le sous-dock, et on lui substitue le faux.
368
 
                                cd_debug (" on detache %s pour la passer dans le sous-dock de sa classe", pSameClassIcon->cName);
369
 
                                cairo_dock_detach_icon_from_dock (pSameClassIcon, pClassMateParentDock, FALSE);
370
 
                                g_free (pSameClassIcon->cParentDockName);
371
 
                                pSameClassIcon->cParentDockName = g_strdup (pSameClassIcon->cClass);
372
 
                                cairo_dock_insert_icon_in_dock_full (pSameClassIcon, pParentDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, ! CAIRO_DOCK_INSERT_SEPARATOR, NULL);
373
 
                                
374
 
                                cd_debug (" on lui substitue le fake");
375
 
                                cairo_dock_insert_icon_in_dock_full (pFakeClassIcon, pClassMateParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, ! CAIRO_DOCK_INSERT_SEPARATOR, NULL);
376
 
                                cairo_dock_calculate_dock_icons (pClassMateParentDock);
377
 
                                cairo_dock_redraw_icon (pFakeClassIcon, CAIRO_CONTAINER (pClassMateParentDock));
378
 
                        }
379
 
                }
380
 
        }
381
 
        else
382
 
                icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
383
 
 
384
 
        return pParentDock;
385
 
}
386
 
 
387
 
CairoDock *cairo_dock_insert_appli_in_dock (Icon *icon, CairoDock *pMainDock, gboolean bUpdateSize, gboolean bAnimate)
388
 
{
389
 
        cd_message ("%s (%s, %d)", __func__, icon->cName, icon->Xid);
390
 
        
391
 
        //\_________________ On gere ses eventuels inhibiteurs.
392
 
        if (myTaskBar.bMixLauncherAppli && cairo_dock_prevent_inhibated_class (icon))
393
 
        {
394
 
                cd_message (" -> se fait inhiber");
395
 
                return NULL;
396
 
        }
397
 
        
398
 
        //\_________________ On gere le filtre 'applis minimisees seulement'.
399
 
        if (!icon->bIsHidden && myTaskBar.bHideVisibleApplis)
400
 
        {
401
 
                cairo_dock_reserve_one_icon_geometry_for_window_manager (&icon->Xid, icon, pMainDock);  // on reserve la position de l'icone dans le dock pour que l'effet de minimisation puisse viser la bonne position avant que l'icone ne soit effectivement dans le dock.
402
 
                return NULL;
403
 
        }
404
 
        
405
 
        //\_________________ On determine dans quel dock l'inserer.
406
 
        CairoDock *pParentDock = _cairo_dock_set_parent_dock_name_for_appli (icon, pMainDock);  // renseigne cParentDockName.
407
 
        g_return_val_if_fail (pParentDock != NULL, NULL);
408
 
 
409
 
        //\_________________ On l'insere dans son dock parent en animant ce dernier eventuellement.
410
 
        if (!myIcons.iSeparateIcons && pParentDock->iRefCount == 0)
411
 
        {
412
 
                cairo_dock_set_class_order (icon);
413
 
        }
414
 
        else
415
 
                icon->fOrder == CAIRO_DOCK_LAST_ORDER;  // en dernier.
416
 
        cairo_dock_insert_icon_in_dock (icon, pParentDock, bUpdateSize, bAnimate);
417
 
        cd_message (" insertion de %s complete (%.2f %.2fx%.2f) dans %s", icon->cName, icon->fInsertRemoveFactor, icon->fWidth, icon->fHeight, icon->cParentDockName);
418
 
 
419
 
        if (bAnimate && cairo_dock_animation_will_be_visible (pParentDock))
420
 
        {
421
 
                cairo_dock_launch_animation (CAIRO_CONTAINER (pParentDock));
422
 
        }
423
 
        else
424
 
        {
425
 
                icon->fInsertRemoveFactor = 0;
426
 
                icon->fScale = 1.;
427
 
        }
428
 
 
429
 
        return pParentDock;
430
 
}
431
 
 
432
 
CairoDock * cairo_dock_detach_appli (Icon *pIcon)
433
 
{
434
 
        cd_debug ("%s (%s)", __func__, pIcon->cName);
435
 
        CairoDock *pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
436
 
        if (pParentDock == NULL)
437
 
                return NULL;
438
 
        
439
 
        cairo_dock_detach_icon_from_dock (pIcon, pParentDock, TRUE);
440
 
        
441
 
        if (pIcon->cClass != NULL && pParentDock == cairo_dock_search_dock_from_name (pIcon->cClass))
442
 
        {
443
 
                gboolean bEmptyClassSubDock = cairo_dock_check_class_subdock_is_empty (pParentDock, pIcon->cClass);
444
 
                if (bEmptyClassSubDock)
445
 
                        return NULL;
446
 
        }
447
 
        cairo_dock_update_dock_size (pParentDock);
448
 
        return pParentDock;
449
 
}
450
 
 
451
 
#define x_icon_geometry(icon, pDock) (pDock->container.iWindowPositionX + icon->fXAtRest + (pDock->container.iWidth - pDock->fFlatDockWidth) / 2 + (pDock->iOffsetForExtend * (pDock->fAlign - .5) * 2))
452
 
#define y_icon_geometry(icon, pDock) (pDock->container.iWindowPositionY + icon->fDrawY - icon->fHeight * myIcons.fAmplitude * pDock->fMagnitudeMax)
453
 
void  cairo_dock_set_one_icon_geometry_for_window_manager (Icon *icon, CairoDock *pDock)
454
 
{
455
 
        //g_print ("%s (%s)\n", __func__, icon->cName);
456
 
        int iX, iY, iWidth, iHeight;
457
 
        iX = x_icon_geometry (icon, pDock);
458
 
        iY = y_icon_geometry (icon, pDock);  // il faudrait un fYAtRest ...
459
 
        //g_print (" -> %d;%d (%.2f)\n", iX - pDock->container.iWindowPositionX, iY - pDock->container.iWindowPositionY, icon->fXAtRest);
460
 
        iWidth = icon->fWidth;
461
 
        iHeight = icon->fHeight * (1. + 2*myIcons.fAmplitude * pDock->fMagnitudeMax);  // on elargit en haut et en bas, pour gerer les cas ou l'icone grossirait vers le haut ou vers le bas.
462
 
        
463
 
        if (pDock->container.bIsHorizontal)
464
 
                cairo_dock_set_xicon_geometry (icon->Xid, iX, iY, iWidth, iHeight);
465
 
        else
466
 
                cairo_dock_set_xicon_geometry (icon->Xid, iY, iX, iHeight, iWidth);
467
 
}
468
 
 
469
 
void cairo_dock_reserve_one_icon_geometry_for_window_manager (Window *Xid, Icon *icon, CairoDock *pMainDock)
470
 
{
471
 
        if (CAIRO_DOCK_IS_APPLI (icon) && icon->cParentDockName == NULL)
472
 
        {
473
 
                Icon *pInhibator = cairo_dock_get_inhibator (icon, FALSE);  // FALSE <=> meme en-dehors d'un dock
474
 
                if (pInhibator == NULL)  // cette icone n'est pas inhinbee, donc se minimisera dans le dock en une nouvelle icone.
475
 
                {
476
 
                        int x, y;
477
 
                        Icon *pClassmate = cairo_dock_get_classmate (icon);
478
 
                        CairoDock *pClassmateDock = (pClassmate ? cairo_dock_search_dock_from_name (pClassmate->cParentDockName) : NULL);
479
 
                        if (myTaskBar.bGroupAppliByClass && pClassmate != NULL && pClassmateDock != NULL)  // on va se grouper avec cette icone.
480
 
                        {
481
 
                                x = x_icon_geometry (pClassmate, pClassmateDock);
482
 
                                if (cairo_dock_is_hidden (pMainDock))
483
 
                                {
484
 
                                        y = (pClassmateDock->container.bDirectionUp ? 0 : g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
485
 
                                }
486
 
                                else
487
 
                                {
488
 
                                        y = y_icon_geometry (pClassmate, pClassmateDock);
489
 
                                }
490
 
                        }
491
 
                        else if (!myIcons.iSeparateIcons && pClassmate != NULL && pClassmateDock != NULL)  // on va se placer a cote.
492
 
                        {
493
 
                                x = x_icon_geometry (pClassmate, pClassmateDock) + pClassmate->fWidth/2;
494
 
                                if (cairo_dock_is_hidden (pClassmateDock))
495
 
                                {
496
 
                                        y = (pClassmateDock->container.bDirectionUp ? 0 : g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
497
 
                                }
498
 
                                else
499
 
                                {
500
 
                                        y = y_icon_geometry (pClassmate, pClassmateDock);
501
 
                                }
502
 
                        }
503
 
                        else  // on va se placer a la fin de la barre des taches.
504
 
                        {
505
 
                                Icon *pLastAppli = cairo_dock_get_last_icon_until_order (pMainDock->icons, CAIRO_DOCK_APPLI);
506
 
                                if (pLastAppli != NULL)  // on se placera juste apres.
507
 
                                {
508
 
                                        x = x_icon_geometry (pLastAppli, pMainDock) + pLastAppli->fWidth/2;
509
 
                                        if (cairo_dock_is_hidden (pMainDock))
510
 
                                        {
511
 
                                                y = (pMainDock->container.bDirectionUp ? 0 : g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
512
 
                                        }
513
 
                                        else
514
 
                                        {
515
 
                                                y = y_icon_geometry (pLastAppli, pMainDock);
516
 
                                        }
517
 
                                }
518
 
                                else  // aucune icone avant notre groupe, on sera insere en 1er.
519
 
                                {
520
 
                                        x = pMainDock->container.iWindowPositionX + 0 + (pMainDock->container.iWidth - pMainDock->fFlatDockWidth) / 2;
521
 
                                        if (cairo_dock_is_hidden (pMainDock))
522
 
                                        {
523
 
                                                y = (pMainDock->container.bDirectionUp ? 0 : g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
524
 
                                        }
525
 
                                        else
526
 
                                        {
527
 
                                                y = pMainDock->container.iWindowPositionY;
528
 
                                        }
529
 
                                }
530
 
                        }
531
 
                        //g_print (" - %s en (%d;%d)\n", icon->cName, x, y);
532
 
                        if (pMainDock->container.bIsHorizontal)
533
 
                                cairo_dock_set_xicon_geometry (icon->Xid, x, y, 1, 1);
534
 
                        else
535
 
                                cairo_dock_set_xicon_geometry (icon->Xid, y, x, 1, 1);
536
 
                }
537
 
                else
538
 
                {
539
 
                        /// gerer les desklets...
540
 
                        
541
 
                }
542
 
        }
543
 
}