Fix IME stuck when 0-len TEXTEDITING event is missing.

This commit is contained in:
TsFreddie 2020-10-25 23:48:12 +08:00
parent bc5b19b644
commit f7ac41adeb
8 changed files with 35 additions and 25 deletions

View file

@ -49,7 +49,7 @@ CInput::CInput()
m_VideoRestartNeeded = 0; m_VideoRestartNeeded = 0;
m_pClipboardText = NULL; m_pClipboardText = NULL;
m_CountEditingText = 0; m_NumTextInputInstances = 0;
m_EditingTextLen = -1; m_EditingTextLen = -1;
m_aEditingText[0] = 0; m_aEditingText[0] = 0;
} }
@ -144,28 +144,28 @@ void CInput::NextFrame()
bool CInput::GetIMEState() bool CInput::GetIMEState()
{ {
return m_CountEditingText > 0; return m_NumTextInputInstances > 0;
} }
void CInput::SetIMEState(bool Activate) void CInput::SetIMEState(bool Activate)
{ {
if(Activate) if(Activate)
{ {
if(m_CountEditingText == 0) if(m_NumTextInputInstances == 0)
SDL_StartTextInput(); SDL_StartTextInput();
m_CountEditingText++; m_NumTextInputInstances++;
} }
else else
{ {
if(m_CountEditingText == 0) if(m_NumTextInputInstances == 0)
return; return;
m_CountEditingText--; m_NumTextInputInstances--;
if(m_CountEditingText == 0) if(m_NumTextInputInstances == 0)
SDL_StopTextInput(); SDL_StopTextInput();
} }
} }
const char *CInput::GetIMECandidate() const char *CInput::GetIMEEditingText()
{ {
if(m_EditingTextLen > 0) if(m_EditingTextLen > 0)
return m_aEditingText; return m_aEditingText;
@ -241,9 +241,14 @@ int CInput::Update()
for(int i = 0; i < Event.edit.start; i++) for(int i = 0; i < Event.edit.start; i++)
m_EditingCursor = str_utf8_forward(m_aEditingText, m_EditingCursor); m_EditingCursor = str_utf8_forward(m_aEditingText, m_EditingCursor);
} }
else
{
m_aEditingText[0] = 0;
}
break; break;
} }
case SDL_TEXTINPUT: case SDL_TEXTINPUT:
m_EditingTextLen = 0;
AddEvent(Event.text.text, 0, IInput::FLAG_TEXT); AddEvent(Event.text.text, 0, IInput::FLAG_TEXT);
break; break;
// handle keys // handle keys

View file

@ -31,8 +31,8 @@ class CInput : public IEngineInput
int m_InputCounter; int m_InputCounter;
// IME support // IME support
int m_CountEditingText; int m_NumTextInputInstances;
char m_aEditingText[32]; char m_aEditingText[INPUT_TEXT_SIZE];
int m_EditingTextLen; int m_EditingTextLen;
int m_EditingCursor; int m_EditingCursor;
@ -62,7 +62,7 @@ public:
virtual bool GetIMEState(); virtual bool GetIMEState();
virtual void SetIMEState(bool Activate); virtual void SetIMEState(bool Activate);
virtual const char *GetIMECandidate(); virtual const char *GetIMEEditingText();
virtual int GetEditingCursor(); virtual int GetEditingCursor();
virtual void SetEditingPosition(float X, float Y); virtual void SetEditingPosition(float X, float Y);
}; };

View file

@ -12,12 +12,17 @@ class IInput : public IInterface
{ {
MACRO_INTERFACE("input", 0) MACRO_INTERFACE("input", 0)
public: public:
enum
{
INPUT_TEXT_SIZE = 128
};
class CEvent class CEvent
{ {
public: public:
int m_Flags; int m_Flags;
int m_Key; int m_Key;
char m_aText[32]; char m_aText[INPUT_TEXT_SIZE];
int m_InputCount; int m_InputCount;
}; };
@ -70,7 +75,7 @@ public:
virtual bool GetIMEState() = 0; virtual bool GetIMEState() = 0;
virtual void SetIMEState(bool Activate) = 0; virtual void SetIMEState(bool Activate) = 0;
virtual const char *GetIMECandidate() = 0; virtual const char *GetIMEEditingText() = 0;
virtual int GetEditingCursor() = 0; virtual int GetEditingCursor() = 0;
virtual void SetEditingPosition(float X, float Y) = 0; virtual void SetEditingPosition(float X, float Y) = 0;
}; };

View file

@ -1152,9 +1152,9 @@ void CChat::OnRender()
int EditingCursor = Input()->GetEditingCursor(); int EditingCursor = Input()->GetEditingCursor();
if(Input()->GetIMEState()) if(Input()->GetIMEState())
{ {
if(str_length(Input()->GetIMECandidate())) if(str_length(Input()->GetIMEEditingText()))
{ {
m_Input.Editing(Input()->GetIMECandidate(), EditingCursor); m_Input.Editing(Input()->GetIMEEditingText(), EditingCursor);
Editing = true; Editing = true;
} }
} }

View file

@ -580,9 +580,9 @@ void CGameConsole::OnRender()
int EditingCursor = Input()->GetEditingCursor(); int EditingCursor = Input()->GetEditingCursor();
if(Input()->GetIMEState()) if(Input()->GetIMEState())
{ {
if(str_length(Input()->GetIMECandidate())) if(str_length(Input()->GetIMEEditingText()))
{ {
pConsole->m_Input.Editing(Input()->GetIMECandidate(), EditingCursor); pConsole->m_Input.Editing(Input()->GetIMEEditingText(), EditingCursor);
Editing = true; Editing = true;
} }
} }

View file

@ -439,11 +439,11 @@ int CMenus::DoEditBox(void *pID, const CUIRect *pRect, char *pStr, unsigned StrS
pDisplayStr = aStars; pDisplayStr = aStars;
} }
char aInputing[32] = {0}; char aInputing[IInput::INPUT_TEXT_SIZE] = {0};
if(UI()->HotItem() == pID && Input()->GetIMEState()) if(UI()->HotItem() == pID && Input()->GetIMEState())
{ {
str_copy(aInputing, pStr, sizeof(aInputing)); str_copy(aInputing, pStr, sizeof(aInputing));
const char *Text = Input()->GetIMECandidate(); const char *Text = Input()->GetIMEEditingText();
if(str_length(Text)) if(str_length(Text))
{ {
int NewTextLen = str_length(Text); int NewTextLen = str_length(Text);

View file

@ -33,19 +33,19 @@ void CLineInput::Set(const char *pString)
void CLineInput::Editing(const char *pString, int Cursor) void CLineInput::Editing(const char *pString, int Cursor)
{ {
str_copy(m_DisplayStr, m_Str, sizeof(m_DisplayStr)); str_copy(m_DisplayStr, m_Str, sizeof(m_DisplayStr));
char Texting[34]; char EditingText[IInput::INPUT_TEXT_SIZE + 2];
str_format(Texting, sizeof(Texting), "[%s]", pString); str_format(EditingText, sizeof(EditingText), "[%s]", pString);
int NewTextLen = str_length(Texting); int NewTextLen = str_length(EditingText);
int CharsLeft = (int)sizeof(m_DisplayStr) - str_length(m_DisplayStr) - 1; int CharsLeft = (int)sizeof(m_DisplayStr) - str_length(m_DisplayStr) - 1;
int FillCharLen = NewTextLen < CharsLeft ? NewTextLen : CharsLeft; int FillCharLen = NewTextLen < CharsLeft ? NewTextLen : CharsLeft;
for(int i = str_length(m_DisplayStr) - 1; i >= m_CursorPos; i--) for(int i = str_length(m_DisplayStr) - 1; i >= m_CursorPos; i--)
m_DisplayStr[i + FillCharLen] = m_DisplayStr[i]; m_DisplayStr[i + FillCharLen] = m_DisplayStr[i];
for(int i = 0; i < FillCharLen; i++) for(int i = 0; i < FillCharLen; i++)
{ {
if(Texting[i] == 28) if(EditingText[i] == 28)
m_DisplayStr[m_CursorPos + i] = ' '; m_DisplayStr[m_CursorPos + i] = ' ';
else else
m_DisplayStr[m_CursorPos + i] = Texting[i]; m_DisplayStr[m_CursorPos + i] = EditingText[i];
} }
m_FakeLen = str_length(m_DisplayStr); m_FakeLen = str_length(m_DisplayStr);
m_FakeCursorPos = m_CursorPos + Cursor + 1; m_FakeCursorPos = m_CursorPos + Cursor + 1;

View file

@ -18,7 +18,7 @@ class CLineInput
int m_CursorPos; int m_CursorPos;
int m_NumChars; int m_NumChars;
char m_DisplayStr[MAX_SIZE + 34]; char m_DisplayStr[MAX_SIZE + IInput::INPUT_TEXT_SIZE + 2];
int m_FakeLen; int m_FakeLen;
int m_FakeCursorPos; int m_FakeCursorPos;