> 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...
--
Jukka Heinonen <http://www.iki.fi/jhei/>