Several of the most used WMs are sending FocusOut events with NotifyGrab mode whenever they take a keyboard grab, which is the case for example when window is being moved from a title bar click, when screen is locked or when activity view is brought up. When releasing the grab they then send FocusIn events with NotifyUngrabbed mode.
However, XGetInputFocus call still returns that the current window still has the input focus, so Wine was not changing the foregound window.
This was causing various number of focus and mouse grab issues when locking screen, moving windows with their title bar, or using the super key to bring up application overview.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winex11.drv/event.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 61dd56dcb4c..42b74b0a973 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -794,9 +794,9 @@ static BOOL X11DRV_FocusIn( HWND hwnd, XEvent *xev ) /********************************************************************** * focus_out */ -static void focus_out( Display *display , HWND hwnd ) +static void focus_out( Display *display , HWND hwnd, BOOL grabbed ) { - HWND hwnd_tmp; + HWND focus_hwnd; Window focus_win; int revert; XIC xic; @@ -820,11 +820,11 @@ static void focus_out( Display *display , HWND hwnd ) XGetInputFocus( display, &focus_win, &revert ); if (focus_win) { - if (XFindContext( display, focus_win, winContext, (char **)&hwnd_tmp ) != 0) + if (XFindContext( display, focus_win, winContext, (char **)&focus_hwnd ) != 0) focus_win = 0; }
- if (!focus_win) + if (!focus_win || (grabbed && focus_hwnd == hwnd)) { /* Abey : 6-Oct-99. Check again if the focus out window is the Foreground window, because in most cases the messages sent @@ -855,7 +855,7 @@ static BOOL X11DRV_FocusOut( HWND hwnd, XEvent *xev ) return TRUE; } if (!hwnd) return FALSE; - focus_out( event->display, hwnd ); + focus_out( event->display, hwnd, event->mode == NotifyGrab ); return TRUE; }
@@ -1665,12 +1665,12 @@ static void handle_xembed_protocol( HWND hwnd, XClientMessageEvent *event )
case XEMBED_WINDOW_DEACTIVATE: TRACE( "win %p/%lx XEMBED_WINDOW_DEACTIVATE message\n", hwnd, event->window ); - focus_out( event->display, GetAncestor( hwnd, GA_ROOT ) ); + focus_out( event->display, GetAncestor( hwnd, GA_ROOT ), FALSE ); break;
case XEMBED_FOCUS_OUT: TRACE( "win %p/%lx XEMBED_FOCUS_OUT message\n", hwnd, event->window ); - focus_out( event->display, GetAncestor( hwnd, GA_ROOT ) ); + focus_out( event->display, GetAncestor( hwnd, GA_ROOT ), FALSE ); break;
case XEMBED_MODALITY_ON: