SDL_SetTextInputRect() has been renamed to SDL_SetTextInputArea()

The new function includes the cursor position so IME UI elements can be placed relative to the cursor, as well as having the whole text area available so on-screen keyboards can avoid it.
This commit is contained in:
Sam Lantinga 2024-06-28 13:17:04 -07:00
parent e324c7d692
commit bdd531986b
35 changed files with 201 additions and 148 deletions

View file

@ -917,6 +917,7 @@ The following functions have been renamed:
The following functions have been removed: The following functions have been removed:
* SDL_IsTextInputShown() * SDL_IsTextInputShown()
* SDL_SetTextInputRect() - replaced with SDL_SetTextInputArea()
The following structures have been removed: The following structures have been removed:
* SDL_Keysym * SDL_Keysym

View file

@ -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. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_SetTextInputRect * \sa SDL_SetTextInputArea
* \sa SDL_StopTextInput * \sa SDL_StopTextInput
* \sa SDL_TextInputActive * \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); 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, * \param window the window for which to set the text input area.
* without covering the text being inputted. * \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.
* 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).
* \returns 0 on success or a negative error code on failure; call * \returns 0 on success or a negative error code on failure; call
* SDL_GetError() for more information. * SDL_GetError() for more information.
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_GetTextInputArea
* \sa SDL_StartTextInput * \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. * Check whether the platform has screen keyboard support.

View file

@ -211,7 +211,7 @@ static DBusHandlerResult DBus_MessageFilter(DBusConnection *conn, DBusMessage *m
SDL_SendEditingText("", 0, 0); SDL_SendEditingText("", 0, 0);
} }
SDL_Fcitx_UpdateTextRect(SDL_GetKeyboardFocus()); SDL_Fcitx_UpdateTextInputArea(SDL_GetKeyboardFocus());
return DBUS_HANDLER_RESULT_HANDLED; 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_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)) { DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) {
if (handled) { if (handled) {
SDL_Fcitx_UpdateTextRect(SDL_GetKeyboardFocus()); SDL_Fcitx_UpdateTextInputArea(SDL_GetKeyboardFocus());
return SDL_TRUE; return SDL_TRUE;
} }
} }
@ -398,7 +398,7 @@ SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
return SDL_FALSE; return SDL_FALSE;
} }
void SDL_Fcitx_UpdateTextRect(SDL_Window *window) void SDL_Fcitx_UpdateTextInputArea(SDL_Window *window)
{ {
int x = 0, y = 0; int x = 0, y = 0;
SDL_Rect *cursor = &fcitx_client.cursor_rect; SDL_Rect *cursor = &fcitx_client.cursor_rect;
@ -407,7 +407,11 @@ void SDL_Fcitx_UpdateTextRect(SDL_Window *window)
return; 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); SDL_GetWindowPosition(window, &x, &y);

View file

@ -29,7 +29,7 @@ extern void SDL_Fcitx_Quit(void);
extern void SDL_Fcitx_SetFocus(SDL_bool focused); extern void SDL_Fcitx_SetFocus(SDL_bool focused);
extern void SDL_Fcitx_Reset(void); extern void SDL_Fcitx_Reset(void);
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); 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); extern void SDL_Fcitx_PumpEvents(void);
#endif /* SDL_fcitx_h_ */ #endif /* SDL_fcitx_h_ */

View file

