[PATCH weston 4/5] data-device: Implement compositor-chosen actions
Jonas Ã…dahl
jadahl at gmail.com
Tue Dec 15 18:52:18 PST 2015
On Tue, Dec 15, 2015 at 06:56:26PM +0100, Carlos Garnacho wrote:
> Set up a keyboard grab during drag-and-drop, so we can translate
> modifiers into preferred actions. The compositor chosen action
> is stored in the current weston_data_source in order to make it
> accessible to the source/offer at the time of calculating the new
> action, but would conceptually be part of weston_drag.
>
> The mapping has been made similar to what GTK+/QT usually do, the
> shift key defaults to "move" and ctrl defaults to "copy".
>
> Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
> ---
> src/compositor.h | 1 +
> src/data-device.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 62 insertions(+)
>
> diff --git a/src/compositor.h b/src/compositor.h
> index 9aa0150..a8bc19d 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -309,6 +309,7 @@ struct weston_data_source {
> struct weston_data_offer *offer;
> bool accepted;
> uint32_t dnd_actions;
> + uint32_t compositor_action;
> uint32_t current_dnd_action;
>
> void (*accept)(struct weston_data_source *source,
> diff --git a/src/data-device.c b/src/data-device.c
> index 9b9f15f..df6a29d 100644
> --- a/src/data-device.c
> +++ b/src/data-device.c
> @@ -44,6 +44,7 @@ struct weston_drag {
> struct weston_view *icon;
> struct wl_listener icon_destroy_listener;
> int32_t dx, dy;
> + struct weston_keyboard_grab keyboard_grab;
> };
>
> struct weston_pointer_drag {
> @@ -104,6 +105,9 @@ data_offer_choose_action(struct weston_data_offer *offer)
> if (!available_actions)
> return 0;
>
> + if (offer->source->compositor_action & available_actions)
> + return offer->source->compositor_action;
> +
> /* If the dest side has a preferred DnD action, use it */
> if ((offer->preferred_dnd_action & available_actions) != 0)
> return offer->preferred_dnd_action;
> @@ -471,9 +475,11 @@ static void
> data_device_end_pointer_drag_grab(struct weston_pointer_drag *drag)
> {
> struct weston_pointer *pointer = drag->grab.pointer;
> + struct weston_keyboard *keyboard = drag->base.keyboard_grab.keyboard;
>
> data_device_end_drag_grab(&drag->base, pointer->seat);
> weston_pointer_end_grab(pointer);
> + weston_keyboard_end_grab(keyboard);
> free(drag);
> }
>
> @@ -531,9 +537,11 @@ static void
> data_device_end_touch_drag_grab(struct weston_touch_drag *drag)
> {
> struct weston_touch *touch = drag->grab.touch;
> + struct weston_keyboard *keyboard = drag->base.keyboard_grab.keyboard;
>
> data_device_end_drag_grab(&drag->base, touch->seat);
> weston_touch_end_grab(touch);
> + weston_keyboard_end_grab(keyboard);
> free(drag);
> }
>
> @@ -625,6 +633,48 @@ static const struct weston_touch_grab_interface touch_drag_grab_interface = {
> };
>
> static void
> +drag_grab_keyboard_key(struct weston_keyboard_grab *grab,
> + uint32_t time, uint32_t key, uint32_t state)
> +{
> +}
> +
> +static void
> +drag_grab_keyboard_modifiers(struct weston_keyboard_grab *grab,
> + uint32_t serial, uint32_t mods_depressed,
> + uint32_t mods_latched,
> + uint32_t mods_locked, uint32_t group)
> +{
> + struct weston_keyboard *keyboard = grab->keyboard;
> + struct weston_drag *drag =
> + container_of(grab, struct weston_drag, keyboard_grab);
> + uint32_t compositor_action;
> +
> + if (mods_depressed & (1 << keyboard->xkb_info->shift_mod))
> + compositor_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
> + else if (mods_depressed & (1 << keyboard->xkb_info->ctrl_mod))
> + compositor_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
> + else
> + compositor_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
> +
> + drag->data_source->compositor_action = compositor_action;
> +
> + if (drag->data_source->offer)
> + data_offer_update_action(drag->data_source->offer);
> +}
> +
> +static void
> +drag_grab_keyboard_cancel(struct weston_keyboard_grab *grab)
> +{
> + /* FIXME: we don't know here whether we're a touch or a pointer drag */
What is it that should be fixed, when we know? End the grab?
I think we can determine whether its a touch or a pointer grab by
checking the current grab, i.e. something like:
struct weston_pointer *pointer = grab->keyboard->seat->pointer_state;
struct weston_touch *touch = grab->keyboard->seat->touch_state;
if (pointer && pointer->grab->interface == &pointer_grab_interface)
.. it's a pointer grab ...
else if (touch && touch->grab->interface == &touch_grab_interface)
.. it's a touch grab ...
Jonas
> +}
> +
> +static const struct weston_keyboard_grab_interface keyboard_drag_grab_interface = {
> + drag_grab_keyboard_key,
> + drag_grab_keyboard_modifiers,
> + drag_grab_keyboard_cancel
> +};
> +
> +static void
> destroy_pointer_data_device_source(struct wl_listener *listener, void *data)
> {
> struct weston_pointer_drag *drag = container_of(listener,
> @@ -649,12 +699,15 @@ weston_pointer_start_drag(struct weston_pointer *pointer,
> struct wl_client *client)
> {
> struct weston_pointer_drag *drag;
> + struct weston_keyboard *keyboard =
> + weston_seat_get_keyboard(pointer->seat);
>
> drag = zalloc(sizeof *drag);
> if (drag == NULL)
> return -1;
>
> drag->grab.interface = &pointer_drag_grab_interface;
> + drag->base.keyboard_grab.interface = &keyboard_drag_grab_interface;
> drag->base.client = client;
> drag->base.data_source = source;
>
> @@ -684,7 +737,10 @@ weston_pointer_start_drag(struct weston_pointer *pointer,
> }
>
> weston_pointer_clear_focus(pointer);
> + weston_keyboard_set_focus(keyboard, NULL);
> +
> weston_pointer_start_grab(pointer, &drag->grab);
> + weston_keyboard_start_grab(keyboard, &drag->base.keyboard_grab);
>
> return 0;
> }
> @@ -705,6 +761,8 @@ weston_touch_start_drag(struct weston_touch *touch,
> struct wl_client *client)
> {
> struct weston_touch_drag *drag;
> + struct weston_keyboard *keyboard =
> + weston_seat_get_keyboard(touch->seat);
>
> drag = zalloc(sizeof *drag);
> if (drag == NULL)
> @@ -739,7 +797,10 @@ weston_touch_start_drag(struct weston_touch *touch,
> &drag->base.data_source_listener);
> }
>
> + weston_keyboard_set_focus(keyboard, NULL);
> +
> weston_touch_start_grab(touch, &drag->grab);
> + weston_keyboard_start_grab(keyboard, &drag->base.keyboard_grab);
>
> drag_grab_touch_focus(drag);
>
> --
> 2.5.0
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list