Fixed invalidation with new clipping code. Only what's needed is

redrawn/invalidated now, with a single exception which I am working
on(when changing the front window the whole window area is invalidated
not just the region that became visible). The old Clipping code is broken
now. I will remove it in the next days.

Actual changes:
* removed Layer::GetWantedRegion() - was badly implemented.
* made Layer::_GetWantedRegion public and renamed it to: you guessed! :-)

* introduced Layer::MarkForRebuild(), TriggerRebuild(). You want to
calculate the new clipping regions, mark an area and then call
TRiggerRebuild() which will rebuild the visible regions for the current
Layer and all its descendants.

* for a Layer to redraw some parts of it, use
RootLayer::MarkForRedraw() to mark a region and then
RootLayer::TriggerRedraw() to see the changes (or send _UPDATE_ message in
case of a WinBorder).






git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14719 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adi Oanca 2005-11-06 17:47:06 +00:00
parent 9c91a5f9d6
commit ac4f06c5c6
7 changed files with 331 additions and 141 deletions

View File

@ -21,7 +21,7 @@
//
// File Name: Layer.cpp
// Author: DarkWyrm <bpmagic@columbus.rr.com>
// Adi Oanca <adioanca@cotty.iren.ro>
// Adi Oanca <adioanca@gmail.com>
// Stephan Aßmus <superstippi@gmx.de>
// Description: Class used for rendering to the frame buffer. One layer per
// view on screen and also for window decorators
@ -89,6 +89,7 @@ Layer::Layer(BRect frame, const char* name, int32 token,
#else
fVisible2(),
fFullVisible2(),
fDirtyForRebuild(),
fClipReg(&fVisible2),
#endif
@ -959,10 +960,17 @@ RebuildFullRegion();
#else
if (invalidate) {
// compute the region this layer wants for itself
BRegion invalidRegion;
_GetWantedRegion(invalidRegion);
if (invalidRegion.CountRects() > 0)
GetRootLayer()->GoInvalidate(this, invalidRegion);
BRegion invalid;
GetWantedRegion(invalid);
if (invalid.CountRects() > 0) {
fParent->MarkForRebuild(invalid);
GetRootLayer()->MarkForRedraw(invalid);
fParent->TriggerRebuild();
GetRootLayer()->TriggerRedraw();
// GetRootLayer()->GoInvalidate(this, invalid);
}
}
#endif
}
@ -988,7 +996,15 @@ Layer::Hide(bool invalidate)
GetRootLayer()->GoInvalidate(this, fFullVisible);
#else
if (invalidate && fFullVisible2.CountRects() > 0) {
GetRootLayer()->GoInvalidate(this, fFullVisible2);
BRegion invalid(fFullVisible2);
fParent->MarkForRebuild(invalid);
GetRootLayer()->MarkForRedraw(invalid);
fParent->TriggerRebuild();
GetRootLayer()->TriggerRedraw();
// GetRootLayer()->GoInvalidate(this, fFullVisible2);
}
#endif
}
@ -1970,15 +1986,6 @@ Layer::ScrolledByHook(float dx, float dy)
// empty.
}
void
Layer::GetWantedRegion(BRegion& reg) const
{
// this is the same as get_user_region.
// because get_user_region modifies nothing.
const_cast<Layer*>(this)->Layer::_GetWantedRegion(reg);
}
//! converts a point from local to parent's coordinate system
void
Layer::ConvertToParent2(BPoint* pt) const
@ -2121,8 +2128,13 @@ Layer::do_Hide()
clear_visible_regions();
if (invalid.Frame().IsValid())
fParent->do_Invalidate(invalid, this);
if (invalid.CountRects() > 0) {
fParent->MarkForRebuild(invalid);
GetRootLayer()->MarkForRedraw(invalid);
fParent->TriggerRebuild();
GetRootLayer()->TriggerRedraw();
}
}
}
@ -2134,41 +2146,18 @@ Layer::do_Show()
if (fParent && !fParent->IsHidden() && GetRootLayer()) {
BRegion invalid;
_GetWantedRegion(invalid);
GetWantedRegion(invalid);
if (invalid.CountRects() > 0)
fParent->do_Invalidate(invalid, this);
if (invalid.CountRects() > 0) {
fParent->MarkForRebuild(invalid);
GetRootLayer()->MarkForRedraw(invalid);
fParent->TriggerRebuild();
GetRootLayer()->TriggerRedraw();
}
}
}
void
Layer::do_Invalidate(const BRegion &invalid, const Layer *startFrom)
{
BRegion localVisible(fFullVisible2);
localVisible.IntersectWith(&invalid);
rebuild_visible_regions(invalid, localVisible,
startFrom? startFrom: LastChild());
// add localVisible to our RootLayer's redraw region.
// GetRootLayer()->fRedrawReg.Include(&localVisible);
GetRootLayer()->fRedrawReg = localVisible;
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
}
void
Layer::do_Redraw(const BRegion &invalid, const Layer *startFrom)
{
BRegion localVisible(fFullVisible2);
localVisible.IntersectWith(&invalid);
// add localVisible to our RootLayer's redraw region.
// GetRootLayer()->fRedrawReg.Include(&localVisible);
GetRootLayer()->fRedrawReg = localVisible;
GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, NULL);
// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)?
}
inline void
Layer::resize_layer_frame_by(float x, float y)
{
@ -2344,7 +2333,7 @@ Layer::do_ResizeBy(float dx, float dy)
// we'll invalidate the old area and the new, maxmial one.
BRegion invalid;
_GetWantedRegion(invalid);
GetWantedRegion(invalid);
invalid.Include(&fFullVisible2);
clear_visible_regions();
@ -2403,7 +2392,7 @@ void Layer::do_MoveBy(float dx, float dy)
// we'll invalidate the old position and the new, maxmial one.
BRegion invalid;
_GetWantedRegion(invalid);
GetWantedRegion(invalid);
invalid.Include(&fFullVisible2);
clear_visible_regions();
@ -2483,7 +2472,7 @@ Layer::do_ScrollBy(float dx, float dy)
}
void
Layer::_GetWantedRegion(BRegion &reg)
Layer::GetWantedRegion(BRegion &reg)
{
// 1) set to frame in screen coords
BRect screenFrame(Bounds());
@ -2537,7 +2526,7 @@ Layer::rebuild_visible_regions(const BRegion &invalid,
// intersect maximum wanted region with the invalid region
BRegion common;
_GetWantedRegion(common);
GetWantedRegion(common);
common.IntersectWith(&invalid);
// if the resulted region is not valid, this layer is not in the catchment area
@ -2592,5 +2581,75 @@ Layer::clear_visible_regions()
child->clear_visible_regions();
}
// mark a region dirty so that the next region rebuild for us
// and our children will take this into account
void
Layer::MarkForRebuild(const BRegion &dirty)
{
fDirtyForRebuild.Include(&dirty);
}
// this will trigger visible region recalculation for us and
// our descendants.
void
Layer::TriggerRebuild()
{
BRegion totalInvalidReg;
_GetAllRebuildDirty(&totalInvalidReg);
if (totalInvalidReg.CountRects() > 0) {
BRegion localFullVisible(fFullVisible2);
// localFullVisible.IntersectWith(&totalInvalidReg);
// clear_visible_regions();
rebuild_visible_regions(totalInvalidReg, localFullVisible, LastChild());
}
}
// find out the region for which we must rebuild the visible regions
void
Layer::_GetAllRebuildDirty(BRegion *totalReg)
{
totalReg->Include(&fDirtyForRebuild);
for (Layer *child = LastChild(); child; child = PreviousChild())
child->_GetAllRebuildDirty(totalReg);
fDirtyForRebuild.MakeEmpty();
}
void
Layer::_AllRedraw(const BRegion &invalid)
{
// couldn't find a simpler way to send _UPDATE_ message to client.
WinBorder *wb = dynamic_cast<WinBorder*>(this);
if (wb)
wb->RequestClientRedraw(invalid);
if (fVisible2.CountRects() > 0) {
BRegion updateReg(fVisible2);
updateReg.IntersectWith(&invalid);
if (updateReg.CountRects() > 0) {
fDriver->ConstrainClippingRegion(&updateReg);
Draw(updateReg.Frame());
fDriver->ConstrainClippingRegion(NULL);
}
}
for (Layer *lay = LastChild(); lay != NULL; lay = PreviousChild()) {
if (!(lay->IsHidden())) {
BRegion common(lay->fFullVisible2);
common.IntersectWith(&invalid);
if (common.CountRects() > 0)
lay->_AllRedraw(invalid);
}
}
}
#endif

View File

@ -4,7 +4,7 @@
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Adi Oanca <adioanca@cotty.iren.com>
* Adi Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
*
* Description:
@ -248,7 +248,13 @@ class Layer {
inline const BRegion& VisibleRegion() const { return fVisible2; }
inline const BRegion& FullVisible() const { return fFullVisible2; }
virtual void GetWantedRegion(BRegion& reg) const;
void MarkForRebuild(const BRegion &dirty);
void TriggerRebuild();
void _GetAllRebuildDirty(BRegion *totalReg);
void _AllRedraw(const BRegion &invalid);
virtual void GetWantedRegion(BRegion& reg);
virtual void MovedByHook(float dx, float dy);
virtual void ResizedByHook(float dx, float dy, bool automatic);
@ -277,18 +283,11 @@ class Layer {
void do_ResizeBy(float dx, float dy);
void do_ScrollBy(float dx, float dy);
void do_Invalidate( const BRegion &invalid,
const Layer *startFrom = NULL);
void do_Redraw( const BRegion &invalid,
const Layer *startFrom = NULL);
void rebuild_visible_regions(const BRegion &invalid,
const BRegion &parentLocalVisible,
const Layer *startFrom);
virtual void _ReserveRegions(BRegion &reg);
virtual void _GetWantedRegion(BRegion &reg);
void clear_visible_regions();
void resize_layer_frame_by(float x, float y);
@ -342,6 +341,7 @@ class Layer {
private:
BRegion fVisible2;
BRegion fFullVisible2;
BRegion fDirtyForRebuild;
protected:
#endif
BRegion* fClipReg;

View File

@ -68,6 +68,8 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
fSavedEventOptions(0),
fAllRegionsLock("root layer region lock"),
fDirtyForRedraw(),
fThreadID(B_ERROR),
fListenPort(-1),
@ -199,13 +201,15 @@ RootLayer::WorkingThread(void *data)
oneRootLayer->RebuildFullRegion();
oneRootLayer->GoInvalidate(oneRootLayer, oneRootLayer->Bounds());
#else
oneRootLayer->rebuild_visible_regions(
BRegion(oneRootLayer->Bounds()),
BRegion(oneRootLayer->Bounds()),
oneRootLayer->LastChild());
// RootLayer starts with valid visible regions
oneRootLayer->fFullVisible2.Set(oneRootLayer->Bounds());
oneRootLayer->fVisible2.Set(oneRootLayer->Bounds());
oneRootLayer->fRedrawReg.Include(oneRootLayer->Bounds());
oneRootLayer->RequestDraw(oneRootLayer->fRedrawReg, oneRootLayer->LastChild());
oneRootLayer->MarkForRebuild(oneRootLayer->Bounds());
oneRootLayer->MarkForRedraw(oneRootLayer->Bounds());
oneRootLayer->TriggerRebuild();
oneRootLayer->TriggerRedraw();
#endif
oneRootLayer->Unlock();
@ -277,38 +281,6 @@ RootLayer::WorkingThread(void *data)
return 0;
}
void
RootLayer::GoInvalidate(Layer *layer, const BRegion &region)
{
BRegion invalidRegion(region);
Lock();
#ifndef NEW_CLIPPING
if (layer->fParent)
layer = layer->fParent;
layer->FullInvalidate(invalidRegion);
#else
layer->do_Invalidate(invalidRegion);
#endif
Unlock();
}
void
RootLayer::GoRedraw(Layer *layer, const BRegion &region)
{
BRegion redrawRegion(region);
Lock();
#ifndef NEW_CLIPPING
layer->Invalidate(redrawRegion);
#else
layer->do_Redraw(redrawRegion);
#endif
Unlock();
}
void
RootLayer::GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel)
{
@ -829,7 +801,7 @@ RootLayer::RevealNewWMState(Workspace::State &oldWMState)
#ifndef NEW_CLIPPING
fRedrawReg.Include(&dirtyRegion);
#else
// TODO: code for new clipping engine!
MarkForRedraw(dirtyRegion);
#endif
}
}
@ -848,37 +820,98 @@ RootLayer::RevealNewWMState(Workspace::State &oldWMState)
// clear visible areas for windows not visible anymore.
int32 oldWindowCount = oldWMState.WindowList.CountItems();
int32 newWindowCount = fWMState.WindowList.CountItems();
bool stillPresent;
Layer *layer;
for (int32 i = 0; i < oldWindowCount; i++)
{
layer = static_cast<Layer*>(oldWMState.WindowList.ItemAtFast(i));
stillPresent = false;
for (int32 j = 0; j < newWindowCount; j++)
if (layer == fWMState.WindowList.ItemAtFast(j))
stillPresent = true;
BList oldStrippedList, newStrippedList;
for (int32 i = 0; i < oldWindowCount; ++i) {
Layer *layer = static_cast<Layer*>(oldWMState.WindowList.ItemAtFast(i));
if (!layer)
continue;
if (!stillPresent && layer)
bool stillPresent = false;
for (int32 j = 0; j < newWindowCount; ++j)
if (layer == fWMState.WindowList.ItemAtFast(j)) {
stillPresent = true;
break;
}
if (!stillPresent) {
MarkForRebuild(layer->FullVisible());
MarkForRedraw(layer->FullVisible());
#ifndef NEW_CLIPPING
empty_visible_regions(layer);
#else
layer->clear_visible_regions();
#endif
}
else {
oldStrippedList.AddItem(layer);
}
}
for (int32 i = 0; i < newWindowCount; ++i) {
Layer *layer = static_cast<Layer*>(fWMState.WindowList.ItemAtFast(i));
if (!layer)
continue;
bool isNewWindow = true;
for (int32 j = 0; j < oldWindowCount; ++j)
if (layer == oldWMState.WindowList.ItemAtFast(j)) {
isNewWindow = false;
break;
}
if (isNewWindow) {
BRegion invalid;
layer->GetWantedRegion(invalid);
MarkForRebuild(invalid);
MarkForRedraw(invalid);
}
else {
newStrippedList.AddItem(layer);
}
}
oldWindowCount = oldStrippedList.CountItems();
newWindowCount = newStrippedList.CountItems();
for (int32 i = 0; i < oldWindowCount; ++i) {
Layer *layer = static_cast<Layer*>(oldStrippedList.ItemAtFast(i));
if (!layer)
continue;
if (i < newStrippedList.IndexOf(layer)) {
BRegion invalid;
layer->GetWantedRegion(invalid);
// TODO: we need to invalidate only the ares that became visible
// not the whole surface of this layer!
// invalid.Exclude(&layer->FullVisible());
MarkForRebuild(invalid);
MarkForRedraw(invalid);
}
}
/*
// for debugging
GetDrawingEngine()->ConstrainClippingRegion(&fDirtyForRedraw);
RGBColor c(rand()%255,rand()%255,rand()%255);
GetDrawingEngine()->FillRect(BRect(0,0,800,600), c);
snooze(2000000);
GetDrawingEngine()->ConstrainClippingRegion(NULL);
*/
// redraw of focus change is automaticaly done
redraw = false;
// trigger region rebuilding and redraw
#ifndef NEW_CLIPPING
GoInvalidate(this, fFull);
#else
do_Invalidate(Bounds());
TriggerRebuild();
TriggerRedraw();
#endif
}
else if (redraw) {
#ifndef NEW_CLIPPING
GoInvalidate(this, dirtyRegion);
#else
do_Redraw(dirtyRegion);
MarkForRedraw(dirtyRegion);
TriggerRedraw();
#endif
}
}
@ -1402,7 +1435,7 @@ RootLayer::LayerRemoved(Layer* layer)
{
if (layer == fNotifyLayer)
fNotifyLayer = NULL;
// TODO: this must not happen!!! Fix this, quickly!
if (layer == fLastLayerUnderMouse)
fLastLayerUnderMouse = NULL;
}
@ -1611,7 +1644,8 @@ RootLayer::AddDebugInfo(const char* string)
{
if (Lock()) {
fDebugInfo << string;
GoRedraw(this, BRegion(fFrame));
MarkForRedraw(VisibleRegion());
TriggerRedraw();
Unlock();
}
}
@ -1683,3 +1717,29 @@ RootLayer::ConvertToMessage(void* raw, int32 code)
return bmsg;
}
void
RootLayer::MarkForRedraw(const BRegion &dirty)
{
BAutolock locker(fAllRegionsLock);
fDirtyForRedraw.Include(&dirty);
}
void
RootLayer::TriggerRedraw()
{
BAutolock locker(fAllRegionsLock);
/*
// for debugging
GetDrawingEngine()->ConstrainClippingRegion(&fDirtyForRedraw);
RGBColor c(rand()%255,rand()%255,rand()%255);
GetDrawingEngine()->FillRect(BRect(0,0,800,600), c);
snooze(2000000);
GetDrawingEngine()->ConstrainClippingRegion(NULL);
*/
_AllRedraw(fDirtyForRedraw);
fDirtyForRedraw.MakeEmpty();
}

