Fixed an interesting bug in the app_server, after beating my head against

this for a long time... what happens when the app_server has requested a
redraw, but the client sends some drawing commands before starting the
redraw session? This would be the case, for example, when TextViews got
notified of their parent window becomming active (they would invert the
selection outside of any update session). When there was an additional
expose event, the app_server would already have the background cleared, so
the lonely "invert" command would invert the freshly painted background. Then
the normal Draw() of the TextView would be called because of the expose event.
By the time the text was rendered, it was rendered on the inverted background,
then the normal Draw() contained another "invert" command to invert the
region of the selection. Thus inverting just the text, and the background
twice. Solution:
* introduced a special handling for drawing commands arriving between
  requested update session and beginning of that session: the pending
  update region is clipped from the region the client is allowed to draw in.
* fixes funny text rendering in the selected part of text views. For example
  ticket #908.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21867 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2007-08-09 00:33:50 +00:00
parent e83f8dc9a0
commit 05357ae700

View File

@ -563,7 +563,11 @@ WindowLayer::GetEffectiveDrawingRegion(ViewLayer* layer, BRegion& region)
{
if (!fEffectiveDrawingRegionValid) {
fEffectiveDrawingRegion = VisibleContentRegion();
if (fInUpdate) {
if (fUpdateRequested && !fInUpdate) {
// we requested an update, but the client has not started it yet,
// so it is only allowed to draw outside the pending update sessions region
fEffectiveDrawingRegion.Exclude(&fPendingUpdateSession.DirtyRegion());
} else if (fInUpdate) {
// enforce the dirty region of the update session
fEffectiveDrawingRegion.IntersectWith(&fCurrentUpdateSession.DirtyRegion());
} else {
@ -1828,10 +1832,16 @@ WindowLayer::_TransferToUpdateSession(BRegion* contentDirtyRegion)
// this could be done smarter (clip layers from pending
// that have not yet been redrawn in the current update
// session)
if (fCurrentUpdateSession.IsUsed() && fCurrentUpdateSession.IsExpose()) {
fCurrentUpdateSession.Exclude(contentDirtyRegion);
fEffectiveDrawingRegionValid = false;
}
// NOTE: appearently the R5 app_server does not do that, it just
// keeps drawing until the screen is valid, without caring much
// for a consistent display while it does so, it just keeps drawing
// until everything settles down. Potentially, this could even give
// the impression of faster updates, even though they might look
// wrong when looked at closer, but will fix themselves shortly later
// if (fCurrentUpdateSession.IsUsed() && fCurrentUpdateSession.IsExpose()) {
// fCurrentUpdateSession.Exclude(contentDirtyRegion);
// fEffectiveDrawingRegionValid = false;
// }
if (!fUpdateRequested) {
// send this to client
@ -1850,6 +1860,7 @@ WindowLayer::_SendUpdateMessage()
ServerWindow()->SendMessageToClient(&message);
fUpdateRequested = true;
fEffectiveDrawingRegionValid = false;
}
void