~ubuntu-branches/ubuntu/maverick/cairo-dock/maverick

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100809232612-yp4c6ig3jt1bzpdv
Tags: 2.2.0~0beta4-0ubuntu1
* New Upstream Version (LP: #614624)
* Fixed a few bugs on LP:
 - LP: #518453: Dock appears under all windows
                 (Compiz - fullscreen window)
 - LP: #521369: Separator are not removed when closing
                 grouped windows
 - LP: #521762: Some sentences are not correct
 - LP: #526466: Icons of apps with same class shouldn't
                 be stacked by default
 - LP: #535083: Dialogues looks ugly when a lot of them
                 appears at the same time
 - More details on the 'ChangeLog' file
* debian/rules:
 - Autotools has been replaced by CMake
 - Man pages are now included in the source code
* debian/copyright:
 - Updated with the new pathes and new files
* debian/control:
 - Autotools has been replaced by CMake
 - Added libcurl4-gnutls-dev as Build-deps
 - Bump Standard-Version to 3.9.1
* debian/cairo-dock-core.install:
 - Man pages are now included in the source code
 - All sonames are now installed into lib32 or lib64
* debian/cairo-dock-dev.install:
 - pkgconfig is now installed into lib32 or lib64

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include <math.h>
 
21
#include <string.h>
 
22
#include <stdio.h>
 
23
#include <stdlib.h>
 
24
 
 
25
#include <gtk/gtk.h>
 
26
#include <glib/gstdio.h>
 
27
 
 
28
#include <cairo.h>
 
29
 
 
30
#ifdef HAVE_GLITZ
 
31
#include <gdk/gdkx.h>
 
32
#include <glitz-glx.h>
 
33
#include <cairo-glitz.h>
 
34
#endif
 
35
 
 
36
#include "cairo-dock-draw.h"
 
37
#include "cairo-dock-draw-opengl.h"
 
38
#include "cairo-dock-animations.h"
 
39
#include "cairo-dock-config.h"
 
40
#include "cairo-dock-modules.h"
 
41
#include "cairo-dock-callbacks.h"
 
42
#include "cairo-dock-dock-factory.h"
 
43
#include "cairo-dock-dock-facility.h"
 
44
#include "cairo-dock-dialog-manager.h"
 
45
#include "cairo-dock-applications-manager.h"
 
46
#include "cairo-dock-application-facility.h"
 
47
#include "cairo-dock-separator-factory.h"
 
48
#include "cairo-dock-log.h"
 
49
#include "cairo-dock-dock-manager.h"
 
50
#include "cairo-dock-file-manager.h"
 
51
#include "cairo-dock-class-manager.h"
 
52
#include "cairo-dock-internal-icons.h"
 
53
#include "cairo-dock-internal-labels.h"
 
54
#include "cairo-dock-internal-background.h"
 
55
#include "cairo-dock-internal-indicators.h"
 
56
#include "cairo-dock-notifications.h"
 
57
#include "cairo-dock-load.h"
 
58
#include "cairo-dock-container.h"
 
59
#include "cairo-dock-emblem.h"
 
60
#include "cairo-dock-desktop-file-factory.h"
 
61
#include "cairo-dock-gui-manager.h"
 
62
#include "cairo-dock-X-manager.h"
 
63
#include "cairo-dock-icons.h"
 
64
 
 
65
int g_iNbNonStickyLaunchers = 0;
 
66
 
 
67
extern CairoDockDesktopGeometry g_desktopGeometry;
 
68
extern gchar *g_cCurrentLaunchersPath;
 
69
extern gboolean g_bUseOpenGL;
 
70
 
 
71
static GList *s_DetachedLaunchersList = NULL;
 
72
 
 
73
 
 
74
static void _cairo_dock_free_icon_buffers (Icon *icon)
 
75
{
 
76
        if (icon == NULL)
 
77
                return ;
 
78
        
 
79
        g_free (icon->cDesktopFileName);
 
80
        g_free (icon->cFileName);
 
81
        g_free (icon->cName);
 
82
        g_free (icon->cInitialName);
 
83
        g_free (icon->cCommand);
 
84
        g_free (icon->cWorkingDirectory);
 
85
        g_free (icon->cBaseURI);
 
86
        g_free (icon->cParentDockName);  // on ne liberera pas le sous-dock ici sous peine de se mordre la queue, donc il faut l'avoir fait avant.
 
87
        g_free (icon->cClass);
 
88
        g_free (icon->cQuickInfo);
 
89
        g_free (icon->cLastAttentionDemand);
 
90
        
 
91
        cairo_surface_destroy (icon->pIconBuffer);
 
92
        cairo_surface_destroy (icon->pReflectionBuffer);
 
93
        cairo_surface_destroy (icon->pTextBuffer);
 
94
        cairo_surface_destroy (icon->pQuickInfoBuffer);
 
95
        
 
96
        if (icon->iIconTexture != 0)
 
97
                _cairo_dock_delete_texture (icon->iIconTexture);
 
98
        if (icon->iLabelTexture != 0)
 
99
                _cairo_dock_delete_texture (icon->iLabelTexture);
 
100
        if (icon->iQuickInfoTexture != 0)
 
101
                _cairo_dock_delete_texture (icon->iQuickInfoTexture);
 
102
}
 
103
void cairo_dock_free_icon (Icon *icon)
 
104
{
 
105
        if (icon == NULL)
 
106
                return ;
 
107
        cd_debug ("%s (%s , %s)", __func__, icon->cName, icon->cClass);
 
108
        
 
109
        cairo_dock_remove_dialog_if_any (icon);
 
110
        if (icon->iSidRedrawSubdockContent != 0)
 
111
                g_source_remove (icon->iSidRedrawSubdockContent);
 
112
        if (icon->iSidLoadImage != 0)
 
113
                g_source_remove (icon->iSidLoadImage);
 
114
        if (icon->cBaseURI != NULL)
 
115
                cairo_dock_fm_remove_monitor_full (icon->cBaseURI, (icon->pSubDock != NULL), (icon->iVolumeID != 0 ? icon->cCommand : NULL));
 
116
        if (CAIRO_DOCK_IS_NORMAL_APPLI (icon))
 
117
                cairo_dock_unregister_appli (icon);
 
118
        else if (icon->cClass != NULL)  // c'est un inhibiteur.
 
119
                cairo_dock_deinhibate_class (icon->cClass, icon);
 
120
        if (icon->pModuleInstance != NULL)
 
121
                cairo_dock_deinstanciate_module (icon->pModuleInstance);
 
122
        cairo_dock_notify (CAIRO_DOCK_STOP_ICON, icon);
 
123
        cairo_dock_remove_transition_on_icon (icon);
 
124
        
 
125
        if (icon->iSpecificDesktop != 0)
 
126
        {
 
127
                g_iNbNonStickyLaunchers --;
 
128
                s_DetachedLaunchersList = g_list_remove(s_DetachedLaunchersList, icon);
 
129
        }
 
130
        
 
131
        cairo_dock_free_notification_table (icon->pNotificationsTab);
 
132
        _cairo_dock_free_icon_buffers (icon);
 
133
        cd_debug ("icon freeed");
 
134
        g_free (icon);
 
135
}
 
136
 
 
137
CairoDockIconType cairo_dock_get_icon_type (Icon *icon)
 
138
{
 
139
        int iType;
 
140
        if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (icon))
 
141
                iType = CAIRO_DOCK_SEPARATOR12;
 
142
        else
 
143
                iType = (icon->iType < CAIRO_DOCK_NB_TYPES ? icon->iType : icon->iType & 1);
 
144
        
 
145
        return iType;
 
146
        /**if (CAIRO_DOCK_IS_APPLI (icon))
 
147
                return CAIRO_DOCK_APPLI;
 
148
        else if (CAIRO_DOCK_IS_APPLET (icon))
 
149
                return CAIRO_DOCK_APPLET;
 
150
        else if (CAIRO_DOCK_IS_SEPARATOR (icon))
 
151
                return CAIRO_DOCK_SEPARATOR12;
 
152
        else
 
153
                return CAIRO_DOCK_LAUNCHER;*/
 
154
}
 
