mirror of
https://github.com/glfw/glfw.git
synced 2025-06-14 03:32:14 +00:00
X11: Change default style to over-the-spot
In over-the-spot mode, almost all APIs are disabled. Applications only need to specify the candidate window position by `glfwSetPreeditCursorPos`. We can change style to on-the-spot by setting "on-the-spot" to the environmental variable `IM_STYLE`. However on-the-spot mode of X11 has the following problems: * Status APIs don't work because status callbacks don't work (at least in my ibus environment) * Can't specify the candidate window position
This commit is contained in:
parent
a5a3cbe5c0
commit
28ea48ea38
@ -440,13 +440,18 @@ static GLFWbool hasUsableInputMethodStyle(void)
|
||||
{
|
||||
GLFWbool found = GLFW_FALSE;
|
||||
XIMStyles* styles = NULL;
|
||||
const char* imStyle = getenv("IM_STYLE");
|
||||
|
||||
if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL)
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfw.x11.imStyle = STYLE_OVERTHESPOT;
|
||||
if (imStyle && strcmp(imStyle, "on-the-spot") == 0)
|
||||
_glfw.x11.imStyle = STYLE_ONTHESPOT;
|
||||
|
||||
for (unsigned int i = 0; i < styles->count_styles; i++)
|
||||
{
|
||||
if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
|
||||
if (styles->supported_styles[i] == _glfw.x11.imStyle)
|
||||
{
|
||||
found = GLFW_TRUE;
|
||||
break;
|
||||
|
@ -91,6 +91,9 @@
|
||||
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
||||
|
||||
#define STYLE_OVERTHESPOT (XIMPreeditNothing | XIMStatusNothing)
|
||||
#define STYLE_ONTHESPOT (XIMPreeditCallbacks | XIMStatusCallbacks)
|
||||
|
||||
typedef XID GLXWindow;
|
||||
typedef XID GLXDrawable;
|
||||
typedef struct __GLXFBConfig* GLXFBConfig;
|
||||
@ -584,6 +587,8 @@ typedef struct _GLFWlibraryX11
|
||||
XContext context;
|
||||
// XIM input method
|
||||
XIM im;
|
||||
// XIM input method style
|
||||
XIMStyle imStyle;
|
||||
// Most recent error code received by X error handler
|
||||
int errorCode;
|
||||
// Primary selection string (while the primary selection is owned)
|
||||
|
@ -1461,6 +1461,11 @@ static void processEvent(XEvent *event)
|
||||
|
||||
if (chars != buffer)
|
||||
_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
|
||||
@ -2085,28 +2090,54 @@ void _glfwCreateInputContextX11(_GLFWwindow* window)
|
||||
XIMCallback callback;
|
||||
callback.callback = (XIMProc) inputContextDestroyCallback;
|
||||
callback.client_data = (XPointer) window;
|
||||
XVaNestedList preeditList = _createXIMPreeditCallbacks(window);
|
||||
XVaNestedList statusList = _createXIMStatusCallbacks(window);
|
||||
|
||||
window->x11.ic = XCreateIC(_glfw.x11.im,
|
||||
XNInputStyle,
|
||||
XIMPreeditCallbacks | XIMStatusCallbacks,
|
||||
XNClientWindow,
|
||||
window->x11.handle,
|
||||
XNFocusWindow,
|
||||
window->x11.handle,
|
||||
XNPreeditAttributes,
|
||||
preeditList,
|
||||
XNStatusAttributes,
|
||||
statusList,
|
||||
XNDestroyCallback,
|
||||
&callback,
|
||||
NULL);
|
||||
|
||||
XFree(preeditList);
|
||||
XFree(statusList);
|
||||
window->x11.imeFocus = GLFW_FALSE;
|
||||
|
||||
if (_glfw.x11.imStyle == STYLE_ONTHESPOT)
|
||||
{
|
||||
XVaNestedList preeditList = _createXIMPreeditCallbacks(window);
|
||||
XVaNestedList statusList = _createXIMStatusCallbacks(window);
|
||||
|
||||
window->x11.ic = XCreateIC(_glfw.x11.im,
|
||||
XNInputStyle,
|
||||
_glfw.x11.imStyle,
|
||||
XNClientWindow,
|
||||
window->x11.handle,
|
||||
XNFocusWindow,
|
||||
window->x11.handle,
|
||||
XNPreeditAttributes,
|
||||
preeditList,
|
||||
XNStatusAttributes,
|
||||
statusList,
|
||||
XNDestroyCallback,
|
||||
&callback,
|
||||
NULL);
|
||||
|
||||
XFree(preeditList);
|
||||
XFree(statusList);
|
||||
}
|
||||
else if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
|
||||
{
|
||||
window->x11.ic = XCreateIC(_glfw.x11.im,
|
||||
XNInputStyle,
|
||||
_glfw.x11.imStyle,
|
||||
XNClientWindow,
|
||||
window->x11.handle,
|
||||
XNFocusWindow,
|
||||
window->x11.handle,
|
||||
XNDestroyCallback,
|
||||
&callback,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// (XIMPreeditNothing | XIMStatusNothing) is considered as STYLE_OVERTHESPOT.
|
||||
// So this branch should not be used now.
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to create input context.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (window->x11.ic)
|
||||
{
|
||||
XWindowAttributes attribs;
|
||||
@ -3435,6 +3466,10 @@ void _glfwPlatformResetPreeditText(_GLFWwindow* window)
|
||||
XVaNestedList preedit_attr;
|
||||
char* result;
|
||||
|
||||
// Can not manage IME in the case of over-the-spot.
|
||||
if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
|
||||
return;
|
||||
|
||||
if (window->ntext == 0)
|
||||
return;
|
||||
|
||||
@ -3458,6 +3493,11 @@ void _glfwPlatformResetPreeditText(_GLFWwindow* window)
|
||||
void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active)
|
||||
{
|
||||
XIC ic = window->x11.ic;
|
||||
|
||||
// Can not manage IME in the case of over-the-spot.
|
||||
if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
|
||||
return;
|
||||
|
||||
if (active)
|
||||
XSetICFocus(ic);
|
||||
else
|
||||
@ -3466,6 +3506,10 @@ void _glfwPlatformSetIMEStatus(_GLFWwindow* window, int active)
|
||||
|
||||
int _glfwPlatformGetIMEStatus(_GLFWwindow* window)
|
||||
{
|
||||
// Can not manage IME in the case of over-the-spot.
|
||||
if (_glfw.x11.imStyle == STYLE_OVERTHESPOT)
|
||||
return GLFW_FALSE;
|
||||
|
||||
return window->x11.imeFocus;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user