At 05:19 PM 6/21/00 -0400, you (Stephane Lussier) wrote:
>Hi,
Hello Stephane
>There's a race condition when receiving an Expose event in Wine that could
>end out with a window not being painted correctly. Let me "expose" the
>problem.
Yes, I think I have seen something like that.
I'm a bit late in answering, but I am deep under the water currently :-/
>Application thread is doing:
>1.a. ShowWindow(Window "abc", SW_SHOW)
>1.b. RedrawWindow(Window "abc")
>1.b.1. Validate the window abc
>1.b.2. Paint the window abc
>
>Service thread on XExposeEvent is doing
>2.a. EVENT_Expose(window "abc")
>2.a.1 RedrawWindow(window "abc", RDW_INVALIDATE | RDW_ERASE_NOW | ...)
>2.a.1.1 Invalidate the expose area for window "abc"
>2.a.1.2 SendMessage(window "abc", WM_ERASEBACKGRND)
>
>
>When running my application I have a thread switch between 1.b.1 and 1.b.2
>(which is possible for whatever reason)
>
>1.So here's the problem, the application is doing a ShowWindow(), which will
>cause a ExposeEvent to be posted in the X queue.
>
>2.There's a thread switch, now the service thread is running, it processes
>the expose Event, call RedrawWindow, which will eventually Invalidate the
>window, and which will eventually call SendMessage(window "abc",
>WM_ERASEBKGND)
>
>3. This is an inter-thread SendMessage, so it's blocking until the
>application thread do a PeekMesage().
>
>4. The application regain the control, call RedrawWindow(), validate the
>window, paint the window and eventually call PeekMessage()
>
>5. The application receives the WM_ERASEBKGND and process the message by
>erasing the background (and erasing the content at the same time).
>
>6. We end out with a window that is valid (do not need to be updated) and
>the background painted but not the content.
>
>
>
>In the Corel tree, they fixed the problem, by forcing a repaint in
>EVENT_Expose() by calling RedrawWindow with RDW_UPDATENOW flag. This fixed
>the problem, but cause some side effects like causing the window to be
>painted too many times when dragging it with the mouse for resizing/moving
>the window.
>
>What I proposed for solution is to instead of forcing the repaint,
>invalidate the window again after the RedrawWindow call. It's not as pretty
>as Corel solution, but it is more efficient.
That's a problem I was hoping to tackle some time (lot of more urgent
problems in the stack); my first idea was rather to flag the windows to be 'in
painting',
test the flag in the event code and just pass on the redrawwindow call; what do you
think of this approach ? (I did not even think to begin a preliminary trial
version so maybe there is an obvious fatal flaw...)
After trying your patch, the test app I had written to test another problem
(and exhibited this one instead :-)) repaints correctly... but sometimes one
time too much. Also ForteFreeAgent 32 (1.21) splash screen flickers
sometime.
Bye
Gerard