/* Virtual function "handle_key_event" was called */ static gboolean _xfdashboard_viewpad_focusable_handle_key_event(XfdashboardFocusable *inFocusable, const ClutterEvent *inEvent) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; gboolean handledEvent; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable), CLUTTER_EVENT_PROPAGATE); g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(inFocusable), CLUTTER_EVENT_PROPAGATE); self=XFDASHBOARD_VIEWPAD(inFocusable); priv=self->priv; /* Set handled key eventto CLUTTER_EVENT_PROPAGATE. It might be set to * CLUTTER_EVENT_STOP if current active view is focusable and it handled * the key event by its virtual function. */ handledEvent=CLUTTER_EVENT_PROPAGATE; /* Viewpad is just a proxy for the current active view. * So check if current active view is focusable and call its * virtual function. */ if(priv->activeView && XFDASHBOARD_IS_FOCUSABLE(priv->activeView)) { handledEvent=xfdashboard_focusable_handle_key_event(XFDASHBOARD_FOCUSABLE(priv->activeView), inEvent); } /* Return focusable state */ return(handledEvent); }
/* Unset focus from actor */ static void _xfdashboard_viewpad_focusable_unset_focus(XfdashboardFocusable *inFocusable) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; XfdashboardFocusableInterface *selfIface; XfdashboardFocusableInterface *parentIface; g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable)); g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(inFocusable)); self=XFDASHBOARD_VIEWPAD(inFocusable); priv=self->priv; /* Viewpad is just a proxy for the current active view. * So check if current active view is focusable and call its * virtual function. */ if(priv->activeView && XFDASHBOARD_IS_FOCUSABLE(priv->activeView)) { /* Call virtual function of view to unset focus */ xfdashboard_focusable_unset_focus(XFDASHBOARD_FOCUSABLE(priv->activeView)); /* Call parent class interface function of this actor */ selfIface=XFDASHBOARD_FOCUSABLE_GET_IFACE(inFocusable); parentIface=g_type_interface_peek_parent(selfIface); if(parentIface && parentIface->unset_focus) { parentIface->unset_focus(inFocusable); } } }
/* Determine if actor can get the focus */ static gboolean _xfdashboard_viewpad_focusable_can_focus(XfdashboardFocusable *inFocusable) { XfdashboardViewpad *self; XfdashboardViewpadPrivate *priv; gboolean canFocus; g_return_val_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable), FALSE); g_return_val_if_fail(XFDASHBOARD_IS_VIEWPAD(inFocusable), FALSE); self=XFDASHBOARD_VIEWPAD(inFocusable); priv=self->priv; /* Set current focusable result to FALSE (not focusable). It will be set * to TRUE automatically if current active view is focusable and its * virtual function will also return TRUE. */ canFocus=FALSE; /* Viewpad is just a proxy for the current active view. * So check if current active view is focusable and call its * virtual function. */ if(priv->activeView && XFDASHBOARD_IS_FOCUSABLE(priv->activeView)) { canFocus=xfdashboard_focusable_can_focus(XFDASHBOARD_FOCUSABLE(priv->activeView)); } /* Return focusable state */ return(canFocus); }
/* A registered focusable actor is going to be destroyed so unregister it */ static void _xfdashboard_focus_manager_on_focusable_destroy(XfdashboardFocusManager *self, gpointer inUserData) { XfdashboardFocusable *focusable; g_return_if_fail(XFDASHBOARD_IS_FOCUS_MANAGER(self)); g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(inUserData)); focusable=XFDASHBOARD_FOCUSABLE(inUserData); /* Unregister going-to-be-destroyed focusable actor */ xfdashboard_focus_manager_unregister(self, focusable); }
/* Action signal to close currently selected window was emitted */ static gboolean _xfdashboard_view_activate(XfdashboardView *self, XfdashboardFocusable *inSource, const gchar *inAction, ClutterEvent *inEvent) { XfdashboardViewPrivate *priv; XfdashboardViewpad *viewpad; XfdashboardFocusManager *focusManager; g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), CLUTTER_EVENT_PROPAGATE); priv=self->priv; /* Only enabled views can be activated */ if(!priv->isEnabled) return(CLUTTER_EVENT_STOP); /* Find viewpad which contains this view */ viewpad=_xfdashboard_view_find_viewpad(self); if(!viewpad) return(CLUTTER_EVENT_STOP); /* Activate view at viewpad if this view is not the active one */ if(xfdashboard_viewpad_get_active_view(viewpad)!=self) { xfdashboard_viewpad_set_active_view(viewpad, self); } /* Set focus to view if it has not the focus */ focusManager=xfdashboard_focus_manager_get_default(); if(XFDASHBOARD_IS_FOCUSABLE(self) && !xfdashboard_focus_manager_has_focus(focusManager, XFDASHBOARD_FOCUSABLE(self))) { xfdashboard_focus_manager_set_focus(focusManager, XFDASHBOARD_FOCUSABLE(self)); } g_object_unref(focusManager); /* Action handled */ return(CLUTTER_EVENT_STOP); }
/* Actor got key focus */ static void _xfdashboard_text_box_key_focus_in(ClutterActor *inActor) { XfdashboardTextBox *self=XFDASHBOARD_TEXT_BOX(inActor); XfdashboardTextBoxPrivate *priv=self->priv; ClutterStage *stage; XfdashboardFocusManager *focusManager; /* Push key focus forward to text box */ stage=CLUTTER_STAGE(clutter_actor_get_stage(inActor)); clutter_stage_set_key_focus(stage, priv->actorTextBox); /* Update focus in focus manager */ focusManager=xfdashboard_focus_manager_get_default(); xfdashboard_focus_manager_set_focus(focusManager, XFDASHBOARD_FOCUSABLE(self)); g_object_unref(focusManager); }
/* Determine if view has the focus */ gboolean xfdashboard_view_has_focus(XfdashboardView *self) { XfdashboardViewPrivate *priv; XfdashboardFocusManager *focusManager; XfdashboardViewpad *viewpad; g_return_val_if_fail(XFDASHBOARD_IS_VIEW(self), FALSE); priv=self->priv; /* The view can only have the focus if this view is enabled, active and * has the current focus. */ if(!priv->isEnabled) { return(FALSE); } viewpad=_xfdashboard_view_find_viewpad(self); if(!viewpad) { return(FALSE); } if(xfdashboard_viewpad_get_active_view(XFDASHBOARD_VIEWPAD(viewpad))!=self) { return(FALSE); } focusManager=xfdashboard_focus_manager_get_default(); if(!XFDASHBOARD_IS_FOCUSABLE(self) || !xfdashboard_focus_manager_has_focus(focusManager, XFDASHBOARD_FOCUSABLE(self))) { g_object_unref(focusManager); return(FALSE); } /* Release allocated resources */ g_object_unref(focusManager); /* All tests passed so this view has the focus */ return(TRUE); }
/* A registered focusable actor is going to be hidden or unrealized */ static void _xfdashboard_focus_manager_on_focusable_hide(XfdashboardFocusManager *self, gpointer inUserData) { XfdashboardFocusManagerPrivate *priv; XfdashboardFocusable *focusable; XfdashboardFocusable *nextFocusable; g_return_if_fail(XFDASHBOARD_IS_FOCUS_MANAGER(self)); g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(inUserData)); priv=self->priv; focusable=XFDASHBOARD_FOCUSABLE(inUserData); /* Only move focus if hidden or unrealized focusable actor is the one * which has the focus currently. */ if(priv->currentFocus!=focusable) return; if(CLUTTER_ACTOR_IS_MAPPED(CLUTTER_ACTOR(focusable)) && CLUTTER_ACTOR_IS_REALIZED(CLUTTER_ACTOR(focusable)) && CLUTTER_ACTOR_IS_VISIBLE(CLUTTER_ACTOR(focusable))) { return; } /* Move focus to next focusable actor if this actor which has the current focus * is going to be unrealized or hidden. */ nextFocusable=xfdashboard_focus_manager_get_next_focusable(self, priv->currentFocus); if(nextFocusable && nextFocusable!=priv->currentFocus) xfdashboard_focus_manager_set_focus(self, nextFocusable); else { xfdashboard_focusable_unset_focus(priv->currentFocus); priv->currentFocus=NULL; } }
/* Dispose this object */ static void _xfdashboard_focus_manager_dispose_unregister_focusable(gpointer inData, gpointer inUserData) { XfdashboardFocusManager *self; XfdashboardFocusable *focusable; g_return_if_fail(XFDASHBOARD_IS_FOCUS_MANAGER(inUserData)); g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(inData)); self=XFDASHBOARD_FOCUS_MANAGER(inUserData); focusable=XFDASHBOARD_FOCUSABLE(inData); /* Unregister focusable actor but do not call general unregister function * to avoid spamming focus changes and to avoid modifying list of focusable * actor while iterating through it. */ g_signal_handlers_disconnect_by_func(focusable, G_CALLBACK(_xfdashboard_focus_manager_on_focusable_destroy), self); g_signal_handlers_disconnect_by_func(focusable, G_CALLBACK(_xfdashboard_focus_manager_on_focusable_hide), self); g_signal_emit(self, XfdashboardFocusManagerSignals[SIGNAL_UNREGISTERED], 0, focusable); }
/* This button was clicked */ static void _xfdashboard_action_button_clicked(XfdashboardButton *inButton) { XfdashboardActionButton *self; XfdashboardActionButtonPrivate *priv; GSList *targets; GSList *iter; g_return_if_fail(XFDASHBOARD_IS_ACTION_BUTTON(inButton)); self=XFDASHBOARD_ACTION_BUTTON(inButton); priv=self->priv; targets=NULL; /* Get target object to perform action at */ targets=xfdashboard_focus_manager_get_targets(priv->focusManager, priv->target); XFDASHBOARD_DEBUG(self, ACTOR, "Target list for '%s' has %d entries", priv->target, g_slist_length(targets)); /* Emit action at each actor in target list */ for(iter=targets; iter; iter=g_slist_next(iter)) { GObject *targetObject; guint signalID; GSignalQuery signalData={ 0, }; const ClutterEvent *event; gboolean eventStatus; /* Get target to emit action signal at */ targetObject=G_OBJECT(iter->data); /* Check if target provides action requested as signal */ signalID=g_signal_lookup(priv->action, G_OBJECT_TYPE(targetObject)); if(!signalID) { g_warning(_("Object type %s does not provide action '%s'"), G_OBJECT_TYPE_NAME(targetObject), priv->action); continue; } /* Query signal for detailed data */ g_signal_query(signalID, &signalData); /* Check if signal is an action signal */ if(!(signalData.signal_flags & G_SIGNAL_ACTION)) { g_warning(_("Action '%s' at object type %s is not an action signal."), priv->action, G_OBJECT_TYPE_NAME(targetObject)); continue; } /* In debug mode also check if signal has right signature * to be able to handle this action properly. */ if(signalID) { GType returnValueType=G_TYPE_BOOLEAN; GType parameterTypes[]={ XFDASHBOARD_TYPE_FOCUSABLE, G_TYPE_STRING, CLUTTER_TYPE_EVENT }; guint parameterCount; guint i; /* Check if signal wants the right type of return value */ if(signalData.return_type!=returnValueType) { g_critical(_("Action '%s' at object type %s wants return value of type %s but expected is %s."), priv->action, G_OBJECT_TYPE_NAME(targetObject), g_type_name(signalData.return_type), g_type_name(returnValueType)); } /* Check if signals wants the right number and types of parameters */ parameterCount=sizeof(parameterTypes)/sizeof(GType); if(signalData.n_params!=parameterCount) { g_critical(_("Action '%s' at object type %s wants %u parameters but expected are %u."), priv->action, G_OBJECT_TYPE_NAME(targetObject), signalData.n_params, parameterCount); } for(i=0; i<(parameterCount<signalData.n_params ? parameterCount : signalData.n_params); i++) { if(signalData.param_types[i]!=parameterTypes[i]) { g_critical(_("Action '%s' at object type %s wants type %s at parameter %u but type %s is expected."), priv->action, G_OBJECT_TYPE_NAME(targetObject), g_type_name(signalData.param_types[i]), i+1, g_type_name(parameterTypes[i])); } } } /* Emit action signal at target */ XFDASHBOARD_DEBUG(self, ACTOR, "Emitting action signal '%s' at actor %s", priv->action, G_OBJECT_TYPE_NAME(targetObject)); event=clutter_get_current_event(); eventStatus=CLUTTER_EVENT_PROPAGATE; g_signal_emit_by_name(targetObject, priv->action, XFDASHBOARD_FOCUSABLE(self), priv->action, event, &eventStatus); XFDASHBOARD_DEBUG(self, ACTOR, "Action signal '%s' was %s by actor %s", priv->action, eventStatus==CLUTTER_EVENT_STOP ? "handled" : "not handled", G_OBJECT_TYPE_NAME(targetObject)); } /* Release allocated resources */ if(targets) g_slist_free_full(targets, g_object_unref); }