From 3df649ecb33bb25aeb4ecb3cee6184eef4451081 Mon Sep 17 00:00:00 2001 From: Adi Oanca Date: Tue, 21 Jun 2005 20:11:44 +0000 Subject: [PATCH] managed to show/hide empty windows with the new clipping code git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13221 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/Layer.cpp | 126 ++++++++++++++++++++----------- src/servers/app/Layer.h | 16 ++-- src/servers/app/RootLayer.cpp | 54 ++++++++++--- src/servers/app/RootLayer.h | 4 +- src/servers/app/ServerWindow.cpp | 23 +++--- src/servers/app/WinBorder.cpp | 74 +++++++++--------- 6 files changed, 185 insertions(+), 112 deletions(-) diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 5aabad5acc..e95785b13f 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -86,13 +86,12 @@ Layer::Layer(BRect frame, const char* name, int32 token, #ifndef NEW_CLIPPING fVisible(), fFullVisible(), + fFull(), + fFrameAction(B_LAYER_ACTION_NONE), #else fVisible2(), fFullVisible2(), #endif -#ifndef NEW_CLIPPING - fFull(), -#endif #ifndef NEW_CLIPPING fClipReg(&fVisible), @@ -113,10 +112,6 @@ Layer::Layer(BRect frame, const char* name, int32 token, fAdFlags(0), fClassID(AS_LAYER_CLASS), -#ifndef NEW_CLIPPING - fFrameAction(B_LAYER_ACTION_NONE), -#endif - fDriver(driver), fLayerData(new LayerData()), @@ -427,6 +422,18 @@ Layer::LayerAt(const BPoint &pt) return lay; } } +#else + if (fVisible2.Contains(pt)) + return this; + + if (fFullVisible2.Contains(pt)) { + Layer *lay = NULL; + for (Layer* child = BottomChild(); child; child = UpperSibling()) { + lay = child->LayerAt(pt); + if (lay) + return lay; + } + } #endif return NULL; } @@ -919,12 +926,12 @@ Layer::Show(bool invalidate) // for Windows that have been resized before they were shown. -Stephan #ifndef NEW_CLIPPING RebuildFullRegion(); -#endif SendViewCoordUpdateMsg(); -#ifndef NEW_CLIPPING if (invalidate) GetRootLayer()->GoInvalidate(this, fFull); +#else + #endif } @@ -1334,6 +1341,10 @@ Layer::UpdateEnd() } } + +#ifndef NEW_CLIPPING + + // move_layer void Layer::move_layer(float x, float y) @@ -1345,28 +1356,23 @@ Layer::move_layer(float x, float y) wb->fUpdateReg.OffsetBy(x, y); }*/ -#ifndef NEW_CLIPPING fFrameAction = B_LAYER_ACTION_MOVE; BPoint pt(x, y); BRect rect(fFull.Frame().OffsetByCopy(pt)); -#endif if (!fParent) { printf("no parent in Layer::move_layer() (%s)\n", GetName()); -#ifndef NEW_CLIPPING fFrameAction = B_LAYER_ACTION_NONE; -#endif return; } -#ifndef NEW_CLIPPING + fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_MOVE, pt); fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible); -#endif fParent->Redraw(fRootLayer->fRedrawReg, this); @@ -1374,41 +1380,31 @@ return; EmptyGlobals(); -#ifndef NEW_CLIPPING fFrameAction = B_LAYER_ACTION_NONE; -#endif } // resize_layer void Layer::resize_layer(float x, float y) { -#ifndef NEW_CLIPPING fFrameAction = B_LAYER_ACTION_RESIZE; BPoint pt(x,y); -#endif -#ifndef NEW_CLIPPING BRect rect(fFull.Frame()); -#else - BRect rect(Frame()); -#endif rect.right += x; rect.bottom += y; if (!fParent) { printf("no parent in Layer::resize_layer() (%s)\n", GetName()); -#ifndef NEW_CLIPPING fFrameAction = B_LAYER_ACTION_NONE; -#endif return; } -#ifndef NEW_CLIPPING + fParent->StartRebuildRegions(BRegion(rect), this, B_LAYER_RESIZE, pt); fDriver->CopyRegionList(&fRootLayer->fCopyRegList, &fRootLayer->fCopyList, fRootLayer->fCopyRegList.CountItems(), &fFullVisible); -#endif + fParent->Redraw(fRootLayer->fRedrawReg, this); @@ -1416,9 +1412,7 @@ return; EmptyGlobals(); -#ifndef NEW_CLIPPING fFrameAction = B_LAYER_ACTION_NONE; -#endif } // FullInvalidate @@ -1439,10 +1433,8 @@ Layer::FullInvalidate(const BRegion& region) printf("\n"); #endif -#ifndef NEW_CLIPPING BPoint pt(0,0); StartRebuildRegions(region, NULL,/* B_LAYER_INVALIDATE, pt); */B_LAYER_NONE, pt); -#endif Redraw(fRootLayer->fRedrawReg); @@ -1466,12 +1458,16 @@ Layer::Invalidate(const BRegion& region) EmptyGlobals(); } +#endif // 5 methods + // RequestDraw void Layer::RequestDraw(const BRegion ®, Layer *startFrom) { STRACE(("Layer(%s)::RequestDraw()\n", GetName())); - +printf("Layer(%s)::RequestDraw()\n", GetName()); +//if (fClassID == AS_ROOTLAYER_CLASS) +// debugger("z"); // do not redraw any child until you must int redraw = false; if (!startFrom) @@ -1480,11 +1476,12 @@ Layer::RequestDraw(const BRegion ®, Layer *startFrom) if (HasClient() && IsTopLayer()) { // calculate the minimum region/rectangle to be updated with // a single message to the client. - BRegion updateReg #ifndef NEW_CLIPPING - (fFullVisible) + BRegion updateReg(fFullVisible); +#else + BRegion updateReg(fFullVisible2); #endif - ; + if (fFlags & B_FULL_UPDATE_ON_RESIZE #ifndef NEW_CLIPPING && fFrameAction == B_LAYER_ACTION_RESIZE @@ -1513,12 +1510,7 @@ if (fOwner->cnt != 1) if (fVisible.CountRects() > 0) { BRegion updateReg(fVisible); // calculate the update region - if (fFlags & B_FULL_UPDATE_ON_RESIZE -#ifndef NEW_CLIPPING - && fFrameAction == B_LAYER_ACTION_RESIZE -#endif - ) - { + if (fFlags & B_FULL_UPDATE_ON_RESIZE && fFrameAction == B_LAYER_ACTION_RESIZE) { // do nothing } else { updateReg.IntersectWith(®); @@ -1530,7 +1522,7 @@ if (fOwner->cnt != 1) fDriver->ConstrainClippingRegion(NULL); } } -#endif + for (Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling()) { if (lay == startFrom) redraw = true; @@ -1538,15 +1530,48 @@ if (fOwner->cnt != 1) if (redraw && !(lay->IsHidden())) { // no need to go deeper if not even the FullVisible region intersects // Update one. -#ifndef NEW_CLIPPING BRegion common(lay->fFullVisible); common.IntersectWith(®); if (common.CountRects() > 0) lay->RequestDraw(reg, NULL); -#endif } } +#else + if (fVisible2.CountRects() > 0) { + BRegion updateReg(fVisible2); + // calculate the update region + if (fFlags & B_FULL_UPDATE_ON_RESIZE +// TODO: must be replaced! +// && fFrameAction == B_LAYER_ACTION_RESIZE + ) { + // do nothing + } else { + updateReg.IntersectWith(®); + } + + if (updateReg.CountRects() > 0) { + fDriver->ConstrainClippingRegion(&updateReg); + Draw(updateReg.Frame()); + fDriver->ConstrainClippingRegion(NULL); + } + } + + for (Layer *lay = BottomChild(); lay != NULL; lay = UpperSibling()) { + if (lay == startFrom) + redraw = true; + + if (redraw && !(lay->IsHidden())) { + // no need to go deeper if not even the FullVisible region intersects + // Update one. + BRegion common(lay->fFullVisible2); + common.IntersectWith(®); + + if (common.CountRects() > 0) + lay->RequestDraw(reg, NULL); + } + } +#endif } /*! @@ -1697,6 +1722,19 @@ Layer::do_Invalidate(const BRegion &invalid, const Layer *startFrom) // 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); +// TODO: --- + GetRootLayer()->RequestDraw(GetRootLayer()->fRedrawReg, BottomChild()); +// GetRootLayer()->RequestRedraw(); // TODO: what if we pass (fParent, startFromTHIS, &redrawReg)? +} + inline void Layer::resize_layer_frame_by(float x, float y) { diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index d7dbe6522c..8551f25e58 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -209,6 +209,9 @@ class Layer { inline const ServerBitmap* OverlayBitmap() const { return fOverlayBitmap; } #ifdef NEW_CLIPPING + inline const BRegion& VisibleRegion() const { return fVisible2; } + inline const BRegion& FullVisible() const { return fFullVisible2; } + virtual void MovedByHook(float dx, float dy) { } virtual void ResizedByHook(float dx, float dy, bool automatic) { } virtual void ScrolledByHook(float dx, float dy) { } @@ -228,6 +231,9 @@ class Layer { 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); @@ -247,12 +253,14 @@ class Layer { friend class WinBorder; friend class ServerWindow; +#ifndef NEW_CLIPPING void move_layer(float x, float y); void resize_layer(float x, float y); void FullInvalidate(const BRect& rect); void FullInvalidate(const BRegion& region); void Invalidate(const BRegion& region); +#endif BRect fFrame; // TODO: should be removed or reused in a similar fashion @@ -272,14 +280,13 @@ class Layer { #ifndef NEW_CLIPPING BRegion fVisible; BRegion fFullVisible; + BRegion fFull; + int8 fFrameAction; #else private: BRegion fVisible2; BRegion fFullVisible2; protected: -#endif -#ifndef NEW_CLIPPING - BRegion fFull; #endif BRegion* fClipReg; @@ -294,9 +301,6 @@ class Layer { bool fIsTopLayer; uint16 fAdFlags; int8 fClassID; -#ifndef NEW_CLIPPING - int8 fFrameAction; -#endif DisplayDriver* fDriver; LayerData* fLayerData; diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index 603cc3f821..8b13941f9c 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -227,8 +227,16 @@ RootLayer::WorkingThread(void *data) oneRootLayer->Lock(); #ifndef NEW_CLIPPING oneRootLayer->RebuildFullRegion(); -#endif oneRootLayer->invalidate_layer(oneRootLayer, oneRootLayer->Bounds()); +#else + oneRootLayer->rebuild_visible_regions( + BRegion(oneRootLayer->Bounds()), + BRegion(oneRootLayer->Bounds()), + oneRootLayer->BottomChild()); + + oneRootLayer->fRedrawReg.Include(oneRootLayer->Bounds()); + oneRootLayer->RequestDraw(oneRootLayer->fRedrawReg, oneRootLayer->BottomChild()); +#endif oneRootLayer->Unlock(); STRACE(("info: RootLayer(%s)::WorkingThread listening on port %ld.\n", oneRootLayer->GetName(), oneRootLayer->fListenPort)); @@ -280,11 +288,16 @@ RootLayer::WorkingThread(void *data) } case AS_ROOTLAYER_DO_INVALIDATE: { +printf("Adi: new message\n"); BRegion invalidRegion; Layer *layer = NULL; messageQueue.Read(&layer); messageQueue.ReadRegion(&invalidRegion); +#ifndef NEW_CLIPPING oneRootLayer->invalidate_layer(layer, invalidRegion); +#else + layer->do_Invalidate(invalidRegion); +#endif break; } case AS_ROOTLAYER_DO_REDRAW: @@ -293,7 +306,11 @@ RootLayer::WorkingThread(void *data) Layer *layer = NULL; messageQueue.Read(&layer); messageQueue.ReadRegion(&redrawRegion); +#ifndef NEW_CLIPPING oneRootLayer->redraw_layer(layer, redrawRegion); +#else + layer->do_Redraw(redrawRegion); +#endif break; } case AS_ROOTLAYER_LAYER_MOVE: @@ -303,7 +320,11 @@ RootLayer::WorkingThread(void *data) messageQueue.Read(&layer); messageQueue.Read(&x); messageQueue.Read(&y); +#ifndef NEW_CLIPPING layer->move_layer(x, y); +#else + layer->do_MoveBy(x, y); +#endif break; } case AS_ROOTLAYER_LAYER_RESIZE: @@ -313,7 +334,11 @@ RootLayer::WorkingThread(void *data) messageQueue.Read(&layer); messageQueue.Read(&x); messageQueue.Read(&y); +#ifndef NEW_CLIPPING layer->resize_layer(x, y); +#else + layer->do_ResizeBy(x, y); +#endif break; } case AS_ROOTLAYER_ADD_TO_SUBSET: @@ -375,11 +400,13 @@ RootLayer::GoInvalidate(const Layer *layer, const BRegion ®ion) { BPrivate::PortLink msg(fListenPort, -1); msg.StartMessage(AS_ROOTLAYER_DO_INVALIDATE); +//debugger("y"); msg.Attach(layer); msg.AttachRegion(region); msg.Flush(); } +#ifndef NEW_CLIPPING void RootLayer::invalidate_layer(Layer *layer, const BRegion ®ion) { // NOTE: our thread (WorkingThread) is locked here. @@ -390,7 +417,7 @@ void RootLayer::invalidate_layer(Layer *layer, const BRegion ®ion) layer->FullInvalidate(region); } - +#endif status_t RootLayer::EnqueueMessage(BPrivate::PortLink &message) @@ -411,7 +438,7 @@ RootLayer::GoRedraw(const Layer *layer, const BRegion ®ion) msg.Flush(); } - +#ifndef NEW_CLIPPING void RootLayer::redraw_layer(Layer *layer, const BRegion ®ion) { @@ -419,7 +446,7 @@ RootLayer::redraw_layer(Layer *layer, const BRegion ®ion) layer->Invalidate(region); } - +#endif void RootLayer::GoChangeWinBorderFeel(const WinBorder *winBorder, int32 newFeel) @@ -1921,9 +1948,10 @@ RootLayer::show_winBorder(WinBorder *winBorder) if (fActiveWksIndex == i) invalidate = invalid; } - +printf("Adi 1\n"); if (invalidate) show_final_scene(exFocus, exActive); +printf("Adi 2\n"); } void RootLayer::hide_winBorder(WinBorder *winBorder) @@ -2029,7 +2057,11 @@ bool RootLayer::get_workspace_windows() present = true; if (!present) +#ifndef NEW_CLIPPING empty_visible_regions(fWinBorderList2[i]); +#else + fWinBorderList2[i]->clear_visible_regions(); +#endif } } @@ -2067,6 +2099,7 @@ RootLayer::draw_window_tab(WinBorder *exFocus) } } +#ifndef NEW_CLIPPING inline void RootLayer::empty_visible_regions(Layer *layer) { @@ -2074,16 +2107,16 @@ RootLayer::empty_visible_regions(Layer *layer) // NOTE: first 'layer' must be a WinBorder Layer *child; -#ifndef NEW_CLIPPING + layer->fFullVisible.MakeEmpty(); layer->fVisible.MakeEmpty(); -#endif child = layer->BottomChild(); while(child) { empty_visible_regions(child); child = layer->UpperSibling(); } } +#endif inline void RootLayer::winborder_activation(WinBorder* exActive) @@ -2109,13 +2142,12 @@ RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive) fHaveWinBorderList = false; // TODO: should it be improved by calling with region of hidden windows // plus the full regions of new windows??? - invalidate_layer(this, #ifndef NEW_CLIPPING - fFull + invalidate_layer(this, fFull); #else - Frame() + // TODO: hmm. Bounds()? Yes, this its OK, for the moment!!! think! + do_Invalidate(Bounds()); #endif - ); } draw_window_tab(exFocus); diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index a6585cf26d..7e911b3127 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -160,11 +160,11 @@ friend class Desktop; bool get_workspace_windows(); void draw_window_tab(WinBorder *exFocus); +#ifndef NEW_CLIPPING void empty_visible_regions(Layer *layer); - void invalidate_layer(Layer *layer, const BRegion ®ion); void redraw_layer(Layer *layer, const BRegion ®ion); - +#endif void winborder_activation(WinBorder* exActive); void show_final_scene(WinBorder *exFocus, WinBorder *exActive); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index a5417d6fcd..12a56b133d 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -479,15 +479,14 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) if (parent != NULL) parent->AddChild(newLayer, this); - if (!newLayer->IsHidden()) { - myRootLayer->GoInvalidate(newLayer, +printf("Adi: create %s\n", fName); + if (!newLayer->IsHidden()) #ifndef NEW_CLIPPING - newLayer->fFull + myRootLayer->GoInvalidate(newLayer, newLayer->fFull); #else - newLayer->Frame() + myRootLayer->GoInvalidate(newLayer, newLayer->Frame()); #endif - ); - } + break; } case AS_LAYER_DELETE: @@ -910,13 +909,11 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) fCurrentLayer->RebuildFullRegion(); #endif if (!(fCurrentLayer->IsHidden())) - myRootLayer->GoInvalidate(fCurrentLayer, #ifndef NEW_CLIPPING - fCurrentLayer->fFull + myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull); #else - fCurrentLayer->Frame() + myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame()); #endif - ); break; } @@ -986,13 +983,11 @@ ServerWindow::DispatchMessage(int32 code, BPrivate::LinkReceiver &link) fCurrentLayer->RebuildFullRegion(); #endif if (!(fCurrentLayer->IsHidden())) - myRootLayer->GoInvalidate(fCurrentLayer, #ifndef NEW_CLIPPING - fCurrentLayer->fFull + myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->fFull); #else - fCurrentLayer->Frame() + myRootLayer->GoInvalidate(fCurrentLayer, fCurrentLayer->Frame()); #endif - ); break; } diff --git a/src/servers/app/WinBorder.cpp b/src/servers/app/WinBorder.cpp index c7ca209b1e..c60dcc16c0 100644 --- a/src/servers/app/WinBorder.cpp +++ b/src/servers/app/WinBorder.cpp @@ -176,6 +176,8 @@ y = (float)int32(y); if (fDecorator) fDecorator->MoveBy(x,y); +#ifndef NEW_CLIPPING + // NOTE: I moved this here from Layer::move_layer() // Should this have any bad consequences I'm not aware of? zUpdateReg.OffsetBy(x, y); @@ -199,9 +201,7 @@ fUpdateReg.OffsetBy(x, y); // has not been added to fParent apperantly. So now // you ask why fParent is even valid? Me too. fFrame.OffsetBy(x, y); -#ifndef NEW_CLIPPING fFull.OffsetBy(x, y); -#endif fTopLayer->move_layer(x, y); // ...and here we get really hacky... fTopLayer->fFrame.OffsetTo(0.0, 0.0); @@ -209,6 +209,10 @@ fUpdateReg.OffsetBy(x, y); move_layer(x, y); } +#else + // implement. maybe... +#endif + if (Window()) { // dispatch a message to the client informing about the changed size BMessage msg(B_WINDOW_MOVED); @@ -243,28 +247,34 @@ y = (float)int32(y); x = wantWidth - fFrame.Width(); y = wantHeight - fFrame.Height(); - if (x != 0.0 || y != 0.0) { - if (fDecorator) - fDecorator->ResizeBy(x, y); - - if (IsHidden()) { - // TODO: See large comment in MoveBy() - fFrame.right += x; - fFrame.bottom += y; + if (x == 0.0 && y == 0.0) + return; - fTopLayer->resize_layer(x, y); - } else { - resize_layer(x, y); - } + if (fDecorator) + fDecorator->ResizeBy(x, y); - if (Window()) { - // send a message to the client informing about the changed size - BRect frame(fTopLayer->Frame()); - BMessage msg(B_WINDOW_RESIZED); - msg.AddInt32("width", frame.Width()); - msg.AddInt32("height", frame.Height()); - Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); - } +#ifndef NEW_CLIPPING + if (IsHidden()) { + // TODO: See large comment in MoveBy() + fFrame.right += x; + fFrame.bottom += y; + + fTopLayer->resize_layer(x, y); + } else { + resize_layer(x, y); + } + +#else + // Do? I don't think so. The new move/resize/scroll hooks should handle these +#endif + + if (Window()) { + // send a message to the client informing about the changed size + BRect frame(fTopLayer->Frame()); + BMessage msg(B_WINDOW_RESIZED); + msg.AddInt32("width", frame.Width()); + msg.AddInt32("height", frame.Height()); + Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); } } @@ -654,18 +664,11 @@ void WinBorder::set_decorator_region(BRect bounds) { fRebuildDecRegion = false; - fDecRegion.MakeEmpty(); - // NOTE: frame is in screen coords - fDecRegion.Include(BRect(bounds.left-4, bounds.top-4, bounds.right+4, bounds.top-1)); - fDecRegion.Include(BRect(bounds.left-4, bounds.bottom+1, bounds.right+4, bounds.bottom+4)); - fDecRegion.Include(BRect(bounds.left-4, bounds.top, bounds.left-1, bounds.bottom)); - fDecRegion.Include(BRect(bounds.right+1, bounds.top, bounds.right+4, bounds.bottom)); - - // tab - fDecRegion.Include(BRect(bounds.left-4, bounds.top-4-10, bounds.left+bounds.Width()/2, bounds.top-4)); - - // resize rect - fDecRegion.Include(BRect(bounds.right-10, bounds.bottom-10, bounds.right, bounds.bottom)); + if (fDecorator) + { + fDecRegion.MakeEmpty(); + fDecorator->GetFootprint(&fDecRegion); + } } bool WinBorder::alter_visible_for_children(BRegion ®ion) @@ -679,7 +682,8 @@ void WinBorder::get_user_regions(BRegion ®) if (fRebuildDecRegion) { set_decorator_region(Bounds()); - ConvertToScreen2(&fDecRegion); + // TODO? the decorator should be in WinBorder coordinates?? It's easier not to. + //ConvertToScreen2(&fDecRegion); } BRect screenFrame(Bounds());