~ubuntu-branches/ubuntu/oneiric/cairo-dock/oneiric-201106091216

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe), Matthieu Baerts (matttbe), Didier Roche
  • Date: 2010-03-01 21:24:00 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100301212400-3a3csog6eonse3in
Tags: 2.1.3-6-0ubuntu1
[ Matthieu Baerts (matttbe) ]
* New Upstream Version. (LP: #521534)
* Updated debian/watch and debian/copyright with LP account.
* Removed debian/patches/02-merge-changelog.patch'
 - data/ChangeLog.txt has to respect a syntax and is used by CD.
* debian/cairo-dock.1:
 - Updated with the latest release.
 - The domain name 'cairo-dock.org' has changed to 'glx-dock.org'
* debian/control:
 - Changed the homepage and other links (glx-dock.org)
 - Updated cairo-dock-dev architecture to 'all' (it no longer contains compiled files)
* debian/cairo-dock-dev.install
 - libcairo-dock.a and libcairo-dock.so no longer exist
* debian/rules
 - removed uneeded changelog file
* Updated debian/patches/01-desktop-file-category.patch

[ Didier Roche ]
* Fix debian/watch
* Fix some issue in versionning
* debian/control: clean the packaging and add right -plugins depends

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "cairo-dock-load.h"
35
35
#include "cairo-dock-icons.h"
36
36
#include "cairo-dock-draw.h"
 
37
#include "cairo-dock-draw-opengl.h"
37
38
#include "cairo-dock-dock-factory.h"
38
39
#include "cairo-dock-dialogs.h"
39
40
#include "cairo-dock-animations.h"
43
44
#include "cairo-dock-dock-manager.h"
44
45
#include "cairo-dock-class-manager.h"
45
46
#include "cairo-dock-X-utilities.h"
46
 
#include "cairo-dock-internal-system.h"
47
47
#include "cairo-dock-internal-taskbar.h"
48
 
#include "cairo-dock-internal-labels.h"
49
48
#include "cairo-dock-internal-icons.h"
50
49
#include "cairo-dock-notifications.h"
51
50
#include "cairo-dock-launcher-factory.h"
53
52
#include "cairo-dock-dock-factory.h"
54
53
#include "cairo-dock-dock-facility.h"
55
54
#include "cairo-dock-callbacks.h"
 
55
#include "cairo-dock-application-facility.h"
56
56
#include "cairo-dock-application-factory.h"
57
57
 
58
58
extern CairoDock *g_pMainDock;
59
59
 
60
 
static GHashTable *s_hAppliTable = NULL;  // table des PID connus de cairo-dock (affichees ou non dans le dock).
61
60
static Display *s_XDisplay = NULL;
62
61
static Atom s_aNetWmIcon;
63
62
static Atom s_aNetWmState;
64
63
static Atom s_aNetWmSkipPager;
65
64
static Atom s_aNetWmSkipTaskbar;
66
 
///static Atom s_aNetWmPid;
67
65
static Atom s_aNetWmWindowType;
68
66
static Atom s_aNetWmWindowTypeNormal;
69
67
static Atom s_aNetWmWindowTypeDialog;
70
 
static Atom s_aNetWmName;
71
 
static Atom s_aUtf8String;
72
 
static Atom s_aWmName;
73
 
static Atom s_aString;
74
68
static Atom s_aWmHints;
75
69
static Atom s_aNetWmHidden;
76
70
static Atom s_aNetWmFullScreen;
84
78
        s_XDisplay = pXDisplay;
85
79
        g_return_if_fail (s_XDisplay != NULL);
86
80
 
87
 
        s_hAppliTable = g_hash_table_new_full (g_int_hash,
88
 
                g_int_equal,
89
 
                g_free,
90
 
                NULL);
91
 
        
92
81
        s_aNetWmIcon = XInternAtom (s_XDisplay, "_NET_WM_ICON", False);
93
82
 
94
83
        s_aNetWmState = XInternAtom (s_XDisplay, "_NET_WM_STATE", False);
96
85
        s_aNetWmSkipTaskbar = XInternAtom (s_XDisplay, "_NET_WM_STATE_SKIP_TASKBAR", False);
97
86
        s_aNetWmHidden = XInternAtom (s_XDisplay, "_NET_WM_STATE_HIDDEN", False);
98
87
 
99
 
        ///s_aNetWmPid = XInternAtom (s_XDisplay, "_NET_WM_PID", False);
100
 
 
101
88
        s_aNetWmWindowType = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE", False);
102
89
        s_aNetWmWindowTypeNormal = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False);
103
90
        s_aNetWmWindowTypeDialog = XInternAtom (s_XDisplay, "_NET_WM_WINDOW_TYPE_DIALOG", False);
104
91
        
105
 
        s_aNetWmName = XInternAtom (s_XDisplay, "_NET_WM_NAME", False);
