SDL
SDL copied to clipboard
Bug in SDL_TEXTINPUT event when typing in hangul in linux fcitx IME
SDL Version is 2.25.0 I am using Linux Mint 20.2 Cinnamon 5.0.7 fcitx version is 4.2.9.7
There is a bug when typing hangul using fcitx.
Let's say that I'm trying to type 마. (U+B9C8 in unicode)
To do that I have to type ㅁ(U+3141) key and ㅏ(U+314F) key on keyboard.
And when I do that SDL_TextEditingEvent.text is 마 as expected.
But after that when I type "/" key, SDL_TEXTINPUT event reports "/" first then reports "마" later which is not the case on windows.
I have written a simple text editing code to demonstrate this bug.
#include <SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
//Screen dimension constants
const int SCREEN_WIDTH = 600;
const int SCREEN_HEIGHT = 400;
char edit_buffer[2048];
char composite_buffer[2048];
int main( int argc, char* args[] )
{
memset(edit_buffer, 0, 2048);
memset(composite_buffer,0, 2048);
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("Failed to init SDL\n");
return 1;
}
SDL_Window *window = SDL_CreateWindow("Test Windows",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT,
0);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_StartTextInput();
bool quit = false;
//clear screen
printf("\x1B[2J");
//set cursor pos to zero
printf("\x1B[H");
SDL_Event event;
while(!quit)
{
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
quit = true;
}
else if(event.type == SDL_TEXTINPUT)
{
strcat(edit_buffer, event.text.text);
}
else if(event.type == SDL_TEXTEDITING)
{
event.edit
memcpy(composite_buffer, event.edit.text, strlen(event.edit.text) + 1);
}
}
//clear screen
printf("\x1B[2J");
//set cursor pos to zero
printf("\x1B[H");
printf("----edit_string----\n");
printf("%s\n", edit_buffer);
printf("----edit_string----\n");
printf("----composite----\n");
printf("%s\n", composite_buffer);
printf("----composite----\n");
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
SDL_StopTextInput();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I'm not going to have time to look at this for this milestone. Anyone who is familiar with Linux IME input, feel free to pick this up!
I'm not really familiar with the code, but just having a quick glance at the code from line 1075 of SDL_keyboard.c seems to be wrong (added by #5398).
The branch is completely useless. Either it should set event.editExt..., or be completely eliminated.
I'm not really familiar with the code, but just having a quick glance at the code from line 1075 of SDL_keyboard.c seems to be wrong (added by #5398).
The branch is completely useless. Either it should set event.editExt..., or be completely eliminated.
That branch is needed to keep compatibility with the behavior pre-SDL_HINT_IME_SUPPORT_EXTENDED_TEXT
.
That branch is needed to keep compatibility with the behavior pre-
SDL_HINT_IME_SUPPORT_EXTENDED_TEXT
.
What do you mean? Lines 1075-1079 are the same as lines 1061-1065. There is nothing in-between which uses the event object.
Ah yeah, I was thinking about the difference with 1069-1073. It looks like it wasn't rebased correctly when going from #5378 to #5398.
I doubt this would cause this issue tho.
I doubt this would cause this issue tho.
That is quite possible. Nevertheless, I'm going to create a PR for that.
Testing the behavior using SDL main
I get this:
Video del 2022-11-14 17-44-08.webm
Pressing ㅁ
then ㅏ
(which are a
and k
on my keyboard) result correctly in 마
.
Pressing /
seems to work fine.
Pressing
seems to break it.
Notice how some keypress events are leaked from the IME. This doesn't happen with other IMEs like Anthy and Mozc.
The same behavior can be seen in other editors that don't use SDL. So I think this is an Hangul IME issue.
Sorry for the late response but I was busy doing some stuffs. And I was very surprised to see that SDL2 is now SDL3, So I decided to test SDL3 with the updated code.
#include <SDL3/SDL.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
//Screen dimension constants
const int SCREEN_WIDTH = 600;
const int SCREEN_HEIGHT = 400;
char edit_buffer[2048];
char composite_buffer[2048];
int main( int argc, char* args[] )
{
memset(edit_buffer, 0, 2048);
memset(composite_buffer,0, 2048);
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("Failed to init SDL\n");
return 1;
}
SDL_Window *window = SDL_CreateWindow("Test Windows",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT,
0);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
SDL_StartTextInput();
bool quit = false;
//clear screen
printf("\x1B[2J");
//set cursor pos to zero
printf("\x1B[H");
SDL_Event event;
while(!quit)
{
while(SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
quit = true;
}
else if(event.type == SDL_TEXTINPUT)
{
strcat(edit_buffer, event.text.text);
}
else if(event.type == SDL_TEXTEDITING)
{
memcpy(composite_buffer, event.edit.text, strlen(event.edit.text) + 1);
}
//clear screen
printf("\x1B[2J");
//set cursor pos to zero
printf("\x1B[H");
printf("----edit_string----\n");
printf(u8"%s\n", edit_buffer);
printf("----edit_string----\n");
printf("----composite----\n");
printf(u8"%s\n", composite_buffer);
printf("----composite----\n");
size_t raw_str_size = strlen(edit_buffer);
printf("----edit buffer raw hex----\n");
for(size_t i=0; i<raw_str_size; i++){
printf("%hhx ", edit_buffer[i]);
}
printf("\n");
printf("----edit buffer raw hex----\n");
raw_str_size = strlen(composite_buffer);
printf("----composite buffer raw hex----\n");
for(size_t i=0; i<raw_str_size; i++){
printf("%hhx ", composite_buffer[i]);
}
printf("\n");
printf("----composite buffer raw hex----\n");
}
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
SDL_StopTextInput();
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
And I'm happy to report that this code absolutely does not work anymore, even for simple ascii!~ yay....
I assume it's because new APIs are being introduced or something. So I'll just close this issue with this comment.
well SDL3 crashes so I tried with latest release from https://github.com/libsdl-org/SDL/releases and problem I described consists.
I changed my mind and decided to reopen the issue. I do know that linux IME is not perfect and it may as well be an hangul IME issue but I'm hoping that this issue post will draw attention to some IME guru that can hopefully fix this.