summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2017-02-05 19:30:58 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2017-02-05 19:30:58 (GMT)
commitec742a6bfebae051f4d9b1a9651b3674edf1174a (patch)
tree741633e60ba06ed11d6a7ccc54a9da3923ea97cf /unix
parent4b01427e67e70e07876c9f56bed7ad10d3fda660 (diff)
parent334a0cab800af743b3db1b6da0023918dfa89790 (diff)
downloadtk-ec742a6bfebae051f4d9b1a9651b3674edf1174a.zip
tk-ec742a6bfebae051f4d9b1a9651b3674edf1174a.tar.gz
tk-ec742a6bfebae051f4d9b1a9651b3674edf1174a.tar.bz2
Fix [7d967c68]: Tk application fault when ibud-daemon IME is restarted
Diffstat (limited to 'unix')
-rw-r--r--unix/tkUnixEvent.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/unix/tkUnixEvent.c b/unix/tkUnixEvent.c
index f3beb16..111d430 100644
--- a/unix/tkUnixEvent.c
+++ b/unix/tkUnixEvent.c
@@ -38,6 +38,8 @@ static void DisplayFileProc(ClientData clientData, int flags);
static void DisplaySetupProc(ClientData clientData, int flags);
static void TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS
+static void InstantiateIMCallback(Display *, XPointer client_data, XPointer call_data);
+static void DestroyIMCallback(XIM im, XPointer client_data, XPointer call_data);
static void OpenIM(TkDisplay *dispPtr);
#endif
@@ -179,6 +181,8 @@ TkpOpenDisplay(
dispPtr->flags |= use_xkb;
#ifdef TK_USE_INPUT_METHODS
OpenIM(dispPtr);
+ XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
+ InstantiateIMCallback, (XPointer) dispPtr);
#endif
Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
DisplayFileProc, dispPtr);
@@ -664,6 +668,35 @@ TkpSync(
}
#ifdef TK_USE_INPUT_METHODS
+static void
+InstantiateIMCallback(
+ Display *display,
+ XPointer client_data,
+ XPointer call_data)
+{
+ TkDisplay *dispPtr;
+
+ dispPtr = (TkDisplay *) client_data;
+ OpenIM(dispPtr);
+ XUnregisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
+ InstantiateIMCallback, (XPointer) dispPtr);
+}
+
+static void
+DestroyIMCallback(
+ XIM im,
+ XPointer client_data,
+ XPointer call_data)
+{
+ TkDisplay *dispPtr;
+
+ dispPtr = (TkDisplay *) client_data;
+ dispPtr->inputMethod = NULL;
+ ++dispPtr->ximGeneration;
+ XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
+ InstantiateIMCallback, (XPointer) dispPtr);
+}
+
/*
*--------------------------------------------------------------
*
@@ -693,11 +726,23 @@ OpenIM(
return;
}
+ ++dispPtr->ximGeneration;
dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
if (dispPtr->inputMethod == NULL) {
return;
}
+ /* Require X11R6 */
+ {
+ XIMCallback destroy_cb;
+
+ destroy_cb.callback = DestroyIMCallback;
+ destroy_cb.client_data = (XPointer) dispPtr;
+ if (XSetIMValues(dispPtr->inputMethod, XNDestroyCallback,
+ &destroy_cb, NULL))
+ goto error;
+ }
+
if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr,
NULL) != NULL) || (stylePtr == NULL)) {
goto error;
@@ -744,6 +789,7 @@ error:
if (dispPtr->inputMethod) {
XCloseIM(dispPtr->inputMethod);
dispPtr->inputMethod = NULL;
+ ++dispPtr->ximGeneration;
}
}
#endif /* TK_USE_INPUT_METHODS */