On Tue, Dec 22, 2015 at 02:33:30AM +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". > > Changes since v1: > - Handle the keyboard grab being cancelled. Initialize new > wl_data_source fields. > > Signed-off-by: Carlos Garnacho <carl...@gnome.org>
Reviewed-by: Jonas Ådahl <jad...@gmail.com> with a couple of minor nits below. > --- > src/compositor.h | 1 + > src/data-device.c | 75 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 76 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; enum wl_data_device_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 045cef5..b3a14a9 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 { > @@ -136,6 +137,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 ((preferred_action & available_actions) != 0) > return preferred_action; > @@ -520,9 +524,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); > } > > @@ -587,9 +593,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); > } > > @@ -681,6 +689,61 @@ 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) > +{ > + struct weston_drag *drag = > + container_of(grab, struct weston_drag, keyboard_grab); > + struct weston_pointer *pointer = grab->keyboard->seat->pointer_state; > + struct weston_touch *touch = grab->keyboard->seat->touch_state; > + > + if (pointer && pointer->grab->interface == > &pointer_drag_grab_interface) { > + struct weston_touch_drag *touch_drag = > + (struct weston_touch_drag *) drag; > + drag_grab_touch_cancel(&touch_drag->grab); > + } else if (touch && touch->grab->interface == > &touch_drag_grab_interface) { > + struct weston_pointer_drag *pointer_drag = > + (struct weston_pointer_drag *) drag; > + drag_grab_cancel(&pointer_drag->grab); > + } > +} > + > +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, > @@ -705,12 +768,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; > > @@ -740,7 +806,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; > } > @@ -761,6 +830,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) > @@ -795,7 +866,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); > > @@ -1030,6 +1104,7 @@ create_data_source(struct wl_client *client, > source->accepted = false; > source->dnd_actions = 0; > source->current_dnd_action = 0; > + source->compositor_action = 0; WL_DATA_DEVICE_ACTION_NONE. Jonas > > wl_array_init(&source->mime_types); > > -- > 2.5.0 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel