Enable glfwSetPreeditCursorPos API to apply the change immediately

In Windows and X11, the changes were applied at the time of the preedit
callback. This has been removed and make them applied immediately.

In macOS, the position callback is provided, so do nothing and leave
this to it.
This commit is contained in:
Daijiro Fukuda 2022-05-20 17:26:25 +09:00
parent 66d668501d
commit 1c7e52faf8
17 changed files with 72 additions and 41 deletions

View File

@ -500,6 +500,7 @@ GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
_glfwGetKeyScancodeCocoa, _glfwGetKeyScancodeCocoa,
_glfwSetClipboardStringCocoa, _glfwSetClipboardStringCocoa,
_glfwGetClipboardStringCocoa, _glfwGetClipboardStringCocoa,
_glfwUpdatePreeditCursorPosCocoa,
_glfwResetPreeditTextCocoa, _glfwResetPreeditTextCocoa,
_glfwSetIMEStatusCocoa, _glfwSetIMEStatusCocoa,
_glfwGetIMEStatusCocoa, _glfwGetIMEStatusCocoa,

View File

@ -268,6 +268,7 @@ void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringCocoa(const char* string); void _glfwSetClipboardStringCocoa(const char* string);
const char* _glfwGetClipboardStringCocoa(void); const char* _glfwGetClipboardStringCocoa(void);
void _glfwUpdatePreeditCursorPosCocoa(_GLFWwindow* window);
void _glfwResetPreeditTextCocoa(_GLFWwindow* window); void _glfwResetPreeditTextCocoa(_GLFWwindow* window);
void _glfwSetIMEStatusCocoa(_GLFWwindow* window, int active); void _glfwSetIMEStatusCocoa(_GLFWwindow* window, int active);
int _glfwGetIMEStatusCocoa(_GLFWwindow* window); int _glfwGetIMEStatusCocoa(_GLFWwindow* window);

View File

@ -1858,6 +1858,12 @@ const char* _glfwGetClipboardStringCocoa(void)
} // autoreleasepool } // autoreleasepool
} }
void _glfwUpdatePreeditCursorPosCocoa(_GLFWwindow* window)
{
// Do nothing. Instead, implement `firstRectForCharacterRange` callback
// to update the position.
}
void _glfwResetPreeditTextCocoa(_GLFWwindow* window) void _glfwResetPreeditTextCocoa(_GLFWwindow* window)
{ {
NSTextInputContext* context = [NSTextInputContext currentInputContext]; NSTextInputContext* context = [NSTextInputContext currentInputContext];

View File

@ -907,9 +907,17 @@ GLFWAPI void glfwGetPreeditCursorPos(GLFWwindow* handle, int *x, int *y, int *h)
GLFWAPI void glfwSetPreeditCursorPos(GLFWwindow* handle, int x, int y, int h) GLFWAPI void glfwSetPreeditCursorPos(GLFWwindow* handle, int x, int y, int h)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
if (x == window->preeditCursorPosX &&
y == window->preeditCursorPosY &&
h == window->preeditCursorHeight)
return;
window->preeditCursorPosX = x; window->preeditCursorPosX = x;
window->preeditCursorPosY = y; window->preeditCursorPosY = y;
window->preeditCursorHeight = h; window->preeditCursorHeight = h;
_glfw.platform.updatePreeditCursorPos(window);
} }
GLFWAPI void glfwResetPreeditText(GLFWwindow* handle) GLFWAPI void glfwResetPreeditText(GLFWwindow* handle)

View File

@ -699,6 +699,7 @@ struct _GLFWplatform
int (*getKeyScancode)(int); int (*getKeyScancode)(int);
void (*setClipboardString)(const char*); void (*setClipboardString)(const char*);
const char* (*getClipboardString)(void); const char* (*getClipboardString)(void);
void (*updatePreeditCursorPos)(_GLFWwindow*);
void (*resetPreeditText)(_GLFWwindow*); void (*resetPreeditText)(_GLFWwindow*);
void (*setIMEStatus)(_GLFWwindow*,int); void (*setIMEStatus)(_GLFWwindow*,int);
int (*getIMEStatus)(_GLFWwindow*); int (*getIMEStatus)(_GLFWwindow*);

View File

