winewayland.drv: Release all keys on keyboard focus loss.

The Wayland specification states about the keyboard leave event:

  After this event client must assume that all keys, including
  modifiers, are lifted and also it must stop key repeating if
  there's some going on.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56001
This commit is contained in:
Alexandros Frantzis 2023-12-12 12:13:15 +02:00 committed by Alexandre Julliard
parent c3dcf1e269
commit b853a670cf

View file

@ -33,6 +33,7 @@
#include "waylanddrv.h" #include "waylanddrv.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/server.h"
WINE_DEFAULT_DEBUG_CHANNEL(keyboard); WINE_DEFAULT_DEBUG_CHANNEL(keyboard);
WINE_DECLARE_DEBUG_CHANNEL(key); WINE_DECLARE_DEBUG_CHANNEL(key);
@ -602,6 +603,50 @@ static BOOL find_xkb_layout_variant(const char *name, const char **layout, const
return FALSE; return FALSE;
} }
static BOOL get_async_key_state(BYTE state[256])
{
BOOL ret;
SERVER_START_REQ(get_key_state)
{
req->async = 1;
req->key = -1;
wine_server_set_reply(req, state, 256);
ret = !wine_server_call(req);
}
SERVER_END_REQ;
return ret;
}
static void release_all_keys(HWND hwnd)
{
BYTE state[256];
int vkey;
INPUT input = {.type = INPUT_KEYBOARD};
get_async_key_state(state);
for (vkey = 1; vkey < 256; vkey++)
{
/* Skip mouse buttons. */
if (vkey < 7 && vkey != VK_CANCEL) continue;
/* Skip left/right-agnostic modifier vkeys. */
if (vkey == VK_SHIFT || vkey == VK_CONTROL || vkey == VK_MENU) continue;
if (state[vkey] & 0x80)
{
UINT scan = NtUserMapVirtualKeyEx(vkey, MAPVK_VK_TO_VSC_EX,
keyboard_hkl);
input.ki.wVk = vkey;
input.ki.wScan = scan & 0xff;
input.ki.dwFlags = KEYEVENTF_KEYUP;
if (scan & ~0xff) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
__wine_send_input(hwnd, &input, NULL);
}
}
}
/********************************************************************** /**********************************************************************
* Keyboard handling * Keyboard handling
*/ */
@ -745,6 +790,10 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard,
keyboard->focused_hwnd = NULL; keyboard->focused_hwnd = NULL;
pthread_mutex_unlock(&keyboard->mutex); pthread_mutex_unlock(&keyboard->mutex);
/* The spec for the leave event tells us to treat all keys as released,
* and for any key repetition to stop. */
release_all_keys(hwnd);
/* FIXME: update foreground window as well */ /* FIXME: update foreground window as well */
} }