user32: Globally invalidate key state on changes in other threads.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Sebastian Lackner 2017-12-18 16:20:58 +01:00 committed by Alexandre Julliard
parent 54c414d96a
commit 059d5ece23
1 changed files with 12 additions and 2 deletions

View File

@ -390,6 +390,7 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
struct user_key_state_info *key_state_info = get_user_thread_info()->key_state;
INT counter = global_key_state_counter;
BYTE prev_key_state;
SHORT ret;
if (key < 0 || key >= 256) return 0;
@ -417,14 +418,23 @@ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
{
req->tid = 0;
req->key = key;
if (key_state_info) wine_server_set_reply( req, key_state_info->state,
sizeof(key_state_info->state) );
if (key_state_info)
{
prev_key_state = key_state_info->state[key];
wine_server_set_reply( req, key_state_info->state, sizeof(key_state_info->state) );
}
if (!wine_server_call( req ))
{
if (reply->state & 0x40) ret |= 0x0001;
if (reply->state & 0x80) ret |= 0x8000;
if (key_state_info)
{
/* force refreshing the key state cache - some multithreaded programs
* (like Adobe Photoshop CS5) expect that changes to the async key state
* are also immediately available in other threads. */
if (prev_key_state != key_state_info->state[key])
counter = interlocked_xchg_add( &global_key_state_counter, 1 ) + 1;
key_state_info->time = GetTickCount();
key_state_info->counter = counter;
}