155
 
 
156
 
 
157
int cairo_dock_compare_icons_order (Icon *icon1, Icon *icon2)
 
158
{
 
159
        int iOrder1 = cairo_dock_get_icon_order (icon1);
 
160
        int iOrder2 = cairo_dock_get_icon_order (icon2);
 
161
        if (iOrder1 < iOrder2)
 
162
                return -1;
 
163
        else if (iOrder1 > iOrder2)
 
164
                return 1;
 
165
        else
 
166
        {
 
167
                if (icon1->fOrder < icon2->fOrder)
 
168
                        return -1;
 
169
                else if (icon1->fOrder > icon2->fOrder)
 
170
                        return 1;
 
171
                else
 
172
                        return 0;
 
173
        }
 
174
}
 
175
int cairo_dock_compare_icons_name (Icon *icon1, Icon *icon2)
 
176
{
 
177
        int iOrder1 = cairo_dock_get_icon_order (icon1);
 
178
        int iOrder2 = cairo_dock_get_icon_order (icon2);
 
179
        if (iOrder1 < iOrder2)
 
180
                return -1;
 
181
        else if (iOrder1 > iOrder2)
 
182
                return 1;
 
183
        
 
184
        if (icon1->cName == NULL)
 
185
                return -1;
 
186
        if (icon2->cName == NULL)
 
187
                return 1;
 
188
        gchar *cURI_1 = g_ascii_strdown (icon1->cName, -1);
 
189
        gchar *cURI_2 = g_ascii_strdown (icon2->cName, -1);
 
190
        int iOrder = strcmp (cURI_1, cURI_2);
 
191
        g_free (cURI_1);
 
192
        g_free (cURI_2);
 
193
        return iOrder;
 
194
}
 
195
 
 
196
int cairo_dock_compare_icons_extension (Icon *icon1, Icon *icon2)
 
