summaryrefslogtreecommitdiffstats
path: root/video/out/wayland_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/wayland_common.c')
-rw-r--r--video/out/wayland_common.c104
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);