diff options
Diffstat (limited to 'video/out/wayland_common.c')
-rw-r--r-- | video/out/wayland_common.c | 104 |
1 files changed, 68 insertions, 36 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index e570c77d21..5d493c11e3 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -119,7 +119,7 @@ static const struct mp_keymap keymap[] = { /* Numpad without numlock */ {XKB_KEY_KP_Insert, MP_KEY_KPINS}, {XKB_KEY_KP_End, MP_KEY_KPEND}, {XKB_KEY_KP_Down, MP_KEY_KPDOWN}, {XKB_KEY_KP_Page_Down, MP_KEY_KPPGDOWN}, - {XKB_KEY_KP_Left, MP_KEY_KPLEFT}, {XKB_KEY_KP_Begin, MP_KEY_KP5}, + {XKB_KEY_KP_Left, MP_KEY_KPLEFT}, {XKB_KEY_KP_Begin, MP_KEY_KPBEGIN}, {XKB_KEY_KP_Right, MP_KEY_KPRIGHT}, {XKB_KEY_KP_Home, MP_KEY_KPHOME}, {XKB_KEY_KP_Up, MP_KEY_KPUP}, {XKB_KEY_KP_Page_Up, MP_KEY_KPPGUP}, {XKB_KEY_KP_Delete, MP_KEY_KPDEL}, @@ -154,6 +154,7 @@ const struct m_sub_options wayland_conf = { M_RANGE(0, INT_MAX)}, {"wayland-edge-pixels-touch", OPT_INT(edge_pixels_touch), M_RANGE(0, INT_MAX)}, + {"wayland-present", OPT_BOOL(present)}, {0}, }, .size = sizeof(struct wayland_opts), @@ -161,6 +162,7 @@ const struct m_sub_options wayland_conf = { .configure_bounds = -1, .edge_pixels_pointer = 16, .edge_pixels_touch = 32, + .present = true, }, }; @@ -211,6 +213,9 @@ struct vo_wayland_seat { bool axis_value120_scroll; bool has_keyboard_input; struct wl_list link; + bool keyboard_entering; + uint32_t *keyboard_entering_keys; + int num_keyboard_entering_keys; }; static bool single_output_spanned(struct vo_wayland_state *wl); @@ -219,7 +224,7 @@ static int check_for_resize(struct vo_wayland_state *wl, int edge_pixels, enum xdg_toplevel_resize_edge *edge); static int get_mods(struct vo_wayland_seat *seat); static int greatest_common_divisor(int a, int b); -static int lookupkey(int key); +static void handle_key_input(struct vo_wayland_seat *s, uint32_t key, uint32_t state); static int set_cursor_visibility(struct vo_wayland_seat *s, bool on); static int spawn_cursor(struct vo_wayland_state *wl); @@ -558,7 +563,12 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; s->has_keyboard_input = true; + s->keyboard_entering = true; guess_focus(wl); + + uint32_t *key; + wl_array_for_each(key, keys) + MP_TARRAY_APPEND(s, s->keyboard_entering_keys, s->num_keyboard_entering_keys, *key); } static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, @@ -579,36 +589,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t state) { struct vo_wayland_seat *s = data; - struct vo_wayland_state *wl = s->wl; - - s->keyboard_code = key + 8; - xkb_keysym_t sym = xkb_state_key_get_one_sym(s->xkb_state, s->keyboard_code); - int mpkey = lookupkey(sym); - - state = state == WL_KEYBOARD_KEY_STATE_PRESSED ? MP_KEY_STATE_DOWN - : MP_KEY_STATE_UP; - - if (mpkey) { - mp_input_put_key(wl->vo->input_ctx, mpkey | state | s->mpmod); - } else { - char str[128]; - if (xkb_keysym_to_utf8(sym, str, sizeof(str)) > 0) { - mp_input_put_key_utf8(wl->vo->input_ctx, state | s->mpmod, bstr0(str)); - } else { - // 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 - // key to not activate it again by accident. - if (state == MP_KEY_STATE_UP) { - s->mpkey = 0; - mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL); - } - return; - } - } - if (state == MP_KEY_STATE_DOWN) - s->mpkey = mpkey; - if (mpkey && state == MP_KEY_STATE_UP) - s->mpkey = 0; + handle_key_input(s, key, state); } static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, @@ -623,8 +604,15 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboar xkb_state_update_mask(s->xkb_state, mods_depressed, mods_latched, mods_locked, 0, 0, group); s->mpmod = get_mods(s); - if (s->mpkey) - mp_input_put_key(wl->vo->input_ctx, s->mpkey | MP_KEY_STATE_DOWN | s->mpmod); + } + // Handle keys pressed during the enter event. + if (s->keyboard_entering) { + s->keyboard_entering = false; + for (int n = 0; n < s->num_keyboard_entering_keys; n++) + handle_key_input(s, s->keyboard_entering_keys[n], WL_KEYBOARD_KEY_STATE_PRESSED); + s->num_keyboard_entering_keys = 0; + } else if (s->xkb_state && s->mpkey) { + mp_input_put_key(wl->vo->input_ctx, s->mpkey | MP_KEY_STATE_DOWN | s->mpmod); } } @@ -1297,7 +1285,7 @@ static void pres_set_clockid(void *data, struct wp_presentation *pres, struct vo_wayland_state *wl = data; if (clockid == CLOCK_MONOTONIC || clockid == CLOCK_MONOTONIC_RAW) - wl->use_present = true; + wl->present_clock = true; } static const struct wp_presentation_listener pres_listener = { @@ -1363,6 +1351,7 @@ static void frame_callback(void *data, struct wl_callback *callback, uint32_t ti wl->frame_callback = wl_surface_frame(wl->callback_surface); wl_callback_add_listener(wl->frame_callback, &frame_listener, wl); + wl->use_present = wl->present_clock && wl->opts->present; if (wl->use_present) { struct wp_presentation_feedback *fback = wp_presentation_feedback(wl->presentation, wl->callback_surface); add_feedback(wl->fback_pool, fback); @@ -1906,6 +1895,49 @@ static int lookupkey(int key) return mpkey; } +static void handle_key_input(struct vo_wayland_seat *s, uint32_t key, + uint32_t state) +{ + struct vo_wayland_state *wl = s->wl; + + switch (state) { + case WL_KEYBOARD_KEY_STATE_RELEASED: + state = MP_KEY_STATE_UP; + break; + case WL_KEYBOARD_KEY_STATE_PRESSED: + state = MP_KEY_STATE_DOWN; + break; + default: + return; + } + + s->keyboard_code = key + 8; + xkb_keysym_t sym = xkb_state_key_get_one_sym(s->xkb_state, s->keyboard_code); + int mpkey = lookupkey(sym); + + if (mpkey) { + mp_input_put_key(wl->vo->input_ctx, mpkey | state | s->mpmod); + } else { + char str[128]; + if (xkb_keysym_to_utf8(sym, str, sizeof(str)) > 0) { + mp_input_put_key_utf8(wl->vo->input_ctx, state | s->mpmod, bstr0(str)); + } else { + // 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 + // key to not activate it again by accident. + if (state == MP_KEY_STATE_UP) { + s->mpkey = 0; + mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL); + } + return; + } + } + if (state == MP_KEY_STATE_DOWN) + s->mpkey = mpkey; + if (mpkey && state == MP_KEY_STATE_UP) + s->mpkey = 0; +} + static void prepare_resize(struct vo_wayland_state *wl) { int32_t width = mp_rect_w(wl->geometry) / wl->scaling; @@ -2120,7 +2152,7 @@ static int set_screensaver_inhibitor(struct vo_wayland_state *wl, int state) if (state) { MP_VERBOSE(wl, "Enabling idle inhibitor\n"); struct zwp_idle_inhibit_manager_v1 *mgr = wl->idle_inhibit_manager; - wl->idle_inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor(mgr, wl->surface); + wl->idle_inhibitor = zwp_idle_inhibit_manager_v1_create_inhibitor(mgr, wl->callback_surface); } else { MP_VERBOSE(wl, "Disabling the idle inhibitor\n"); zwp_idle_inhibitor_v1_destroy(wl->idle_inhibitor); |