/** * xfdashboard_get_global_stage_of_actor: * @inActor: The #ClutterActor for which to find the global stage * * Gets the main #XfdashboardStage where @inActor belongs to. * * Return value: (transfer none): The #XfdashboardStage found * or %NULL if none was found. */ XfdashboardStage* xfdashboard_get_global_stage_of_actor(ClutterActor *inActor) { ClutterActor *parent; g_return_val_if_fail(CLUTTER_IS_ACTOR(inActor), NULL); /* Iterate through parents and return first XfdashboardStage * found. That's the main global and all monitors spanning * stage where the requested actor belongs to. */ parent=clutter_actor_get_parent(inActor); while(parent) { /* Check if current iterated parent is a XfdashboardStage. * If it is return it. */ if(XFDASHBOARD_IS_STAGE(parent)) return(XFDASHBOARD_STAGE(parent)); /* Continue with next parent */ parent=clutter_actor_get_parent(parent); } /* If we get here we did not find the global stage the actor * belongs to, so return NULL. */ return(NULL); }
/* Switch to requested view */ static void _xfdashboard_application_switch_to_view(XfdashboardApplication *self, const gchar *inInternalViewName) { GSList *stages, *iter; g_return_if_fail(XFDASHBOARD_IS_APPLICATION(self)); /* If no view name was specified then do nothing and return immediately */ if(!inInternalViewName || !inInternalViewName[0]) { g_debug("No view to switch to specified"); return; } /* Iterate through list of stages and set specified view at stage */ g_debug("Trying to switch to view '%s'", inInternalViewName); stages=clutter_stage_manager_list_stages(clutter_stage_manager_get_default()); for(iter=stages; iter; iter=g_slist_next(iter)) { /* Tell stage to switch view */ if(XFDASHBOARD_IS_STAGE(iter->data)) { xfdashboard_stage_set_switch_to_view(XFDASHBOARD_STAGE(iter->data), inInternalViewName); } } }
/* Pointer left actor with tooltip */ static gboolean _xfdashboard_tooltip_action_on_leave_event(XfdashboardTooltipAction *self, ClutterEvent *inEvent, gpointer inUserData) { XfdashboardTooltipActionPrivate *priv; ClutterActor *actor; ClutterActor *stage; ClutterActor *actorMeta; g_return_val_if_fail(XFDASHBOARD_IS_TOOLTIP_ACTION(self), CLUTTER_EVENT_PROPAGATE); g_return_val_if_fail(CLUTTER_IS_ACTOR(inUserData), CLUTTER_EVENT_PROPAGATE); priv=self->priv; actor=CLUTTER_ACTOR(inUserData); /* Get current actor this action belongs to */ actorMeta=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self)); /* Release all sources and signal handler (except for enter event) */ if(priv->motionSignalID!=0) { if(actorMeta) g_signal_handler_disconnect(actorMeta, priv->motionSignalID); priv->motionSignalID=0; } if(priv->leaveSignalID!=0) { if(actorMeta) g_signal_handler_disconnect(actorMeta, priv->leaveSignalID); priv->leaveSignalID=0; } if(priv->captureSignalID) { if(priv->captureSignalActor) g_signal_handler_disconnect(priv->captureSignalActor, priv->captureSignalID); priv->captureSignalActor=NULL; priv->captureSignalID=0; } if(priv->timeoutSourceID!=0) { g_source_remove(priv->timeoutSourceID); priv->timeoutSourceID=0; } /* Clear last actor we remembered if it is pointing to this actor */ if(_xfdashboard_tooltip_last_event_actor==actor) { _xfdashboard_tooltip_last_event_actor=NULL; } /* Hide tooltip now */ stage=clutter_actor_get_stage(actor); if(stage && XFDASHBOARD_IS_STAGE(stage)) { g_signal_emit_by_name(stage, "hide-tooltip", self, NULL); priv->isVisible=FALSE; } return(CLUTTER_EVENT_PROPAGATE); }
/* An event after a tooltip was shown so check if tooltip should be hidden again */ static gboolean _xfdashboard_tooltip_action_on_captured_event_after_tooltip(XfdashboardTooltipAction *self, ClutterEvent *inEvent, gpointer inUserData) { gboolean doHide; g_return_val_if_fail(XFDASHBOARD_IS_TOOLTIP_ACTION(self), CLUTTER_EVENT_PROPAGATE); g_return_val_if_fail(XFDASHBOARD_IS_STAGE(inUserData), CLUTTER_EVENT_PROPAGATE); /* Check if tooltip should be hidden depending on event type */ switch(clutter_event_type(inEvent)) { case CLUTTER_NOTHING: case CLUTTER_MOTION: doHide=FALSE; break; default: doHide=TRUE; break; } /* Hide tooltip if requested */ if(doHide) { _xfdashboard_tooltip_action_on_leave_event(self, inEvent, inUserData); } return(CLUTTER_EVENT_PROPAGATE); }
/* Actor was (re)parented */ static void _xfdashboard_actor_parent_set(ClutterActor *inActor, ClutterActor *inOldParent) { XfdashboardActor *self; XfdashboardActorPrivate *priv; ClutterActorClass *parentClass; g_return_if_fail(XFDASHBOARD_IS_ACTOR(inActor)); self=XFDASHBOARD_ACTOR(inActor); priv=self->priv; /* Call parent's virtual function */ parentClass=CLUTTER_ACTOR_CLASS(xfdashboard_actor_parent_class); if(parentClass->parent_set) { parentClass->parent_set(inActor, inOldParent); } /* Check if it is a newly created actor which is parented for the first time. * Then emit 'actor-created' signal on stage. */ if(priv->isFirstParent && !inOldParent && clutter_actor_get_parent(inActor)) { ClutterActor *stage; /* Get stage where this actor belongs to and emit signal at stage */ stage=clutter_actor_get_stage(inActor); if(XFDASHBOARD_IS_STAGE(stage)) { g_signal_emit_by_name(stage, "actor-created", inActor, NULL); } /* Set flag that a parent set and signal was emitted */ priv->isFirstParent=FALSE; } /* Invalide styling to get it recomputed because its ID (from point * of view of css) has changed. Also invalidate children as they might * reference the old, invalid parent or the new, valid one. */ _xfdashboard_actor_invalidate_recursive(CLUTTER_ACTOR(self)); }
/* Actor was (re)parented */ static void xfdashboard_stage_interface_parent_set(ClutterActor *inActor, ClutterActor *inOldParent) { XfdashboardStageInterface *self; XfdashboardStageInterfacePrivate *priv; ClutterActorClass *parentClass; ClutterActor *newParent; g_return_if_fail(XFDASHBOARD_IS_STAGE_INTERFACE(inActor)); self=XFDASHBOARD_STAGE_INTERFACE(inActor); priv=self->priv; /* Call parent's virtual function */ parentClass=CLUTTER_ACTOR_CLASS(xfdashboard_stage_interface_parent_class); if(parentClass->parent_set) { parentClass->parent_set(inActor, inOldParent); } /* Set up property bindings to new parent actor */ newParent=clutter_actor_get_parent(inActor); if(priv->bindingBackgroundImageType) { g_object_unref(priv->bindingBackgroundImageType); priv->bindingBackgroundImageType=NULL; } if(priv->bindingBackgroundColor) { g_object_unref(priv->bindingBackgroundColor); priv->bindingBackgroundColor=NULL; } if(newParent && XFDASHBOARD_IS_STAGE(newParent)) { priv->bindingBackgroundImageType=g_object_bind_property(self, "background-image-type", newParent, "background-image-type", G_BINDING_DEFAULT); priv->bindingBackgroundColor=g_object_bind_property(self, "background-color", newParent, "background-color", G_BINDING_DEFAULT); } }
/* Timeout for tooltip has been reached */ static gboolean _xfdashboard_tooltip_action_on_timeout(gpointer inUserData) { XfdashboardTooltipAction *self; XfdashboardTooltipActionPrivate *priv; ClutterActor *actor; ClutterActor *stage; g_return_val_if_fail(XFDASHBOARD_IS_TOOLTIP_ACTION(inUserData), G_SOURCE_REMOVE); self=XFDASHBOARD_TOOLTIP_ACTION(inUserData); priv=self->priv; /* Regardless how this function ends we will let this source be * removed from main loop. So forget source ID ;) */ priv->timeoutSourceID=0; /* Check if last seen actor is this actor. If not we cannot display * a tooltip and remove this source on return. */ actor=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self)); if(actor!=_xfdashboard_tooltip_last_event_actor) return(G_SOURCE_REMOVE); /* Show tooltip */ stage=clutter_actor_get_stage(actor); if(stage && XFDASHBOARD_IS_STAGE(stage)) { /* Emit 'activating' signal for last chance to update tooltip text */ g_signal_emit(self, XfdashboardTooltipActionSignals[SIGNAL_ACTIVATING], 0); /* Show tooltip */ g_signal_emit_by_name(stage, "show-tooltip", self, NULL); priv->isVisible=TRUE; } /* Remove source */ return(G_SOURCE_REMOVE); }
/** * xfdashboard_notify: * @inSender: The sending #ClutterActor or %NULL * @inIconName: The icon name to display in notification or %NULL * @inFormat: A standard printf() format string for notification text * @...: The parameters to insert into the format string * * Shows a notification with the formatted text as specified in @inFormat * and the parameters at the monitor where the sending actor @inSender * is placed on. * * If @inSender is NULL the primary monitor is used. * * If @inIconName is NULL no icon will be shown in notification. */ void xfdashboard_notify(ClutterActor *inSender, const gchar *inIconName, const gchar *inFormat, ...) { XfdashboardStage *stage; ClutterStageManager *stageManager; va_list args; gchar *text; g_return_if_fail(inSender==NULL || CLUTTER_IS_ACTOR(inSender)); stage=NULL; /* Build text to display */ va_start(args, inFormat); text=g_strdup_vprintf(inFormat, args); va_end(args); /* Get stage of sending actor if available */ if(inSender) stage=XFDASHBOARD_STAGE(clutter_actor_get_stage(inSender)); /* No sending actor specified or no stage found so get default stage */ if(!stage) { const GSList *stages; const GSList *stagesIter; ClutterActorIter interfaceIter; ClutterActor *child; XfdashboardWindowTrackerMonitor *stageMonitor; /* Get stage manager to iterate through stages to find the one * for primary monitor or at least the first stage. */ stageManager=clutter_stage_manager_get_default(); /* Find stage for primary monitor and if we cannot find it * use first stage. */ if(stageManager && CLUTTER_IS_STAGE_MANAGER(stageManager)) { /* Get list of all stages */ stages=clutter_stage_manager_peek_stages(stageManager); /* Iterate through list of all stage and lookup the one for * primary monitor. */ for(stagesIter=stages; stagesIter && !stage; stagesIter=stagesIter->next) { /* Skip this stage if it is not a XfdashboardStage */ if(!XFDASHBOARD_IS_STAGE(stagesIter->data)) continue; /* Iterate through stage's children and lookup stage interfaces */ clutter_actor_iter_init(&interfaceIter, CLUTTER_ACTOR(stagesIter->data)); while(clutter_actor_iter_next(&interfaceIter, &child)) { if(XFDASHBOARD_IS_STAGE_INTERFACE(child)) { stageMonitor=xfdashboard_stage_interface_get_monitor(XFDASHBOARD_STAGE_INTERFACE(child)); if(xfdashboard_window_tracker_monitor_is_primary(stageMonitor)) { stage=XFDASHBOARD_STAGE(clutter_actor_get_stage(child)); } } } } /* If we did not get stage for primary monitor use first stage */ if(!stage && stages) { stage=XFDASHBOARD_STAGE(stages->data); } } /* If we still do not have found a stage to show notification * stop further processing and show notification text as a critical * warning in addition to the critical warning that we could not * find any stage. */ if(!stage) { g_critical(_("Could find any stage to show notification: %s"), text); } } /* Show notification on stage (if any found) */ if(stage) xfdashboard_stage_show_notification(stage, inIconName, text); /* Release allocated resources */ g_free(text); }
/* Pointer was moved over actor with tooltip */ static gboolean _xfdashboard_tooltip_action_on_motion_event(XfdashboardTooltipAction *self, ClutterEvent *inEvent, gpointer inUserData) { XfdashboardTooltipActionPrivate *priv; ClutterActor *actor; guint tooltipTimeout; ClutterActor *stage; g_return_val_if_fail(XFDASHBOARD_IS_TOOLTIP_ACTION(self), CLUTTER_EVENT_PROPAGATE); g_return_val_if_fail(CLUTTER_IS_ACTOR(inUserData), CLUTTER_EVENT_PROPAGATE); priv=self->priv; actor=CLUTTER_ACTOR(inUserData); tooltipTimeout=0; /* Do nothing if tooltip is already visible */ if(priv->isVisible) return(CLUTTER_EVENT_PROPAGATE); /* Remove any timeout source we have added for this actor */ if(priv->timeoutSourceID!=0) { g_source_remove(priv->timeoutSourceID); priv->timeoutSourceID=0; } /* Remember position and actor */ clutter_event_get_position(inEvent, &priv->lastPosition); _xfdashboard_tooltip_last_event_actor=actor; /* Set up new timeout source */ #if GTK_CHECK_VERSION(3, 14 ,0) /* Since GTK+ version 3.10 the setting "gtk-tooltip-timeout" is * not supported anymore and ignored by GTK+ derived application. * So we should also. We set the timeout statically to the default * duration which GTK+ is also using. * This also prevents warning about forthcoming deprecation of this * setting printed to console. */ tooltipTimeout=DEFAULT_TOOLTIP_TIMEOUT; #else /* Get configured duration when a tooltip should be shown from * GTK+ settings. */ g_object_get(gtk_settings_get_default(), "gtk-tooltip-timeout", &tooltipTimeout, NULL); #endif priv->timeoutSourceID=clutter_threads_add_timeout(tooltipTimeout, (GSourceFunc)_xfdashboard_tooltip_action_on_timeout, self); /* Capture next events to check if tooltip should be hidden again */ stage=clutter_actor_get_stage(actor); if(stage && XFDASHBOARD_IS_STAGE(stage)) { g_warn_if_fail((priv->captureSignalID==0 && priv->captureSignalActor==NULL) || (priv->captureSignalID!=0 && priv->captureSignalActor==stage)); if((priv->captureSignalID==0 && priv->captureSignalActor==NULL) || (priv->captureSignalID && priv->captureSignalActor!=stage)) { if(priv->captureSignalActor) g_signal_handler_disconnect(priv->captureSignalActor, priv->captureSignalID); priv->captureSignalActor=NULL; priv->captureSignalID=0; priv->captureSignalActor=stage; priv->captureSignalID=g_signal_connect_swapped(stage, "captured-event", G_CALLBACK(_xfdashboard_tooltip_action_on_captured_event_after_tooltip), self); } } return(CLUTTER_EVENT_PROPAGATE); }