1.1.10
by Matthieu Baerts (matttbe)
Import upstream version 2.2.0~0beta4 |
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 |
}
|