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

« back to all changes in this revision

Viewing changes to src/cairo-dock-callbacks.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 <sys/time.h>
22
 
#include <string.h>
23
 
#include <stdlib.h>
24
 
#include <unistd.h> 
25
 
#include <cairo.h>
26
 
#include <gdk/gdkkeysyms.h>
27
 
#include <gtk/gtk.h>
28
 
 
29
 
#include <X11/Xlib.h>
30
 
#include <X11/Xatom.h>
31
 
#include <X11/Xutil.h>
32
 
#include <gdk/gdkx.h>
33
 
 
34
 
#ifdef HAVE_GLITZ
35
 
#include <gdk/gdkx.h>
36
 
#include <glitz-glx.h>
37
 
#include <cairo-glitz.h>
38
 
#endif
39
 
#include <gtk/gtkgl.h>
40
 
#include <GL/glu.h>
41
 
 
42
 
#include "cairo-dock-menu.h"
43
 
#include "cairo-dock-draw.h"
44
 
#include "cairo-dock-animations.h"
45
 
#include "cairo-dock-load.h"
46
 
#include "cairo-dock-icons.h"
47
 
#include "cairo-dock-applications-manager.h"
48
 
#include "cairo-dock-desktop-file-factory.h"
49
 
#include "cairo-dock-launcher-factory.h"
50
 
#include "cairo-dock-config.h"
51
 
#include "cairo-dock-container.h"
52
 
#include "cairo-dock-dock-facility.h"
53
 
#include "cairo-dock-notifications.h"
54
 
#include "cairo-dock-themes-manager.h"
55
 
#include "cairo-dock-dialogs.h"
56
 
#include "cairo-dock-file-manager.h"
57
 
#include "cairo-dock-log.h"
58
 
#include "cairo-dock-dock-manager.h"
59
 
#include "cairo-dock-keybinder.h"
60
 
#include "cairo-dock-desklet.h"
61
 
#include "cairo-dock-draw-opengl.h"
62
 
#include "cairo-dock-flying-container.h"
63
 
#include "cairo-dock-animations.h"
64
 
#include "cairo-dock-renderer-manager.h"
65
 
#include "cairo-dock-internal-accessibility.h"
66
 
#include "cairo-dock-internal-system.h"
67
 
#include "cairo-dock-internal-taskbar.h"
68
 
#include "cairo-dock-internal-icons.h"
69
 
#include "cairo-dock-internal-background.h"
70
 
#include "cairo-dock-class-manager.h"
71
 
#include "cairo-dock-X-utilities.h"
72
 
#include "cairo-dock-callbacks.h"
73
 
 
74
 
static Icon *s_pIconClicked = NULL;  // pour savoir quand on deplace une icone a la souris. Dangereux si l'icone se fait effacer en cours ...
75
 
static int s_iClickX, s_iClickY;  // coordonnees du clic dans le dock, pour pouvoir initialiser le deplacement apres un seuil.
76
 
static CairoDock *s_pLastPointedDock = NULL;  // pour savoir quand on passe d'un dock a un autre.
77
 
static int s_iSidShowSubDockDemand = 0;
78
 
static int s_iSidShowAppliForDrop = 0;
79
 
static CairoDock *s_pDockShowingSubDock = NULL;  // on n'accede pas a son contenu, seulement l'adresse.
80
 
static CairoFlyingContainer *s_pFlyingContainer = NULL;
81
 
 
82
 
extern CairoDock *g_pMainDock;
83
 
extern gboolean g_bKeepAbove;
84
 
 
85
 
extern gint g_iXScreenWidth[2];
86
 
extern gint g_iXScreenHeight[2];
87
 
extern cairo_surface_t *g_pBackgroundSurfaceFull[2];
88
 
 
89
 
extern gboolean g_bUseOpenGL;
90
 
extern gboolean g_bLocked;
91
 
 
92
 
static gboolean s_bHideAfterShortcut = FALSE;
93
 
static gboolean s_bFrozenDock = FALSE;
94
 
static gboolean s_bIconDragged = FALSE;
95
 
 
96
 
#define _xy_is_really_outside(x, y, pDock) (pDock->container.bIsHorizontal ? (x < 0 || x >= pDock->container.iWidth || y < 0 || y >= pDock->container.iHeight) : (y < 0 || y >= pDock->container.iWidth || x < 0 || x >= pDock->container.iHeight))
97
 
#define _mouse_is_really_outside(pDock) (pDock->container.iMouseX <= 0 || pDock->container.iMouseX >= pDock->container.iWidth || pDock->container.iMouseY <= 0 || pDock->container.iMouseY >= pDock->container.iHeight)
98
 
#define CD_CLICK_ZONE 5
99
 
 
100
 
void cairo_dock_freeze_docks (gboolean bFreeze)
101
 
{
102
 
        s_bFrozenDock = bFreeze;
103
 
}
104
 
 
105
 
gboolean cairo_dock_render_dock_notification (gpointer pUserData, CairoDock *pDock, cairo_t *pCairoContext)
106
 
{
107
 
        if (! pCairoContext)  // on n'a pas mis le rendu cairo ici a cause du rendu optimise.
108
 
        {
109
 
                glLoadIdentity ();
110
 
                glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (pDock->pRenderer->bUseStencil ? GL_STENCIL_BUFFER_BIT : 0));
111
 
                cairo_dock_apply_desktop_background_opengl (CAIRO_CONTAINER (pDock));
112
 
                
113
 
                if (pDock->fHideOffset != 0)
114
 
                {
115
 
                        double dy = pDock->iMaxDockHeight * pDock->fHideOffset * (pDock->container.bDirectionUp ? -1 : 1);
116
 
                        if (pDock->container.bIsHorizontal)
117
 
                                glTranslatef (0., dy, 0.);
118
 
                        else
119
 
                                glTranslatef (-dy, 0., 0.);
120
 
                }
121
 
                pDock->pRenderer->render_opengl (pDock);
122
 
        }
123
 
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
124
 
}
125
 
 
126
 
gboolean cairo_dock_on_expose (GtkWidget *pWidget,
127
 
        GdkEventExpose *pExpose,
128
 
        CairoDock *pDock)
129
 
{
130
 
        //g_print ("%s ((%d;%d) %dx%d)\n", __func__, pExpose->area.x, pExpose->area.y, pExpose->area.width, pExpose->area.height);
131
 
        if (g_bUseOpenGL && pDock->pRenderer->render_opengl != NULL)
132
 
        {
133
 
                GdkGLContext *pGlContext = gtk_widget_get_gl_context (pDock->container.pWidget);
134
 
                GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pDock->container.pWidget);
135
 
                if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
136
 
                        return FALSE;
137
 
                
138
 
                if (pExpose->area.x + pExpose->area.y != 0)
139
 
                {
140
 
                        glEnable (GL_SCISSOR_TEST);  // ou comment diviser par 4 l'occupation CPU !
141
 
                        glScissor ((int) pExpose->area.x,
142
 
                                (int) (pDock->container.bIsHorizontal ? pDock->container.iHeight : pDock->container.iWidth) -
143
 
                                        pExpose->area.y - pExpose->area.height,  // lower left corner of the scissor box.
144
 
                                (int) pExpose->area.width,
145
 
                                (int) pExpose->area.height);
146
 
                }
147
 
                
148
 
                if (cairo_dock_is_loading ())
149
 
                {
150
 
                        // on laisse transparent
151
 
                }
152
 
                else if (cairo_dock_is_hidden (pDock))
153
 
                {
154
 
                        cairo_dock_render_hidden_dock_opengl (pDock);
155
 
                }
156
 
                else
157
 
                {
158
 
                        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_RENDER_DOCK, pDock, NULL);
159
 
                }
160
 
                glDisable (GL_SCISSOR_TEST);
161
 
                
162
 
                if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
163
 
                        gdk_gl_drawable_swap_buffers (pGlDrawable);
164
 
                else
165
 
                        glFlush ();
166
 
                gdk_gl_drawable_gl_end (pGlDrawable);
167
 
                
168
 
                return FALSE ;
169
 
        }
170
 
        
171
 
        if (pExpose->area.x + pExpose->area.y != 0)  // x et/ou y sont > 0.
172
 
        {
173
 
                if (! cairo_dock_is_hidden (pDock))
174
 
                {
175
 
                        cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_area (CAIRO_CONTAINER (pDock), &pExpose->area, NULL);
176
 
                        
177
 
                        if (pDock->fHideOffset != 0)
178
 
                        {
179
 
                                double dy = pDock->iMaxDockHeight * pDock->fHideOffset * (pDock->container.bDirectionUp ? 1 : -1);
180
 
                                if (pDock->container.bIsHorizontal)
181
 
                                        cairo_translate (pCairoContext, 0., dy);
182
 
                                else
183
 
                                        cairo_translate (pCairoContext, dy, 0.);
184
 
                        }
185
 
                        
186
 
                        if (pDock->pRenderer->render_optimized != NULL)
187
 
                                pDock->pRenderer->render_optimized (pCairoContext, pDock, &pExpose->area);
188
 
                        else
189
 
                                pDock->pRenderer->render (pCairoContext, pDock);
190
 
                        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_RENDER_DOCK, pDock, pCairoContext);
191
 
                        
192
 
                        cairo_destroy (pCairoContext);
193
 
                }
194
 
                return FALSE;
195
 
        }
196
 
        
197
 
        
198
 
        cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDock));
199
 
        
200
 
        if (cairo_dock_is_loading ())  // transparent pendant le chargement.
201
 
        {
202
 
                
203
 
        }
204
 
        else if (cairo_dock_is_hidden (pDock))
205
 
        {
206
 
                cairo_dock_render_hidden_dock (pCairoContext, pDock);
207
 
        }
208
 
        else
209
 
        {
210
 
                if (pDock->fHideOffset != 0)
211
 
                {
212
 
                        double dy = pDock->iMaxDockHeight * pDock->fHideOffset * (pDock->container.bDirectionUp ? 1 : -1);
213
 
                        if (pDock->container.bIsHorizontal)
214
 
                                cairo_translate (pCairoContext, 0., dy);
215
 
                        else
216
 
                                cairo_translate (pCairoContext, dy, 0.);
217
 
                }
218
 
                pDock->pRenderer->render (pCairoContext, pDock);
219
 
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_RENDER_DOCK, pDock, pCairoContext);
220
 
        }
221
 
        
222
 
        cairo_destroy (pCairoContext);
223
 
        
224
 
#ifdef HAVE_GLITZ
225
 
        if (pDock->container.pDrawFormat && pDock->container.pDrawFormat->doublebuffer)
226
 
                glitz_drawable_swap_buffers (pDock->container.pGlitzDrawable);
227
 
#endif
228
 
        return FALSE;
229
 
}
230
 
 
231
 
 
232
 
static gboolean _cairo_dock_show_sub_dock_delayed (CairoDock *pDock)
233
 
{
234
 
        s_iSidShowSubDockDemand = 0;
235
 
        s_pDockShowingSubDock = NULL;
236
 
        Icon *icon = cairo_dock_get_pointed_icon (pDock->icons);
237
 
        //g_print ("%s (%x, %x)", __func__, icon, icon ? icon->pSubDock:0);
238
 
        if (icon != NULL && icon->pSubDock != NULL)
239
 
                cairo_dock_show_subdock (icon, pDock, FALSE);
240
 
 
241
 
        return FALSE;
242
 
}
243
 
static gboolean _cairo_dock_show_xwindow_for_drop (gpointer data)
244
 
{
245
 
        Window Xid = GPOINTER_TO_INT (data);
246
 
        cairo_dock_show_xwindow (Xid);
247
 
        s_iSidShowAppliForDrop = 0;
248
 
        return FALSE;
249
 
}
250
 
void cairo_dock_on_change_icon (Icon *pLastPointedIcon, Icon *pPointedIcon, CairoDock *pDock)
251
 
