diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index fe4a040046d..b78306dfb3d 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -143,7 +143,7 @@ Window CDECL X11DRV_create_desktop( UINT width, UINT height ) /* Create window */ win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | EnterWindowMask | - PointerMotionMask | ButtonPressMask | ButtonReleaseMask; + PointerMotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask; win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow ); if (visual != DefaultVisual( display, DefaultScreen(display) )) diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 3af56f8c614..52d4b81b081 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -706,6 +706,7 @@ static void X11DRV_FocusIn( HWND hwnd, XEvent *xev ) TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] ); if (event->detail == NotifyPointer) return; + if (hwnd == GetDesktopWindow()) return; if ((xic = X11DRV_get_ic( hwnd ))) { @@ -740,20 +741,13 @@ static void X11DRV_FocusOut( HWND hwnd, XEvent *xev ) int revert; XIC xic; - if (!hwnd) - { - if (event->detail == NotifyPointer && event->window == x11drv_thread_data()->clip_window) - { - TRACE( "clip window lost focus\n" ); - ungrab_clipping_window(); - ClipCursor( NULL ); /* make sure the clip rectangle is reset too */ - } - return; - } - TRACE( "win %p xwin %lx detail=%s\n", hwnd, event->window, focus_details[event->detail] ); - if (event->detail == NotifyPointer) return; + if (event->detail == NotifyPointer) + { + if (!hwnd && event->window == x11drv_thread_data()->clip_window) reset_clipping_window(); + return; + } if (ximInComposeMode) return; x11drv_thread_data()->last_focus = hwnd; @@ -763,8 +757,12 @@ static void X11DRV_FocusOut( HWND hwnd, XEvent *xev ) XUnsetICFocus( xic ); wine_tsx11_unlock(); } + if (root_window != DefaultRootWindow(event->display)) + { + if (hwnd == GetDesktopWindow()) reset_clipping_window(); + return; + } if (hwnd != GetForegroundWindow()) return; - if (root_window != DefaultRootWindow(event->display)) return; SendMessageW( hwnd, WM_CANCELMODE, 0, 0 ); /* don't reset the foreground window, if the window which is diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index fdc92ab6fe6..06805a7f77b 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -448,6 +448,17 @@ void ungrab_clipping_window(void) SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, 0 ); } +/*********************************************************************** + * reset_clipping_window + * + * Forcibly reset the window clipping on external events. + */ +void reset_clipping_window(void) +{ + ungrab_clipping_window(); + ClipCursor( NULL ); /* make sure the clip rectangle is reset too */ +} + /*********************************************************************** * clip_cursor_notify * diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 7113a02cb11..a924e06a6ed 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -831,6 +831,7 @@ extern void set_window_cursor( Window window, HCURSOR handle ); extern void sync_window_cursor( Window window ); extern LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd ); extern void ungrab_clipping_window(void); +extern void reset_clipping_window(void); extern void X11DRV_InitKeyboard( Display *display ); extern DWORD CDECL X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout, DWORD mask, DWORD flags );