Skip to content

Commit 057e1d6

Browse files
committed
Properly reset state when enabling text input
When starting text input, not all state was reset properly. The text input protocol requires to be re-enabled every time text input changes, which SDL did not do. Also, XKB compose state was not reset at all, causing composite and dead keys to carry over from when text input was disabled.
1 parent aaf3694 commit 057e1d6

File tree

4 files changed

+38
-24
lines changed

4 files changed

+38
-24
lines changed

src/video/wayland/SDL_waylandevents.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,9 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
11731173
SDL_IME_SetFocus(SDL_TRUE);
11741174
}
11751175
#endif
1176+
if (input->text_input && input->text_input->is_enabled) {
1177+
Wayland_EnableTextInput(input->text_input);
1178+
}
11761179

11771180
wl_array_for_each (key, keys) {
11781181
const SDL_Scancode scancode = Wayland_get_scancode_from_key(input, *key + 8);
@@ -1234,7 +1237,7 @@ static SDL_bool keyboard_input_get_text(char text[8], const struct SDL_WaylandIn
12341237
const xkb_keysym_t *syms;
12351238
xkb_keysym_t sym;
12361239

1237-
if (!window || window->keyboard_device != input || !input->xkb.state || !input->text_input->is_enabled) {
1240+
if (!window || window->keyboard_device != input || !input->xkb.state) {
12381241
return SDL_FALSE;
12391242
}
12401243

src/video/wayland/SDL_waylandkeyboard.c

+32-23
Original file line numberDiff line numberDiff line change
@@ -51,42 +51,51 @@ void Wayland_QuitKeyboard(_THIS)
5151
#endif
5252
}
5353

54+
void Wayland_EnableTextInput(SDL_WaylandTextInput *text_input)
55+
{
56+
const SDL_Rect *rect = &text_input->cursor_rect;
57+
58+
/* For some reason this has to be done twice, it appears to be a
59+
* bug in mutter? Maybe?
60+
* -flibit
61+
*/
62+
zwp_text_input_v3_enable(text_input->text_input);
63+
zwp_text_input_v3_commit(text_input->text_input);
64+
zwp_text_input_v3_enable(text_input->text_input);
65+
zwp_text_input_v3_commit(text_input->text_input);
66+
67+
/* Now that it's enabled, set the input properties */
68+
zwp_text_input_v3_set_content_type(text_input->text_input,
69+
ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE,
70+
ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL);
71+
if (!SDL_RectEmpty(rect)) {
72+
/* This gets reset on enable so we have to cache it */
73+
zwp_text_input_v3_set_cursor_rectangle(text_input->text_input,
74+
rect->x,
75+
rect->y,
76+
rect->w,
77+
rect->h);
78+
}
79+
zwp_text_input_v3_commit(text_input->text_input);
80+
}
81+
5482
void Wayland_StartTextInput(_THIS)
5583
{
5684
SDL_VideoData *driverdata = _this->driverdata;
5785

5886
if (driverdata->text_input_manager) {
5987
struct SDL_WaylandInput *input = driverdata->input;
6088
if (input && input->text_input) {
61-
const SDL_Rect *rect = &input->text_input->cursor_rect;
62-
6389
/* Don't re-enable if we're already enabled. */
6490
if (input->text_input->is_enabled) {
6591
return;
6692
}
6793

68-
/* For some reason this has to be done twice, it appears to be a
69-
* bug in mutter? Maybe?
70-
* -flibit
71-
*/
72-
zwp_text_input_v3_enable(input->text_input->text_input);
73-
zwp_text_input_v3_commit(input->text_input->text_input);
74-
zwp_text_input_v3_enable(input->text_input->text_input);
75-
zwp_text_input_v3_commit(input->text_input->text_input);
76-
77-
/* Now that it's enabled, set the input properties */
78-
zwp_text_input_v3_set_content_type(input->text_input->text_input,
79-
ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE,
80-
ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL);
81-
if (!SDL_RectEmpty(rect)) {
82-
/* This gets reset on enable so we have to cache it */
83-
zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input,
84-
rect->x,
85-
rect->y,
86-
rect->w,
87-
rect->h);
94+
Wayland_EnableTextInput(input->text_input);
95+
if (input->xkb.compose_state) {
96+
/* Reset compose state so composite and dead keys don't carry over */
97+
WAYLAND_xkb_compose_state_reset(input->xkb.compose_state);
8898
}
89-
zwp_text_input_v3_commit(input->text_input->text_input);
9099
input->text_input->is_enabled = SDL_TRUE;
91100
}
92101
}

src/video/wayland/SDL_waylandkeyboard.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ typedef struct SDL_WaylandTextInput
3333

3434
extern int Wayland_InitKeyboard(_THIS);
3535
extern void Wayland_QuitKeyboard(_THIS);
36+
extern void Wayland_EnableTextInput(SDL_WaylandTextInput *input);
3637
extern void Wayland_StartTextInput(_THIS);
3738
extern void Wayland_StopTextInput(_THIS);
3839
extern void Wayland_SetTextInputRect(_THIS, const SDL_Rect *rect);

src/video/wayland/SDL_waylandsym.h

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ SDL_WAYLAND_SYM(struct xkb_compose_table *, xkb_compose_table_new_from_locale, (
146146
const char *locale, enum xkb_compose_compile_flags) )
147147
SDL_WAYLAND_SYM(void, xkb_compose_table_unref, (struct xkb_compose_table *) )
148148
SDL_WAYLAND_SYM(struct xkb_compose_state *, xkb_compose_state_new, (struct xkb_compose_table *, enum xkb_compose_state_flags) )
149+
SDL_WAYLAND_SYM(void, xkb_compose_state_reset, (struct xkb_compose_state *) )
149150
SDL_WAYLAND_SYM(void, xkb_compose_state_unref, (struct xkb_compose_state *) )
150151
SDL_WAYLAND_SYM(enum xkb_compose_feed_result, xkb_compose_state_feed, (struct xkb_compose_state *, xkb_keysym_t) )
151152
SDL_WAYLAND_SYM(enum xkb_compose_status, xkb_compose_state_get_status, (struct xkb_compose_state *) )

0 commit comments

Comments
 (0)