This adds keyboard input support while Wine windows are in background, so the events can be translated to raw input messages as on Windows, which are required to keep dinput8 keyboard state up-to-date when Alt+Tab is used to switch to a non-Wine window. --- dlls/winex11.drv/keyboard.c | 42 +++++++++++++++++++++++++++++++++- dlls/winex11.drv/mouse.c | 6 +++++ dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 1 + 4 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 61a2881e60c..f336256c15d 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -33,6 +33,9 @@ #ifdef HAVE_X11_XKBLIB_H #include <X11/XKBlib.h> #endif +#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H +#include <X11/extensions/XInput2.h> +#endif
#include <ctype.h> #include <stdarg.h> @@ -1148,7 +1151,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD f input.u.ki.time = time; input.u.ki.dwExtraInfo = 0;
- __wine_send_input( hwnd, &input, 0 ); + __wine_send_input( hwnd, &input, SEND_HWMSG_SKIP_RAW ); }
@@ -1417,6 +1420,43 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev ) return TRUE; }
+ +#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H +/*********************************************************************** + * X11DRV_KeyEvent + * + * Handle a raw XInput2 key event for background windows + */ +BOOL X11DRV_RawKeyEvent( XGenericEventCookie *cookie ) +{ + XIRawEvent *event = cookie->data; + DWORD flags; + WORD vkey, scan; + INPUT input; + + vkey = keyc2vkey[event->detail]; + scan = keyc2scan[event->detail]; + + flags = 0; + if ( event->evtype == XI_RawKeyRelease ) flags |= KEYEVENTF_KEYUP; + if ( vkey & 0x100 ) flags |= KEYEVENTF_EXTENDEDKEY; + + TRACE_(key)( "vkey=%04x scan=%04x flags=%04x\n", vkey, scan, flags ); + + input.type = INPUT_KEYBOARD; + input.u.ki.wVk = vkey & 0xff; + input.u.ki.wScan = scan & 0xff; + input.u.ki.dwFlags = flags; + input.u.ki.time = EVENT_x11_time_to_win32_time(event->time); + input.u.ki.dwExtraInfo = 0; + + __wine_send_input( 0, &input, SEND_HWMSG_BCAST_RAW | SEND_HWMSG_ONLY_RAW ); + + return TRUE; +} +#endif + + /********************************************************************** * X11DRV_KEYBOARD_DetectLayout * diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 1074586f628..03397a69e02 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -331,6 +331,8 @@ void X11DRV_XInput2_Enable(void) { XISetMask( mask_bits, XI_RawButtonPress ); XISetMask( mask_bits, XI_RawButtonRelease ); + XISetMask( mask_bits, XI_RawKeyPress ); + XISetMask( mask_bits, XI_RawKeyRelease ); data->xi2_rawinput_only = TRUE; } else @@ -1933,6 +1935,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev ) case XI_RawButtonRelease: ret = X11DRV_RawButtonEvent( event ); break; + case XI_RawKeyPress: + case XI_RawKeyRelease: + ret = X11DRV_RawKeyEvent( event ); + break;
default: TRACE( "Unhandled event %#x\n", event->evtype ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index b981beb6660..32fbfd38d2d 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -514,6 +514,7 @@ extern BOOL X11DRV_ButtonRelease( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN; extern BOOL X11DRV_MotionNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN; extern BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN; extern BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN; +extern BOOL X11DRV_RawKeyEvent( XGenericEventCookie *cookie ) DECLSPEC_HIDDEN; extern BOOL X11DRV_KeymapNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN; extern BOOL X11DRV_DestroyNotify( HWND hwnd, XEvent *event ) DECLSPEC_HIDDEN; extern BOOL X11DRV_SelectionRequest( HWND hWnd, XEvent *event ) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index c3a2ef93db2..4f615611afe 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -532,6 +532,7 @@ static void init_visuals( Display *display, int screen ) default_visual.visualid, default_visual.class, argb_visual.visualid ); }
+ /*********************************************************************** * X11DRV process initialisation routine */