1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-05 17:28:47 +00:00

server: Queue a hardware WM_WINE_CLIPCURSOR message to the foreground thread.

When applying a new cursor clipping rect, or to the previous foreground
thread when foreground changes, to notify it of the cursor clipping rect
being reset.
This commit is contained in:
Rémi Bernon 2023-06-02 12:11:21 +02:00 committed by Alexandre Julliard
parent bd06c87b5b
commit 5ebb1ed132
2 changed files with 52 additions and 4 deletions

View File

@ -449,8 +449,25 @@ static void get_message_defaults( struct msg_queue *queue, int *x, int *y, unsig
*time = get_tick_count(); *time = get_tick_count();
} }
static void queue_clip_cursor_msg( struct desktop *desktop, lparam_t wparam, lparam_t lparam )
{
static const struct hw_msg_source source = { IMDT_UNAVAILABLE, IMO_SYSTEM };
struct thread_input *input;
struct message *msg;
if (!(msg = alloc_hardware_message( 0, source, get_tick_count(), 0 ))) return;
msg->msg = WM_WINE_CLIPCURSOR;
msg->wparam = wparam;
msg->lparam = lparam;
msg->x = desktop->cursor.x;
msg->y = desktop->cursor.y;
if ((input = desktop->foreground_input)) msg->win = input->active;
queue_hardware_message( desktop, msg, 1 );
}
/* set the cursor clip rectangle */ /* set the cursor clip rectangle */
void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int send_clip_msg ) void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int reset )
{ {
rectangle_t top_rect; rectangle_t top_rect;
int x, y; int x, y;
@ -468,12 +485,16 @@ void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int s
} }
else desktop->cursor.clip = top_rect; else desktop->cursor.clip = top_rect;
if (send_clip_msg) post_desktop_message( desktop, WM_WINE_CLIPCURSOR, rect == NULL, 0 );
/* warp the mouse to be inside the clip rect */ /* warp the mouse to be inside the clip rect */
x = max( min( desktop->cursor.x, desktop->cursor.clip.right - 1 ), desktop->cursor.clip.left ); x = max( min( desktop->cursor.x, desktop->cursor.clip.right - 1 ), desktop->cursor.clip.left );
y = max( min( desktop->cursor.y, desktop->cursor.clip.bottom - 1 ), desktop->cursor.clip.top ); y = max( min( desktop->cursor.y, desktop->cursor.clip.bottom - 1 ), desktop->cursor.clip.top );
if (x != desktop->cursor.x || y != desktop->cursor.y) set_cursor_pos( desktop, x, y ); if (x != desktop->cursor.x || y != desktop->cursor.y) set_cursor_pos( desktop, x, y );
/* request clip cursor rectangle reset to the desktop thread */
if (reset) post_desktop_message( desktop, WM_WINE_CLIPCURSOR, TRUE, FALSE );
/* notify foreground thread, of reset, or to apply new cursor clipping rect */
queue_clip_cursor_msg( desktop, rect == NULL, reset );
} }
/* change the foreground input and reset the cursor clip rect */ /* change the foreground input and reset the cursor clip rect */
@ -558,6 +579,7 @@ static inline int get_hardware_msg_bit( struct message *msg )
if (msg->msg == WM_INPUT_DEVICE_CHANGE || msg->msg == WM_INPUT) return QS_RAWINPUT; if (msg->msg == WM_INPUT_DEVICE_CHANGE || msg->msg == WM_INPUT) return QS_RAWINPUT;
if (msg->msg == WM_MOUSEMOVE || msg->msg == WM_NCMOUSEMOVE) return QS_MOUSEMOVE; if (msg->msg == WM_MOUSEMOVE || msg->msg == WM_NCMOUSEMOVE) return QS_MOUSEMOVE;
if (msg->msg >= WM_KEYFIRST && msg->msg <= WM_KEYLAST) return QS_KEY; if (msg->msg >= WM_KEYFIRST && msg->msg <= WM_KEYLAST) return QS_KEY;
if (msg->msg == WM_WINE_CLIPCURSOR) return QS_RAWINPUT;
return QS_MOUSEBUTTON; return QS_MOUSEBUTTON;
} }
@ -610,10 +632,36 @@ static int merge_mousemove( struct thread_input *input, const struct message *ms
return 1; return 1;
} }
/* try to merge a WM_WINE_CLIPCURSOR message with the last in the list; return 1 if successful */
static int merge_wine_clipcursor( struct thread_input *input, const struct message *msg )
{
struct message *prev;
LIST_FOR_EACH_ENTRY_REV( prev, &input->msg_list, struct message, entry )
if (prev->msg == WM_WINE_CLIPCURSOR) break;
if (&prev->entry == &input->msg_list) return 0;
if (prev->result) return 0;
if (prev->win != msg->win) return 0;
if (prev->type != msg->type) return 0;
/* now we can merge it */
prev->wparam = msg->wparam;
prev->lparam = msg->lparam;
prev->x = msg->x;
prev->y = msg->y;
prev->time = msg->time;
list_remove( &prev->entry );
list_add_tail( &input->msg_list, &prev->entry );
return 1;
}
/* try to merge a message with the messages in the list; return 1 if successful */ /* try to merge a message with the messages in the list; return 1 if successful */
static int merge_message( struct thread_input *input, const struct message *msg ) static int merge_message( struct thread_input *input, const struct message *msg )
{ {
if (msg->msg == WM_MOUSEMOVE) return merge_mousemove( input, msg ); if (msg->msg == WM_MOUSEMOVE) return merge_mousemove( input, msg );
if (msg->msg == WM_WINE_CLIPCURSOR) return merge_wine_clipcursor( input, msg );
return 0; return 0;
} }

View File

@ -109,7 +109,7 @@ extern void queue_cleanup_window( struct thread *thread, user_handle_t win );
extern int init_thread_queue( struct thread *thread ); extern int init_thread_queue( struct thread *thread );
extern int attach_thread_input( struct thread *thread_from, struct thread *thread_to ); extern int attach_thread_input( struct thread *thread_from, struct thread *thread_to );
extern void detach_thread_input( struct thread *thread_from ); extern void detach_thread_input( struct thread *thread_from );
extern void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int send_clip_msg ); extern void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int reset );
extern void post_message( user_handle_t win, unsigned int message, extern void post_message( user_handle_t win, unsigned int message,
lparam_t wparam, lparam_t lparam ); lparam_t wparam, lparam_t lparam );
extern void send_notify_message( user_handle_t win, unsigned int message, extern void send_notify_message( user_handle_t win, unsigned int message,