[PATCH v3 4/6] winex11.drv: Do not react to keyboard grab focus events

Rémi Bernon rbernon at codeweavers.com
Thu Jun 27 09:30:13 CDT 2019


Several window managers are sending FocusOut with NotifyGrab mode
then FocusOut with NotifyWhileGrabbed mode when a window focus is lost,
as a consequence of grabbing the keyboard input before changing window
focus.

This is the case during alt-tab, but keyboard can also be grabbed when
bringing activity view or clicking on the title bar. In this cases
NotifyWhileGrabbed events aren't sent until the window really loses
foreground.

In the same manner, when focus is restored, they usually send FocusIn
with NotifyWhileGrabbed mode followed by FocusIn with NotifyUngrab mode
when the keyboard grab is released.

When pressing Super key, or clicking on the title bar, only NotifyGrab
and NotifyUngrab mode events will be sent.

In order to be consistent across WM and to help simplifying focus
handling, just ignore focus events related to keyboard grabs.

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

diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index 92d35466a35..83e09477ba7 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -772,6 +772,19 @@ static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev )
     if (event->detail == NotifyPointer) return FALSE;
     if (hwnd == GetDesktopWindow()) return FALSE;
 
+    switch (event->mode)
+    {
+    case NotifyGrab:
+        WARN( "unexpected FocusIn event with NotifyGrab mode\n" );
+        break;
+    case NotifyWhileGrabbed:
+        break;
+    case NotifyNormal:
+        break;
+    case NotifyUngrab:
+        return FALSE; /* ignore wm specific NotifyUngrab / NotifyGrab events w.r.t focus */
+    }
+
     if ((xic = X11DRV_get_ic( hwnd ))) XSetICFocus( xic );
     if (use_take_focus)
     {
@@ -855,6 +868,20 @@ static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev )
         return TRUE;
     }
     if (!hwnd) return FALSE;
+
+    switch (event->mode)
+    {
+    case NotifyUngrab:
+        WARN( "unexpected FocusOut event with NotifyUngrab mode\n" );
+        break;
+    case NotifyNormal:
+        break;
+    case NotifyWhileGrabbed:
+        break;
+    case NotifyGrab:
+        return FALSE; /* ignore wm specific NotifyUngrab / NotifyGrab events w.r.t focus */
+    }
+
     focus_out( event->display, hwnd );
     return TRUE;
 }
-- 
2.20.1




More information about the wine-devel mailing list