mirror of
https://github.com/glfw/glfw
synced 2026-09-26 16:18:21 +03:00
Wayland: Fix text input v3 preedit cursor offsets
Convert text-input-v3 preedit cursor byte offsets to GLFW's codepoint-based caret index before reporting preedit state. The protocol reports cursor_begin and cursor_end as UTF-8 byte offsets, while the GLFW preedit callback exposes caret and block sizes in codepoint units. Keep the reported preedit block as the full preedit string because text-input-v3 does not provide styling blocks. Also clear the current preedit state before delivering committed text, matching the v1 path.
This commit is contained in:
parent
300b3207e0
commit
068858eece
1 changed files with 31 additions and 18 deletions
|
|
@ -2452,6 +2452,25 @@ static void textInputV3Leave(void* data,
|
|||
textInputV3Reset(window);
|
||||
}
|
||||
|
||||
static int utf8OffsetToCodepointIndex(const char* text, int32_t offset)
|
||||
{
|
||||
const char* cur = text;
|
||||
const char* end;
|
||||
int index = 0;
|
||||
|
||||
if (!text || offset <= 0)
|
||||
return 0;
|
||||
|
||||
end = text + offset;
|
||||
while (*cur && cur < end)
|
||||
{
|
||||
_glfwDecodeUTF8(&cur);
|
||||
index++;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static void textInputV3PreeditString(void* data,
|
||||
struct zwp_text_input_v3* textInputV3,
|
||||
const char* text,
|
||||
|
|
@ -2461,7 +2480,7 @@ static void textInputV3PreeditString(void* data,
|
|||
_GLFWwindow* window = (_GLFWwindow*) data;
|
||||
_GLFWpreedit* preedit = &window->preedit;
|
||||
const char* cur = text;
|
||||
unsigned int cursorLength = 0;
|
||||
int cursorPos = 0;
|
||||
|
||||
if (textInputFocusDisabled(window))
|
||||
return;
|
||||
|
|
@ -2471,6 +2490,8 @@ static void textInputV3PreeditString(void* data,
|
|||
preedit->focusedBlockIndex = 0;
|
||||
preedit->caretIndex = 0;
|
||||
|
||||
cursorPos = utf8OffsetToCodepointIndex(text, cursorBegin);
|
||||
|
||||
// Store preedit text
|
||||
while (cur && *cur)
|
||||
{
|
||||
|
|
@ -2478,11 +2499,6 @@ static void textInputV3PreeditString(void* data,
|
|||
|
||||
++preedit->textCount;
|
||||
|
||||
if (cur == text + cursorBegin)
|
||||
preedit->caretIndex = preedit->textCount;
|
||||
if (cursorBegin != cursorEnd && cur == text + cursorEnd)
|
||||
cursorLength = preedit->textCount - cursorBegin;
|
||||
|
||||
if (preedit->textBufferCount < preedit->textCount + 1)
|
||||
{
|
||||
int bufSize = preedit->textBufferCount;
|
||||
|
|
@ -2500,12 +2516,14 @@ static void textInputV3PreeditString(void* data,
|
|||
if (preedit->text)
|
||||
preedit->text[preedit->textCount] = 0;
|
||||
|
||||
if (cursorPos > preedit->textCount)
|
||||
cursorPos = preedit->textCount;
|
||||
preedit->caretIndex = cursorPos;
|
||||
|
||||
// Store preedit blocks
|
||||
if (preedit->textCount)
|
||||
{
|
||||
int* blocks = preedit->blockSizes;
|
||||
int blockCount = preedit->blockSizesCount;
|
||||
int cursorPos = preedit->caretIndex;
|
||||
int textCount = preedit->textCount;
|
||||
|
||||
if (!preedit->blockSizes)
|
||||
|
|
@ -2519,16 +2537,9 @@ static void textInputV3PreeditString(void* data,
|
|||
blocks = preedit->blockSizes;
|
||||
}
|
||||
|
||||
if (cursorLength && cursorPos)
|
||||
blocks[blockCount++] = cursorPos;
|
||||
|
||||
preedit->focusedBlockIndex = blockCount;
|
||||
blocks[blockCount++] = cursorLength ? cursorLength : textCount;
|
||||
|
||||
if (cursorLength && cursorPos + cursorLength != textCount)
|
||||
blocks[blockCount++] = textCount - cursorPos - cursorLength;
|
||||
|
||||
preedit->blockSizesCount = blockCount;
|
||||
blocks[0] = textCount;
|
||||
preedit->focusedBlockIndex = 0;
|
||||
preedit->blockSizesCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2542,6 +2553,8 @@ static void textInputV3CommitString(void* data,
|
|||
if (textInputFocusDisabled(window))
|
||||
return;
|
||||
|
||||
textInputV3Reset(window);
|
||||
|
||||
if (!window->callbacks.character)
|
||||
return;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue