1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
3
** Login : <ctaf42@gmail.com>
4
** Started on Sun Jan 27 18:35:38 2008 Cedric GESTES
8
** - Cedric GESTES <ctaf42@gmail.com>
11
** Copyright (C) 2008 Cedric GESTES
12
** This program is free software; you can redistribute it and/or modify
13
** it under the terms of the GNU General Public License as published by
14
** the Free Software Foundation; either version 3 of the License, or
15
** (at your option) any later version.
17
** This program is distributed in the hope that it will be useful,
18
** but WITHOUT ANY WARRANTY; without even the implied warranty of
19
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
** GNU General Public License for more details.
22
** You should have received a copy of the GNU General Public License
23
** along with this program; if not, write to the Free Software
24
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31
#include <gtk/gtkgl.h>
35
#include <gdk/x11/gdkglx.h>
38
#include "cairo-dock-draw.h"
39
#include "cairo-dock-modules.h"
40
#include "cairo-dock-dialog-manager.h"
41
#include "cairo-dock-icons.h"
42
#include "cairo-dock-config.h"
43
#include "cairo-dock-X-manager.h"
44
#include "cairo-dock-notifications.h"
45
#include "cairo-dock-log.h"
46
#include "cairo-dock-container.h"
47
#include "cairo-dock-X-utilities.h"
48
#include "cairo-dock-surface-factory.h"
49
#include "cairo-dock-backends-manager.h"
50
#include "cairo-dock-draw-opengl.h"
51
#include "cairo-dock-load.h"
52
#include "cairo-dock-animations.h"
53
#include "cairo-dock-internal-desklets.h"
54
#include "cairo-dock-gui-manager.h"
55
#include "cairo-dock-launcher-manager.h"
56
#include "cairo-dock-desklet-factory.h"
58
extern gboolean g_bUseOpenGL;
59
extern CairoDockDesktopGeometry g_desktopGeometry;
61
static void _cairo_dock_reserve_space_for_desklet (CairoDesklet *pDesklet, gboolean bReserve);
62
static void on_drag_data_received_desklet (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, CairoDesklet *pDesklet);
68
static gboolean on_expose_desklet(GtkWidget *pWidget,
69
GdkEventExpose *pExpose,
70
CairoDesklet *pDesklet)
72
if (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0 && (pDesklet->iKnownWidth != pDesklet->iDesiredWidth || pDesklet->iKnownHeight != pDesklet->iDesiredHeight))
74
//g_print ("on saute le dessin\n");
77
// dessiner la fausse transparence.
81
cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
82
cairo_destroy (pCairoContext);
87
if (g_bUseOpenGL && pDesklet->pRenderer && pDesklet->pRenderer->render_opengl)
89
GdkGLContext *pGlContext = gtk_widget_get_gl_context (pDesklet->container.pWidget);
90
GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pDesklet->container.pWidget);
91
if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
94
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
97
cairo_dock_apply_desktop_background_opengl (CAIRO_CONTAINER (pDesklet));
99
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_RENDER_DESKLET, pDesklet, NULL);
101
if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
102
gdk_gl_drawable_swap_buffers (pGlDrawable);
105
gdk_gl_drawable_gl_end (pGlDrawable);
109
cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
111
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_RENDER_DESKLET, pDesklet, pCairoContext);
113
cairo_destroy (pCairoContext);
119
static void _cairo_dock_set_desklet_input_shape (CairoDesklet *pDesklet)
121
gtk_widget_input_shape_combine_mask (pDesklet->container.pWidget,
125
if (pDesklet->bNoInput)
127
GdkBitmap *pShapeBitmap = (GdkBitmap*) gdk_pixmap_new (NULL,
128
pDesklet->container.iWidth,
129
pDesklet->container.iHeight,
132
cairo_t *pCairoContext = gdk_cairo_create (pShapeBitmap);
133
cairo_set_source_rgba (pCairoContext, 0.0f, 0.0f, 0.0f, 0.0f);
134
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
135
cairo_paint (pCairoContext);
136
cairo_set_source_rgba (pCairoContext, 1., 1., 1., 1.);
137
cairo_rectangle (pCairoContext,
138
pDesklet->container.iWidth - myDesklets.iDeskletButtonSize,
139
pDesklet->container.iHeight - myDesklets.iDeskletButtonSize,
140
myDesklets.iDeskletButtonSize,
141
myDesklets.iDeskletButtonSize);
142
cairo_fill (pCairoContext);
143
cairo_destroy (pCairoContext);
144
gtk_widget_input_shape_combine_mask (pDesklet->container.pWidget,
148
g_object_unref (pShapeBitmap);
149
//g_print ("input shape : %dx%d\n", pDesklet->container.iWidth, pDesklet->container.iHeight);
153
static gboolean _cairo_dock_write_desklet_size (CairoDesklet *pDesklet)
155
if ((pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0) && pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
157
gchar *cSize = g_strdup_printf ("%d;%d", pDesklet->container.iWidth, pDesklet->container.iHeight);
158
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
159
G_TYPE_STRING, "Desklet", "size", cSize,
162
cairo_dock_update_desklet_size_in_gui (pDesklet->pIcon->pModuleInstance,
163
pDesklet->container.iWidth,
164
pDesklet->container.iHeight);
166
pDesklet->iSidWriteSize = 0;
167
pDesklet->iKnownWidth = pDesklet->container.iWidth;
168
pDesklet->iKnownHeight = pDesklet->container.iHeight;
169
if (((pDesklet->iDesiredWidth != 0 || pDesklet->iDesiredHeight != 0) && pDesklet->iDesiredWidth == pDesklet->container.iWidth && pDesklet->iDesiredHeight == pDesklet->container.iHeight) || (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0))
171
pDesklet->iDesiredWidth = 0;
172
pDesklet->iDesiredHeight = 0;
174
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDesklet));
175
cairo_dock_load_desklet_decorations (pDesklet);
176
cairo_destroy (pCairoContext);
178
if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
180
// on recalcule la vue du desklet a la nouvelle dimension.
181
CairoDeskletRenderer *pRenderer = pDesklet->pRenderer;
184
// on calcule les icones et les parametres internes de la vue.
185
if (pRenderer->calculate_icons != NULL)
186
pRenderer->calculate_icons (pDesklet);
188
// on recharge l'icone principale.
189
Icon* pIcon = pDesklet->pIcon;
192
pIcon->iImageWidth = pIcon->fWidth;
193
pIcon->iImageHeight = pIcon->fHeight;
194
if (pIcon->iImageWidth > 0)
195
cairo_dock_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet)); // pas de trigger, car on veut pouvoir associer un contexte a l'icone principale tout de suite.
198
// on recharge chaque icone.
200
for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
203
if ((int)pIcon->fWidth != pIcon->iImageWidth || (int)pIcon->fHeight != pIcon->iImageHeight)
205
pIcon->iImageWidth = pIcon->fWidth;
206
pIcon->iImageHeight = pIcon->fHeight;
207
cairo_dock_trigger_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet));
211
// on recharge les buffers de la vue.
212
if (pRenderer->load_data != NULL)
213
pRenderer->load_data (pDesklet);
216
// on recharge le module associe.
217
cairo_dock_reload_module_instance (pDesklet->pIcon->pModuleInstance, FALSE);
219
gtk_widget_queue_draw (pDesklet->container.pWidget); // sinon on ne redessine que l'interieur.
222
Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
223
if (pDesklet->bSpaceReserved) // l'espace est reserve, on reserve la nouvelle taille.
225
_cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);
229
//g_print ("iWidth <- %d;iHeight <- %d ; (%dx%d) (%x)\n", pDesklet->container.iWidth, pDesklet->container.iHeight, pDesklet->iKnownWidth, pDesklet->iKnownHeight, pDesklet->pIcon);
232
static gboolean _cairo_dock_write_desklet_position (CairoDesklet *pDesklet)
234
if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
236
int iRelativePositionX = (pDesklet->container.iWindowPositionX + pDesklet->container.iWidth/2 <= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL]/2 ? pDesklet->container.iWindowPositionX : pDesklet->container.iWindowPositionX - g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL]);
237
int iRelativePositionY = (pDesklet->container.iWindowPositionY + pDesklet->container.iHeight/2 <= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]/2 ? pDesklet->container.iWindowPositionY : pDesklet->container.iWindowPositionY - g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
239
Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
240
int iNumDesktop = -1;
241
if (! cairo_dock_xwindow_is_sticky (Xid))
243
int iDesktop = cairo_dock_get_xwindow_desktop (Xid);
244
int iGlobalPositionX, iGlobalPositionY, iWidthExtent, iHeightExtent;
245
cairo_dock_get_xwindow_geometry (Xid, &iGlobalPositionX, &iGlobalPositionY, &iWidthExtent, &iHeightExtent);
246
if (iGlobalPositionX < 0)
247
iGlobalPositionX += g_desktopGeometry.iNbViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
248
if (iGlobalPositionY < 0)
249
iGlobalPositionY += g_desktopGeometry.iNbViewportY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
251
int iViewportX = iGlobalPositionX / g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
252
int iViewportY = iGlobalPositionY / g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
254
int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
255
cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
257
iViewportX += iCurrentViewportX;
258
if (iViewportX >= g_desktopGeometry.iNbViewportX)
259
iViewportX -= g_desktopGeometry.iNbViewportX;
260
iViewportY += iCurrentViewportY;
261
if (iViewportY >= g_desktopGeometry.iNbViewportY)
262
iViewportY -= g_desktopGeometry.iNbViewportY;
263
//g_print ("position : %d,%d,%d / %d,%d,%d\n", iDesktop, iViewportX, iViewportY, iCurrentDesktop, iCurrentViewportX, iCurrentViewportY);
265
iNumDesktop = iDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iViewportX * g_desktopGeometry.iNbViewportY + iViewportY;
266
//g_print ("desormais on place le desklet sur le bureau (%d,%d,%d)\n", iDesktop, iViewportX, iViewportY);
269
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
270
G_TYPE_INT, "Desklet", "x position", iRelativePositionX,
271
G_TYPE_INT, "Desklet", "y position", iRelativePositionY,
272
G_TYPE_INT, "Desklet", "num desktop", iNumDesktop,
274
cairo_dock_update_desklet_position_in_gui (pDesklet->pIcon->pModuleInstance,
279
if (pDesklet->bSpaceReserved) // l'espace est reserve, on reserve a la nouvelle position.
281
_cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);
283
if (pDesklet->pIcon && cairo_dock_icon_has_dialog (pDesklet->pIcon))
285
cairo_dock_replace_all_dialogs ();
287
pDesklet->iSidWritePosition = 0;
290
static gboolean on_configure_desklet (GtkWidget* pWidget,
291
GdkEventConfigure* pEvent,
292
CairoDesklet *pDesklet)
294
//g_print (" >>>>>>>>> %s (%dx%d, %d;%d)", __func__, pEvent->width, pEvent->height, pEvent->x, pEvent->y);
295
if (pDesklet->container.iWidth != pEvent->width || pDesklet->container.iHeight != pEvent->height)
297
if ((pEvent->width < pDesklet->container.iWidth || pEvent->height < pDesklet->container.iHeight) && (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0))
299
gdk_window_resize (pDesklet->container.pWidget->window,
300
pDesklet->iDesiredWidth,
301
pDesklet->iDesiredHeight);
304
pDesklet->container.iWidth = pEvent->width;
305
pDesklet->container.iHeight = pEvent->height;
309
GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
310
GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
311
GLsizei w = pEvent->width;
312
GLsizei h = pEvent->height;
313
if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
316
glViewport(0, 0, w, h);
318
cairo_dock_set_perspective_view (CAIRO_CONTAINER (pDesklet));
320
gdk_gl_drawable_gl_end (pGlDrawable);
323
if (pDesklet->bNoInput)
324
_cairo_dock_set_desklet_input_shape (pDesklet);
326
if (pDesklet->iSidWriteSize != 0)
328
g_source_remove (pDesklet->iSidWriteSize);
330
pDesklet->iSidWriteSize = g_timeout_add (500, (GSourceFunc) _cairo_dock_write_desklet_size, (gpointer) pDesklet);
333
int x = pEvent->x, y = pEvent->y;
334
//g_print ("new desklet position : (%d;%d)", x, y);
335
while (x < 0) // on passe au referentiel du viewport de la fenetre; inutile de connaitre sa position, puisqu'ils ont tous la meme taille.
336
x += g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
337
while (x >= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL])
338
x -= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
340
y += g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
341
while (y >= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
342
y -= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
343
//g_print (" => (%d;%d)\n", x, y);
344
if (pDesklet->container.iWindowPositionX != x || pDesklet->container.iWindowPositionY != y)
346
pDesklet->container.iWindowPositionX = x;
347
pDesklet->container.iWindowPositionY = y;
349
if (pDesklet->iSidWritePosition != 0)
351
g_source_remove (pDesklet->iSidWritePosition);
353
pDesklet->iSidWritePosition = g_timeout_add (500, (GSourceFunc) _cairo_dock_write_desklet_position, (gpointer) pDesklet);
355
pDesklet->moving = FALSE;
360
static gboolean on_scroll_desklet (GtkWidget* pWidget,
361
GdkEventScroll* pScroll,
362
CairoDesklet *pDesklet)
364
//g_print ("scroll\n");
365
if (! (pScroll->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
367
Icon *icon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
370
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_SCROLL_ICON, icon, pDesklet, pScroll->direction);
376
static gboolean on_unmap_desklet (GtkWidget* pWidget,
378
CairoDesklet *pDesklet)
380
cd_debug ("unmap desklet (bAllowMinimize:%d)\n", pDesklet->bAllowMinimize);
381
Window Xid = GDK_WINDOW_XID (pWidget->window);
382
if (cairo_dock_window_is_utility (Xid)) // sur la couche des widgets, on ne fait rien.
384
if (! pDesklet->bAllowMinimize)
386
if (pDesklet->pUnmapTimer)
388
double fElapsedTime = g_timer_elapsed (pDesklet->pUnmapTimer, NULL);
389
cd_debug ("fElapsedTime : %fms\n", fElapsedTime);
390
g_timer_destroy (pDesklet->pUnmapTimer);
391
pDesklet->pUnmapTimer = NULL;
392
if (fElapsedTime < .2)
395
gtk_window_present (GTK_WINDOW (pWidget));
399
pDesklet->bAllowMinimize = FALSE;
400
if (pDesklet->pUnmapTimer == NULL)
401
pDesklet->pUnmapTimer = g_timer_new (); // starts the timer.
403
return TRUE; // stops other handlers from being invoked for the event.
406
static gboolean on_button_press_desklet(GtkWidget *pWidget,
407
GdkEventButton *pButton,
408
CairoDesklet *pDesklet)
410
if (pButton->button == 1) // clic gauche.
412
if (pButton->type == GDK_BUTTON_PRESS)
414
pDesklet->bClicked = TRUE;
415
if (cairo_dock_desklet_is_free (pDesklet))
417
pDesklet->container.iMouseX = pButton->x; // pour le deplacement manuel.
418
pDesklet->container.iMouseY = pButton->y;
420
if (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
421
pDesklet->rotating = TRUE;
422
else if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
423
pDesklet->retaching = TRUE;
424
else if (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize)
425
pDesklet->rotatingY = TRUE;
426
else if (pButton->y > (pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDesklets.iDeskletButtonSize)/2 && pButton->x < myDesklets.iDeskletButtonSize)
427
pDesklet->rotatingX = TRUE;
429
pDesklet->time = pButton->time;
431
if (pDesklet->bAllowNoClickable && pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y > pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)
432
pDesklet->making_transparent = TRUE;
434
else if (pButton->type == GDK_BUTTON_RELEASE)
436
if (!pDesklet->bClicked) // on n'accepte le release que si on avait clique sur le desklet avant (on peut recevoir le release si on avat clique sur un dialogue qui chevauchait notre desklet et qui a disparu au clic).
440
pDesklet->bClicked = FALSE;
441
cd_debug ("GDK_BUTTON_RELEASE");
442
if (pDesklet->moving)
444
pDesklet->moving = FALSE;
446
else if (pDesklet->rotating)
448
pDesklet->rotating = FALSE;
449
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
450
G_TYPE_INT, "Desklet", "rotation", (int) (pDesklet->fRotation / G_PI * 180.),
452
gtk_widget_queue_draw (pDesklet->container.pWidget);
454
else if (pDesklet->retaching)
456
pDesklet->retaching = FALSE;
457
if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize) // on verifie qu'on est encore dedans.
459
Icon *icon = pDesklet->pIcon;
460
g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
461
cairo_dock_detach_module_instance (icon->pModuleInstance);
462
return TRUE; // interception du signal.
465
else if (pDesklet->making_transparent)
467
cd_debug ("pDesklet->making_transparent\n");
468
pDesklet->making_transparent = FALSE;
469
if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y > pDesklet->container.iHeight - myDesklets.iDeskletButtonSize) // on verifie qu'on est encore dedans.
471
Icon *icon = pDesklet->pIcon;
472
g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
473
pDesklet->bNoInput = ! pDesklet->bNoInput;
474
cd_debug ("no input : %d (%s)\n", pDesklet->bNoInput, icon->pModuleInstance->cConfFilePath);
475
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
476
G_TYPE_BOOLEAN, "Desklet", "no input", pDesklet->bNoInput,
478
_cairo_dock_set_desklet_input_shape (pDesklet);
479
gtk_widget_queue_draw (pDesklet->container.pWidget);
480
if (pDesklet->bNoInput)
481
cairo_dock_allow_widget_to_receive_data (pDesklet->container.pWidget, G_CALLBACK (on_drag_data_received_desklet), pDesklet);
483
cairo_dock_disallow_widget_to_receive_data (pDesklet->container.pWidget);
486
else if (pDesklet->rotatingY)
488
pDesklet->rotatingY = FALSE;
489
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
490
G_TYPE_INT, "Desklet", "depth rotation y", (int) (pDesklet->fDepthRotationY / G_PI * 180.),
492
gtk_widget_queue_draw (pDesklet->container.pWidget);
494
else if (pDesklet->rotatingX)
496
pDesklet->rotatingX = FALSE;
497
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
498
G_TYPE_INT, "Desklet", "depth rotation x", (int) (pDesklet->fDepthRotationX / G_PI * 180.),
500
gtk_widget_queue_draw (pDesklet->container.pWidget);
504
Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
505
cairo_dock_notify (CAIRO_DOCK_CLICK_ICON, pClickedIcon, pDesklet, pButton->state);
508
else if (pButton->type == GDK_2BUTTON_PRESS)
510
if (! (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize) && ! (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize))
512
Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
513
cairo_dock_notify (CAIRO_DOCK_DOUBLE_CLICK_ICON, pClickedIcon, pDesklet);
517
else if (pButton->button == 3 && pButton->type == GDK_BUTTON_PRESS) // clique droit.
519
Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
520
GtkWidget *menu = cairo_dock_build_menu (pClickedIcon, CAIRO_CONTAINER (pDesklet)); // genere un CAIRO_DOCK_BUILD_ICON_MENU.
521
gtk_widget_show_all (menu);
522
gtk_menu_popup (GTK_MENU (menu),
528
gtk_get_current_event_time ());
529
pDesklet->container.bInside = FALSE;
530
///pDesklet->iGradationCount = 0; // on force le fond a redevenir transparent.
531
gtk_widget_queue_draw (pDesklet->container.pWidget);
533
else if (pButton->button == 2 && pButton->type == GDK_BUTTON_PRESS) // clique milieu.
535
if (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
537
pDesklet->fRotation = 0.;
538
gtk_widget_queue_draw (pDesklet->container.pWidget);
539
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
540
G_TYPE_INT, "Desklet", "rotation", 0,
543
else if (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize)
545
pDesklet->fDepthRotationY = 0.;
546
gtk_widget_queue_draw (pDesklet->container.pWidget);
547
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
548
G_TYPE_INT, "Desklet", "depth rotation y", 0,
551
else if (pButton->y > (pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDesklets.iDeskletButtonSize)/2 && pButton->x < myDesklets.iDeskletButtonSize)
553
pDesklet->fDepthRotationX = 0.;
554
gtk_widget_queue_draw (pDesklet->container.pWidget);
555
cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
556
G_TYPE_INT, "Desklet", "depth rotation x", 0,
561
cairo_dock_notify (CAIRO_DOCK_MIDDLE_CLICK_ICON, pDesklet->pIcon, pDesklet);
567
static void on_drag_data_received_desklet (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, CairoDesklet *pDesklet)
569
//g_print ("%s (%dx%d)\n", __func__, x, y);
571
//\_________________ On recupere l'URI.
572
gchar *cReceivedData = (gchar *) selection_data->data; // gtk_selection_data_get_text
573
g_return_if_fail (cReceivedData != NULL);
574
int length = strlen (cReceivedData);
575
if (cReceivedData[length-1] == '\n')
576
cReceivedData[--length] = '\0'; // on vire le retour chariot final.
577
if (cReceivedData[length-1] == '\r')
578
cReceivedData[--length] = '\0';
580
pDesklet->container.iMouseX = x;
581
pDesklet->container.iMouseY = y;
582
Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
583
cairo_dock_notify_drop_data (cReceivedData, pClickedIcon, 0, CAIRO_CONTAINER (pDesklet));
586
static gboolean on_motion_notify_desklet(GtkWidget *pWidget,
587
GdkEventMotion* pMotion,
588
CairoDesklet *pDesklet)
590
if (pMotion->state & GDK_BUTTON1_MASK && cairo_dock_desklet_is_free (pDesklet))
592
cd_debug ("root : %d;%d", (int) pMotion->x_root, (int) pMotion->y_root);
593
/*pDesklet->moving = TRUE;
594
gtk_window_move (GTK_WINDOW (pWidget),
595
pMotion->x_root + pDesklet->diff_x,
596
pMotion->y_root + pDesklet->diff_y);*/
598
else // le 'press-button' est local au sous-widget clique, alors que le 'motion-notify' est global a la fenetre; c'est donc par lui qu'on peut avoir a coup sur les coordonnees du curseur (juste avant le clic).
600
pDesklet->container.iMouseX = pMotion->x;
601
pDesklet->container.iMouseY = pMotion->y;
602
gboolean bStartAnimation = FALSE;
603
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_MOUSE_MOVED, pDesklet, &bStartAnimation);
605
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
608
if (pDesklet->rotating && cairo_dock_desklet_is_free (pDesklet))
610
double alpha = atan2 (pDesklet->container.iHeight, - pDesklet->container.iWidth);
611
pDesklet->fRotation = alpha - atan2 (.5*pDesklet->container.iHeight - pMotion->y, pMotion->x - .5*pDesklet->container.iWidth);
612
while (pDesklet->fRotation > G_PI)
613
pDesklet->fRotation -= 2 * G_PI;
614
while (pDesklet->fRotation <= - G_PI)
615
pDesklet->fRotation += 2 * G_PI;
616
gtk_widget_queue_draw(pDesklet->container.pWidget);
618
else if (pDesklet->rotatingY && cairo_dock_desklet_is_free (pDesklet))
620
pDesklet->fDepthRotationY = G_PI * (pMotion->x - .5*pDesklet->container.iWidth) / pDesklet->container.iWidth;
621
gtk_widget_queue_draw(pDesklet->container.pWidget);
623
else if (pDesklet->rotatingX && cairo_dock_desklet_is_free (pDesklet))
625
pDesklet->fDepthRotationX = G_PI * (pMotion->y - .5*pDesklet->container.iHeight) / pDesklet->container.iHeight;
626
gtk_widget_queue_draw(pDesklet->container.pWidget);
628
else if (pMotion->state & GDK_BUTTON1_MASK && cairo_dock_desklet_is_free (pDesklet) && ! pDesklet->moving)
630
gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (pWidget)),
631
1/*pButton->button*/,
632
pMotion->x_root/*pButton->x_root*/,
633
pMotion->y_root/*pButton->y_root*/,
634
pDesklet->time/*pButton->time*/);
635
pDesklet->moving = TRUE;
639
gboolean bStartAnimation = FALSE;
640
Icon *pIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
643
if (! pIcon->bPointed)
645
Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
646
if (pPointedIcon != NULL)
647
pPointedIcon->bPointed = FALSE;
648
pIcon->bPointed = TRUE;
650
//g_print ("on survole %s\n", pIcon->cName);
651
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_ICON, pIcon, pDesklet, &bStartAnimation);
656
Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
657
if (pPointedIcon != NULL)
659
pPointedIcon->bPointed = FALSE;
661
//g_print ("kedal\n");
662
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_ICON, pPointedIcon, pDesklet, &bStartAnimation);
668
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
672
gdk_device_get_state (pMotion->device, pMotion->window, NULL, NULL); // pour recevoir d'autres MotionNotify.
677
static gboolean on_focus_in_out_desklet(GtkWidget *widget,
678
GdkEventFocus *event,
679
CairoDesklet *pDesklet)
681
gtk_widget_queue_draw(pDesklet->container.pWidget);
685
static gboolean on_enter_desklet (GtkWidget* pWidget,
686
GdkEventCrossing* pEvent,
687
CairoDesklet *pDesklet)
689
//g_print ("%s (%d)\n", __func__, pDesklet->container.bInside);
690
if (! pDesklet->container.bInside) // avant on etait dehors, on redessine donc.
692
pDesklet->container.bInside = TRUE;
693
gtk_widget_queue_draw (pWidget); // redessin des boutons.
697
gboolean bStartAnimation = FALSE;
698
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_DESKLET, pDesklet, &bStartAnimation);
700
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
705
static gboolean on_leave_desklet (GtkWidget* pWidget,
706
GdkEventCrossing* pEvent,
707
CairoDesklet *pDesklet)
709
//g_print ("%s (%d)\n", __func__, pDesklet->container.bInside);
710
int iMouseX, iMouseY;
711
gdk_window_get_pointer (pWidget->window, &iMouseX, &iMouseY, NULL);
712
if (gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget)) != NULL && iMouseX > 0 && iMouseX < pDesklet->container.iWidth && iMouseY > 0 && iMouseY < pDesklet->container.iHeight) // en fait on est dans un widget fils, donc on ne fait rien.
717
pDesklet->container.bInside = FALSE;
718
gtk_widget_queue_draw (pWidget); // redessin des boutons.
720
gboolean bStartAnimation = FALSE;
721
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_LEAVE_DESKLET, pDesklet, &bStartAnimation);
723
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
733
static void _cairo_dock_set_icon_size (CairoContainer *pContainer, Icon *icon)
735
CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
736
/**if (pDesklet->pRenderer && pDesklet->pRenderer->set_icon_size)
737
pDesklet->pRenderer->set_icon_size (pDesklet, icon);*/
740
CairoDesklet *cairo_dock_new_desklet (void)
742
cd_message ("%s ()", __func__);
743
CairoDesklet *pDesklet = g_new0(CairoDesklet, 1);
744
pDesklet->container.iType = CAIRO_DOCK_TYPE_DESKLET;
745
pDesklet->container.bIsHorizontal = TRUE;
746
pDesklet->container.bDirectionUp = TRUE;
747
pDesklet->container.fRatio = 1;
748
pDesklet->container.fRatio = 1;
750
pDesklet->container.iface.set_icon_size = _cairo_dock_set_icon_size;
752
GtkWidget* pWindow = cairo_dock_init_container (CAIRO_CONTAINER (pDesklet));
754
gtk_window_set_title (GTK_WINDOW(pWindow), "cairo-dock-desklet");
755
gtk_widget_add_events( pWindow, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_FOCUS_CHANGE_MASK);
756
gtk_container_set_border_width(GTK_CONTAINER(pWindow), 2); // comme ca.
757
gtk_window_set_default_size(GTK_WINDOW(pWindow), 10, 10); // idem.
759
g_signal_connect (G_OBJECT (pWindow),
761
G_CALLBACK (on_expose_desklet),
763
g_signal_connect (G_OBJECT (pWindow),
765
G_CALLBACK (on_configure_desklet),
767
g_signal_connect (G_OBJECT (pWindow),
768
"motion-notify-event",
769
G_CALLBACK (on_motion_notify_desklet),
771
g_signal_connect (G_OBJECT (pWindow),
772
"button-press-event",
773
G_CALLBACK (on_button_press_desklet),
775
g_signal_connect (G_OBJECT (pWindow),
776
"button-release-event",
777
G_CALLBACK (on_button_press_desklet),
779
g_signal_connect (G_OBJECT (pWindow),
781
G_CALLBACK (on_focus_in_out_desklet),
783
g_signal_connect (G_OBJECT (pWindow),
785
G_CALLBACK (on_focus_in_out_desklet),
787
g_signal_connect (G_OBJECT (pWindow),
788
"enter-notify-event",
789
G_CALLBACK (on_enter_desklet),
791
g_signal_connect (G_OBJECT (pWindow),
792
"leave-notify-event",
793
G_CALLBACK (on_leave_desklet),
795
g_signal_connect (G_OBJECT (pWindow),
797
G_CALLBACK (on_unmap_desklet),
799
g_signal_connect (G_OBJECT (pWindow),
801
G_CALLBACK (on_scroll_desklet),
803
cairo_dock_allow_widget_to_receive_data (pWindow, G_CALLBACK (on_drag_data_received_desklet), pDesklet);
805
gtk_widget_show_all(pWindow);
810
void cairo_dock_free_desklet (CairoDesklet *pDesklet)
812
if (pDesklet == NULL)
815
if (pDesklet->iSidWriteSize != 0)
816
g_source_remove (pDesklet->iSidWriteSize);
817
if (pDesklet->iSidWritePosition != 0)
818
g_source_remove (pDesklet->iSidWritePosition);
819
cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_STOP_DESKLET, pDesklet);
821
cairo_dock_steal_interactive_widget_from_desklet (pDesklet);
823
cairo_dock_finish_container (CAIRO_CONTAINER (pDesklet));
825
if (pDesklet->pRenderer != NULL)
827
if (pDesklet->pRenderer->free_data != NULL)
829
pDesklet->pRenderer->free_data (pDesklet);
830
pDesklet->pRendererData = NULL;
834
if (pDesklet->icons != NULL)
836
g_list_foreach (pDesklet->icons, (GFunc) cairo_dock_free_icon, NULL);
837
g_list_free (pDesklet->icons);
840
g_free (pDesklet->cDecorationTheme);
841
cairo_dock_free_desklet_decoration (pDesklet->pUserDecoration);
843
cairo_dock_unload_image_buffer (&pDesklet->backGroundImageBuffer);
844
cairo_dock_unload_image_buffer (&pDesklet->foreGroundImageBuffer);
850
void cairo_dock_configure_desklet (CairoDesklet *pDesklet, CairoDeskletAttribute *pAttribute)
852
//g_print ("%s (%dx%d ; (%d,%d) ; %d)\n", __func__, pAttribute->iDeskletWidth, pAttribute->iDeskletHeight, pAttribute->iDeskletPositionX, pAttribute->iDeskletPositionY, pAttribute->iVisibility);
853
if (pAttribute->bDeskletUseSize && (pAttribute->iDeskletWidth != pDesklet->container.iWidth || pAttribute->iDeskletHeight != pDesklet->container.iHeight))
855
pDesklet->iDesiredWidth = pAttribute->iDeskletWidth;
856
pDesklet->iDesiredHeight = pAttribute->iDeskletHeight;
857
gdk_window_resize (pDesklet->container.pWidget->window,
858
pAttribute->iDeskletWidth,
859
pAttribute->iDeskletHeight);
861
if (! pAttribute->bDeskletUseSize)
863
gtk_container_set_border_width (GTK_CONTAINER (pDesklet->container.pWidget), 0);
864
gtk_window_set_resizable (GTK_WINDOW(pDesklet->container.pWidget), FALSE);
867
int iAbsolutePositionX = (pAttribute->iDeskletPositionX < 0 ? g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] + pAttribute->iDeskletPositionX : pAttribute->iDeskletPositionX);
868
iAbsolutePositionX = MAX (0, MIN (g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - pAttribute->iDeskletWidth, iAbsolutePositionX));
869
int iAbsolutePositionY = (pAttribute->iDeskletPositionY < 0 ? g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] + pAttribute->iDeskletPositionY : pAttribute->iDeskletPositionY);
870
iAbsolutePositionY = MAX (0, MIN (g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - pAttribute->iDeskletHeight, iAbsolutePositionY));
872
if (pAttribute->bOnAllDesktops)
873
gdk_window_move(pDesklet->container.pWidget->window,
876
//g_print (" let's place the deklet at (%d;%d)", iAbsolutePositionX, iAbsolutePositionY);
878
cairo_dock_set_desklet_accessibility (pDesklet, pAttribute->iVisibility, FALSE);
880
if (pAttribute->bOnAllDesktops)
882
gtk_window_stick (GTK_WINDOW (pDesklet->container.pWidget));
886
gtk_window_unstick (GTK_WINDOW (pDesklet->container.pWidget));
887
Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
888
if (g_desktopGeometry.iNbViewportX > 0 && g_desktopGeometry.iNbViewportY > 0)
890
int iNumDesktop, iNumViewportX, iNumViewportY;
891
iNumDesktop = pAttribute->iNumDesktop / (g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY);
892
int index2 = pAttribute->iNumDesktop % (g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY);
893
iNumViewportX = index2 / g_desktopGeometry.iNbViewportY;
894
iNumViewportY = index2 % g_desktopGeometry.iNbViewportY;
896
int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
897
cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
898
cd_debug (">>> on fixe le desklet sur le bureau (%d,%d,%d) (cur : %d,%d,%d)\n", iNumDesktop, iNumViewportX, iNumViewportY, iCurrentDesktop, iCurrentViewportX, iCurrentViewportY);
900
iNumViewportX -= iCurrentViewportX;
901
iNumViewportY -= iCurrentViewportY;
903
cd_debug ("on le place en %d + %d\n", iNumViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL], iAbsolutePositionX);
904
cairo_dock_move_xwindow_to_absolute_position (Xid, iNumDesktop, iNumViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] + iAbsolutePositionX, iNumViewportY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] + iAbsolutePositionY);
907
pDesklet->bPositionLocked = pAttribute->bPositionLocked;
908
pDesklet->bNoInput = pAttribute->bNoInput;
909
if (pDesklet->bNoInput)
910
cairo_dock_disallow_widget_to_receive_data (pDesklet->container.pWidget);
911
pDesklet->fRotation = pAttribute->iRotation / 180. * G_PI ;
912
pDesklet->fDepthRotationY = pAttribute->iDepthRotationY / 180. * G_PI ;
913
pDesklet->fDepthRotationX = pAttribute->iDepthRotationX / 180. * G_PI ;
915
g_free (pDesklet->cDecorationTheme);
916
pDesklet->cDecorationTheme = pAttribute->cDecorationTheme;
917
pAttribute->cDecorationTheme = NULL;
918
cairo_dock_free_desklet_decoration (pDesklet->pUserDecoration);
919
pDesklet->pUserDecoration = pAttribute->pUserDecoration;
920
pAttribute->pUserDecoration = NULL;
922
//cd_debug ("%s (%dx%d ; %d)", __func__, pDesklet->iDesiredWidth, pDesklet->iDesiredHeight, pDesklet->iSidWriteSize);
923
if (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0 && pDesklet->iSidWriteSize == 0)
925
cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDesklet));
926
cairo_dock_load_desklet_decorations (pDesklet);
927
cairo_destroy (pCairoContext);
931
void cairo_dock_load_desklet_decorations (CairoDesklet *pDesklet)
933
cairo_dock_unload_image_buffer (&pDesklet->backGroundImageBuffer);
934
cairo_dock_unload_image_buffer (&pDesklet->foreGroundImageBuffer);
936
CairoDeskletDecoration *pDeskletDecorations;
937
//cd_debug ("%s (%s)", __func__, pDesklet->cDecorationTheme);
938
if (pDesklet->cDecorationTheme == NULL || strcmp (pDesklet->cDecorationTheme, "personnal") == 0)
939
pDeskletDecorations = pDesklet->pUserDecoration;
940
else if (strcmp (pDesklet->cDecorationTheme, "default") == 0)
941
pDeskletDecorations = cairo_dock_get_desklet_decoration (myDesklets.cDeskletDecorationsName);
943
pDeskletDecorations = cairo_dock_get_desklet_decoration (pDesklet->cDecorationTheme);
944
if (pDeskletDecorations == NULL) // peut arriver si rendering n'a pas encore charge ses decorations.
946
//cd_debug ("pDeskletDecorations : %s (%x)", pDesklet->cDecorationTheme, pDeskletDecorations);
948
double fZoomX = 0., fZoomY = 0.;
949
if (pDeskletDecorations->cBackGroundImagePath != NULL && pDeskletDecorations->fBackGroundAlpha > 0)
951
//cd_debug ("bg : %s", pDeskletDecorations->cBackGroundImagePath);
952
cairo_dock_load_image_buffer_full (&pDesklet->backGroundImageBuffer,
953
pDeskletDecorations->cBackGroundImagePath,
954
pDesklet->container.iWidth,
955
pDesklet->container.iHeight,
956
pDeskletDecorations->iLoadingModifier,
957
pDeskletDecorations->fBackGroundAlpha);
958
fZoomX = pDesklet->backGroundImageBuffer.fZoomX;
959
fZoomY = pDesklet->backGroundImageBuffer.fZoomY;
961
if (pDeskletDecorations->cForeGroundImagePath != NULL && pDeskletDecorations->fForeGroundAlpha > 0)
963
//cd_debug ("fg : %s", pDeskletDecorations->cForeGroundImagePath);
964
cairo_dock_load_image_buffer_full (&pDesklet->foreGroundImageBuffer,
965
pDeskletDecorations->cForeGroundImagePath,
966
pDesklet->container.iWidth,
967
pDesklet->container.iHeight,
968
pDeskletDecorations->iLoadingModifier,
969
pDeskletDecorations->fForeGroundAlpha);
970
fZoomX = pDesklet->foreGroundImageBuffer.fZoomX;
971
fZoomY = pDesklet->foreGroundImageBuffer.fZoomY;
973
pDesklet->iLeftSurfaceOffset = pDeskletDecorations->iLeftMargin * fZoomX;
974
pDesklet->iTopSurfaceOffset = pDeskletDecorations->iTopMargin * fZoomY;
975
pDesklet->iRightSurfaceOffset = pDeskletDecorations->iRightMargin * fZoomX;
976
pDesklet->iBottomSurfaceOffset = pDeskletDecorations->iBottomMargin * fZoomY;
977
//g_print ("%d;%d;%d;%d ; %.2f;%.2f\n", pDesklet->iLeftSurfaceOffset, pDesklet->iTopSurfaceOffset, pDesklet->iRightSurfaceOffset, pDesklet->iBottomSurfaceOffset, fZoomX, fZoomY);
980
void cairo_dock_free_desklet_decoration (CairoDeskletDecoration *pDecoration)
982
if (pDecoration == NULL)
984
g_free (pDecoration->cBackGroundImagePath);
985
g_free (pDecoration->cForeGroundImagePath);
986
g_free (pDecoration);
993
void cairo_dock_add_interactive_widget_to_desklet_full (GtkWidget *pInteractiveWidget, CairoDesklet *pDesklet, int iRightMargin)
995
g_return_if_fail (pDesklet != NULL && pInteractiveWidget != NULL);
996
if (pDesklet->pInteractiveWidget != NULL || gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget)) != NULL)
998
cd_warning ("This desklet already has an interactive widget !");
1002
//gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pInteractiveWidget);
1003
GtkWidget *pHBox = gtk_hbox_new (FALSE, 0);
1004
gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pHBox);
1006
gtk_box_pack_start (GTK_BOX (pHBox), pInteractiveWidget, TRUE, TRUE, 0);
1007
pDesklet->pInteractiveWidget = pInteractiveWidget;
1009
if (iRightMargin != 0)
1011
GtkWidget *pMarginBox = gtk_vbox_new (FALSE, 0);
1012
gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
1013
gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0); // a tester ...
1016
gtk_widget_show_all (pHBox);
1019
void cairo_dock_set_desklet_margin (CairoDesklet *pDesklet, int iRightMargin)
1021
g_return_if_fail (pDesklet != NULL && pDesklet->pInteractiveWidget != NULL);
1023
GtkWidget *pHBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
1024
if (pHBox && pHBox != pDesklet->pInteractiveWidget) // precaution.
1026
GList *pChildList = gtk_container_get_children (GTK_CONTAINER (pHBox));
1027
if (pChildList != NULL)
1029
if (pChildList->next != NULL)
1031
GtkWidget *pMarginBox = GTK_WIDGET (pChildList->next->data);
1032
gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
1034
else // on rajoute le widget de la marge.
1036
GtkWidget *pMarginBox = gtk_vbox_new (FALSE, 0);
1037
gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
1038
gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0);
1040
g_list_free (pChildList);
1045
GtkWidget *cairo_dock_steal_interactive_widget_from_desklet (CairoDesklet *pDesklet)
1047
if (pDesklet == NULL)
1050
GtkWidget *pInteractiveWidget = pDesklet->pInteractiveWidget;
1051
if (pInteractiveWidget != NULL)
1053
pInteractiveWidget = cairo_dock_steal_widget_from_its_container (pInteractiveWidget);
1054
pDesklet->pInteractiveWidget = NULL;
1055
GtkWidget *pBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
1057
gtk_widget_destroy (pBox);
1059
return pInteractiveWidget;
1064
void cairo_dock_hide_desklet (CairoDesklet *pDesklet)
1068
pDesklet->bAllowMinimize = TRUE;
1069
gtk_widget_hide (pDesklet->container.pWidget);
1073
void cairo_dock_show_desklet (CairoDesklet *pDesklet)
1077
gtk_window_present(GTK_WINDOW(pDesklet->container.pWidget));
1078
gtk_window_move (GTK_WINDOW(pDesklet->container.pWidget), pDesklet->container.iWindowPositionX, pDesklet->container.iWindowPositionY); // sinon le WM le place n'importe ou.
1082
void cairo_dock_zoom_out_desklet (CairoDesklet *pDesklet)
1084
g_return_if_fail (pDesklet != NULL);
1085
pDesklet->container.fRatio = 0.1;
1086
pDesklet->bGrowingUp = TRUE;
1087
cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
1090
static void _cairo_dock_reserve_space_for_desklet (CairoDesklet *pDesklet, gboolean bReserve)
1092
cd_debug ("%s (%d)\n", __func__, bReserve);
1093
Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
1094
int left=0, right=0, top=0, bottom=0;
1095
int left_start_y=0, left_end_y=0, right_start_y=0, right_end_y=0, top_start_x=0, top_end_x=0, bottom_start_x=0, bottom_end_x=0;
1096
int iHeight = pDesklet->container.iHeight, iWidth = pDesklet->container.iWidth;
1097
int iX = pDesklet->container.iWindowPositionX, iY = pDesklet->container.iWindowPositionY;
1100
int iTopOffset, iBottomOffset, iRightOffset, iLeftOffset;
1102
iBottomOffset = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - 1 - (iY + iHeight);
1104
iRightOffset = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - 1 - (iX + iWidth);
1106
if (iBottomOffset < MIN (iLeftOffset, iRightOffset)) // en bas.
1108
bottom = iHeight + iBottomOffset;
1109
bottom_start_x = iX;
1110
bottom_end_x = iX + iWidth;
1112
else if (iTopOffset < MIN (iLeftOffset, iRightOffset)) // en haut.
1114
top = iHeight + iTopOffset;
1116
top_end_x = iX + iWidth;
1118
else if (iLeftOffset < iRightOffset) // a gauche.
1120
left = iWidth + iLeftOffset;
1122
left_end_y = iY + iHeight;
1126
right = iWidth + iRightOffset;
1128
right_end_y = iY + iHeight;
1131
//cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_DOCK");
1132
cairo_dock_set_strut_partial (Xid, left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x);
1133
pDesklet->bSpaceReserved = bReserve;
1136
//for compiz fusion "widget layer"
1137
//set behaviour in compiz to: (class=Cairo-dock & type=utility)
1138
void cairo_dock_set_desklet_accessibility (CairoDesklet *pDesklet, CairoDeskletVisibility iVisibility, gboolean bSaveState)
1140
//g_print ("%s (%d)\n", __func__, iVisibility);
1142
//\_________________ On applique la nouvelle accessibilite.
1143
gtk_window_set_keep_below (GTK_WINDOW (pDesklet->container.pWidget), iVisibility == CAIRO_DESKLET_KEEP_BELOW);
1144
gtk_window_set_keep_above (GTK_WINDOW (pDesklet->container.pWidget), iVisibility == CAIRO_DESKLET_KEEP_ABOVE);
1146
Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
1147
if (iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
1148
cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_UTILITY"); // le hide-show le fait deconner completement, il perd son skip_task_bar ! au moins sous KDE3.
1150
cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_NORMAL");
1152
if (iVisibility == CAIRO_DESKLET_RESERVE_SPACE)
1154
if (! pDesklet->bSpaceReserved)
1155
_cairo_dock_reserve_space_for_desklet (pDesklet, TRUE); // sinon inutile de le refaire, s'il y'a un changement de taille ce sera fait lors du configure-event.
1157
else if (pDesklet->bSpaceReserved)
1159
_cairo_dock_reserve_space_for_desklet (pDesklet, FALSE);
1162
//\_________________ On enregistre le nouvel etat.
1163
Icon *icon = pDesklet->pIcon;
1164
if (bSaveState && CAIRO_DOCK_IS_APPLET (icon))
1165
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
1166
G_TYPE_INT, "Desklet", "accessibility", iVisibility,
1169
//\_________________ On verifie que la regle de Compiz est correcte.
1170
if (iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER && bSaveState)
1172
// pour activer le plug-in, recuperer la liste, y rajouter widget-layer, puis envoyer :
1173
//dbus-send --print-reply --type=method_call --dest=org.freedesktop.compiz /org/freedesktop/compiz/core/allscreens/active_plugins org.freedesktop.compiz.get
1174
// dbus-send --print-reply --type=method_call --dest=org.freedesktop.compiz /org/freedesktop/compiz/core/allscreens/active_plugins org.freedesktop.compiz.set array:string:"foo",string:"fum"
1176
// on recupere la regle
1177
gchar *cDbusAnswer = cairo_dock_launch_command_sync ("dbus-send --print-reply --type=method_call --dest=org.freedesktop.compiz /org/freedesktop/compiz/widget/screen0/match org.freedesktop.compiz.get");
1178
cd_debug ("cDbusAnswer : '%s'", cDbusAnswer);
1179
gchar *cRule = NULL;
1180
gchar *str = (cDbusAnswer ? strchr (cDbusAnswer, '\n') : NULL);
1186
if (strncmp (str, "string", 6) == 0)
1194
gchar *ptr = strrchr (str, '"');
1198
cRule = g_strdup (str);
1203
g_free (cDbusAnswer);
1204
cd_debug ("got rule : '%s'", cRule);
1206
if (cRule == NULL) /// on ne sait pas le distinguer d'une regle vide...
1208
cd_warning ("couldn't get Widget Layer rule from Compiz");
1211
// on complete la regle si necessaire.
1212
if (cRule == NULL || *cRule == '\0' || (g_strstr_len (cRule, -1, "class=Cairo-dock & type=utility") == NULL && g_strstr_len (cRule, -1, "(class=Cairo-dock) & (type=utility)") == NULL && g_strstr_len (cRule, -1, "name=cairo-dock & type=utility") == NULL))
1214
gchar *cNewRule = (cRule == NULL || *cRule == '\0' ?
1215
g_strdup ("(class=Cairo-dock & type=utility)") :
1216
g_strdup_printf ("(%s) | (class=Cairo-dock & type=utility)", cRule));
1217
cd_debug ("set rule : %s", cNewRule);
1218
gchar *cCommand = g_strdup_printf ("dbus-send --print-reply --type=method_call --dest=org.freedesktop.compiz /org/freedesktop/compiz/widget/screen0/match org.freedesktop.compiz.set string:\"%s\"", cNewRule);
1219
cairo_dock_launch_command_sync (cCommand);
1227
void cairo_dock_set_desklet_sticky (CairoDesklet *pDesklet, gboolean bSticky)
1229
//g_print ("%s (%d)\n", __func__, bSticky);
1233
gtk_window_stick (GTK_WINDOW (pDesklet->container.pWidget));
1238
gtk_window_unstick (GTK_WINDOW (pDesklet->container.pWidget));
1239
int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
1240
cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
1241
iNumDesktop = iCurrentDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportY;
1242
cd_debug (">>> on colle ce desklet sur le bureau %d", iNumDesktop);
1245
//\_________________ On enregistre le nouvel etat.
1246
Icon *icon = pDesklet->pIcon;
1247
if (CAIRO_DOCK_IS_APPLET (icon))
1248
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
1249
G_TYPE_BOOLEAN, "Desklet", "sticky", bSticky,
1250
G_TYPE_INT, "Desklet", "num desktop", iNumDesktop,
1254
void cairo_dock_lock_desklet_position (CairoDesklet *pDesklet, gboolean bPositionLocked)
1256
//g_print ("%s (%d)\n", __func__, bPositionLocked);
1257
pDesklet->bPositionLocked = bPositionLocked;
1259
//\_________________ On enregistre le nouvel etat.
1260
Icon *icon = pDesklet->pIcon;
1261
if (CAIRO_DOCK_IS_APPLET (icon))
1262
cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
1263
G_TYPE_BOOLEAN, "Desklet", "locked", pDesklet->bPositionLocked,
1268
void cairo_dock_update_desklet_icons (CairoDesklet *pDesklet)
1270
// compute icons size
1271
if (pDesklet->pRenderer && pDesklet->pRenderer->calculate_icons != NULL)
1272
pDesklet->pRenderer->calculate_icons (pDesklet);
1274
// trigger load if changed
1275
Icon* pIcon = pDesklet->pIcon;
1277
cairo_dock_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet));
1280
for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
1283
if ((int)pIcon->fWidth != pIcon->iImageWidth || (int)pIcon->fHeight != pIcon->iImageHeight)
1285
pIcon->iImageWidth = pIcon->fWidth;
1286
pIcon->iImageHeight = pIcon->fHeight;
1287
cairo_dock_trigger_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet));
1292
cairo_dock_redraw_container (CAIRO_CONTAINER (pDesklet));
1295
void cairo_dock_insert_icon_in_desklet (Icon *icon, CairoDesklet *pDesklet)
1297
g_return_if_fail (icon != NULL);
1298
if (g_list_find (pDesklet->icons, icon) != NULL) // elle est deja dans ce desklet.
1302
pDesklet->icons = g_list_insert_sorted (pDesklet->icons,
1304
(GCompareFunc)cairo_dock_compare_icons_order);
1305
icon->pContainerForLoad = CAIRO_CONTAINER (pDesklet);
1308
cairo_dock_update_desklet_icons (pDesklet);
1311
gboolean cairo_dock_detach_icon_from_desklet (Icon *icon, CairoDesklet *pDesklet)
1313
if (pDesklet == NULL)
1316
GList *ic = g_list_find (pDesklet->icons, icon);
1321
pDesklet->icons = g_list_delete_link (pDesklet->icons, ic);
1323
icon->pContainerForLoad = NULL;
1326
cairo_dock_update_desklet_icons (pDesklet);