@ -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; 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(); SDL_Window *window = SDL_GetKeyboardFocus();
if (SDL_TextInputActive(window)) { if (SDL_TextInputActive(window)) {
SDL_IBus_SetFocus(SDL_TRUE); SDL_IBus_SetFocus(SDL_TRUE);
SDL_IBus_UpdateTextRect(window); SDL_IBus_UpdateTextInputArea(window);
} else { } else {
SDL_IBus_SetFocus(SDL_FALSE); 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); return (result != 0);
} }
void SDL_IBus_UpdateTextRect(SDL_Window *window) void SDL_IBus_UpdateTextInputArea(SDL_Window *window)
{ {
int x = 0, y = 0; int x = 0, y = 0;
SDL_DBusContext *dbus; SDL_DBusContext *dbus;
@ -688,7 +688,11 @@ void SDL_IBus_UpdateTextRect(SDL_Window *window)
return; 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); SDL_GetWindowPosition(window, &x, &y);

View file

@ -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 /* 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. */ 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 / /* Checks DBus for new IBus events, and calls SDL_SendKeyboardText /
SDL_SendEditingText for each event it finds */ SDL_SendEditingText for each event it finds */

View file

@ -29,7 +29,7 @@ typedef void (*SDL_IME_Quit_t)(void);
typedef void (*SDL_IME_SetFocus_t)(SDL_bool); typedef void (*SDL_IME_SetFocus_t)(SDL_bool);
typedef void (*SDL_IME_Reset_t)(void); typedef void (*SDL_IME_Reset_t)(void);
typedef SDL_bool (*SDL_IME_ProcessKeyEvent_t)(Uint32, Uint32, Uint8 state); 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); typedef void (*SDL_IME_PumpEvents_t)(void);
static SDL_IME_Init_t SDL_IME_Init_Real = NULL; 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_SetFocus_t SDL_IME_SetFocus_Real = NULL;
static SDL_IME_Reset_t SDL_IME_Reset_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_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 SDL_IME_PumpEvents_t SDL_IME_PumpEvents_Real = NULL;
static void InitIME(void) static void InitIME(void)
@ -64,7 +64,7 @@ static void InitIME(void)
SDL_IME_SetFocus_Real = SDL_Fcitx_SetFocus; SDL_IME_SetFocus_Real = SDL_Fcitx_SetFocus;
SDL_IME_Reset_Real = SDL_Fcitx_Reset; SDL_IME_Reset_Real = SDL_Fcitx_Reset;
SDL_IME_ProcessKeyEvent_Real = SDL_Fcitx_ProcessKeyEvent; 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; SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents;
} }
#endif /* HAVE_FCITX */ #endif /* HAVE_FCITX */
@ -77,7 +77,7 @@ static void InitIME(void)
SDL_IME_SetFocus_Real = SDL_IBus_SetFocus; SDL_IME_SetFocus_Real = SDL_IBus_SetFocus;
SDL_IME_Reset_Real = SDL_IBus_Reset; SDL_IME_Reset_Real = SDL_IBus_Reset;
SDL_IME_ProcessKeyEvent_Real = SDL_IBus_ProcessKeyEvent; 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; SDL_IME_PumpEvents_Real = SDL_IBus_PumpEvents;
} }
#endif /* HAVE_IBUS_IBUS_H */ #endif /* HAVE_IBUS_IBUS_H */
@ -98,7 +98,7 @@ SDL_bool SDL_IME_Init(void)
SDL_IME_SetFocus_Real = NULL; SDL_IME_SetFocus_Real = NULL;
SDL_IME_Reset_Real = NULL; SDL_IME_Reset_Real = NULL;
SDL_IME_ProcessKeyEvent_Real = NULL; SDL_IME_ProcessKeyEvent_Real = NULL;
SDL_IME_UpdateTextRect_Real = NULL; SDL_IME_UpdateTextInputArea_Real = NULL;
SDL_IME_PumpEvents_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; return SDL_FALSE;
} }
void SDL_IME_UpdateTextRect(SDL_Window *window) void SDL_IME_UpdateTextInputArea(SDL_Window *window)
{ {
if (SDL_IME_UpdateTextRect_Real) { if (SDL_IME_UpdateTextInputArea_Real) {
SDL_IME_UpdateTextRect_Real(window); SDL_IME_UpdateTextInputArea_Real(window);
} }
} }

View file

@ -29,7 +29,7 @@ extern void SDL_IME_Quit(void);
extern void SDL_IME_SetFocus(SDL_bool focused); extern void SDL_IME_SetFocus(SDL_bool focused);
extern void SDL_IME_Reset(void); extern void SDL_IME_Reset(void);
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); 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); extern void SDL_IME_PumpEvents(void);
#endif /* SDL_ime_h_ */ #endif /* SDL_ime_h_ */

View file

@ -437,6 +437,7 @@ SDL3_0.0.0 {
SDL_GetSystemRAM; SDL_GetSystemRAM;
SDL_GetSystemTheme; SDL_GetSystemTheme;
SDL_GetTLS; SDL_GetTLS;
SDL_GetTextInputArea;
SDL_GetTextureAlphaMod; SDL_GetTextureAlphaMod;
SDL_GetTextureAlphaModFloat; SDL_GetTextureAlphaModFloat;
SDL_GetTextureBlendMode; SDL_GetTextureBlendMode;
@ -745,7 +746,7 @@ SDL3_0.0.0 {
SDL_SetSurfacePalette; SDL_SetSurfacePalette;
SDL_SetSurfaceRLE; SDL_SetSurfaceRLE;
SDL_SetTLS; SDL_SetTLS;
SDL_SetTextInputRect; SDL_SetTextInputArea;
SDL_SetTextureAlphaMod; SDL_SetTextureAlphaMod;
SDL_SetTextureAlphaModFloat; SDL_SetTextureAlphaModFloat;
SDL_SetTextureBlendMode; SDL_SetTextureBlendMode;

View file

@ -462,6 +462,7 @@
#define SDL_GetSystemRAM SDL_GetSystemRAM_REAL #define SDL_GetSystemRAM SDL_GetSystemRAM_REAL
#define SDL_GetSystemTheme SDL_GetSystemTheme_REAL #define SDL_GetSystemTheme SDL_GetSystemTheme_REAL
#define SDL_GetTLS SDL_GetTLS_REAL #define SDL_GetTLS SDL_GetTLS_REAL
#define SDL_GetTextInputArea SDL_GetTextInputArea_REAL
#define SDL_GetTextureAlphaMod SDL_GetTextureAlphaMod_REAL #define SDL_GetTextureAlphaMod SDL_GetTextureAlphaMod_REAL
#define SDL_GetTextureAlphaModFloat SDL_GetTextureAlphaModFloat_REAL #define SDL_GetTextureAlphaModFloat SDL_GetTextureAlphaModFloat_REAL
#define SDL_GetTextureBlendMode SDL_GetTextureBlendMode_REAL #define SDL_GetTextureBlendMode SDL_GetTextureBlendMode_REAL
@ -770,7 +771,7 @@
#define SDL_SetSurfacePalette SDL_SetSurfacePalette_REAL #define SDL_SetSurfacePalette SDL_SetSurfacePalette_REAL
#define SDL_SetSurfaceRLE SDL_SetSurfaceRLE_REAL #define SDL_SetSurfaceRLE SDL_SetSurfaceRLE_REAL
#define SDL_SetTLS SDL_SetTLS_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_SetTextureAlphaMod SDL_SetTextureAlphaMod_REAL
#define SDL_SetTextureAlphaModFloat SDL_SetTextureAlphaModFloat_REAL #define SDL_SetTextureAlphaModFloat SDL_SetTextureAlphaModFloat_REAL
#define SDL_SetTextureBlendMode SDL_SetTextureBlendMode_REAL #define SDL_SetTextureBlendMode SDL_SetTextureBlendMode_REAL

View file

@ -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(int,SDL_GetSystemRAM,(void),(),return)
SDL_DYNAPI_PROC(SDL_SystemTheme,SDL_GetSystemTheme,(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(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_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_GetTextureAlphaModFloat,(SDL_Texture *a, float *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetTextureBlendMode,(SDL_Texture *a, SDL_BlendMode *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_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_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_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_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_SetTextureAlphaModFloat,(SDL_Texture *a, float b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_SetTextureBlendMode,(SDL_Texture *a, SDL_BlendMode b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetTextureBlendMode,(SDL_Texture *a, SDL_BlendMode b),(a,b),return)

View file

@ -103,6 +103,7 @@ struct SDL_Window
SDL_bool text_input_active; SDL_bool text_input_active;
SDL_Rect text_input_rect; SDL_Rect text_input_rect;
int text_input_cursor;
SDL_Rect mouse_rect; SDL_Rect mouse_rect;
@ -327,7 +328,7 @@ struct SDL_VideoDevice
/* Text input */ /* Text input */
int (*StartTextInput)(SDL_VideoDevice *_this, SDL_Window *window); int (*StartTextInput)(SDL_VideoDevice *_this, SDL_Window *window);
int (*StopTextInput)(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); int (*ClearComposition)(SDL_VideoDevice *_this, SDL_Window *window);
/* Screen keyboard */ /* Screen keyboard */

View file

@ -5074,24 +5074,39 @@ int SDL_StopTextInput(SDL_Window *window)
return 0; 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); CHECK_WINDOW_MAGIC(window, -1);
if (rect) { if (rect) {
SDL_copyp(&window->text_input_rect, rect); SDL_copyp(&window->text_input_rect, rect);
window->text_input_cursor = cursor;
} else { } else {
SDL_zero(window->text_input_rect); SDL_zero(window->text_input_rect);
window->text_input_cursor = 0;
} }
if (_this && _this->UpdateTextInputRect) { if (_this && _this->UpdateTextInputArea) {
if (_this->UpdateTextInputRect(_this, window) < 0) { if (_this->UpdateTextInputArea(_this, window) < 0) {
return -1; return -1;
} }
} }
return 0; 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) int SDL_ClearComposition(SDL_Window *window)
{ {
CHECK_WINDOW_MAGIC(window, -1); CHECK_WINDOW_MAGIC(window, -1);

View file

@ -29,7 +29,7 @@ extern void Cocoa_QuitKeyboard(SDL_VideoDevice *_this);
extern int Cocoa_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int Cocoa_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window);
extern int Cocoa_StopTextInput(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); extern int Cocoa_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool grabbed);

View file

@ -368,7 +368,7 @@ int Cocoa_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window)
[nswindow makeFirstResponder:data.fieldEdit]; [nswindow makeFirstResponder:data.fieldEdit];
} }
} }
return Cocoa_UpdateTextInputRect(_this, window); return Cocoa_UpdateTextInputArea(_this, window);
} }
int Cocoa_StopTextInput(SDL_VideoDevice *_this, SDL_Window *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; 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; SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->driverdata;
if (data.fieldEdit) { if (data.fieldEdit) {

View file

@ -172,7 +172,7 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void)
device->StartTextInput = Cocoa_StartTextInput; device->StartTextInput = Cocoa_StartTextInput;
device->StopTextInput = Cocoa_StopTextInput; device->StopTextInput = Cocoa_StopTextInput;
device->UpdateTextInputRect = Cocoa_UpdateTextInputRect; device->UpdateTextInputArea = Cocoa_UpdateTextInputArea;
device->SetClipboardData = Cocoa_SetClipboardData; device->SetClipboardData = Cocoa_SetClipboardData;
device->GetClipboardData = Cocoa_GetClipboardData; device->GetClipboardData = Cocoa_GetClipboardData;

View file

@ -200,7 +200,7 @@ int GDK_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window)
return 0; 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 * XGameUiShowTextEntryAsync does not allow you to set

View file

@ -34,7 +34,7 @@ void GDK_EnsureHints(void);
int GDK_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); int GDK_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window);
int GDK_StopTextInput(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); int GDK_ClearComposition(SDL_VideoDevice *_this, SDL_Window *window);
SDL_bool GDK_HasScreenKeyboardSupport(SDL_VideoDevice *_this); SDL_bool GDK_HasScreenKeyboardSupport(SDL_VideoDevice *_this);

