/* 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); } } }
/* Unregister a focusable actor */ void xfdashboard_focus_manager_unregister(XfdashboardFocusManager *self, XfdashboardFocusable *inFocusable) { XfdashboardFocusManagerPrivate *priv; g_return_if_fail(XFDASHBOARD_IS_FOCUS_MANAGER(self)); g_return_if_fail(inFocusable); priv=self->priv; /* Unregister type if registered. * We do not need to check if the given actor is focusable or stylable * because it could not be registered if it is not. */ if(g_list_find(priv->registeredFocusables, inFocusable)!=NULL) { g_debug("Unregistering focusable %s", G_OBJECT_TYPE_NAME(inFocusable)); /* If we unregister the focusable actor which has the focus currently * move focus to next focusable actor first but check that we will not * reselect the focusable actor which should be unregistered. That can * happen because this actor is not yet removed from list of registered * focusable actor and is the only selectable one. But it needs to be * still in the list otherwise we could not find the next actor to * focus appropiately. */ if(inFocusable==priv->currentFocus) { XfdashboardFocusable *focusable; focusable=xfdashboard_focus_manager_get_next_focusable(self, priv->currentFocus); if(focusable && focusable!=priv->currentFocus) xfdashboard_focus_manager_set_focus(self, focusable); else { xfdashboard_focusable_unset_focus(priv->currentFocus); priv->currentFocus=NULL; } } /* Remove focusable actor from list of registered focusable actors */ priv->registeredFocusables=g_list_remove(priv->registeredFocusables, inFocusable); /* Disconnect from signals because we are not interested in this actor anymore */ g_signal_handlers_disconnect_by_func(inFocusable, G_CALLBACK(_xfdashboard_focus_manager_on_focusable_destroy), self); g_signal_handlers_disconnect_by_func(inFocusable, G_CALLBACK(_xfdashboard_focus_manager_on_focusable_hide), self); /* Emit signal */ g_signal_emit(self, XfdashboardFocusManagerSignals[SIGNAL_UNREGISTERED], 0, inFocusable); } }
/* 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; } }
/* Set focus to a registered focusable actor */ void xfdashboard_focus_manager_set_focus(XfdashboardFocusManager *self, XfdashboardFocusable *inFocusable) { XfdashboardFocusManagerPrivate *priv; XfdashboardFocusable *oldFocusable; g_return_if_fail(XFDASHBOARD_IS_FOCUS_MANAGER(self)); g_return_if_fail(XFDASHBOARD_IS_FOCUSABLE(inFocusable)); priv=self->priv; oldFocusable=NULL; /* Check if focusable actor is really registered */ if(g_list_find(priv->registeredFocusables, inFocusable)==NULL) { g_warning(_("Trying to focus an unregistered focusable actor")); return; } /* Check if new focusable actor can be focussed. If it cannot be focussed * move focus to next focusable actor. If no focusable actor can be found * do not change focus at all. */ if(!xfdashboard_focusable_can_focus(inFocusable)) { XfdashboardFocusable *newFocusable; newFocusable=xfdashboard_focus_manager_get_next_focusable(self, inFocusable); if(!newFocusable) { g_debug("Requested focusable actor '%s' cannot be focus but no other focusable actor was found", G_OBJECT_TYPE_NAME(inFocusable)); return; } g_debug("Requested focusable actor '%s' cannot be focused - moving focus to '%s'", G_OBJECT_TYPE_NAME(inFocusable), newFocusable ? G_OBJECT_TYPE_NAME(newFocusable) : "<nothing>"); inFocusable=newFocusable; } /* Do nothing if current focused actor and new one are the same */ oldFocusable=priv->currentFocus; if(oldFocusable==inFocusable) { g_debug("Current focused actor and new one are the same so do nothing."); return; } /* Unset focus at current focused actor */ if(priv->currentFocus) { xfdashboard_focusable_unset_focus(priv->currentFocus); priv->currentFocus=NULL; } /* Set focus to new focusable actor */ priv->currentFocus=inFocusable; xfdashboard_focusable_set_focus(priv->currentFocus); g_debug("Moved focus from '%s' to '%s'", oldFocusable ? G_OBJECT_TYPE_NAME(oldFocusable) : "<nothing>", G_OBJECT_TYPE_NAME(priv->currentFocus)); /* Emit signal for changed focus */ g_signal_emit(self, XfdashboardFocusManagerSignals[SIGNAL_CHANGED], 0, oldFocusable, priv->currentFocus); }