Aric Stewart : server: Fixup input windows on thread_detach.

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 6 09:29:05 CDT 2015


Module: wine
Branch: master
Commit: 3599f956e2bfe3dd76d7134ddd06b1e5cf5be4d5
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3599f956e2bfe3dd76d7134ddd06b1e5cf5be4d5

Author: Aric Stewart <aric at codeweavers.com>
Date:   Tue May  5 09:14:25 2015 -0500

server: Fixup input windows on thread_detach.

---

 dlls/user32/tests/input.c | 80 +++++++++++++++++++++++++++++++++++++++++------
 server/queue.c            | 21 ++++++++++++-
 2 files changed, 90 insertions(+), 11 deletions(-)

diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 78f4d8b..30b91a0 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -2028,6 +2028,12 @@ static void test_Input_mouse(void)
 
 static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
+    if (message == WM_USER+1)
+    {
+        HWND hwnd = (HWND)lParam;
+        ok(GetFocus() == hwnd, "thread expected focus %p, got %p\n", hwnd, GetFocus());
+        ok(GetActiveWindow() == hwnd, "thread expected active %p, got %p\n", hwnd, GetActiveWindow());
+    }
     return DefWindowProcA(hwnd, message, wParam, lParam);
 }
 
@@ -2067,7 +2073,7 @@ static DWORD WINAPI thread_proc(void *param)
 static void test_attach_input(void)
 {
     HANDLE hThread;
-    HWND ourWnd;
+    HWND ourWnd, Wnd2;
     DWORD ret, tid;
     struct wnd_event wnd_event;
     WNDCLASSA cls;
@@ -2102,6 +2108,10 @@ static void test_attach_input(void)
                             0, 0, 0, 0, 0, 0, 0, NULL);
     ok(ourWnd!= 0, "failed to create ourWnd window\n");
 
+    Wnd2 = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
+                            0, 0, 0, 0, 0, 0, 0, NULL);
+    ok(Wnd2!= 0, "failed to create Wnd2 window\n");
+
     SetFocus(ourWnd);
     SetActiveWindow(ourWnd);
 
@@ -2111,8 +2121,35 @@ static void test_attach_input(void)
     ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
     ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
 
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
+
     ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
     ok(ret, "AttachThreadInput error %d\n", GetLastError());
+    ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
+    ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == ourWnd, "expected active %p, got %p\n", ourWnd, GetActiveWindow());
+    ok(GetFocus() == ourWnd, "expected focus %p, got %p\n", ourWnd, GetFocus());
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)ourWnd);
+
+    SetActiveWindow(Wnd2);
+    SetFocus(Wnd2);
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)Wnd2);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
 
     ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
     ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
@@ -2122,11 +2159,6 @@ static void test_attach_input(void)
 
     wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
     wnd_event.setWindows = TRUE;
-    if (!wnd_event.start_event)
-    {
-        win_skip("skipping interthread message test under win9x\n");
-        return;
-    }
 
     hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
     ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
@@ -2134,10 +2166,6 @@ static void test_attach_input(void)
     ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
     CloseHandle(wnd_event.start_event);
 
-    ourWnd = CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW,
-                                      100, 100, 200, 200, 0, 0, 0, NULL);
-    ok(ourWnd!= 0, "failed to create ourWnd window\n");
-
     SetFocus(ourWnd);
     SetActiveWindow(ourWnd);
 
@@ -2147,14 +2175,46 @@ static void test_attach_input(void)
     ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
     ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
 
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)wnd_event.hwnd);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
+    ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)wnd_event.hwnd);
+
+    ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+    ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+    ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
+    ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)wnd_event.hwnd);
+
+    SetFocus(Wnd2);
+    SetActiveWindow(Wnd2);
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, (LPARAM)Wnd2);
+
     ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
     ok(ret, "AttachThreadInput error %d\n", GetLastError());
 
+    ok(GetActiveWindow() == Wnd2, "expected active %p, got %p\n", Wnd2, GetActiveWindow());
+    ok(GetFocus() == Wnd2, "expected focus %p, got %p\n", Wnd2, GetFocus());
+
+    SendMessageA(wnd_event.hwnd, WM_USER+1, 0, 0);
+
     ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
     ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
 
     ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
     CloseHandle(hThread);
+    DestroyWindow(ourWnd);
+    DestroyWindow(Wnd2);
 }
 
 START_TEST(input)
diff --git a/server/queue.c b/server/queue.c
index 350d45a..30869a0 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -1095,10 +1095,29 @@ int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
 /* detach two thread input data structures */
 void detach_thread_input( struct thread *thread_from )
 {
-    struct thread_input *input;
+    struct thread *thread;
+    struct thread_input *input, *old_input = thread_from->queue->input;
 
     if ((input = create_thread_input( thread_from )))
     {
+        if (old_input->focus && (thread = get_window_thread( old_input->focus )))
+        {
+            if (thread == thread_from)
+            {
+                input->focus = old_input->focus;
+                old_input->focus = 0;
+            }
+            release_object( thread );
+        }
+        if (old_input->active && (thread = get_window_thread( old_input->active )))
+        {
+            if (thread == thread_from)
+            {
+                input->active = old_input->active;
+                old_input->active = 0;
+            }
+            release_object( thread );
+        }
         assign_thread_input( thread_from, input );
         release_object( input );
     }




More information about the wine-cvs mailing list