diff --git a/docs/README-migration.md b/docs/README-migration.md index 63399f7dc9..122983b499 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -917,6 +917,7 @@ The following functions have been renamed: The following functions have been removed: * SDL_IsTextInputShown() +* SDL_SetTextInputRect() - replaced with SDL_SetTextInputArea() The following structures have been removed: * SDL_Keysym diff --git a/include/SDL3/SDL_keyboard.h b/include/SDL3/SDL_keyboard.h index fd44ef2f9d..50ee5927da 100644 --- a/include/SDL3/SDL_keyboard.h +++ b/include/SDL3/SDL_keyboard.h @@ -369,7 +369,7 @@ extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); * * \since This function is available since SDL 3.0.0. * - * \sa SDL_SetTextInputRect + * \sa SDL_SetTextInputArea * \sa SDL_StopTextInput * \sa SDL_TextInputActive */ @@ -418,32 +418,39 @@ extern SDL_DECLSPEC int SDLCALL SDL_StopTextInput(SDL_Window *window); extern SDL_DECLSPEC int SDLCALL SDL_ClearComposition(SDL_Window *window); /** - * Set the rectangle used to type Unicode text inputs. + * Set the area used to type Unicode text input. * - * This is often set to the extents of a text field within the window. + * Native input methods may place a window with word suggestions near the cursor, without covering the text being entered. * - * Native input methods will place a window with word suggestions near it, - * without covering the text being inputted. - * - * To start text input in a given location, this function is intended to be - * called before SDL_StartTextInput, although some platforms support moving - * the rectangle even while text input (and a composition) is active. - * - * Note: If you want to use the system native IME window, try setting hint - * **SDL_HINT_IME_SHOW_UI** to **1**, otherwise this function won't give you - * any feedback. - * - * \param window the window for which to set the text input rectangle. - * \param rect the SDL_Rect structure representing the rectangle to receive - * text (ignored if NULL). + * \param window the window for which to set the text input area. + * \param rect the SDL_Rect representing the text input area, in window coordinates, or NULL to clear it. + * \param cursor the offset of the current cursor location relative to `rect->x`, in window coordinates. * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. * + * \sa SDL_GetTextInputArea * \sa SDL_StartTextInput */ -extern SDL_DECLSPEC int SDLCALL SDL_SetTextInputRect(SDL_Window *window, const SDL_Rect *rect); +extern SDL_DECLSPEC int SDLCALL SDL_SetTextInputArea(SDL_Window *window, const SDL_Rect *rect, int cursor); + +/** + * Get the area used to type Unicode text input. + * + * This returns the values previously set by SDL_SetTextInputArea(). + * + * \param window the window for which to query the text input area. + * \param rect a pointer to an SDL_Rect filled in with the text input area, may be NULL. + * \param cursor a pointer to the offset of the current cursor location relative to `rect->x`, may be NULL. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_SetTextInputArea + */ +extern SDL_DECLSPEC int SDLCALL SDL_GetTextInputArea(SDL_Window *window, SDL_Rect *rect, int *cursor); /** * Check whether the platform has screen keyboard support. diff --git a/src/core/linux/SDL_fcitx.c b/src/core/linux/SDL_fcitx.c index bd0a8fb7b2..41895fa221 100644 --- a/src/core/linux/SDL_fcitx.c +++ b/src/core/linux/SDL_fcitx.c @@ -211,7 +211,7 @@ static DBusHandlerResult DBus_MessageFilter(DBusConnection *conn, DBusMessage *m SDL_SendEditingText("", 0, 0); } - SDL_Fcitx_UpdateTextRect(SDL_GetKeyboardFocus()); + SDL_Fcitx_UpdateTextInputArea(SDL_GetKeyboardFocus()); return DBUS_HANDLER_RESULT_HANDLED; } @@ -390,7 +390,7 @@ SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID, DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) { if (handled) { - SDL_Fcitx_UpdateTextRect(SDL_GetKeyboardFocus()); + SDL_Fcitx_UpdateTextInputArea(SDL_GetKeyboardFocus()); return SDL_TRUE; } } @@ -398,7 +398,7 @@ SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) return SDL_FALSE; } -void SDL_Fcitx_UpdateTextRect(SDL_Window *window) +void SDL_Fcitx_UpdateTextInputArea(SDL_Window *window) { int x = 0, y = 0; SDL_Rect *cursor = &fcitx_client.cursor_rect; @@ -407,7 +407,11 @@ void SDL_Fcitx_UpdateTextRect(SDL_Window *window) return; } - SDL_copyp(cursor, &window->text_input_rect); + // We'll use a square at the text input cursor location for the cursor_rect + cursor->x = window->text_input_rect.x + window->text_input_cursor; + cursor->y = window->text_input_rect.x; + cursor->w = window->text_input_rect.h; + cursor->h = window->text_input_rect.h; SDL_GetWindowPosition(window, &x, &y); diff --git a/src/core/linux/SDL_fcitx.h b/src/core/linux/SDL_fcitx.h index daddf8fd4e..75c2510e05 100644 --- a/src/core/linux/SDL_fcitx.h +++ b/src/core/linux/SDL_fcitx.h @@ -29,7 +29,7 @@ extern void SDL_Fcitx_Quit(void); extern void SDL_Fcitx_SetFocus(SDL_bool focused); extern void SDL_Fcitx_Reset(void); extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); -extern void SDL_Fcitx_UpdateTextRect(SDL_Window *window); +extern void SDL_Fcitx_UpdateTextInputArea(SDL_Window *window); extern void SDL_Fcitx_PumpEvents(void); #endif /* SDL_fcitx_h_ */ diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index 370dff7d4b..ed73cc5bd8 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -261,7 +261,7 @@ static DBusHandlerResult IBus_MessageHandler(DBusConnection *conn, DBusMessage * } } - SDL_IBus_UpdateTextRect(SDL_GetKeyboardFocus()); + SDL_IBus_UpdateTextInputArea(SDL_GetKeyboardFocus()); return DBUS_HANDLER_RESULT_HANDLED; } @@ -483,7 +483,7 @@ static SDL_bool IBus_SetupConnection(SDL_DBusContext *dbus, const char *addr) SDL_Window *window = SDL_GetKeyboardFocus(); if (SDL_TextInputActive(window)) { SDL_IBus_SetFocus(SDL_TRUE); - SDL_IBus_UpdateTextRect(window); + SDL_IBus_UpdateTextInputArea(window); } else { SDL_IBus_SetFocus(SDL_FALSE); } @@ -674,12 +674,12 @@ SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) } } - SDL_IBus_UpdateTextRect(SDL_GetKeyboardFocus()); + SDL_IBus_UpdateTextInputArea(SDL_GetKeyboardFocus()); return (result != 0); } -void SDL_IBus_UpdateTextRect(SDL_Window *window) +void SDL_IBus_UpdateTextInputArea(SDL_Window *window) { int x = 0, y = 0; SDL_DBusContext *dbus; @@ -688,7 +688,11 @@ void SDL_IBus_UpdateTextRect(SDL_Window *window) return; } - SDL_copyp(&ibus_cursor_rect, &window->text_input_rect); + // We'll use a square at the text input cursor location for the ibus_cursor + ibus_cursor_rect.x = window->text_input_rect.x + window->text_input_cursor; + ibus_cursor_rect.y = window->text_input_rect.x; + ibus_cursor_rect.w = window->text_input_rect.h; + ibus_cursor_rect.h = window->text_input_rect.h; SDL_GetWindowPosition(window, &x, &y); diff --git a/src/core/linux/SDL_ibus.h b/src/core/linux/SDL_ibus.h index 5ff90cb82d..1a6fc5bb73 100644 --- a/src/core/linux/SDL_ibus.h +++ b/src/core/linux/SDL_ibus.h @@ -44,7 +44,7 @@ extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 st /* Update the position of IBus' candidate list. If rect is NULL then this will just reposition it relative to the focused window's new position. */ -extern void SDL_IBus_UpdateTextRect(SDL_Window *window); +extern void SDL_IBus_UpdateTextInputArea(SDL_Window *window); /* Checks DBus for new IBus events, and calls SDL_SendKeyboardText / SDL_SendEditingText for each event it finds */ diff --git a/src/core/linux/SDL_ime.c b/src/core/linux/SDL_ime.c index 7f2ba82392..d9be1f0edf 100644 --- a/src/core/linux/SDL_ime.c +++ b/src/core/linux/SDL_ime.c @@ -29,7 +29,7 @@ typedef void (*SDL_IME_Quit_t)(void); typedef void (*SDL_IME_SetFocus_t)(SDL_bool); typedef void (*SDL_IME_Reset_t)(void); typedef SDL_bool (*SDL_IME_ProcessKeyEvent_t)(Uint32, Uint32, Uint8 state); -typedef void (*SDL_IME_UpdateTextRect_t)(SDL_Window *window); +typedef void (*SDL_IME_UpdateTextInputArea_t)(SDL_Window *window); typedef void (*SDL_IME_PumpEvents_t)(void); static SDL_IME_Init_t SDL_IME_Init_Real = NULL; @@ -37,7 +37,7 @@ static SDL_IME_Quit_t SDL_IME_Quit_Real = NULL; static SDL_IME_SetFocus_t SDL_IME_SetFocus_Real = NULL; static SDL_IME_Reset_t SDL_IME_Reset_Real = NULL; static SDL_IME_ProcessKeyEvent_t SDL_IME_ProcessKeyEvent_Real = NULL; -static SDL_IME_UpdateTextRect_t SDL_IME_UpdateTextRect_Real = NULL; +static SDL_IME_UpdateTextInputArea_t SDL_IME_UpdateTextInputArea_Real = NULL; static SDL_IME_PumpEvents_t SDL_IME_PumpEvents_Real = NULL; static void InitIME(void) @@ -64,7 +64,7 @@ static void InitIME(void) SDL_IME_SetFocus_Real = SDL_Fcitx_SetFocus; SDL_IME_Reset_Real = SDL_Fcitx_Reset; SDL_IME_ProcessKeyEvent_Real = SDL_Fcitx_ProcessKeyEvent; - SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect; + SDL_IME_UpdateTextInputArea_Real = SDL_Fcitx_UpdateTextInputArea; SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents; } #endif /* HAVE_FCITX */ @@ -77,7 +77,7 @@ static void InitIME(void) SDL_IME_SetFocus_Real = SDL_IBus_SetFocus; SDL_IME_Reset_Real = SDL_IBus_Reset; SDL_IME_ProcessKeyEvent_Real = SDL_IBus_ProcessKeyEvent; - SDL_IME_UpdateTextRect_Real = SDL_IBus_UpdateTextRect; + SDL_IME_UpdateTextInputArea_Real = SDL_IBus_UpdateTextInputArea; SDL_IME_PumpEvents_Real = SDL_IBus_PumpEvents; } #endif /* HAVE_IBUS_IBUS_H */ @@ -98,7 +98,7 @@ SDL_bool SDL_IME_Init(void) SDL_IME_SetFocus_Real = NULL; SDL_IME_Reset_Real = NULL; SDL_IME_ProcessKeyEvent_Real = NULL; - SDL_IME_UpdateTextRect_Real = NULL; + SDL_IME_UpdateTextInputArea_Real = NULL; SDL_IME_PumpEvents_Real = NULL; } @@ -135,10 +135,10 @@ SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) return SDL_FALSE; } -void SDL_IME_UpdateTextRect(SDL_Window *window) +void SDL_IME_UpdateTextInputArea(SDL_Window *window) { - if (SDL_IME_UpdateTextRect_Real) { - SDL_IME_UpdateTextRect_Real(window); + if (SDL_IME_UpdateTextInputArea_Real) { + SDL_IME_UpdateTextInputArea_Real(window); } } diff --git a/src/core/linux/SDL_ime.h b/src/core/linux/SDL_ime.h index 088ac53397..700f5c626c 100644 --- a/src/core/linux/SDL_ime.h +++ b/src/core/linux/SDL_ime.h @@ -29,7 +29,7 @@ extern void SDL_IME_Quit(void); extern void SDL_IME_SetFocus(SDL_bool focused); extern void SDL_IME_Reset(void); extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); -extern void SDL_IME_UpdateTextRect(SDL_Window *window); +extern void SDL_IME_UpdateTextInputArea(SDL_Window *window); extern void SDL_IME_PumpEvents(void); #endif /* SDL_ime_h_ */ diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index f6ce6ba8be..b81b894f45 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -437,6 +437,7 @@ SDL3_0.0.0 { SDL_GetSystemRAM; SDL_GetSystemTheme; SDL_GetTLS; + SDL_GetTextInputArea; SDL_GetTextureAlphaMod; SDL_GetTextureAlphaModFloat; SDL_GetTextureBlendMode; @@ -745,7 +746,7 @@ SDL3_0.0.0 { SDL_SetSurfacePalette; SDL_SetSurfaceRLE; SDL_SetTLS; - SDL_SetTextInputRect; + SDL_SetTextInputArea; SDL_SetTextureAlphaMod; SDL_SetTextureAlphaModFloat; SDL_SetTextureBlendMode; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 8e238965b6..4cfcd09b63 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -462,6 +462,7 @@ #define SDL_GetSystemRAM SDL_GetSystemRAM_REAL #define SDL_GetSystemTheme SDL_GetSystemTheme_REAL #define SDL_GetTLS SDL_GetTLS_REAL +#define SDL_GetTextInputArea SDL_GetTextInputArea_REAL #define SDL_GetTextureAlphaMod SDL_GetTextureAlphaMod_REAL #define SDL_GetTextureAlphaModFloat SDL_GetTextureAlphaModFloat_REAL #define SDL_GetTextureBlendMode SDL_GetTextureBlendMode_REAL @@ -770,7 +771,7 @@ #define SDL_SetSurfacePalette SDL_SetSurfacePalette_REAL #define SDL_SetSurfaceRLE SDL_SetSurfaceRLE_REAL #define SDL_SetTLS SDL_SetTLS_REAL -#define SDL_SetTextInputRect SDL_SetTextInputRect_REAL +#define SDL_SetTextInputArea SDL_SetTextInputArea_REAL #define SDL_SetTextureAlphaMod SDL_SetTextureAlphaMod_REAL #define SDL_SetTextureAlphaModFloat SDL_SetTextureAlphaModFloat_REAL #define SDL_SetTextureBlendMode SDL_SetTextureBlendMode_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 4780080bbf..4c43f04070 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -482,6 +482,7 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetSurfaceProperties,(SDL_Surface *a),(a),r SDL_DYNAPI_PROC(int,SDL_GetSystemRAM,(void),(),return) SDL_DYNAPI_PROC(SDL_SystemTheme,SDL_GetSystemTheme,(void),(),return) SDL_DYNAPI_PROC(void*,SDL_GetTLS,(SDL_TLSID a),(a),return) +SDL_DYNAPI_PROC(int,SDL_GetTextInputArea,(SDL_Window *a, SDL_Rect *b, int *c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_GetTextureAlphaMod,(SDL_Texture *a, Uint8 *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetTextureAlphaModFloat,(SDL_Texture *a, float *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetTextureBlendMode,(SDL_Texture *a, SDL_BlendMode *b),(a,b),return) @@ -780,7 +781,7 @@ SDL_DYNAPI_PROC(int,SDL_SetSurfaceColorspace,(SDL_Surface *a, SDL_Colorspace b), SDL_DYNAPI_PROC(int,SDL_SetSurfacePalette,(SDL_Surface *a, SDL_Palette *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetSurfaceRLE,(SDL_Surface *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetTLS,(SDL_TLSID a, const void *b, SDL_TLSDestructorCallback c),(a,b,c),return) -SDL_DYNAPI_PROC(int,SDL_SetTextInputRect,(SDL_Window *a, const SDL_Rect *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_SetTextInputArea,(SDL_Window *a, const SDL_Rect *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_SetTextureAlphaMod,(SDL_Texture *a, Uint8 b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetTextureAlphaModFloat,(SDL_Texture *a, float b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetTextureBlendMode,(SDL_Texture *a, SDL_BlendMode b),(a,b),return) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 91c86cd02b..5437a838aa 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -103,6 +103,7 @@ struct SDL_Window SDL_bool text_input_active; SDL_Rect text_input_rect; + int text_input_cursor; SDL_Rect mouse_rect; @@ -327,7 +328,7 @@ struct SDL_VideoDevice /* Text input */ int (*StartTextInput)(SDL_VideoDevice *_this, SDL_Window *window); int (*StopTextInput)(SDL_VideoDevice *_this, SDL_Window *window); - int (*UpdateTextInputRect)(SDL_VideoDevice *_this, SDL_Window *window); + int (*UpdateTextInputArea)(SDL_VideoDevice *_this, SDL_Window *window); int (*ClearComposition)(SDL_VideoDevice *_this, SDL_Window *window); /* Screen keyboard */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 69b71b3bcc..5fa53035ad 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -5074,24 +5074,39 @@ int SDL_StopTextInput(SDL_Window *window) return 0; } -int SDL_SetTextInputRect(SDL_Window *window, const SDL_Rect *rect) +int SDL_SetTextInputArea(SDL_Window *window, const SDL_Rect *rect, int cursor) { CHECK_WINDOW_MAGIC(window, -1); if (rect) { SDL_copyp(&window->text_input_rect, rect); + window->text_input_cursor = cursor; } else { SDL_zero(window->text_input_rect); + window->text_input_cursor = 0; } - if (_this && _this->UpdateTextInputRect) { - if (_this->UpdateTextInputRect(_this, window) < 0) { + if (_this && _this->UpdateTextInputArea) { + if (_this->UpdateTextInputArea(_this, window) < 0) { return -1; } } return 0; } +int SDL_GetTextInputArea(SDL_Window *window, SDL_Rect *rect, int *cursor) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (rect) { + SDL_copyp(rect, &window->text_input_rect); + } + if (cursor) { + *cursor = window->text_input_cursor; + } + return 0; +} + int SDL_ClearComposition(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, -1); diff --git a/src/video/cocoa/SDL_cocoakeyboard.h b/src/video/cocoa/SDL_cocoakeyboard.h index ccbc057b44..85a409258a 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.h +++ b/src/video/cocoa/SDL_cocoakeyboard.h @@ -29,7 +29,7 @@ extern void Cocoa_QuitKeyboard(SDL_VideoDevice *_this); extern int Cocoa_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int Cocoa_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window); -extern int Cocoa_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window); +extern int Cocoa_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); extern int Cocoa_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed); diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index b003d6910b..bda67f2884 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -368,7 +368,7 @@ int Cocoa_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window) [nswindow makeFirstResponder:data.fieldEdit]; } } - return Cocoa_UpdateTextInputRect(_this, window); + return Cocoa_UpdateTextInputArea(_this, window); } int Cocoa_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) @@ -384,7 +384,7 @@ int Cocoa_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) return 0; } -int Cocoa_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) +int Cocoa_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) { SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata; if (data.fieldEdit) { diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 0b63c248cc..c9cb9043d2 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -172,7 +172,7 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void) device->StartTextInput = Cocoa_StartTextInput; device->StopTextInput = Cocoa_StopTextInput; - device->UpdateTextInputRect = Cocoa_UpdateTextInputRect; + device->UpdateTextInputArea = Cocoa_UpdateTextInputArea; device->SetClipboardData = Cocoa_SetClipboardData; device->GetClipboardData = Cocoa_GetClipboardData; diff --git a/src/video/gdk/SDL_gdktextinput.cpp b/src/video/gdk/SDL_gdktextinput.cpp index de82500ded..3f73f66779 100644 --- a/src/video/gdk/SDL_gdktextinput.cpp +++ b/src/video/gdk/SDL_gdktextinput.cpp @@ -200,7 +200,7 @@ int GDK_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) return 0; } -int GDK_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) +int GDK_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) { /* * XGameUiShowTextEntryAsync does not allow you to set diff --git a/src/video/gdk/SDL_gdktextinput.h b/src/video/gdk/SDL_gdktextinput.h index 78c506cbf2..cbd043885c 100644 --- a/src/video/gdk/SDL_gdktextinput.h +++ b/src/video/gdk/SDL_gdktextinput.h @@ -34,7 +34,7 @@ void GDK_EnsureHints(void); int GDK_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); int GDK_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window); -int GDK_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window); +int GDK_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); int GDK_ClearComposition(SDL_VideoDevice *_this, SDL_Window *window); SDL_bool GDK_HasScreenKeyboardSupport(SDL_VideoDevice *_this); diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m index dea57315cf..916afb1d5d 100644 --- a/src/video/uikit/SDL_uikitvideo.m +++ b/src/video/uikit/SDL_uikitvideo.m @@ -100,7 +100,7 @@ static SDL_VideoDevice *UIKit_CreateDevice(void) device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard; device->HideScreenKeyboard = UIKit_HideScreenKeyboard; device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown; - device->UpdateTextInputRect = UIKit_UpdateTextInputRect; + device->UpdateTextInputArea = UIKit_UpdateTextInputArea; #endif device->SetClipboardText = UIKit_SetClipboardText; diff --git a/src/video/uikit/SDL_uikitviewcontroller.h b/src/video/uikit/SDL_uikitviewcontroller.h index 670c174fef..cfd8767dba 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/video/uikit/SDL_uikitviewcontroller.h @@ -91,5 +91,5 @@ SDL_bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this); void UIKit_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); void UIKit_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); SDL_bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window); -int UIKit_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window); +int UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); #endif diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index 1027b8d883..0d69f50fbb 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -623,7 +623,7 @@ SDL_bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window) } } -int UIKit_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) +int UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) { @autoreleasepool { SDL_uikitviewcontroller *vc = GetWindowViewController(window); diff --git a/src/video/wayland/SDL_waylandkeyboard.c b/src/video/wayland/SDL_waylandkeyboard.c index 481e706cb2..7f8d55e60a 100644 --- a/src/video/wayland/SDL_waylandkeyboard.c +++ b/src/video/wayland/SDL_waylandkeyboard.c @@ -83,7 +83,7 @@ int Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window) WAYLAND_xkb_compose_state_reset(input->xkb.compose_state); } - return Wayland_UpdateTextInputRect(_this, window); + return Wayland_UpdateTextInputArea(_this, window); } int Wayland_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) @@ -110,7 +110,7 @@ int Wayland_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) return 0; } -int Wayland_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) +int Wayland_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) { SDL_VideoData *driverdata = _this->driverdata; if (driverdata->text_input_manager) { @@ -130,7 +130,7 @@ int Wayland_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) #ifdef SDL_USE_IME else { - SDL_IME_UpdateTextRect(window); + SDL_IME_UpdateTextInputArea(window); } #endif return 0; diff --git a/src/video/wayland/SDL_waylandkeyboard.h b/src/video/wayland/SDL_waylandkeyboard.h index b42bb11b91..8550aec2b4 100644 --- a/src/video/wayland/SDL_waylandkeyboard.h +++ b/src/video/wayland/SDL_waylandkeyboard.h @@ -34,7 +34,7 @@ extern int Wayland_InitKeyboard(SDL_VideoDevice *_this); extern void Wayland_QuitKeyboard(SDL_VideoDevice *_this); extern int Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int Wayland_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window); -extern int Wayland_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window); +extern int Wayland_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); extern SDL_bool Wayland_HasScreenKeyboardSupport(SDL_VideoDevice *_this); #endif /* SDL_waylandkeyboard_h_ */ diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 893fd1bd9a..6f07959e25 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -511,7 +511,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void) device->HasClipboardData = Wayland_HasClipboardData; device->StartTextInput = Wayland_StartTextInput; device->StopTextInput = Wayland_StopTextInput; - device->UpdateTextInputRect = Wayland_UpdateTextInputRect; + device->UpdateTextInputArea = Wayland_UpdateTextInputArea; #ifdef SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary; diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index 76973f0079..80016fea2c 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -36,10 +36,10 @@ #else #define SDL_DebugIMELog(...) #endif -static int IME_Init(SDL_VideoData *videodata, HWND hwnd); +static int IME_Init(SDL_VideoData *videodata, SDL_Window *window); static void IME_Enable(SDL_VideoData *videodata, HWND hwnd); static void IME_Disable(SDL_VideoData *videodata, HWND hwnd); -static void IME_SetTextInputRect(SDL_VideoData *videodata, const SDL_Rect *rect); +static void IME_SetTextInputArea(SDL_VideoData *videodata, const SDL_Rect *rect, int cursor); static void IME_Quit(SDL_VideoData *videodata); #endif /* !SDL_DISABLE_WINDOWS_IME */ @@ -208,10 +208,10 @@ int WIN_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window) #ifndef SDL_DISABLE_WINDOWS_IME HWND hwnd = window->driverdata->hwnd; SDL_VideoData *videodata = _this->driverdata; - IME_Init(videodata, hwnd); + IME_Init(videodata, window); IME_Enable(videodata, hwnd); - WIN_UpdateTextInputRect(_this, window); + WIN_UpdateTextInputArea(_this, window); #endif /* !SDL_DISABLE_WINDOWS_IME */ return 0; @@ -224,19 +224,19 @@ int WIN_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) #ifndef SDL_DISABLE_WINDOWS_IME HWND hwnd = window->driverdata->hwnd; SDL_VideoData *videodata = _this->driverdata; - IME_Init(videodata, hwnd); + IME_Init(videodata, window); IME_Disable(videodata, hwnd); #endif /* !SDL_DISABLE_WINDOWS_IME */ return 0; } -int WIN_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) +int WIN_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) { #ifndef SDL_DISABLE_WINDOWS_IME SDL_VideoData *data = _this->driverdata; - IME_SetTextInputRect(data, &window->text_input_rect); + IME_SetTextInputArea(data, &window->text_input_rect, window->text_input_cursor); #endif /* !SDL_DISABLE_WINDOWS_IME */ return 0; @@ -313,7 +313,7 @@ DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3, 0x7594, 0x4CB0, 0xBB, 0x58, 0x69, 0x static void IME_UpdateInputLocale(SDL_VideoData *videodata); static void IME_ClearComposition(SDL_VideoData *videodata); -static void IME_SetWindow(SDL_VideoData *videodata, HWND hwnd); +static void IME_SetWindow(SDL_VideoData *videodata, SDL_Window *window); static void IME_SetupAPI(SDL_VideoData *videodata); static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex); static void IME_SendEditingEvent(SDL_VideoData *videodata); @@ -329,8 +329,9 @@ static SDL_bool WIN_ShouldShowNativeUI() return SDL_GetHintBoolean(SDL_HINT_IME_SHOW_UI, SDL_TRUE); } -static int IME_Init(SDL_VideoData *videodata, HWND hwnd) +static int IME_Init(SDL_VideoData *videodata, SDL_Window *window) { + HWND hwnd = window->driverdata->hwnd; HRESULT hResult = S_OK; if (videodata->ime_initialized) { @@ -360,7 +361,7 @@ static int IME_Init(SDL_VideoData *videodata, HWND hwnd) videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMCC"); /* *INDENT-ON* */ /* clang-format on */ - IME_SetWindow(videodata, hwnd); + IME_SetWindow(videodata, window); videodata->ime_himc = ImmGetContext(hwnd); ImmReleaseContext(hwnd, videodata->ime_himc); if (!videodata->ime_himc) { @@ -678,9 +679,16 @@ static void IME_SetupAPI(SDL_VideoData *videodata) } } -static void IME_SetWindow(SDL_VideoData *videodata, HWND hwnd) +static void IME_SetWindow(SDL_VideoData *videodata, SDL_Window *window) { - videodata->ime_hwnd_current = hwnd; + HWND hwnd = window->driverdata->hwnd; + + if (hwnd != videodata->ime_hwnd_current) { + videodata->ime_hwnd_current = hwnd; + SDL_zero(videodata->ime_composition_area); + SDL_zero(videodata->ime_candidate_area); + } + if (videodata->ime_threadmgr) { struct ITfDocumentMgr *document_mgr = 0; if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) { @@ -689,42 +697,45 @@ static void IME_SetWindow(SDL_VideoData *videodata, HWND hwnd) } } } - IME_SetTextInputRect(videodata, &videodata->ime_rect); + + IME_SetTextInputArea(videodata, &window->text_input_rect, window->text_input_cursor); } -static void IME_SetTextInputRect(SDL_VideoData *videodata, const SDL_Rect *rect) +static void IME_SetTextInputArea(SDL_VideoData *videodata, const SDL_Rect *rect, int cursor) { - HIMC himc = 0; - - if (SDL_memcmp(rect, &videodata->ime_rect, sizeof(*rect)) == 0) { - return; - } - - videodata->ime_rect = *rect; + HIMC himc; himc = ImmGetContext(videodata->ime_hwnd_current); if (himc) { COMPOSITIONFORM cof; CANDIDATEFORM caf; + SDL_zero(cof); cof.dwStyle = CFS_RECT; - cof.ptCurrentPos.x = videodata->ime_rect.x; - cof.ptCurrentPos.y = videodata->ime_rect.y; - cof.rcArea.left = videodata->ime_rect.x; - cof.rcArea.right = (LONG)videodata->ime_rect.x + videodata->ime_rect.w; - cof.rcArea.top = videodata->ime_rect.y; - cof.rcArea.bottom = (LONG)videodata->ime_rect.y + videodata->ime_rect.h; - ImmSetCompositionWindow(himc, &cof); + cof.ptCurrentPos.x = rect->x + cursor; + cof.ptCurrentPos.y = rect->y; + cof.rcArea.left = rect->x; + cof.rcArea.right = (LONG)rect->x + rect->w; + cof.rcArea.top = rect->y; + cof.rcArea.bottom = (LONG)rect->y + rect->h; + if (SDL_memcmp(&cof, &videodata->ime_composition_area, sizeof(cof)) != 0) { + SDL_copyp(&videodata->ime_composition_area, &cof); + ImmSetCompositionWindow(himc, &cof); + } + SDL_zero(caf); caf.dwIndex = 0; caf.dwStyle = CFS_EXCLUDE; - caf.ptCurrentPos.x = videodata->ime_rect.x; - caf.ptCurrentPos.y = videodata->ime_rect.y; - caf.rcArea.left = videodata->ime_rect.x; - caf.rcArea.right = (LONG)videodata->ime_rect.x + videodata->ime_rect.w; - caf.rcArea.top = videodata->ime_rect.y; - caf.rcArea.bottom = (LONG)videodata->ime_rect.y + videodata->ime_rect.h; - ImmSetCandidateWindow(himc, &caf); + caf.ptCurrentPos.x = rect->x + cursor; + caf.ptCurrentPos.y = rect->y; + caf.rcArea.left = rect->x; + caf.rcArea.right = (LONG)rect->x + rect->w; + caf.rcArea.top = rect->y; + caf.rcArea.bottom = (LONG)rect->y + rect->h; + if (SDL_memcmp(&caf, &videodata->ime_candidate_area, sizeof(caf)) != 0) { + SDL_copyp(&videodata->ime_candidate_area, &caf); + ImmSetCandidateWindow(himc, &caf); + } ImmReleaseContext(videodata->ime_hwnd_current, himc); } diff --git a/src/video/windows/SDL_windowskeyboard.h b/src/video/windows/SDL_windowskeyboard.h index 0c614b5488..e62ce045f8 100644 --- a/src/video/windows/SDL_windowskeyboard.h +++ b/src/video/windows/SDL_windowskeyboard.h @@ -31,7 +31,7 @@ extern void WIN_ResetDeadKeys(void); extern int WIN_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int WIN_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window); -extern int WIN_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window); +extern int WIN_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); extern int WIN_ClearComposition(SDL_VideoDevice *_this, SDL_Window *window); extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 889f5e58ab..688bc04b6a 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -268,7 +268,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void) #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) device->StartTextInput = WIN_StartTextInput; device->StopTextInput = WIN_StopTextInput; - device->UpdateTextInputRect = WIN_UpdateTextInputRect; + device->UpdateTextInputArea = WIN_UpdateTextInputArea; device->ClearComposition = WIN_ClearComposition; device->SetClipboardData = WIN_SetClipboardData; @@ -281,7 +281,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void) device->StartTextInput = GDK_StartTextInput; device->StopTextInput = GDK_StopTextInput; - device->SetTextInputRect = GDK_SetTextInputRect; + device->SetTextInputArea = GDK_SetTextInputArea; device->ClearComposition = GDK_ClearComposition; device->HasScreenKeyboardSupport = GDK_HasScreenKeyboardSupport; diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index 97d196a088..3d078619ad 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -447,7 +447,8 @@ struct SDL_VideoData int ime_candlistindexbase; SDL_bool ime_horizontal_candidates; - SDL_Rect ime_rect; + COMPOSITIONFORM ime_composition_area; + CANDIDATEFORM ime_candidate_area; HKL ime_hkl; void *ime_himm32; diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 560d316ca2..daf6d93798 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1293,7 +1293,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) #ifdef SDL_USE_IME if (SDL_TextInputActive(data->window)) { /* Update IME candidate list position */ - SDL_IME_UpdateTextRect(NULL); + SDL_IME_UpdateTextInputArea(NULL); } #endif for (w = data->window->first_child; w; w = w->next_sibling) { diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 6f7a6d3e0c..eed27218f3 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -448,7 +448,7 @@ int X11_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window) { X11_ResetXIM(_this, window); - return X11_UpdateTextInputRect(_this, window); + return X11_UpdateTextInputArea(_this, window); } int X11_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) @@ -460,10 +460,10 @@ int X11_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) return 0; } -int X11_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) +int X11_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) { #ifdef SDL_USE_IME - SDL_IME_UpdateTextRect(window); + SDL_IME_UpdateTextInputArea(window); #endif return 0; } diff --git a/src/video/x11/SDL_x11keyboard.h b/src/video/x11/SDL_x11keyboard.h index 7fe7384496..60e96af0bd 100644 --- a/src/video/x11/SDL_x11keyboard.h +++ b/src/video/x11/SDL_x11keyboard.h @@ -28,7 +28,7 @@ extern void X11_UpdateKeymap(SDL_VideoDevice *_this, SDL_bool send_event); extern void X11_QuitKeyboard(SDL_VideoDevice *_this); extern int X11_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int X11_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window); -extern int X11_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window); +extern int X11_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); extern SDL_bool X11_HasScreenKeyboardSupport(SDL_VideoDevice *_this); extern void X11_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); extern void X11_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index aba3cfc728..4f59aaeda5 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -267,7 +267,7 @@ static SDL_VideoDevice *X11_CreateDevice(void) device->HasPrimarySelectionText = X11_HasPrimarySelectionText; device->StartTextInput = X11_StartTextInput; device->StopTextInput = X11_StopTextInput; - device->UpdateTextInputRect = X11_UpdateTextInputRect; + device->UpdateTextInputArea = X11_UpdateTextInputArea; device->HasScreenKeyboardSupport = X11_HasScreenKeyboardSupport; device->ShowScreenKeyboard = X11_ShowScreenKeyboard; device->HideScreenKeyboard = X11_HideScreenKeyboard; diff --git a/test/checkkeys.c b/test/checkkeys.c index 052a7b98d6..36aa88d439 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -73,23 +73,21 @@ static void UpdateTextWindowInputRect(SDL_WindowID id) SDLTest_TextWindow *textwindow = windowstates[i].textwindow; int w, h; SDL_Rect rect; + int cursor = 0; int current = textwindow->current; const char *current_line = textwindow->lines[current]; SDL_GetWindowSize(state->windows[i], &w, &h); - rect.x = (int)TEXT_WINDOW_OFFSET_X; if (current_line) { - rect.x += (int)SDL_utf8strlen(current_line) * FONT_CHARACTER_SIZE; + cursor = (int)SDL_utf8strlen(current_line) * FONT_CHARACTER_SIZE; } + + rect.x = (int)TEXT_WINDOW_OFFSET_X; rect.y = (int)TEXT_WINDOW_OFFSET_Y + current * FONT_LINE_HEIGHT; -#if 1 - rect.w = FONT_CHARACTER_SIZE; -#else rect.w = (int)(w - (2 * TEXT_WINDOW_OFFSET_X)); -#endif - rect.h = FONT_LINE_HEIGHT; - SDL_SetTextInputRect(state->windows[i], &rect); + rect.h = FONT_CHARACTER_SIZE; + SDL_SetTextInputArea(state->windows[i], &rect, cursor); return; } } diff --git a/test/testautomation_keyboard.c b/test/testautomation_keyboard.c index d15d170520..25a4d9b7f6 100644 --- a/test/testautomation_keyboard.c +++ b/test/testautomation_keyboard.c @@ -361,14 +361,14 @@ static int keyboard_startStopTextInput(void *arg) return TEST_COMPLETED; } -/* Internal function to test SDL_SetTextInputRect */ -static void testSetTextInputRect(SDL_Window *window, SDL_Rect refRect) +/* Internal function to test SDL_SetTextInputArea */ +static void testSetTextInputArea(SDL_Window *window, SDL_Rect refRect) { SDL_Rect testRect; testRect = refRect; - SDL_SetTextInputRect(window, &testRect); - SDLTest_AssertPass("Call to SDL_SetTextInputRect with refRect(x:%d,y:%d,w:%d,h:%d)", refRect.x, refRect.y, refRect.w, refRect.h); + SDL_SetTextInputArea(window, &testRect, 0); + SDLTest_AssertPass("Call to SDL_SetTextInputArea with refRect(x:%d,y:%d,w:%d,h:%d)", refRect.x, refRect.y, refRect.w, refRect.h); SDLTest_AssertCheck( (refRect.x == testRect.x) && (refRect.y == testRect.y) && (refRect.w == testRect.w) && (refRect.h == testRect.h), "Check that input data was not modified, expected: x:%d,y:%d,w:%d,h:%d, got: x:%d,y:%d,w:%d,h:%d", @@ -377,11 +377,11 @@ static void testSetTextInputRect(SDL_Window *window, SDL_Rect refRect) } /** - * Check call to SDL_SetTextInputRect + * Check call to SDL_SetTextInputArea * - * \sa SDL_SetTextInputRect + * \sa SDL_SetTextInputArea */ -static int keyboard_setTextInputRect(void *arg) +static int keyboard_setTextInputArea(void *arg) { SDL_Window *window = SDL_GetKeyboardFocus(); SDL_Rect refRect; @@ -391,77 +391,77 @@ static int keyboard_setTextInputRect(void *arg) refRect.y = SDLTest_RandomIntegerInRange(1, 50); refRect.w = SDLTest_RandomIntegerInRange(10, 50); refRect.h = SDLTest_RandomIntegerInRange(10, 50); - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* Normal visible refRect, origin 0,0 */ refRect.x = 0; refRect.y = 0; refRect.w = SDLTest_RandomIntegerInRange(10, 50); refRect.h = SDLTest_RandomIntegerInRange(10, 50); - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* 1Pixel refRect */ refRect.x = SDLTest_RandomIntegerInRange(10, 50); refRect.y = SDLTest_RandomIntegerInRange(10, 50); refRect.w = 1; refRect.h = 1; - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* 0pixel refRect */ refRect.x = 1; refRect.y = 1; refRect.w = 1; refRect.h = 0; - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* 0pixel refRect */ refRect.x = 1; refRect.y = 1; refRect.w = 0; refRect.h = 1; - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* 0pixel refRect */ refRect.x = 1; refRect.y = 1; refRect.w = 0; refRect.h = 0; - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* 0pixel refRect */ refRect.x = 0; refRect.y = 0; refRect.w = 0; refRect.h = 0; - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* negative refRect */ refRect.x = SDLTest_RandomIntegerInRange(-200, -100); refRect.y = SDLTest_RandomIntegerInRange(-200, -100); refRect.w = 50; refRect.h = 50; - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* oversized refRect */ refRect.x = SDLTest_RandomIntegerInRange(1, 50); refRect.y = SDLTest_RandomIntegerInRange(1, 50); refRect.w = 5000; refRect.h = 5000; - testSetTextInputRect(window, refRect); + testSetTextInputArea(window, refRect); /* NULL refRect */ - SDL_SetTextInputRect(window, NULL); - SDLTest_AssertPass("Call to SDL_SetTextInputRect(NULL)"); + SDL_SetTextInputArea(window, NULL, 0); + SDLTest_AssertPass("Call to SDL_SetTextInputArea(NULL)"); return TEST_COMPLETED; } /** - * Check call to SDL_SetTextInputRect with invalid data + * Check call to SDL_SetTextInputArea with invalid data * - * \sa SDL_SetTextInputRect + * \sa SDL_SetTextInputArea */ -static int keyboard_setTextInputRectNegative(void *arg) +static int keyboard_setTextInputAreaNegative(void *arg) { /* Some platforms set also an error message; prepare for checking it */ #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_ANDROID) || defined(SDL_VIDEO_DRIVER_COCOA) @@ -473,8 +473,8 @@ static int keyboard_setTextInputRectNegative(void *arg) #endif /* NULL refRect */ - SDL_SetTextInputRect(SDL_GetKeyboardFocus(), NULL); - SDLTest_AssertPass("Call to SDL_SetTextInputRect(NULL)"); + SDL_SetTextInputArea(SDL_GetKeyboardFocus(), NULL, 0); + SDLTest_AssertPass("Call to SDL_SetTextInputArea(NULL)"); /* Some platforms set also an error message; so check it */ #if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_ANDROID) || defined(SDL_VIDEO_DRIVER_COCOA) @@ -666,11 +666,11 @@ static const SDLTest_TestCaseReference keyboardTest7 = { }; static const SDLTest_TestCaseReference keyboardTest8 = { - (SDLTest_TestCaseFp)keyboard_setTextInputRect, "keyboard_setTextInputRect", "Check call to SDL_SetTextInputRect", TEST_ENABLED + (SDLTest_TestCaseFp)keyboard_setTextInputArea, "keyboard_setTextInputArea", "Check call to SDL_SetTextInputArea", TEST_ENABLED }; static const SDLTest_TestCaseReference keyboardTest9 = { - (SDLTest_TestCaseFp)keyboard_setTextInputRectNegative, "keyboard_setTextInputRectNegative", "Check call to SDL_SetTextInputRect with invalid data", TEST_ENABLED + (SDLTest_TestCaseFp)keyboard_setTextInputAreaNegative, "keyboard_setTextInputAreaNegative", "Check call to SDL_SetTextInputArea with invalid data", TEST_ENABLED }; static const SDLTest_TestCaseReference keyboardTest10 = { diff --git a/test/testime.c b/test/testime.c index 0adb9e2242..24d3006537 100644 --- a/test/testime.c +++ b/test/testime.c @@ -457,6 +457,8 @@ static Uint32 utf8_decode(char *p, size_t len) static void InitInput(void) { + int i; + /* Prepare a rect for text input */ textRect.x = textRect.y = 100.0f; textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x; @@ -466,7 +468,9 @@ static void InitInput(void) markedRect = textRect; markedText[0] = 0; - SDL_StartTextInput(state->windows[0]); + for (i = 0; i < state->num_windows; ++i) { + SDL_StartTextInput(state->windows[i]); + } } @@ -649,6 +653,18 @@ static void DrawCandidates(int rendererID, SDL_FRect *cursorRect) } } +static void UpdateTextInputArea(SDL_Window *window, const SDL_FRect *cursorRect) +{ + SDL_Rect rect; + int cursor_offset = (int)(cursorRect->x - textRect.x); + + rect.x = (int)textRect.x; + rect.y = (int)textRect.y; + rect.w = (int)textRect.w; + rect.h = (int)textRect.h; + SDL_SetTextInputArea(window, &rect, cursor_offset); +} + static void CleanupVideo(void) { SDL_StopTextInput(state->windows[0]); @@ -827,16 +843,8 @@ static void RedrawWindow(int rendererID) /* Draw the candidates */ DrawCandidates(rendererID, &cursorRect); - { - SDL_Rect inputrect; - - /* The input rect is a square at the cursor insertion point */ - inputrect.x = (int)cursorRect.x; - inputrect.y = (int)cursorRect.y; - inputrect.w = (int)cursorRect.h; - inputrect.h = (int)cursorRect.h; - SDL_SetTextInputRect(state->windows[0], &inputrect); - } + /* Update the area used to draw composition UI */ + UpdateTextInputArea(state->windows[0], &cursorRect); } static void Redraw(void)