diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index eca3e57e9b..4b32771545 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -88,16 +88,13 @@ Layer::Layer(BRect frame, const char* name, int32 token, fFullVisible(), fFull(), fFrameAction(B_LAYER_ACTION_NONE), + fClipReg(&fVisible), #else fVisible2(), fFullVisible2(), + fClipReg(&fVisible2), #endif -#ifndef NEW_CLIPPING - fClipReg(&fVisible), -#else - fClipReg(&fVisible2), -#endif fServerWin(NULL), fName(name), fViewToken(token), @@ -927,16 +924,23 @@ Layer::Show(bool invalidate) fHidden = false; + SendViewCoordUpdateMsg(); + // NOTE: I added this here and it solves the invalid region problem // for Windows that have been resized before they were shown. -Stephan #ifndef NEW_CLIPPING RebuildFullRegion(); -SendViewCoordUpdateMsg(); if (invalidate) GetRootLayer()->GoInvalidate(this, fFull); #else - + if (invalidate) { + // compute the region this layer wants for itself + BRegion invalidRegion; + get_user_regions(invalidRegion); + if (invalidRegion.CountRects() > 0) + GetRootLayer()->GoInvalidate(this, invalidRegion); + } #endif } @@ -959,6 +963,10 @@ Layer::Hide(bool invalidate) #ifndef NEW_CLIPPING if (invalidate) GetRootLayer()->GoInvalidate(this, fFullVisible); +#else + if (invalidate && fFullVisible2.CountRects() > 0) { + GetRootLayer()->GoInvalidate(this, fFullVisible2); + } #endif } @@ -1654,6 +1662,14 @@ Layer::SetOverlayBitmap(const ServerBitmap* bitmap) #ifdef NEW_CLIPPING +void +Layer::GetWantedRegion(BRegion& reg) const +{ + // this is the same as get_user_region. + // because get_user_region modifies nothing. + const_cast(this)->Layer::get_user_regions(reg); +} + //! converts a point from local to parent's coordinate system void Layer::ConvertToParent2(BPoint* pt) const diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index 2ec2da55d2..78565e5a5f 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -41,7 +41,7 @@ #include "RGBColor.h" #include "ServerWindow.h" -//#define NEW_CLIPPING 1 +#define NEW_CLIPPING 1 enum { B_LAYER_NONE = 1, @@ -212,6 +212,8 @@ class Layer { inline const BRegion& VisibleRegion() const { return fVisible2; } inline const BRegion& FullVisible() const { return fFullVisible2; } + virtual void GetWantedRegion(BRegion& reg) const; + virtual void MovedByHook(float dx, float dy) { } virtual void ResizedByHook(float dx, float dy, bool automatic) { } virtual void ScrolledByHook(float dx, float dy) { } diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 160df09a66..b8d359fe32 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -514,11 +514,15 @@ myRootLayer->Lock(); if (parent != NULL) parent->AddChild(newLayer, this); - if (!newLayer->IsHidden()) + if (!newLayer->IsHidden() && parent) #ifndef NEW_CLIPPING myRootLayer->GoInvalidate(newLayer, newLayer->fFull); #else - myRootLayer->GoInvalidate(newLayer, newLayer->Frame()); + { + BRegion invalidRegion; + newLayer->GetWantedRegion(invalidRegion); + myRootLayer->GoInvalidate(newLayer, invalidRegion); + } #endif myRootLayer->Unlock(); @@ -532,16 +536,28 @@ myRootLayer->Unlock(); // area assuming that the view was visible when removed STRACE(("ServerWindow %s: AS_LAYER_DELETE(self)...\n", fTitle)); - Layer *parent; - parent = fCurrentLayer->fParent; +myRootLayer->Lock(); + Layer *parent = fCurrentLayer->fParent; + BRegion *invalidRegion = NULL; + + if (!fCurrentLayer->IsHidden() && parent) { +#ifndef NEW_CLIPPING + if (fCurrentLayer->fFullVisible.CountRects() > 0) + invalidRegion = new BRegion(fCurrentLayer->fFullVisible); +#else + if (fCurrentLayer->FullVisible().Frame().IsValid()) + invalidRegion = new BRegion(fCurrentLayer->FullVisible()); +#endif + } // here we remove current layer from list. -myRootLayer->Lock(); fCurrentLayer->RemoveSelf(); fCurrentLayer->PruneTree(); - if (parent) - myRootLayer->GoInvalidate(parent, BRegion(fCurrentLayer->Frame())); + if (invalidRegion) { + myRootLayer->GoInvalidate(parent, *invalidRegion); + delete invalidRegion; + } myRootLayer->Unlock(); #ifdef DEBUG_SERVERWINDOW @@ -827,13 +843,15 @@ myRootLayer->Unlock(); rgb_color c; link.Read(&c, sizeof(rgb_color)); - +myRootLayer->Lock(); fCurrentLayer->SetViewColor(RGBColor(c)); - // TODO: this should not trigger redraw, no?!? #ifndef NEW_CLIPPING myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible); +#else + myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion()); #endif +myRootLayer->Unlock(); break; } case AS_LAYER_GET_COLORS: @@ -940,7 +958,11 @@ myRootLayer->Unlock(); #ifndef NEW_CLIPPING myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull); #else - myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame()); + { + BRegion invalidRegion; + fCurrentLayer->GetWantedRegion(invalidRegion); + myRootLayer->GoInvalidate(fCurrentLayer, invalidRegion); + } #endif break;