106
 
        s_aUtf8String = XInternAtom (s_XDisplay, "UTF8_STRING", False);
107
 
        s_aWmName = XInternAtom (s_XDisplay, "WM_NAME", False);
108
 
        s_aString = XInternAtom (s_XDisplay, "STRING", False);
109
 
 
110
92
        s_aWmHints = XInternAtom (s_XDisplay, "WM_HINTS", False);
111
93
        
112
94
        s_aNetWmFullScreen = XInternAtom (s_XDisplay, "_NET_WM_STATE_FULLSCREEN", False);
115
97
        s_aNetWmDemandsAttention = XInternAtom (s_XDisplay, "_NET_WM_STATE_DEMANDS_ATTENTION", False);
116
98
}
117
99
 
118
 
void cairo_dock_unregister_pid (Icon *icon)
119
 
{
120
 
        /**if (myTaskBar.bUniquePid && CAIRO_DOCK_IS_APPLI (icon) && icon->iPid != 0)
121
 
        {
122
 
                g_hash_table_remove (s_hAppliTable, &icon->iPid);
123
 
        }*/
124
 
}
125
 
 
126
100
cairo_surface_t *cairo_dock_create_surface_from_xpixmap (Pixmap Xid, cairo_t *pSourceContext, double fMaxScale, double *fWidth, double *fHeight)
127
101
{
128
102
        g_return_val_if_fail (cairo_status (pSourceContext) == CAIRO_STATUS_SUCCESS && Xid > 0, NULL);
129
103
        GdkPixbuf *pPixbuf = cairo_dock_get_pixbuf_from_pixmap (Xid, TRUE);
130
104
        if (pPixbuf == NULL)
131
105
        {
132
 
                cd_warning ("Can't have thumbnail for a window that is minimized when the dock is launched.");
 
106
                cd_warning ("No thumbnail available.\nEither the WM doesn't support this functionnality, or the window was minimized when the dock has been launched.");
133
107
                return NULL;
134
108
        }
135
109
        cd_debug ("window pixmap : %dx%d", gdk_pixbuf_get_width (pPixbuf), gdk_pixbuf_get_height (pPixbuf));
158
132
 
159
133
        if (iBufferNbElements > 2)
160
134
        {
161
 
                cairo_surface_t *pNewSurface = cairo_dock_create_surface_from_xicon_buffer (pXIconBuffer, iBufferNbElements, pSourceContext, fMaxScale, fWidth, fHeight);
 
135
                cairo_surface_t *pNewSurface = cairo_dock_create_surface_from_xicon_buffer (pXIconBuffer,
 
136
                        iBufferNbElements,
 
137
                        pSourceContext,
 
138
                        myIcons.tIconAuthorizedWidth[CAIRO_DOCK_APPLI],
 
139
                        myIcons.tIconAuthorizedHeight[CAIRO_DOCK_APPLI],
 
140
                        fMaxScale,
 
141
                        fWidth, fHeight);
162
142
                XFree (pXIconBuffer);
163
143
                return pNewSurface;
164
144
        }
241
221
}
242
222
 
243
223
 
244
 
CairoDock *cairo_dock_manage_appli_class (Icon *icon, CairoDock *pMainDock)
245
 
{
246
 
        cd_message ("%s (%s)", __func__, icon->cName);
247
 
        CairoDock *pParentDock = pMainDock;
248
 
        g_free (icon->cParentDockName);
249
 
        if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.bGroupAppliByClass && icon->cClass != NULL && ! cairo_dock_class_is_expanded (icon->cClass))
250
 
        {
251
 
                Icon *pSameClassIcon = cairo_dock_get_classmate (icon);  // un inhibiteur dans un dock OU une appli de meme classe dans le main dock.
252
 
                if (pSameClassIcon == NULL)  // aucun classmate => elle va dans le main dock.
253
 
                {
254
 
                        cd_message ("  classe %s encore vide", icon->cClass);
255
 
                        pParentDock = cairo_dock_search_dock_from_name (icon->cClass);
256
 
                        if (pParentDock == NULL)
257
 
                        {
258
 
                                pParentDock = pMainDock;
259
 
                                icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
260
 
                        }
261
 
                        else
262
 
                        {
263
 
                                icon->cParentDockName = g_strdup (icon->cClass);
264
 
                        }
265
 
                }
266
 
                else  // on la met dans le sous-dock de sa classe.
267
 
                {
268
 
                        icon->cParentDockName = g_strdup (icon->cClass);
269
 
 
270
 
                        //\____________ On cree ce sous-dock si necessaire.
271
 
                        pParentDock = cairo_dock_search_dock_from_name (icon->cClass);
272
 
                        if (pParentDock == NULL)  // alors il faut creer le sous-dock, qu'on associera soit a pSameClassIcon soit a un fake.
273
 
                        {
274
 
                                cd_message ("  creation du dock pour la classe %s", icon->cClass);
275
 
                                pParentDock = cairo_dock_create_subdock_from_scratch (NULL, icon->cClass, pMainDock);
276
 
                        }
277
 
                        else
278
 
                                cd_message ("  sous-dock de la classe %s existant", icon->cClass);
279
 
                        
280
 
                        if (CAIRO_DOCK_IS_LAUNCHER (pSameClassIcon) || CAIRO_DOCK_IS_APPLET (pSameClassIcon))  // c'est un inhibiteur.
281
 
                        {
282
 
                                if (pSameClassIcon->Xid != 0)  // actuellement l'inhibiteur inhibe 1 seule appli.
283
 
                                {
284
 
                                        cd_debug ("actuellement l'inhibiteur inhibe 1 seule appli");
285
 
                                        Icon *pInhibatedIcon = cairo_dock_get_icon_with_Xid (pSameClassIcon->Xid);
286
 
                                        pSameClassIcon->Xid = 0;  // on lui laisse par contre l'indicateur.
287
 
                                        if (pSameClassIcon->pSubDock == NULL)
288
 
                                        {
289
 
                                                if (pSameClassIcon->cInitialName != NULL)
290
 
                                                {
291
 
                                                        CairoDock *pSameClassDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
292
 
                                                        if (pSameClassDock != NULL)
293
 
                                                        {
294
 
                                                                cairo_t *pCairoContext = cairo_dock_create_context_from_window (CAIRO_CONTAINER (pSameClassDock));
295
 
                                                                cairo_dock_set_icon_name (pCairoContext, pSameClassIcon->cInitialName, pSameClassIcon, CAIRO_CONTAINER (pSameClassDock));  // on lui remet son nom de lanceur.
296
 
                                                                cairo_destroy (pCairoContext);
297
 
                                                        }
298
 
                                                }
299
 
                                                pSameClassIcon->pSubDock = pParentDock;
300
 
                                                CairoDock *pRootDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
301
 
                                                if (pRootDock != NULL)
302
 
                                                        cairo_dock_redraw_icon (pSameClassIcon, CAIRO_CONTAINER (pRootDock));  // on la redessine car elle prend l'indicateur de classe.
303
 
                                        }
304
 
                                        else if (pSameClassIcon->pSubDock != pParentDock)
305
 
                                                cd_warning ("this launcher (%s) already has a subdock, but it's not the class's subdock !", pSameClassIcon->cName);
306
 
                                        if (pInhibatedIcon != NULL)
307
 
                                        {
308
 
                                                cd_debug (" on insere %s dans le dock de la classe", pInhibatedIcon->cName);
309
 
                                                g_free (pInhibatedIcon->cParentDockName);
310
 
                                                pInhibatedIcon->cParentDockName = g_strdup (icon->cClass);
311
 
                                                cairo_dock_insert_icon_in_dock_full (pInhibatedIcon, pParentDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, ! CAIRO_DOCK_INSERT_SEPARATOR, NULL);
312
 
                                        }
313
 
                                }
314
 
                                else if (pSameClassIcon->pSubDock != pParentDock)
315
 
                                        cd_warning ("this inhibator doesn't hold the class dock !");
316
 
                        }
317
 
                        else  // c'est donc une appli du main dock.
318
 
                        {
319
 
                                //\______________ On cree une icone de paille.
320
 
                                cd_debug (" on cree un fake...");
321
 
                                CairoDock *pClassMateParentDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);  // c'est en fait le main dock.
322
 
                                Icon *pFakeClassIcon = g_new0 (Icon, 1);
323
 
                                pFakeClassIcon->cName = g_strdup (pSameClassIcon->cClass);
324
 
                                pFakeClassIcon->cClass = g_strdup (pSameClassIcon->cClass);
325
 
                                pFakeClassIcon->iType = pSameClassIcon->iType;
326
 
                                pFakeClassIcon->fOrder = pSameClassIcon->fOrder;
327
 
                                pFakeClassIcon->cParentDockName = g_strdup (pSameClassIcon->cParentDockName);
328
 
                                pFakeClassIcon->fWidth = pSameClassIcon->fWidth / pClassMateParentDock->container.fRatio;
329
 
                                pFakeClassIcon->fHeight = pSameClassIcon->fHeight / pClassMateParentDock->container.fRatio;
330
 
                                pFakeClassIcon->fXMax = pSameClassIcon->fXMax;
331
 
                                pFakeClassIcon->fXMin = pSameClassIcon->fXMin;
332
 
                                pFakeClassIcon->fXAtRest = pSameClassIcon->fXAtRest;
333
 
                                pFakeClassIcon->pSubDock = pParentDock;  // grace a cela ce sera un lanceur.
334
 
                                
335
 
                                //\______________ On la charge.
336
 
                                cairo_dock_load_one_icon_from_scratch (pFakeClassIcon, CAIRO_CONTAINER (pClassMateParentDock));
337
 
                                
338
 
                                //\______________ On detache le classmate, on le place dans le sous-dock, et on lui substitue le faux.
339
 
                                cd_debug (" on detache %s pour la passer dans le sous-dock de sa classe", pSameClassIcon->cName);
340
 
                                cairo_dock_detach_icon_from_dock (pSameClassIcon, pClassMateParentDock, FALSE);
341
 
                                g_free (pSameClassIcon->cParentDockName);
342
 
                                pSameClassIcon->cParentDockName = g_strdup (pSameClassIcon->cClass);
343
 
                                cairo_dock_insert_icon_in_dock_full (pSameClassIcon, pParentDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, ! CAIRO_DOCK_INSERT_SEPARATOR, NULL);
344
 
                                
345
 
                                cd_debug (" on lui substitue le fake");
346
 
                                cairo_dock_insert_icon_in_dock_full (pFakeClassIcon, pClassMateParentDock,  CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON, ! CAIRO_DOCK_INSERT_SEPARATOR, NULL);
347
 
                                cairo_dock_calculate_dock_icons (pClassMateParentDock);
348
 
                                cairo_dock_redraw_icon (pFakeClassIcon, CAIRO_CONTAINER (pClassMateParentDock));
349
 
                        }
350
 
                }
