[PATCH] winex11.drv: call XIMReset on CPS_COMPLETE

Alex Kwak take-me-home at kakao.com
Wed Mar 30 21:09:35 CDT 2022


The composition on the IME message is end, but the XIM string is
in-composition state, and the same string remains on the XIM
afterwards.
so, call X11DRV_ForceXIMReset and finish composition state in the XIM.

When XmbResetIC is performed in the composition state, a KeyEvent is
generated to empty the existing buffer.

However, Wine directly manages the Composition state, so the following
strings are unnecessary. so, ignore it.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52754
Signed-off-by: Alex Kwak <take-me-home at kakao.com>
---
 dlls/winex11.drv/ime.c |  1 +
 dlls/winex11.drv/xim.c | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c
index c1584930861..69ab2e4e850 100644
--- a/dlls/winex11.drv/ime.c
+++ b/dlls/winex11.drv/ime.c
@@ -752,6 +752,7 @@ BOOL WINAPI NotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue)
 
                     myPrivate->bInComposition = FALSE;
                     ImmUnlockIMCC(lpIMC->hPrivate);
+                    X11DRV_ForceXIMReset(lpIMC->hWnd);
 
                     bRet = TRUE;
                 }
diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c
index 3994c2106cc..098a520e629 100644
--- a/dlls/winex11.drv/xim.c
+++ b/dlls/winex11.drv/xim.c
@@ -44,6 +44,7 @@ BOOL ximInComposeMode=FALSE;
 static DWORD dwCompStringLength = 0;
 static LPBYTE CompositionString = NULL;
 static DWORD dwCompStringSize = 0;
+static BOOL ignoreNextLookupChars = FALSE;
 
 #define STYLE_OFFTHESPOT (XIMPreeditArea | XIMStatusArea)
 #define STYLE_OVERTHESPOT (XIMPreeditPosition | XIMStatusNothing)
@@ -106,6 +107,12 @@ void X11DRV_XIMLookupChars( const char *str, DWORD count )
 
     TRACE("%p %u\n", str, count);
 
+    if (ignoreNextLookupChars)
+    {
+        ignoreNextLookupChars = FALSE;
+        return;
+    }
+
     dwOutput = MultiByteToWideChar(CP_UNIXCP, 0, str, count, NULL, 0);
     wcOutput = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * dwOutput);
     if (wcOutput == NULL)
@@ -255,8 +262,20 @@ void X11DRV_ForceXIMReset(HWND hwnd)
     if (ic)
     {
         char* leftover;
+        BOOL bInCompose = ximInComposeMode;
+
         TRACE("Forcing Reset %p\n",ic);
         leftover = XmbResetIC(ic);
+
+        /*
+         * When Reset is performed in the composition state, a KeyEvent is
+         * generated to empty the existing buffer.
+         *
+         * However, Wine directly manages the Composition state, so the
+         * following strings are unnecessary.
+         */
+        ignoreNextLookupChars = bInCompose && leftover;
+
         XFree(leftover);
     }
 }
-- 
2.32.0




More information about the wine-devel mailing list