Skip to content

Commit

Permalink
wayland: keyboard: Cache text input parameters.
Browse files Browse the repository at this point in the history
Some applications (and embarrassingly, testime is one of them) call
SDL_StartTextInput() or SDL_SetTextInputRect() every frame. On KDE/KWin
with fcitx5, this causes there to be several preedit events every frame
(particularly given some of the workarounds in Wayland_StartTextInput),
which slows testime down to an unusable crawl.

Instead, make SDL_StartTextInput() a no-op if text input is already
enabled, and cache the input rect, only changing it when the new rect is
actually different.

With these changes, we only get preedit events (and hence
SDL_TEXTEDITING events) when the preedit string actually changes. This
matches the behaviour under XWayland, and works very smoothly.
  • Loading branch information
sulix authored and slouken committed Nov 18, 2022
1 parent 6dc96aa commit 81479d8
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 7 deletions.
23 changes: 16 additions & 7 deletions src/video/wayland/SDL_waylandkeyboard.c
Expand Up @@ -61,6 +61,10 @@ Wayland_StartTextInput(_THIS)
if (input != NULL && input->text_input) {
const SDL_Rect *rect = &input->text_input->cursor_rect;

/* Don't re-enable if we're already enabled. */
if (input->text_input->is_enabled)
return;

/* For some reason this has to be done twice, it appears to be a
* bug in mutter? Maybe?
* -flibit
Expand All @@ -83,6 +87,7 @@ Wayland_StartTextInput(_THIS)
rect->h);
}
zwp_text_input_v3_commit(input->text_input->text_input);
input->text_input->is_enabled = SDL_TRUE;
}
}
}
Expand All @@ -97,6 +102,7 @@ Wayland_StopTextInput(_THIS)
if (input != NULL && input->text_input) {
zwp_text_input_v3_disable(input->text_input->text_input);
zwp_text_input_v3_commit(input->text_input->text_input);
input->text_input->is_enabled = SDL_FALSE;
}
}

Expand All @@ -120,13 +126,16 @@ Wayland_SetTextInputRect(_THIS, const SDL_Rect *rect)
if (driverdata->text_input_manager) {
struct SDL_WaylandInput *input = driverdata->input;
if (input != NULL && input->text_input) {
SDL_copyp(&input->text_input->cursor_rect, rect);
zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input,
rect->x,
rect->y,
rect->w,
rect->h);
zwp_text_input_v3_commit(input->text_input->text_input);
if (!SDL_RectEquals(rect, &input->text_input->cursor_rect))
{
SDL_copyp(&input->text_input->cursor_rect, rect);
zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input,
rect->x,
rect->y,
rect->w,
rect->h);
zwp_text_input_v3_commit(input->text_input->text_input);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/video/wayland/SDL_waylandkeyboard.h
Expand Up @@ -28,6 +28,7 @@ typedef struct SDL_WaylandTextInput
struct zwp_text_input_v3 *text_input;
SDL_Rect cursor_rect;
SDL_bool has_preedit;
SDL_bool is_enabled;
} SDL_WaylandTextInput;

extern int Wayland_InitKeyboard(_THIS);
Expand Down

0 comments on commit 81479d8

Please sign in to comment.