{
252
 
        //g_print ("%s (%x;%x)\n", __func__, pLastPointedIcon, pPointedIcon);
253
 
        //cd_debug ("on change d'icone dans %x (-> %s)", pDock, (pPointedIcon != NULL ? pPointedIcon->cName : "rien"));
254
 
        if (s_iSidShowSubDockDemand != 0 && pDock == s_pDockShowingSubDock)
255
 
        {
256
 
                //cd_debug ("on annule la demande de montrage de sous-dock");
257
 
                g_source_remove (s_iSidShowSubDockDemand);
258
 
                s_iSidShowSubDockDemand = 0;
259
 
                s_pDockShowingSubDock = NULL;
260
 
        }
261
 
        
262
 
        if (pDock->bIsDragging && s_iSidShowAppliForDrop != 0)
263
 
        {
264
 
                //cd_debug ("on annule la demande de montrage d'appli");
265
 
                g_source_remove (s_iSidShowAppliForDrop);
266
 
                s_iSidShowAppliForDrop = 0;
267
 
        }
268
 
        cairo_dock_replace_all_dialogs ();
269
 
        if (pDock->bIsDragging && CAIRO_DOCK_IS_APPLI (pPointedIcon))
270
 
        {
271
 
                s_iSidShowAppliForDrop = g_timeout_add (500, (GSourceFunc) _cairo_dock_show_xwindow_for_drop, GINT_TO_POINTER (pPointedIcon->Xid));
272
 
        }
273
 
        
274
 
        //g_print ("%x/%x , %x, %x\n", pDock, s_pLastPointedDock, pLastPointedIcon, pLastPointedIcon?pLastPointedIcon->pSubDock:NULL);
275
 
        if ((pDock == s_pLastPointedDock || s_pLastPointedDock == NULL) && pLastPointedIcon != NULL && pLastPointedIcon->pSubDock != NULL)  // on a quitte une icone ayant un sous-dock.
276
 
        {
277
 
                CairoDock *pSubDock = pLastPointedIcon->pSubDock;
278
 
                if (GTK_WIDGET_VISIBLE (pSubDock->container.pWidget))
279
 
                {
280
 
                        //g_print ("on cache %s en changeant d'icone\n", pLastPointedIcon->cName);
281
 
                        if (pSubDock->iSidLeaveDemand == 0)
282
 
                        {
283
 
                                //g_print ("  on retarde le cachage du dock de %dms\n", MAX (myAccessibility.iLeaveSubDockDelay, 330));
284
 
                                pSubDock->iSidLeaveDemand = g_timeout_add (MAX (myAccessibility.iLeaveSubDockDelay, 330), (GSourceFunc) cairo_dock_emit_leave_signal, (gpointer) pSubDock);
285
 
                        }
286
 
                }
287
 
                //else
288
 
                //      cd_debug ("pas encore visible !\n");
289
 
        }
290
 
        if (pPointedIcon != NULL && pPointedIcon->pSubDock != NULL && pPointedIcon->pSubDock != s_pLastPointedDock && (! myAccessibility.bShowSubDockOnClick || CAIRO_DOCK_IS_APPLI (pPointedIcon) || pDock->bIsDragging))  // on entre sur une icone ayant un sous-dock.
291
 
        {
292
 
                //cd_debug ("il faut montrer un sous-dock");
293
 
                if (pPointedIcon->pSubDock->iSidLeaveDemand != 0)
294
 
                {
295
 
                        g_source_remove (pPointedIcon->pSubDock->iSidLeaveDemand);
296
 
                        pPointedIcon->pSubDock->iSidLeaveDemand = 0;
297
 
                }
298
 
                if (myAccessibility.iShowSubDockDelay > 0)
299
 
                {
300
 
                        //pDock->container.iMouseX = iX;
301
 
                        if (s_iSidShowSubDockDemand != 0)
302
 
                                g_source_remove (s_iSidShowSubDockDemand);
303
 
                        s_iSidShowSubDockDemand = g_timeout_add (myAccessibility.iShowSubDockDelay, (GSourceFunc) _cairo_dock_show_sub_dock_delayed, pDock);
304
 
                        s_pDockShowingSubDock = pDock;
305
 
                        //g_print ("s_iSidShowSubDockDemand <- %d\n", s_iSidShowSubDockDemand);
306
 
                }
307
 
                else
308
 
                        cairo_dock_show_subdock (pPointedIcon, pDock, FALSE);
309
 
                s_pLastPointedDock = pDock;
310
 
        }
311
 
 
312
 
        if (s_pLastPointedDock == NULL)
313
 
        {
314
 
                //g_print ("pLastPointedDock n'est plus null\n");
315
 
                s_pLastPointedDock = pDock;
316
 
        }
317
 
        if (pPointedIcon != NULL && pDock->pRenderer->render_opengl != NULL && ! CAIRO_DOCK_IS_SEPARATOR (pPointedIcon) && pPointedIcon->iAnimationState <= CAIRO_DOCK_STATE_MOUSE_HOVERED)
318
 
        {
319
 
                gboolean bStartAnimation = FALSE;
320
 
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_ENTER_ICON, pPointedIcon, pDock, &bStartAnimation);
321
 
                
322
 
                if (bStartAnimation)
323
 
                {
324
 
                        pPointedIcon->iAnimationState = CAIRO_DOCK_STATE_MOUSE_HOVERED;
325
 
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
326
 
                }
327
 
        }
328
 
}
329
 
 
330
 
 
331
 
void cairo_dock_stop_icon_glide (CairoDock *pDock)
332
 
{
333
 
        Icon *icon;
334
 
        GList *ic;
335
 
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
336
 
        {
337
 
                icon = ic->data;
338
 
                icon->fGlideOffset = 0;
339
 
                icon->iGlideDirection = 0;
340
 
        }
341
 
}
342
 
static void _cairo_dock_make_icon_glide (Icon *pPointedIcon, Icon *pMovingicon, CairoDock *pDock)
343
 
{
344
 
        Icon *icon;
345
 
        GList *ic;
346
 
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
347
 
        {
348
 
                icon = ic->data;
349
 
                if (icon == pMovingicon)
350
 
                        continue;
351
 
                //if (pDock->container.iMouseX > s_pMovingicon->fDrawXAtRest + s_pMovingicon->fWidth * s_pMovingicon->fScale /2)  // on a deplace l'icone a droite.  // fDrawXAtRest
352
 
                if (pMovingicon->fXAtRest < pPointedIcon->fXAtRest)  // on a deplace l'icone a droite.
353
 
                {
354
 
                        //g_print ("%s : %.2f / %.2f ; %.2f / %d (%.2f)\n", icon->cName, icon->fXAtRest, pMovingicon->fXAtRest, icon->fDrawX, pDock->container.iMouseX, icon->fGlideOffset);
355
 
                        if (icon->fXAtRest > pMovingicon->fXAtRest && icon->fDrawX < pDock->container.iMouseX + 5 && icon->fGlideOffset == 0)  // icone entre l'icone deplacee et le curseur.
356
 
                        {
357
 
                                //g_print ("  %s glisse vers la gauche\n", icon->cName);
358
 
                                icon->iGlideDirection = -1;
359
 
                        }
360
 
                        else if (icon->fXAtRest > pMovingicon->fXAtRest && icon->fDrawX > pDock->container.iMouseX && icon->fGlideOffset != 0)
361
 
                        {
362
 
                                //g_print ("  %s glisse vers la droite\n", icon->cName);
363
 
                                icon->iGlideDirection = 1;
364
 
                        }
365
 
                        else if (icon->fXAtRest < pMovingicon->fXAtRest && icon->fGlideOffset > 0)
366
 
                        {
367
 
                                //g_print ("  %s glisse en sens inverse vers la gauche\n", icon->cName);
368
 
                                icon->iGlideDirection = -1;
369
 
                        }
370
 
                }
371
 
                else
372
 
                {
373
 
                        //g_print ("deplacement de %s vers la gauche (%.2f / %d)\n", icon->cName, icon->fDrawX + icon->fWidth * (1+myIcons.fAmplitude) + myIcons.iIconGap, pDock->container.iMouseX);
374
 
                        if (icon->fXAtRest < pMovingicon->fXAtRest && icon->fDrawX + icon->fWidth * (1+myIcons.fAmplitude) + myIcons.iIconGap >= pDock->container.iMouseX && icon->fGlideOffset == 0)  // icone entre l'icone deplacee et le curseur.
375
 
                        {
376
 
                                //g_print ("  %s glisse vers la droite\n", icon->cName);
377
 
                                icon->iGlideDirection = 1;
378
 
                        }
379
 
                        else if (icon->fXAtRest < pMovingicon->fXAtRest && icon->fDrawX + icon->fWidth * (1+myIcons.fAmplitude) + myIcons.iIconGap <= pDock->container.iMouseX && icon->fGlideOffset != 0)
380
 
                        {
381
 
                                //g_print ("  %s glisse vers la gauche\n", icon->cName);
382
 
                                icon->iGlideDirection = -1;
383
 
                        }
384
 
                        else if (icon->fXAtRest > pMovingicon->fXAtRest && icon->fGlideOffset < 0)
385
 
                        {
386
 
                                //g_print ("  %s glisse en sens inverse vers la droite\n", icon->cName);
387
 
                                icon->iGlideDirection = 1;
388
 
                        }
389
 
                }
390
 
        }
391
 
}
392
 
gboolean cairo_dock_on_motion_notify (GtkWidget* pWidget,
393
 
        GdkEventMotion* pMotion,
394
 
        CairoDock *pDock)
395
 
{
396
 
        static double fLastTime = 0;
397
 
        if (s_bFrozenDock && pMotion != NULL && pMotion->time != 0)
398
 
                return FALSE;
399
 
        Icon *pPointedIcon=NULL, *pLastPointedIcon = cairo_dock_get_pointed_icon (pDock->icons);
400
 
        int iLastMouseX = pDock->container.iMouseX;
401
 
        //g_print ("%s (%.2f;%.2f)\n", __func__, pMotion->x, pMotion->y);
402
 
        
403
 
        if (pMotion != NULL)
404
 
        {
405
 
                //g_print ("%s (%d,%d) (%d, %.2fms, bAtBottom:%d; bIsShrinkingDown:%d)\n", __func__, (int) pMotion->x, (int) pMotion->y, pMotion->is_hint, pMotion->time - fLastTime, pDock->bAtBottom, pDock->bIsShrinkingDown);
406
 
                //\_______________ On deplace le dock si ALT est enfoncee.
407
 
                if ((pMotion->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) && (pMotion->state & GDK_BUTTON1_MASK))
408
 
                {
409
 
                        if (pDock->container.bIsHorizontal)
410
 
                        {
411
 
                                pDock->container.iWindowPositionX = pMotion->x_root - pDock->container.iMouseX;
412
 
                                pDock->container.iWindowPositionY = pMotion->y_root - pDock->container.iMouseY;
413
 
                                gtk_window_move (GTK_WINDOW (pWidget),
414
 
                                        pDock->container.iWindowPositionX,
415
 
                                        pDock->container.iWindowPositionY);
416
 
                        }
417
 
                        else
418
 
                        {
419
 
                                pDock->container.iWindowPositionX = pMotion->y_root - pDock->container.iMouseX;
420
 
                                pDock->container.iWindowPositionY = pMotion->x_root - pDock->container.iMouseY;
421
 
                                gtk_window_move (GTK_WINDOW (pWidget),
422
 
                                        pDock->container.iWindowPositionY,
423
 
                                        pDock->container.iWindowPositionX);
424
 
                        }
425
 
                        gdk_device_get_state (pMotion->device, pMotion->window, NULL, NULL);
426
 
                        return FALSE;
427
 
                }
428
 
                
429
 
                //\_______________ On recupere la position de la souris.
430
 
                if (pDock->container.bIsHorizontal)
431
 
                {
432
 
                        pDock->container.iMouseX = (int) pMotion->x;
433
 
                        pDock->container.iMouseY = (int) pMotion->y;
434
 
                }
435
 
                else
436
 
                {
437
 
                        pDock->container.iMouseX = (int) pMotion->y;
438
 
                        pDock->container.iMouseY = (int) pMotion->x;
439
 
                }
440
 
                
441
 
                //\_______________ On tire l'icone volante.
442
 
                if (s_pFlyingContainer != NULL && ! pDock->container.bInside)
443
 
                {
444
 
                        cairo_dock_drag_flying_container (s_pFlyingContainer, pDock);
445
 
                }
446
 
                
447
 
                //\_______________ On elague le flux des MotionNotify, sinon X en envoie autant que le permet le CPU !
448
 
                if (pMotion->time != 0 && pMotion->time - fLastTime < mySystem.fRefreshInterval && s_pIconClicked == NULL)
449
 
                {
450
 
                        gdk_device_get_state (pMotion->device, pMotion->window, NULL, NULL);
451
 
                        return FALSE;
452
 
                }
453
 
                
454
 
                //\_______________ On recalcule toutes les icones et on redessine.
455
 
                pPointedIcon = cairo_dock_calculate_dock_icons (pDock);
456
 
                gtk_widget_queue_draw (pWidget);
457
 
                fLastTime = pMotion->time;
458
 
                
459
 
                //\_______________ On tire l'icone cliquee.
460
 
                if (s_pIconClicked != NULL && s_pIconClicked->iAnimationState != CAIRO_DOCK_STATE_REMOVE_INSERT && ! g_bLocked && ! myAccessibility.bLockIcons && ! myAccessibility.bLockAll && (fabs (pMotion->x - s_iClickX) > CD_CLICK_ZONE || fabs (pMotion->y - s_iClickY) > CD_CLICK_ZONE))
461
 
                {
462
 
                        s_bIconDragged = TRUE;
463
 
                        s_pIconClicked->iAnimationState = CAIRO_DOCK_STATE_FOLLOW_MOUSE;
464
 
                        //pDock->fAvoidingMouseMargin = .5;
465
 
                        pDock->iAvoidingMouseIconType = s_pIconClicked->iType;  // on pourrait le faire lors du clic aussi.
466
 
                        s_pIconClicked->fScale = 1 + myIcons.fAmplitude;
467
 
                        s_pIconClicked->fDrawX = pDock->container.iMouseX  - s_pIconClicked->fWidth * s_pIconClicked->fScale / 2;
468
 
                        s_pIconClicked->fDrawY = pDock->container.iMouseY - s_pIconClicked->fHeight * s_pIconClicked->fScale / 2 ;
469
 
                        s_pIconClicked->fAlpha = 0.75;
470
 
                        if (myIcons.fAmplitude == 0)
471
 
                                gtk_widget_queue_draw (pWidget);
472
 
                }
473
 
 
474
 
                //gdk_event_request_motions (pMotion);  // ce sera pour GDK 2.12.
475
 
                gdk_device_get_state (pMotion->device, pMotion->window, NULL, NULL);  // pour recevoir d'autres MotionNotify.
476
 
        }
477
 
        else  // cas d'un drag and drop.
478
 
        {
479
 
                //g_print ("motion on drag\n");
480
 
                //\_______________ On recupere la position de la souris.
481
 
                if (pDock->container.bIsHorizontal)
482
 
                        gdk_window_get_pointer (pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
483
 
                else
484
 
                        gdk_window_get_pointer (pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
485
 
                
486
 
                //\_______________ On recalcule toutes les icones et on redessine.
487
 
                pPointedIcon = cairo_dock_calculate_dock_icons (pDock);
488
 
                gtk_widget_queue_draw (pWidget);
489
 
                
490
 
                pDock->fAvoidingMouseMargin = .25;  // on peut dropper entre 2 icones ...
491
 
                pDock->iAvoidingMouseIconType = CAIRO_DOCK_LAUNCHER;  // ... seulement entre 2 lanceurs.
492
 
        }
493
 
        
494
 
        //\_______________ On asservit les decorations au curseur.
495
 
        if (pDock->container.bInside)
496
 
        {
497
 
                if (myBackground.bDecorationsFollowMouse)
498
 
                {
499
 
                        pDock->fDecorationsOffsetX = pDock->container.iMouseX - pDock->container.iWidth / 2;
500
 
                        //g_print ("fDecorationsOffsetX <- %.2f\n", pDock->fDecorationsOffsetX);
501
 
                }
502
 
                else
503
 
                {
504
 
                        if (pDock->container.iMouseX > iLastMouseX)
505
 
                        {
506
 
                                pDock->fDecorationsOffsetX += 10;
507
 
                                if (pDock->fDecorationsOffsetX > pDock->container.iWidth / 2)
508
 
                                {
509
 
                                        if (myBackground.cBackgroundImageFile && !myBackground.bBackgroundImageRepeat)
510
 
                                                pDock->fDecorationsOffsetX -= pDock->container.iWidth;
511
 
                                        else
512
 
                                                pDock->fDecorationsOffsetX = pDock->container.iWidth / 2;
513
 
                                }
514
 
                        }
515
 
                        else
516
 
                        {
517
 
                                pDock->fDecorationsOffsetX -= 10;
518
 
                                if (pDock->fDecorationsOffsetX < - pDock->container.iWidth / 2)
519
 
                                {
520
 
                                        if (myBackground.cBackgroundImageFile && !myBackground.bBackgroundImageRepeat)
521
 
                                                pDock->fDecorationsOffsetX += pDock->container.iWidth;
522
 
                                        else
523
 
                                                pDock->fDecorationsOffsetX = - pDock->container.iWidth / 2;
524
 
                                }
525
 
                        }
526
 
                }
527
 
        }
528
 
        
529
 
        //\_______________ On gere le changement d'icone.
530
 
        gboolean bStartAnimation = FALSE;
531
 
        if (pPointedIcon != pLastPointedIcon || s_pLastPointedDock == NULL)
532
 
        {
533
 
                cairo_dock_on_change_icon (pLastPointedIcon, pPointedIcon, pDock);
534
 
                
535
 
                if (pPointedIcon != NULL && s_pIconClicked != NULL && cairo_dock_get_icon_order (s_pIconClicked) == cairo_dock_get_icon_order (pPointedIcon) && ! g_bLocked && ! myAccessibility.bLockIcons && ! myAccessibility.bLockAll)
536
 
                {
537
 
                        //g_print ("on change d'icone\n");
538
 
                        _cairo_dock_make_icon_glide (pPointedIcon, s_pIconClicked, pDock);
539
 
                        bStartAnimation = TRUE;
540
 
                }
541
 
        }
542
 
        
543
 
        //\_______________ On notifie tout le monde.
544
 
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDock), CAIRO_DOCK_MOUSE_MOVED, pDock, &bStartAnimation);
545
 
        if (bStartAnimation)
546
 
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
547
 
        
548
 
        return FALSE;
549
 
}
550
 
 
551
 
