diff --git a/clutter/clutter/clutter-grab.h b/clutter/clutter/clutter-grab.h index 8c8704649..5d23d634b 100644 --- a/clutter/clutter/clutter-grab.h +++ b/clutter/clutter/clutter-grab.h @@ -35,4 +35,7 @@ typedef struct _ClutterGrab ClutterGrab; CLUTTER_EXPORT void clutter_grab_dismiss (ClutterGrab *grab); +CLUTTER_EXPORT +ClutterGrabState clutter_grab_get_seat_state (ClutterGrab *grab); + #endif /* CLUTTER_GRAB_H */ diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 19c8ebd70..449f61676 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -62,6 +62,7 @@ #include "clutter-paint-volume-private.h" #include "clutter-pick-context-private.h" #include "clutter-private.h" +#include "clutter-seat-private.h" #include "clutter-stage-manager-private.h" #include "clutter-stage-private.h" #include "clutter-stage-view-private.h" @@ -115,6 +116,7 @@ struct _ClutterStagePrivate ClutterActor *key_focused_actor; ClutterGrab *topmost_grab; + ClutterGrabState grab_state; GQueue *event_queue; @@ -3863,6 +3865,18 @@ clutter_stage_grab (ClutterStage *stage, g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL); g_return_val_if_fail (CLUTTER_IS_ACTOR (actor), NULL); + if (!priv->topmost_grab) + { + ClutterMainContext *context; + ClutterSeat *seat; + + /* First grab in the chain, trigger a backend grab too */ + context = _clutter_context_get_default (); + seat = clutter_backend_get_default_seat (context->backend); + priv->grab_state = + clutter_seat_grab (seat, clutter_get_current_event_time ()); + } + grab = g_new0 (ClutterGrab, 1); grab->stage = stage; grab->actor = actor; @@ -3908,6 +3922,18 @@ clutter_stage_unlink_grab (ClutterStage *stage, clutter_actor_detach_grab (grab->actor, grab); + if (!priv->topmost_grab) + { + ClutterMainContext *context; + ClutterSeat *seat; + + /* This was the last remaining grab, trigger a backend ungrab */ + context = _clutter_context_get_default (); + seat = clutter_backend_get_default_seat (context->backend); + clutter_seat_ungrab (seat, clutter_get_current_event_time ()); + priv->grab_state = CLUTTER_GRAB_STATE_NONE; + } + grab->next = NULL; grab->prev = NULL; } @@ -3921,6 +3947,14 @@ clutter_grab_dismiss (ClutterGrab *grab) g_free (grab); } +ClutterGrabState +clutter_grab_get_seat_state (ClutterGrab *grab) +{ + g_return_val_if_fail (grab != NULL, CLUTTER_GRAB_STATE_NONE); + + return grab->stage->priv->grab_state; +} + ClutterActor * clutter_stage_get_grab_actor (ClutterStage *stage) {