351
 
        }
352
 
        else
353
 
                icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
354
 
 
355
 
        return pParentDock;
356
 
}
357
 
 
358
224
static Window _cairo_dock_get_parent_window (Window Xid)
359
225
{
360
226
        Atom aReturnedType = 0;
408
274
                //g_print (" -------- bSkip : %d\n",  bSkip);
409
275
                XFree (pXStateBuffer);
410
276
        }
411
 
        //else
412
 
        //      cd_message ("pas d'etat defini, donc on continue\n");
413
277
        if (bSkip)
414
278
        {
415
279
                cd_debug ("  cette fenetre est timide");
416
280
                return NULL;
417
281
        }
418
282
 
419
 
        //\__________________ On recupere son PID si on est en mode "PID unique".
420
 
        /**if (myTaskBar.bUniquePid)
421
 
        {
422
 
                iBufferNbElements = 0;
423
 
                XGetWindowProperty (s_XDisplay, Xid, s_aNetWmPid, 0, G_MAXULONG, False, XA_CARDINAL, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, (guchar **)&pPidBuffer);
424
 
                if (iBufferNbElements > 0)
425
 
                {
426
 
                        //g_print (" +++ PID %d\n", *pPidBuffer);
427
 
 
428
 
                        Icon *pIcon = g_hash_table_lookup (s_hAppliTable, pPidBuffer);
429
 
                        if (pIcon != NULL)  // si c'est une fenetre d'une appli deja referencee, on ne rajoute pas d'icones.
430
 
                        {
431
 
                                XFree (pPidBuffer);
432
 
                                return NULL;
433
 
                        }
434
 
                }
435
 
                else
436
 
                {
437
 
                        //g_print ("pas de PID defini -> elle degage\n");
438
 
                        return NULL;
439
 
                }
440
 
        }*/
441
 
 
442
283
        //\__________________ On regarde son type.
443
284
        gulong *pTypeBuffer = NULL;
444
285
        cd_debug (" + nouvelle icone d'appli (%d)", Xid);
455
296
                                Window XMainAppliWindow = _cairo_dock_get_parent_window (Xid);
456
297
                                if (XMainAppliWindow != 0)
457
298
                                {
458
 
                                        cd_debug ("  dialogue 'transient for' => on ignore");
 
299
                                        cd_debug ("  dialogue 'transient for %d' => on ignore", XMainAppliWindow);
459
300
                                        if (bDemandsAttention && (myTaskBar.bDemandsAttentionWithDialog || myTaskBar.cAnimationOnDemandsAttention))
460
301
                                        {
461
302
                                                Icon *pParentIcon = cairo_dock_get_icon_with_Xid (XMainAppliWindow);
474
315
                        }
475
316
                        else
476
317
                        {
477
 
                                cd_debug ("type indesirable");
 
318
                                cd_debug ("type indesirable (%d)", *pTypeBuffer);
478
319
                                XFree (pTypeBuffer);
479
 
                                /**if (myTaskBar.bUniquePid)
480
 
                                        g_hash_table_insert (s_hAppliTable, pPidBuffer, NULL);  // On rajoute son PID meme si c'est une appli qu'on n'affichera pas.*/
481
320
                                return NULL;
482
321
                        }
483
322
                }
503
342
                        }
504
343
                        return NULL;  // meme remarque.
505
344
                }
506
 
                //else
507
 
                //      cd_message (" pas de type defini -> on suppose que son type est 'normal'\n");
508
345
        }
509
346
        
510
347
        
511
348
        //\__________________ On recupere son nom.
