244
CairoDock *cairo_dock_manage_appli_class (Icon *icon, CairoDock *pMainDock)
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))
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.
254
cd_message (" classe %s encore vide", icon->cClass);
255
pParentDock = cairo_dock_search_dock_from_name (icon->cClass);
256
if (pParentDock == NULL)
258
pParentDock = pMainDock;
259
icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
263
icon->cParentDockName = g_strdup (icon->cClass);
266
else // on la met dans le sous-dock de sa classe.
268
icon->cParentDockName = g_strdup (icon->cClass);
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.
274
cd_message (" creation du dock pour la classe %s", icon->cClass);
275
pParentDock = cairo_dock_create_subdock_from_scratch (NULL, icon->cClass, pMainDock);
278
cd_message (" sous-dock de la classe %s existant", icon->cClass);
280
if (CAIRO_DOCK_IS_LAUNCHER (pSameClassIcon) || CAIRO_DOCK_IS_APPLET (pSameClassIcon)) // c'est un inhibiteur.
282
if (pSameClassIcon->Xid != 0) // actuellement l'inhibiteur inhibe 1 seule appli.
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)
289
if (pSameClassIcon->cInitialName != NULL)
291
CairoDock *pSameClassDock = cairo_dock_search_dock_from_name (pSameClassIcon->cParentDockName);
292
if (pSameClassDock != NULL)
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);
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.
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)
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);
314
else if (pSameClassIcon->pSubDock != pParentDock)
315
cd_warning ("this inhibator doesn't hold the class dock !");
317
else // c'est donc une appli du main dock.
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.
335
//\______________ On la charge.
336
cairo_dock_load_one_icon_from_scratch (pFakeClassIcon, CAIRO_CONTAINER (pClassMateParentDock));
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);
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));
353
icon->cParentDockName = g_strdup (CAIRO_DOCK_MAIN_DOCK_NAME);
358
224
static Window _cairo_dock_get_parent_window (Window Xid)
360
226
Atom aReturnedType = 0;
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)
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);*/
422
//\____________ On remplit ses buffers.
582
423
cairo_dock_fill_icon_buffers_for_dock (icon, pSourceContext, pDock);
584
/**if (myTaskBar.bUniquePid)
585
g_hash_table_insert (s_hAppliTable, pPidBuffer, icon);*/
425
if (icon->bIsHidden && myTaskBar.iMinimizedWindowRenderType == 2)
427
cairo_dock_draw_hidden_appli_icon (icon, CAIRO_CONTAINER (pDock), FALSE);
430
//\____________ On enregistre l'appli et on commence a la surveiller.
586
431
cairo_dock_register_appli (icon);
590
433
cairo_dock_set_xwindow_mask (Xid, PropertyChangeMask | StructureNotifyMask);
597
void cairo_dock_Xproperty_changed (Icon *icon, Atom aProperty, int iState, CairoDock *pDock)
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))
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)
613
if (icon->cName == NULL || strcmp (icon->cName, (gchar *)pNameBuffer) != 0)
615
g_free (icon->cName);
616
icon->cName = g_strdup ((gchar *)pNameBuffer);
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);
623
cairo_dock_update_name_on_inhibators (icon->cClass, icon->Xid, icon->cName);
627
else if (iState == PropertyNewValue && aProperty == s_aNetWmIcon)
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)
632
cairo_dock_reload_one_icon_buffer_in_dock (icon, pDock);
633
cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pDock));
636
else if (aProperty == s_aWmHints)
638
XWMHints *pWMHints = XGetWMHints (s_XDisplay, icon->Xid);
639
if (pWMHints != NULL)
641
if ((pWMHints->flags & XUrgencyHint) && (myTaskBar.bDemandsAttentionWithDialog || myTaskBar.cAnimationOnDemandsAttention))
643
if (iState == PropertyNewValue)
645
cd_debug ("%s vous interpelle !", icon->cName);
646
cairo_dock_appli_demands_attention (icon);
648
else if (iState == PropertyDelete)
650
cd_debug ("%s arrette de vous interpeler.", icon->cName);
651
cairo_dock_appli_stops_demanding_attention (icon);
654
cd_warning (" etat du changement d'urgence inconnu sur %s !", icon->cName);
656
if (iState == PropertyNewValue && (pWMHints->flags & (IconPixmapHint | IconMaskHint | IconWindowHint)))
658
//g_print ("%s change son icone\n", icon->cName);
659
if (cairo_dock_class_is_using_xicon (icon->cClass) || ! myTaskBar.bOverWriteXIcons)
661
cairo_dock_reload_one_icon_buffer_in_dock (icon, pDock);
662
cairo_dock_redraw_icon (icon, CAIRO_CONTAINER (pDock));
670
static void _cairo_dock_appli_demands_attention (Icon *icon, CairoDock *pDock, gboolean bForceDemand, Icon *pHiddenIcon)
672
cd_debug ("%s (%s, force:%d)\n", __func__, icon->cName, bForceDemand);
673
icon->bIsDemandingAttention = TRUE;
674
if (myTaskBar.bDemandsAttentionWithDialog)
676
CairoDialog *pDialog;
677
if (pHiddenIcon == NULL)
679
pDialog = cairo_dock_show_temporary_dialog_with_icon (icon->cName, icon, CAIRO_CONTAINER (pDock), 1000*myTaskBar.iDialogDuration, "same icon");
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);
687
if (pDialog && bForceDemand)
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.
695
if (myTaskBar.cAnimationOnDemandsAttention && ! pHiddenIcon) // on ne l'anime pas si elle n'est pas dans un dock.
697
if (pDock->iRefCount == 0)
699
cairo_dock_pop_up (pDock);
700
if (pDock->iSidPopDown != 0)
702
g_source_remove(pDock->iSidPopDown);
703
pDock->iSidPopDown = 0;
705
if (pDock->bAutoHide && bForceDemand)
707
g_print ("force dock to raise\n");
708
cairo_dock_emit_enter_signal (pDock);
711
else if (bForceDemand)
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);
717
cairo_dock_show_subdock (pPointedIcon, pParentDock, FALSE);
719
cairo_dock_request_icon_animation (icon, pDock, myTaskBar.cAnimationOnDemandsAttention, 10000);
721
cairo_dock_launch_animation (CAIRO_CONTAINER (pDock)); // precaution au cas ou le dock ne serait pas encore visible.
724
void cairo_dock_appli_demands_attention (Icon *icon)
726
//g_print ("%s (%s)\n", __func__, icon->cName);
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.
735
g_free (icon->cLastAttentionDemand);
736
icon->cLastAttentionDemand = g_strdup (icon->cName);
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.
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.
746
pParentDock = cairo_dock_search_dock_from_name (pInhibitorIcon->cParentDockName);
747
if (pParentDock != NULL)
748
_cairo_dock_appli_demands_attention (pInhibitorIcon, pParentDock, bForceDemand, NULL);
750
else if (bForceDemand) // appli pas affichee, mais on veut tout de m�me etre notifie.
752
Icon *pOneIcon = cairo_dock_get_dialogless_icon ();
753
if (pOneIcon != NULL)
754
_cairo_dock_appli_demands_attention (pOneIcon, g_pMainDock, bForceDemand, icon);
757
else // appli dans un dock.
758
_cairo_dock_appli_demands_attention (icon, pParentDock, bForceDemand, NULL);
761
static void _cairo_dock_appli_stops_demanding_attention (Icon *icon, CairoDock *pDock)
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)
769
g_print ("pop down the dock\n");
770
cairo_dock_pop_down (pDock);
772
if (pDock->bAutoHide)
774
g_print ("force dock to auto-hide\n");
775
cairo_dock_emit_leave_signal (pDock);
779
void cairo_dock_appli_stops_demanding_attention (Icon *icon)
781
CairoDock *pParentDock = cairo_dock_search_dock_from_name (icon->cParentDockName);
782
if (pParentDock == NULL)
784
icon->bIsDemandingAttention = FALSE; // idem que plus haut.
785
Icon *pInhibitorIcon = cairo_dock_get_inhibator (icon, TRUE);
786
if (pInhibitorIcon != NULL)
788
pParentDock = cairo_dock_search_dock_from_name (pInhibitorIcon->cParentDockName);
789
if (pParentDock != NULL)
790
_cairo_dock_appli_stops_demanding_attention (pInhibitorIcon, pParentDock);
794
_cairo_dock_appli_stops_demanding_attention (icon, pParentDock);