[PATCH] winex11.drv: Also send input events when the keymap state has changed

Rémi Bernon rbernon at codeweavers.com
Wed Aug 7 08:44:58 CDT 2019


When pressing Alt-Tab for example, the application receives the KeyPress
event for Alt key before losing focus, but when focusing it back it
never receives the corresponding KeyRelease event and this can lead to
incorrect key state for applications listening on WM_SYSKEYUP/DOWN
messages, or for applications that use dinput keyboard device which is
implemented with the corresponding low-level keyboard hooks messages.

When focus is gained back the application receives a KeymapNotify to
indicate the full keyboard state, and this can be used to make up for
the missing KeyRelease events.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/winex11.drv/keyboard.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 131c5f5442f..166b5446aab 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1209,14 +1209,20 @@ BOOL X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
     int i, j;
     BYTE keystate[256];
     WORD vkey;
+    WORD scan;
+    DWORD flags;
     BOOL changed = FALSE;
     struct {
         WORD vkey;
+        WORD scan;
         WORD pressed;
     } keys[256];
 
     if (!get_async_key_state( keystate )) return FALSE;
 
+    /* from KeymapNotify documentation this should always be true */
+    if (!hwnd) hwnd = GetForegroundWindow();
+
     memset(keys, 0, sizeof(keys));
 
     EnterCriticalSection( &kbd_section );
@@ -1229,11 +1235,13 @@ BOOL X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
         for (j = 0; j < 8; j++)
         {
             vkey = keyc2vkey[(i * 8) + j];
+            scan = keyc2scan[(i * 8) + j] & 0xff;
 
             /* If multiple keys map to the same vkey, we want to report it as
              * pressed iff any of them are pressed. */
             if (!keys[vkey & 0xff].vkey) keys[vkey & 0xff].vkey = vkey;
             if (event->xkeymap.key_vector[i] & (1<<j)) keys[vkey & 0xff].pressed = TRUE;
+            keys[vkey & 0xff].scan = scan;
         }
     }
 
@@ -1244,6 +1252,14 @@ BOOL X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
             TRACE( "Adjusting state for vkey %#.2x. State before %#.2x\n",
                    keys[vkey].vkey, keystate[vkey]);
 
+            flags = 0;
+            if (!keys[vkey].pressed)
+               flags |= KEYEVENTF_KEYUP;
+            if (keys[vkey].vkey & 0x100)
+               flags |= KEYEVENTF_EXTENDEDKEY;
+
+            X11DRV_send_keyboard_input( hwnd, vkey, keys[vkey].scan, flags, GetTickCount() );
+
             update_key_state( keystate, vkey, keys[vkey].pressed );
             changed = TRUE;
         }
-- 
2.20.1




More information about the wine-devel mailing list