Gerard Patel gerard.patel@nerim.net writes:
Now, when after all this the X events are processed, Wine handles a X focusin event for A, that is generating a WM_GETFOCUS, then a focusout for A, generating other WM_KILLFOCUS and WM_ GETFOCUS, focusin for B, etc..; the sequence of events when creating windows is perfect, but there are extra events after.
IMO what's wrong is that X focus events are not ignored when they are the following of program action.
IMO the right fix is to add support for the take focus window manager protocol, and avoid messing with the X focus ourselves. This is somewhere on my todo list...
IMO the right fix is to add support for the take focus window manager protocol, and avoid messing with the X focus ourselves. This is somewhere on my todo list...
Take focus protocol would indeed solve this problem. According to ICCCM (and assuming Globally Active Input model) you can only switch focus using XSetInputFocus if you either already have focus in one of your windows or you receive WM_TAKE_FOCUS client message or you receive mouse press/release (or passive grabbed key events, but I bet Wine doesn't want to deal with them).
The latter two cases also identify those places where we want to call SetForegroundWindow (instead of in FocusIn handler) and if called from these two places I think livelock is not possible (needs to be checked).
It seems there are still few problems left:
1. DirectDraw GrabPointer forces input focus using XSetInputFocus, this should probably be changed to XGrabKeyboard so that we are compliant with ICCCM.
2. WM_TAKE_FOCUS (or mouse event) time stamp needs to be forwarded to the XSetInputFocus call.
3. If WM_TAKE_FOCUS (or mouse event) handling calls SetForegroundWindow, Wine application believes it has input focus even though request has only been pushed into X queue. This means that another Wine window may still receive keyboard events, which could cause problems even though I fail to figure any good examples...
4. It is not possible for a Wine application to get input focus by calling SetForegroundWindow unless user clicks Wine window or Window Manager decides to yield focus.
5. If we have non-managed windows (by setting x11drv/Managed to N for example), these windows can only get focus if they either grab keyboard or the application has a managed top-level window that has input focus. Which means clicking mouse over these windows does not transfer focus unless we grab keyboard (just like in case 1). However, this would mean that non-Wine windows stop to receive input focus...