From: Mike Blumenkrantz Date: Tue, 21 Jul 2015 18:27:29 +0000 (-0400) Subject: redo wl compositor key eventing X-Git-Tag: upstream/0.20.0~529 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5c00c1009b84a42e9e1643fe98da867092f6808f;p=platform%2Fupstream%2Fenlightenment.git redo wl compositor key eventing * break out key callbacks into EINTERNs * remove extraneous/unused mouse event handlers * enforce wl modifier updating in all cases * ensure keybinds are activated before wl clients receive input - block wl client input during grabs fixes T2565 --- diff --git a/src/bin/e_comp_canvas.c b/src/bin/e_comp_canvas.c index 7300c18..66b9b1b 100644 --- a/src/bin/e_comp_canvas.c +++ b/src/bin/e_comp_canvas.c @@ -94,7 +94,13 @@ _e_comp_canvas_cb_mouse_wheel(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Obj static Eina_Bool _e_comp_cb_key_down(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event_Key *ev) { - if (e_menu_grab_window_get()) return ECORE_CALLBACK_RENEW; + if (e_menu_grab_window_get() || e_comp->input_key_grabs) + { +#ifdef HAVE_WAYLAND + e_comp_wl_key_down(ev); +#endif + return ECORE_CALLBACK_RENEW; + } if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root)) { E_Client *ec; @@ -107,15 +113,29 @@ _e_comp_cb_key_down(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event */ if ((!ec) || (ev->event_window != e_comp->ee_win)) return ECORE_CALLBACK_RENEW; } - return !e_bindings_key_down_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev); + return !e_bindings_key_down_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev) +#ifdef HAVE_WAYLAND + && !e_comp_wl_key_down(ev) +#endif + ; } static Eina_Bool _e_comp_cb_key_up(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event_Key *ev) { - if (e_menu_grab_window_get()) return ECORE_CALLBACK_RENEW; + if (e_menu_grab_window_get() || e_comp->input_key_grabs) + { +#ifdef HAVE_WAYLAND + e_comp_wl_key_up(ev); +#endif + return ECORE_CALLBACK_RENEW; + } if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root)) return ECORE_CALLBACK_PASS_ON; - return !e_bindings_key_up_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev); + return !e_bindings_key_up_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev) +#ifdef HAVE_WAYLAND + && !e_comp_wl_key_up(ev) +#endif + ; } //////////////////////////////////// diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index a3f8ebf..43b8066 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -843,143 +843,13 @@ _e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Ev return ECORE_CALLBACK_RENEW; } -static void -_e_comp_wl_cb_key_down(void *event) -{ - E_Comp_Wl_Data *cdata; - E_Client *ec; - Ecore_Event_Key *ev; - uint32_t serial, *end, *k, keycode; - - ev = event; - if (ev->window != e_comp->ee_win) return; - - keycode = (ev->keycode - 8); - if (!(cdata = e_comp->wl_comp_data)) return; - -#ifndef E_RELEASE_BUILD - if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) && - ((ev->modifiers & ECORE_EVENT_MODIFIER_ALT) || - (ev->modifiers & ECORE_EVENT_MODIFIER_ALTGR)) && - eina_streq(ev->key, "BackSpace")) - exit(0); -#endif - - end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); - - for (k = cdata->kbd.keys.data; k < end; k++) - { - /* ignore server-generated key repeats */ - if (*k == keycode) return; - } - - cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; - if (!(k = wl_array_add(&cdata->kbd.keys, sizeof(*k)))) - { - DBG("wl_array_add: Out of memory\n"); - return; - } - *k = keycode; - - if ((ec = e_client_focused_get())) - { - if (ec->comp_data->surface && (!e_client_action_get()) && (!e_comp->input_key_grabs)) - { - struct wl_client *wc; - struct wl_resource *res; - Eina_List *l; - - if (eina_list_count(cdata->kbd.resources)) - { - wc = wl_resource_get_client(ec->comp_data->surface); - serial = wl_display_next_serial(cdata->wl.disp); - EINA_LIST_FOREACH(cdata->kbd.resources, l, res) - { - if (wl_resource_get_client(res) != wc) continue; - wl_keyboard_send_key(res, serial, ev->timestamp, - keycode, WL_KEYBOARD_KEY_STATE_PRESSED); - } - } - } - } - - /* update modifier state */ - e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE); -} - -static void -_e_comp_wl_cb_key_up(void *event) -{ - E_Client *ec; - E_Comp_Wl_Data *cdata; - Ecore_Event_Key *ev; - uint32_t serial, *end, *k, keycode; - struct wl_client *wc = NULL; - struct wl_resource *res; - Eina_List *l; - - ev = event; - if (ev->window != e_comp->ee_win) return; - - keycode = (ev->keycode - 8); - if (!(cdata = e_comp->wl_comp_data)) return; - - end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); - for (k = cdata->kbd.keys.data; k < end; k++) - if (*k == keycode) *k = *--end; - - cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; - - ec = e_client_focused_get(); - if ((ec) && (ec->comp_data->surface) && (!e_client_action_get()) && (!e_comp->input_key_grabs)) - { - wc = wl_resource_get_client(ec->comp_data->surface); - } - - if (eina_list_count(cdata->kbd.resources)) - { - serial = wl_display_next_serial(cdata->wl.disp); - EINA_LIST_FOREACH(cdata->kbd.resources, l, res) - { - if (wc) - { - if (wl_resource_get_client(res) != wc) continue; - } - - wl_keyboard_send_key(res, serial, ev->timestamp, - keycode, WL_KEYBOARD_KEY_STATE_RELEASED); - } - } - - /* update modifier state */ - e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE); -} - -static void -_e_comp_wl_cb_mouse_move(void *event) -{ - E_Comp_Wl_Data *cdata; - Ecore_Event_Mouse_Move *ev; - - if (!(cdata = e_comp->wl_comp_data)) return; - - ev = event; - cdata->ptr.x = wl_fixed_from_int(ev->x); - cdata->ptr.y = wl_fixed_from_int(ev->y); -} - static Eina_Bool -_e_comp_wl_cb_input_event(void *data EINA_UNUSED, int type, void *ev) +_e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Move *ev) { _last_event_time = ecore_loop_time_get(); - if (type == ECORE_EVENT_KEY_DOWN) - _e_comp_wl_cb_key_down(ev); - else if (type == ECORE_EVENT_KEY_UP) - _e_comp_wl_cb_key_up(ev); - else if (type == ECORE_EVENT_MOUSE_MOVE) - _e_comp_wl_cb_mouse_move(ev); - + e_comp->wl_comp_data->ptr.x = wl_fixed_from_int(ev->x); + e_comp->wl_comp_data->ptr.y = wl_fixed_from_int(ev->y); return ECORE_CALLBACK_RENEW; } @@ -2728,18 +2598,8 @@ e_comp_wl_init(void) E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD, _e_comp_wl_cb_comp_object_add, NULL); - E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_DOWN, - _e_comp_wl_cb_input_event, NULL); - E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_UP, - _e_comp_wl_cb_input_event, NULL); - E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, - _e_comp_wl_cb_input_event, NULL); - E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_BUTTON_UP, - _e_comp_wl_cb_input_event, NULL); E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_MOVE, - _e_comp_wl_cb_input_event, NULL); - E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_WHEEL, - _e_comp_wl_cb_input_event, NULL); + _e_comp_wl_cb_mouse_move, NULL); /* add hooks to catch e_client events */ e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, _e_comp_wl_client_cb_new, NULL); @@ -3101,6 +2961,116 @@ e_comp_wl_output_remove(const char *id) } } +EINTERN Eina_Bool +e_comp_wl_key_down(Ecore_Event_Key *ev) +{ + E_Comp_Wl_Data *cdata; + E_Client *ec = NULL; + uint32_t serial, *end, *k, keycode; + + if ((e_comp_>comp_type != E_PIXMAP_TYPE_WL) || (ev->window != e_comp->ee_win)) return EINA_FALSE; + _last_event_time = ecore_loop_time_get(); + + keycode = (ev->keycode - 8); + if (!(cdata = e_comp->wl_comp_data)) return EINA_FALSE; + +#ifndef E_RELEASE_BUILD + if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) && + ((ev->modifiers & ECORE_EVENT_MODIFIER_ALT) || + (ev->modifiers & ECORE_EVENT_MODIFIER_ALTGR)) && + eina_streq(ev->key, "BackSpace")) + exit(0); +#endif + + end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); + + for (k = cdata->kbd.keys.data; k < end; k++) + { + /* ignore server-generated key repeats */ + if (*k == keycode) return EINA_FALSE; + } + + cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; + if (!(k = wl_array_add(&cdata->kbd.keys, sizeof(*k)))) + { + DBG("wl_array_add: Out of memory\n"); + return EINA_FALSE; + } + *k = keycode; + + if ((!e_client_action_get()) && (!e_comp->input_key_grabs) && (!e_menu_grab_window_get())) + { + ec = e_client_focused_get(); + if (ec && ec->comp_data->surface && cdata->kbd.resources) + { + struct wl_client *wc; + struct wl_resource *res; + Eina_List *l; + + wc = wl_resource_get_client(ec->comp_data->surface); + serial = wl_display_next_serial(cdata->wl.disp); + EINA_LIST_FOREACH(cdata->kbd.resources, l, res) + { + if (wl_resource_get_client(res) != wc) continue; + wl_keyboard_send_key(res, serial, ev->timestamp, + keycode, WL_KEYBOARD_KEY_STATE_PRESSED); + } + } + } + + /* update modifier state */ + e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE); + return !!ec; +} + +EINTERN Eina_Bool +e_comp_wl_key_up(Ecore_Event_Key *ev) +{ + E_Client *ec = NULL; + E_Comp_Wl_Data *cdata; + uint32_t serial, *end, *k, keycode; + struct wl_resource *res; + Eina_List *l; + + if ((e_comp_>comp_type != E_PIXMAP_TYPE_WL) || (ev->window != e_comp->ee_win)) return EINA_FALSE; + _last_event_time = ecore_loop_time_get(); + + keycode = (ev->keycode - 8); + if (!(cdata = e_comp->wl_comp_data)) return EINA_FALSE; + + end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k)); + for (k = cdata->kbd.keys.data; k < end; k++) + if (*k == keycode) *k = *--end; + + cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data; + + if ((!e_client_action_get()) && (!e_comp->input_key_grabs) && (!e_menu_grab_window_get())) + { + struct wl_client *wc = NULL; + + ec = e_client_focused_get(); + if (ec && ec->comp_data->surface) + { + wc = wl_resource_get_client(ec->comp_data->surface); + } + + if (wc && cdata->kbd.resources) + { + serial = wl_display_next_serial(cdata->wl.disp); + EINA_LIST_FOREACH(cdata->kbd.resources, l, res) + { + if (wl_resource_get_client(res) != wc) continue; + wl_keyboard_send_key(res, serial, ev->timestamp, + keycode, WL_KEYBOARD_KEY_STATE_RELEASED); + } + } + } + + /* update modifier state */ + e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE); + return !!ec; +} + EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec) { diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h index 736cc90..cb4b7ca 100644 --- a/src/bin/e_comp_wl.h +++ b/src/bin/e_comp_wl.h @@ -320,6 +320,10 @@ E_API struct wl_signal e_comp_wl_surface_create_signal_get(void); E_API double e_comp_wl_idle_time_get(void); E_API Eina_Bool e_comp_wl_output_init(const char *id, const char *make, const char *model, int x, int y, int w, int h, int pw, int ph, unsigned int refresh, unsigned int subpixel, unsigned int transform); E_API void e_comp_wl_output_remove(const char *id); + +EINTERN Eina_Bool e_comp_wl_key_down(Ecore_Event_Key *ev); +EINTERN Eina_Bool e_comp_wl_key_up(Ecore_Event_Key *ev); + # ifndef HAVE_WAYLAND_ONLY EINTERN void e_comp_wl_xwayland_client_queue(E_Client *ec); static inline E_Comp_X_Client_Data *