View file

@ -100,7 +100,7 @@ static SDL_VideoDevice *UIKit_CreateDevice(void)
device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard; device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
device->HideScreenKeyboard = UIKit_HideScreenKeyboard; device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown; device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
device->UpdateTextInputRect = UIKit_UpdateTextInputRect; device->UpdateTextInputArea = UIKit_UpdateTextInputArea;
#endif #endif
device->SetClipboardText = UIKit_SetClipboardText; device->SetClipboardText = UIKit_SetClipboardText;

View file

@ -91,5 +91,5 @@ SDL_bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
void UIKit_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); void UIKit_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);
void UIKit_HideScreenKeyboard(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); 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 #endif

View file

@ -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 { @autoreleasepool {
SDL_uikitviewcontroller *vc = GetWindowViewController(window); SDL_uikitviewcontroller *vc = GetWindowViewController(window);

View file

@ -83,7 +83,7 @@ int Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window)
WAYLAND_xkb_compose_state_reset(input->xkb.compose_state); 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) int Wayland_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window)
@ -110,7 +110,7 @@ int Wayland_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window)
return 0; 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; SDL_VideoData *driverdata = _this->driverdata;
if (driverdata->text_input_manager) { if (driverdata->text_input_manager) {
@ -130,7 +130,7 @@ int Wayland_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window)
#ifdef SDL_USE_IME #ifdef SDL_USE_IME
else { else {
SDL_IME_UpdateTextRect(window); SDL_IME_UpdateTextInputArea(window);
} }
#endif #endif
return 0; return 0;

View file

@ -34,7 +34,7 @@ extern int Wayland_InitKeyboard(SDL_VideoDevice *_this);
extern void Wayland_QuitKeyboard(SDL_VideoDevice *_this); extern void Wayland_QuitKeyboard(SDL_VideoDevice *_this);
extern int Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int Wayland_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window);
extern int Wayland_StopTextInput(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); extern SDL_bool Wayland_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
#endif /* SDL_waylandkeyboard_h_ */ #endif /* SDL_waylandkeyboard_h_ */

View file

@ -511,7 +511,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
device->HasClipboardData = Wayland_HasClipboardData; device->HasClipboardData = Wayland_HasClipboardData;
device->StartTextInput = Wayland_StartTextInput; device->StartTextInput = Wayland_StartTextInput;
device->StopTextInput = Wayland_StopTextInput; device->StopTextInput = Wayland_StopTextInput;
device->UpdateTextInputRect = Wayland_UpdateTextInputRect; device->UpdateTextInputArea = Wayland_UpdateTextInputArea;
#ifdef SDL_VIDEO_VULKAN #ifdef SDL_VIDEO_VULKAN
device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary; device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary;

View file

