Focus livelock

Gerard Patel gerard.patel at nerim.net
Mon Sep 10 10:02:20 CDT 2001


At 10:09 AM 09/09/2001 +0300, you wrote:
>I posted a patch that would fix a focus related livelock.
>However, I have to admit that the patch is quite hacky and likely 
>not to be included in Wine. Since I would like to get this bug fixed,
>I thought to ask opinions about the correct way to fix the bug.
>
>The short description of the bug is that setting 
>active/foreground/focus window in Wine calls
>X11DRV_SetFocus, which calls XSetInputFocus. 
>This makes Wine receive FocusIn event, the handler of
>which calls SetForegroundWindow. Even though SetForegroundWindow
>does nothing if its parameter matches current foreground window,
>it can be easily seen that having more than one window can lead
>into livelock.

I think that the problem with focus is that when a window is shown
by Wine, synthetic WM_GETFOCUS and WM_SETFOCUS events
are generated, that are themselves generating X focus events.
The X events are kept in the X queue until Wine finds time to handle
them.
Wine creates window  A : WM_GETFOCUS for A
Wine creates window B : WM_KILLFOCUS for A, WM_GETFOCUS for B
Wine creates window C : WM_KILLFOCUS for B, WM_GETFOCUS for C

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.

The following hack disables focus handling in this case. I have no
clue on its value since I am currently struggling with other bugs.
and I will not come to these problems until some time - maybe a lot
of time if current Wine progress (aka regressions :-)) continues.

--- event.c.orig        Fri Aug 24 09:30:46 2001
+++ event.c     Mon Sep 10 13:00:28 2001
@@ -534,6 +534,8 @@
 
     if (!hWnd) return;
 
+    if (!event->send_event) return;
+
     bIsDisabled = GetWindowLongA( hWnd, GWL_STYLE ) & WS_DISABLED;
 
     /* If the window has been disabled and we are in managed mode,

HTH
Gerard





More information about the wine-devel mailing list