197
{
 
198
        int iOrder1 = cairo_dock_get_icon_order (icon1);
 
199
        int iOrder2 = cairo_dock_get_icon_order (icon2);
 
200
        if (iOrder1 < iOrder2)
 
201
                return -1;
 
202
        else if (iOrder1 > iOrder2)
 
203
                return 1;
 
204
        
 
205
        if (icon1->cBaseURI == NULL)
 
206
                return -1;
 
207
        if (icon2->cBaseURI == NULL)
 
208
                return 1;
 
209
        
 
210
        gchar *ext1 = strrchr (icon1->cBaseURI, '.');
 
211
        gchar *ext2 = strrchr (icon2->cBaseURI, '.');
 
212
        if (ext1 == NULL)
 
213
                return -1;
 
214
        if (ext2 == NULL)
 
215
                return 1;
 
216
        
 
217
        ext1 = g_ascii_strdown (ext1+1, -1);
 
218
        ext2 = g_ascii_strdown (ext2+1, -1);
 
219
        
 
220
        int iOrder = strcmp (ext1, ext2);
 
221
        g_free (ext1);
 
222
        g_free (ext2);
 
223
        return iOrder;
 
224
}
 
225
 
 
226
GList *cairo_dock_sort_icons_by_order (GList *pIconList)
 
227
{
 
228
        return g_list_sort (pIconList, (GCompareFunc) cairo_dock_compare_icons_order);
 
229
}
 
230
 
 
231
GList *cairo_dock_sort_icons_by_name (GList *pIconList)
 
232
{
 
233
        GList *pSortedIconList = g_list_sort (pIconList, (GCompareFunc) cairo_dock_compare_icons_name);
 
234
        int iOrder = 0;
 
235
        Icon *icon;
 
236
        GList *ic;
 
237
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
238
        {
 
239
                icon = ic->data;
 
240
                icon->fOrder = iOrder ++;
 
241
        }
 
242
        return pSortedIconList;
 
243
}
 
244
 
 
245
 
 
246
 
 
247
Icon* cairo_dock_get_first_icon (GList *pIconList)
 
248
{
 
249
        GList *pListHead = g_list_first(pIconList);
 
250
        return (pListHead != NULL ? pListHead->data : NULL);
 
251
}
 
252
 
 
253
Icon* cairo_dock_get_last_icon (GList *pIconList)
 
254
{
 
255
        GList *pListTail = g_list_last(pIconList);
 
256
        return (pListTail != NULL ? pListTail->data : NULL);
 
257
}
 
258
 
 
259
Icon *cairo_dock_get_first_drawn_icon (CairoDock *pDock)
 
260
{
 
261
        if (pDock->pFirstDrawnElement != NULL)
 
262
                return pDock->pFirstDrawnElement->data;
 
263
        else
 
264
                return cairo_dock_get_first_icon (pDock->icons);
 
265
}
 
266
 
 
267
Icon *cairo_dock_get_last_drawn_icon (CairoDock *pDock)
 
268
{
 
269
        if (pDock->pFirstDrawnElement != NULL)
 
270
        {
 
271
                if (pDock->pFirstDrawnElement->prev != NULL)
 
272
                        return pDock->pFirstDrawnElement->prev->data;
 
273
                else
 
274
                        return cairo_dock_get_last_icon (pDock->icons);
 
275
        }
 
276
        else
 
277
                return cairo_dock_get_last_icon (pDock->icons);;
 
278
}
 
279
 
 
280
Icon* cairo_dock_get_first_icon_of_group (GList *pIconList, CairoDockIconType iType)
 
281
{
 
282
        GList* ic;
 
283
        Icon *icon;
 
284
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
285
        {
 
286
                icon = ic->data;
 
287
                if (icon->iType == iType)
 
288
                        return icon;
 
289
        }
 
290
        return NULL;
 
291
}
 
292
Icon* cairo_dock_get_last_icon_of_group (GList *pIconList, CairoDockIconType iType)
 
293
{
 
294
        GList* ic;
 
295
        Icon *icon;
 
296
        for (ic = g_list_last (pIconList); ic != NULL; ic = ic->prev)
 
297
        {
 
298
                icon = ic->data;
 
299
                if (icon->iType == iType)
 
300
                        return icon;
 
301
        }
 
302
        return NULL;
 
303
}
 
304
Icon* cairo_dock_get_first_icon_of_order (GList *pIconList, CairoDockIconType iType)
 
305
{
 
306
        CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
 
307
        GList* ic;
 
308
        Icon *icon;
 
309
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
310
        {
 
311
                icon = ic->data;
 
312
                if (cairo_dock_get_icon_order (icon) == iGroupOrder)
 
313
                        return icon;
 
314
        }
 
315
        return NULL;
 
316
}
 
317
Icon* cairo_dock_get_last_icon_of_order (GList *pIconList, CairoDockIconType iType)
 
318
{
 
319
        CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
 
320
        GList* ic;
 
321
        Icon *icon;
 
322
        for (ic = g_list_last (pIconList); ic != NULL; ic = ic->prev)
 
323
        {
 
324
                icon = ic->data;
 
325
                if (cairo_dock_get_icon_order (icon) == iGroupOrder)
 
326
                        return icon;
 
327
        }
 
328
        return NULL;
 
329
}
 
330
Icon* cairo_dock_get_last_icon_until_order (GList *pIconList, CairoDockIconType iType)
 
331
{
 
332
        CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
 
333
        GList* ic;
 
334
        Icon *icon = NULL;
 
335
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
336
        {
 
337
                icon = ic->data;
 
338
                if (cairo_dock_get_icon_order (icon) > iGroupOrder)
 
339
                {
 
340
                        if (ic->prev != NULL)
 
341
                                icon = ic->prev->data;
 
342
                        else
 
343
                                icon = NULL;
 
344
                        break;
 
345
                }
 
346
        }
 
347
        return icon;
 
348
}
 
349
 
 
350
Icon* cairo_dock_get_pointed_icon (GList *pIconList)
 
351
{
 
352
        GList* ic;
 
353
        Icon *icon;
 
354
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
355
        {
 
356
                icon = ic->data;
 
357
                if (icon->bPointed)
 
358
                        return icon;
 
359
        }
 
360
        return NULL;
 
361
}
 
362
 
 
363
 
 
364
Icon *cairo_dock_get_next_icon (GList *pIconList, Icon *pIcon)
 
365
{
 
366
        GList* ic;
 
367
        Icon *icon;
 
368
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
369
        {
 
370
                icon = ic->data;
 
371
                if (icon == pIcon)
 
372
                {
 
373
                        if (ic->next != NULL)
 
374
                                return ic->next->data;
 
375
                        else
 
376
                                return NULL;
 
377
                }
 
378
        }
 
379
        return NULL;
 
380
}
 
381
 
 
382
Icon *cairo_dock_get_previous_icon (GList *pIconList, Icon *pIcon)
 
383
{
 
384
        GList* ic;
 
385
        Icon *icon;
 
386
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
387
        {
 
388
                icon = ic->data;
 
389
                if (icon == pIcon)
 
390
                {
 
391
                        if (ic->prev != NULL)
 
392
                                return ic->prev->data;
 
393
                        else
 
394
                                return NULL;
 
395
                }
 
396
        }
 
397
        return NULL;
 
398
}
 
399
 
 
400
Icon *cairo_dock_get_icon_with_command (GList *pIconList, const gchar *cCommand)
 
401
{
 
402
        g_return_val_if_fail (cCommand != NULL, NULL);
 
403
        GList* ic;
 
404
        Icon *icon;
 
405
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
406
        {
 
407
                icon = ic->data;
 
408
                if (icon->cCommand != NULL && strncmp (icon->cCommand, cCommand, MIN (strlen (icon->cCommand), strlen (cCommand))) == 0)
 
409
                        return icon;
 
410
        }
 
411
        return NULL;
 
412
}
 
413
 
 
414
Icon *cairo_dock_get_icon_with_base_uri (GList *pIconList, const gchar *cBaseURI)
 
415
{
 
416
        g_return_val_if_fail (cBaseURI != NULL, NULL);
 
417
        GList* ic;
 
418
        Icon *icon;
 
419
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
420
        {
 
421
                icon = ic->data;
 
422
                //cd_message ("  icon->cBaseURI : %s\n", icon->cBaseURI);
 
423
                if (icon->cBaseURI != NULL && strcmp (icon->cBaseURI, cBaseURI) == 0)
 
424
                        return icon;
 
425
        }
 
426
        return NULL;
 
427
}
 
428
 
 
429
Icon *cairo_dock_get_icon_with_name (GList *pIconList, const gchar *cName)
 
430
{
 
431
        g_return_val_if_fail (cName != NULL, NULL);
 
432
        GList* ic;
 
433
        Icon *icon;
 
434
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
435
        {
 
436
                icon = ic->data;
 
437
                //cd_message ("  icon->cName : %s\n", icon->cName);
 
438
                if (icon->cName != NULL && strcmp (icon->cName, cName) == 0)
 
439
                        return icon;
 
440
        }
 
441
        return NULL;
 
442
}
 
443
 
 
444
Icon *cairo_dock_get_icon_with_subdock (GList *pIconList, CairoDock *pSubDock)
 
445
{
 
446
        GList* ic;
 
447
        Icon *icon;
 
448
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
449
        {
 
450
                icon = ic->data;
 
451
                if (icon->pSubDock == pSubDock)
 
452
                        return icon;
 
453
        }
 
454
        return NULL;
 
455
}
 
456
 
 
457
Icon *cairo_dock_get_icon_with_module (GList *pIconList, CairoDockModule *pModule)
 
458
{
 
459
        GList* ic;
 
460
        Icon *icon;
 
461
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
462
        {
 
463
                icon = ic->data;
 
464
                if (icon->pModuleInstance->pModule == pModule)
 
465
                        return icon;
 
466
        }
 
467
        return NULL;
 
468
}
 
469
 
 
470
void cairo_dock_get_icon_extent (Icon *pIcon, CairoContainer *pContainer, int *iWidth, int *iHeight)
 
471
{
 
472
        /**double fMaxScale = cairo_dock_get_max_scale (pContainer);
 
473
        double fRatio = (CAIRO_DOCK_IS_DOCK (pContainer) ? pContainer->fRatio : 1.);  // on ne tient pas compte de l'effet de zoom initial du desklet.
 
474
        if (!pContainer || pContainer->bIsHorizontal)
 
475
        {
 
476
                *iWidth = (int) (pIcon->fWidth / fRatio * fMaxScale);
 
477
                *iHeight = (int) (pIcon->fHeight / fRatio * fMaxScale);
 
478
        }
 
479
        else
 
480
        {
 
481
                *iHeight = (int) (pIcon->fWidth / fRatio * fMaxScale);
 
482
                *iWidth = (int) (pIcon->fHeight / fRatio * fMaxScale);
 
483
        }*/
 
484
        *iWidth = pIcon->iImageWidth;
 
485
        *iHeight = pIcon->iImageHeight;
 
486
}
 
