diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index 8165bcf5d..9177f1095 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -1628,6 +1628,15 @@ typedef enum CLUTTER_PHASE_BUBBLE, } ClutterEventPhase; +typedef enum +{ + CLUTTER_GRAB_STATE_NONE = 0, + CLUTTER_GRAB_STATE_POINTER = 1 << 0, + CLUTTER_GRAB_STATE_KEYBOARD = 1 << 1, + CLUTTER_GRAB_STATE_ALL = (CLUTTER_GRAB_STATE_POINTER | + CLUTTER_GRAB_STATE_KEYBOARD), +} ClutterGrabState; + G_END_DECLS #endif /* __CLUTTER_ENUMS_H__ */ diff --git a/clutter/clutter/clutter-seat-private.h b/clutter/clutter/clutter-seat-private.h index 2adb7bcd6..da6349e66 100644 --- a/clutter/clutter/clutter-seat-private.h +++ b/clutter/clutter/clutter-seat-private.h @@ -28,4 +28,9 @@ CLUTTER_EXPORT void clutter_seat_destroy (ClutterSeat *seat); +ClutterGrabState clutter_seat_grab (ClutterSeat *seat, + uint32_t time); +void clutter_seat_ungrab (ClutterSeat *seat, + uint32_t time); + #endif /* CLUTTER_SEAT_PRIVATE_H */ diff --git a/clutter/clutter/clutter-seat.c b/clutter/clutter/clutter-seat.c index 3e7435fd9..121304297 100644 --- a/clutter/clutter/clutter-seat.c +++ b/clutter/clutter/clutter-seat.c @@ -705,3 +705,27 @@ clutter_seat_destroy (ClutterSeat *seat) g_object_run_dispose (G_OBJECT (seat)); g_object_unref (seat); } + +ClutterGrabState +clutter_seat_grab (ClutterSeat *seat, + uint32_t time) +{ + ClutterSeatClass *seat_class; + + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + if (seat_class->grab) + return seat_class->grab (seat, time); + else + return CLUTTER_GRAB_STATE_ALL; +} + +void +clutter_seat_ungrab (ClutterSeat *seat, + uint32_t time) +{ + ClutterSeatClass *seat_class; + + seat_class = CLUTTER_SEAT_GET_CLASS (seat); + if (seat_class->ungrab) + return seat_class->ungrab (seat, time); +} diff --git a/clutter/clutter/clutter-seat.h b/clutter/clutter/clutter-seat.h index 5c5dfe6eb..5195b6c8b 100644 --- a/clutter/clutter/clutter-seat.h +++ b/clutter/clutter/clutter-seat.h @@ -97,6 +97,11 @@ struct _ClutterSeatClass graphene_point_t *coords, ClutterModifierType *modifiers); + ClutterGrabState (* grab) (ClutterSeat *seat, + uint32_t time); + void (* ungrab) (ClutterSeat *seat, + uint32_t time); + /* Virtual devices */ ClutterVirtualInputDevice * (* create_virtual_device) (ClutterSeat *seat, ClutterInputDeviceType device_type); diff --git a/src/backends/x11/meta-seat-x11.c b/src/backends/x11/meta-seat-x11.c index 0cfa2e510..5cab92e4b 100644 --- a/src/backends/x11/meta-seat-x11.c +++ b/src/backends/x11/meta-seat-x11.c @@ -71,6 +71,7 @@ struct _MetaSeatX11 int pointer_id; int keyboard_id; int opcode; + ClutterGrabState grab_state; guint has_touchscreens : 1; guint touch_mode : 1; guint has_pointer_focus : 1; @@ -1652,6 +1653,56 @@ meta_touch_info_free (MetaTouchInfo *touch_info) g_free (touch_info); } +static ClutterGrabState +meta_seat_x11_grab (ClutterSeat *seat, + uint32_t time) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + MetaBackend *backend = meta_get_backend (); + ClutterGrabState state = CLUTTER_GRAB_STATE_NONE; + + g_return_val_if_fail (seat_x11->grab_state == CLUTTER_GRAB_STATE_NONE, + seat_x11->grab_state); + + if (meta_backend_grab_device (backend, + META_VIRTUAL_CORE_POINTER_ID, + time)) + state |= CLUTTER_GRAB_STATE_POINTER; + + if (meta_backend_grab_device (backend, + META_VIRTUAL_CORE_KEYBOARD_ID, + time)) + state |= CLUTTER_GRAB_STATE_KEYBOARD; + + seat_x11->grab_state = state; + + return state; +} + +static void +meta_seat_x11_ungrab (ClutterSeat *seat, + uint32_t time) +{ + MetaSeatX11 *seat_x11 = META_SEAT_X11 (seat); + MetaBackend *backend = meta_get_backend (); + + if ((seat_x11->grab_state & CLUTTER_GRAB_STATE_POINTER) != 0) + { + meta_backend_ungrab_device (backend, + META_VIRTUAL_CORE_POINTER_ID, + time); + } + + if ((seat_x11->grab_state & CLUTTER_GRAB_STATE_KEYBOARD) != 0) + { + meta_backend_ungrab_device (backend, + META_VIRTUAL_CORE_KEYBOARD_ID, + time); + } + + seat_x11->grab_state = CLUTTER_GRAB_STATE_NONE; +} + static void meta_seat_x11_class_init (MetaSeatX11Class *klass) { @@ -1673,6 +1724,8 @@ meta_seat_x11_class_init (MetaSeatX11Class *klass) seat_class->warp_pointer = meta_seat_x11_warp_pointer; seat_class->handle_event_post = meta_seat_x11_handle_event_post; seat_class->query_state = meta_seat_x11_query_state; + seat_class->grab = meta_seat_x11_grab; + seat_class->ungrab = meta_seat_x11_ungrab; props[PROP_OPCODE] = g_param_spec_int ("opcode",