Module: wine Branch: master Commit: 4b81771b00c2f60bb4cd4c9cfedb1a77a59213e8 URL: https://source.winehq.org/git/wine.git/?a=commit;h=4b81771b00c2f60bb4cd4c9cf...
Author: Rémi Bernon rbernon@codeweavers.com Date: Fri Aug 30 12:17:58 2019 +0200
winex11.drv: Do not react to keyboard grab focus events.
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 bringing activity view back and forth, or clicking on the title bar, only NotifyUngrab event 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@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
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 edeae7c..ff4cbb2 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 TRUE; /* 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 TRUE; /* ignore wm specific NotifyUngrab / NotifyGrab events w.r.t focus */ + } + focus_out( event->display, hwnd ); return TRUE; }