From cf00b0b990fce8ab128034fc4084d86e92cfbd4f Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sat, 7 Nov 2020 13:47:26 -0600 Subject: wayland: check for modifier keys on pointer events The pointer button event had no code to handle any modifier keys. So this meant input combinations like Shift+MTBN_LEFT did not work. Fix this by ripping out the modifier-checking code in keyboard key event to a separate function and using it for both the keyboard and mouse events. In the case of the mouse, it is possible that the keyboard may not exist so be sure to check before trying to get any modifiers. Fixes #8239. --- video/out/wayland_common.c | 72 +++++++++++++++++++++++++--------------------- video/out/wayland_common.h | 1 + 2 files changed, 40 insertions(+), 33 deletions(-) (limited to 'video/out') diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index b72cd9346b..beb2a16316 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -125,6 +125,32 @@ static int set_cursor_visibility(struct vo_wayland_state *wl, bool on) return VO_TRUE; } +static int get_mods(struct vo_wayland_state *wl) +{ + static const char *mod_names[] = { + XKB_MOD_NAME_SHIFT, + XKB_MOD_NAME_CTRL, + XKB_MOD_NAME_ALT, + XKB_MOD_NAME_LOGO, + }; + + static int mods[] = { + MP_KEY_MODIFIER_SHIFT, + MP_KEY_MODIFIER_CTRL, + MP_KEY_MODIFIER_ALT, + MP_KEY_MODIFIER_META, + }; + + for (int n = 0; mods[n]; n++) { + xkb_mod_index_t index = xkb_keymap_mod_get_index(wl->xkb_keymap, mod_names[n]); + if (!xkb_state_mod_index_is_consumed(wl->xkb_state, wl->keyboard_code, index) + && xkb_state_mod_index_is_active(wl->xkb_state, index, + XKB_STATE_MODS_DEPRESSED)) + return mods[n]; + } + return 0; +} + static void pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) @@ -207,6 +233,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, uint32_t state) { struct vo_wayland_state *wl = data; + int mpmod = 0; state = state == WL_POINTER_BUTTON_STATE_PRESSED ? MP_KEY_STATE_DOWN : MP_KEY_STATE_UP; @@ -232,9 +259,11 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, break; } - if (button) { - mp_input_put_key(wl->vo->input_ctx, button | state); - } + if (wl->keyboard) + mpmod = get_mods(wl); + + if (button) + mp_input_put_key(wl->vo->input_ctx, button | state | mpmod); if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y) && (button == MP_MBTN_LEFT) && (state == MP_KEY_STATE_DOWN)) { @@ -492,43 +521,20 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, { struct vo_wayland_state *wl = data; - uint32_t code = code = key + 8; - xkb_keysym_t sym = xkb_state_key_get_one_sym(wl->xkb_state, code); - - int mpmod = state == WL_KEYBOARD_KEY_STATE_PRESSED ? MP_KEY_STATE_DOWN - : MP_KEY_STATE_UP; - - static const char *mod_names[] = { - XKB_MOD_NAME_SHIFT, - XKB_MOD_NAME_CTRL, - XKB_MOD_NAME_ALT, - XKB_MOD_NAME_LOGO, - 0, - }; + wl->keyboard_code = key + 8; + xkb_keysym_t sym = xkb_state_key_get_one_sym(wl->xkb_state, wl->keyboard_code); - static int mods[] = { - MP_KEY_MODIFIER_SHIFT, - MP_KEY_MODIFIER_CTRL, - MP_KEY_MODIFIER_ALT, - MP_KEY_MODIFIER_META, - 0, - }; - - for (int n = 0; mods[n]; n++) { - xkb_mod_index_t index = xkb_keymap_mod_get_index(wl->xkb_keymap, mod_names[n]); - if (!xkb_state_mod_index_is_consumed(wl->xkb_state, code, index) - && xkb_state_mod_index_is_active(wl->xkb_state, index, - XKB_STATE_MODS_DEPRESSED)) - mpmod |= mods[n]; - } + state = state == WL_KEYBOARD_KEY_STATE_PRESSED ? MP_KEY_STATE_DOWN + : MP_KEY_STATE_UP; + int mpmod = get_mods(wl); int mpkey = lookupkey(sym); if (mpkey) { - mp_input_put_key(wl->vo->input_ctx, mpkey | mpmod); + mp_input_put_key(wl->vo->input_ctx, mpkey | state | mpmod); } else { char s[128]; if (xkb_keysym_to_utf8(sym, s, sizeof(s)) > 0) - mp_input_put_key_utf8(wl->vo->input_ctx, mpmod, bstr0(s)); + mp_input_put_key_utf8(wl->vo->input_ctx, state | mpmod, bstr0(s)); } } diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index f2c1a31f66..41edcf5d2f 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -119,6 +119,7 @@ struct vo_wayland_state { int64_t vsync_duration; /* Input */ + uint32_t keyboard_code; struct wl_seat *seat; struct wl_pointer *pointer; struct wl_touch *touch; -- cgit v1.2.3