[Pkg-tcltk-devel] Bug#860927: Tk applications segmentation fault when ibus-daemon IME is restarted

Jonathan Nieder jrnieder at gmail.com
Sat Apr 22 00:14:55 UTC 2017


debdiff attached.  Still untested.  Sorry for the broken partial patch before.

Thanks,
Jonathan
-------------- next part --------------
diff -Nru tk8.6-8.6.6/debian/changelog tk8.6-8.6.6/debian/changelog
--- tk8.6-8.6.6/debian/changelog	2016-07-27 20:22:45.000000000 -0700
+++ tk8.6-8.6.6/debian/changelog	2017-04-21 17:11:11.000000000 -0700
@@ -1,3 +1,10 @@
+tk8.6 (8.6.6-2) local; urgency=medium
+
+  * Added patch from upstream to fix crash when X input methods are
+    restarted (closes: #860927).
+
+ -- Jonathan Nieder <jrnieder at gmail.com>  Fri, 21 Apr 2017 17:00:08 -0700
+
 tk8.6 (8.6.6-1) unstable; urgency=medium
 
   * New upstream release.
diff -Nru tk8.6-8.6.6/debian/patches/series tk8.6-8.6.6/debian/patches/series
--- tk8.6-8.6.6/debian/patches/series	2014-08-27 09:25:53.000000000 -0700
+++ tk8.6-8.6.6/debian/patches/series	2017-04-21 17:10:25.000000000 -0700
@@ -4,3 +4,4 @@
 non-linux.diff
 manpages.diff
 xft.diff
+ximgeneration.diff
diff -Nru tk8.6-8.6.6/debian/patches/ximgeneration.diff tk8.6-8.6.6/debian/patches/ximgeneration.diff
--- tk8.6-8.6.6/debian/patches/ximgeneration.diff	1969-12-31 16:00:00.000000000 -0800
+++ tk8.6-8.6.6/debian/patches/ximgeneration.diff	2017-04-21 17:13:54.000000000 -0700
@@ -0,0 +1,186 @@
+Patch by Brad Larson to handle an input method being restarted.
+http://core.tcl.tk/tk/tktview?name=7d967c68a0
+
+--- a/generic/tkEvent.c
++++ b/generic/tkEvent.c
+@@ -356,6 +356,7 @@ CreateXIC(
+ 	/* XCreateIC failed. */
+ 	return;
+     }
++    winPtr->ximGeneration = dispPtr->ximGeneration;
+ 
+     /*
+      * Adjust the window's event mask if the IM requires it.
+@@ -1288,6 +1289,14 @@ Tk_HandleEvent(
+      */
+ 
+ #ifdef TK_USE_INPUT_METHODS
++    /*
++     * If the XIC has been invalidated, it must be recreated.
++     */
++    if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) {
++	winPtr->flags &= ~TK_CHECKED_IC;
++	winPtr->inputContext = NULL;
++    }
++
+     if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) {
+ 	if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) {
+ 	    winPtr->flags |= TK_CHECKED_IC;
+@@ -1295,7 +1304,9 @@ Tk_HandleEvent(
+ 		CreateXIC(winPtr);
+ 	    }
+ 	}
+-	if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) {
++	if ((eventPtr->type == FocusIn) &&
++		(winPtr->dispPtr->inputMethod != NULL) &&
++		(winPtr->inputContext != NULL)) {
+ 	    XSetICFocus(winPtr->inputContext);
+ 	}
+     }
+--- a/generic/tkInt.h
++++ b/generic/tkInt.h
+@@ -508,6 +508,9 @@ typedef struct TkDisplay {
+ 
+     int iconDataSize;		/* Size of default iconphoto image data. */
+     unsigned char *iconDataPtr;	/* Default iconphoto image data, if set. */
++#ifdef TK_USE_INPUT_METHODS
++    int ximGeneration;          /* Used to invalidate XIC */
++#endif /* TK_USE_INPUT_METHODS */
+ } TkDisplay;
+ 
+ /*
+@@ -809,6 +812,9 @@ typedef struct TkWindow {
+     int minReqWidth;		/* Minimum requested width. */
+     int minReqHeight;		/* Minimum requested height. */
+     char *geometryMaster;
++#ifdef TK_USE_INPUT_METHODS
++    int ximGeneration;          /* Used to invalidate XIC */
++#endif /* TK_USE_INPUT_METHODS */
+ } TkWindow;
+ 
+ /*
+--- a/generic/tkWindow.c
++++ b/generic/tkWindow.c
+@@ -355,6 +355,9 @@ CreateTopLevelWindow(
+      * Set the flags specified in the call.
+      */
+ 
++#ifdef TK_USE_INPUT_METHODS
++    winPtr->ximGeneration = 0;
++#endif /*TK_USE_INPUT_METHODS*/
+     winPtr->flags |= flags;
+ 
+     /*
+@@ -650,6 +653,7 @@ TkAllocWindow(
+     winPtr->flags = 0;
+     winPtr->handlerList = NULL;
+ #ifdef TK_USE_INPUT_METHODS
++    winPtr->ximGeneration = 0;
+     winPtr->inputContext = NULL;
+ #endif /* TK_USE_INPUT_METHODS */
+     winPtr->tagPtr = NULL;
+@@ -1442,10 +1446,11 @@ Tk_DestroyWindow(
+     UnlinkWindow(winPtr);
+     TkEventDeadWindow(winPtr);
+ #ifdef TK_USE_INPUT_METHODS
+-    if (winPtr->inputContext != NULL) {
++    if (winPtr->inputContext != NULL &&
++	    winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) {
+ 	XDestroyIC(winPtr->inputContext);
+-	winPtr->inputContext = NULL;
+     }
++    winPtr->inputContext = NULL;
+ #endif /* TK_USE_INPUT_METHODS */
+     if (winPtr->tagPtr != NULL) {
+ 	TkFreeBindingTags(winPtr);
+--- 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 */
+-- 
+2.12.2.816.g2cccc81164
+


More information about the Pkg-tcltk-devel mailing list