@ -56,6 +56,7 @@ GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
_glfwGetKeyScancodeNull, _glfwGetKeyScancodeNull,
_glfwSetClipboardStringNull, _glfwSetClipboardStringNull,
_glfwGetClipboardStringNull, _glfwGetClipboardStringNull,
_glfwUpdatePreeditCursorPosNull,
_glfwResetPreeditTextNull, _glfwResetPreeditTextNull,
_glfwSetIMEStatusNull, _glfwSetIMEStatusNull,
_glfwGetIMEStatusNull, _glfwGetIMEStatusNull,

View File

@ -137,6 +137,7 @@ const char* _glfwGetClipboardStringNull(void);
const char* _glfwGetScancodeNameNull(int scancode); const char* _glfwGetScancodeNameNull(int scancode);
int _glfwGetKeyScancodeNull(int key); int _glfwGetKeyScancodeNull(int key);
void _glfwUpdatePreeditCursorPosNull(_GLFWwindow* window);
void _glfwResetPreeditTextNull(_GLFWwindow* window); void _glfwResetPreeditTextNull(_GLFWwindow* window);
void _glfwSetIMEStatusNull(_GLFWwindow* window, int active); void _glfwSetIMEStatusNull(_GLFWwindow* window, int active);
int _glfwGetIMEStatusNull(_GLFWwindow* window); int _glfwGetIMEStatusNull(_GLFWwindow* window);

View File

@ -542,6 +542,10 @@ const char* _glfwGetClipboardStringNull(void)
return _glfw.null.clipboardString; return _glfw.null.clipboardString;
} }
void _glfwUpdatePreeditCursorPosNull(_GLFWwindow* window)
{
}
void _glfwResetPreeditTextNull(_GLFWwindow* window) void _glfwResetPreeditTextNull(_GLFWwindow* window)
{ {
} }

View File

@ -596,6 +596,7 @@ GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
_glfwGetKeyScancodeWin32, _glfwGetKeyScancodeWin32,
_glfwSetClipboardStringWin32, _glfwSetClipboardStringWin32,
_glfwGetClipboardStringWin32, _glfwGetClipboardStringWin32,
_glfwUpdatePreeditCursorPosWin32,
_glfwResetPreeditTextWin32, _glfwResetPreeditTextWin32,
_glfwSetIMEStatusWin32, _glfwSetIMEStatusWin32,
_glfwGetIMEStatusWin32, _glfwGetIMEStatusWin32,

View File

