From bf3c1c6913cf00e12a579a637abb8c4e68233a8c Mon Sep 17 00:00:00 2001 From: Xiong Zhang Date: Mon, 25 Nov 2013 18:42:51 +0800 Subject: [PATCH] distinguish touch screen and pointer dnd in client Data device interface in client just handle with pointer's dnd. If a touch screen trigger dnd, it will use pointer struct like i nput->sx, input->sy, input->pointer_focus. So if pointer is moving when touch screen trigeer a dnd, wrong behaviore will occur. Before touch screen start dnd, system call touch_grab() to mark the following drag and drop operation is generated by touch screen. Defined some common variables in struct input to track dnd. Note, touch screen and pointer can't generate drag and drop at the same time, becuae data device protocol can't identify the drag and drop event is generated by touch screen or pointer. Signed-off-by: Xiong Zhang Reviewed-by: Kristian Hogsberg --- clients/dnd.c | 3 ++- clients/window.c | 65 ++++++++++++++++++++++++++++++++++++++---------- clients/window.h | 6 +++++ 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/clients/dnd.c b/clients/dnd.c index 3bf4b5b2..00739c31 100644 --- a/clients/dnd.c +++ b/clients/dnd.c @@ -483,7 +483,8 @@ dnd_touch_down_handler(struct widget *widget, int_x = (int32_t)x; int_y = (int32_t)y; - create_drag_source(dnd, input, time, int_x, int_y); + if (create_drag_source(dnd, input, time, int_x, int_y) == 0) + touch_grab(input, 0); } static int diff --git a/clients/window.c b/clients/window.c index 83af7ed5..a201ebb4 100644 --- a/clients/window.c +++ b/clients/window.c @@ -320,6 +320,11 @@ struct input { struct wl_data_device *data_device; struct data_offer *drag_offer; struct data_offer *selection_offer; + uint32_t touch_grab; + int32_t touch_grab_id; + float drag_x, drag_y; + struct window *drag_focus; + uint32_t drag_enter_serial; struct { struct xkb_keymap *keymap; @@ -2545,6 +2550,31 @@ input_set_focus_widget(struct input *input, struct widget *focus, } } +void +touch_grab(struct input *input, int32_t touch_id) +{ + input->touch_grab = 1; + input->touch_grab_id = touch_id; +} + +void +touch_ungrab(struct input *input) +{ + struct touch_point *tp, *tmp; + + input->touch_grab = 0; + + wl_list_for_each_safe(tp, tmp, + &input->touch_point_list, link) { + if (tp->id != input->touch_grab_id) + continue; + wl_list_remove(&tp->link); + free(tp); + + return; + } +} + void input_grab(struct input *input, struct widget *widget, uint32_t button) { @@ -3245,11 +3275,14 @@ data_device_enter(void *data, struct wl_data_device *data_device, float y = wl_fixed_to_double(y_w); char **p; - input->pointer_enter_serial = serial; window = wl_surface_get_user_data(surface); - input->pointer_focus = window; - input->sx = x; - input->sy = y; + input->drag_enter_serial = serial; + input->drag_focus = window, + input->drag_x = x; + input->drag_y = y; + + if (!input->touch_grab) + input->pointer_enter_serial = serial; if (offer) { input->drag_offer = wl_data_offer_get_user_data(offer); @@ -3263,7 +3296,6 @@ data_device_enter(void *data, struct wl_data_device *data_device, types_data = NULL; } - window = input->pointer_focus; if (window->data_handler) window->data_handler(window, input, x, y, types_data, window->user_data); @@ -3285,13 +3317,13 @@ data_device_motion(void *data, struct wl_data_device *data_device, uint32_t time, wl_fixed_t x_w, wl_fixed_t y_w) { struct input *input = data; - struct window *window = input->pointer_focus; + struct window *window = input->drag_focus; float x = wl_fixed_to_double(x_w); float y = wl_fixed_to_double(y_w); void *types_data; - input->sx = x; - input->sy = y; + input->drag_x = x; + input->drag_y = y; if (input->drag_offer) types_data = input->drag_offer->types.data; @@ -3307,11 +3339,18 @@ static void data_device_drop(void *data, struct wl_data_device *data_device) { struct input *input = data; - struct window *window = input->pointer_focus; + struct window *window = input->drag_focus; + float x, y; + + x = input->drag_x; + y = input->drag_y; if (window->drop_handler) window->drop_handler(window, input, - input->sx, input->sy, window->user_data); + x, y, window->user_data); + + if (input->touch_grab) + touch_ungrab(input); } static void @@ -3480,7 +3519,7 @@ void input_accept(struct input *input, const char *type) { wl_data_offer_accept(input->drag_offer->offer, - input->pointer_enter_serial, type); + input->drag_enter_serial, type); } static void @@ -3528,8 +3567,8 @@ input_receive_drag_data(struct input *input, const char *mime_type, data_func_t func, void *data) { data_offer_receive_data(input->drag_offer, mime_type, func, data); - input->drag_offer->x = input->sx; - input->drag_offer->y = input->sy; + input->drag_offer->x = input->drag_x; + input->drag_offer->y = input->drag_y; } int diff --git a/clients/window.h b/clients/window.h index 66cf9857..63ed788c 100644 --- a/clients/window.h +++ b/clients/window.h @@ -522,6 +522,12 @@ input_get_position(struct input *input, int32_t *x, int32_t *y); uint32_t input_get_modifiers(struct input *input); +void +touch_grab(struct input *input, int32_t touch_id); + +void +touch_ungrab(struct input *input); + void input_grab(struct input *input, struct widget *widget, uint32_t button);