I'm getting pretty much the same problem, except that in my case
restarting WindowMaker does fix it. I found this statement in actions.c
(function wSetFocusTo) suspicious:

    if (scr->flags.ignore_focus_events || LastFocusChange > timestamp)
        return;

timestamp is defined like this:

    int timestamp=LastTimestamp;

where LastTimestamp is of type Time (which is an unsigned 32-bit integer
according to my /usr/include/X11/X.h) and so is LastFocusChange.

This way of comparing timestamps is broken and not only because of the
signedness. If this is the cause of this bug, then it should be
reproducable exactly every 24 days, 20 hours, 31 mins, 23.648 seconds
(which is 2^31 milliseconds) or maybe the double.

I've attached a patch that compares the timestamps properly. It is done
against version 0.92.0-6.1 which is current in etch as of this writing.

I have just checked that it does not seem to break anything and that
reverting the condition (the direction of the comparison) causes the
expected symptoms. I have not verified that the bug is periodic, so I
can't be sure that this will fix it. If necessary I can wait for another
24 days (or maybe 48) if no downtime happens here, to verify the
periodicity of the bug and another 24 (or 48) more to check if the fix
works.

-- Pedro Gimeno
--- actions.c.original	2005-07-03 19:25:14.000000000 +0200
+++ actions.c	2008-03-31 00:17:26.000000000 +0200
@@ -78,6 +78,18 @@
 #define SHADE_STEPS	shadePars[(int)wPreferences.shade_speed].steps
 #define SHADE_DELAY	shadePars[(int)wPreferences.shade_speed].delay
 
+static int
+compareTimes(Time t1, Time t2)
+{
+    Time diff;
+    /* Perform a comparison modulo 2^30, to avoid all kinds of
+       overflow problems. */
+    if (t1 == t2)
+      return 0;
+    diff = ((t1 & 0x3FFFFFFFL) | 0x40000000L) - (t2 & 0x3FFFFFFFL);
+    diff &= 0x3FFFFFFFL;
+    return (diff >= 0x20000000L) ? -1 : 1;
+}
 
 /*
  *----------------------------------------------------------------------
@@ -99,11 +111,11 @@
 
     WWindow *old_focused;
     WWindow *focused=scr->focused_window;
-    int timestamp=LastTimestamp;
+    Time timestamp=LastTimestamp;
     WApplication *oapp=NULL, *napp=NULL;
     int wasfocused;
 
-    if (scr->flags.ignore_focus_events || LastFocusChange > timestamp)
+    if (scr->flags.ignore_focus_events || compareTimes(LastFocusChange, timestamp) > 0)
         return;
 
     if (!old_scr)

Reply via email to