487
 
 
488
void cairo_dock_get_current_icon_size (Icon *pIcon, CairoContainer *pContainer, double *fSizeX, double *fSizeY)
 
489
{
 
490
        if (pContainer->bIsHorizontal)
 
491
        {
 
492
                if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (pIcon))
 
493
                {
 
494
                        *fSizeX = pIcon->fWidth;
 
495
                        *fSizeY = pIcon->fHeight;
 
496
                }
 
497
                else
 
498
                {
 
499
                        *fSizeX = pIcon->fWidth * pIcon->fWidthFactor * pIcon->fScale * pIcon->fGlideScale;
 
500
                        *fSizeY = pIcon->fHeight * pIcon->fHeightFactor * pIcon->fScale * pIcon->fGlideScale;
 
501
                }
 
502
        }
 
503
        else
 
504
        {
 
505
                if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (pIcon))
 
506
                {
 
507
                        *fSizeX = pIcon->fHeight;
 
508
                        *fSizeY = pIcon->fWidth;
 
509
                }
 
510
                else
 
511
                {
 
512
                        *fSizeX = pIcon->fHeight * pIcon->fHeightFactor * pIcon->fScale * pIcon->fGlideScale;
 
513
                        *fSizeY = pIcon->fWidth * pIcon->fWidthFactor * pIcon->fScale * pIcon->fGlideScale;
 
514
                }
 
515
        }
 
516
}
 
517
 
 
518
void cairo_dock_compute_icon_area (Icon *icon, CairoContainer *pContainer, GdkRectangle *pArea)
 
519
{
 
520
        double fReflectSize = 0;
 
521
        if (pContainer->bUseReflect)
 
522
        {
 
523
                fReflectSize = myIcons.fReflectSize * icon->fScale * fabs (icon->fHeightFactor) + icon->fDeltaYReflection + myBackground.iFrameMargin;  // un peu moyen le iFrameMargin mais bon ...
 
524
        }
 
525
        if (! myIndicators.bIndicatorOnIcon)
 
526
                fReflectSize = MAX (fReflectSize, myIndicators.fIndicatorDeltaY * icon->fHeight);
 
527
        
 
528
        double fX = icon->fDrawX;
 
529
        fX += icon->fWidth * icon->fScale * (1 - fabs (icon->fWidthFactor))/2 + icon->fGlideOffset * icon->fWidth * icon->fScale;
 
530
        
 
531
        double fY = icon->fDrawY;
 
532
        fY += (pContainer->bDirectionUp ? icon->fHeight * icon->fScale * (1 - icon->fHeightFactor)/2 : - fReflectSize);
 
533
        if (fY < 0)
 
534
                fY = 0;
 
535
        
 
536
        if (pContainer->bIsHorizontal)
 
537
        {
 
538
                pArea->x = (int) floor (fX) - 1;
 
539
                pArea->y = (int) floor (fY);
 
540
                pArea->width = (int) ceil (icon->fWidth * icon->fScale * fabs (icon->fWidthFactor)) + 2;
 
541
                pArea->height = (int) ceil (icon->fHeight * icon->fScale * fabs (icon->fHeightFactor) + fReflectSize);
 
542
        }
 
543
        else
 
544
        {
 
545
                pArea->x = (int) floor (fY);
 
546
                pArea->y = (int) floor (fX) - 1;
 
547
                pArea->width = ((int) ceil (icon->fHeight * icon->fScale * fabs (icon->fHeightFactor) + fReflectSize));
 
548
                pArea->height = (int) ceil (icon->fWidth * icon->fScale * fabs (icon->fWidthFactor)) + 2;
 
549
        }
 
550
        //g_print ("redraw : %d;%d %dx%d\n", pArea->x, pArea->y, pArea->width,pArea->height);
 
551
}
 
552
 
 
553
 
 
554
 
 
555
void cairo_dock_normalize_icons_order (GList *pIconList, CairoDockIconType iType)
 
556
{
 
557
        cd_message ("%s (%d)", __func__, iType);
 
558
        int iOrder = 1;
 
559
        CairoDockIconType iGroupOrder = cairo_dock_get_group_order (iType);
 
560
        GString *sDesktopFilePath = g_string_new ("");
 
561
        GList* ic;
 
562
        Icon *icon;
 
563
        for (ic = pIconList; ic != NULL; ic = ic->next)
 
564
        {
 
565
                icon = ic->data;
 
566
                if (cairo_dock_get_icon_order (icon) != iGroupOrder)
 
567
                        continue;
 
568
                
 
569
                icon->fOrder = iOrder ++;
 
570
                if (icon->cDesktopFileName != NULL)
 
571
                {
 
572
                        g_string_printf (sDesktopFilePath, "%s/%s", g_cCurrentLaunchersPath, icon->cDesktopFileName);
 
573
                        cairo_dock_update_conf_file (sDesktopFilePath->str,
 
574
                                G_TYPE_DOUBLE, "Desktop Entry", "Order", icon->fOrder,
 
575
                                G_TYPE_INVALID);
 
576
                }
 
577
                else if (CAIRO_DOCK_IS_APPLET (icon))
 
578
                {
 
579
                        cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
 
580
                                G_TYPE_DOUBLE, "Icon", "order", icon->fOrder,
 
581
                                G_TYPE_INVALID);
 
582
                }
 
583
        }
 