512
 
        XGetWindowProperty (s_XDisplay, Xid, s_aNetWmName, 0, G_MAXULONG, False, s_aUtf8String, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
513
 
        if (iBufferNbElements == 0)
514
 
        {
515
 
                XGetWindowProperty (s_XDisplay, Xid, s_aWmName, 0, G_MAXULONG, False, s_aString, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
516
 
        }
517
 
        if (iBufferNbElements == 0)
518
 
        {
519
 
                cd_debug ("pas de nom, on en mettra un par defaut.");
520
 
                
521
 
                //return NULL;
522
 
        }
523
 
        cd_debug ("recuperation de '%s' (bIsHidden : %d)", pNameBuffer, bIsHidden);
 
349
        gchar *cName = cairo_dock_get_xwindow_name (Xid, TRUE);
 
350
        cd_debug ("recuperation de '%s' (bIsHidden : %d)", cName, bIsHidden);
524
351
        
525
352
        
526
353
        //\__________________ On recupere la classe.
529
356
        if (XGetClassHint (s_XDisplay, Xid, pClassHint) != 0)
530
357
        {
531
358
                cd_debug ("  res_name : %s(%x); res_class : %s(%x)", pClassHint->res_name, pClassHint->res_name, pClassHint->res_class, pClassHint->res_class);
532
 
                cClass = g_ascii_strdown (pClassHint->res_class, -1);  // on la passe en minuscule, car certaines applis ont la bonne idee de donner des classes avec une majuscule ou non suivant les fenetres. Il reste le cas des applis telles que Glade2 ('Glade' et 'Glade-2' ...)
 
359
                if (pClassHint->res_class && strcmp (pClassHint->res_class, "Wine") == 0 && pClassHint->res_name && g_str_has_suffix (pClassHint->res_name, ".exe"))
 
360
                {
 
361
                        cd_debug ("  wine application detected, changing the class '%s' to '%s'", pClassHint->res_class, pClassHint->res_name);
 
362
                        cClass = g_ascii_strdown (pClassHint->res_name, -1);
 
363
                }
 
364
                else if (*pClassHint->res_class == '/' && g_str_has_suffix (pClassHint->res_class, ".exe"))  // cas des applications Mono telles que tomboy ...
 
365
                {
 
366
                        gchar *str = strrchr (pClassHint->res_class, '/');
 
367
                        if (str)
 
368
                                str ++;
 
369
                        else
 
370
                                str = pClassHint->res_class;
 
371
                        cClass = g_ascii_strdown (str, -1);
 
372
                        cClass[strlen (cClass) - 4] = '\0';
 
373
                }
 
374
                else
 
375
                        cClass = g_ascii_strdown (pClassHint->res_class, -1);  // on la passe en minuscule, car certaines applis ont la bonne idee de donner des classes avec une majuscule ou non suivant les fenetres.
 
376
                
 
377
                cairo_dock_remove_version_from_string (cClass);  // on enleve les numeros de version (Openoffice.org-3.1)
 
378
                
533
379
                XFree (pClassHint->res_name);
534
380
                XFree (pClassHint->res_class);
535
 
                //g_print (".\n");
536
381
        }
537
382
        else
538
383
        {
540
385
        }
541
386
        XFree (pClassHint);
542
387
        
543
 
        /*const XklEngine *eng = xkl_engine_get_instance (cairo_dock_get_Xdisplay ());
544
 
        XklState state;
545
 
        xkl_engine_get_state (eng, Xid, &state);
546
 
        const gchar **names = xkl_engine_get_group_names (eng);
547
 
        int n = xkl_engine_get_num_groups (eng);
548
 
        for (i=0; i<n; i++)
549
 
                g_print ("name %d : %s\n", i, names[i]);*/
550
388
        
551
389
        //\__________________ On cree, on remplit l'icone, et on l'enregistre, par contre elle sera inseree plus tard.
552
390
        Icon *icon = g_new0 (Icon, 1);
553
 
        icon->cName = (pNameBuffer ? g_strdup ((gchar *)pNameBuffer) : g_strdup (cClass));
554
 
        /**if (myTaskBar.bUniquePid)
555
 
                icon->iPid = *pPidBuffer;*/
 
391
        icon->iType = CAIRO_DOCK_APPLI;
556
392
        icon->Xid = Xid;
 
393
        
 
394
        //\__________________ On renseigne les infos en provenance de X.
 
395
        icon->cName = (cName ? cName : g_strdup (cClass));
557
396
        icon->cClass = cClass;
558
 
        Icon * pLastAppli = cairo_dock_get_last_appli (pDock->icons);
559
 
        icon->fOrder = (pLastAppli != NULL ? pLastAppli->fOrder + 1 : 1);
560
 
        icon->iType = CAIRO_DOCK_APPLI;
561
397
        icon->bIsHidden = bIsHidden;
562
398
        icon->bIsMaximized = bIsMaximized;
563
399
        icon->bIsFullScreen = bIsFullScreen;
564
400
        icon->bIsDemandingAttention = bDemandsAttention;
565
401
        icon->bHasIndicator = myTaskBar.bDrawIndicatorOnAppli;
 
402
        /**Icon * pLastAppli = cairo_dock_get_last_appli (pDock->icons);
 
403
        icon->fOrder = (pLastAppli != NULL ? pLastAppli->fOrder + 1 : 1);*/
 
404
        icon->fOrder = CAIRO_DOCK_LAST_ORDER;
566
405
        
567
406
        cairo_dock_get_xwindow_geometry (Xid,
568
407
                &icon->windowGeometry.x,
571
410
                &icon->windowGeometry.height);
572
411
        icon->iNumDesktop = cairo_dock_get_xwindow_desktop (Xid);
573
412
        #ifdef HAVE_XEXTEND
574
 
        if (myTaskBar.bShowThumbnail)
 
413
        if (myTaskBar.iMinimizedWindowRenderType == 1)
575
414
        {
576
 
                icon->iBackingPixmap = XCompositeNameWindowPixmap (s_XDisplay, Xid);
 
415
                Display *display = gdk_x11_get_default_xdisplay ();
 
416
                icon->iBackingPixmap = XCompositeNameWindowPixmap (display, Xid);
577
417
                /*icon->iDamageHandle = XDamageCreate (s_XDisplay, Xid, XDamageReportNonEmpty);  // XDamageReportRawRectangles
578
418
                g_print ("backing pixmap : %d ; iDamageHandle : %d\n", icon->iBackingPixmap, icon->iDamageHandle);*/
579
419
        }
580
420
        #endif
581
421
        
 
422
        //\____________ On remplit ses buffers.
582
423
        cairo_dock_fill_icon_buffers_for_dock (icon, pSourceContext, pDock);
583
424
        
584
 
        /**if (myTaskBar.bUniquePid)
585
 
                g_hash_table_insert (s_hAppliTable, pPidBuffer, icon);*/
 
425
        if (icon->bIsHidden && myTaskBar.iMinimizedWindowRenderType == 2)
 
426
        {
 
427
                cairo_dock_draw_hidden_appli_icon (icon, CAIRO_CONTAINER (pDock), FALSE);
 
428
        }
 
429
        
 
430
        //\____________ On enregistre l'appli et on commence a la surveiller.
586
431
        cairo_dock_register_appli (icon);
587
 
        if (pNameBuffer)
588
 
                XFree (pNameBuffer);
589
432
        
590
433
        cairo_dock_set_xwindow_mask (Xid, PropertyChangeMask | StructureNotifyMask);
591
434
 
592
435
        return icon;
593
436
}
594
 
 
595
 
 
596
 
 
597
 
void cairo_dock_Xproperty_changed (Icon *icon, Atom aProperty, int iState, CairoDock *pDock)
598
 
{
599
 
        //g_print ("%s (%s, %s)\n", __func__, icon->cName, gdk_x11_get_xatom_name (aProperty));
600
 
        Atom aReturnedType = 0;
601
 
        int aReturnedFormat = 0;
602
 
        unsigned long iLeftBytes, iBufferNbElements=0;
603
 
        cairo_t* pCairoContext;
604
 
        if (iState == PropertyNewValue && (aProperty == s_aNetWmName || aProperty == s_aWmName))
605
 
        {
606
 
                //g_print ("chgt de nom (%d)\n", aProperty);
607
 
                guchar *pNameBuffer = NULL;
608
 
                XGetWindowProperty (s_XDisplay, icon->Xid, s_aNetWmName, 0, G_MAXULONG, False, s_aUtf8String, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);  // on cherche en priorite le nom en UTF8, car on est notifie des 2, mais il vaut mieux eviter le WM_NAME qui, ne l'etant pas, contient des caracteres bizarres qu'on ne peut pas convertir avec g_locale_to_utf8, puisque notre locale _est_ UTF8.
609
 
                if (iBufferNbElements == 0 && aProperty == s_aWmName)
610
 
                        XGetWindowProperty (s_XDisplay, icon->Xid, aProperty, 0, G_MAXULONG, False, s_aString, &aReturnedType, &aReturnedFormat, &iBufferNbElements, &iLeftBytes, &pNameBuffer);
611
 
                if (iBufferNbElements > 0)
612
 
                {
613
 
                        if (icon->cName == NULL || strcmp (icon->cName, (gchar *)pNameBuffer) != 0)
614
 
                        {
615
 
                                g_free (icon->cName);
616
 
                                icon->cName = g_strdup ((gchar *)pNameBuffer);
617
 
                                XFree (pNameBuffer);
618
 
 
619
 
                                pCairoContext = cairo_dock_create_context_from_window (CAIRO_CONTAINER (pDock));
620
 
                                cairo_dock_fill_one_text_buffer (icon, pCairoContext, &myLabels.iconTextDescription);
621
 
                                cairo_destroy (pCairoContext);
622
 
                                
623
 
                                cairo_dock_update_name_on_inhibators (icon->cClass, icon->Xid, icon->cName);
624
 
                        }
625
 
                }
626
 
        }
627
 
        else if (iState == PropertyNewValue && aProperty == s_aNetWmIcon)
628
 
        {
629
 
                cd_debug ("%s change son icone (%d)", icon->cName, cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons);
630
 
                if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons)
631
 
                {
632
 
                        cairo_dock_reload_one_icon_buffer_in_dock (icon, pDock);
633
 
                        cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pDock));
634
 
                }
635
 
        }
636
 
        else if (aProperty == s_aWmHints)
637
 
        {
638
 
                XWMHints *pWMHints = XGetWMHints (s_XDisplay, icon->Xid);
639
 
                if (pWMHints != NULL)
640
 
                {
641
 
                        if ((pWMHints->flags & XUrgencyHint) && (myTaskBar.bDemandsAttentionWithDialog || myTaskBar.cAnimationOnDemandsAttention))
642
 
                        {
643
 
                                if (iState == PropertyNewValue)
644
 
                                {
645
 
                                        cd_debug ("%s vous interpelle !", icon->cName);
646
 
                                        cairo_dock_appli_demands_attention (icon);
647
 
                                }
648
 
                                else if (iState == PropertyDelete)
649
 
                                {
650
 
                                        cd_debug ("%s arrette de vous interpeler.", icon->cName);
651
 
                                        cairo_dock_appli_stops_demanding_attention (icon);
652
 
                                }
653
 
                                else
654
 
                                        cd_warning ("  etat du changement d'urgence inconnu sur %s !", icon->cName);
655
 
                        }
656
 
                        if (iState == PropertyNewValue && (pWMHints->flags & (IconPixmapHint | IconMaskHint | IconWindowHint)))
657
 
                        {
658
 
                                //g_print ("%s change son icone\n", icon->cName);
659
 
                                if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons)
660
 
                                {
661
 
                                        cairo_dock_reload_one_icon_buffer_in_dock (icon, pDock);
662
 
                                        cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pDock));
663
 
                                }
664
 
                        }
665
 
                }
666
 
        }
667
 
}
668
 
 
669
 
 
670
 
static void _cairo_dock_appli_demands_attention (Icon *icon, CairoDock *pDock, gboolean bForceDemand, Icon *pHiddenIcon)
671
 
{
672
 
        cd_debug ("%s (%s, force:%d)\n", __func__, icon->cName, bForceDemand);
673
 
        icon->bIsDemandingAttention = TRUE;
674
 
        if (myTaskBar.bDemandsAttentionWithDialog)
675
 
        {
676
 
                CairoDialog *pDialog;
677
 
                if (pHiddenIcon == NULL)
678
 
                {
679
 
                        pDialog = cairo_dock_show_temporary_dialog_with_icon (icon->cName, icon, CAIRO_CONTAINER (pDock), 1000*myTaskBar.iDialogDuration, "same icon");
680
 
                }
681
 
                else
682
 
                {
683
 
                        pDialog = cairo_dock_show_temporary_dialog (pHiddenIcon->cName, icon, CAIRO_CONTAINER (pDock), 1000*myTaskBar.iDialogDuration);
684
 
                        g_return_if_fail (pDialog != NULL);
685
 
                        cairo_dock_set_new_dialog_icon_surface (pDialog, pHiddenIcon->pIconBuffer, pDialog->iIconSize);
686
 
                }
687
 
                if (pDialog && bForceDemand)
688
 
                {
689
 
                        g_print ("force dialog on top\n");
690
 
                        gtk_window_set_keep_above (GTK_WINDOW (pDialog->container.pWidget), TRUE);
691
 
                        Window Xid = GDK_WINDOW_XID (pDialog->container.pWidget->window);
692
 
                        cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_DOCK");  // pour passer devant les fenetres plein ecran; depend du WM.
693
 
                }
694
 
        }
695
 
        if (myTaskBar.cAnimationOnDemandsAttention && ! pHiddenIcon)  // on ne l'anime pas si elle n'est pas dans un dock.
696
 
        {
697
 
                if (pDock->iRefCount == 0)
698
 
                {
699
 
                        cairo_dock_pop_up (pDock);
700
 
                        if (pDock->iSidPopDown != 0)
701
 
                        {
702
 
                                g_source_remove(pDock->iSidPopDown);
703
 
                                pDock->iSidPopDown = 0;
704
 
                        }
705
 
                        if (pDock->bAutoHide && bForceDemand)
706
 
                        {
707
 
                                g_print ("force dock to raise\n");
708
 
                                cairo_dock_emit_enter_signal (pDock);
709
 
                        }
710
 
                }
711
 
                else if (bForceDemand)
712
 
                {
713
 
                        g_print ("force sub-dock to raise\n");
714
 
                        CairoDock *pParentDock = NULL;
715
 
                        Icon *pPointedIcon = cairo_dock_search_icon_pointing_on_dock (pDock, &pParentDock);
716
 
                        if (pParentDock)
717
 
                                cairo_dock_show_subdock (pPointedIcon, pParentDock, FALSE);
718
 
                }
719
 
                cairo_dock_request_icon_animation (icon, pDock, myTaskBar.cAnimationOnDemandsAttention, 10000);
720
 
                if (bForceDemand)
721
 
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDock));  // precaution au cas ou le dock ne serait pas encore visible.
722
 
        }
