Only do work to process text events if text input is active
Fixes https://github.com/libsdl-org/SDL/issues/9353
This commit is contained in:
parent
658f3cdcf1
commit
fa236f169b
@ -1180,6 +1180,10 @@ int SDL_SendKeyboardText(const char *text)
|
||||
SDL_Keyboard *keyboard = &SDL_keyboard;
|
||||
int posted;
|
||||
|
||||
if (!SDL_TextInputActive()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Don't post text events for unprintable characters */
|
||||
if (SDL_iscntrl((unsigned char)*text)) {
|
||||
return 0;
|
||||
@ -1210,6 +1214,10 @@ int SDL_SendEditingText(const char *text, int start, int length)
|
||||
SDL_Keyboard *keyboard = &SDL_keyboard;
|
||||
int posted;
|
||||
|
||||
if (!SDL_TextInputActive()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Post the event, if desired */
|
||||
posted = 0;
|
||||
if (SDL_EventEnabled(SDL_EVENT_TEXT_EDITING)) {
|
||||
|
@ -837,11 +837,14 @@ static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent
|
||||
|
||||
static EM_BOOL Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
|
||||
{
|
||||
char text[5];
|
||||
if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) {
|
||||
SDL_SendKeyboardText(text);
|
||||
if (SDL_TextInputActive()) {
|
||||
char text[5];
|
||||
if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) {
|
||||
SDL_SendKeyboardText(text);
|
||||
}
|
||||
return EM_TRUE;
|
||||
}
|
||||
return SDL_EventEnabled(SDL_EVENT_TEXT_INPUT);
|
||||
return EM_FALSE;
|
||||
}
|
||||
|
||||
static EM_BOOL Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData)
|
||||
|
@ -1605,7 +1605,9 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
||||
Wayland_UpdateImplicitGrabSerial(input, serial);
|
||||
|
||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime);
|
||||
if (SDL_TextInputActive()) {
|
||||
has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime);
|
||||
}
|
||||
} else {
|
||||
if (keyboard_repeat_key_is_set(&input->keyboard_repeat, key)) {
|
||||
/* Send any due key repeat events before stopping the repeat and generating the key up event.
|
||||
|
@ -1164,33 +1164,40 @@ LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||
if (wParam == UNICODE_NOCHAR) {
|
||||
returnCode = 1;
|
||||
} else {
|
||||
char text[5];
|
||||
if (SDL_UCS4ToUTF8((Uint32)wParam, text) != text) {
|
||||
SDL_SendKeyboardText(text);
|
||||
if (SDL_TextInputActive()) {
|
||||
char text[5];
|
||||
if (SDL_UCS4ToUTF8((Uint32)wParam, text) != text) {
|
||||
SDL_SendKeyboardText(text);
|
||||
}
|
||||
}
|
||||
returnCode = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
/* Characters outside Unicode Basic Multilingual Plane (BMP)
|
||||
* are coded as so called "surrogate pair" in two separate UTF-16 character events.
|
||||
* Cache high surrogate until next character event. */
|
||||
if (IS_HIGH_SURROGATE(wParam)) {
|
||||
data->high_surrogate = (WCHAR)wParam;
|
||||
} else {
|
||||
WCHAR utf16[3];
|
||||
if (SDL_TextInputActive()) {
|
||||
/* Characters outside Unicode Basic Multilingual Plane (BMP)
|
||||
* are coded as so called "surrogate pair" in two separate UTF-16 character events.
|
||||
* Cache high surrogate until next character event. */
|
||||
if (IS_HIGH_SURROGATE(wParam)) {
|
||||
data->high_surrogate = (WCHAR)wParam;
|
||||
} else {
|
||||
if (SDL_TextInputActive()) {
|
||||
WCHAR utf16[3];
|
||||
|
||||
utf16[0] = data->high_surrogate ? data->high_surrogate : (WCHAR)wParam;
|
||||
utf16[1] = data->high_surrogate ? (WCHAR)wParam : L'\0';
|
||||
utf16[2] = L'\0';
|
||||
utf16[0] = data->high_surrogate ? data->high_surrogate : (WCHAR)wParam;
|
||||
utf16[1] = data->high_surrogate ? (WCHAR)wParam : L'\0';
|
||||
utf16[2] = L'\0';
|
||||
|
||||
char utf8[5];
|
||||
int result = WIN_WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16, -1, utf8, sizeof(utf8), NULL, NULL);
|
||||
if (result > 0) {
|
||||
SDL_SendKeyboardText(utf8);
|
||||
char utf8[5];
|
||||
int result = WIN_WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16, -1, utf8, sizeof(utf8), NULL, NULL);
|
||||
if (result > 0) {
|
||||
SDL_SendKeyboardText(utf8);
|
||||
}
|
||||
}
|
||||
data->high_surrogate = L'\0';
|
||||
}
|
||||
|
||||
} else {
|
||||
data->high_surrogate = L'\0';
|
||||
}
|
||||
|
||||
|
@ -88,25 +88,29 @@ void WINRT_ProcessCharacterReceivedEvent(SDL_Window *window, Windows::UI::Core::
|
||||
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
|
||||
/* Characters outside Unicode Basic Multilingual Plane (BMP)
|
||||
* are coded as so called "surrogate pair" in two separate UTF-16 character events.
|
||||
* Cache high surrogate until next character event. */
|
||||
if (IS_HIGH_SURROGATE(args->KeyCode)) {
|
||||
data->high_surrogate = (WCHAR)args->KeyCode;
|
||||
} else {
|
||||
WCHAR utf16[] = {
|
||||
data->high_surrogate ? data->high_surrogate : (WCHAR)args->KeyCode,
|
||||
data->high_surrogate ? (WCHAR)args->KeyCode : L'\0',
|
||||
L'\0'
|
||||
};
|
||||
if (SDL_TextInputActive()) {
|
||||
/* Characters outside Unicode Basic Multilingual Plane (BMP)
|
||||
* are coded as so called "surrogate pair" in two separate UTF-16 character events.
|
||||
* Cache high surrogate until next character event. */
|
||||
if (IS_HIGH_SURROGATE(args->KeyCode)) {
|
||||
data->high_surrogate = (WCHAR)args->KeyCode;
|
||||
} else {
|
||||
WCHAR utf16[] = {
|
||||
data->high_surrogate ? data->high_surrogate : (WCHAR)args->KeyCode,
|
||||
data->high_surrogate ? (WCHAR)args->KeyCode : L'\0',
|
||||
L'\0'
|
||||
};
|
||||
|
||||
char utf8[5];
|
||||
// doesn't need to be WIN_WideCharToMultiByte, since we don't care about WinXP support in WinRT.
|
||||
int result = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16, -1, utf8, sizeof(utf8), NULL, NULL);
|
||||
if (result > 0) {
|
||||
SDL_SendKeyboardText(utf8);
|
||||
char utf8[5];
|
||||
// doesn't need to be WIN_WideCharToMultiByte, since we don't care about WinXP support in WinRT.
|
||||
int result = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, utf16, -1, utf8, sizeof(utf8), NULL, NULL);
|
||||
if (result > 0) {
|
||||
SDL_SendKeyboardText(utf8);
|
||||
}
|
||||
|
||||
data->high_surrogate = L'\0';
|
||||
}
|
||||
|
||||
} else {
|
||||
data->high_surrogate = L'\0';
|
||||
}
|
||||
}
|
||||
|
@ -842,35 +842,6 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
|
||||
Status status = 0;
|
||||
SDL_bool handled_by_ime = SDL_FALSE;
|
||||
|
||||
/* Save the original keycode for dead keys, which are filtered out by
|
||||
the XFilterEvent() call below.
|
||||
*/
|
||||
int orig_event_type = xevent->type;
|
||||
KeyCode orig_keycode = xevent->xkey.keycode;
|
||||
|
||||
/* filter events catches XIM events and sends them to the correct handler */
|
||||
if (X11_XFilterEvent(xevent, None)) {
|
||||
#if 0
|
||||
printf("Filtered event type = %d display = %d window = %d\n",
|
||||
xevent->type, xevent->xany.display, xevent->xany.window);
|
||||
#endif
|
||||
/* Make sure dead key press/release events are sent */
|
||||
/* But only if we're using one of the DBus IMEs, otherwise
|
||||
some XIM IMEs will generate duplicate events */
|
||||
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX)
|
||||
SDL_Scancode scancode = videodata->key_layout[orig_keycode];
|
||||
videodata->filter_code = orig_keycode;
|
||||
videodata->filter_time = xevent->xkey.time;
|
||||
|
||||
if (orig_event_type == KeyPress) {
|
||||
SDL_SendKeyboardKey(0, keyboardID, SDL_PRESSED, scancode);
|
||||
} else {
|
||||
SDL_SendKeyboardKey(0, keyboardID, SDL_RELEASED, scancode);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: %s (X11 keycode = 0x%X)\n", data, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode);
|
||||
#endif
|
||||
@ -885,23 +856,54 @@ void X11_HandleKeyEvent(SDL_VideoDevice *_this, SDL_WindowData *windowdata, SDL_
|
||||
}
|
||||
#endif /* DEBUG SCANCODES */
|
||||
|
||||
SDL_zeroa(text);
|
||||
text[0] = '\0';
|
||||
|
||||
if (SDL_TextInputActive()) {
|
||||
/* Save the original keycode for dead keys, which are filtered out by
|
||||
the XFilterEvent() call below.
|
||||
*/
|
||||
int orig_event_type = xevent->type;
|
||||
KeyCode orig_keycode = xevent->xkey.keycode;
|
||||
|
||||
/* filter events catches XIM events and sends them to the correct handler */
|
||||
if (X11_XFilterEvent(xevent, None)) {
|
||||
#if 0
|
||||
printf("Filtered event type = %d display = %d window = %d\n",
|
||||
xevent->type, xevent->xany.display, xevent->xany.window);
|
||||
#endif
|
||||
/* Make sure dead key press/release events are sent */
|
||||
/* But only if we're using one of the DBus IMEs, otherwise
|
||||
some XIM IMEs will generate duplicate events */
|
||||
#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX)
|
||||
SDL_Scancode scancode = videodata->key_layout[orig_keycode];
|
||||
videodata->filter_code = orig_keycode;
|
||||
videodata->filter_time = xevent->xkey.time;
|
||||
|
||||
if (orig_event_type == KeyPress) {
|
||||
SDL_SendKeyboardKey(0, keyboardID, SDL_PRESSED, scancode);
|
||||
} else {
|
||||
SDL_SendKeyboardKey(0, keyboardID, SDL_RELEASED, scancode);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (windowdata->ic && xevent->type == KeyPress) {
|
||||
X11_Xutf8LookupString(windowdata->ic, &xevent->xkey, text, sizeof(text),
|
||||
&keysym, &status);
|
||||
} else {
|
||||
XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL);
|
||||
}
|
||||
if (windowdata->ic && xevent->type == KeyPress) {
|
||||
X11_Xutf8LookupString(windowdata->ic, &xevent->xkey, text, sizeof(text),
|
||||
&keysym, &status);
|
||||
} else {
|
||||
XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL);
|
||||
}
|
||||
#else
|
||||
XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL);
|
||||
XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL);
|
||||
#endif
|
||||
|
||||
#ifdef SDL_USE_IME
|
||||
if (SDL_TextInputActive()) {
|
||||
handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode, (xevent->type == KeyPress ? SDL_PRESSED : SDL_RELEASED));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!handled_by_ime) {
|
||||
if (xevent->type == KeyPress) {
|
||||
/* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
|
||||
|
Loading…
x
Reference in New Issue
Block a user