static gboolean sagarmatha_stack_navigate_focus (StWidget *widget, ClutterActor *from, GtkDirectionType direction) { ClutterActor *top_actor; GList *children; /* If the stack is itself focusable, then focus into or out of * it, as appropriate. */ if (st_widget_get_can_focus (widget)) { if (from && clutter_actor_contains (CLUTTER_ACTOR (widget), from)) return FALSE; clutter_actor_grab_key_focus (CLUTTER_ACTOR (widget)); return TRUE; } /* Otherwise, navigate into its top-most child only */ children = st_container_get_children_list (ST_CONTAINER (widget)); if (!children) return FALSE; top_actor = g_list_last (children)->data; if (ST_IS_WIDGET (top_actor)) return st_widget_navigate_focus (ST_WIDGET (top_actor), from, direction, FALSE); else return FALSE; }
static void clutter_bind_constraint_set_actor (ClutterActorMeta *meta, ClutterActor *new_actor) { ClutterBindConstraint *bind = CLUTTER_BIND_CONSTRAINT (meta); ClutterActorMetaClass *parent; if (new_actor != NULL && bind->source != NULL && clutter_actor_contains (new_actor, bind->source)) { g_warning (G_STRLOC ": The source actor '%s' is contained " "by the actor '%s' associated to the constraint " "'%s'", _clutter_actor_get_debug_name (bind->source), _clutter_actor_get_debug_name (new_actor), _clutter_actor_meta_get_debug_name (meta)); return; } /* store the pointer to the actor, for later use */ bind->actor = new_actor; parent = CLUTTER_ACTOR_META_CLASS (clutter_bind_constraint_parent_class); parent->set_actor (meta, new_actor); }
static gboolean shell_stack_navigate_focus (StWidget *widget, ClutterActor *from, GtkDirectionType direction) { ClutterActor *top_actor; /* If the stack is itself focusable, then focus into or out of * it, as appropriate. */ if (st_widget_get_can_focus (widget)) { if (from && clutter_actor_contains (CLUTTER_ACTOR (widget), from)) return FALSE; if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (widget))) { clutter_actor_grab_key_focus (CLUTTER_ACTOR (widget)); return TRUE; } else { return FALSE; } } top_actor = clutter_actor_get_last_child (CLUTTER_ACTOR (widget)); if (ST_IS_WIDGET (top_actor)) return st_widget_navigate_focus (ST_WIDGET (top_actor), from, direction, FALSE); else return FALSE; }
static gboolean st_button_button_release (ClutterActor *actor, ClutterButtonEvent *event) { StButton *button = ST_BUTTON (actor); StButtonPrivate *priv = st_button_get_instance_private (button); StButtonMask mask = ST_BUTTON_MASK_FROM_BUTTON (event->button); ClutterInputDevice *device = clutter_event_get_device ((ClutterEvent*) event); if (priv->button_mask & mask) { gboolean is_click; is_click = priv->grabbed && clutter_actor_contains (actor, event->source); st_button_release (button, device, mask, is_click ? event->button : 0, NULL); priv->grabbed &= ~mask; if (priv->grabbed == 0) clutter_ungrab_pointer (); return TRUE; } return FALSE; }
/** * clutter_bind_constraint_set_source: * @constraint: a #ClutterBindConstraint * @source: (allow-none): a #ClutterActor, or %NULL to unset the source * * Sets the source #ClutterActor for the constraint * * Since: 1.4 */ void clutter_bind_constraint_set_source (ClutterBindConstraint *constraint, ClutterActor *source) { ClutterActor *old_source, *actor; ClutterActorMeta *meta; g_return_if_fail (CLUTTER_IS_BIND_CONSTRAINT (constraint)); g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); if (constraint->source == source) return; meta = CLUTTER_ACTOR_META (constraint); actor = clutter_actor_meta_get_actor (meta); if (source != NULL && actor != NULL) { if (clutter_actor_contains (actor, source)) { g_warning (G_STRLOC ": The source actor '%s' is contained " "by the actor '%s' associated to the constraint " "'%s'", _clutter_actor_get_debug_name (source), _clutter_actor_get_debug_name (actor), _clutter_actor_meta_get_debug_name (meta)); return; } } old_source = constraint->source; if (old_source != NULL) { g_signal_handlers_disconnect_by_func (old_source, G_CALLBACK (source_destroyed), constraint); g_signal_handlers_disconnect_by_func (old_source, G_CALLBACK (source_queue_relayout), constraint); } constraint->source = source; if (constraint->source != NULL) { g_signal_connect (constraint->source, "queue-relayout", G_CALLBACK (source_queue_relayout), constraint); g_signal_connect (constraint->source, "destroy", G_CALLBACK (source_destroyed), constraint); if (constraint->actor != NULL) clutter_actor_queue_relayout (constraint->actor); } g_object_notify_by_pspec (G_OBJECT (constraint), obj_props[PROP_SOURCE]); }
/** * clutter_align_constraint_set_source: * @align: a #ClutterAlignConstraint * @source: (allow-none): a #ClutterActor, or %NULL to unset the source * * Sets the source of the alignment constraint * * Since: 1.4 */ void clutter_align_constraint_set_source (ClutterAlignConstraint *align, ClutterActor *source) { ClutterActor *old_source, *actor; ClutterActorMeta *meta; g_return_if_fail (CLUTTER_IS_ALIGN_CONSTRAINT (align)); g_return_if_fail (source == NULL || CLUTTER_IS_ACTOR (source)); if (align->source == source) return; meta = CLUTTER_ACTOR_META (align); actor = clutter_actor_meta_get_actor (meta); if (actor != NULL && source != NULL) { if (clutter_actor_contains (actor, source)) { g_warning (G_STRLOC ": The source actor '%s' is contained " "by the actor '%s' associated to the constraint " "'%s'", _clutter_actor_get_debug_name (source), _clutter_actor_get_debug_name (actor), _clutter_actor_meta_get_debug_name (meta)); return; } } old_source = align->source; if (old_source != NULL) { g_signal_handlers_disconnect_by_func (old_source, G_CALLBACK (source_destroyed), align); g_signal_handlers_disconnect_by_func (old_source, G_CALLBACK (source_position_changed), align); } align->source = source; if (align->source != NULL) { g_signal_connect (align->source, "allocation-changed", G_CALLBACK (source_position_changed), align); g_signal_connect (align->source, "destroy", G_CALLBACK (source_destroyed), align); if (align->actor != NULL) clutter_actor_queue_relayout (align->actor); } g_object_notify_by_pspec (G_OBJECT (align), obj_props[PROP_SOURCE]); }
static gboolean st_bin_navigate_focus (StWidget *widget, ClutterActor *from, GtkDirectionType direction) { StBinPrivate *priv = ST_BIN (widget)->priv; ClutterActor *bin_actor = CLUTTER_ACTOR (widget); if (st_widget_get_can_focus (widget)) { if (from && clutter_actor_contains (bin_actor, from)) return FALSE; clutter_actor_grab_key_focus (bin_actor); return TRUE; } else if (priv->child && ST_IS_WIDGET (priv->child)) return st_widget_navigate_focus (ST_WIDGET (priv->child), from, direction, FALSE); else return FALSE; }
static gboolean on_captured_event (ClutterActor *stage, ClutterEvent *event, ClutterClickAction *action) { ClutterClickActionPrivate *priv = action->priv; ClutterActor *actor; ClutterModifierType modifier_state; gboolean has_button = TRUE; actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (action)); switch (clutter_event_type (event)) { case CLUTTER_TOUCH_END: has_button = FALSE; case CLUTTER_BUTTON_RELEASE: if (!priv->is_held) return CLUTTER_EVENT_STOP; if ((has_button && clutter_event_get_button (event) != priv->press_button) || (has_button && clutter_event_get_click_count (event) != 1) || clutter_event_get_device_id (event) != priv->press_device_id || clutter_event_get_event_sequence (event) != priv->press_sequence) return CLUTTER_EVENT_PROPAGATE; click_action_set_held (action, FALSE); click_action_cancel_long_press (action); /* disconnect the capture */ if (priv->capture_id != 0) { g_signal_handler_disconnect (priv->stage, priv->capture_id); priv->capture_id = 0; } if (priv->long_press_id != 0) { g_source_remove (priv->long_press_id); priv->long_press_id = 0; } if (!clutter_actor_contains (actor, clutter_event_get_source (event))) return CLUTTER_EVENT_PROPAGATE; /* exclude any button-mask so that we can compare * the press and release states properly */ modifier_state = clutter_event_get_state (event) & ~(CLUTTER_BUTTON1_MASK | CLUTTER_BUTTON2_MASK | CLUTTER_BUTTON3_MASK | CLUTTER_BUTTON4_MASK | CLUTTER_BUTTON5_MASK); /* if press and release states don't match we * simply ignore modifier keys. i.e. modifier keys * are expected to be pressed throughout the whole * click */ if (modifier_state != priv->modifier_state) priv->modifier_state = 0; click_action_set_pressed (action, FALSE); g_signal_emit (action, click_signals[CLICKED], 0, actor); break; case CLUTTER_MOTION: case CLUTTER_TOUCH_UPDATE: { gfloat motion_x, motion_y; gfloat delta_x, delta_y; if (!priv->is_held) return CLUTTER_EVENT_PROPAGATE; clutter_event_get_coords (event, &motion_x, &motion_y); delta_x = ABS (motion_x - priv->press_x); delta_y = ABS (motion_y - priv->press_y); if (delta_x > priv->drag_threshold || delta_y > priv->drag_threshold) click_action_cancel_long_press (action); } break; default: break; } return CLUTTER_EVENT_STOP; }
static gboolean on_event (ClutterActor *actor, ClutterEvent *event, ClutterClickAction *action) { ClutterClickActionPrivate *priv = action->priv; gboolean has_button = TRUE; if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (action))) return CLUTTER_EVENT_PROPAGATE; switch (clutter_event_type (event)) { case CLUTTER_TOUCH_BEGIN: has_button = FALSE; case CLUTTER_BUTTON_PRESS: if (has_button && clutter_event_get_click_count (event) != 1) return CLUTTER_EVENT_PROPAGATE; if (priv->is_held) return CLUTTER_EVENT_STOP; if (!clutter_actor_contains (actor, clutter_event_get_source (event))) return CLUTTER_EVENT_PROPAGATE; priv->press_button = has_button ? clutter_event_get_button (event) : 0; priv->press_device_id = clutter_event_get_device_id (event); priv->press_sequence = clutter_event_get_event_sequence (event); priv->modifier_state = clutter_event_get_state (event); clutter_event_get_coords (event, &priv->press_x, &priv->press_y); if (priv->long_press_threshold < 0) { ClutterSettings *settings = clutter_settings_get_default (); g_object_get (settings, "dnd-drag-threshold", &priv->drag_threshold, NULL); } else priv->drag_threshold = priv->long_press_threshold; if (priv->stage == NULL) priv->stage = clutter_actor_get_stage (actor); priv->capture_id = g_signal_connect_after (priv->stage, "captured-event", G_CALLBACK (on_captured_event), action); click_action_set_pressed (action, TRUE); click_action_set_held (action, TRUE); click_action_query_long_press (action); break; case CLUTTER_ENTER: click_action_set_pressed (action, priv->is_held); break; case CLUTTER_LEAVE: click_action_set_pressed (action, priv->is_held); click_action_cancel_long_press (action); break; default: break; } return CLUTTER_EVENT_PROPAGATE; }
/* An event was received */ static gboolean _xfdashboard_click_action_on_event(XfdashboardClickAction *self, ClutterEvent *inEvent, gpointer inUserData) { XfdashboardClickActionPrivate *priv; gboolean hasButton; ClutterActor *actor; g_return_val_if_fail(XFDASHBOARD_IS_CLICK_ACTION(self), CLUTTER_EVENT_PROPAGATE); g_return_val_if_fail(CLUTTER_IS_ACTOR(inUserData), CLUTTER_EVENT_PROPAGATE); priv=self->priv; hasButton=TRUE; actor=CLUTTER_ACTOR(inUserData); /* Check if actor is enabled to handle events */ if(!clutter_actor_meta_get_enabled(CLUTTER_ACTOR_META(self))) return(CLUTTER_EVENT_PROPAGATE); /* Handle event */ switch(clutter_event_type(inEvent)) { case CLUTTER_TOUCH_BEGIN: hasButton=FALSE; case CLUTTER_BUTTON_PRESS: /* We only handle single clicks if it is pointer device */ if(hasButton && clutter_event_get_click_count(inEvent)!=1) { return(CLUTTER_EVENT_PROPAGATE); } /* Do we already held the press? */ if(priv->isHeld) return(CLUTTER_EVENT_STOP); /* Is the source of event a child of this actor. If not do * not handle this event but any other. */ if(!clutter_actor_contains(actor, clutter_event_get_source(inEvent))) { return(CLUTTER_EVENT_PROPAGATE); } /* Remember event data */ priv->pressButton=hasButton ? clutter_event_get_button(inEvent) : 0; priv->pressDeviceID=clutter_event_get_device_id(inEvent); priv->pressSequence=clutter_event_get_event_sequence(inEvent); priv->modifierState=clutter_event_get_state(inEvent); clutter_event_get_coords(inEvent, &priv->pressX, &priv->pressY); if(priv->longPressThreshold<0) { ClutterSettings *settings=clutter_settings_get_default(); g_object_get(settings, "dnd-drag-threshold", &priv->dragThreshold, NULL); } else priv->dragThreshold=priv->longPressThreshold; if(priv->stage==NULL) priv->stage=clutter_actor_get_stage(actor); /* Connect signals */ priv->captureID=g_signal_connect_object(priv->stage, "captured-event", G_CALLBACK(_xfdashboard_click_action_on_captured_event), self, G_CONNECT_AFTER | G_CONNECT_SWAPPED); /* Set state of this action */ _xfdashboard_click_action_set_pressed(self, TRUE); _xfdashboard_click_action_set_held(self, TRUE); _xfdashboard_click_action_query_long_press(self); break; case CLUTTER_ENTER: _xfdashboard_click_action_set_pressed(self, priv->isHeld); break; case CLUTTER_LEAVE: _xfdashboard_click_action_set_pressed(self, priv->isHeld); _xfdashboard_click_action_cancel_long_press(self); break; default: break; } return(CLUTTER_EVENT_PROPAGATE); }
/* An event was captured */ static gboolean _xfdashboard_click_action_on_captured_event(XfdashboardClickAction *self, ClutterEvent *inEvent, gpointer inUserData) { XfdashboardClickActionPrivate *priv; ClutterActor *stage G_GNUC_UNUSED; ClutterActor *actor; ClutterModifierType modifierState; gboolean hasButton; g_return_val_if_fail(XFDASHBOARD_IS_CLICK_ACTION(self), CLUTTER_EVENT_PROPAGATE); g_return_val_if_fail(CLUTTER_IS_ACTOR(inUserData), CLUTTER_EVENT_PROPAGATE); priv=self->priv; stage=CLUTTER_ACTOR(inUserData); hasButton=TRUE; /* Handle captured event */ actor=clutter_actor_meta_get_actor(CLUTTER_ACTOR_META(self)); switch(clutter_event_type(inEvent)) { case CLUTTER_TOUCH_END: hasButton=FALSE; case CLUTTER_BUTTON_RELEASE: if(!priv->isHeld) return(CLUTTER_EVENT_STOP); if((hasButton && clutter_event_get_button(inEvent)!=priv->pressButton) || (hasButton && clutter_event_get_click_count(inEvent)!=1) || clutter_event_get_device_id(inEvent)!=priv->pressDeviceID || clutter_event_get_event_sequence(inEvent)!=priv->pressSequence) { return(CLUTTER_EVENT_PROPAGATE); } _xfdashboard_click_action_set_held(self, FALSE); _xfdashboard_click_action_cancel_long_press(self); /* Disconnect the capture */ if(priv->captureID!=0) { g_signal_handler_disconnect(priv->stage, priv->captureID); priv->captureID = 0; } if(priv->longPressID!=0) { g_source_remove(priv->longPressID); priv->longPressID=0; } if(!clutter_actor_contains(actor, clutter_event_get_source(inEvent))) { return(CLUTTER_EVENT_PROPAGATE); } /* Exclude any button-mask so that we can compare * the press and release states properly */ modifierState=clutter_event_get_state(inEvent) & ~(CLUTTER_BUTTON1_MASK | CLUTTER_BUTTON2_MASK | CLUTTER_BUTTON3_MASK | CLUTTER_BUTTON4_MASK | CLUTTER_BUTTON5_MASK); /* If press and release states don't match we simply ignore * modifier keys. i.e. modifier keys are expected to be pressed * throughout the whole click */ if(modifierState!=priv->modifierState) priv->modifierState=0; _xfdashboard_click_action_set_pressed(self, FALSE); g_signal_emit(self, XfdashboardClickActionSignals[SIGNAL_CLICKED], 0, actor); break; case CLUTTER_MOTION: case CLUTTER_TOUCH_UPDATE: { gfloat motionX, motionY; gfloat deltaX, deltaY; if(!priv->isHeld) return(CLUTTER_EVENT_PROPAGATE); clutter_event_get_coords (inEvent, &motionX, &motionY); deltaX=ABS(motionX-priv->pressX); deltaY=ABS(motionY-priv->pressY); if(deltaX>priv->dragThreshold || deltaY>priv->dragThreshold) { _xfdashboard_click_action_cancel_long_press(self); } } break; default: break; } /* This is line changed in returning CLUTTER_EVENT_PROPAGATE * instead of CLUTTER_EVENT_STOP */ return(CLUTTER_EVENT_PROPAGATE); }
/* Set new active view and deactive current one */ static void _xfdashboard_viewpad_activate_view(XfdashboardViewpad *self, XfdashboardView *inView) { XfdashboardViewpadPrivate *priv; gfloat x, y; g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self)); g_return_if_fail(inView==NULL || XFDASHBOARD_IS_VIEW(inView)); priv=self->priv; /* Only set value if it changes */ if(inView==priv->activeView) return; /* Check if view is a child of this actor */ if(inView && clutter_actor_contains(CLUTTER_ACTOR(self), CLUTTER_ACTOR(inView))==FALSE) { g_warning(_("View %s is not a child of %s and cannot be activated"), G_OBJECT_TYPE_NAME(inView), G_OBJECT_TYPE_NAME(self)); return; } /* Only allow enabled views to be activated */ if(inView && !xfdashboard_view_get_enabled(inView)) { g_warning(_("Cannot activate disabled view %s at %s"), G_OBJECT_TYPE_NAME(inView), G_OBJECT_TYPE_NAME(self)); return; } /* Deactivate current view */ if(priv->activeView) { /* Hide current view and emit signal before and after deactivation */ g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_DEACTIVATING], 0, priv->activeView); g_signal_emit_by_name(priv->activeView, "deactivating"); clutter_actor_hide(CLUTTER_ACTOR(priv->activeView)); g_debug("Deactivated view %s", G_OBJECT_TYPE_NAME(priv->activeView)); g_signal_emit_by_name(priv->activeView, "deactivated"); g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_DEACTIVATED], 0, priv->activeView); g_object_unref(priv->activeView); priv->activeView=NULL; } /* Activate new view (if available) by showing new view, setting up * scrollbars and emitting signal before and after activation. * Prevent signal handling for scrollbars' "value-changed" as it will * mess up with clipping and viewport. We only need to set value of * scrollbars but we do not need to handle the changed value. */ if(inView) { priv->activeView=g_object_ref(inView); g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_ACTIVATING], 0, priv->activeView); g_signal_emit_by_name(priv->activeView, "activating"); g_signal_handlers_block_by_func(priv->hScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); g_signal_handlers_block_by_func(priv->vScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); x=y=0.0f; clutter_actor_get_clip(CLUTTER_ACTOR(priv->activeView), &x, &y, NULL, NULL); _xfdashboard_viewpad_update_scrollbars(self); xfdashboard_scrollbar_set_value(XFDASHBOARD_SCROLLBAR(priv->hScrollbar), x); xfdashboard_scrollbar_set_value(XFDASHBOARD_SCROLLBAR(priv->vScrollbar), y); _xfdashboard_viewpad_update_view_viewport(self); clutter_actor_show(CLUTTER_ACTOR(priv->activeView)); g_debug("Activated view %s", G_OBJECT_TYPE_NAME(priv->activeView)); g_signal_handlers_unblock_by_func(priv->hScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); g_signal_handlers_unblock_by_func(priv->vScrollbar, _xfdashboard_viewpad_on_scrollbar_value_changed, self); g_signal_emit_by_name(priv->activeView, "activated"); g_signal_emit(self, XfdashboardViewpadSignals[SIGNAL_VIEW_ACTIVATED], 0, priv->activeView); } /* Notify about property change */ g_object_notify_by_pspec(G_OBJECT(self), XfdashboardViewpadProperties[PROP_ACTIVE_VIEW]); }