gboolean cairo_dock_emit_signal_on_dock (CairoDock *pDock, const gchar *cSignal)
552
 
{
553
 
        static gboolean bReturn;
554
 
        g_signal_emit_by_name (pDock->container.pWidget, cSignal, NULL, &bReturn);
555
 
        return FALSE;
556
 
}
557
 
gboolean cairo_dock_emit_leave_signal (CairoDock *pDock)
558
 
{
559
 
        return cairo_dock_emit_signal_on_dock (pDock, "leave-notify-event");
560
 
}
561
 
gboolean cairo_dock_emit_enter_signal (CairoDock *pDock)
562
 
{
563
 
        return cairo_dock_emit_signal_on_dock (pDock, "enter-notify-event");
564
 
}
565
 
 
566
 
 
567
 
void cairo_dock_leave_from_main_dock (CairoDock *pDock)
568
 
{
569
 
        //g_print ("%s (%d, %d)\n", __func__, pDock->iRefCount, pDock->bMenuVisible);
570
 
        pDock->iAvoidingMouseIconType = -1;
571
 
        pDock->fAvoidingMouseMargin = 0;
572
 
        pDock->container.bInside = FALSE;
573
 
        
574
 
        //\_______________ On quitte si le menu est leve, pour rester en position haute.
575
 
        if (pDock->bMenuVisible)
576
 
                return ;
577
 
        
578
 
        //\_______________ On gere le drag d'une icone hors du dock.
579
 
        if (s_pIconClicked != NULL && (CAIRO_DOCK_IS_LAUNCHER (s_pIconClicked) || CAIRO_DOCK_IS_DETACHABLE_APPLET (s_pIconClicked) || CAIRO_DOCK_IS_USER_SEPARATOR(s_pIconClicked)) && s_pFlyingContainer == NULL && ! g_bLocked && ! myAccessibility.bLockIcons && ! myAccessibility.bLockAll)
580
 
        {
581
 
                g_print ("on a sorti %s du dock (%d;%d) / %dx%d\n", s_pIconClicked->cName, pDock->container.iMouseX, pDock->container.iMouseY, pDock->container.iWidth, pDock->container.iHeight);
582
 
                
583
 
                //if (! cairo_dock_hide_child_docks (pDock))  // on quitte si on entre dans un sous-dock, pour rester en position "haute".
584
 
                //      return ;
585
 
                
586
 
                CairoDock *pOriginDock = cairo_dock_search_dock_from_name (s_pIconClicked->cParentDockName);
587
 
                g_return_if_fail (pOriginDock != NULL);
588
 
                if (pOriginDock == pDock && _mouse_is_really_outside (pDock))  // ce test est la pour parer aux WM deficients mentaux comme KWin qui nous font sortir/rentrer lors d'un clic.
589
 
                {
590
 
                        g_print (" on detache l'icone\n");
591
 
                        pOriginDock->bIconIsFlyingAway = TRUE;
592
 
                        gchar *cParentDockName = s_pIconClicked->cParentDockName;
593
 
                        s_pIconClicked->cParentDockName = NULL;
594
 
                        cairo_dock_detach_icon_from_dock (s_pIconClicked, pOriginDock, TRUE);
595
 
                        s_pIconClicked->cParentDockName = cParentDockName;
596
 
                        cairo_dock_update_dock_size (pOriginDock);
597
 
                        cairo_dock_stop_icon_glide (pOriginDock);
598
 
                        
599
 
                        s_pFlyingContainer = cairo_dock_create_flying_container (s_pIconClicked, pOriginDock, TRUE);
600
 
                        //g_print ("- s_pIconClicked <- NULL\n");
601
 
                        s_pIconClicked = NULL;
602
 
                        if (pDock->iRefCount > 0 || pDock->bAutoHide)  // pour garder le dock visible.
603
 
                        {
604
 
                                return;
605
 
                        }
606
 
                }
607
 
        }
608
 
        else if (s_pFlyingContainer != NULL && s_pFlyingContainer->pIcon != NULL && pDock->iRefCount > 0)  // on evite les bouclages.
609
 
        {
610
 
                CairoDock *pOriginDock = cairo_dock_search_dock_from_name (s_pFlyingContainer->pIcon->cParentDockName);
611
 
                if (pOriginDock == pDock)
612
 
                        return;
613
 
        }
614
 
        
615
 
        //\_______________ On lance l'animation du dock.
616
 
        if (pDock->iRefCount == 0)
617
 
        {
618
 
                //g_print ("%s (auto-hide:%d)\n", __func__, pDock->bAutoHide);
619
 
                if (pDock->bAutoHide)
620
 
                {
621
 
                        pDock->fFoldingFactor = (mySystem.bAnimateOnAutoHide ? 0.001 : 0.);
622
 
                        cairo_dock_start_hiding (pDock);
623
 
                }
624
 
        }
625
 
        else if (pDock->icons != NULL)
626
 
        {
627
 
                pDock->fFoldingFactor = (mySystem.bAnimateSubDock ? 0.001 : 0.);
628
 
                /*Icon *pIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
629
 
                cairo_dock_notify_on_icon (pIcon, CAIRO_DOCK_UNFOLD_SUBDOCK, pIcon);*/  // 2.1.4
630
 
        }
631
 
        cairo_dock_start_shrinking (pDock);  // on commence a faire diminuer la taille des icones.
632
 
}
633
 
gboolean cairo_dock_on_leave_notify (GtkWidget* pWidget, GdkEventCrossing* pEvent, CairoDock *pDock)
634
 
{
635
 
        //g_print ("%s (bInside:%d; iState:%d; iRefCount:%d)\n", __func__, pDock->container.bInside, pDock->iInputState, pDock->iRefCount);
636
 
        //\_______________ On tire le dock => on ignore le signal.
637
 
        if (pEvent != NULL && (pEvent->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) && (pEvent->state & GDK_BUTTON1_MASK))
638
 
        {
639
 
                return FALSE;
640
 
        }
641
 
        
642
 
        if (pEvent && !_xy_is_really_outside (pEvent->x, pEvent->y, pDock))  // ce test est la pour parer aux WM deficients mentaux comme KWin qui nous font sortir/rentrer lors d'un clic.
643
 
        {
644
 
                //g_print ("not really outside (%d;%d)\n", (int)pEvent->x, (int)pEvent->y);
645
 
                return FALSE;
646
 
        }
647
 
        
648
 
        //\_______________ On retarde la sortie.
649
 
        if (pDock->iSidLeaveDemand == 0 && pEvent != NULL)  // pas encore de demande de sortie et sortie naturelle.
650
 
        {
651
 
                if (pDock->iRefCount == 0)  // cas du main dock : on retarde si on pointe sur un sous-dock, pour laisser le temps au signal d'entree dans le sous-dock d'etre traite
652
 
                {
653
 
                        //g_print (" leave event : %.1f;%.1f (%dx%d)\n", pEvent->x, pEvent->y, pDock->container.iWidth, pDock->container.iHeight);
654
 
                        Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDock->icons);
655
 
                        if ((pPointedIcon != NULL && pPointedIcon->pSubDock != NULL && GTK_WIDGET_VISIBLE (pPointedIcon->pSubDock->container.pWidget)) || (pDock->bAutoHide)/* || !_xy_is_really_outside (pEvent->x, pEvent->y, pDock)*/)  // ce test est la pour parer aux WM deficients mentaux comme KWin qui nous font sortir/rentrer lors d'un clic.
656
 
                        {
657
 
                                //g_print ("  on retarde la sortie du dock de %dms\n", MAX (myAccessibility.iLeaveSubDockDelay, 330));
658
 
                                pDock->iSidLeaveDemand = g_timeout_add (MAX (myAccessibility.iLeaveSubDockDelay, 330), (GSourceFunc) cairo_dock_emit_leave_signal, (gpointer) pDock);
659
 
                                return TRUE;
660
 
                        }
661
 
                }
662
 
                else if (myAccessibility.iLeaveSubDockDelay != 0)  // cas d'un sous-dock : on retarde le cachage.
663
 
                {
664
 
                        //g_print ("  on retarde la sortie du sous-dock de %dms\n", myAccessibility.iLeaveSubDockDelay);
665
 
                        pDock->iSidLeaveDemand = g_timeout_add (myAccessibility.iLeaveSubDockDelay, (GSourceFunc) cairo_dock_emit_leave_signal, (gpointer) pDock);
666
 
                        return TRUE;
667
 
                }
668
 
        }