@ -36,10 +36,10 @@
#else #else
#define SDL_DebugIMELog(...) #define SDL_DebugIMELog(...)
#endif #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_Enable(SDL_VideoData *videodata, HWND hwnd);
static void IME_Disable(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); static void IME_Quit(SDL_VideoData *videodata);
#endif /* !SDL_DISABLE_WINDOWS_IME */ #endif /* !SDL_DISABLE_WINDOWS_IME */
@ -208,10 +208,10 @@ int WIN_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window)
#ifndef SDL_DISABLE_WINDOWS_IME #ifndef SDL_DISABLE_WINDOWS_IME
HWND hwnd = window->driverdata->hwnd; HWND hwnd = window->driverdata->hwnd;
SDL_VideoData *videodata = _this->driverdata; SDL_VideoData *videodata = _this->driverdata;
IME_Init(videodata, hwnd); IME_Init(videodata, window);
IME_Enable(videodata, hwnd); IME_Enable(videodata, hwnd);
WIN_UpdateTextInputRect(_this, window); WIN_UpdateTextInputArea(_this, window);
#endif /* !SDL_DISABLE_WINDOWS_IME */ #endif /* !SDL_DISABLE_WINDOWS_IME */
return 0; return 0;
@ -224,19 +224,19 @@ int WIN_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window)
#ifndef SDL_DISABLE_WINDOWS_IME #ifndef SDL_DISABLE_WINDOWS_IME
HWND hwnd = window->driverdata->hwnd; HWND hwnd = window->driverdata->hwnd;
SDL_VideoData *videodata = _this->driverdata; SDL_VideoData *videodata = _this->driverdata;
IME_Init(videodata, hwnd); IME_Init(videodata, window);
IME_Disable(videodata, hwnd); IME_Disable(videodata, hwnd);
#endif /* !SDL_DISABLE_WINDOWS_IME */ #endif /* !SDL_DISABLE_WINDOWS_IME */
return 0; 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 #ifndef SDL_DISABLE_WINDOWS_IME
SDL_VideoData *data = _this->driverdata; 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 */ #endif /* !SDL_DISABLE_WINDOWS_IME */
return 0; 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_UpdateInputLocale(SDL_VideoData *videodata);
static void IME_ClearComposition(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 void IME_SetupAPI(SDL_VideoData *videodata);
static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex); static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex);
static void IME_SendEditingEvent(SDL_VideoData *videodata); 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); 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; HRESULT hResult = S_OK;
if (videodata->ime_initialized) { 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"); videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMCC");
/* *INDENT-ON* */ /* clang-format on */ /* *INDENT-ON* */ /* clang-format on */
IME_SetWindow(videodata, hwnd); IME_SetWindow(videodata, window);
videodata->ime_himc = ImmGetContext(hwnd); videodata->ime_himc = ImmGetContext(hwnd);
ImmReleaseContext(hwnd, videodata->ime_himc); ImmReleaseContext(hwnd, videodata->ime_himc);
if (!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)
{ {
HWND hwnd = window->driverdata->hwnd;
if (hwnd != videodata->ime_hwnd_current) {
videodata->ime_hwnd_current = hwnd; videodata->ime_hwnd_current = hwnd;
SDL_zero(videodata->ime_composition_area);
SDL_zero(videodata->ime_candidate_area);
}
if (videodata->ime_threadmgr) { if (videodata->ime_threadmgr) {
struct ITfDocumentMgr *document_mgr = 0; struct ITfDocumentMgr *document_mgr = 0;
if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) { 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; HIMC himc;
if (SDL_memcmp(rect, &videodata->ime_rect, sizeof(*rect)) == 0) {
return;
}
videodata->ime_rect = *rect;
himc = ImmGetContext(videodata->ime_hwnd_current); himc = ImmGetContext(videodata->ime_hwnd_current);
if (himc) { if (himc) {
COMPOSITIONFORM cof; COMPOSITIONFORM cof;
CANDIDATEFORM caf; CANDIDATEFORM caf;
SDL_zero(cof);
cof.dwStyle = CFS_RECT; cof.dwStyle = CFS_RECT;
cof.ptCurrentPos.x = videodata->ime_rect.x; cof.ptCurrentPos.x = rect->x + cursor;
cof.ptCurrentPos.y = videodata->ime_rect.y; cof.ptCurrentPos.y = rect->y;
cof.rcArea.left = videodata->ime_rect.x; cof.rcArea.left = rect->x;
cof.rcArea.right = (LONG)videodata->ime_rect.x + videodata->ime_rect.w; cof.rcArea.right = (LONG)rect->x + rect->w;
cof.rcArea.top = videodata->ime_rect.y; cof.rcArea.top = rect->y;
cof.rcArea.bottom = (LONG)videodata->ime_rect.y + videodata->ime_rect.h; 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); ImmSetCompositionWindow(himc, &cof);
}
SDL_zero(caf);
caf.dwIndex = 0; caf.dwIndex = 0;
caf.dwStyle = CFS_EXCLUDE; caf.dwStyle = CFS_EXCLUDE;
caf.ptCurrentPos.x = videodata->ime_rect.x; caf.ptCurrentPos.x = rect->x + cursor;
caf.ptCurrentPos.y = videodata->ime_rect.y; caf.ptCurrentPos.y = rect->y;
caf.rcArea.left = videodata->ime_rect.x; caf.rcArea.left = rect->x;
caf.rcArea.right = (LONG)videodata->ime_rect.x + videodata->ime_rect.w; caf.rcArea.right = (LONG)rect->x + rect->w;
caf.rcArea.top = videodata->ime_rect.y; caf.rcArea.top = rect->y;
caf.rcArea.bottom = (LONG)videodata->ime_rect.y + videodata->ime_rect.h; 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); ImmSetCandidateWindow(himc, &caf);
}
ImmReleaseContext(videodata->ime_hwnd_current, himc); ImmReleaseContext(videodata->ime_hwnd_current, himc);
} }

View file

@ -31,7 +31,7 @@ extern void WIN_ResetDeadKeys(void);
extern int WIN_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int WIN_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_StopTextInput(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 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); extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata);

View file

@ -268,7 +268,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
device->StartTextInput = WIN_StartTextInput; device->StartTextInput = WIN_StartTextInput;
device->StopTextInput = WIN_StopTextInput; device->StopTextInput = WIN_StopTextInput;
device->UpdateTextInputRect = WIN_UpdateTextInputRect; device->UpdateTextInputArea = WIN_UpdateTextInputArea;
device->ClearComposition = WIN_ClearComposition; device->ClearComposition = WIN_ClearComposition;
device->SetClipboardData = WIN_SetClipboardData; device->SetClipboardData = WIN_SetClipboardData;
@ -281,7 +281,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
device->StartTextInput = GDK_StartTextInput; device->StartTextInput = GDK_StartTextInput;
device->StopTextInput = GDK_StopTextInput; device->StopTextInput = GDK_StopTextInput;
device->SetTextInputRect = GDK_SetTextInputRect; device->SetTextInputArea = GDK_SetTextInputArea;
device->ClearComposition = GDK_ClearComposition; device->ClearComposition = GDK_ClearComposition;
device->HasScreenKeyboardSupport = GDK_HasScreenKeyboardSupport; device->HasScreenKeyboardSupport = GDK_HasScreenKeyboardSupport;

View file

@ -447,7 +447,8 @@ struct SDL_VideoData
int ime_candlistindexbase; int ime_candlistindexbase;
SDL_bool ime_horizontal_candidates; SDL_bool ime_horizontal_candidates;
SDL_Rect ime_rect; COMPOSITIONFORM ime_composition_area;
CANDIDATEFORM ime_candidate_area;
HKL ime_hkl; HKL ime_hkl;
void *ime_himm32; void *ime_himm32;

View file

@ -1293,7 +1293,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
#ifdef SDL_USE_IME #ifdef SDL_USE_IME
if (SDL_TextInputActive(data->window)) { if (SDL_TextInputActive(data->window)) {
/* Update IME candidate list position */ /* Update IME candidate list position */
SDL_IME_UpdateTextRect(NULL); SDL_IME_UpdateTextInputArea(NULL);
} }
#endif #endif
for (w = data->window->first_child; w; w = w->next_sibling) { for (w = data->window->first_child; w; w = w->next_sibling) {

View file

@ -448,7 +448,7 @@ int X11_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window)
{ {
X11_ResetXIM(_this, window); X11_ResetXIM(_this, window);
return X11_UpdateTextInputRect(_this, window); return X11_UpdateTextInputArea(_this, window);
} }
int X11_StopTextInput(SDL_VideoDevice *_this, SDL_Window *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; return 0;
} }
int X11_UpdateTextInputRect(SDL_VideoDevice *_this, SDL_Window *window) int X11_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window)
{ {
#ifdef SDL_USE_IME #ifdef SDL_USE_IME
SDL_IME_UpdateTextRect(window); SDL_IME_UpdateTextInputArea(window);
#endif #endif
return 0; return 0;
} }

View file

@ -28,7 +28,7 @@ extern void X11_UpdateKeymap(SDL_VideoDevice *_this, SDL_bool send_event);
extern void X11_QuitKeyboard(SDL_VideoDevice *_this); extern void X11_QuitKeyboard(SDL_VideoDevice *_this);
extern int X11_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window); extern int X11_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window);
extern int X11_StopTextInput(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 SDL_bool X11_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
extern void X11_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); extern void X11_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);
extern void X11_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window); extern void X11_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);

View file

@ -267,7 +267,7 @@ static SDL_VideoDevice *X11_CreateDevice(void)
device->HasPrimarySelectionText = X11_HasPrimarySelectionText; device->HasPrimarySelectionText = X11_HasPrimarySelectionText;
device->StartTextInput = X11_StartTextInput; device->StartTextInput = X11_StartTextInput;
device->StopTextInput = X11_StopTextInput; device->StopTextInput = X11_StopTextInput;
device->UpdateTextInputRect = X11_UpdateTextInputRect; device->UpdateTextInputArea = X11_UpdateTextInputArea;
device->HasScreenKeyboardSupport = X11_HasScreenKeyboardSupport; device->HasScreenKeyboardSupport = X11_HasScreenKeyboardSupport;
device->ShowScreenKeyboard = X11_ShowScreenKeyboard; device->ShowScreenKeyboard = X11_ShowScreenKeyboard;
device->HideScreenKeyboard = X11_HideScreenKeyboard; device->HideScreenKeyboard = X11_HideScreenKeyboard;

View file

@ -73,23 +73,21 @@ static void UpdateTextWindowInputRect(SDL_WindowID id)
SDLTest_TextWindow *textwindow = windowstates[i].textwindow; SDLTest_TextWindow *textwindow = windowstates[i].textwindow;
int w, h; int w, h;
SDL_Rect rect; SDL_Rect rect;
int cursor = 0;
int current = textwindow->current; int current = textwindow->current;
const char *current_line = textwindow->lines[current]; const char *current_line = textwindow->lines[current];
SDL_GetWindowSize(state->windows[i], &w, &h); SDL_GetWindowSize(state->windows[i], &w, &h);
rect.x = (int)TEXT_WINDOW_OFFSET_X;
if (current_line) { 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; 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)); rect.w = (int)(w - (2 * TEXT_WINDOW_OFFSET_X));
#endif rect.h = FONT_CHARACTER_SIZE;
rect.h = FONT_LINE_HEIGHT; SDL_SetTextInputArea(state->windows[i], &rect, cursor);
SDL_SetTextInputRect(state->windows[i], &rect);
return; return;
} }
} }

View file

@ -361,14 +361,14 @@ static int keyboard_startStopTextInput(void *arg)
return TEST_COMPLETED; return TEST_COMPLETED;
} }
/* Internal function to test SDL_SetTextInputRect */ /* Internal function to test SDL_SetTextInputArea */
static void testSetTextInputRect(SDL_Window *window, SDL_Rect refRect) static void testSetTextInputArea(SDL_Window *window, SDL_Rect refRect)
{ {
SDL_Rect testRect; SDL_Rect testRect;
testRect = refRect; testRect = refRect;
SDL_SetTextInputRect(window, &testRect); SDL_SetTextInputArea(window, &testRect, 0);
SDLTest_AssertPass("Call to SDL_SetTextInputRect with refRect(x:%d,y:%d,w:%d,h:%d)", refRect.x, refRect.y, refRect.w, refRect.h); 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( SDLTest_AssertCheck(
(refRect.x == testRect.x) && (refRect.y == testRect.y) && (refRect.w == testRect.w) && (refRect.h == testRect.h), (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", "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_Window *window = SDL_GetKeyboardFocus();
SDL_Rect refRect; SDL_Rect refRect;
@ -391,77 +391,77 @@ static int keyboard_setTextInputRect(void *arg)
refRect.y = SDLTest_RandomIntegerInRange(1, 50); refRect.y = SDLTest_RandomIntegerInRange(1, 50);
refRect.w = SDLTest_RandomIntegerInRange(10, 50); refRect.w = SDLTest_RandomIntegerInRange(10, 50);
refRect.h = SDLTest_RandomIntegerInRange(10, 50); refRect.h = SDLTest_RandomIntegerInRange(10, 50);
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* Normal visible refRect, origin 0,0 */ /* Normal visible refRect, origin 0,0 */
refRect.x = 0; refRect.x = 0;
refRect.y = 0; refRect.y = 0;
refRect.w = SDLTest_RandomIntegerInRange(10, 50); refRect.w = SDLTest_RandomIntegerInRange(10, 50);
refRect.h = SDLTest_RandomIntegerInRange(10, 50); refRect.h = SDLTest_RandomIntegerInRange(10, 50);
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* 1Pixel refRect */ /* 1Pixel refRect */
refRect.x = SDLTest_RandomIntegerInRange(10, 50); refRect.x = SDLTest_RandomIntegerInRange(10, 50);
refRect.y = SDLTest_RandomIntegerInRange(10, 50); refRect.y = SDLTest_RandomIntegerInRange(10, 50);
refRect.w = 1; refRect.w = 1;
refRect.h = 1; refRect.h = 1;
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* 0pixel refRect */ /* 0pixel refRect */
refRect.x = 1; refRect.x = 1;
refRect.y = 1; refRect.y = 1;
refRect.w = 1; refRect.w = 1;
refRect.h = 0; refRect.h = 0;
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* 0pixel refRect */ /* 0pixel refRect */
refRect.x = 1; refRect.x = 1;
refRect.y = 1; refRect.y = 1;
refRect.w = 0; refRect.w = 0;
refRect.h = 1; refRect.h = 1;
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* 0pixel refRect */ /* 0pixel refRect */
refRect.x = 1; refRect.x = 1;
refRect.y = 1; refRect.y = 1;
refRect.w = 0; refRect.w = 0;
refRect.h = 0; refRect.h = 0;
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* 0pixel refRect */ /* 0pixel refRect */
refRect.x = 0; refRect.x = 0;
refRect.y = 0; refRect.y = 0;
refRect.w = 0; refRect.w = 0;
refRect.h = 0; refRect.h = 0;
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* negative refRect */ /* negative refRect */
refRect.x = SDLTest_RandomIntegerInRange(-200, -100); refRect.x = SDLTest_RandomIntegerInRange(-200, -100);
refRect.y = SDLTest_RandomIntegerInRange(-200, -100); refRect.y = SDLTest_RandomIntegerInRange(-200, -100);
refRect.w = 50; refRect.w = 50;
refRect.h = 50; refRect.h = 50;
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* oversized refRect */ /* oversized refRect */
refRect.x = SDLTest_RandomIntegerInRange(1, 50); refRect.x = SDLTest_RandomIntegerInRange(1, 50);
refRect.y = SDLTest_RandomIntegerInRange(1, 50); refRect.y = SDLTest_RandomIntegerInRange(1, 50);
refRect.w = 5000; refRect.w = 5000;
refRect.h = 5000; refRect.h = 5000;
testSetTextInputRect(window, refRect); testSetTextInputArea(window, refRect);
/* NULL refRect */ /* NULL refRect */
SDL_SetTextInputRect(window, NULL); SDL_SetTextInputArea(window, NULL, 0);
SDLTest_AssertPass("Call to SDL_SetTextInputRect(NULL)"); SDLTest_AssertPass("Call to SDL_SetTextInputArea(NULL)");
return TEST_COMPLETED; 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 */ /* 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) #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 #endif
/* NULL refRect */ /* NULL refRect */
SDL_SetTextInputRect(SDL_GetKeyboardFocus(), NULL); SDL_SetTextInputArea(SDL_GetKeyboardFocus(), NULL, 0);
SDLTest_AssertPass("Call to SDL_SetTextInputRect(NULL)"); SDLTest_AssertPass("Call to SDL_SetTextInputArea(NULL)");
/* Some platforms set also an error message; so check it */ /* 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) #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 = { 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 = { 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 = { static const SDLTest_TestCaseReference keyboardTest10 = {

View file

@ -457,6 +457,8 @@ static Uint32 utf8_decode(char *p, size_t len)
static void InitInput(void) static void InitInput(void)
{ {
int i;
/* Prepare a rect for text input */ /* Prepare a rect for text input */
textRect.x = textRect.y = 100.0f; textRect.x = textRect.y = 100.0f;
textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x; textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x;
@ -466,7 +468,9 @@ static void InitInput(void)
markedRect = textRect; markedRect = textRect;
markedText[0] = 0; 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) static void CleanupVideo(void)
{ {
SDL_StopTextInput(state->windows[0]); SDL_StopTextInput(state->windows[0]);
@ -827,16 +843,8 @@ static void RedrawWindow(int rendererID)
/* Draw the candidates */ /* Draw the candidates */
DrawCandidates(rendererID, &cursorRect); DrawCandidates(rendererID, &cursorRect);
{ /* Update the area used to draw composition UI */
SDL_Rect inputrect; UpdateTextInputArea(state->windows[0], &cursorRect);
/* 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);
}
} }
static void Redraw(void) static void Redraw(void)