From 05357ae700ff080f0de4e7bef10e7b05ff777f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Thu, 9 Aug 2007 00:33:50 +0000 Subject: [PATCH] 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 --- src/servers/app/WindowLayer.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/servers/app/WindowLayer.cpp b/src/servers/app/WindowLayer.cpp index cc00e9aa3b..484d101296 100644 --- a/src/servers/app/WindowLayer.cpp +++ b/src/servers/app/WindowLayer.cpp @@ -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