summaryrefslogtreecommitdiffstats
path: root/unix/tkUnixEvent.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2016-12-15 16:07:06 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2016-12-15 16:07:06 (GMT)
commite5d46c829ed41bda771655006278d94adca115fc (patch)
tree767bdf02a5953ce6966e4eb8e6eded15ceb364fb /unix/tkUnixEvent.c
parent007b0626d2fc73a6bead019a52340418942361d7 (diff)
downloadtk-e5d46c829ed41bda771655006278d94adca115fc.zip
tk-e5d46c829ed41bda771655006278d94adca115fc.tar.gz
tk-e5d46c829ed41bda771655006278d94adca115fc.tar.bz2
Proposed fix for [7d967c68a09e07e355358af40f36dd5dd84c7022|7d967c68]: Tk applications segmentation fault when ibus-daemon IME is restarted
Diffstat (limited to 'unix/tkUnixEvent.c')
-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 */