mirror of
https://github.com/glfw/glfw.git
synced 2025-06-14 03:32:14 +00:00
Add caret position to preedit-callback
- Win32: This works fine. - macOS: The caret is always at the last of the preedit text. - X11: - over-the-spot: The callback is not used. - on-the-spot: In IBus, the caret is always at the last of the preedit text, although the actual position can be changed. On-the-spot on X11 has many other unstable behaviors, so allow this problem for now.
This commit is contained in:
parent
7563d1bce0
commit
0ba4b36557
@ -255,7 +255,8 @@ void preedit_callback(GLFWwindow* window,
|
||||
unsigned int* preedit_string,
|
||||
int block_count,
|
||||
int* block_sizes,
|
||||
int focused_block)
|
||||
int focused_block,
|
||||
int caret)
|
||||
{
|
||||
}
|
||||
@endcode
|
||||
@ -273,7 +274,7 @@ times like the following sequence:
|
||||
-# key event: s
|
||||
-# preedit: [preedit_string: "すs", block_sizes: [2], focused_block: 0]
|
||||
-# key event: h
|
||||
-# preedit: [preedit_string: "すsh", block_sizes: [2], focused_block: 0]
|
||||
-# preedit: [preedit_string: "すsh", block_sizes: [3], focused_block: 0]
|
||||
-# key event: i
|
||||
-# preedit: [preedit_string: "すし", block_sizes: [2], focused_block: 0]
|
||||
-# key event: ' '
|
||||
@ -296,6 +297,16 @@ blocks and the second block is focused.
|
||||
The application side should draw a focused block and unfocused blocks
|
||||
in different styles.
|
||||
|
||||
You can use the "caret" parameter to draw the caret of the preedit text.
|
||||
The specification of this parameter depends on the specification of the input method.
|
||||
The following is an example on Win32.
|
||||
|
||||
- "あいうえお|" (caret: 5)
|
||||
- key event: arrow-left
|
||||
- "あいうえ|お" (caret: 4)
|
||||
- ...
|
||||
- "|あいうえお" (caret: 0)
|
||||
|
||||
GLFW provides helper functions to teach the suitable position of the candidate window
|
||||
to the window system. The window system decides the best position from text cursor
|
||||
geometry (x, y coords and height).
|
||||
|
@ -1893,6 +1893,7 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow* window, unsigned int codepoint, int
|
||||
* @param[in] block_count Attributed block count.
|
||||
* @param[in] block_sizes List of attributed block size.
|
||||
* @param[in] focused_block Focused block index.
|
||||
* @param[in] caret Caret position.
|
||||
*
|
||||
* @sa @ref preedit
|
||||
* @sa glfwSetPreeditCallback
|
||||
@ -1904,7 +1905,8 @@ typedef void (* GLFWpreeditfun)(GLFWwindow* window,
|
||||
unsigned int* preedit_string,
|
||||
int block_count,
|
||||
int* block_sizes,
|
||||
int focused_block);
|
||||
int focused_block,
|
||||
int caret);
|
||||
|
||||
/*! @brief The function pointer type for IME status change callbacks.
|
||||
*
|
||||
@ -5277,7 +5279,8 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
|
||||
unsigned int* preedit_string,
|
||||
int block_count,
|
||||
int* block_sizes,
|
||||
int focused_block)
|
||||
int focused_block,
|
||||
int caret)
|
||||
* @endcode
|
||||
* For more information about the callback parameters, see the
|
||||
* [function pointer type](@ref GLFWpreeditfun).
|
||||
|
@ -763,7 +763,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
focusedBlock = window->nblocks;
|
||||
window->nblocks++;
|
||||
}
|
||||
_glfwInputPreedit(window, focusedBlock);
|
||||
// The caret is always at the last of preedit in macOS.
|
||||
_glfwInputPreedit(window, focusedBlock, window->ntext);
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
@ -771,7 +772,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
[[markedText mutableString] setString:@""];
|
||||
window->nblocks = 0;
|
||||
window->ntext = 0;
|
||||
_glfwInputPreedit(window, 0);
|
||||
_glfwInputPreedit(window, 0, 0);
|
||||
}
|
||||
|
||||
- (NSArray*)validAttributesForMarkedText
|
||||
|
@ -315,7 +315,7 @@ void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool
|
||||
|
||||
// Notifies shrared code of a preedit event
|
||||
//
|
||||
void _glfwInputPreedit(_GLFWwindow* window, int focusedBlock)
|
||||
void _glfwInputPreedit(_GLFWwindow* window, int focusedBlock, int caret)
|
||||
{
|
||||
if (window->callbacks.preedit)
|
||||
{
|
||||
@ -324,7 +324,8 @@ void _glfwInputPreedit(_GLFWwindow* window, int focusedBlock)
|
||||
window->preeditText,
|
||||
window->nblocks,
|
||||
window->preeditAttributeBlocks,
|
||||
focusedBlock);
|
||||
focusedBlock,
|
||||
caret);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,7 +936,7 @@ void _glfwInputKey(_GLFWwindow* window,
|
||||
int key, int scancode, int action, int mods);
|
||||
void _glfwInputChar(_GLFWwindow* window,
|
||||
uint32_t codepoint, int mods, GLFWbool plain);
|
||||
void _glfwInputPreedit(_GLFWwindow* window, int focusedBlock);
|
||||
void _glfwInputPreedit(_GLFWwindow* window, int focusedBlock, int caret);
|
||||
void _glfwInputIMEStatus(_GLFWwindow* window);
|
||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||
|
@ -577,6 +577,7 @@ static GLFWbool getImmPreedit(_GLFWwindow* window)
|
||||
LONG preeditBytes = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0);
|
||||
LONG attrBytes = ImmGetCompositionStringW(hIMC, GCS_COMPATTR, NULL, 0);
|
||||
LONG clauseBytes = ImmGetCompositionStringW(hIMC, GCS_COMPCLAUSE, NULL, 0);
|
||||
LONG cursorPos = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, NULL, 0);
|
||||
|
||||
if (preeditBytes > 0)
|
||||
{
|
||||
@ -663,7 +664,7 @@ static GLFWbool getImmPreedit(_GLFWwindow* window)
|
||||
_glfw_free(attributes);
|
||||
_glfw_free(clauses);
|
||||
|
||||
_glfwInputPreedit(window, focusedBlock);
|
||||
_glfwInputPreedit(window, focusedBlock, cursorPos);
|
||||
}
|
||||
|
||||
ImmReleaseContext(window->win32.handle, hIMC);
|
||||
@ -994,7 +995,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
||||
{
|
||||
window->nblocks = 0;
|
||||
window->ntext = 0;
|
||||
_glfwInputPreedit(window, 0);
|
||||
_glfwInputPreedit(window, 0, 0);
|
||||
commitImmResultStr(window);
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -574,7 +574,7 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
|
||||
// preedit text is empty
|
||||
window->ntext = 0;
|
||||
window->nblocks = 0;
|
||||
_glfwInputPreedit(window, 0);
|
||||
_glfwInputPreedit(window, 0, 0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -634,7 +634,7 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
|
||||
window->nblocks = 1;
|
||||
window->preeditAttributeBlocks[0] = length;
|
||||
window->preeditAttributeBlocks[1] = 0;
|
||||
_glfwInputPreedit(window, 0);
|
||||
_glfwInputPreedit(window, 0, callData->caret);
|
||||
}
|
||||
else if (rstart == 0)
|
||||
{
|
||||
@ -643,7 +643,7 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
|
||||
window->nblocks = 1;
|
||||
window->preeditAttributeBlocks[0] = length;
|
||||
window->preeditAttributeBlocks[1] = 0;
|
||||
_glfwInputPreedit(window, 0);
|
||||
_glfwInputPreedit(window, 0, callData->caret);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -651,7 +651,7 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
|
||||
window->preeditAttributeBlocks[0] = rend + 1;
|
||||
window->preeditAttributeBlocks[1] = length - rend - 1;
|
||||
window->preeditAttributeBlocks[2] = 0;
|
||||
_glfwInputPreedit(window, 0);
|
||||
_glfwInputPreedit(window, 0, callData->caret);
|
||||
}
|
||||
}
|
||||
else if (rend == length - 1)
|
||||
@ -660,7 +660,7 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
|
||||
window->preeditAttributeBlocks[0] = rstart;
|
||||
window->preeditAttributeBlocks[1] = length - rstart;
|
||||
window->preeditAttributeBlocks[2] = 0;
|
||||
_glfwInputPreedit(window, 1);
|
||||
_glfwInputPreedit(window, 1, callData->caret);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -669,7 +669,7 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
|
||||
window->preeditAttributeBlocks[1] = rend - rstart + 1;
|
||||
window->preeditAttributeBlocks[2] = length - rend - 1;
|
||||
window->preeditAttributeBlocks[3] = 0;
|
||||
_glfwInputPreedit(window, 1);
|
||||
_glfwInputPreedit(window, 1, callData->caret);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3298,7 +3298,7 @@ void _glfwResetPreeditTextX11(_GLFWwindow* window)
|
||||
|
||||
window->ntext = 0;
|
||||
window->nblocks = 0;
|
||||
_glfwInputPreedit(window, 0);
|
||||
_glfwInputPreedit(window, 0, 0);
|
||||
|
||||
XFree (result);
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ static void char_callback(GLFWwindow* window, unsigned int codepoint)
|
||||
|
||||
static void preedit_callback(GLFWwindow* window, int strLength,
|
||||
unsigned int* string, int blockLength,
|
||||
int* blocks, int focusedBlock)
|
||||
int* blocks, int focusedBlock, int caret)
|
||||
{
|
||||
Slot* slot = glfwGetWindowUserPointer(window);
|
||||
int i, blockIndex = -1, blockCount = 0;
|
||||
@ -482,12 +482,16 @@ static void preedit_callback(GLFWwindow* window, int strLength,
|
||||
if (blockIndex == focusedBlock)
|
||||
printf("[");
|
||||
}
|
||||
if (i == caret)
|
||||
printf("|");
|
||||
encode_utf8(encoded, string[i]);
|
||||
printf("%s", encoded);
|
||||
blockCount--;
|
||||
}
|
||||
if (blockIndex == focusedBlock)
|
||||
printf("]");
|
||||
if (caret == strLength)
|
||||
printf("|");
|
||||
printf("\n");
|
||||
glfwGetWindowSize(window, &width, &height);
|
||||
glfwSetPreeditCursorPos(window, width/2, height/2, 20);
|
||||
|
@ -516,7 +516,7 @@ static void ime_callback(GLFWwindow* window)
|
||||
|
||||
static void preedit_callback(GLFWwindow* window, int strLength,
|
||||
unsigned int* string, int blockLength,
|
||||
int* blocks, int focusedBlock)
|
||||
int* blocks, int focusedBlock, int caret)
|
||||
{
|
||||
int blockIndex = -1, blockCount = 0;
|
||||
if (strLength == 0 || blockLength == 0)
|
||||
@ -531,6 +531,11 @@ static void preedit_callback(GLFWwindow* window, int strLength,
|
||||
{
|
||||
char encoded[5] = "";
|
||||
|
||||
if (i == caret)
|
||||
{
|
||||
if (strlen(preeditBuf) + strlen("|") < MAX_PREDIT_LEN)
|
||||
strcat(preeditBuf, "|");
|
||||
}
|
||||
if (blockCount == 0)
|
||||
{
|
||||
if (blockIndex == focusedBlock)
|
||||
@ -556,6 +561,11 @@ static void preedit_callback(GLFWwindow* window, int strLength,
|
||||
if (strlen(preeditBuf) + strlen("]") < MAX_PREDIT_LEN)
|
||||
strcat(preeditBuf, "]");
|
||||
}
|
||||
if (caret == strLength)
|
||||
{
|
||||
if (strlen(preeditBuf) + strlen("|") < MAX_PREDIT_LEN)
|
||||
strcat(preeditBuf, "|");
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
|
Loading…
Reference in New Issue
Block a user