forked from enlightenment/efl
efl-wl: create and maintain xserver-based keymap and keyboard states under x11
when run in a non-wayland environment, it's necessary to do some extra work in order to guarantee that the keymap remains the same in the compositor as in the xserver and to also guarantee that modifier states are accurately applied even when the compositor is not actively focused fix T6631
This commit is contained in:
parent
6e4c3b0445
commit
a32735e9a7
|
@ -3807,6 +3807,7 @@ EFL_OPTIONAL_INTERNAL_DEPEND_PKG([EFL_WL], [${want_x11_any}], [ecore_x])
|
|||
|
||||
EFL_DEPEND_PKG([EFL_WL], [WAYLAND],
|
||||
[wayland-server >= 1.11.0 xkbcommon >= 0.6.0])
|
||||
EFL_OPTIONAL_DEPEND_PKG([EFL_WL], [${want_x11_any}], [XKBCOMMONX11], [xkbcommon-x11])
|
||||
|
||||
EFL_EVAL_PKGS([EFL_WL])
|
||||
|
||||
|
|
|
@ -356,3 +356,53 @@ drag_grab_button(Comp_Seat *s,
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECORE_X
|
||||
static xkb_mod_index_t x11_kbd_shift_mod;
|
||||
static xkb_mod_index_t x11_kbd_caps_mod;
|
||||
static xkb_mod_index_t x11_kbd_ctrl_mod;
|
||||
static xkb_mod_index_t x11_kbd_alt_mod;
|
||||
static xkb_mod_index_t x11_kbd_mod2_mod;
|
||||
static xkb_mod_index_t x11_kbd_mod3_mod;
|
||||
static xkb_mod_index_t x11_kbd_super_mod;
|
||||
static xkb_mod_index_t x11_kbd_mod5_mod;
|
||||
|
||||
static void
|
||||
keymap_mods_init(struct xkb_keymap *keymap)
|
||||
{
|
||||
x11_kbd_shift_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
|
||||
x11_kbd_caps_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
|
||||
x11_kbd_ctrl_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
|
||||
x11_kbd_alt_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT);
|
||||
x11_kbd_mod2_mod = xkb_keymap_mod_get_index(keymap, "Mod2");
|
||||
x11_kbd_mod3_mod = xkb_keymap_mod_get_index(keymap, "Mod3");
|
||||
x11_kbd_super_mod = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
|
||||
x11_kbd_mod5_mod = xkb_keymap_mod_get_index(keymap, "Mod5");
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
get_xkb_mod_mask(uint32_t in)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
|
||||
if ((in & ECORE_X_MODIFIER_SHIFT) && x11_kbd_shift_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_shift_mod);
|
||||
if ((in & ECORE_X_LOCK_CAPS) && x11_kbd_caps_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_caps_mod);
|
||||
if ((in & ECORE_X_MODIFIER_CTRL) && x11_kbd_ctrl_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_ctrl_mod);
|
||||
if ((in & ECORE_X_MODIFIER_ALT) && x11_kbd_alt_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_alt_mod);
|
||||
if ((in & ECORE_X_LOCK_NUM) && x11_kbd_mod2_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_mod2_mod);
|
||||
if ((in & ECORE_X_LOCK_SCROLL) && x11_kbd_mod3_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_mod3_mod);
|
||||
if ((in & ECORE_X_MODIFIER_WIN) && x11_kbd_super_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_super_mod);
|
||||
if ((in & ECORE_X_MODIFIER_ALTGR) && x11_kbd_mod5_mod != XKB_MOD_INVALID)
|
||||
ret |= (1 << x11_kbd_mod5_mod);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3710,6 +3710,10 @@ seat_keymap_update(Comp_Seat *s)
|
|||
Eina_Tmpstr *file;
|
||||
xkb_mod_mask_t latched = 0, locked = 0;
|
||||
|
||||
#ifdef HAVE_ECORE_X
|
||||
if (!x11_kbd_keymap)
|
||||
{
|
||||
#endif
|
||||
if (s->kbd.keymap_mem) munmap(s->kbd.keymap_mem, s->kbd.keymap_mem_size);
|
||||
if (s->kbd.keymap_fd > -1) close(s->kbd.keymap_fd);
|
||||
|
||||
|
@ -3729,7 +3733,9 @@ seat_keymap_update(Comp_Seat *s)
|
|||
|
||||
s->kbd.state = xkb_state_new(s->kbd.keymap);
|
||||
xkb_state_update_mask(s->kbd.state, 0, latched, locked, 0, 0, 0);
|
||||
|
||||
#ifdef HAVE_ECORE_X
|
||||
}
|
||||
#endif
|
||||
str = xkb_map_get_as_string(s->kbd.keymap);
|
||||
s->kbd.keymap_mem_size = strlen(str) + 1;
|
||||
s->kbd.keymap_fd = eina_file_mkstemp("comp-keymapXXXXXX", &file);
|
||||
|
@ -4395,6 +4401,11 @@ comp_device_caps_update(Comp_Seat *s)
|
|||
{
|
||||
if (s->keyboard)
|
||||
{
|
||||
#ifdef HAVE_ECORE_X
|
||||
if ((!s->c->parent_disp) && ecore_x_display_get())
|
||||
x11_kbd_apply(s);
|
||||
else
|
||||
#endif
|
||||
seat_keymap_create(s);
|
||||
seat_kbd_repeat_rate_update(s);
|
||||
}
|
||||
|
@ -4462,9 +4473,16 @@ comp_seats_proxy(Comp *c)
|
|||
if (s->kbd.keymap) xkb_keymap_ref(s->kbd.keymap);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_ECORE_X
|
||||
if ((!s->c->parent_disp) && ecore_x_display_get())
|
||||
x11_kbd_apply(s);
|
||||
else
|
||||
#endif
|
||||
seat_keymap_create(s);
|
||||
seat_kbd_repeat_rate_update(s);
|
||||
}
|
||||
seat_keymap_update(s);
|
||||
seat_kbd_repeat_rate_update(s);
|
||||
s->keyboard = !!s->kbd.state;
|
||||
}
|
||||
}
|
||||
|
@ -5339,6 +5357,7 @@ comp_smart_add(Evas_Object *obj)
|
|||
#ifdef HAVE_ECORE_X
|
||||
if (ecore_x_display_get())
|
||||
{
|
||||
ecore_x_xkb_track_state();
|
||||
// if proxiedallowed
|
||||
ecore_x_dnd_aware_set(ecore_evas_window_get(ecore_evas_ecore_evas_get(c->evas)), EINA_TRUE);
|
||||
if (!comps) x11_init();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include "xkbcommon/xkbcommon-x11.h"
|
||||
|
||||
#define WL_TEXT_STR "text/plain;charset=utf-8"
|
||||
#define INCR_CHUNK_SIZE 1 << 17
|
||||
|
||||
|
@ -562,6 +564,99 @@ x11_dnd_move(void *data, Ecore_X_Xdnd_Position *pos)
|
|||
evas_object_move(data, pos->position.x, pos->position.y);
|
||||
}
|
||||
|
||||
static int32_t x11_core_device = -1;
|
||||
static struct xkb_context *x11_kbd_context;
|
||||
static struct xkb_keymap *x11_kbd_keymap;
|
||||
static struct xkb_state *x11_kbd_state;
|
||||
|
||||
static Eina_Bool seat_kbd_mods_update(Comp_Seat *s);
|
||||
static void comp_seat_send_modifiers(Comp_Seat *s, struct wl_resource *res, uint32_t serial);
|
||||
|
||||
static Eina_Bool
|
||||
x11_xkb_state(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_X_Event_Xkb *ev)
|
||||
{
|
||||
Comp *c;
|
||||
Eina_List *l;
|
||||
Comp_Seat *s;
|
||||
|
||||
if (!xkb_state_update_mask(x11_kbd_state,
|
||||
get_xkb_mod_mask(ev->base_mods),
|
||||
get_xkb_mod_mask(ev->latched_mods),
|
||||
get_xkb_mod_mask(ev->locked_mods),
|
||||
0,
|
||||
0,
|
||||
ev->group)) return ECORE_CALLBACK_RENEW;
|
||||
EINA_LIST_FOREACH(comps, l, c)
|
||||
EINA_INLIST_FOREACH(c->seats, s)
|
||||
{
|
||||
Eina_List *ll, *lll;
|
||||
uint32_t serial;
|
||||
struct wl_resource *res;
|
||||
|
||||
seat_kbd_mods_update(s);
|
||||
ll = seat_kbd_active_resources_get(s);
|
||||
if (!ll) continue;
|
||||
serial = wl_display_next_serial(s->c->display);
|
||||
EINA_LIST_FOREACH(ll, lll, res)
|
||||
comp_seat_send_modifiers(s, res, serial);
|
||||
}
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_kbd_destroy(void)
|
||||
{
|
||||
if (x11_kbd_state) xkb_state_unref(x11_kbd_state);
|
||||
x11_kbd_state = NULL;
|
||||
if (x11_kbd_keymap) xkb_keymap_unref(x11_kbd_keymap);
|
||||
x11_kbd_keymap = NULL;
|
||||
if (x11_kbd_context) xkb_context_unref(x11_kbd_context);
|
||||
x11_kbd_context = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_kbd_create(void)
|
||||
{
|
||||
Ecore_X_Connection *conn = ecore_x_connection_get();
|
||||
|
||||
x11_kbd_destroy();
|
||||
|
||||
x11_kbd_context = xkb_context_new(0);
|
||||
x11_core_device = xkb_x11_get_core_keyboard_device_id(conn);
|
||||
x11_kbd_keymap = xkb_x11_keymap_new_from_device(x11_kbd_context, conn, x11_core_device, 0);
|
||||
x11_kbd_state = xkb_x11_state_new_from_device(x11_kbd_keymap, conn, x11_core_device);
|
||||
keymap_mods_init(x11_kbd_keymap);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_kbd_apply(Comp_Seat *s)
|
||||
{
|
||||
if (!x11_kbd_state) x11_kbd_create();
|
||||
s->kbd.context = x11_kbd_context;
|
||||
s->kbd.keymap = x11_kbd_keymap;
|
||||
s->kbd.state = x11_kbd_state;
|
||||
}
|
||||
|
||||
static void seat_keymap_update(Comp_Seat *s);
|
||||
|
||||
static Eina_Bool
|
||||
x11_xkb_refresh()
|
||||
{
|
||||
Eina_List *l;
|
||||
Comp *c;
|
||||
Comp_Seat *s;
|
||||
|
||||
x11_kbd_create();
|
||||
EINA_LIST_FOREACH(comps, l, c)
|
||||
EINA_INLIST_FOREACH(c->seats, s)
|
||||
{
|
||||
if (!s->keyboard) continue;
|
||||
x11_kbd_apply(s);
|
||||
seat_keymap_update(s);
|
||||
}
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_init(void)
|
||||
{
|
||||
|
@ -589,18 +684,29 @@ x11_init(void)
|
|||
handlers = eina_list_append(handlers, h);
|
||||
h = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP, (Ecore_Event_Handler_Cb)x11_dnd_mouse_up, NULL);
|
||||
handlers = eina_list_append(handlers, h);
|
||||
h = ecore_event_handler_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, (Ecore_Event_Handler_Cb)x11_xkb_state, NULL);
|
||||
handlers = eina_list_append(handlers, h);
|
||||
h = ecore_event_handler_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, (Ecore_Event_Handler_Cb)x11_xkb_refresh, NULL);
|
||||
handlers = eina_list_append(handlers, h);
|
||||
if (!xconvertselection)
|
||||
{
|
||||
xconvertselection = dlsym(NULL, "XConvertSelection");
|
||||
string_atom = ecore_x_atom_get("UTF8_STRING");
|
||||
timestamp_atom = ecore_x_atom_get("TIMESTAMP");
|
||||
int_atom = ecore_x_atom_get("INTEGER");
|
||||
incr_atom = ecore_x_atom_get("TIMESTAMP");
|
||||
comp_dnd_atom = ecore_x_atom_get("SIRCMPWIDG_ATOM");
|
||||
ecore_x_xkb_track_state();
|
||||
}
|
||||
|
||||
pipes = eina_hash_int32_new((Eina_Free_Cb)_pipe_free);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_shutdown(void)
|
||||
{
|
||||
x11_core_device = -1;
|
||||
x11_kbd_destroy();
|
||||
eina_hash_free(pipes);
|
||||
pipes = NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue