Skip to content

Commit c7549eb

Browse files
committed
wayland: Set the text input cursor rect properly
The text input cursor should reflect the cursor position, not the entire text input rect. Set it correctly so that IME chooser dialogs appear in the correct location.
1 parent 3be57ec commit c7549eb

File tree

2 files changed

+41
-16
lines changed

2 files changed

+41
-16
lines changed

src/video/wayland/SDL_waylandevents_c.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ typedef struct SDL_WaylandSeat
170170
struct
171171
{
172172
struct zwp_text_input_v3 *zwp_text_input;
173-
SDL_Rect cursor_rect;
173+
SDL_Rect text_input_rect;
174+
int text_input_cursor;
174175
bool enabled;
175176
bool has_preedit;
176177
} text_input;

src/video/wayland/SDL_waylandkeyboard.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,33 @@ void Wayland_UpdateTextInput(SDL_VideoData *display)
6161

6262
if (seat->text_input.zwp_text_input) {
6363
if (focus && focus->text_input_props.active) {
64+
SDL_Window *window = focus->sdlwindow;
65+
6466
// Enabling will reset all state, so don't do it redundantly.
6567
if (!seat->text_input.enabled) {
6668
seat->text_input.enabled = true;
6769
zwp_text_input_v3_enable(seat->text_input.zwp_text_input);
6870

6971
// Now that it's enabled, set the input properties
7072
zwp_text_input_v3_set_content_type(seat->text_input.zwp_text_input, focus->text_input_props.hint, focus->text_input_props.purpose);
71-
if (!SDL_RectEmpty(&focus->sdlwindow->text_input_rect)) {
72-
SDL_copyp(&seat->text_input.cursor_rect, &focus->sdlwindow->text_input_rect);
73-
74-
// This gets reset on enable so we have to cache it
73+
if (!SDL_RectEmpty(&window->text_input_rect)) {
74+
const SDL_Rect scaled_rect = {
75+
(int)SDL_floor(window->text_input_rect.x / focus->pointer_scale.x),
76+
(int)SDL_floor(window->text_input_rect.y / focus->pointer_scale.y),
77+
(int)SDL_ceil(window->text_input_rect.w / focus->pointer_scale.x),
78+
(int)SDL_ceil(window->text_input_rect.h / focus->pointer_scale.y)
79+
};
80+
const int scaled_cursor = (int)SDL_floor(window->text_input_cursor / focus->pointer_scale.x);
81+
82+
SDL_copyp(&seat->text_input.text_input_rect, &scaled_rect);
83+
seat->text_input.text_input_cursor = scaled_cursor;
84+
85+
// Clamp the x value so it doesn't run too far past the end of the text input area.
7586
zwp_text_input_v3_set_cursor_rectangle(seat->text_input.zwp_text_input,
76-
focus->sdlwindow->text_input_rect.x,
77-
focus->sdlwindow->text_input_rect.y,
78-
focus->sdlwindow->text_input_rect.w,
79-
focus->sdlwindow->text_input_rect.h);
87+
SDL_min(scaled_rect.x + scaled_cursor, scaled_rect.x + scaled_rect.w),
88+
scaled_rect.y,
89+
1,
90+
scaled_rect.h);
8091
}
8192
zwp_text_input_v3_commit(seat->text_input.zwp_text_input);
8293

@@ -88,7 +99,8 @@ void Wayland_UpdateTextInput(SDL_VideoData *display)
8899
} else {
89100
if (seat->text_input.enabled) {
90101
seat->text_input.enabled = false;
91-
SDL_zero(seat->text_input.cursor_rect);
102+
SDL_zero(seat->text_input.text_input_rect);
103+
seat->text_input.text_input_cursor = 0;
92104
zwp_text_input_v3_disable(seat->text_input.zwp_text_input);
93105
zwp_text_input_v3_commit(seat->text_input.zwp_text_input);
94106
}
@@ -203,13 +215,25 @@ bool Wayland_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window)
203215

204216
wl_list_for_each (seat, &internal->seat_list, link) {
205217
if (seat->text_input.zwp_text_input && seat->keyboard.focus == window->internal) {
206-
if (!SDL_RectsEqual(&window->text_input_rect, &seat->text_input.cursor_rect)) {
207-
SDL_copyp(&seat->text_input.cursor_rect, &window->text_input_rect);
218+
SDL_WindowData *wind = window->internal;
219+
const SDL_Rect scaled_rect = {
220+
(int)SDL_floor(window->text_input_rect.x / wind->pointer_scale.x),
221+
(int)SDL_floor(window->text_input_rect.y / wind->pointer_scale.y),
222+
(int)SDL_ceil(window->text_input_rect.w / wind->pointer_scale.x),
223+
(int)SDL_ceil(window->text_input_rect.h / wind->pointer_scale.y)
224+
};
225+
const int scaled_cursor = (int)SDL_floor(window->text_input_cursor / wind->pointer_scale.x);
226+
227+
if (!SDL_RectsEqual(&scaled_rect, &seat->text_input.text_input_rect) || scaled_cursor != seat->text_input.text_input_cursor) {
228+
SDL_copyp(&seat->text_input.text_input_rect, &scaled_rect);
229+
seat->text_input.text_input_cursor = scaled_cursor;
230+
231+
// Clamp the x value so it doesn't run too far past the end of the text input area.
208232
zwp_text_input_v3_set_cursor_rectangle(seat->text_input.zwp_text_input,
209-
window->text_input_rect.x,
210-
window->text_input_rect.y,
211-
window->text_input_rect.w,
212-
window->text_input_rect.h);
233+
SDL_min(scaled_rect.x + scaled_cursor, scaled_rect.x + scaled_rect.w),
234+
scaled_rect.y,
235+
1,
236+
scaled_rect.h);
213237
zwp_text_input_v3_commit(seat->text_input.zwp_text_input);
214238
}
215239
}

0 commit comments

Comments
 (0)