In my attempts to make wily time aware for autosaving, I tried to use ecanread in the main event loop, to keep the loop going without fuss as long as there are queued events to process and no awakening timer event needs to be rigged. (It looks like this might not be worthwhile, but I want to be careful and evaluate different ways.) Anyhow, I found a bug in 9libs. eread processes X event one at a time until it gets a 9libs event to return. If ecanread doesn't find any queued 9libs events, it too processes X events one at a time until there is one 9libs event on the queue or there are no more X events. eread always starts with processing one X event, so after a call to first ecanread and then to eread, there may be two 9libs events queued up. If they are both mouse events, a very rarely invoked mouse events "compression" feature kicks in, and all but the last 9libs mouse event are dropped. This is good for mouse movements, but bad for mouse buttons. I think multiple 9libs mouse events can queue up under other circumstances too, but since wily as it is only uses eread in its main event loop, it is very unlikely to happen. Further, the button mouse events must come close in time to make one disappear, and they must have different button configurations to cause any bad effect. The only way I succeed with this on my equipment is with the scroll wheel (I have the scroll wheel patches applied). Yet further, for the "button depressed" (first) event to disappear (the only interesting case), its X event must be processed and queued from ecanread, and thus must come close in time after some other event (processed and queued from eread). This happens when I move the mouse at the same time as I turn the scroll wheel. Yeah, real big deal, huh? :-) I'm so surprised no one has discovered this before. ;-) Ok, it's hard to keep the mouse absolutely still when using the scroll wheel, so the impression is that wily's response to the scroll wheel sometimes gets very sluggish. I find it confusing that 9libs both has this mouse event compression and does not process X events more aggressively, since it thus will never get a chance to compress mouse events. I tried to make it always process all pending X mouse events (after fixing the bug), to make better use of the compression, and while I span the mouse wheel furiously and flung the mouse around, I managed to peak with three cut out mouse events. So, the bug is in code that almost never is invoked, and when it is, the benefit of it is highly questionable. (I think, I have not tried it on a slow computer.) Anyhow, the bug is a bug, and a patch is at the end of this email. -- Tommy Pettersson <ptp@xxxxxxxxxxxxxx> diff -rN -u diff-old/9libs-1.0/libXg/xtbinit.c diff-new/9libs-1.0/libXg/xtbinit.c --- diff-old/9libs-1.0/libXg/xtbinit.c Fri Oct 15 16:19:09 2004 +++ diff-new/9libs-1.0/libXg/xtbinit.c Fri Oct 15 16:18:49 2004 @@ -832,7 +832,7 @@ eb = s->head; #ifdef COMPRESSMOUSE if(s == &esrc[Smouse]) { - while(eb->next) { + while(eb->next && ((Mouse*) eb->buf)->buttons == ((Mouse*) eb->next->buf)->buttons) { s->head = eb->next; s->count--; free(eb);