View File

@ -131,10 +131,12 @@ public:
void Unlock() { fAllRegionsLock.Unlock(); }
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
void RunThread();
void GoInvalidate(Layer *layer, const BRegion &region);
void GoRedraw(Layer *layer, const BRegion &region);
void GoChangeWinBorderFeel(WinBorder *winBorder, int32 newFeel);
void MarkForRedraw(const BRegion &dirty);
void TriggerRedraw();
virtual void Draw(const BRect &r);
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
@ -186,6 +188,8 @@ friend class WinBorder; // temporarily, I need invalidate_layer()
BLocker fAllRegionsLock;
BRegion fDirtyForRedraw;
thread_id fThreadID;
port_id fListenPort;
BMessageQueue fQueue;

View File

@ -654,7 +654,13 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
{
BRegion invalidRegion;
newLayer->GetWantedRegion(invalidRegion);
myRootLayer->GoInvalidate(newLayer, invalidRegion);
parent->MarkForRebuild(invalidRegion);
parent->TriggerRebuild();
if (newLayer->VisibleRegion().Frame().IsValid()) {
myRootLayer->MarkForRedraw(newLayer->VisibleRegion());
myRootLayer->TriggerRedraw();
}
// myRootLayer->GoInvalidate(newLayer, invalidRegion);
}
#endif
break;
@ -669,15 +675,19 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
STRACE(("ServerWindow %s: AS_LAYER_DELETE(self)...\n", fTitle));
Layer *parent = fCurrentLayer->fParent;
BRegion *invalidRegion = NULL;
// BRegion *invalidRegion = NULL;
if (!fCurrentLayer->IsHidden() && parent) {
if (!fCurrentLayer->IsHidden() && parent && myRootLayer) {
#ifndef NEW_CLIPPING
if (fCurrentLayer->fFullVisible.CountRects() > 0)
invalidRegion = new BRegion(fCurrentLayer->fFullVisible);
#else
if (fCurrentLayer->FullVisible().Frame().IsValid())
invalidRegion = new BRegion(fCurrentLayer->FullVisible());
if (fCurrentLayer->FullVisible().Frame().IsValid()) {
parent->MarkForRebuild(fCurrentLayer->FullVisible());
myRootLayer->MarkForRedraw(fCurrentLayer->FullVisible());
// invalidRegion = new BRegion(fCurrentLayer->FullVisible());
}
#endif
}
@ -685,15 +695,12 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fCurrentLayer->RemoveSelf();
fCurrentLayer->PruneTree();
if (parent)
parent->TriggerRebuild();
if (myRootLayer) {
myRootLayer->LayerRemoved(fCurrentLayer);
// trigger update
if (invalidRegion) {
myRootLayer->GoInvalidate(parent, *invalidRegion);
delete invalidRegion;
}
myRootLayer->TriggerRedraw();
}
#ifdef DEBUG_SERVERWINDOW
@ -990,8 +997,13 @@ if (myRootLayer)
if (myRootLayer)
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->fVisible);
#else
if (myRootLayer)
myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion());
if (myRootLayer) {
myRootLayer->MarkForRedraw(fCurrentLayer->VisibleRegion());
myRootLayer->TriggerRedraw();
}
// if (myRootLayer)
// myRootLayer->GoRedraw(fCurrentLayer, fCurrentLayer->VisibleRegion());
#endif
if (myRootLayer)
myRootLayer->Unlock();
@ -1115,7 +1127,15 @@ if (myRootLayer)
{
BRegion invalidRegion;
fCurrentLayer->GetWantedRegion(invalidRegion);
myRootLayer->GoInvalidate(fCurrentLayer, invalidRegion);
// TODO: this is broken! a smaller area may be invalidated!
fCurrentLayer->fParent->MarkForRebuild(invalidRegion);
fCurrentLayer->fParent->TriggerRebuild();
myRootLayer->MarkForRedraw(invalidRegion);
myRootLayer->TriggerRedraw();
// myRootLayer->GoInvalidate(fCurrentLayer, invalidRegion);
}
#endif
@ -1206,8 +1226,9 @@ if (myRootLayer)
#ifdef NEW_CLIPPING
invalidRegion.IntersectWith(&fCurrentLayer->fVisible2);
#endif
myRootLayer->GoRedraw(fWinBorder, invalidRegion);
// myRootLayer->RequestDraw(invalidRegion, fWinBorder);
myRootLayer->MarkForRedraw(invalidRegion);
myRootLayer->TriggerRedraw();
// myRootLayer->GoRedraw(fWinBorder, invalidRegion);
}
break;
}
@ -1217,7 +1238,7 @@ if (myRootLayer)
// TODO: handle transformation (origin and scale) prior to converting to top
// TODO: Handle conversion to top
BRegion invalReg;
BRegion invalidReg;
int32 noOfRects;
BRect rect;
@ -1225,11 +1246,17 @@ if (myRootLayer)
for (int i = 0; i < noOfRects; i++) {
link.Read<BRect>(&rect);
invalReg.Include(rect);
invalidReg.Include(rect);
}
if (myRootLayer)
myRootLayer->GoRedraw(fCurrentLayer, invalReg);
if (myRootLayer) {
fCurrentLayer->ConvertToScreen2(&invalidReg);
myRootLayer->MarkForRedraw(invalidReg);
myRootLayer->TriggerRedraw();
// myRootLayer->GoRedraw(fCurrentLayer, invalReg);
}
break;
}