584
        g_string_free (sDesktopFilePath, TRUE);
 
585
        cairo_dock_trigger_refresh_launcher_gui ();
 
586
}
 
587
 
 
588
void cairo_dock_move_icon_after_icon (CairoDock *pDock, Icon *icon1, Icon *icon2)
 
589
{
 
590
        //g_print ("%s (%s, %.2f, %x)\n", __func__, icon1->cName, icon1->fOrder, icon2);
 
591
        if ((icon2 != NULL) && fabs (cairo_dock_get_icon_order (icon1) - cairo_dock_get_icon_order (icon2)) > 1)
 
592
                return ;
 
593
        //\_________________ On change l'ordre de l'icone.
 
594
        gboolean bForceUpdate = FALSE;
 
595
        if (icon2 != NULL)
 
596
        {
 
597
                Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon2);
 
598
                if (pNextIcon != NULL && fabs (pNextIcon->fOrder - icon2->fOrder) < 1e-2)
 
599
                {
 
600
                        bForceUpdate = TRUE;
 
601
                }
 
602
                if (pNextIcon == NULL || cairo_dock_get_icon_order (pNextIcon) != cairo_dock_get_icon_order (icon2))
 
603
                        icon1->fOrder = icon2->fOrder + 1;
 
604
                else
 
605
                        icon1->fOrder = (pNextIcon->fOrder - icon2->fOrder > 1 ? icon2->fOrder + 1 : (pNextIcon->fOrder + icon2->fOrder) / 2);
 
606
        }
 
607
        else
 
608
        {
 
609
                Icon *pFirstIcon = cairo_dock_get_first_icon_of_order (pDock->icons, icon1->iType);
 
610
                if (pFirstIcon != NULL)
 
611
                        icon1->fOrder = pFirstIcon->fOrder - 1;
 
612
                else
 
613
                        icon1->fOrder = 1;
 
614
        }
 
615
        //g_print ("icon1->fOrder:%.2f\n", icon1->fOrder);
 
616
        
 
617
        //\_________________ On change l'ordre dans le fichier du lanceur 1.
 
618
        cairo_dock_write_order_in_conf_file (icon1, icon1->fOrder);
 
619
        
 
620
        //\_________________ On change sa place dans la liste.
 
621
        pDock->pFirstDrawnElement = NULL;
 
622
        pDock->icons = g_list_remove (pDock->icons, icon1);
 
623
        pDock->icons = g_list_insert_sorted (pDock->icons,
 
624
                icon1,
 
625
                (GCompareFunc) cairo_dock_compare_icons_order);
 
626
 
 
627
        //\_________________ On recalcule la largeur max, qui peut avoir ete influencee par le changement d'ordre.
 
628
        cairo_dock_update_dock_size (pDock);
 
629
        
 
630
        if (icon1->pSubDock != NULL && icon1->cClass != NULL)
 
631
        {
 
632
                cairo_dock_trigger_set_WM_icons_geometry (icon1->pSubDock);
 
633
        }
 
634
        
 
635
        if (pDock->iRefCount != 0)
 
636
        {
 
637
                cairo_dock_redraw_subdock_content (pDock);
 
638
        }
 
639
        
 
640
        if (bForceUpdate)
 
641
                cairo_dock_normalize_icons_order (pDock->icons, icon1->iType);
 
642
        if (CAIRO_DOCK_IS_STORED_LAUNCHER (icon1) || CAIRO_DOCK_IS_USER_SEPARATOR (icon1) || CAIRO_DOCK_ICON_TYPE_IS_APPLET (icon1))
 
643
                cairo_dock_trigger_refresh_launcher_gui ();
 
644
}
 
645
 
 
646
 
 
647
Icon *cairo_dock_foreach_icons_of_type (GList *pIconList, CairoDockIconType iType, CairoDockForeachIconFunc pFuntion, gpointer data)
 
648
{
 
649
        //g_print ("%s (%d)\n", __func__, iType);
 
650
        if (pIconList == NULL)
 
651
                return NULL;
 
652
 
 
653
        Icon *icon;
 
654
        GList *ic = pIconList, *next_ic;
 
655
        gboolean bOneIconFound = FALSE;
 
656
        Icon *pSeparatorIcon = NULL;
 
657
        while (ic != NULL)  // on parcourt tout, inutile de complexifier la chose pour gagner 3ns.
 
658
        {
 
659
                icon = ic->data;
 
660
                next_ic = ic->next;
 
661
                if (icon->iType == iType)
 
662
                {
 
663
                        bOneIconFound = TRUE;
 
664
                        pFuntion (icon, NULL, data);
 
665
                }
 
666
                else
 
667
                {
 
668
                        if (CAIRO_DOCK_IS_AUTOMATIC_SEPARATOR (icon))
 
669
                        {
 
670
                                if ( (bOneIconFound && pSeparatorIcon == NULL) || (! bOneIconFound) )
 
671
                                        pSeparatorIcon = icon;
 
672
                        }
 
673
                }
 
674
                ic = next_ic;
 
675
        }
 
676
 
 
677
        if (bOneIconFound)
 
678
                return pSeparatorIcon;
 
679
        else
 
680
                return NULL;
 
681
}
 
682
 
 
683
 
 
684
 
 
685
void cairo_dock_update_icon_s_container_name (Icon *icon, const gchar *cNewParentDockName)
 
686
{
 
687
        g_free (icon->cParentDockName);
 
688
        icon->cParentDockName = g_strdup (cNewParentDockName);
 
689
        
 
690
        cairo_dock_write_container_name_in_conf_file (icon, cNewParentDockName);
 
691
}
 
692
 
 
693
 
 
694
void cairo_dock_set_icon_name (const gchar *cIconName, Icon *pIcon, CairoContainer *pContainer)  // fonction proposee par Necropotame.
 
695
{
 
696
        g_return_if_fail (pIcon != NULL && pContainer != NULL);  // le contexte sera verifie plus loin.
 
697
        gchar *cUniqueName = NULL;
 
698
        
 
699
        if (pIcon->pSubDock != NULL)
 
700
        {
 
701
                cUniqueName = cairo_dock_get_unique_dock_name (cIconName);
 
702
                cIconName = cUniqueName;
 
703
                cairo_dock_rename_dock (pIcon->cName, pIcon->pSubDock, cUniqueName);
 
704
        }
 
705
        if (pIcon->cName != cIconName)
 
706
        {
 
707
                g_free (pIcon->cName);
 
708
                pIcon->cName = g_strdup (cIconName);
 
709
        }
 
710
        
 
711
        g_free (cUniqueName);
 
712
        
 
713
        cairo_dock_load_icon_text (pIcon, &myLabels.iconTextDescription);
 
714
}
 
715
 
 
716
void cairo_dock_set_icon_name_printf (Icon *pIcon, CairoContainer *pContainer, const gchar *cIconNameFormat, ...)
 
717
{
 
718
        va_list args;
 
719
        va_start (args, cIconNameFormat);
 
720
        gchar *cFullText = g_strdup_vprintf (cIconNameFormat, args);
 
721
        cairo_dock_set_icon_name (cFullText, pIcon, pContainer);
 
722
        g_free (cFullText);
 
723
        va_end (args);
 
724
}
 
725
 
 
726
void cairo_dock_set_quick_info (Icon *pIcon, CairoContainer *pContainer, const gchar *cQuickInfo)
 
727
{
 
728
        g_return_if_fail (pIcon != NULL);  // le contexte sera verifie plus loin.
 
729
 
 
730
        if (pIcon->cQuickInfo != cQuickInfo)
 
731
        {
 
732
                g_free (pIcon->cQuickInfo);
 
733
                pIcon->cQuickInfo = g_strdup (cQuickInfo);
 
734
        }
 
735
        
 
736
        double fMaxScale = cairo_dock_get_max_scale (pContainer);
 
737
        cairo_dock_load_icon_quickinfo (pIcon,
 
738
                &myLabels.quickInfoTextDescription,
 
739
                fMaxScale);
 
740
}
 
741
 
 
742
void cairo_dock_set_quick_info_printf (Icon *pIcon, CairoContainer *pContainer, const gchar *cQuickInfoFormat, ...)
 
743
{
 
744
        va_list args;
 
745
        va_start (args, cQuickInfoFormat);
 
746
        gchar *cFullText = g_strdup_vprintf (cQuickInfoFormat, args);
 
747
        cairo_dock_set_quick_info (pIcon, pContainer, cFullText);
 
748
        g_free (cFullText);
 
749
        va_end (args);
 
750
}
 
751
 
 
752
 
 
753
 
 
754
static CairoDock *_cairo_dock_insert_launcher_in_dock (Icon *icon, CairoDock *pMainDock, gboolean bUpdateSize, gboolean bAnimate)
 
755
{
 
756
        cd_message ("%s (%s)", __func__, icon->cName);
 
757
        g_return_val_if_fail (pMainDock != NULL, NULL);
 
758
        
 
759
        cairo_dock_reserve_one_icon_geometry_for_window_manager (&icon->Xid, icon, pMainDock);
 
760
        
 
761
        //\_________________ On determine dans quel dock l'inserer.
 
762
        CairoDock *pParentDock = pMainDock;
 
763
        g_return_val_if_fail (pParentDock != NULL, NULL);
 
764
 
 
765
        //\_________________ On l'insere dans son dock parent en animant ce dernier eventuellement.
 
766
        cairo_dock_insert_icon_in_dock (icon, pParentDock, bUpdateSize, bAnimate);
 
767
        cd_message (" insertion de %s complete (%.2f %.2fx%.2f) dans %s", icon->cName, icon->fInsertRemoveFactor, icon->fWidth, icon->fHeight, icon->cParentDockName);
 
768
 
 
769
        if (bAnimate && cairo_dock_animation_will_be_visible (pParentDock))
 
770
        {
 
771
                cairo_dock_launch_animation (CAIRO_CONTAINER (pParentDock));
 
772
        }
 
773
        else
 
774
        {
 
775
                icon->fInsertRemoveFactor = 0;
 
776
                icon->fScale = 1.;
 
777
        }
 
778
 
 
779
        return pParentDock;
 
780
}
 
