Howdy,
Another in my pattern of posting intermediate debugging results here, in case anyone can contribute some insight...
Looking into the bug that Dimitrie reported here: http://www.winehq.com/hypermail/wine-devel/2002/09/0748.html
Here is what is happening (testing on the Listview Control Spy) when sliding the obscuring window. I changed a bunch of TRACE messages to ERR, and added a few. The window of interest, that the artifacts are appearing in is 0x10039 (the "Control Notifications" window):
err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 0,138 11x1 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 304,138 4x1 err:x11drv:X11DRV_Expose win 0x10039 (2e00032) 0,110 2x1 err:x11drv:X11DRV_Expose win 0x10039 (2e00033) 0,108 99x1 err:x11drv:X11DRV_Expose win 0x10040 (2e00041) 0,126 293x1 err:win:BeginPaint hwnd 0x10021 hdc = 0x9e8 box = (0,138 - 409,139) err:win:EndPaint Here err:win:BeginPaint hwnd 0x10039 hdc = 0x9e8 box = (0,108 - 99,109) err:win:EndPaint Here err:win:BeginPaint hwnd 0x10040 hdc = 0x9e8 box = (0,0 - 293,186) err:win:EndPaint Here err:win:BeginPaint hwnd 0x10047 hdc = 0x890 box = (0,109 - 277,110) err:win:EndPaint Here
So an initial exposure occurred and was almost immediately painted. The obscuring window is now at y=109. The first expose of the pair is a validate, and the second is the invalidate. Then ScrollWindowEx is called, which eventually gets to X11DRV_ScrollDC, where the bitblt that scrolls the window is called.
err:bitblt:BitBlt hdcSrc=0x9e8 0,14 24 bpp->hdcDest=0x9e8 0,0 126x154x24 rop=cc0020
After scrolling, X11DRV_EndGraphicsExposures is called, which checks pending exposure events as a result of the scroll.
err:x11drv:X11DRV_EndGraphicsExposures got 0,96 99x14 count 0
Note that the exposed part is the rectangle with y coordinates from 96 to 110. That means that before the bitblt copy had occurred, the obscuring window had already moved down one pixel. The bitblt moved the previously obscured rectangle at (0,109 - 99,110) to (0,95 - 99,96), but that rectangle did not get into the update rectangle.
This is because the only pending events checked are those that are a direct result of exposure due to the copy in bitblt, and does not include any additional areas that were exposed by sliding the obscuring region.
err:scroll:X11DRV_ScrollWindowEx A hwnd 0x10039 rgn rect = (0,96,126,168) err:win:GetUpdateRgn hrgnUpdate 0 err:scroll:X11DRV_ScrollWindowEx B hwnd 0x10039 rgn rect = (0,96,126,168)
It should be pointed out that X did not lose the exposure event due to sliding the obscuring window, because here it shows up in the next exposure event
err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 0,139 11x1 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 304,139 4x1 err:x11drv:X11DRV_Expose win 0x10039 (2e00032) 0,111 2x1 err:x11drv:X11DRV_Expose win 0x10039 (2e00033) 0,109 99x1 ^^^ Unfortunately, we have already handled the offset due to scrolling, so this event is put into the update region unshifted. The remaining exposures are new, so no shifting is needed.
err:x11drv:X11DRV_Expose win 0x10040 (2e00041) 0,127 293x1 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 0,140 11x3 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 304,140 4x3 err:x11drv:X11DRV_Expose win 0x10039 (2e00032) 0,112 2x3 err:x11drv:X11DRV_Expose win 0x10039 (2e00033) 0,110 99x3 err:x11drv:X11DRV_Expose win 0x10040 (2e00041) 0,128 293x3 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 0,143 11x1 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 304,143 4x1 err:x11drv:X11DRV_Expose win 0x10039 (2e00032) 0,115 2x1 err:x11drv:X11DRV_Expose win 0x10039 (2e00033) 0,113 99x1 err:x11drv:X11DRV_Expose win 0x10040 (2e00041) 0,131 293x1 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 0,144 11x2 err:x11drv:X11DRV_Expose win 0x10021 (2e00003) 304,144 4x2 err:x11drv:X11DRV_Expose win 0x10039 (2e00032) 0,116 2x2 err:x11drv:X11DRV_Expose win 0x10039 (2e00033) 0,114 99x2 err:x11drv:X11DRV_Expose win 0x10040 (2e00041) 0,132 293x2 err:win:BeginPaint hwnd 0x10021 hdc = 0x890 box = (0,139 - 409,146) err:win:EndPaint Here
And finally the update region is painted. This update region includes the region exposed by the scroll, plus all the additional exposure events that occurred due to sliding the obscuring window.
err:win:BeginPaint hwnd 0x10039 hdc = 0x890 box = (0,96 - 126,168) err:win:EndPaint Here
But there is a one pixel artifact at (0,95 - 99,96), because it is not in the update region.
Fundamentally, the problem is that the X events are handled out of order, because X11DRV_EndGraphicsExposures stripped out particular events (due to copying) without accounting for other pending events that might be relevant (plain old exposure).
Duane Clark wrote:
Fundamentally, the problem is that the X events are handled out of order, because X11DRV_EndGraphicsExposures stripped out particular events (due to copying) without accounting for other pending events that might be relevant (plain old exposure).
Well, that conclusion appears to not be quite correct. I stuck a XPending check at the end of X11DRV_EndGraphicsExposures to see whether there were any pending events, and there were apparently none. So I am not sure why the GraphicsExpose event is coming out before the regular expose event, since in real time, they occurred in the opposite order.