This is perhaps third or fourth time I send some kind of patch that would fix this annoying bug that locks several games (unless you use desktop mode). This time I try to make the patch as small as possible. The patch should not change how Wine handles focus (even though Wine focus handling is quite far from ICCCM compliance). The patch adds one SetFocus call, the missing of which is actually bug because it means that X11 and Wine may have different ideas about which window has focus. Changelog: Changed the input model of managed windows from passive input into globally active input. Moved code to detect focus changes from FocusIn handler to WM_TAKE_FOCUS handler. Index: dlls/x11drv/window.c =================================================================== RCS file: /home/wine/wine/dlls/x11drv/window.c,v retrieving revision 1.31 diff -u -b -r1.31 window.c --- dlls/x11drv/window.c 9 Mar 2002 23:44:35 -0000 1.31 +++ dlls/x11drv/window.c 30 Apr 2002 20:02:31 -0000 @@ -637,8 +637,7 @@ winContext = XUniqueContext(); wmProtocols = XInternAtom( display, "WM_PROTOCOLS", False ); wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", False ); -/* wmTakeFocus = XInternAtom( display, "WM_TAKE_FOCUS", False );*/ - wmTakeFocus = 0; /* not yet */ + wmTakeFocus = XInternAtom( display, "WM_TAKE_FOCUS", False ); dndProtocol = XInternAtom( display, "DndProtocol" , False ); dndSelection = XInternAtom( display, "DndSelection" , False ); wmChangeState = XInternAtom( display, "WM_CHANGE_STATE", False ); Index: windows/x11drv/event.c =================================================================== RCS file: /home/wine/wine/windows/x11drv/event.c,v retrieving revision 1.115 diff -u -b -r1.115 event.c --- windows/x11drv/event.c 22 Mar 2002 01:03:36 -0000 1.115 +++ windows/x11drv/event.c 30 Apr 2002 20:03:05 -0000 @@ -56,6 +56,7 @@ extern Atom wmProtocols; extern Atom wmDeleteWindow; +extern Atom wmTakeFocus; extern Atom dndProtocol; extern Atom dndSelection; @@ -99,6 +100,7 @@ static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event); static void EVENT_PropertyNotify( XPropertyEvent *event ); static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event ); +static void EVENT_TakeFocus( HWND hWnd, XClientMessageEvent *event ); extern void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event ); extern void X11DRV_ButtonRelease( HWND hwnd, XButtonEvent *event ); @@ -368,7 +370,15 @@ */ static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event ) { - WND *pWndLastFocus; +} + + +/********************************************************************** + * EVENT_TakeFocus + */ +static void EVENT_TakeFocus( HWND hWnd, XClientMessageEvent *event ) +{ + HWND pWndLastFocus; XWindowAttributes win_attr; BOOL bIsDisabled; @@ -391,15 +401,21 @@ if (XGetWindowAttributes( event->display, glastXFocusWin, &win_attr ) && (win_attr.map_state == IsViewable) ) { + /* + * FIXME: The call below is required because time stamp used by + * X11DRV_SetFocus is not valid in all cases. When + * that routine is fixed, this call can be deleted, + * since SetFocus calls X11DRV_SetFocus. + */ XSetInputFocus( event->display, glastXFocusWin, RevertToParent, CurrentTime ); wine_tsx11_unlock(); + SetFocus(pWndLastFocus); return; } } wine_tsx11_unlock(); } - if (event->detail != NotifyPointer && hWnd != GetForegroundWindow()) SetForegroundWindow( hWnd ); } @@ -1252,6 +1268,11 @@ /* Ignore the delete window request if the window has been disabled */ if (!(GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED)) PostMessageA( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 ); + } + else if (event->message_type == wmProtocols && + (Atom)event->data.l[0] == wmTakeFocus) + { + EVENT_TakeFocus(hWnd, event); } else if (event->message_type == dndProtocol) { -- Jukka Heinonen <http://www.iki.fi/jhei/>