user32: Cache the global key state to avoid performance issues in applications that poll constantly.
This commit is contained in:
parent
5a30e31806
commit
cb3b723792
|
@ -385,6 +385,10 @@ static LRESULT call_hook( struct hook_info *info, INT code, WPARAM wparam, LPARA
|
|||
thread_info->hook_unicode = prev_unicode;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->id == WH_KEYBOARD_LL || info->id == WH_MOUSE_LL)
|
||||
get_user_thread_info()->key_state_time = 0; /* force refreshing the key state cache */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -374,21 +374,31 @@ HWND WINAPI GetCapture(void)
|
|||
*/
|
||||
SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState( INT key )
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
SHORT ret;
|
||||
|
||||
if (key < 0 || key >= 256) return 0;
|
||||
|
||||
if ((ret = USER_Driver->pGetAsyncKeyState( key )) == -1)
|
||||
{
|
||||
if (thread_info->key_state)
|
||||
{
|
||||
if (GetTickCount() - thread_info->key_state_time < 50)
|
||||
return (thread_info->key_state[key] & 0x80) ? 0x8000 : 0;
|
||||
}
|
||||
else thread_info->key_state = HeapAlloc( GetProcessHeap(), 0, 256 );
|
||||
|
||||
ret = 0;
|
||||
SERVER_START_REQ( get_key_state )
|
||||
{
|
||||
req->tid = 0;
|
||||
req->key = key;
|
||||
if (thread_info->key_state) wine_server_set_reply( req, thread_info->key_state, 256 );
|
||||
if (!wine_server_call( req ))
|
||||
{
|
||||
if (reply->state & 0x40) ret |= 0x0001;
|
||||
if (reply->state & 0x80) ret |= 0x8000;
|
||||
thread_info->key_state_time = GetTickCount();
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
|
|
@ -3112,6 +3112,7 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
|
|||
*/
|
||||
NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
||||
{
|
||||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
struct send_message_info info;
|
||||
NTSTATUS ret;
|
||||
BOOL wait;
|
||||
|
@ -3149,11 +3150,14 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags )
|
|||
req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH );
|
||||
break;
|
||||
}
|
||||
if (thread_info->key_state) wine_server_set_reply( req, thread_info->key_state, 256 );
|
||||
ret = wine_server_call( req );
|
||||
wait = reply->wait;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!ret && thread_info->key_state) thread_info->key_state_time = GetTickCount();
|
||||
|
||||
if (wait)
|
||||
{
|
||||
LRESULT ignored;
|
||||
|
|
|
@ -312,6 +312,7 @@ static void thread_detach(void)
|
|||
if (thread_info->msg_window) WIN_DestroyThreadWindows( thread_info->msg_window );
|
||||
CloseHandle( thread_info->server_queue );
|
||||
HeapFree( GetProcessHeap(), 0, thread_info->wmchar_data );
|
||||
HeapFree( GetProcessHeap(), 0, thread_info->key_state );
|
||||
|
||||
exiting_thread_id = 0;
|
||||
}
|
||||
|
|
|
@ -176,10 +176,12 @@ struct user_thread_info
|
|||
DWORD GetMessagePosVal; /* Value for GetMessagePos */
|
||||
ULONG_PTR GetMessageExtraInfoVal; /* Value for GetMessageExtraInfo */
|
||||
UINT active_hooks; /* Bitmap of active hooks */
|
||||
UINT key_state_time; /* Time of last key state refresh */
|
||||
BYTE *key_state; /* Cache of global key state */
|
||||
HWND top_window; /* Desktop window */
|
||||
HWND msg_window; /* HWND_MESSAGE parent window */
|
||||
|
||||
ULONG pad[11]; /* Available for more data */
|
||||
ULONG pad[9]; /* Available for more data */
|
||||
};
|
||||
|
||||
struct hook_extra_info
|
||||
|
|
|
@ -401,6 +401,7 @@ BOOL WINAPI SetThreadDesktop( HDESK handle )
|
|||
struct user_thread_info *thread_info = get_user_thread_info();
|
||||
thread_info->top_window = 0;
|
||||
thread_info->msg_window = 0;
|
||||
thread_info->key_state_time = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue