diff -uNr qt-everywhere-opensource-src-4.6.2.orig/src/gui/inputmethod/qximinputcontext_p.h qt-everywhere-opensource-src-4.6.2/src/gui/inputmethod/qximinputcontext_p.h
--- qt-everywhere-opensource-src-4.6.2.orig/src/gui/inputmethod/qximinputcontext_p.h	2010-02-11 22:55:22.000000000 +0700
+++ qt-everywhere-opensource-src-4.6.2/src/gui/inputmethod/qximinputcontext_p.h	2010-06-11 08:57:19.781551363 +0700
@@ -122,6 +122,8 @@
     void update();
 
     ICData *icData() const;
+
+    bool supports_string_conv;
 protected:
     bool x11FilterEvent( QWidget *keywidget, XEvent *event );
 
diff -uNr qt-everywhere-opensource-src-4.6.2.orig/src/gui/inputmethod/qximinputcontext_x11.cpp qt-everywhere-opensource-src-4.6.2/src/gui/inputmethod/qximinputcontext_x11.cpp
--- qt-everywhere-opensource-src-4.6.2.orig/src/gui/inputmethod/qximinputcontext_x11.cpp	2010-02-11 22:55:22.000000000 +0700
+++ qt-everywhere-opensource-src-4.6.2/src/gui/inputmethod/qximinputcontext_x11.cpp	2010-06-11 09:04:19.937302520 +0700
@@ -281,6 +281,106 @@
 	// handles InputMethodEnd with commit string.
 	return 0;
     }
+
+    static void xic_string_conversion_callback(XIC, XPointer client_data, XPointer call_data) {
+        // qDebug("xic_string_conversion_callback");
+        QXIMInputContext *qic = (QXIMInputContext *) client_data;
+        if (!qic) {
+            XIM_DEBUG("xic_string_conversion_callback: no qic");
+            return;
+        }
+        QXIMInputContext::ICData *data = qic->icData();
+        if (!data) {
+            XIM_DEBUG("xic_string_conversion_callback: no ic data");
+            return;
+        }
+        if (!data->widget) {
+            XIM_DEBUG("xic_string_conversion_callback: no widget in ic data");
+            return;
+        }
+        XIM_DEBUG("xic_string_conversion_callback");
+
+        XIMStringConversionCallbackStruct *conv_data = (XIMStringConversionCallbackStruct *) call_data;
+
+        QString surrounding = data->widget->inputMethodQuery(Qt::ImSurroundingText).toString();
+        int cursor_index = data->widget->inputMethodQuery(Qt::ImCursorPosition).toInt();
+
+        if (!surrounding.isNull() && !surrounding.isEmpty()) {
+            int  subst_offset = 0, subst_nchars = 0;
+            int  i;
+            short position = (short)conv_data->position;
+
+            /* According to X11R6.4 Xlib - C Library Reference Manual
+             * section 13.5.7.3 String Conversion Callback,
+             * XIMStringConversionPosition is starting position _relative_
+             * to current client's cursor position. So it should be able
+             * to be negative, or referring to a position before the cursor
+             * would be impossible. But current X protocol defines this as
+             * unsigned short. So, compiler may warn about the value range
+             * here. We hope the X protocol is fixed soon.
+             */
+            QString str_tmp;
+
+            switch (conv_data->direction)
+            {
+            case XIMForwardChar:
+                if (cursor_index > 0 && cursor_index + position >= 0)
+                    for (i = cursor_index + position; i < cursor_index + position + conv_data->factor; i++)
+                        str_tmp.append(surrounding[i]);
+
+                subst_offset = position + conv_data->factor;
+                subst_nchars = conv_data->factor;
+                break;
+
+            case XIMBackwardChar:
+                if (cursor_index > 0 && cursor_index + position - conv_data->factor >= 0)
+                    for (i = cursor_index + position-conv_data->factor; i < cursor_index + position; i++)
+                        str_tmp.append(surrounding[i]);
+
+                subst_offset = position - conv_data->factor;
+                subst_nchars = conv_data->factor;
+                break;
+
+            case XIMForwardWord:
+            case XIMBackwardWord:
+            case XIMCaretUp:
+            case XIMCaretDown:
+            case XIMNextLine:
+            case XIMPreviousLine:
+            case XIMLineStart:
+            case XIMLineEnd:
+            case XIMAbsolutePosition:
+            case XIMDontChange:
+            default:
+                break;
+            }
+
+            /* block out any failure happenning to "text", including conversion */
+            if (!str_tmp.isNull() && !str_tmp.isEmpty()) {
+                conv_data->text = (XIMStringConversionText *) malloc (sizeof (XIMStringConversionText));
+                if (conv_data->text) {
+                    conv_data->text->length = str_tmp.length();
+                    conv_data->text->feedback = NULL;
+                    conv_data->text->encoding_is_wchar = True;
+                    conv_data->text->string.wcs = (wchar_t *) malloc (str_tmp.length() * sizeof (wchar_t));
+                    if (conv_data->text->string.wcs) {
+                        for (i = 0; i < str_tmp.length(); i++)
+                            conv_data->text->string.wcs[i] = str_tmp[i].unicode();
+                    }
+                    else {
+                        free (conv_data->text);
+                        conv_data->text = NULL;
+                    }
+                }
+            }
+
+            if (conv_data->operation == XIMStringConversionSubstitution && subst_nchars > 0) {
+                QInputMethodEvent im_event;
+                im_event.setCommitString(QLatin1String(""), subst_offset, subst_nchars);
+                qic->sendEvent(im_event);
+            }
+        }
+    }
 }
 
 void QXIMInputContext::ICData::clear()
@@ -352,6 +452,7 @@
         qt_xim_preferred_style = xim_default_style;
 
     xim = 0;
+    supports_string_conv = false;
     QByteArray ximServerName(qt_ximServer);
     if (qt_ximServer)
         ximServerName.prepend("@im=");
@@ -397,7 +498,8 @@
 #endif // USE_X11R6_XIM
 
         XIMStyles *styles = 0;
-        XGetIMValues(xim, XNQueryInputStyle, &styles, (char *) 0, (char *) 0);
+        XIMValuesList *ic_values = 0;
+        XGetIMValues(xim, XNQueryInputStyle, &styles, XNQueryICValuesList, &ic_values, (char *) 0);
         if (styles) {
             int i;
             for (i = 0; !xim_style && i < styles->count_styles; i++) {
@@ -427,6 +529,18 @@
             XFree((char *)styles);
         }
 
+        // Check support string converion flag
+        if (ic_values) {
+            for (int i = 0; i < ic_values->count_values; i++) {
+                if (strcmp (ic_values->supported_values[i],
+                            XNStringConversionCallback) == 0) {
+                    supports_string_conv = true;
+                    break;
+                }
+            }
+            XFree (ic_values);
+        }
+
         if (xim_style) {
 
 #ifdef USE_X11R6_XIM
@@ -616,6 +730,17 @@
         return;
 
     ICData *data = ximData.value(w->effectiveWinId());
+
+    if (data && data->ic &&
+        w && w->testAttribute(Qt::WA_InputMethodEnabled) &&
+        w->nativeParentWidget() && 
+        w->nativeParentWidget()->effectiveWinId() == w->effectiveWinId()
+        ) {
+        // w may be a non-native (alien) widget, lets assign data->widget 
+        // to point to w instead of it's native parent.
+        data->widget = w;
+    }
+
     if (!data)
         data = createICData(w);
 
@@ -697,7 +822,7 @@
     data->preeditEmpty = true;
 
     XVaNestedList preedit_attr = 0;
-    XIMCallback startcallback, drawcallback, donecallback;
+    XIMCallback startcallback, drawcallback, donecallback, stringconv_callback;
 
     QFont font = w->font();
     data->fontset = getFontSet(font);
@@ -754,6 +879,12 @@
     if (data->ic) {
         // when resetting the input context, preserve the input state
         (void) XSetICValues(data->ic, XNResetState, XIMPreserveState, (char *) 0);
+        // Register string conversion callback
+        if (supports_string_conv) {
+            stringconv_callback.client_data = (XPointer) this;
+            stringconv_callback.callback = (XIMProc) xic_string_conversion_callback;
+            (void) XSetICValues(data->ic, XNStringConversionCallback, &stringconv_callback, (char *) 0);
+        }
     } else {
         qWarning("Failed to create XIC");
     }