781
static CairoDock * _cairo_dock_detach_launcher(Icon *pIcon)
 
782
{
 
783
        cd_debug ("%s (%s, parent dock=%s)", __func__, pIcon->cName, pIcon->cParentDockName);
 
784
        CairoDock *pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
 
785
        if (pParentDock == NULL)
 
786
                return NULL;
 
787
 
 
788
        gchar *cParentDockName = g_strdup(pIcon->cParentDockName);
 
789
        cairo_dock_detach_icon_from_dock (pIcon, pParentDock, TRUE); // this will set cParentDockName to NULL
 
790
        
 
791
        pIcon->cParentDockName = cParentDockName; // put it back !
 
792
 
 
793
        cairo_dock_update_dock_size (pParentDock);
 
794
        return pParentDock;
 
795
}
 
796
static void _cairo_dock_hide_show_launchers_on_other_desktops (Icon *icon, CairoContainer *pContainer, CairoDock *pMainDock)
 
797
{
 
798
        if (CAIRO_DOCK_IS_LAUNCHER(icon))
 
799
        {
 
800
                cd_debug ("%s (%s, iNumViewport=%d)", __func__, icon->cName, icon->iSpecificDesktop);
 
801
                CairoDock *pParentDock = NULL;
 
802
                // a specific desktop/viewport has been selected for this icon
 
803
 
 
804
                int iCurrentDesktop = 0, iCurrentViewportX = 0, iCurrentViewportY = 0;
 
805
                cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
 
806
                int index = iCurrentDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportY + 1;  // +1 car on commence a compter a partir de 1.
 
807
                
 
808
                if (icon->iSpecificDesktop == 0 || icon->iSpecificDesktop == index || icon->iSpecificDesktop > g_desktopGeometry.iNbDesktops * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY)
 
809
                /**if( icon->iSpecificDesktop <= 0 ||
 
810
                // metacity case: metacity uses desktop instead of viewport.
 
811
                    (g_desktopGeometry.iNbViewportX*g_desktopGeometry.iNbViewportY==1 &&
 
812
                    (icon->iSpecificDesktop-1 == iCurrentDesktop || 
 
813
                     icon->iSpecificDesktop >= g_desktopGeometry.iNbDesktops)) ||
 
814
                // compiz case: viewports are used within a desktop
 
815
                                (g_desktopGeometry.iNbViewportX*g_desktopGeometry.iNbViewportY>1 &&
 
816
                    (icon->iSpecificDesktop-1 == iCurrentViewportX + g_desktopGeometry.iNbViewportX*iCurrentViewportY ||
 
817
                     icon->iSpecificDesktop >= g_desktopGeometry.iNbViewportX*g_desktopGeometry.iNbViewportY)) )*/
 
818
                {
 
819
                        cd_debug (" => est visible sur ce viewport (iSpecificDesktop = %d).",icon->iSpecificDesktop);
 
820
                        // check that it is in the detached list
 
821
                        if( g_list_find(s_DetachedLaunchersList, icon) != NULL )
 
822
                        {
 
823
                                pParentDock = _cairo_dock_insert_launcher_in_dock (icon, pMainDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
 
824
                                s_DetachedLaunchersList = g_list_remove(s_DetachedLaunchersList, icon);
 
825
                        }
 
826
                }
 
827
                else
 
828
                {
 
829
                        cd_debug (" Viewport actuel = %d => n'est pas sur le viewport actuel.", iCurrentViewportX + g_desktopGeometry.iNbViewportX*iCurrentViewportY);
 
830
                        if( g_list_find(s_DetachedLaunchersList, icon) == NULL ) // only if not yet detached
 
831
                        {
 
832
                                cd_debug( "Detach launcher %s", icon->cName);
 
833
                                pParentDock = _cairo_dock_detach_launcher(icon);
 
834
                                s_DetachedLaunchersList = g_list_prepend(s_DetachedLaunchersList, icon);
 
835
                        }
 
836
                }
 
837
                if (pParentDock != NULL)
 
838
                        gtk_widget_queue_draw (pParentDock->container.pWidget);
 
839
        }
 
840
}
 
841
 
 
842
void cairo_dock_hide_show_launchers_on_other_desktops (CairoDock *pDock)
 
843
{
 
844
        if (g_iNbNonStickyLaunchers <= 0)
 
845
                return ;
 
846
        // first we detach what shouldn't be show on this viewport
 
847
        cairo_dock_foreach_icons_of_type (pDock->icons, CAIRO_DOCK_LAUNCHER, (CairoDockForeachIconFunc)_cairo_dock_hide_show_launchers_on_other_desktops, pDock);
 
848
        // then we reattach what was eventually missing
 
849
        cairo_dock_foreach_icons_of_type (s_DetachedLaunchersList, CAIRO_DOCK_LAUNCHER, (CairoDockForeachIconFunc)_cairo_dock_hide_show_launchers_on_other_desktops, pDock);
 
850
}