From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/user32/tests/input.c | 8 ++++---- server/queue.c | 34 +++++++++++++++++++++++++++++----- 2 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 31d7f1fad35..3052ce6832c 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -3195,13 +3195,13 @@ static void test_rawinput_keyboard( const char* argv0 ) #define RAW_KEY(s, f, v, m, ...) {.func = RAW_INPUT_KEYBOARD, .raw_input.kbd = {.MakeCode = s, .Flags = f, .VKey = v, .Message = m}, ## __VA_ARGS__} struct send_input_keyboard_test raw_test[] = { - {.expect = {RAW_KEY(1, RI_KEY_MAKE, 'A', WM_KEYDOWN), {0, .todo = TRUE}}, .expect_async = {['A'] = 0x80}}, - {.expect = {RAW_KEY(1, RI_KEY_BREAK, 'A', WM_KEYUP), {0, .todo = TRUE}}}, + {.expect = {RAW_KEY(1, RI_KEY_MAKE, 'A', WM_KEYDOWN), {0}}, .expect_async = {['A'] = 0x80}}, + {.expect = {RAW_KEY(1, RI_KEY_BREAK, 'A', WM_KEYUP), {0}}}, }; struct send_input_keyboard_test raw_test_no_focus[] = { - {.expect = {RAW_KEY(1, RI_KEY_MAKE, 'A', WM_KEYDOWN, .todo = TRUE), {0, .todo = TRUE}}, .expect_async = {['A'] = 0x80}}, - {.expect = {RAW_KEY(1, RI_KEY_BREAK, 'A', WM_KEYUP, .todo = TRUE), {0, .todo = TRUE}}}, + {.expect = {RAW_KEY(1, RI_KEY_MAKE, 'A', WM_KEYDOWN, .todo = TRUE), {0}}, .expect_async = {['A'] = 0x80}}, + {.expect = {RAW_KEY(1, RI_KEY_BREAK, 'A', WM_KEYUP, .todo = TRUE), {0}}}, }; struct send_input_keyboard_test raw_test_no_fg[] = {{.expect_async = {['A'] = 0x80}}, {}}; #undef RAW_KEY diff --git a/server/queue.c b/server/queue.c index 2e9460e4c0a..f90ffb58af5 100644 --- a/server/queue.c +++ b/server/queue.c @@ -2086,15 +2086,32 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons return wait; }
+static struct thread *get_keyboard_message_thread( struct desktop *desktop, user_handle_t win ) +{ + struct thread *thread; + struct thread_input *input; + user_handle_t target = 0; + + if (win && (thread = get_window_thread( win ))) + { + input = thread->queue->input; + release_object( thread ); + } + else input = desktop->foreground_input; + + if (input && !(target = input->focus)) target = input->active; + + return get_window_thread( target ); +} + /* queue a hardware message for a keyboard event */ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, unsigned int origin, struct msg_queue *sender ) { struct hw_msg_source source = { IMDT_KEYBOARD, origin }; - const struct rawinput_device *device; struct hardware_msg_data *msg_data; struct message *msg; - struct thread *foreground; + struct thread *foreground, *msg_thread; unsigned char vkey = input->kbd.vkey, hook_vkey = vkey; unsigned int message_code, time; lparam_t lparam = input->kbd.scan << 16; @@ -2207,10 +2224,17 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c release_object( foreground ); }
- if ((device = current->process->rawinput_kbd) && (device->flags & RIDEV_NOLEGACY)) + if ((msg_thread = get_keyboard_message_thread( desktop, win ))) { - update_input_key_state( desktop, desktop->keystate, message_code, vkey ); - return 0; + const struct rawinput_device *device = msg_thread->process->rawinput_kbd; + BOOL nolegacy = device && (device->flags & RIDEV_NOLEGACY); + + release_object( msg_thread ); + if (nolegacy) + { + update_input_key_state( desktop, desktop->keystate, message_code, vkey ); + return 0; + } }
if (!(msg = alloc_hardware_message( input->kbd.info, source, time, 0 ))) return 0;