server: Don't queue a hardware WM_MOUSEMOVE if the position hasn't changed.
diff --git a/server/queue.c b/server/queue.c
index c4657e6..b9b42e4 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -203,7 +203,7 @@
 /* pointer to input structure of foreground thread */
 static unsigned int last_input_time;
 
-static void queue_hardware_message( struct desktop *desktop, struct message *msg );
+static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue );
 static void free_message( struct message *msg );
 
 /* set the caret window in a given thread input */
@@ -343,7 +343,7 @@
     msg->data_size = sizeof(*msg_data);
     msg_data->x    = x;
     msg_data->y    = y;
-    queue_hardware_message( desktop, msg );
+    queue_hardware_message( desktop, msg, 1 );
 }
 
 /* set the cursor clip rectangle */
@@ -464,9 +464,10 @@
 static int merge_message( struct thread_input *input, const struct message *msg )
 {
     struct message *prev;
-    struct list *ptr = list_tail( &input->msg_list );
+    struct list *ptr;
 
-    if (!ptr) return 0;
+    if (msg->msg != WM_MOUSEMOVE) return 0;
+    if (!(ptr = list_tail( &input->msg_list ))) return 0;
     prev = LIST_ENTRY( ptr, struct message, entry );
     if (prev->result) return 0;
     if (prev->win && msg->win && prev->win != msg->win) return 0;
@@ -525,7 +526,7 @@
         if (!error && result)  /* rejected by the hook */
             free_message( res->hardware_msg );
         else
-            queue_hardware_message( res->desktop, res->hardware_msg );
+            queue_hardware_message( res->desktop, res->hardware_msg, 0 );
 
         res->hardware_msg = NULL;
     }
@@ -1274,7 +1275,7 @@
             if (owner->queue->input != input)
             {
                 list_remove( &msg->entry );
-                if (msg->msg == WM_MOUSEMOVE && merge_message( owner->queue->input, msg ))
+                if (merge_message( owner->queue->input, msg ))
                 {
                     free_message( msg );
                     release_object( owner );
@@ -1323,7 +1324,7 @@
 }
 
 /* queue a hardware message into a given thread input */
-static void queue_hardware_message( struct desktop *desktop, struct message *msg )
+static void queue_hardware_message( struct desktop *desktop, struct message *msg, int always_queue )
 {
     user_handle_t win;
     struct thread *thread;
@@ -1333,6 +1334,7 @@
 
     update_input_key_state( desktop, desktop->keystate, msg );
     last_input_time = get_tick_count();
+    if (msg->msg != WM_MOUSEMOVE) always_queue = 1;
 
     if (is_keyboard_msg( msg ))
     {
@@ -1344,8 +1346,11 @@
     {
         if (msg->msg == WM_MOUSEMOVE)
         {
-            desktop->cursor.x = min(max(data->x, desktop->cursor.clip.left), desktop->cursor.clip.right-1);
-            desktop->cursor.y = min(max(data->y, desktop->cursor.clip.top), desktop->cursor.clip.bottom-1);
+            int x = min( max( data->x, desktop->cursor.clip.left ), desktop->cursor.clip.right-1 );
+            int y = min( max( data->y, desktop->cursor.clip.top ), desktop->cursor.clip.bottom-1 );
+            if (desktop->cursor.x != x || desktop->cursor.y != y) always_queue = 1;
+            desktop->cursor.x = x;
+            desktop->cursor.y = y;
             desktop->cursor.last_change = get_tick_count();
         }
         if (desktop->keystate[VK_LBUTTON] & 0x80)  msg->wparam |= MK_LBUTTON;
@@ -1375,7 +1380,10 @@
     }
     input = thread->queue->input;
 
-    if (msg->msg == WM_MOUSEMOVE && merge_message( input, msg )) free_message( msg );
+    if (win != desktop->cursor.win) always_queue = 1;
+    desktop->cursor.win = win;
+
+    if (!always_queue || merge_message( input, msg )) free_message( msg );
     else
     {
         msg->unique_id = 0;  /* will be set once we return it to the app */
@@ -1514,10 +1522,10 @@
         if (!(flags & ((1 << sizeof(messages)/sizeof(messages[0])) - 1)))
         {
             if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
-                queue_hardware_message( desktop, msg );
+                queue_hardware_message( desktop, msg, 0 );
         }
         else if (!send_hook_ll_message( desktop, msg, input, NULL ))
-            queue_hardware_message( desktop, msg );
+            queue_hardware_message( desktop, msg, 0 );
     }
     return wait;
 }
@@ -1628,7 +1636,7 @@
         break;
     }
     if (!(wait = send_hook_ll_message( desktop, msg, input, sender )))
-        queue_hardware_message( desktop, msg );
+        queue_hardware_message( desktop, msg, 1 );
 
     return wait;
 }
@@ -1658,7 +1666,7 @@
     msg->data      = msg_data;
     msg->data_size = sizeof(*msg_data);
 
-    queue_hardware_message( desktop, msg );
+    queue_hardware_message( desktop, msg, 1 );
 }
 
 /* check message filter for a hardware message */