diff --git a/src/add-ons/decorators/SATDecorator/SATGroup.cpp b/src/add-ons/decorators/SATDecorator/SATGroup.cpp index 618de39339..1b537cb781 100644 --- a/src/add-ons/decorators/SATDecorator/SATGroup.cpp +++ b/src/add-ons/decorators/SATDecorator/SATGroup.cpp @@ -84,6 +84,7 @@ WindowArea::_AddWindow(SATWindow* window, SATWindow* after) if (fWindowList.CountItems() <= 1) _InitCorners(); + fWindowLayerOrder.AddItem(window); return true; } @@ -94,6 +95,7 @@ WindowArea::_RemoveWindow(SATWindow* window) if (!fWindowList.RemoveItem(window)) return false; + fWindowLayerOrder.RemoveItem(window); window->RemovedFromArea(this); ReleaseReference(); return true; @@ -165,6 +167,15 @@ WindowArea::PropagateToGroup(SATGroup* group) } +bool +WindowArea::MoveToTopLayer(SATWindow* window) +{ + if (!fWindowLayerOrder.RemoveItem(window)) + return false; + return fWindowLayerOrder.AddItem(window); +} + + BReference WindowArea::_CrossingByPosition(Crossing* crossing, SATGroup* group) { diff --git a/src/add-ons/decorators/SATDecorator/SATGroup.h b/src/add-ons/decorators/SATDecorator/SATGroup.h index f876333c0f..a0a3897002 100644 --- a/src/add-ons/decorators/SATDecorator/SATGroup.h +++ b/src/add-ons/decorators/SATDecorator/SATGroup.h @@ -133,6 +133,7 @@ public: bool SetGroup(SATGroup* group); const SATWindowList& WindowList() { return fWindowList; } + const SATWindowList& LayerOrder() { return fWindowLayerOrder; } bool MoveWindowToPosition(SATWindow* window, int32 index); @@ -154,6 +155,8 @@ public: bool PropagateToGroup(SATGroup* group); + bool MoveToTopLayer(SATWindow* window); + private: friend class SATGroup; /*! SATGroup adds new windows to the area. */ @@ -180,6 +183,8 @@ private: SATWindowList fWindowList; + SATWindowList fWindowLayerOrder; + BReference fLeftTopCrossing; BReference fRightTopCrossing; BReference fLeftBottomCrossing; @@ -214,6 +219,8 @@ public: int32 CountItems(); SATWindow* WindowAt(int32 index); + const WindowAreaList& GetAreaList() { return fWindowAreaList; } + /*! \return a sorted tab list. */ const TabList* HorizontalTabs(); const TabList* VerticalTabs(); diff --git a/src/add-ons/decorators/SATDecorator/StackAndTile.cpp b/src/add-ons/decorators/SATDecorator/StackAndTile.cpp index 47cf0d47fe..56f268c337 100644 --- a/src/add-ons/decorators/SATDecorator/StackAndTile.cpp +++ b/src/add-ons/decorators/SATDecorator/StackAndTile.cpp @@ -220,8 +220,9 @@ StackAndTile::WindowSentBehind(Window* window, Window* behindOf) if (!desktop) return; - for (int i = 0; i < group->CountItems(); i++) { - SATWindow* listWindow = group->WindowAt(i); + WindowIterator iter(group, true); + for (SATWindow* listWindow = iter.NextWindow(); listWindow != NULL; + listWindow = iter.NextWindow()) { if (listWindow != satWindow) desktop->SendWindowBehind(listWindow->GetWindow(), behindOf); } @@ -367,16 +368,20 @@ StackAndTile::_ActivateWindow(SATWindow* satWindow) Desktop* desktop = satWindow->GetWindow()->Desktop(); if (!desktop) return; + WindowArea* area = satWindow->GetWindowArea(); + if (!area) + return; + area->MoveToTopLayer(satWindow); //desktop->ActivateWindow(satWindow->GetWindow()); - for (int i = 0; i < group->CountItems(); i++) { - SATWindow* listWindow = group->WindowAt(i); - if (listWindow == satWindow) - continue; - //desktop->SendWindowBehind(listWindow->GetWindow(), - // satWindow->GetWindow()); - desktop->ActivateWindow(listWindow->GetWindow()); + WindowIterator iter(group); + for (SATWindow* listWindow = iter.NextWindow(); listWindow != NULL; + listWindow = iter.NextWindow()) { + if (listWindow != satWindow) + //desktop->SendWindowBehind(listWindow->GetWindow(), + // satWindow->GetWindow()); + desktop->ActivateWindow(listWindow->GetWindow()); } desktop->ActivateWindow(satWindow->GetWindow()); @@ -426,6 +431,71 @@ GroupIterator::NextGroup() } +WindowIterator::WindowIterator(SATGroup* group, bool reverseLayerOrder) + : + fGroup(group), + fReverseLayerOrder(reverseLayerOrder) +{ + if (fReverseLayerOrder) + _ReverseRewind(); + else + Rewind(); +} + + +void +WindowIterator::Rewind() +{ + fAreaIndex = 0; + fWindowIndex = 0; + fCurrentArea = fGroup->GetAreaList().ItemAt(fAreaIndex); +} + + +SATWindow* +WindowIterator::NextWindow() +{ + if (fReverseLayerOrder) + return _ReverseNextWindow(); + + if (fWindowIndex == fCurrentArea->LayerOrder().CountItems()) { + fAreaIndex++; + fWindowIndex = 0; + fCurrentArea = fGroup->GetAreaList().ItemAt(fAreaIndex); + if (!fCurrentArea) + return NULL; + } + SATWindow* window = fCurrentArea->LayerOrder().ItemAt(fWindowIndex); + fWindowIndex++; + return window; +} + + +SATWindow* +WindowIterator::_ReverseNextWindow() +{ + if (fWindowIndex < 0) { + fAreaIndex++; + fCurrentArea = fGroup->GetAreaList().ItemAt(fAreaIndex); + if (!fCurrentArea) + return NULL; + fWindowIndex = fCurrentArea->LayerOrder().CountItems() - 1; + } + SATWindow* window = fCurrentArea->LayerOrder().ItemAt(fWindowIndex); + fWindowIndex--; + return window; +} + + +void +WindowIterator::_ReverseRewind() +{ + Rewind(); + if (fCurrentArea) + fWindowIndex = fCurrentArea->LayerOrder().CountItems() - 1; +} + + SATSnappingBehaviour::~SATSnappingBehaviour() { diff --git a/src/add-ons/decorators/SATDecorator/StackAndTile.h b/src/add-ons/decorators/SATDecorator/StackAndTile.h index ee12748606..ec07d60ce4 100644 --- a/src/add-ons/decorators/SATDecorator/StackAndTile.h +++ b/src/add-ons/decorators/SATDecorator/StackAndTile.h @@ -114,6 +114,32 @@ private: }; +class WindowIterator { +public: + WindowIterator(SATGroup* group, + bool reverseLayerOrder = false); + + void Rewind(); + /*! Iterates over all areas in the group and return the windows in the + areas. Within on area the windows are ordered by layer position. The + bottommost window comes first. */ + SATWindow* NextWindow(); + + +private: + /*! The windows in the area are returned in reverse order. */ + SATWindow* _ReverseNextWindow(); + void _ReverseRewind(); + + SATGroup* fGroup; + bool fReverseLayerOrder; + + WindowArea* fCurrentArea; + int32 fAreaIndex; + int32 fWindowIndex; +}; + + class SATSnappingBehaviour { public: virtual ~SATSnappingBehaviour();