723
 
}
724
 
void cairo_dock_appli_demands_attention (Icon *icon)
725
 
{
726
 
        //g_print ("%s (%s)\n", __func__, icon->cName);
727
 
        
728
 
        if (icon->bIsDemandingAttention &&
729
 
                cairo_dock_icon_has_dialog (icon) &&
730
 
                ((! icon->cLastAttentionDemand && ! icon->cName) ||
731
 
                (icon->cLastAttentionDemand && icon->cName && strcmp (icon->cLastAttentionDemand, icon->cName) == 0)))  // la demande n'a pas change entre les 2 demandes.
732
 
        {
733
 
                return ;
734
 
        }
735
 
        g_free (icon->cLastAttentionDemand);
736
 
        icon->cLastAttentionDemand = g_strdup (icon->cName);
737
 
        
738
 
        gboolean bForceDemand = (myTaskBar.cForceDemandsAttention && icon->cClass && g_strstr_len (myTaskBar.cForceDemandsAttention, -1, icon->cClass));
739
 
        CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
740
 
        if (pParentDock == NULL)  // appli inhibee ou non affichee.
741
 
        {
742
 
                icon->bIsDemandingAttention = TRUE;  // on met a TRUE meme si ce n'est pas reellement elle qui va prendre la demande.
743
 
                Icon *pInhibitorIcon = cairo_dock_get_inhibator (icon, TRUE);  // on cherche son inhibiteur dans un dock.
744
 
                if (pInhibitorIcon != NULL)  // appli inhibee.
745
 
                {
746
 
                        pParentDock = cairo_dock_search_dock_from_name (pInhibitorIcon->cParentDockName);
747
 
                        if (pParentDock != NULL)
748
 
                                _cairo_dock_appli_demands_attention (pInhibitorIcon, pParentDock, bForceDemand, NULL);
749
 
                }
750
 
                else if (bForceDemand)  // appli pas affichee, mais on veut tout de m�me etre notifie.
751
 
                {
752
 
                        Icon *pOneIcon = cairo_dock_get_dialogless_icon ();
753
 
                        if (pOneIcon != NULL)
754
 
                                _cairo_dock_appli_demands_attention (pOneIcon, g_pMainDock, bForceDemand, icon);
755
 
                }
756
 
        }
757
 
        else  // appli dans un dock.
758
 
                _cairo_dock_appli_demands_attention (icon, pParentDock, bForceDemand, NULL);
759
 
}
760
 
 
761
 
static void _cairo_dock_appli_stops_demanding_attention (Icon *icon, CairoDock *pDock)
762
 
{
763
 
        icon->bIsDemandingAttention = FALSE;
764
 
        if (myTaskBar.bDemandsAttentionWithDialog)
765
 
                cairo_dock_remove_dialog_if_any (icon);
766
 
        cairo_dock_notify (CAIRO_DOCK_STOP_ICON, icon);  // arrete son animation quelqu'elle soit.
767
 
        if (! pDock->container.bInside)
768
 
        {
769
 
                g_print ("pop down the dock\n");
770
 
                cairo_dock_pop_down (pDock);
771
 
                
772
 
                if (pDock->bAutoHide)
773
 
                {
774
 
                        g_print ("force dock to auto-hide\n");
775
 
                        cairo_dock_emit_leave_signal (pDock);
776
 
                }
777
 
        }
778
 
}
779
 
void cairo_dock_appli_stops_demanding_attention (Icon *icon)
780
 
{
781
 
        CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
782
 
        if (pParentDock == NULL)
783
 
        {
784
 
                icon->bIsDemandingAttention = FALSE;  // idem que plus haut.
785
 
                Icon *pInhibitorIcon = cairo_dock_get_inhibator (icon, TRUE);
786
 
                if (pInhibitorIcon != NULL)
787
 
                {
788
 
                        pParentDock = cairo_dock_search_dock_from_name (pInhibitorIcon->cParentDockName);
789
 
                        if (pParentDock != NULL)
790
 
                                _cairo_dock_appli_stops_demanding_attention (pInhibitorIcon, pParentDock);
791
 
                }
792
 
        }
793
 
        else
794
 
                _cairo_dock_appli_stops_demanding_attention (icon, pParentDock);
795
 
}
796