server: Send mouse hardware messages to thread owning top-most window.
Also don't limit mouse message scope to top-most window when message comes from SendInput or window that generated the event is minimized/transparent.
This commit is contained in:
parent
2235c820a9
commit
3f1bbdcae3
|
@ -1803,8 +1803,8 @@ static void test_Input_mouse(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
|
ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
|
||||||
todo_wine ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
|
ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
|
||||||
todo_wine ok(got_button_up, "expected WM_RBUTTONUP message\n");
|
ok(got_button_up, "expected WM_RBUTTONUP message\n");
|
||||||
DestroyWindow(static_win);
|
DestroyWindow(static_win);
|
||||||
|
|
||||||
/* click through HTTRANSPARENT top-level window */
|
/* click through HTTRANSPARENT top-level window */
|
||||||
|
|
|
@ -7295,7 +7295,7 @@ static void window_from_point_proc(HWND parent)
|
||||||
DispatchMessageA(&msg);
|
DispatchMessageA(&msg);
|
||||||
}
|
}
|
||||||
ok(got_hittest, "transparent window didn't get WM_NCHITTEST message\n");
|
ok(got_hittest, "transparent window didn't get WM_NCHITTEST message\n");
|
||||||
todo_wine ok(got_click, "button under static window didn't get WM_LBUTTONUP\n");
|
ok(got_click, "button under static window didn't get WM_LBUTTONUP\n");
|
||||||
|
|
||||||
ret = WaitForSingleObject(end_event, 5000);
|
ret = WaitForSingleObject(end_event, 5000);
|
||||||
ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret);
|
ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret);
|
||||||
|
|
|
@ -1379,11 +1379,13 @@ found:
|
||||||
|
|
||||||
/* find the window that should receive a given hardware message */
|
/* find the window that should receive a given hardware message */
|
||||||
static user_handle_t find_hardware_message_window( struct desktop *desktop, struct thread_input *input,
|
static user_handle_t find_hardware_message_window( struct desktop *desktop, struct thread_input *input,
|
||||||
struct message *msg, unsigned int *msg_code )
|
struct message *msg, unsigned int *msg_code,
|
||||||
|
struct thread **thread )
|
||||||
{
|
{
|
||||||
struct hardware_msg_data *data = msg->data;
|
struct hardware_msg_data *data = msg->data;
|
||||||
user_handle_t win = 0;
|
user_handle_t win = 0;
|
||||||
|
|
||||||
|
*thread = NULL;
|
||||||
*msg_code = msg->msg;
|
*msg_code = msg->msg;
|
||||||
if (msg->msg == WM_INPUT)
|
if (msg->msg == WM_INPUT)
|
||||||
{
|
{
|
||||||
|
@ -1397,14 +1399,16 @@ static user_handle_t find_hardware_message_window( struct desktop *desktop, stru
|
||||||
if (*msg_code < WM_SYSKEYDOWN) *msg_code += WM_SYSKEYDOWN - WM_KEYDOWN;
|
if (*msg_code < WM_SYSKEYDOWN) *msg_code += WM_SYSKEYDOWN - WM_KEYDOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* mouse message */
|
else if (!input || !(win = input->capture)) /* mouse message */
|
||||||
{
|
{
|
||||||
if (!input || !(win = input->capture))
|
if (is_window_visible( msg->win ) && !is_window_transparent( msg->win )) win = msg->win;
|
||||||
{
|
else win = shallow_window_from_point( desktop, data->x, data->y );
|
||||||
if (!(win = msg->win) || !is_window_visible( win ) || is_window_transparent( win ))
|
|
||||||
win = window_from_point( desktop, data->x, data->y );
|
*thread = window_thread_from_point( win, data->x, data->y );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!*thread)
|
||||||
|
*thread = get_window_thread( win );
|
||||||
return win;
|
return win;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,8 +1495,8 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg
|
||||||
}
|
}
|
||||||
else input = desktop->foreground_input;
|
else input = desktop->foreground_input;
|
||||||
|
|
||||||
win = find_hardware_message_window( desktop, input, msg, &msg_code );
|
win = find_hardware_message_window( desktop, input, msg, &msg_code, &thread );
|
||||||
if (!win || !(thread = get_window_thread(win)))
|
if (!win || !thread)
|
||||||
{
|
{
|
||||||
if (input) update_input_key_state( input->desktop, input->keystate, msg );
|
if (input) update_input_key_state( input->desktop, input->keystate, msg );
|
||||||
free_message( msg );
|
free_message( msg );
|
||||||
|
@ -1928,8 +1932,8 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
|
||||||
struct hardware_msg_data *data = msg->data;
|
struct hardware_msg_data *data = msg->data;
|
||||||
|
|
||||||
ptr = list_next( &input->msg_list, ptr );
|
ptr = list_next( &input->msg_list, ptr );
|
||||||
win = find_hardware_message_window( input->desktop, input, msg, &msg_code );
|
win = find_hardware_message_window( input->desktop, input, msg, &msg_code, &win_thread );
|
||||||
if (!win || !(win_thread = get_window_thread( win )))
|
if (!win || !win_thread)
|
||||||
{
|
{
|
||||||
/* no window at all, remove it */
|
/* no window at all, remove it */
|
||||||
update_input_key_state( input->desktop, input->keystate, msg );
|
update_input_key_state( input->desktop, input->keystate, msg );
|
||||||
|
|
|
@ -157,7 +157,8 @@ extern int is_window_visible( user_handle_t window );
|
||||||
extern int is_window_transparent( user_handle_t window );
|
extern int is_window_transparent( user_handle_t window );
|
||||||
extern int make_window_active( user_handle_t window );
|
extern int make_window_active( user_handle_t window );
|
||||||
extern struct thread *get_window_thread( user_handle_t handle );
|
extern struct thread *get_window_thread( user_handle_t handle );
|
||||||
extern user_handle_t window_from_point( struct desktop *desktop, int x, int y );
|
extern user_handle_t shallow_window_from_point( struct desktop *desktop, int x, int y );
|
||||||
|
extern struct thread *window_thread_from_point( user_handle_t scope, int x, int y );
|
||||||
extern user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *thread );
|
extern user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *thread );
|
||||||
extern struct window_class *get_window_class( user_handle_t window );
|
extern struct window_class *get_window_class( user_handle_t window );
|
||||||
|
|
||||||
|
|
|
@ -727,14 +727,38 @@ static int get_window_children_from_point( struct window *parent, int x, int y,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find window containing point (in absolute coords) */
|
/* get handle of root of top-most window containing point */
|
||||||
user_handle_t window_from_point( struct desktop *desktop, int x, int y )
|
user_handle_t shallow_window_from_point( struct desktop *desktop, int x, int y )
|
||||||
{
|
{
|
||||||
struct window *ret;
|
struct window *ptr;
|
||||||
|
|
||||||
if (!desktop->top_window) return 0;
|
if (!desktop->top_window) return 0;
|
||||||
ret = child_window_from_point( desktop->top_window, x, y );
|
|
||||||
return ret->handle;
|
LIST_FOR_EACH_ENTRY( ptr, &desktop->top_window->children, struct window, entry )
|
||||||
|
{
|
||||||
|
if (!is_point_in_window( ptr, x, y )) continue; /* skip it */
|
||||||
|
return ptr->handle;
|
||||||
|
}
|
||||||
|
return desktop->top_window->handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return thread of top-most window containing point (in absolute coords) */
|
||||||
|
struct thread *window_thread_from_point( user_handle_t scope, int x, int y )
|
||||||
|
{
|
||||||
|
struct window *win = get_user_object( scope, USER_WINDOW );
|
||||||
|
struct window *ptr;
|
||||||
|
|
||||||
|
if (!win) return NULL;
|
||||||
|
|
||||||
|
for (ptr = win; ptr && !is_desktop_window(ptr); ptr = ptr->parent)
|
||||||
|
{
|
||||||
|
x -= ptr->client_rect.left;
|
||||||
|
y -= ptr->client_rect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = child_window_from_point( win, x, y );
|
||||||
|
if (!ptr->thread) return NULL;
|
||||||
|
return (struct thread *)grab_object( ptr->thread );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return list of all windows containing point (in absolute coords) */
|
/* return list of all windows containing point (in absolute coords) */
|
||||||
|
|
Loading…
Reference in New Issue