mirror of
https://github.com/mpv-player/mpv
synced 2025-03-20 10:17:31 +00:00
wayland_common: handle keyboard state per seat
Avoids modifiers from mulitple seats from interfering with each other and messing up xkb states.
This commit is contained in:
parent
b6dcf9ecee
commit
04bc6a4a43
@ -198,12 +198,17 @@ struct vo_wayland_seat {
|
|||||||
/* TODO: unvoid this if required wayland protocols is bumped to 1.32+ */
|
/* TODO: unvoid this if required wayland protocols is bumped to 1.32+ */
|
||||||
void *cursor_shape_device;
|
void *cursor_shape_device;
|
||||||
uint32_t pointer_serial;
|
uint32_t pointer_serial;
|
||||||
|
struct xkb_keymap *xkb_keymap;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
uint32_t keyboard_code;
|
||||||
|
int mpkey;
|
||||||
|
int mpmod;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int check_for_resize(struct vo_wayland_state *wl, int edge_pixels,
|
static int check_for_resize(struct vo_wayland_state *wl, int edge_pixels,
|
||||||
enum xdg_toplevel_resize_edge *edge);
|
enum xdg_toplevel_resize_edge *edge);
|
||||||
static int get_mods(struct vo_wayland_state *wl);
|
static int get_mods(struct vo_wayland_seat *seat);
|
||||||
static int lookupkey(int key);
|
static int lookupkey(int key);
|
||||||
static int set_cursor_visibility(struct vo_wayland_seat *s, bool on);
|
static int set_cursor_visibility(struct vo_wayland_seat *s, bool on);
|
||||||
static int spawn_cursor(struct vo_wayland_state *wl);
|
static int spawn_cursor(struct vo_wayland_state *wl);
|
||||||
@ -293,7 +298,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (button)
|
if (button)
|
||||||
mp_input_put_key(wl->vo->input_ctx, button | state | wl->mpmod);
|
mp_input_put_key(wl->vo->input_ctx, button | state | s->mpmod);
|
||||||
|
|
||||||
if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y) &&
|
if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y) &&
|
||||||
!wl->locked_size && (button == MP_MBTN_LEFT) && (state == MP_KEY_STATE_DOWN))
|
!wl->locked_size && (button == MP_MBTN_LEFT) && (state == MP_KEY_STATE_DOWN))
|
||||||
@ -345,13 +350,13 @@ static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value_vertical > 0)
|
if (value_vertical > 0)
|
||||||
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_DOWN | wl->mpmod, +value_vertical);
|
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_DOWN | s->mpmod, +value_vertical);
|
||||||
if (value_vertical < 0)
|
if (value_vertical < 0)
|
||||||
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_UP | wl->mpmod, -value_vertical);
|
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_UP | s->mpmod, -value_vertical);
|
||||||
if (value_horizontal > 0)
|
if (value_horizontal > 0)
|
||||||
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_RIGHT | wl->mpmod, +value_horizontal);
|
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_RIGHT | s->mpmod, +value_horizontal);
|
||||||
if (value_horizontal < 0)
|
if (value_horizontal < 0)
|
||||||
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_LEFT | wl->mpmod, -value_horizontal);
|
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_LEFT | s->mpmod, -value_horizontal);
|
||||||
|
|
||||||
wl->axis_value120_scroll = false;
|
wl->axis_value120_scroll = false;
|
||||||
wl->axis_value_vertical = 0;
|
wl->axis_value_vertical = 0;
|
||||||
@ -496,25 +501,25 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wl->xkb_keymap)
|
if (!s->xkb_keymap)
|
||||||
wl->xkb_keymap = xkb_keymap_new_from_buffer(wl->xkb_context, map_str,
|
s->xkb_keymap = xkb_keymap_new_from_buffer(wl->xkb_context, map_str,
|
||||||
strnlen(map_str, size),
|
strnlen(map_str, size),
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1, 0);
|
XKB_KEYMAP_FORMAT_TEXT_V1, 0);
|
||||||
|
|
||||||
munmap(map_str, size);
|
munmap(map_str, size);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
if (!wl->xkb_keymap) {
|
if (!s->xkb_keymap) {
|
||||||
MP_ERR(wl, "failed to compile keymap\n");
|
MP_ERR(wl, "failed to compile keymap\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wl->xkb_state)
|
if (!s->xkb_state)
|
||||||
wl->xkb_state = xkb_state_new(wl->xkb_keymap);
|
s->xkb_state = xkb_state_new(s->xkb_keymap);
|
||||||
if (!wl->xkb_state) {
|
if (!s->xkb_state) {
|
||||||
MP_ERR(wl, "failed to create XKB state\n");
|
MP_ERR(wl, "failed to create XKB state\n");
|
||||||
xkb_keymap_unref(wl->xkb_keymap);
|
xkb_keymap_unref(s->xkb_keymap);
|
||||||
wl->xkb_keymap = NULL;
|
s->xkb_keymap = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,9 +540,9 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
|
|||||||
struct vo_wayland_seat *s = data;
|
struct vo_wayland_seat *s = data;
|
||||||
struct vo_wayland_state *wl = s->wl;
|
struct vo_wayland_state *wl = s->wl;
|
||||||
wl->has_keyboard_input = false;
|
wl->has_keyboard_input = false;
|
||||||
wl->keyboard_code = 0;
|
s->keyboard_code = 0;
|
||||||
wl->mpkey = 0;
|
s->mpkey = 0;
|
||||||
wl->mpmod = 0;
|
s->mpmod = 0;
|
||||||
mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL);
|
mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL);
|
||||||
guess_focus(wl);
|
guess_focus(wl);
|
||||||
}
|
}
|
||||||
@ -549,34 +554,34 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,
|
|||||||
struct vo_wayland_seat *s = data;
|
struct vo_wayland_seat *s = data;
|
||||||
struct vo_wayland_state *wl = s->wl;
|
struct vo_wayland_state *wl = s->wl;
|
||||||
|
|
||||||
wl->keyboard_code = key + 8;
|
s->keyboard_code = key + 8;
|
||||||
xkb_keysym_t sym = xkb_state_key_get_one_sym(wl->xkb_state, wl->keyboard_code);
|
xkb_keysym_t sym = xkb_state_key_get_one_sym(s->xkb_state, s->keyboard_code);
|
||||||
int mpkey = lookupkey(sym);
|
int mpkey = lookupkey(sym);
|
||||||
|
|
||||||
state = state == WL_KEYBOARD_KEY_STATE_PRESSED ? MP_KEY_STATE_DOWN
|
state = state == WL_KEYBOARD_KEY_STATE_PRESSED ? MP_KEY_STATE_DOWN
|
||||||
: MP_KEY_STATE_UP;
|
: MP_KEY_STATE_UP;
|
||||||
|
|
||||||
if (mpkey) {
|
if (mpkey) {
|
||||||
mp_input_put_key(wl->vo->input_ctx, mpkey | state | wl->mpmod);
|
mp_input_put_key(wl->vo->input_ctx, mpkey | state | s->mpmod);
|
||||||
} else {
|
} else {
|
||||||
char str[128];
|
char str[128];
|
||||||
if (xkb_keysym_to_utf8(sym, str, sizeof(str)) > 0) {
|
if (xkb_keysym_to_utf8(sym, str, sizeof(str)) > 0) {
|
||||||
mp_input_put_key_utf8(wl->vo->input_ctx, state | wl->mpmod, bstr0(str));
|
mp_input_put_key_utf8(wl->vo->input_ctx, state | s->mpmod, bstr0(str));
|
||||||
} else {
|
} else {
|
||||||
// Assume a modifier was pressed and handle it in the mod event instead.
|
// Assume a modifier was pressed and handle it in the mod event instead.
|
||||||
// If a modifier is released before a regular key, also release that
|
// If a modifier is released before a regular key, also release that
|
||||||
// key to not activate it again by accident.
|
// key to not activate it again by accident.
|
||||||
if (state == MP_KEY_STATE_UP) {
|
if (state == MP_KEY_STATE_UP) {
|
||||||
wl->mpkey = 0;
|
s->mpkey = 0;
|
||||||
mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL);
|
mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state == MP_KEY_STATE_DOWN)
|
if (state == MP_KEY_STATE_DOWN)
|
||||||
wl->mpkey = mpkey;
|
s->mpkey = mpkey;
|
||||||
if (mpkey && state == MP_KEY_STATE_UP)
|
if (mpkey && state == MP_KEY_STATE_UP)
|
||||||
wl->mpkey = 0;
|
s->mpkey = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
|
static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,
|
||||||
@ -587,12 +592,12 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar
|
|||||||
struct vo_wayland_seat *s = data;
|
struct vo_wayland_seat *s = data;
|
||||||
struct vo_wayland_state *wl = s->wl;
|
struct vo_wayland_state *wl = s->wl;
|
||||||
|
|
||||||
if (wl->xkb_state) {
|
if (s->xkb_state) {
|
||||||
xkb_state_update_mask(wl->xkb_state, mods_depressed, mods_latched,
|
xkb_state_update_mask(s->xkb_state, mods_depressed, mods_latched,
|
||||||
mods_locked, 0, 0, group);
|
mods_locked, 0, 0, group);
|
||||||
wl->mpmod = get_mods(wl);
|
s->mpmod = get_mods(s);
|
||||||
if (wl->mpkey)
|
if (s->mpkey)
|
||||||
mp_input_put_key(wl->vo->input_ctx, wl->mpkey | MP_KEY_STATE_DOWN | wl->mpmod);
|
mp_input_put_key(wl->vo->input_ctx, s->mpkey | MP_KEY_STATE_DOWN | s->mpmod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1718,7 +1723,7 @@ static char **get_displays_spanned(struct vo_wayland_state *wl)
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_mods(struct vo_wayland_state *wl)
|
static int get_mods(struct vo_wayland_seat *s)
|
||||||
{
|
{
|
||||||
static char* const mod_names[] = {
|
static char* const mod_names[] = {
|
||||||
XKB_MOD_NAME_SHIFT,
|
XKB_MOD_NAME_SHIFT,
|
||||||
@ -1737,9 +1742,9 @@ static int get_mods(struct vo_wayland_state *wl)
|
|||||||
int modifiers = 0;
|
int modifiers = 0;
|
||||||
|
|
||||||
for (int n = 0; n < MP_ARRAY_SIZE(mods); n++) {
|
for (int n = 0; n < MP_ARRAY_SIZE(mods); n++) {
|
||||||
xkb_mod_index_t index = xkb_keymap_mod_get_index(wl->xkb_keymap, mod_names[n]);
|
xkb_mod_index_t index = xkb_keymap_mod_get_index(s->xkb_keymap, mod_names[n]);
|
||||||
if (index != XKB_MOD_INVALID
|
if (index != XKB_MOD_INVALID
|
||||||
&& xkb_state_mod_index_is_active(wl->xkb_state, index,
|
&& xkb_state_mod_index_is_active(s->xkb_state, index,
|
||||||
XKB_STATE_MODS_EFFECTIVE))
|
XKB_STATE_MODS_EFFECTIVE))
|
||||||
modifiers |= mods[n];
|
modifiers |= mods[n];
|
||||||
}
|
}
|
||||||
@ -1908,6 +1913,10 @@ static void remove_seat(struct vo_wayland_seat *seat)
|
|||||||
if (seat->cursor_shape_device)
|
if (seat->cursor_shape_device)
|
||||||
wp_cursor_shape_device_v1_destroy(seat->cursor_shape_device);
|
wp_cursor_shape_device_v1_destroy(seat->cursor_shape_device);
|
||||||
#endif
|
#endif
|
||||||
|
if (seat->xkb_keymap)
|
||||||
|
xkb_keymap_unref(seat->xkb_keymap);
|
||||||
|
if (seat->xkb_state)
|
||||||
|
xkb_state_unref(seat->xkb_state);
|
||||||
|
|
||||||
wl_seat_destroy(seat->seat);
|
wl_seat_destroy(seat->seat);
|
||||||
talloc_free(seat);
|
talloc_free(seat);
|
||||||
@ -2713,12 +2722,6 @@ void vo_wayland_uninit(struct vo *vo)
|
|||||||
if (wl->xkb_context)
|
if (wl->xkb_context)
|
||||||
xkb_context_unref(wl->xkb_context);
|
xkb_context_unref(wl->xkb_context);
|
||||||
|
|
||||||
if (wl->xkb_keymap)
|
|
||||||
xkb_keymap_unref(wl->xkb_keymap);
|
|
||||||
|
|
||||||
if (wl->xkb_state)
|
|
||||||
xkb_state_unref(wl->xkb_state);
|
|
||||||
|
|
||||||
struct vo_wayland_output *output, *output_tmp;
|
struct vo_wayland_output *output, *output_tmp;
|
||||||
wl_list_for_each_safe(output, output_tmp, &wl->output_list, link)
|
wl_list_for_each_safe(output, output_tmp, &wl->output_list, link)
|
||||||
remove_output(output);
|
remove_output(output);
|
||||||
|
@ -144,11 +144,6 @@ struct vo_wayland_state {
|
|||||||
/* Input */
|
/* Input */
|
||||||
struct wl_list seat_list;
|
struct wl_list seat_list;
|
||||||
struct xkb_context *xkb_context;
|
struct xkb_context *xkb_context;
|
||||||
struct xkb_keymap *xkb_keymap;
|
|
||||||
struct xkb_state *xkb_state;
|
|
||||||
uint32_t keyboard_code;
|
|
||||||
int mpkey;
|
|
||||||
int mpmod;
|
|
||||||
double axis_value_vertical;
|
double axis_value_vertical;
|
||||||
int32_t axis_value120_vertical;
|
int32_t axis_value120_vertical;
|
||||||
double axis_value_horizontal;
|
double axis_value_horizontal;
|
||||||
|
Loading…
Reference in New Issue
Block a user