View File

@ -876,7 +876,7 @@ WinBorder::_ReserveRegions(BRegion &reg)
}
void
WinBorder::_GetWantedRegion(BRegion &reg)
WinBorder::GetWantedRegion(BRegion &reg)
{
if (fRebuildDecRegion)
{
@ -889,11 +889,49 @@ WinBorder::_GetWantedRegion(BRegion &reg)
ConvertToScreen2(&screenFrame);
reg.Set(screenFrame);
reg.Include(&fDecRegion);
BRegion screenReg(GetRootLayer()->Bounds());
reg.IntersectWith(&screenReg);
}
reg.Include(&fDecRegion);
void
WinBorder::RequestClientRedraw(const BRegion &invalid)
{
BRegion updateReg(fTopLayer->FullVisible());
updateReg.IntersectWith(&invalid);
if (updateReg.CountRects() > 0) {
fCumulativeRegion.Include(&updateReg);
if (fUpdateRequestsEnabled && !InUpdate() && !fRequestSent) {
fInUpdateRegion = fCumulativeRegion;
cnt++;
if (cnt != 1)
CRITICAL("WinBorder::RequestClientRedraw(): cnt != 1 -> Not Allowed!");
fRequestSent = true; // this is here to avoid a possible de-synchronization
BMessage msg;
msg.what = _UPDATE_;
#ifndef NEW_CLIPPING
msg.AddRect("_rect", ConvertFromTop(fInUpdateRegion.Frame()));
#else
BRect rect(fInUpdateRegion.Frame());
ConvertFromScreen2(&rect);
msg.AddRect("_rect", rect );
#endif
msg.AddRect("debug_rect", fInUpdateRegion.Frame());
if (Window()->SendMessageToClient(&msg) == B_OK) {
fCumulativeRegion.MakeEmpty();
}
else {
fRequestSent = false;
fInUpdateRegion.MakeEmpty();
}
}
}
}
#endif

View File

@ -60,8 +60,9 @@ class WinBorder : public Layer {
#ifndef NEW_CLIPPING
virtual void RebuildFullRegion();
#else
virtual void GetWantedRegion(BRegion &reg);
#endif
void UpdateStart();
void UpdateEnd();
inline bool InUpdate() const
@ -126,10 +127,11 @@ class WinBorder : public Layer {
virtual void MovedByHook(float dx, float dy);
virtual void ResizedByHook(float dx, float dy, bool automatic);
void RequestClientRedraw(const BRegion &invalid);
private:
void set_decorator_region(BRect frame);
virtual void _ReserveRegions(BRegion &reg);
virtual void _GetWantedRegion(BRegion &reg);
BRegion fDecRegion;
bool fRebuildDecRegion;