IME_SetResultString() function overwrite composition string as empty. so, next composition may not appear on the displayed. but, still have an xim. Therefore, there was a string that seemed to have disappeared in the middle of the input.
Therefore, change it as follows. When calling IME_SetResultString(), if in a Composition state, no longer generate WM_IME_ENDCOMPOSITION and Use CompositionString in XIM to match the current XIM status rather than overwriting Composition.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52700 Signed-off-by: Alex Kwak take-me-home@kakao.com --- v2: use updateCompStr instead IME_SetResultString. v3: Change the description and data type. --- dlls/winex11.drv/ime.c | 18 ++++++++++++++---- dlls/winex11.drv/x11drv.h | 3 ++- dlls/winex11.drv/xim.c | 3 ++- 3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index c1584930861..51ed452e3bf 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -1015,7 +1015,8 @@ BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, lpRead, dwReadLen); }
-void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) +void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen, + const WCHAR *compStr, DWORD dwCompStrLen) { HIMC imc; LPINPUTCONTEXT lpIMC; @@ -1028,7 +1029,7 @@ void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) if (lpIMC == NULL) return;
- newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0); + newCompStr = updateCompStr(lpIMC->hCompStr, compStr, dwCompStrLen); ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = newCompStr;
@@ -1046,12 +1047,21 @@ void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0); }
- GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_COMPSTR); GenerateIMEMessage(imc, WM_IME_COMPOSITION, lpResult[0], GCS_RESULTSTR|GCS_RESULTCLAUSE); - GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); + if (dwCompStrLen > 0) + { + GenerateIMEMessage(imc, WM_IME_COMPOSITION, compStr[0], GCS_COMPSTR); + } + else + { + GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_COMPSTR); + }
if (!inComp) + { + GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); ImmSetOpenStatus(imc, FALSE); + }
ImmUnlockIMC(imc); } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f389f3e0836..e97df20e0d5 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -290,7 +290,8 @@ extern void IME_UpdateAssociation(HWND focus) DECLSPEC_HIDDEN; extern BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, LPCVOID lpRead, DWORD dwReadLen) DECLSPEC_HIDDEN; -extern void IME_SetResultString(LPWSTR lpResult, DWORD dwResultlen) DECLSPEC_HIDDEN; +extern void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen, + const WCHAR *compStr, DWORD dwCompStrLen) DECLSPEC_HIDDEN;
extern void X11DRV_XDND_EnterEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN; extern void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 3994c2106cc..7f2b6531e8a 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -115,7 +115,8 @@ void X11DRV_XIMLookupChars( const char *str, DWORD count ) if ((focus = GetFocus())) IME_UpdateAssociation(focus);
- IME_SetResultString(wcOutput, dwOutput); + IME_SetResultString(wcOutput, dwOutput, (WCHAR *) CompositionString, + dwCompStringLength / sizeof(WCHAR)); HeapFree(GetProcessHeap(), 0, wcOutput); }
Hi.
Wine invert the order of GCS_COMPSTR, GCS_RESULTSTR pair.
The XIM server sends messages in the correct order; please test the input with the attached test program.
$ XMODIFIERS=@im=ibus ./xim_test $ XMODIFIERS=@im=ibus WINEDEBUG=key,xim wine notepad
WINEDEBUG output shows that the order has been inverted.
I submitted two patches, please review it.
On 4/3/22 12:08 AM, Alex Kwak wrote:
IME_SetResultString() function overwrite composition string as empty. so, next composition may not appear on the displayed. but, still have an xim. Therefore, there was a string that seemed to have disappeared in the middle of the input.
Therefore, change it as follows. When calling IME_SetResultString(), if in a Composition state, no longer generate WM_IME_ENDCOMPOSITION and Use CompositionString in XIM to match the current XIM status rather than overwriting Composition.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52700 Signed-off-by: Alex Kwak take-me-home@kakao.com
v2: use updateCompStr instead IME_SetResultString. v3: Change the description and data type.
dlls/winex11.drv/ime.c | 18 ++++++++++++++---- dlls/winex11.drv/x11drv.h | 3 ++- dlls/winex11.drv/xim.c | 3 ++- 3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/ime.c b/dlls/winex11.drv/ime.c index c1584930861..51ed452e3bf 100644 --- a/dlls/winex11.drv/ime.c +++ b/dlls/winex11.drv/ime.c @@ -1015,7 +1015,8 @@ BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, lpRead, dwReadLen); }
-void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) +void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen,
const WCHAR *compStr, DWORD dwCompStrLen)
{ HIMC imc; LPINPUTCONTEXT lpIMC; @@ -1028,7 +1029,7 @@ void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) if (lpIMC == NULL) return;
- newCompStr = updateCompStr(lpIMC->hCompStr, NULL, 0);
- newCompStr = updateCompStr(lpIMC->hCompStr, compStr, dwCompStrLen); ImmDestroyIMCC(lpIMC->hCompStr); lpIMC->hCompStr = newCompStr;
@@ -1046,12 +1047,21 @@ void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen) GenerateIMEMessage(imc, WM_IME_STARTCOMPOSITION, 0, 0); }
- GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_COMPSTR); GenerateIMEMessage(imc, WM_IME_COMPOSITION, lpResult[0], GCS_RESULTSTR|GCS_RESULTCLAUSE);
- GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0);
if (dwCompStrLen > 0)
{
GenerateIMEMessage(imc, WM_IME_COMPOSITION, compStr[0], GCS_COMPSTR);
}
else
{
GenerateIMEMessage(imc, WM_IME_COMPOSITION, 0, GCS_COMPSTR);
}
if (!inComp)
{
GenerateIMEMessage(imc, WM_IME_ENDCOMPOSITION, 0, 0); ImmSetOpenStatus(imc, FALSE);
}
ImmUnlockIMC(imc);
} diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f389f3e0836..e97df20e0d5 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -290,7 +290,8 @@ extern void IME_UpdateAssociation(HWND focus) DECLSPEC_HIDDEN; extern BOOL IME_SetCompositionString(DWORD dwIndex, LPCVOID lpComp, DWORD dwCompLen, LPCVOID lpRead, DWORD dwReadLen) DECLSPEC_HIDDEN; -extern void IME_SetResultString(LPWSTR lpResult, DWORD dwResultlen) DECLSPEC_HIDDEN; +extern void IME_SetResultString(LPWSTR lpResult, DWORD dwResultLen,
const WCHAR *compStr, DWORD dwCompStrLen) DECLSPEC_HIDDEN;
extern void X11DRV_XDND_EnterEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN; extern void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 3994c2106cc..7f2b6531e8a 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -115,7 +115,8 @@ void X11DRV_XIMLookupChars( const char *str, DWORD count ) if ((focus = GetFocus())) IME_UpdateAssociation(focus);
- IME_SetResultString(wcOutput, dwOutput);
- IME_SetResultString(wcOutput, dwOutput, (WCHAR *) CompositionString,
HeapFree(GetProcessHeap(), 0, wcOutput);dwCompStringLength / sizeof(WCHAR));
}