Skip to content

Commit 1c7ef74

Browse files
committed
Merge pull request #113346 from deralmas/wl-keyboard-saga/unify-keys
Wayland: Unify key handling logic
2 parents da3233a + 9a814b4 commit 1c7ef74

File tree

3 files changed

+73
-91
lines changed

3 files changed

+73
-91
lines changed

platform/linuxbsd/wayland/display_server_wayland.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,6 +1695,8 @@ void DisplayServerWayland::try_suspend() {
16951695
void DisplayServerWayland::process_events() {
16961696
wayland_thread.mutex.lock();
16971697

1698+
wayland_thread.keyboard_echo_keys();
1699+
16981700
while (wayland_thread.has_message()) {
16991701
Ref<WaylandThread::Message> msg = wayland_thread.pop_message();
17001702

@@ -1837,8 +1839,6 @@ void DisplayServerWayland::process_events() {
18371839
}
18381840
}
18391841

1840-
wayland_thread.keyboard_echo_keys();
1841-
18421842
switch (suspend_state) {
18431843
case SuspendState::NONE: {
18441844
bool emulate_vsync = false;

platform/linuxbsd/wayland/wayland_thread.cpp

Lines changed: 69 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,73 @@ Ref<InputEventKey> WaylandThread::_seat_state_get_unstuck_key_event(SeatState *p
302302
return event;
303303
}
304304

305+
void WaylandThread::_seat_state_handle_xkb_keycode(SeatState *p_ss, xkb_keycode_t p_xkb_keycode, bool p_pressed, bool p_echo) {
306+
ERR_FAIL_NULL(p_ss);
307+
308+
WaylandThread *wayland_thread = p_ss->wayland_thread;
309+
ERR_FAIL_NULL(wayland_thread);
310+
311+
Key last_key = Key::NONE;
312+
xkb_compose_status compose_status = xkb_compose_state_get_status(p_ss->xkb_compose_state);
313+
314+
if (p_pressed) {
315+
xkb_keysym_t keysym = xkb_state_key_get_one_sym(p_ss->xkb_state, p_xkb_keycode);
316+
xkb_compose_feed_result compose_result = xkb_compose_state_feed(p_ss->xkb_compose_state, keysym);
317+
compose_status = xkb_compose_state_get_status(p_ss->xkb_compose_state);
318+
319+
if (compose_result == XKB_COMPOSE_FEED_ACCEPTED && compose_status == XKB_COMPOSE_COMPOSED) {
320+
// We need to generate multiple key events to report the composed result, One
321+
// per character.
322+
char str_xkb[256] = {};
323+
int str_xkb_size = xkb_compose_state_get_utf8(p_ss->xkb_compose_state, str_xkb, 255);
324+
325+
String decoded_str = String::utf8(str_xkb, str_xkb_size);
326+
for (int i = 0; i < decoded_str.length(); ++i) {
327+
Ref<InputEventKey> k = _seat_state_get_key_event(p_ss, p_xkb_keycode, p_pressed);
328+
if (k.is_null()) {
329+
continue;
330+
}
331+
332+
k->set_unicode(decoded_str[i]);
333+
k->set_echo(p_echo);
334+
335+
Ref<InputEventMessage> msg;
336+
msg.instantiate();
337+
msg->event = k;
338+
wayland_thread->push_message(msg);
339+
340+
last_key = k->get_keycode();
341+
}
342+
}
343+
}
344+
345+
if (last_key == Key::NONE && compose_status == XKB_COMPOSE_NOTHING) {
346+
// If we continued with other compose status (e.g. XKB_COMPOSE_COMPOSING) we
347+
// would get the composing keys _and_ the result.
348+
Ref<InputEventKey> k = _seat_state_get_key_event(p_ss, p_xkb_keycode, p_pressed);
349+
if (k.is_valid()) {
350+
k->set_echo(p_echo);
351+
352+
Ref<InputEventMessage> msg;
353+
msg.instantiate();
354+
msg->event = k;
355+
wayland_thread->push_message(msg);
356+
357+
last_key = k->get_keycode();
358+
}
359+
}
360+
361+
if (last_key != Key::NONE) {
362+
Ref<InputEventKey> uk = _seat_state_get_unstuck_key_event(p_ss, p_xkb_keycode, p_pressed, last_key);
363+
if (uk.is_valid()) {
364+
Ref<InputEventMessage> u_msg;
365+
u_msg.instantiate();
366+
u_msg->event = uk;
367+
wayland_thread->push_message(u_msg);
368+
}
369+
}
370+
}
371+
305372
void WaylandThread::_set_current_seat(struct wl_seat *p_seat) {
306373
if (p_seat == wl_seat_current) {
307374
return;
@@ -2198,16 +2265,10 @@ void WaylandThread::_wl_keyboard_on_key(void *data, struct wl_keyboard *wl_keybo
21982265
return;
21992266
}
22002267

2201-
WaylandThread *wayland_thread = ss->wayland_thread;
2202-
ERR_FAIL_NULL(wayland_thread);
2203-
22042268
// We have to add 8 to the scancode to get an XKB-compatible keycode.
22052269
xkb_keycode_t xkb_keycode = key + 8;
22062270

22072271
bool pressed = state & WL_KEYBOARD_KEY_STATE_PRESSED;
2208-
Key last_key = Key::NONE;
2209-
2210-
xkb_compose_status compose_status = xkb_compose_state_get_status(ss->xkb_compose_state);
22112272

22122273
if (pressed) {
22132274
if (xkb_keymap_key_repeats(ss->xkb_keymap, xkb_keycode)) {
@@ -2216,58 +2277,11 @@ void WaylandThread::_wl_keyboard_on_key(void *data, struct wl_keyboard *wl_keybo
22162277
}
22172278

22182279
ss->last_key_pressed_serial = serial;
2219-
2220-
xkb_keysym_t keysym = xkb_state_key_get_one_sym(ss->xkb_state, xkb_keycode);
2221-
xkb_compose_feed_result compose_result = xkb_compose_state_feed(ss->xkb_compose_state, keysym);
2222-
compose_status = xkb_compose_state_get_status(ss->xkb_compose_state);
2223-
2224-
if (compose_result == XKB_COMPOSE_FEED_ACCEPTED && compose_status == XKB_COMPOSE_COMPOSED) {
2225-
// We need to generate multiple key events to report the composed result, One
2226-
// per character.
2227-
char str_xkb[256] = {};
2228-
int str_xkb_size = xkb_compose_state_get_utf8(ss->xkb_compose_state, str_xkb, 255);
2229-
2230-
String decoded_str = String::utf8(str_xkb, str_xkb_size);
2231-
for (int i = 0; i < decoded_str.length(); ++i) {
2232-
Ref<InputEventKey> k = _seat_state_get_key_event(ss, xkb_keycode, pressed);
2233-
k->set_unicode(decoded_str[i]);
2234-
2235-
Ref<InputEventMessage> msg;
2236-
msg.instantiate();
2237-
msg->event = k;
2238-
wayland_thread->push_message(msg);
2239-
2240-
last_key = k->get_keycode();
2241-
}
2242-
}
22432280
} else if (ss->repeating_keycode == xkb_keycode) {
22442281
ss->repeating_keycode = XKB_KEYCODE_INVALID;
22452282
}
22462283

2247-
if (last_key == Key::NONE && compose_status == XKB_COMPOSE_NOTHING) {
2248-
// If we continued with other compose status (e.g. XKB_COMPOSE_COMPOSING) we
2249-
// would get the composing keys _and_ the result.
2250-
Ref<InputEventKey> k = _seat_state_get_key_event(ss, xkb_keycode, pressed);
2251-
2252-
if (k.is_valid()) {
2253-
Ref<InputEventMessage> msg;
2254-
msg.instantiate();
2255-
msg->event = k;
2256-
wayland_thread->push_message(msg);
2257-
2258-
last_key = k->get_keycode();
2259-
}
2260-
}
2261-
2262-
if (last_key != Key::NONE) {
2263-
Ref<InputEventKey> uk = _seat_state_get_unstuck_key_event(ss, xkb_keycode, pressed, last_key);
2264-
if (uk.is_valid()) {
2265-
Ref<InputEventMessage> u_msg;
2266-
u_msg.instantiate();
2267-
u_msg->event = uk;
2268-
wayland_thread->push_message(u_msg);
2269-
}
2270-
}
2284+
_seat_state_handle_xkb_keycode(ss, xkb_keycode, pressed);
22712285
}
22722286

22732287
void WaylandThread::_wl_keyboard_on_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) {
@@ -3683,42 +3697,8 @@ void WaylandThread::seat_state_echo_keys(SeatState *p_ss) {
36833697

36843698
int keys_amount = (ticks_delta / p_ss->repeat_key_delay_msec);
36853699

3686-
xkb_compose_status compose_status = xkb_compose_state_get_status(p_ss->xkb_compose_state);
3687-
3688-
Key last_key = Key::NONE;
36893700
for (int i = 0; i < keys_amount; i++) {
3690-
xkb_keysym_t keysym = xkb_state_key_get_one_sym(p_ss->xkb_state, p_ss->repeating_keycode);
3691-
xkb_compose_feed_result compose_result = xkb_compose_state_feed(p_ss->xkb_compose_state, keysym);
3692-
compose_status = xkb_compose_state_get_status(p_ss->xkb_compose_state);
3693-
3694-
if (compose_result == XKB_COMPOSE_FEED_ACCEPTED && compose_status == XKB_COMPOSE_COMPOSED) {
3695-
// We need to generate multiple key events to report the composed result, One
3696-
// per character.
3697-
char str_xkb[256] = {};
3698-
int str_xkb_size = xkb_compose_state_get_utf8(p_ss->xkb_compose_state, str_xkb, 255);
3699-
3700-
String decoded_str = String::utf8(str_xkb, str_xkb_size);
3701-
for (int j = 0; j < decoded_str.length(); ++j) {
3702-
Ref<InputEventKey> k = _seat_state_get_key_event(p_ss, p_ss->repeating_keycode, true);
3703-
k->set_unicode(decoded_str[j]);
3704-
Input::get_singleton()->parse_input_event(k);
3705-
3706-
last_key = k->get_keycode();
3707-
}
3708-
} else if (compose_status == XKB_COMPOSE_NOTHING) {
3709-
Ref<InputEventKey> k = _seat_state_get_key_event(p_ss, p_ss->repeating_keycode, true);
3710-
k->set_echo(true);
3711-
Input::get_singleton()->parse_input_event(k);
3712-
3713-
last_key = k->get_keycode();
3714-
}
3715-
3716-
if (last_key != Key::NONE) {
3717-
Ref<InputEventKey> uk = _seat_state_get_unstuck_key_event(p_ss, p_ss->repeating_keycode, true, last_key);
3718-
if (uk.is_valid()) {
3719-
Input::get_singleton()->parse_input_event(uk);
3720-
}
3721-
}
3701+
_seat_state_handle_xkb_keycode(p_ss, p_ss->repeating_keycode, true, true);
37223702
}
37233703

37243704
p_ss->last_repeat_msec += ticks_delta - (ticks_delta % p_ss->repeat_key_delay_msec);

platform/linuxbsd/wayland/wayland_thread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,8 @@ class WaylandThread {
10371037
static Ref<InputEventKey> _seat_state_get_key_event(SeatState *p_ss, xkb_keycode_t p_keycode, bool p_pressed);
10381038
static Ref<InputEventKey> _seat_state_get_unstuck_key_event(SeatState *p_ss, xkb_keycode_t p_keycode, bool p_pressed, Key p_key);
10391039

1040+
static void _seat_state_handle_xkb_keycode(SeatState *p_ss, xkb_keycode_t p_xkb_keycode, bool p_pressed, bool p_echo = false);
1041+
10401042
static void _wayland_state_update_cursor();
10411043

10421044
void _set_current_seat(struct wl_seat *p_seat);

0 commit comments

Comments
 (0)