Piotr Caban : imm32: Destroy default IME windows in ImmDisableIME.
Alexandre Julliard
julliard at winehq.org
Fri Oct 15 15:40:06 CDT 2021
Module: wine
Branch: master
Commit: 684d023faad9549c642274d02c1363d5d179a417
URL: https://source.winehq.org/git/wine.git/?a=commit;h=684d023faad9549c642274d02c1363d5d179a417
Author: Piotr Caban <piotr at codeweavers.com>
Date: Fri Oct 15 15:27:24 2021 +0200
imm32: Destroy default IME windows in ImmDisableIME.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/imm32/imm.c | 50 +++++++++++++++++++++++++++++++++++++-------
dlls/imm32/tests/imm32.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c
index 023d816a51e..1230c2e2b95 100644
--- a/dlls/imm32/imm.c
+++ b/dlls/imm32/imm.c
@@ -992,18 +992,58 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
return FALSE;
}
+static HWND imm_detach_default_window(IMMThreadData *thread_data)
+{
+ HWND to_destroy;
+
+ imm_couninit_thread(thread_data, TRUE);
+ to_destroy = thread_data->hwndDefault;
+ thread_data->hwndDefault = NULL;
+ thread_data->windowRefs = 0;
+ return to_destroy;
+}
+
/***********************************************************************
* ImmDisableIME (IMM32.@)
*/
BOOL WINAPI ImmDisableIME(DWORD idThread)
{
+ IMMThreadData *thread_data;
+ HWND to_destroy;
+
if (idThread == (DWORD)-1)
+ {
disable_ime = TRUE;
- else {
- IMMThreadData *thread_data = IMM_GetThreadData(NULL, idThread);
+
+ while (1)
+ {
+ to_destroy = 0;
+ EnterCriticalSection(&threaddata_cs);
+ LIST_FOR_EACH_ENTRY(thread_data, &ImmThreadDataList, IMMThreadData, entry)
+ {
+ if (thread_data->hwndDefault)
+ {
+ to_destroy = imm_detach_default_window(thread_data);
+ break;
+ }
+ }
+ LeaveCriticalSection(&threaddata_cs);
+
+ if (!to_destroy)
+ break;
+ DestroyWindow(to_destroy);
+ }
+ }
+ else
+ {
+ thread_data = IMM_GetThreadData(NULL, idThread);
if (!thread_data) return FALSE;
thread_data->disableIME = TRUE;
+ to_destroy = imm_detach_default_window(thread_data);
LeaveCriticalSection(&threaddata_cs);
+
+ if (to_destroy)
+ DestroyWindow(to_destroy);
}
return TRUE;
}
@@ -1878,11 +1918,7 @@ void WINAPI __wine_unregister_window(HWND hwnd)
/* Destroy default IME window */
if (thread_data->windowRefs == 0)
- {
- imm_couninit_thread(thread_data, TRUE);
- to_destroy = thread_data->hwndDefault;
- thread_data->hwndDefault = NULL;
- }
+ to_destroy = imm_detach_default_window(thread_data);
LeaveCriticalSection(&threaddata_cs);
if (to_destroy) DestroyWindow( to_destroy );
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c
index 759b564aba9..9e0e59d384d 100644
--- a/dlls/imm32/tests/imm32.c
+++ b/dlls/imm32/tests/imm32.c
@@ -2241,6 +2241,57 @@ static void test_com_initialization(void)
test_apttype(-1);
}
+static DWORD WINAPI disable_ime_thread(void *arg)
+{
+ HWND h, def;
+ MSG msg;
+ BOOL r;
+
+ h = CreateWindowA("static", "static", 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ ok(h != NULL, "CreateWindow failed\n");
+ def = ImmGetDefaultIMEWnd(h);
+ ok(def != NULL, "ImmGetDefaultIMEWnd returned NULL\n");
+
+ r = ImmDisableIME(arg ? GetCurrentThreadId() : 0);
+ ok(r, "ImmDisableIME failed\n");
+
+ if (arg)
+ {
+ def = ImmGetDefaultIMEWnd(h);
+ todo_wine ok(def != NULL, "ImmGetDefaultIMEWnd returned NULL\n");
+ while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
+ DispatchMessageA(&msg);
+ }
+ def = ImmGetDefaultIMEWnd(h);
+ ok(!def, "ImmGetDefaultIMEWnd returned %p\n", def);
+ return 0;
+}
+
+static void test_ImmDisableIME(void)
+{
+ HANDLE thread;
+ HWND def;
+ BOOL r;
+
+ def = ImmGetDefaultIMEWnd(hwnd);
+ ok(def != NULL, "ImmGetDefaultIMEWnd(hwnd) returned NULL\n");
+
+ thread = CreateThread(NULL, 0, disable_ime_thread, 0, 0, NULL);
+ ok(thread != NULL, "CreateThread failed\n");
+ WaitForSingleObject(thread, INFINITE);
+ CloseHandle(thread);
+
+ thread = CreateThread(NULL, 0, disable_ime_thread, (void*)1, 0, NULL);
+ ok(thread != NULL, "CreateThread failed\n");
+ WaitForSingleObject(thread, INFINITE);
+ CloseHandle(thread);
+
+ r = ImmDisableIME(-1);
+ ok(r, "ImmDisableIME(-1) failed\n");
+ def = ImmGetDefaultIMEWnd(hwnd);
+ ok(!def, "ImmGetDefaultIMEWnd(hwnd) returned %p\n", def);
+}
+
START_TEST(imm32) {
if (!is_ime_enabled())
{
@@ -2276,6 +2327,9 @@ START_TEST(imm32) {
if (pSendInput)
test_ime_processkey();
else win_skip("SendInput is not available\n");
+
+ /* there's no way of enabling IME - keep the test last */
+ test_ImmDisableIME();
}
cleanup();
}
More information about the wine-cvs
mailing list