diff --git a/src/lib/ecore_wayland/ecore_wl_input.c b/src/lib/ecore_wayland/ecore_wl_input.c index 4661891500..aa0ed7074a 100644 --- a/src/lib/ecore_wayland/ecore_wl_input.c +++ b/src/lib/ecore_wayland/ecore_wl_input.c @@ -165,6 +165,28 @@ ecore_wl_input_ungrab(Ecore_Wl_Input *input) input->grab_button = 0; } +/* NB: This function should be called just before shell move and shell resize + * functions. Those requests will trigger a mouse/touch implicit grab on the + * compositor that will prevent the respective mouse/touch up events being + * released after the end of the operation. This function checks if such grab + * is in place for those windows and, if so, emit the respective mouse up + * event. It's a workaround to the fact that wayland doesn't inform the + * application about this move or resize grab being finished. + */ +void +_ecore_wl_input_grab_release(Ecore_Wl_Input *input, Ecore_Wl_Window *win) +{ + LOGFN(__FILE__, __LINE__, __FUNCTION__); + + if (!input) return; + if (input->grab != win) return; + + _ecore_wl_input_mouse_up_send(input, input->pointer_focus, + 0, input->grab_button, input->grab_timestamp); + + ecore_wl_input_ungrab(input); +} + static void _pointer_update_stop(Ecore_Wl_Input *input) { @@ -497,7 +519,10 @@ _ecore_wl_input_cb_pointer_button(void *data, struct wl_pointer *pointer EINA_UN if (state) { if ((input->pointer_focus) && (!input->grab) && (state)) - ecore_wl_input_grab(input, input->pointer_focus, button); + { + ecore_wl_input_grab(input, input->pointer_focus, button); + input->grab_timestamp = timestamp; + } if (input->pointer_focus) _ecore_wl_input_mouse_down_send(input, input->pointer_focus, @@ -861,37 +886,6 @@ _ecore_wl_input_cb_pointer_enter(void *data, struct wl_pointer *pointer EINA_UNU _ecore_wl_input_mouse_in_send(input, win, input->timestamp); } - - /* NB: This whole 'if' below is a major HACK due to wayland's stupidness - * of not sending a mouse_up (or any notification at all for that matter) - * when a move or resize grab is finished */ - if (input->grab) - { - /* NB: This COULD mean a move has finished, or it could mean that - * a 'drag' is being done to a different surface */ - - if ((input->grab == win) && (win->moving)) - { - /* NB: 'Fake' a mouse_up for move finished */ - win->moving = EINA_FALSE; - _ecore_wl_input_mouse_up_send(input, win, 0, - BTN_LEFT, input->timestamp); - - if ((input->grab) && (input->grab_button == BTN_LEFT)) - ecore_wl_input_ungrab(input); - } - else if ((input->grab == win) && (win->resizing)) - { - /* NB: 'Fake' a mouse_up for resize finished */ - win->resizing = EINA_FALSE; - _ecore_wl_input_mouse_up_send(input, win, 0, - BTN_LEFT, input->timestamp); - - if ((input->grab) && (input->grab_button == BTN_LEFT)) - ecore_wl_input_ungrab(input); - } - /* FIXME: Test d-n-d and potentially add needed case here */ - } } static void @@ -1011,6 +1005,12 @@ _ecore_wl_input_cb_touch_down(void *data, struct wl_touch *touch EINA_UNUSED, un _ecore_wl_input_mouse_move_send(input, input->pointer_focus, timestamp, id); _ecore_wl_input_cb_pointer_enter(data, NULL, serial, surface, x, y); + if ((input->touch_focus) && (!input->grab)) + { + ecore_wl_input_grab(input, input->pointer_focus, BTN_LEFT); + input->grab_timestamp = timestamp; + } + _ecore_wl_input_mouse_down_send(input, input->touch_focus, id, 0, timestamp); } @@ -1029,6 +1029,8 @@ _ecore_wl_input_cb_touch_up(void *data, struct wl_touch *touch EINA_UNUSED, unsi input->display->serial = serial; _ecore_wl_input_mouse_up_send(input, input->touch_focus, id, 0, timestamp); + if ((input->grab) && (input->grab_button == BTN_LEFT)) + ecore_wl_input_ungrab(input); } static void diff --git a/src/lib/ecore_wayland/ecore_wl_private.h b/src/lib/ecore_wayland/ecore_wl_private.h index 80b454c0c2..ecb54f0467 100644 --- a/src/lib/ecore_wayland/ecore_wl_private.h +++ b/src/lib/ecore_wayland/ecore_wl_private.h @@ -129,8 +129,6 @@ struct _Ecore_Wl_Window /* Eina_Bool resize_scheduled : 1; */ Eina_Bool alpha : 1; Eina_Bool transparent : 1; - Eina_Bool moving : 1; - Eina_Bool resizing : 1; Eina_Bool has_buffer : 1; Ecore_Wl_Window_Type type; @@ -183,6 +181,7 @@ struct _Ecore_Wl_Input Ecore_Wl_Window *grab; unsigned int grab_button; + unsigned int grab_timestamp; Ecore_Wl_Dnd_Source *drag_source; Ecore_Wl_Dnd_Source *selection_source; @@ -258,6 +257,7 @@ void _ecore_wl_output_del(Ecore_Wl_Output *output); void _ecore_wl_input_add(Ecore_Wl_Display *ewd, unsigned int id); void _ecore_wl_input_del(Ecore_Wl_Input *input); void _ecore_wl_input_pointer_xy_get(int *x, int *y); +void _ecore_wl_input_grab_release(Ecore_Wl_Input *input, Ecore_Wl_Window *win); void _ecore_wl_dnd_add(Ecore_Wl_Input *input, struct wl_data_device *data_device, struct wl_data_offer *offer); void _ecore_wl_dnd_enter(void *data, struct wl_data_device *data_device, unsigned int timestamp, struct wl_surface *surface, int x, int y, struct wl_data_offer *offer); diff --git a/src/lib/ecore_wayland/ecore_wl_window.c b/src/lib/ecore_wayland/ecore_wl_window.c index e9ecd795e4..127563575d 100644 --- a/src/lib/ecore_wayland/ecore_wl_window.c +++ b/src/lib/ecore_wayland/ecore_wl_window.c @@ -136,8 +136,6 @@ ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y) if (!win) return; - win->moving = EINA_TRUE; - ecore_wl_window_update_location(win, x, y); if (win->shell_surface) @@ -155,6 +153,7 @@ ecore_wl_window_move(Ecore_Wl_Window *win, int x, int y) if ((!input) || (!input->seat)) return; + _ecore_wl_input_grab_release(input, win); wl_shell_surface_move(win->shell_surface, input->seat, input->display->serial); } @@ -167,7 +166,6 @@ ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location) if (!win) return; - win->resizing = EINA_TRUE; ecore_wl_window_update_size(win, w, h); if (win->shell_surface) @@ -185,6 +183,7 @@ ecore_wl_window_resize(Ecore_Wl_Window *win, int w, int h, int location) if ((!input) || (!input->seat)) return; + _ecore_wl_input_grab_release(input, win); wl_shell_surface_resize(win->shell_surface, input->seat, input->display->serial, location); }