forked from enlightenment/enlightenment
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
This commit is contained in:
parent
d2fce4ce27
commit
5c00c1009b
|
@ -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
|
||||
;
|
||||
}
|
||||
|
||||
////////////////////////////////////
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 *
|
||||
|
|
Loading…
Reference in New Issue