@ -629,6 +629,7 @@ void _glfwSetCursorWin32(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringWin32(const char* string); void _glfwSetClipboardStringWin32(const char* string);
const char* _glfwGetClipboardStringWin32(void); const char* _glfwGetClipboardStringWin32(void);
void _glfwUpdatePreeditCursorPosWin32(_GLFWwindow* window);
void _glfwResetPreeditTextWin32(_GLFWwindow* window); void _glfwResetPreeditTextWin32(_GLFWwindow* window);
void _glfwSetIMEStatusWin32(_GLFWwindow* window, int active); void _glfwSetIMEStatusWin32(_GLFWwindow* window, int active);
int _glfwGetIMEStatusWin32(_GLFWwindow* window); int _glfwGetIMEStatusWin32(_GLFWwindow* window);

View File

@ -533,16 +533,6 @@ static void maximizeWindowManually(_GLFWwindow* window)
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
} }
// Set cursor position to decide candidate window
static void _win32ChangeCursorPosition(HIMC hIMC, _GLFWwindow* window)
{
int x = window->preeditCursorPosX;
int y = window->preeditCursorPosY;
int h = window->preeditCursorHeight;
CANDIDATEFORM excludeRect = { 0, CFS_EXCLUDE, { x, y }, { x, y, x, y + h } };
ImmSetCandidateWindow(hIMC, &excludeRect);
}
static GLFWbool getImmPreedit(_GLFWwindow* window) static GLFWbool getImmPreedit(_GLFWwindow* window)
{ {
HIMC hIMC = ImmGetContext(window->win32.handle); HIMC hIMC = ImmGetContext(window->win32.handle);
@ -628,7 +618,6 @@ static GLFWbool getImmPreedit(_GLFWwindow* window)
_glfw_free(clauses); _glfw_free(clauses);
_glfwInputPreedit(window, focusedBlock); _glfwInputPreedit(window, focusedBlock);
_win32ChangeCursorPosition(hIMC, window);
} }
ImmReleaseContext(window->win32.handle, hIMC); ImmReleaseContext(window->win32.handle, hIMC);
@ -2524,6 +2513,21 @@ const char* _glfwGetClipboardStringWin32(void)
return _glfw.win32.clipboardString; return _glfw.win32.clipboardString;
} }
void _glfwUpdatePreeditCursorPosWin32(_GLFWwindow* window)
{
HWND hWnd = window->win32.handle;
HIMC hIMC = ImmGetContext(hWnd);
int x = window->preeditCursorPosX;
int y = window->preeditCursorPosY;
int h = window->preeditCursorHeight;
CANDIDATEFORM excludeRect = { 0, CFS_EXCLUDE, { x, y }, { x, y, x, y + h } };
ImmSetCandidateWindow(hIMC, &excludeRect);
ImmReleaseContext(hWnd, hIMC);
}
void _glfwResetPreeditTextWin32(_GLFWwindow* window) void _glfwResetPreeditTextWin32(_GLFWwindow* window)
{ {
HWND hWnd = window->win32.handle; HWND hWnd = window->win32.handle;

View File

@ -362,6 +362,7 @@ GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
_glfwGetKeyScancodeWayland, _glfwGetKeyScancodeWayland,
_glfwSetClipboardStringWayland, _glfwSetClipboardStringWayland,
_glfwGetClipboardStringWayland, _glfwGetClipboardStringWayland,
_glfwUpdatePreeditCursorPosWayland,
_glfwResetPreeditTextWayland, _glfwResetPreeditTextWayland,
_glfwSetIMEStatusWayland, _glfwSetIMEStatusWayland,
_glfwGetIMEStatusWayland, _glfwGetIMEStatusWayland,

View File

@ -490,6 +490,7 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringWayland(const char* string); void _glfwSetClipboardStringWayland(const char* string);
const char* _glfwGetClipboardStringWayland(void); const char* _glfwGetClipboardStringWayland(void);
void _glfwUpdatePreeditCursorPosWayland(_GLFWwindow* window);
void _glfwResetPreeditTextWayland(_GLFWwindow* window); void _glfwResetPreeditTextWayland(_GLFWwindow* window);
void _glfwSetIMEStatusWayland(_GLFWwindow* window, int active); void _glfwSetIMEStatusWayland(_GLFWwindow* window, int active);
int _glfwGetIMEStatusWayland(_GLFWwindow* window); int _glfwGetIMEStatusWayland(_GLFWwindow* window);

View File

@ -2592,6 +2592,10 @@ const char* _glfwGetClipboardStringWayland(void)
return _glfw.wl.clipboardString; return _glfw.wl.clipboardString;
} }
void _glfwUpdatePreeditCursorPosWayland(_GLFWwindow* window)
{
}
void _glfwResetPreeditTextWayland(_GLFWwindow* window) void _glfwResetPreeditTextWayland(_GLFWwindow* window)
{ {
} }

View File

@ -1184,6 +1184,7 @@ GLFWbool _glfwConnectX11(int platformID, _GLFWplatform* platform)
_glfwGetKeyScancodeX11, _glfwGetKeyScancodeX11,
_glfwSetClipboardStringX11, _glfwSetClipboardStringX11,
_glfwGetClipboardStringX11, _glfwGetClipboardStringX11,
_glfwUpdatePreeditCursorPosX11,
_glfwResetPreeditTextX11, _glfwResetPreeditTextX11,
_glfwSetIMEStatusX11, _glfwSetIMEStatusX11,
_glfwGetIMEStatusX11, _glfwGetIMEStatusX11,

View File