669
 
        pDock->iSidLeaveDemand = 0;
670
 
        
671
 
        //\_______________ Arrive ici, on est sorti du dock.
672
 
        pDock->container.bInside = FALSE;
673
 
        
674
 
        //\_______________ On cache ses sous-docks.
675
 
        if (! cairo_dock_hide_child_docks (pDock))  // on quitte si l'un des sous-docks reste visible (on est entre dedans), pour rester en position "haute".
676
 
                return TRUE;
677
 
        
678
 
        if (s_iSidShowSubDockDemand != 0 && pDock->iRefCount == 0)  // si l'un des sous-docks etait programme pour se montrer, on annule.
679
 
        {
680
 
                g_source_remove (s_iSidShowSubDockDemand);
681
 
                s_iSidShowSubDockDemand = 0;
682
 
                s_pDockShowingSubDock = NULL;
683
 
        }
684
 
        
685
 
        if (pEvent != NULL)
686
 
        {
687
 
                if (pDock->container.bIsHorizontal)
688
 
                {
689
 
                        pDock->container.iMouseX = pEvent->x;
690
 
                        pDock->container.iMouseY = pEvent->y;
691
 
                }
692
 
                else
693
 
                {
694
 
                        pDock->container.iMouseX = pEvent->y;
695
 
                        pDock->container.iMouseY = pEvent->x;
696
 
                }
697
 
        }
698
 
        
699
 
        cairo_dock_leave_from_main_dock (pDock);
700
 
        
701
 
        return TRUE;
702
 
}
703
 
 
704
 
gboolean cairo_dock_on_enter_notify (GtkWidget* pWidget, GdkEventCrossing* pEvent, CairoDock *pDock)
705
 
{
706
 
        //g_print ("%s (bIsMainDock : %d; bInside:%d; state:%d; iMagnitudeIndex:%d)\n", __func__, pDock->bIsMainDock, pDock->container.bInside, pDock->iInputState, pDock->iMagnitudeIndex);
707
 
        s_pLastPointedDock = NULL;  // ajoute le 04/10/07 pour permettre aux sous-docks d'apparaitre si on entre en pointant tout de suite sur l'icone.
708
 
        if (! cairo_dock_entrance_is_allowed (pDock))
709
 
        {
710
 
                cd_message ("* entree non autorisee");
711
 
                return FALSE;
712
 
        }
713
 
        
714
 
        // stop les timers.
715
 
        if (pDock->iSidLeaveDemand != 0)
716
 
        {
717
 
                g_source_remove (pDock->iSidLeaveDemand);
718
 
                pDock->iSidLeaveDemand = 0;
719
 
        }
720
 
        if (s_iSidShowSubDockDemand != 0)  // gere un cas tordu mais bien reel.
721
 
        {
722
 
                g_source_remove (s_iSidShowSubDockDemand);
723
 
                s_iSidShowSubDockDemand = 0;
724
 
        }
725
 
        
726
 
        // input shape desactivee, le dock devient actif.
727
 
        if ((pDock->pShapeBitmap || pDock->pHiddenShapeBitmap) && pDock->iInputState != CAIRO_DOCK_INPUT_ACTIVE)
728
 
        {
729
 
                //g_print ("+++ input shape active on enter\n");
730
 
                gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
731
 
                        NULL,
732
 
                        0,
733
 
                        0);
734
 
        }
735
 
        pDock->iInputState = CAIRO_DOCK_INPUT_ACTIVE;
736
 
        
737
 
        // si on etait deja dedans, ou qu'on etait cense l'etre, on relance juste le grossissement.
738
 
        if (pDock->container.bInside || pDock->bIsHiding)
739
 
        {
740
 
                pDock->container.bInside = TRUE;
741
 
                cairo_dock_start_growing (pDock);
742
 
                if (pDock->bIsHiding || cairo_dock_is_hidden (pDock))  // on (re)monte.
743
 
                {
744
 
                        g_print ("  on etait deja dedans\n");
745
 
                        cairo_dock_start_showing (pDock);
746
 
                }
747
 
                return FALSE;
748
 
        }
749
 
        
750
 
        pDock->container.bInside = TRUE;
751
 
        // animation d'entree.
752
 
        gboolean bStartAnimation = FALSE;
753
 
        cairo_dock_notify (CAIRO_DOCK_ENTER_DOCK, pDock, &bStartAnimation);
754
 
        if (bStartAnimation)
755
 
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
756
 
        
757
 
        pDock->fDecorationsOffsetX = 0;
758
 
        cairo_dock_stop_quick_hide ();
759
 
        
760
 
        if (s_pIconClicked != NULL)  // on pourrait le faire a chaque motion aussi.
761
 
        {
762
 
                pDock->iAvoidingMouseIconType = s_pIconClicked->iType;
763
 
                pDock->fAvoidingMouseMargin = .5;  /// inutile il me semble ...
764
 
        }
765
 
        
766
 
        // si on rentre avec une icone volante, on la met dedans.
767
 
        if (s_pFlyingContainer != NULL)
768
 
        {
769
 
                Icon *pFlyingIcon = s_pFlyingContainer->pIcon;
770
 
                if (pDock != pFlyingIcon->pSubDock)  // on evite les boucles.
771
 
                {
772
 
                        struct timeval tv;
773
 
                        int r = gettimeofday (&tv, NULL);
774
 
                        double t = tv.tv_sec + tv.tv_usec * 1e-6;
775
 
                        if (t - s_pFlyingContainer->fCreationTime > 1)  // on empeche le cas ou enlever l'icone fait augmenter le ratio du dock, et donc sa hauteur, et nous fait rentrer dedans des qu'on sort l'icone.
776
 
                        {
777
 
                                g_print ("on remet l'icone volante dans un dock (dock d'origine : %s)\n", pFlyingIcon->cParentDockName);
778
 
                                cairo_dock_free_flying_container (s_pFlyingContainer);
779
 
                                cairo_dock_stop_icon_animation (pFlyingIcon);
780
 
                                cairo_dock_insert_icon_in_dock (pFlyingIcon, pDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
781
 
                                cairo_dock_start_icon_animation (pFlyingIcon, pDock);
782
 
                                s_pFlyingContainer = NULL;
783
 
                                pDock->bIconIsFlyingAway = FALSE;
784
 
                        }
785
 
                }
786
 
        }
787
 
        
788
 
        // on repasse au premier plan.
789
 
        if (myAccessibility.bPopUp && pDock->iRefCount == 0)
790
 
        {
791
 
                cairo_dock_pop_up (pDock);
792
 
                //If the dock window is entered, and there is a pending drop below event then it should be cancelled
793
 
                if (pDock->iSidPopDown != 0)
794
 
                {
795
 
                        g_source_remove(pDock->iSidPopDown);
796
 
                        pDock->iSidPopDown = 0;
797
 
                }
798
 
        }
799
 
        
800
 
        // si on etait en auto-hide, on commence a monter.
801
 
        if (pDock->fHideOffset != 0 && pDock->iRefCount == 0)
802
 
        {
803
 
                //g_print ("  on commence a monter\n");
804
 
                cairo_dock_start_showing (pDock);  // on a mis a jour la zone d'input avant, sinon la fonction le ferait, ce qui serait inutile.
805
 
        }
806
 
        
807
 
        // cas special.
808
 
        Icon *icon = cairo_dock_get_pointed_icon (pDock->icons);
809
 
        if (icon != NULL)
810
 
        {
811
 
                //g_print (">>> we've just entered the dock, pointed icon becomes NULL\n");
812
 
                //if (s_pIconClicked != NULL)
813
 
                //      g_print (">>> on est rentre par un clic ! (KDE:%d)\n", g_iDesktopEnv == CAIRO_DOCK_KDE);
814
 
                if (_mouse_is_really_outside (pDock))  // ce test est la pour parer aux WM deficients mentaux comme KWin qui nous font sortir/rentrer lors d'un clic.
815
 
                        icon->bPointed = FALSE;  // sinon on ne detecte pas l'arrive sur l'icone, c'est genant si elle a un sous-dock.
816
 
                //else
817
 
                //      g_print (">>> we already are inside the dock, why does this stupid WM make us enter one more time ???\n");
818
 
        }
819
 
        
820
 
        // on lance le grossissement.
821
 
        cairo_dock_start_growing (pDock);
822
 
        
823
 
        return TRUE;
824
 
}
825
 
 
826
 
/// This function checks for the mouse cursor's position. If the mouse
827
 
/// cursor touches the edge of the screen upon which the dock is resting,
828
 
/// then the dock will pop up over other windows...
829
 
gboolean cairo_dock_poll_screen_edge (CairoDock *pDock)  // thanks to Smidgey for the pop-up patch !
830
 
{
831
 
        static int iPrevPointerX = -1, iPrevPointerY = -1;
832
 
        gint iMousePosX, iMousePosY;
833
 
        
834
 
        if (!pDock->bPopped)
835
 
        {
836
 
                gdk_display_get_pointer(gdk_display_get_default(), NULL, &iMousePosX, &iMousePosY, NULL);
837
 
                if (iPrevPointerX == iMousePosX && iPrevPointerY == iMousePosY)
838
 
                        return myAccessibility.bPopUp;
839
 
                
840
 
                iPrevPointerX = iMousePosX;
841
 
                iPrevPointerY = iMousePosY;
842
 
                
843
 
                CairoDockPositionType iScreenBorder1 = CAIRO_DOCK_INSIDE_SCREEN, iScreenBorder2 = CAIRO_DOCK_INSIDE_SCREEN;
844
 
                if (iMousePosY == 0)
845
 
                {
846
 
                        iScreenBorder1 = CAIRO_DOCK_TOP;
847
 
                }
848
 
                else if (iMousePosY + 1 == g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
849
 
                {
850
 
                        iScreenBorder1 = CAIRO_DOCK_BOTTOM;
851
 
                }
852
 
                if (iMousePosX == 0)
853
 
                {
854
 
                        iScreenBorder2 = CAIRO_DOCK_LEFT;
855
 
                }
856
 
                else if (iMousePosX + 1 == g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL])
857
 
                {
858
 
                        iScreenBorder2 = CAIRO_DOCK_RIGHT;
859
 
                }
860
 
                if (iScreenBorder1 == CAIRO_DOCK_INSIDE_SCREEN && iScreenBorder2 == CAIRO_DOCK_INSIDE_SCREEN)
861
 
                        return myAccessibility.bPopUp;
862
 
                if ((iScreenBorder1 != CAIRO_DOCK_INSIDE_SCREEN && iScreenBorder2 != CAIRO_DOCK_INSIDE_SCREEN) || myAccessibility.bPopUpOnScreenBorder)
863
 
                {
864
 
                        if (cairo_dock_search_window_on_our_way (pDock, FALSE, TRUE) == NULL)  // ce test est la pour parer aux WM qui laissent passer des fenetres en avant-plan alors qu'une fenetre plein ecran est presente (Compiz ...). c'est particulierement penible pendant son Starcraft du soir.
865
 
                        {
866
 
                                if (iScreenBorder1 != CAIRO_DOCK_INSIDE_SCREEN)
867
 
                                        cairo_dock_pop_up_root_docks_on_screen_edge (iScreenBorder1);
868
 
                                if (iScreenBorder2 != CAIRO_DOCK_INSIDE_SCREEN)
869
 
                                        cairo_dock_pop_up_root_docks_on_screen_edge (iScreenBorder2);
870
 
                        }
871
 
                }
872
 
        }
873
 
        
874
 
        return myAccessibility.bPopUp;
875
 
}
876
 
 
877
 
gboolean cairo_dock_on_key_release (GtkWidget *pWidget,
878
 
        GdkEventKey *pKey,
879
 
        CairoDock *pDock)
880
 
{
881
 
        g_print ("on a appuye sur une touche (%d)\n", pKey->keyval);
882
 
        if (pKey->type == GDK_KEY_PRESS)
883
 
        {
884
 
                cairo_dock_notify (CAIRO_DOCK_KEY_PRESSED, pDock, pKey->keyval, pKey->state, pKey->string);
885
 
        }
886
 
        else if (pKey->type == GDK_KEY_RELEASE)
887
 
        {
888
 
                //g_print ("release : pKey->keyval = %d\n", pKey->keyval);
889
 
                if ((pKey->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) && pKey->keyval == 0)  // On relache la touche ALT, typiquement apres avoir fait un ALT + clique gauche + deplacement.
890
 
                {
891
 
                        if (pDock->iRefCount == 0)
892
 
                                cairo_dock_write_root_dock_gaps (pDock);
893
 
                }
894
 
        }
895
 
        return TRUE;
896
 
}
897
 
 
898
 
gchar *cairo_dock_launch_command_sync (const gchar *cCommand)
899
 
{
900
 
        gchar *standard_output=NULL, *standard_error=NULL;
901
 
        gint exit_status=0;
902
 
        GError *erreur = NULL;
903
 
        gboolean r = g_spawn_command_line_sync (cCommand,
904
 
                &standard_output,
905
 
                &standard_error,
906
 
                &exit_status,
907
 
                &erreur);
908
 
        if (erreur != NULL)
909
 
        {
910
 
                cd_warning (erreur->message);
911
 
                g_error_free (erreur);
912
 
                g_free (standard_error);
913
 
                return NULL;
914
 
        }
915
 
        if (standard_error != NULL && *standard_error != '\0')
916
 
        {
917
 
                cd_warning (standard_error);
918
 
        }
919
 
        g_free (standard_error);
920
 
        if (standard_output != NULL && *standard_output == '\0')
921
 
        {
922
 
                g_free (standard_output);
923
 
                return NULL;
924
 
        }
925
 
        if (standard_output[strlen (standard_output) - 1] == '\n')
926
 
                standard_output[strlen (standard_output) - 1] ='\0';
927
 
        return standard_output;
928
 
}
929
 
 
930
 
static gpointer _cairo_dock_launch_threaded (gchar *cCommand)
931
 
{
932
 
        int r;
933
 
        r = system (cCommand);
934
 
        g_free (cCommand);
935
 
        return NULL;
936
 
}
937
 
 
938
 
gboolean cairo_dock_launch_command_printf (const gchar *cCommandFormat, gchar *cWorkingDirectory, ...)
939
 
{
940
 
        va_list args;
941
 
        va_start (args, cWorkingDirectory);
942
 
        gchar *cCommand = g_strdup_vprintf (cCommandFormat, args);
943
 
        va_end (args);
944
 
        
945
 
        gboolean r = cairo_dock_launch_command_full (cCommand, cWorkingDirectory);
946
 
        g_free (cCommand);
947
 
        
948
 
        return r;
949
 
}
950
 
 
951
 
gboolean cairo_dock_launch_command_full (const gchar *cCommand, gchar *cWorkingDirectory)
952
 
{
953
 
        g_return_val_if_fail (cCommand != NULL, FALSE);
954
 
        cd_debug ("%s (%s , %s)", __func__, cCommand, cWorkingDirectory);
955
 
        
956
 
        gchar *cBGCommand = NULL;
957
 
        if (cCommand[strlen (cCommand)-1] != '&')
958
 
                cBGCommand = g_strconcat (cCommand, " &", NULL);
959
 
        
960
 
        gchar *cCommandFull = NULL;
961
 
        if (cWorkingDirectory != NULL)
962
 
        {
963
 
                cCommandFull = g_strdup_printf ("cd \"%s\" && %s", cWorkingDirectory, cBGCommand ? cBGCommand : cCommand);
964
 
                g_free (cBGCommand);
965
 
                cBGCommand = NULL;
966
 
        }
967
 
        else if (cBGCommand != NULL)
968
 
        {
969
 
                cCommandFull = cBGCommand;
970
 
                cBGCommand = NULL;
971
 
        }
972
 
        
973
 
        if (cCommandFull == NULL)
974
 
                cCommandFull = g_strdup (cCommand);
975
 
        
976
 
        GError *erreur = NULL;
977
 
        GThread* pThread = g_thread_create ((GThreadFunc) _cairo_dock_launch_threaded, cCommandFull, FALSE, &erreur);
978
 
        if (erreur != NULL)
979
 
        {
980
 
                cd_warning ("couldn't launch this command (%s : %s)", cCommandFull, erreur->message);
981
 
                g_error_free (erreur);
982
 
                g_free (cCommandFull);
983
 
                return FALSE;
984
 
        }
985
 
        return TRUE;
986
 
}
987
 
 
988
 
static int _compare_zorder (Icon *icon1, Icon *icon2)  // classe par z-order decroissant.
989
 
{
990
 
        if (icon1->iStackOrder < icon2->iStackOrder)
991
 
                return -1;
992
 
        else if (icon1->iStackOrder > icon2->iStackOrder)
993
 
                return 1;
994
 
        else
995
 
                return 0;
996
 
}
997
 
static void _cairo_dock_hide_show_in_class_subdock (Icon *icon)
998
 
{
999
 
        Icon *pIcon;
1000
 
        GList *ic;
1001
 
        for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
1002
 
        {
1003
 
                pIcon = ic->data;
1004
 
                if (pIcon->Xid != 0 && ! pIcon->bIsHidden)  // par defaut on cache tout.
1005
 
                {
1006
 
                        break;
1007
 
                }
1008
 
        }
1009
 
        
1010
 
        if (ic != NULL)  // au moins une fenetre est visible, on cache tout.
1011
 
        {
1012
 
                for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
1013
 
                {
1014
 
                        pIcon = ic->data;
1015
 
                        if (pIcon->Xid != 0 && ! pIcon->bIsHidden)
1016
 
                        {
1017
 
                                cairo_dock_minimize_xwindow (pIcon->Xid);
1018
 
                        }
1019
 
                }
1020
 
        }
1021
 
        else  // on montre tout, dans l'ordre du z-order.
1022
 
        {
1023
 
                GList *pZOrderList = NULL;
1024
 
                for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
1025
 
                {
1026
 
                        pIcon = ic->data;
1027
 
                        if (pIcon->Xid != 0)
1028
 
                                pZOrderList = g_list_insert_sorted (pZOrderList, pIcon, (GCompareFunc) _compare_zorder);
1029
 
                }
1030
 
                for (ic = pZOrderList; ic != NULL; ic = ic->next)
1031
 
                {
1032
 
                        pIcon = ic->data;
1033
 
                        cairo_dock_show_xwindow (pIcon->Xid);
1034
 
                }
1035
 
                g_list_free (pZOrderList);
1036
 
        }
1037
 
}
1038
 
 
1039
 
static void _cairo_dock_show_prev_next_in_class_subdock (Icon *icon, gboolean bNext)
1040
 
{
1041
 
        Icon *pActiveIcon = cairo_dock_get_current_active_icon ();
1042
 
        Icon *pNextIcon;
1043
 
        if (pActiveIcon != NULL)
1044
 
        {
1045
 
                if (bNext)
1046
 
                {
1047
 
                        pNextIcon = cairo_dock_get_next_icon (icon->pSubDock->icons, pActiveIcon);
1048
 
                        if (pNextIcon == NULL)  // pas trouvee ou derniere de la liste.
1049
 
                                pNextIcon = cairo_dock_get_first_icon (icon->pSubDock->icons);
1050
 
                }
1051
 
                else
1052
 
                {
1053
 
                        pNextIcon = cairo_dock_get_previous_icon (icon->pSubDock->icons, pActiveIcon);
1054
 
                        if (pNextIcon == NULL)  // pas trouvee ou premiere de la liste.
1055
 
                                pNextIcon = cairo_dock_get_last_icon (icon->pSubDock->icons);
1056
 
                }
1057
 
        }
1058
 
        else
1059
 
        {
1060
 
                pNextIcon = cairo_dock_get_first_icon (icon->pSubDock->icons);
1061
 
        }
1062
 
        if (pNextIcon != NULL)
1063
 
                cairo_dock_show_xwindow (pNextIcon->Xid);
1064
 
}
1065
 
 
1066
 
static void _cairo_dock_close_all_in_class_subdock (Icon *icon)
1067
 
{
1068
 
        Icon *pIcon;
1069
 
        GList *ic;
1070
 
        for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
1071
 
        {
1072
 
                pIcon = ic->data;
1073
 
                if (pIcon->Xid != 0)
1074
 
                {
1075
 
                        cairo_dock_close_xwindow (pIcon->Xid);
1076
 
                }
1077
 
        }
1078
 
}
1079
 
 
1080
 
 
1081
 
gboolean cairo_dock_notification_click_icon (gpointer pUserData, Icon *icon, CairoDock *pDock, guint iButtonState)
1082
 
{
1083
 
        //g_print ("+ %s (%s)\n", __func__, icon ? icon->cName : "no icon");
1084
 
        if (icon == NULL)
1085
 
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1086
 
        if (icon->pSubDock != NULL && (myAccessibility.bShowSubDockOnClick || !GTK_WIDGET_VISIBLE (pDock->container.pWidget)) && ! (iButtonState & GDK_SHIFT_MASK))  // icone de sous-dock a montrer au clic.
1087
 
        {
1088
 
                cairo_dock_show_subdock (icon, pDock, FALSE);
1089
 
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1090
 
        }
1091
 
        else if (CAIRO_DOCK_IS_URI_LAUNCHER (icon))  // URI : on lance ou on monte.
1092
 
        {
1093
 
                cd_debug (" uri launcher");
1094
 
                gboolean bIsMounted = FALSE;
1095
 
                if (icon->iVolumeID > 0)
1096
 
                {
1097
 
                        gchar *cActivationURI = cairo_dock_fm_is_mounted (icon->cBaseURI, &bIsMounted);
1098
 
                        g_free (cActivationURI);
1099
 
                }
1100
 
                if (icon->iVolumeID > 0 && ! bIsMounted)
1101
 
                {
1102
 
                        int answer = cairo_dock_ask_question_and_wait (_("Do you want to mount this point ?"), icon, CAIRO_CONTAINER (pDock));
1103
 
                        if (answer != GTK_RESPONSE_YES)
1104
 
                        {
1105
 
                                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1106
 
                        }
1107
 
                        cairo_dock_fm_mount (icon, CAIRO_CONTAINER (pDock));
1108
 
                }
1109
 
                else
1110
 
                        cairo_dock_fm_launch_uri (icon->cCommand);
1111
 
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1112
 
        }
1113
 
        else if (CAIRO_DOCK_IS_APPLI (icon) && ! ((iButtonState & GDK_SHIFT_MASK) && CAIRO_DOCK_IS_LAUNCHER (icon)) && ! CAIRO_DOCK_IS_APPLET (icon))  // une icone d'appli ou d'inhibiteur (hors applet) mais sans le shift+clic : on cache ou on montre.
1114
 
        {
1115
 
                cd_debug (" appli");
1116
 
                if (cairo_dock_get_current_active_window () == icon->Xid && myTaskBar.bMinimizeOnClick)  // ne marche que si le dock est une fenĆŖtre de type 'dock', sinon il prend le focus.
1117
 
                        cairo_dock_minimize_xwindow (icon->Xid);
1118
 
                else
1119
 
                        cairo_dock_show_xwindow (icon->Xid);
1120
 
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1121
 
        }
1122
 
        else if (CAIRO_DOCK_IS_LAUNCHER (icon))
1123
 
        {
1124
 
                //g_print ("+ launcher\n");
1125
 
                if (CAIRO_DOCK_IS_MULTI_APPLI (icon) && ! (iButtonState & GDK_SHIFT_MASK))  // un lanceur ayant un sous-dock de classe ou une icone de paille : on cache ou on montre.
1126
 
                {
1127
 
                        if (! myAccessibility.bShowSubDockOnClick)
1128
 
                        {
1129
 
                                _cairo_dock_hide_show_in_class_subdock (icon);
1130
 
                        }
1131
 
                        return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1132
 
                }
1133
 
                else if (icon->cCommand != NULL && strcmp (icon->cCommand, "none") != 0)  // finalement, on lance la commande.
1134
 
                {
1135
 
                        if (pDock->iRefCount != 0)
1136
 
                        {
1137
 
                                Icon *pMainIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
1138
 
                                if (CAIRO_DOCK_IS_APPLET (pMainIcon))
1139
 
                                        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1140
 
                        }
1141
 
                        
1142
 
                        gboolean bSuccess = FALSE;
1143
 
                        if (*icon->cCommand == '<')
1144
 
                        {
1145
 
                                bSuccess = cairo_dock_simulate_key_sequence (icon->cCommand);
1146
 
                                if (!bSuccess)
1147
 
                                        bSuccess = cairo_dock_launch_command_full (icon->cCommand, icon->cWorkingDirectory);
1148
 
                        }
1149
 
                        else
1150
 
                        {
1151
 
                                bSuccess = cairo_dock_launch_command_full (icon->cCommand, icon->cWorkingDirectory);
1152
 
                                if (! bSuccess)
1153
 
                                        bSuccess = cairo_dock_simulate_key_sequence (icon->cCommand);
1154
 
                        }
1155
 
                        if (! bSuccess)
1156
 
                        {
1157
 
                                cairo_dock_request_icon_animation (icon, pDock, "blink", 1);  // 1 clignotement si echec
1158
 
                        }
1159
 
                        return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1160
 
                }
1161
 
        }
1162
 
        else
1163
 
                cd_debug ("no action here");
1164
 
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1165
 
}
1166
 
 
1167
 
 
1168
 
gboolean cairo_dock_notification_middle_click_icon (gpointer pUserData, Icon *icon, CairoDock *pDock)
1169
 
{
1170
 
        if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.bCloseAppliOnMiddleClick && ! CAIRO_DOCK_IS_APPLET (icon))
1171
 
        {
1172
 
                cairo_dock_close_xwindow (icon->Xid);
1173
 
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1174
 
        }
1175
 
        if (CAIRO_DOCK_IS_URI_LAUNCHER (icon) && icon->pSubDock != NULL)  // icone de repertoire.
1176
 
        {
1177
 
                cairo_dock_fm_launch_uri (icon->cCommand);
1178
 
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1179
 
        }
1180
 
        if (CAIRO_DOCK_IS_MULTI_APPLI (icon))
1181
 
        {
1182
 
                // On ferme tout.
1183
 
                _cairo_dock_close_all_in_class_subdock (icon);
1184
 
                
1185
 
                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1186
 
        }
1187
 
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1188
 
}
1189
 
 
1190
 
gboolean cairo_dock_on_button_press (GtkWidget* pWidget, GdkEventButton* pButton, CairoDock *pDock)
1191
 
{
1192
 
        //g_print ("+ %s (%d/%d, %x)\n", __func__, pButton->type, pButton->button, pWidget);
1193
 
        if (pDock->container.bIsHorizontal)  // utile ?
1194
 
        {
1195
 
                pDock->container.iMouseX = (int) pButton->x;
1196
 
                pDock->container.iMouseY = (int) pButton->y;
1197
 
        }
1198
 
        else
1199
 
        {
1200
 
                pDock->container.iMouseX = (int) pButton->y;
1201
 
                pDock->container.iMouseY = (int) pButton->x;
1202
 
        }
1203
 
 
1204
 
        Icon *icon = cairo_dock_get_pointed_icon (pDock->icons);
1205
 
        if (pButton->button == 1)  // clic gauche.
1206
 
        {
1207
 
                //g_print ("+ left click\n");
1208
 
                switch (pButton->type)
1209
 
                {
1210
 
                        case GDK_BUTTON_RELEASE :
1211
 
                                //g_print ("+ GDK_BUTTON_RELEASE (%d/%d sur %s/%s)\n", pButton->state, GDK_CONTROL_MASK | GDK_MOD1_MASK, icon ? icon->cName : "personne", icon ? icon->cCommand : "");  // 272 = 100010000
1212
 
                                if ( ! (pButton->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
1213
 
                                {
1214
 
                                        if (s_pIconClicked != NULL)
1215
 
                                        {
1216
 
                                                cd_debug ("activate %s (%s)", s_pIconClicked->cName, icon ? icon->cName : "none");
1217
 
                                                s_pIconClicked->iAnimationState = CAIRO_DOCK_STATE_REST;  // stoppe les animations de suivi du curseur.
1218
 
                                                pDock->iAvoidingMouseIconType = -1;
1219
 
                                                cairo_dock_stop_icon_glide (pDock);
1220
 
                                        }
1221
 
                                        if (icon != NULL && ! CAIRO_DOCK_IS_SEPARATOR (icon) && icon == s_pIconClicked)
1222
 
                                        {
1223
 
                                                s_pIconClicked = NULL;  // il faut le faire ici au cas ou le clic induirait un dialogue bloquant qui nous ferait sortir du dock par exemple.
1224
 
                                                //g_print ("+ click on '%s' (%s)\n", icon->cName, icon->cCommand);
1225
 
                                                if (! s_bIconDragged)  // on ignore le drag'n'drop sur elle-meme.
1226
 
                                                {
1227
 
                                                        cairo_dock_notify (CAIRO_DOCK_CLICK_ICON, icon, pDock, pButton->state);
1228
 
                                                        if (myAccessibility.cRaiseDockShortcut != NULL)
1229
 
                                                                s_bHideAfterShortcut = TRUE;
1230
 
                                                        
1231
 
                                                        cairo_dock_start_icon_animation (icon, pDock);
1232
 
                                                }
1233
 
                                        }
1234
 
                                        else if (s_pIconClicked != NULL && icon != NULL && icon != s_pIconClicked && ! g_bLocked && ! myAccessibility.bLockIcons && ! myAccessibility.bLockAll)  //  && icon->iType == s_pIconClicked->iType
1235
 
                                        {
1236
 
                                                //g_print ("deplacement de %s\n", s_pIconClicked->cName);
1237
 
                                                CairoDock *pOriginDock = CAIRO_DOCK (cairo_dock_search_container_from_icon (s_pIconClicked));
1238
 
                                                if (pOriginDock != NULL && pDock != pOriginDock)
1239
 
                                                {
1240
 
                                                        cairo_dock_detach_icon_from_dock (s_pIconClicked, pOriginDock, TRUE);
1241
 
                                                        cairo_dock_update_dock_size (pOriginDock);
1242
 
                                                        
1243
 
                                                        cairo_dock_update_icon_s_container_name (s_pIconClicked, icon->cParentDockName);
1244
 
                                                        
1245
 
                                                        cairo_dock_insert_icon_in_dock (s_pIconClicked, pDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
1246
 
                                                        cairo_dock_start_icon_animation (s_pIconClicked, pDock);
1247
 
                                                }
1248
 
 
1249
 
                                                Icon *prev_icon, *next_icon;
1250
 
                                                if (icon->fXAtRest > s_pIconClicked->fXAtRest)
1251
 
                                                {
1252
 
                                                        prev_icon = icon;
1253
 
                                                        next_icon = cairo_dock_get_next_icon (pDock->icons, icon);
1254
 
                                                }
1255
 
                                                else
1256
 
                                                {
1257
 
                                                        prev_icon = cairo_dock_get_previous_icon (pDock->icons, icon);
1258
 
                                                        next_icon = icon;
1259
 
                                                }
1260
 
                                                if ((prev_icon == NULL || cairo_dock_get_icon_order (prev_icon) != cairo_dock_get_icon_order (s_pIconClicked)) && (next_icon == NULL || cairo_dock_get_icon_order (next_icon) != cairo_dock_get_icon_order (s_pIconClicked)))
1261
 
                                                {
1262
 
                                                        s_pIconClicked = NULL;
1263
 
                                                        return FALSE;
1264
 
                                                }
1265
 
                                                //g_print ("deplacement de %s\n", s_pIconClicked->cName);
1266
 
                                                if (prev_icon != NULL && cairo_dock_get_icon_order (prev_icon) != cairo_dock_get_icon_order (s_pIconClicked))
1267
 
                                                        prev_icon = NULL;
1268
 
                                                cairo_dock_move_icon_after_icon (pDock, s_pIconClicked, prev_icon);
1269
 
 
1270
 
                                                pDock->pRenderer->calculate_icons (pDock);
1271
 
 
1272
 
                                                if (! CAIRO_DOCK_IS_SEPARATOR (s_pIconClicked))
1273
 
                                                {
1274
 
                                                        cairo_dock_request_icon_animation (s_pIconClicked, pDock, "bounce", 2);
1275
 
                                                }
1276
 
                                                if (pDock->container.iSidGLAnimation == 0 || ! CAIRO_CONTAINER_IS_OPENGL (CAIRO_CONTAINER (pDock)))
1277
 
                                                        gtk_widget_queue_draw (pDock->container.pWidget);
1278
 
                                        }
1279
 
                                        
1280
 
                                        if (s_pFlyingContainer != NULL)
1281
 
                                        {
1282
 
                                                g_print ("on relache l'icone volante\n");
1283
 
                                                if (pDock->container.bInside)
1284
 
                                                {
1285
 
                                                        //g_print ("  on la remet dans son dock d'origine\n");
1286
 
                                                        Icon *pFlyingIcon = s_pFlyingContainer->pIcon;
1287
 
                                                        cairo_dock_free_flying_container (s_pFlyingContainer);
1288
 
                                                        cairo_dock_stop_marking_icon_as_following_mouse (pFlyingIcon);
1289
 
                                                        cairo_dock_stop_icon_animation (pFlyingIcon);
1290
 
                                                        cairo_dock_insert_icon_in_dock (pFlyingIcon, pDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, CAIRO_DOCK_ANIMATE_ICON);
1291
 
                                                        cairo_dock_start_icon_animation (pFlyingIcon, pDock);
1292
 
                                                }
1293
 
                                                else
1294
 
                                                {
1295
 
                                                        cairo_dock_terminate_flying_container (s_pFlyingContainer);  // supprime ou detache l'icone, l'animation se terminera toute seule.
1296
 
                                                }
1297
 
                                                s_pFlyingContainer = NULL;
1298
 
                                                pDock->bIconIsFlyingAway = FALSE;
1299
 
                                                cairo_dock_stop_icon_glide (pDock);
1300
 
                                        }
1301
 
                                }
1302
 
                                else
1303
 
                                {
1304
 
                                        if (pDock->iRefCount == 0)
1305
 
                                                cairo_dock_write_root_dock_gaps (pDock);
1306
 
                                }
1307
 
                                //g_print ("- apres clic : s_pIconClicked <- NULL\n");
1308
 
                                s_pIconClicked = NULL;
1309
 
                                s_bIconDragged = FALSE;
1310
 
                        break ;
1311
 
                        
1312
 
                        case GDK_BUTTON_PRESS :
1313
 
                                if ( ! (pButton->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
1314
 
                                {
1315
 
                                        //g_print ("+ clic sur %s (%.2f)!\n", icon ? icon->cName : "rien", icon ? icon->fInsertRemoveFactor : 0.);
1316
 
                                        s_iClickX = pButton->x;
1317
 
                                        s_iClickY = pButton->y;
1318
 
                                        if (icon && ! cairo_dock_icon_is_being_removed (icon))
1319
 
                                        {
1320
 
                                                s_pIconClicked = icon;  // on ne definit pas l'animation FOLLOW_MOUSE ici , on le fera apres le 1er mouvement, pour eviter que l'icone soit dessinee comme tel quand on clique dessus alors que le dock est en train de jouer une animation (ca provoque un flash desagreable).
1321
 
                                                cd_debug ("clicked on %s", icon->cName);
1322
 
                                        }
1323
 
                                        else
1324
 
                                                s_pIconClicked = NULL;
1325
 
                                }
1326
 
                        break ;
1327
 
 
1328
 
                        case GDK_2BUTTON_PRESS :
1329
 
                                {
1330
 
                                        if (icon && ! cairo_dock_icon_is_being_removed (icon))
1331
 
                                                cairo_dock_notify (CAIRO_DOCK_DOUBLE_CLICK_ICON, icon, pDock);
1332
 
                                }
1333
 
                        break ;
1334
 
 
1335
 
                        default :
1336
 
                        break ;
1337
 
                }
1338
 
        }
1339
 
        else if (pButton->button == 3 && pButton->type == GDK_BUTTON_PRESS)  // clique droit.
1340
 
        {
1341
 
                GtkWidget *menu = cairo_dock_build_menu (icon, CAIRO_CONTAINER (pDock));  // genere un CAIRO_DOCK_BUILD_CONTAINER_MENU et CAIRO_DOCK_BUILD_ICON_MENU.
1342
 
                
1343
 
                cairo_dock_popup_menu_on_container (menu, CAIRO_CONTAINER (pDock));
1344
 
        }
1345
 
        else if (pButton->button == 2 && pButton->type == GDK_BUTTON_PRESS)  // clique milieu.
1346
 
        {
1347
 
                if (icon && ! cairo_dock_icon_is_being_removed (icon))
1348
 
                        cairo_dock_notify (CAIRO_DOCK_MIDDLE_CLICK_ICON, icon, pDock);
1349
 
        }
1350
 
 
1351
 
        return FALSE;
1352
 
}
1353
 
 
1354
 
 
1355
 
gboolean cairo_dock_notification_scroll_icon (gpointer pUserData, Icon *icon, CairoDock *pDock, int iDirection)
1356
 
{
1357
 
        if (CAIRO_DOCK_IS_MULTI_APPLI (icon))  // on emule un alt+tab sur la liste des applis du sous-dock.
1358
 
        {
1359
 
                _cairo_dock_show_prev_next_in_class_subdock (icon, iDirection == GDK_SCROLL_DOWN);
1360
 
        }
1361
 
        else if (CAIRO_DOCK_IS_APPLI (icon) && icon->cClass != NULL)
1362
 
        {
1363
 
                Icon *pNextIcon = cairo_dock_get_prev_next_classmate_icon (icon, iDirection == GDK_SCROLL_DOWN);
1364
 
                if (pNextIcon != NULL)
1365
 
                        cairo_dock_show_xwindow (pNextIcon->Xid);
1366
 
        }
1367
 
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1368
 
}
1369
 
gboolean cairo_dock_on_scroll (GtkWidget* pWidget, GdkEventScroll* pScroll, CairoDock *pDock)
1370
 
{
1371
 
        if (pScroll->direction != GDK_SCROLL_UP && pScroll->direction != GDK_SCROLL_DOWN)  // on degage les scrolls horizontaux.
1372
 
        {
1373
 
                return FALSE;
1374
 
        }
1375
 
        Icon *icon = cairo_dock_get_pointed_icon (pDock->icons);
1376
 
        if (icon != NULL)
1377
 
        {
1378
 
                cairo_dock_notify (CAIRO_DOCK_SCROLL_ICON, icon, pDock, pScroll->direction);
1379
 
        }
1380
 
 
1381
 
        return FALSE;
1382
 
}
1383
 
 
1384
 
 
1385
 
gboolean cairo_dock_on_configure (GtkWidget* pWidget, GdkEventConfigure* pEvent, CairoDock *pDock)
1386
 
{
1387
 
        //g_print ("%s (main dock : %d) : (%d;%d) (%dx%d)\n", __func__, pDock->bIsMainDock, pEvent->x, pEvent->y, pEvent->width, pEvent->height);
1388
 
        gint iNewWidth, iNewHeight, iNewX, iNewY;
1389
 
        if (pDock->container.bIsHorizontal)
1390
 
        {
1391
 
                iNewWidth = pEvent->width;
1392
 
                iNewHeight = pEvent->height;
1393
 
                
1394
 
                iNewX = pEvent->x;
1395
 
                iNewY = pEvent->y;
1396
 
        }
1397
 
        else
1398
 
        {
1399
 
                iNewWidth = pEvent->height;
1400
 
                iNewHeight = pEvent->width;
1401
 
                
1402
 
                iNewX = pEvent->y;
1403
 
                iNewY = pEvent->x;
1404
 
        }
1405
 
        
1406
 
        if ((iNewWidth != pDock->container.iWidth || iNewHeight != pDock->container.iHeight) && iNewWidth > 1)  // changement de taille
1407
 
        {
1408
 
                //g_print ("-> %dx%d\n", iNewWidth, iNewHeight);
1409
 
                pDock->container.iWidth = iNewWidth;
1410
 
                pDock->container.iHeight = iNewHeight;
1411
 
                pDock->container.iWindowPositionX = iNewX;
1412
 
                pDock->container.iWindowPositionY = iNewY;
1413
 
                
1414
 
                if (pDock->container.bIsHorizontal)
1415
 
                        gdk_window_get_pointer (pWidget->window, &pDock->container.iMouseX, &pDock->container.iMouseY, NULL);
1416
 
                else
1417
 
                        gdk_window_get_pointer (pWidget->window, &pDock->container.iMouseY, &pDock->container.iMouseX, NULL);
1418
 
                if (pDock->container.iMouseX < 0 || pDock->container.iMouseX > pDock->container.iWidth)  // utile ?
1419
 
                        pDock->container.iMouseX = 0;
1420
 
                //g_print ("x,y : %d;%d\n", pDock->container.iMouseX, pDock->container.iMouseY);
1421
 
                
1422
 
                // les dimensions ont change, il faut remettre l'input shape a la bonne place.
1423
 
                if (pDock->pHiddenShapeBitmap != NULL && pDock->iInputState == CAIRO_DOCK_INPUT_HIDDEN)
1424
 
                {
1425
 
                        //g_print ("+++ input shape hidden on configure\n");
1426
 
                        gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
1427
 
                                NULL,
1428
 
                                0,
1429
 
                                0);
1430
 
                        gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
1431
 
                                pDock->pHiddenShapeBitmap,
1432
 
                                0,
1433
 
                                0);
1434
 
                }
1435
 
                else if (pDock->pShapeBitmap != NULL && pDock->iInputState == CAIRO_DOCK_INPUT_AT_REST)
1436
 
                {
1437
 
                        //g_print ("+++ input shape at rest on configure\n");
1438
 
                        gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
1439
 
                                NULL,
1440
 
                                0,
1441
 
                                0);
1442
 
                        gtk_widget_input_shape_combine_mask (pDock->container.pWidget,
1443
 
                                pDock->pShapeBitmap,
1444
 
                                0,
1445
 
                                0);
1446
 
                }
1447
 
                
1448
 
                if (g_bUseOpenGL)
1449
 
                {
1450
 
                        GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
1451
 
                        GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
1452
 
                        GLsizei w = pEvent->width;
1453
 
                        GLsizei h = pEvent->height;
1454
 
                        if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
1455
 
                                return FALSE;
1456
 
                        
1457
 
                        glViewport(0, 0, w, h);
1458
 
                        
1459
 
                        /*glMatrixMode(GL_PROJECTION);
1460
 
                        glLoadIdentity();
1461
 
                        glOrtho(0, w, 0, h, 0.0, 500.0);
1462
 
                        
1463
 
                        glMatrixMode (GL_MODELVIEW);
1464
 
                        glLoadIdentity ();
1465
 
                        gluLookAt (w/2, h/2, 3.,
1466
 
                                w/2, h/2, 0.,
1467
 
                                0.0f, 1.0f, 0.0f);
1468
 
                        glTranslatef (0.0f, 0.0f, -3.);*/
1469
 
                        cairo_dock_set_ortho_view (w, h);
1470
 
                        
1471
 
                        glClearAccum (0., 0., 0., 0.);
1472
 
                        glClear (GL_ACCUM_BUFFER_BIT);
1473
 
                        
1474
 
                        gdk_gl_drawable_gl_end (pGlDrawable);
1475
 
                }
1476
 
                
1477
 
                #ifdef HAVE_GLITZ
1478
 
                if (pDock->container.pGlitzDrawable)
1479
 
                {
1480
 
                        glitz_drawable_update_size (pDock->container.pGlitzDrawable,
1481
 
                                pEvent->width,
1482
 
                                pEvent->height);
1483
 
                }
1484
 
                #endif
1485
 
                
1486
 
                cairo_dock_calculate_dock_icons (pDock);
1487
 
                //g_print ("configure size\n");
1488
 
                cairo_dock_trigger_set_WM_icons_geometry (pDock);  // changement de position ou de taille du dock => on replace les icones.
1489
 
                
1490
 
                cairo_dock_replace_all_dialogs ();
1491
 
        }
1492
 
        else if (pDock->container.iWindowPositionX != iNewX || pDock->container.iWindowPositionY != iNewY)  // changement de position.
1493
 
        {
1494
 
                pDock->container.iWindowPositionX = iNewX;
1495
 
                pDock->container.iWindowPositionY = iNewY;
1496
 
                //g_print ("configure x,y\n");
1497
 
                cairo_dock_trigger_set_WM_icons_geometry (pDock);  // changement de position de la fenetre du dock => on replace les icones.
1498
 
                
1499
 
                cairo_dock_replace_all_dialogs ();
1500
 
        }
1501
 
        
1502
 
        gtk_widget_queue_draw (pWidget);
1503
 
        
1504
 
        return FALSE;
1505
 
}
1506
 
 
1507
 
 
1508
 
 
1509
 
static gboolean s_bWaitForData = FALSE;
1510
 
 
1511
 
void cairo_dock_on_drag_data_received (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint time, CairoDock *pDock)
1512
 
{
1513
 
        g_print ("%s (%dx%d, %d, %d)\n", __func__, x, y, time, pDock->container.bInside);
1514
 
        if (cairo_dock_is_hidden (pDock))  // X ne semble pas tenir compte de la zone d'input pour dropper les trucs...
1515
 
                return ;
1516
 
        //\_________________ On recupere l'URI.
1517
 
        gchar *cReceivedData = (gchar *) selection_data->data;  // gtk_selection_data_get_text
1518
 
        g_return_if_fail (cReceivedData != NULL);
1519
 
        int length = strlen (cReceivedData);
1520
 
        if (cReceivedData[length-1] == '\n')
1521
 
                cReceivedData[--length] = '\0';  // on vire le retour chariot final.
1522
 
        if (cReceivedData[length-1] == '\r')
1523
 
                cReceivedData[--length] = '\0';
1524
 
        
1525
 
        if (s_bWaitForData)
1526
 
        {
1527
 
                s_bWaitForData = FALSE;
1528
 
                gdk_drag_status (dc, GDK_ACTION_COPY, time);
1529
 
                g_print ("drag info : <%s>\n", cReceivedData);
1530
 
                pDock->iAvoidingMouseIconType = CAIRO_DOCK_LAUNCHER;
1531
 
                if (g_str_has_suffix (cReceivedData, ".desktop")/** || g_str_has_suffix (cReceivedData, ".sh")*/)
1532
 
                        pDock->fAvoidingMouseMargin = .5;  // on ne sera jamais dessus.
1533
 
                else
1534
 
                        pDock->fAvoidingMouseMargin = .25;
1535
 
                return ;
1536
 
        }
1537
 
        
1538
 
        //\_________________ On arrete l'animation.
1539
 
        //cairo_dock_stop_marking_icons (pDock);
1540
 
        pDock->iAvoidingMouseIconType = -1;
1541
 
        pDock->fAvoidingMouseMargin = 0;
1542
 
        
1543
 
        //\_________________ On calcule la position a laquelle on l'a lache.
1544
 
        cd_message (">>> cReceivedData : '%s'", cReceivedData);
1545
 
        int iDropX = (pDock->container.bIsHorizontal ? x : y);
1546
 
        double fOrder = CAIRO_DOCK_LAST_ORDER;
1547
 
        Icon *pPointedIcon = NULL, *pNeighboorIcon = NULL;
1548
 
        Icon *icon;
1549
 
        GList *ic;
1550
 
        for (ic = pDock->icons; ic != NULL; ic = ic->next)
1551
 
        {
1552
 
                icon = ic->data;
1553
 
                if (icon->bPointed)
1554
 
                {
1555
 
                        //g_print ("On pointe sur %s\n", icon->cName);
1556
 
                        pPointedIcon = icon;
1557
 
                        double fMargin;  /// deviendra obsolete si le drag-received fonctionne.
1558
 
                        if (g_str_has_suffix (cReceivedData, ".desktop")/** || g_str_has_suffix (cReceivedData, ".sh")*/)  // si c'est un .desktop, on l'ajoute.
1559
 
                        {
1560
 
                                if (g_bLocked || myAccessibility.bLockIcons || myAccessibility.bLockAll)
1561
 
                                {
1562
 
                                        gtk_drag_finish (dc, FALSE, FALSE, time);
1563
 
                                        return ;
1564
 
                                }
1565
 
                                fMargin = 0.5;  // on ne sera jamais dessus.
1566
 
                        }
1567
 
                        else  // sinon on le lance si on est sur l'icone, et on l'ajoute autrement.
1568
 
                                fMargin = 0.25;
1569
 
 
1570
 
                        if (iDropX > icon->fX + icon->fWidth * icon->fScale * (1 - fMargin))  // on est apres.
1571
 
                        {
1572
 
                                if (g_bLocked || myAccessibility.bLockIcons || myAccessibility.bLockAll)
1573
 
                                {
1574
 
                                        gtk_drag_finish (dc, FALSE, FALSE, time);
1575
 
                                        return ;
1576
 
                                }
1577
 
                                pNeighboorIcon = (ic->next != NULL ? ic->next->data : NULL);
1578
 
                                fOrder = (pNeighboorIcon != NULL ? (icon->fOrder + pNeighboorIcon->fOrder) / 2 : icon->fOrder + 1);
1579
 
                        }
1580
 
                        else if (iDropX < icon->fX + icon->fWidth * icon->fScale * fMargin)  // on est avant.
1581
 
                        {
1582
 
                                if (g_bLocked || myAccessibility.bLockIcons || myAccessibility.bLockAll)
1583
 
                                {
1584
 
                                        gtk_drag_finish (dc, FALSE, FALSE, time);
1585
 
                                        return ;
1586
 
                                }
1587
 
                                pNeighboorIcon = (ic->prev != NULL ? ic->prev->data : NULL);
1588
 
                                fOrder = (pNeighboorIcon != NULL ? (icon->fOrder + pNeighboorIcon->fOrder) / 2 : icon->fOrder - 1);
1589
 
                        }
1590
 
                        else  // on est dessus.
1591
 
                        {
1592
 
                                fOrder = CAIRO_DOCK_LAST_ORDER;
1593
 
                        }
1594
 
                }
1595
 
        }
1596
 
        
1597
 
        cairo_dock_notify_drop_data (cReceivedData, pPointedIcon, fOrder, CAIRO_CONTAINER (pDock));
1598
 
        
1599
 
        gtk_drag_finish (dc, TRUE, FALSE, time);
1600
 
}
1601
 
 
1602
 
gboolean cairo_dock_on_drag_drop (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, guint time, CairoDock *pDock)
1603
 
{
1604
 
        cd_message ("%s (%dx%d, %d)", __func__, x, y, time);
1605
 
        GdkAtom target = gtk_drag_dest_find_target (pWidget, dc, NULL);
1606
 
        gtk_drag_get_data (pWidget, dc, target, time);
1607
 
        return TRUE;  // in a drop zone.
1608
 
}
1609
 
 
1610
 
gboolean cairo_dock_notification_drop_data (gpointer pUserData, const gchar *cReceivedData, Icon *icon, double fOrder, CairoContainer *pContainer)
1611
 
{
1612
 
        if (! CAIRO_DOCK_IS_DOCK (pContainer))
1613
 
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1614
 
        
1615
 
        CairoDock *pDock = CAIRO_DOCK (pContainer);
1616
 
        CairoDock *pReceivingDock = pDock;
1617
 
        if (g_str_has_suffix (cReceivedData, ".desktop"))  // ajout d'un nouveau lanceur si on a lache sur ou entre 2 lanceurs.
1618
 
        {
1619
 
                if ((myIcons.iSeparateIcons == 1 || myIcons.iSeparateIcons == 3) && CAIRO_DOCK_IS_NORMAL_APPLI (icon))
1620
 
                        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1621
 
                if ((myIcons.iSeparateIcons == 2 || myIcons.iSeparateIcons == 3) && CAIRO_DOCK_IS_APPLET (icon))
1622
 
                        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1623
 
                if (fOrder == CAIRO_DOCK_LAST_ORDER && icon && icon->pSubDock != NULL)  // on a lache sur une icone de sous-dock => on l'ajoute dans le sous-dock.
1624
 
                {
1625
 
                        pReceivingDock = icon->pSubDock;
1626
 
                }
1627
 
        }
1628
 
        else  // c'est un fichier.
1629
 
        {
1630
 
                if (fOrder == CAIRO_DOCK_LAST_ORDER)  // on a lache dessus.
1631
 
                {
1632
 
                        if (CAIRO_DOCK_IS_LAUNCHER (icon))
1633
 
                        {
1634
 
                                if (CAIRO_DOCK_IS_URI_LAUNCHER (icon))
1635
 
                                {
1636
 
                                        if (icon->pSubDock != NULL || icon->iVolumeID != 0)  // on le lache sur un repertoire ou un point de montage.
1637
 
                                        {
1638
 
                                                cairo_dock_fm_move_into_directory (cReceivedData, icon, pContainer);
1639
 
                                                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1640
 
                                        }
1641
 
                                        else  // on le lache sur un fichier.
1642
 
                                        {
1643
 
                                                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1644
 
                                        }
1645
 
                                }
1646
 
                                else if (CAIRO_DOCK_IS_CONTAINER_LAUNCHER (icon))  // on le lache sur un sous-dock de lanceurs.
1647
 
                                {
1648
 
                                        pReceivingDock = icon->pSubDock;
1649
 
                                }
1650
 
                                else  // on le lache sur un lanceur.
1651
 
                                {
1652
 
                                        gchar *cPath = NULL;
1653
 
                                        if (strncmp (cReceivedData, "file://", 7) == 0)  // tous les programmes ne gerent pas les URI; pour parer au cas ou il ne le gererait pas, dans le cas d'un fichier local, on convertit en un chemin
1654
 
                                        {
1655
 
                                                cPath = g_filename_from_uri (cReceivedData, NULL, NULL);
1656
 
                                        }
1657
 
                                        gchar *cCommand = g_strdup_printf ("%s \"%s\"", icon->cCommand, cPath ? cPath : cReceivedData);
1658
 
                                        cd_message ("will open the file with the command '%s'...\n", cCommand);
1659
 
                                        g_spawn_command_line_async (cCommand, NULL);
1660
 
                                        g_free (cPath);
1661
 
                                        g_free (cCommand);
1662
 
                                        cairo_dock_request_icon_animation (icon, pDock, "blink", 2);
1663
 
                                        return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1664
 
                                }
1665
 
                        }
1666
 
                        else  // on le lache sur autre chose qu'un lanceur.
1667
 
                        {
1668
 
                                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1669
 
                        }
1670
 
                }
1671
 
                else  // on a lache a cote.
1672
 
                {
1673
 
                        Icon *pPointingIcon = cairo_dock_search_icon_pointing_on_dock (pDock, NULL);
1674
 
                        if (CAIRO_DOCK_IS_URI_LAUNCHER (pPointingIcon))  // on a lache dans un dock qui est un repertoire, on copie donc le fichier dedans.
1675
 
                        {
1676
 
                                cairo_dock_fm_move_into_directory (cReceivedData, icon, pContainer);
1677
 
                                return CAIRO_DOCK_INTERCEPT_NOTIFICATION;
1678
 
                        }
1679
 
                }
1680
 
        }
1681
 
 
1682
 
        if (g_bLocked)
1683
 
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1684
 
        
1685
 
        cairo_dock_add_new_launcher_by_uri (cReceivedData, pReceivingDock, fOrder);
1686
 
        
1687
 
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
1688
 
}
1689
 
 
1690
 
 
1691
 
gboolean cairo_dock_on_drag_motion (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, guint time, CairoDock *pDock)
1692
 
{
1693
 
        //g_print ("%s (%d;%d, %d)\n", __func__, x, y, time);
1694
 
        //\_________________ On simule les evenements souris habituels.
1695
 
        if (! pDock->bIsDragging)
1696
 
        {
1697
 
                g_print ("start dragging\n");
1698
 
                pDock->bIsDragging = TRUE;
1699
 
                
1700
 
                /*GdkAtom gdkAtom = gdk_drag_get_selection (dc);
1701
 
                Atom xAtom = gdk_x11_atom_to_xatom (gdkAtom);
1702
 
                Window Xid = GDK_WINDOW_XID (dc->source_window);
1703
 
                g_print (" <%s>\n", cairo_dock_get_property_name_on_xwindow (Xid, xAtom));*/
1704
 
                
1705
 
                gboolean bStartAnimation = FALSE;
1706
 
                cairo_dock_notify (CAIRO_DOCK_START_DRAG_DATA, pDock, &bStartAnimation);
1707
 
                if (bStartAnimation)
1708
 
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));
1709
 
                
1710
 
                /*pDock->iAvoidingMouseIconType = -1;
1711
 
                
1712
 
                GdkAtom target = gtk_drag_dest_find_target (pWidget, dc, NULL);
1713
 
                if (target == GDK_NONE)
1714
 
                        gdk_drag_status (dc, 0, time);
1715
 
                else
1716
 
                {
1717
 
                        gtk_drag_get_data (pWidget, dc, target, time);
1718
 
                        s_bWaitForData = TRUE;
1719
 
                        g_print ("get-data envoye\n");
1720
 
                }*/
1721
 
                
1722
 
                cairo_dock_on_enter_notify (pWidget, NULL, pDock);  // ne sera effectif que la 1ere fois a chaque entree dans un dock.
1723
 
        }
1724
 
        else
1725
 
        {
1726
 
                //g_print ("move dragging\n");
1727
 
                cairo_dock_on_motion_notify (pWidget, NULL, pDock);
1728
 
        }
1729
 
        
1730
 
        int X, Y;
1731
 
        if (pDock->container.bIsHorizontal)
1732
 
        {
1733
 
                X = x - pDock->container.iWidth/2;
1734
 
                Y = y;
1735
 
        }
1736
 
        else
1737
 
        {
1738
 
                Y = x;
1739
 
                X = y - pDock->container.iWidth/2;
1740
 
        }
1741
 
        int w, h;
1742
 
        Icon *icon = cairo_dock_get_pointed_icon (pDock->icons);
1743
 
        ///if (!icon || !icon->pSubDock)
1744
 
        {
1745
 
                if (pDock->iInputState == CAIRO_DOCK_INPUT_AT_REST)
1746
 
                {
1747
 
                        w = pDock->iMinDockWidth;
1748
 
                        h = pDock->iMinDockHeight;
1749
 
                        
1750
 
                        if (X <= -w/2 || X >= w/2)
1751
 
                                return FALSE;  // on n'accepte pas le drop.
1752
 
                        if (pDock->container.bDirectionUp)
1753
 
                        {
1754
 
                                if (Y <= pDock->container.iHeight - h || Y >= pDock->container.iHeight)
1755
 
                                        return FALSE;  // on n'accepte pas le drop.
1756
 
                        }
1757
 
                        else
1758
 
                        {
1759
 
                                if (Y < 0 || Y > h)
1760
 
                                        return FALSE;  // on n'accepte pas le drop.
1761
 
                        }
1762
 
                }
1763
 
                else if (pDock->iInputState == CAIRO_DOCK_INPUT_HIDDEN)
1764
 
                {
1765
 
                        w = MIN (myAccessibility.iVisibleZoneWidth, pDock->iMaxDockWidth);
1766
 
                        h = MIN (myAccessibility.iVisibleZoneHeight, pDock->iMaxDockHeight);
1767
 
                        
1768
 
                        if (X <= -w/2 || X >= w/2)
1769
 
                                return FALSE;  // on n'accepte pas le drop.
1770
 
                        if (pDock->container.bDirectionUp)
1771
 
                        {
1772
 
                                if (Y <= pDock->container.iHeight - h || Y >= pDock->container.iHeight)
1773
 
                                        return FALSE;  // on n'accepte pas le drop.
1774
 
                        }
1775
 
                        else
1776
 
                        {
1777
 
                                if (Y < 0 || Y > h)
1778
 
                                        return FALSE;  // on n'accepte pas le drop.
1779
 
                        }
1780
 
                }
1781
 
        }
1782
 
        
1783
 
        gdk_drag_status (dc, GDK_ACTION_COPY, time);
1784
 
        return TRUE;  // on accepte le drop.
1785
 
}
1786
 
 
1787
 
void cairo_dock_on_drag_leave (GtkWidget *pWidget, GdkDragContext *dc, guint time, CairoDock *pDock)
1788
 
{
1789
 
        g_print ("stop dragging1\n");
1790
 
        Icon *icon = cairo_dock_get_pointed_icon (pDock->icons);
1791
 
        if ((icon && icon->pSubDock) || pDock->iRefCount > 0)  // on retarde l'evenement, car il arrive avant le leave-event, et donc le sous-dock se cache avant qu'on puisse y entrer.
1792
 
        {
1793
 
                cd_debug (">>> on attend...");
1794
 
                while (gtk_events_pending ())  // on laisse le temps au signal d'entree dans le sous-dock d'etre traite, de facon a avoir un start-dragging avant de quitter cette fonction.
1795
 
                        gtk_main_iteration ();
1796
 
                cd_debug (">>> pDock->container.bInside : %d", pDock->container.bInside);
1797
 
        }
1798
 
        g_print ("stop dragging2\n");
1799
 
        s_bWaitForData = FALSE;
1800
 
        pDock->bIsDragging = FALSE;
1801
 
        pDock->bCanDrop = FALSE;
1802
 
        //cairo_dock_stop_marking_icons (pDock);
1803
 
        pDock->iAvoidingMouseIconType = -1;
1804
 
        cairo_dock_emit_leave_signal (pDock);
1805
 
}
1806
 
 
1807
 
 
1808
 
 
1809
 
void cairo_dock_show_dock_at_mouse (CairoDock *pDock)
1810
 
{
1811
 
        g_return_if_fail (pDock != NULL);
1812
 
        int iMouseX, iMouseY;
1813
 
        if (pDock->container.bIsHorizontal)
1814
 
                gdk_window_get_pointer (pDock->container.pWidget->window, &iMouseX, &iMouseY, NULL);
1815
 
        else
1816
 
                gdk_window_get_pointer (pDock->container.pWidget->window, &iMouseY, &iMouseX, NULL);
1817
 
        //g_print (" %d;%d\n", iMouseX, iMouseY);
1818
 
        
1819
 
        pDock->iGapX = pDock->container.iWindowPositionX + iMouseX - g_iXScreenWidth[pDock->container.bIsHorizontal] * pDock->fAlign;
1820
 
        pDock->iGapY = (pDock->container.bDirectionUp ? g_iXScreenHeight[pDock->container.bIsHorizontal] - (pDock->container.iWindowPositionY + iMouseY) : pDock->container.iWindowPositionY + iMouseY);
1821
 
        //g_print (" => %d;%d\n", g_pMainDock->iGapX, g_pMainDock->iGapY);
1822
 
        
1823
 
        int iNewPositionX, iNewPositionY;
1824
 
        cairo_dock_get_window_position_at_balance (pDock,
1825
 
                pDock->container.iWidth, pDock->container.iHeight,
1826
 
                &iNewPositionX, &iNewPositionY);
1827
 
        
1828
 
        gtk_window_move (GTK_WINDOW (pDock->container.pWidget),
1829
 
                (pDock->container.bIsHorizontal ? iNewPositionX : iNewPositionY),
1830
 
                (pDock->container.bIsHorizontal ? iNewPositionY : iNewPositionX));
1831
 
        gtk_widget_show (pDock->container.pWidget);
1832
 
}
1833
 
 
1834
 
void cairo_dock_raise_from_keyboard (const char *cKeyShortcut, gpointer data)
1835
 
{
1836
 
        if (GTK_WIDGET_VISIBLE (g_pMainDock->container.pWidget))
1837
 
        {
1838
 
                gtk_widget_hide (g_pMainDock->container.pWidget);
1839
 
        }
1840
 
        else
1841
 
        {
1842
 
                cairo_dock_show_dock_at_mouse (g_pMainDock);
1843
 
        }
1844
 
        s_bHideAfterShortcut = FALSE;
1845
 
}
1846
 
 
1847
 
void cairo_dock_hide_dock_like_a_menu (void)
1848
 
{
1849
 
        if (s_bHideAfterShortcut && GTK_WIDGET_VISIBLE (g_pMainDock->container.pWidget))
1850
 
        {
1851
 
                gtk_widget_hide (g_pMainDock->container.pWidget);
1852
 
                s_bHideAfterShortcut = FALSE;
1853
 
        }
1854
 
}