@ -979,6 +979,7 @@ void _glfwSetCursorX11(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringX11(const char* string); void _glfwSetClipboardStringX11(const char* string);
const char* _glfwGetClipboardStringX11(void); const char* _glfwGetClipboardStringX11(void);
void _glfwUpdatePreeditCursorPosX11(_GLFWwindow* window);
void _glfwResetPreeditTextX11(_GLFWwindow* window); void _glfwResetPreeditTextX11(_GLFWwindow* window);
void _glfwSetIMEStatusX11(_GLFWwindow* window, int active); void _glfwSetIMEStatusX11(_GLFWwindow* window, int active);
int _glfwGetIMEStatusX11(_GLFWwindow* window); int _glfwGetIMEStatusX11(_GLFWwindow* window);

View File

@ -543,20 +543,6 @@ static void inputContextDestroyCallback(XIC ic, XPointer clientData, XPointer ca
window->x11.ic = NULL; window->x11.ic = NULL;
} }
// Update cursor position to decide candidate window
//
static void _ximChangeCursorPosition(XIC xic, _GLFWwindow* window)
{
XVaNestedList preedit_attr;
XPoint spot;
spot.x = window->preeditCursorPosX;
spot.y = window->preeditCursorPosY + window->preeditCursorHeight;
preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
XSetICValues(xic, XNPreeditAttributes, preedit_attr, NULL);
XFree(preedit_attr);
}
// IME Start callback (do nothing) // IME Start callback (do nothing)
// //
static void _ximPreeditStartCallback(XIC xic, XPointer clientData, XPointer callData) static void _ximPreeditStartCallback(XIC xic, XPointer clientData, XPointer callData)
@ -581,11 +567,6 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
XIMFeedback f; XIMFeedback f;
_GLFWwindow* window = (_GLFWwindow*) clientData; _GLFWwindow* window = (_GLFWwindow*) clientData;
// keep cursor position to reduce API call
int cursorX = window->preeditCursorPosX;
int cursorY = window->preeditCursorPosY;
int cursorHeight = window->preeditCursorHeight;
if (!callData->text) if (!callData->text)
{ {
// preedit text is empty // preedit text is empty
@ -688,12 +669,6 @@ static void _ximPreeditDrawCallback(XIC xic, XPointer clientData, XIMPreeditDraw
window->preeditAttributeBlocks[3] = 0; window->preeditAttributeBlocks[3] = 0;
_glfwInputPreedit(window, 1); _glfwInputPreedit(window, 1);
} }
if ((cursorX != window->preeditCursorPosX) ||
(cursorY != window->preeditCursorPosY) ||
(cursorHeight != window->preeditCursorHeight))
{
_ximChangeCursorPosition(xic, window);
}
} }
} }
@ -1461,11 +1436,6 @@ static void processEvent(XEvent *event)
if (chars != buffer) if (chars != buffer)
_glfw_free(chars); _glfw_free(chars);
// In the case of over-the-spot, need to update the position here
// because preedit-callbacks can not be used.
if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
_ximChangeCursorPosition(window->x11.ic, window);
} }
} }
else else
@ -3259,6 +3229,21 @@ const char* _glfwGetClipboardStringX11(void)
return getSelectionString(_glfw.x11.CLIPBOARD); return getSelectionString(_glfw.x11.CLIPBOARD);
} }
void _glfwUpdatePreeditCursorPosX11(_GLFWwindow* window)
{
XVaNestedList preedit_attr;
XPoint spot;
if (!window->x11.ic)
return;
spot.x = window->preeditCursorPosX;
spot.y = window->preeditCursorPosY + window->preeditCursorHeight;
preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
XSetICValues(window->x11.ic, XNPreeditAttributes, preedit_attr, NULL);
XFree(preedit_attr);
}
void _glfwResetPreeditTextX11(_GLFWwindow* window) void _glfwResetPreeditTextX11(_GLFWwindow* window)
{ {
XIC ic = window->x11.ic; XIC ic = window->x11.ic;
@ -3268,6 +3253,9 @@ void _glfwResetPreeditTextX11(_GLFWwindow* window)
XVaNestedList preedit_attr; XVaNestedList preedit_attr;
char* result; char* result;
if (!ic)
return;
// Can not manage IME in the case of over-the-spot. // Can not manage IME in the case of over-the-spot.
if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
return; return;
@ -3296,6 +3284,9 @@ void _glfwSetIMEStatusX11(_GLFWwindow* window, int active)
{ {
XIC ic = window->x11.ic; XIC ic = window->x11.ic;
if (!ic)
return;
// Can not manage IME in the case of over-the-spot. // Can not manage IME in the case of over-the-spot.
if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
return; return;
@ -3308,6 +3299,9 @@ void _glfwSetIMEStatusX11(_GLFWwindow* window, int active)
int _glfwGetIMEStatusX11(_GLFWwindow* window) int _glfwGetIMEStatusX11(_GLFWwindow* window)
{ {
if (!window->x11.ic)
return GLFW_FALSE;
// Can not manage IME in the case of over-the-spot. // Can not manage IME in the case of over-the-spot.
if (_glfw.x11.imStyle == STYLE_OVERTHESPOT) if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
return GLFW_FALSE; return GLFW_FALSE;