- If there is no SATWindow because of lack of memory try to create a SATWindow when asking for it.

- Add untested code to save a SATGroup and to restore a SATGroup.
- Splitting of a SATGroup is now triggered from the WindowArea destructor. This make it easier to restore S&T groups when windows in a group are missing. A group decays automatically in multiple groups when the missing window connected multiple windows.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39461 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler
2010-11-17 03:06:09 +00:00
parent 631cc3ea7b
commit f72d191b12
6 changed files with 202 additions and 27 deletions
+129 -15
View File
@@ -9,13 +9,19 @@
#include "SATGroup.h" #include "SATGroup.h"
#include <vector>
#include <Debug.h> #include <Debug.h>
#include <Message.h>
#include "SATWindow.h" #include "SATWindow.h"
#include "StackAndTile.h" #include "StackAndTile.h"
#include "Window.h" #include "Window.h"
using namespace std;
WindowArea::WindowArea(Crossing* leftTop, Crossing* rightTop, WindowArea::WindowArea(Crossing* leftTop, Crossing* rightTop,
Crossing* leftBottom, Crossing* rightBottom) Crossing* leftBottom, Crossing* rightBottom)
: :
@@ -46,6 +52,9 @@ WindowArea::SetGroup(SATGroup* group)
WindowArea::~WindowArea() WindowArea::~WindowArea()
{ {
if (fGroup)
fGroup->WindowAreaRemoved(this);
_CleanupCorners(); _CleanupCorners();
SetGroup(NULL); SetGroup(NULL);
} }
@@ -706,8 +715,6 @@ SATGroup::RemoveWindow(SATWindow* window)
if (!fSATWindowList.RemoveItem(window)) if (!fSATWindowList.RemoveItem(window))
return false; return false;
_SplitGroupIfNecessary(window);
WindowArea* area = window->GetWindowArea(); WindowArea* area = window->GetWindowArea();
if (area) if (area)
area->_RemoveWindow(window); area->_RemoveWindow(window);
@@ -784,6 +791,119 @@ SATGroup::AdjustWindows(SATWindow* triggerWindow)
} }
void
SATGroup::WindowAreaRemoved(WindowArea* area)
{
_SplitGroupIfNecessary(area);
}
status_t
SATGroup::RestoreGroup(const BMessage& archive, StackAndTile* sat)
{
// create new group
SATGroup* group = new (std::nothrow)SATGroup;
if (!group)
return B_NO_MEMORY;
BReference<SATGroup> groupRef;
groupRef.SetTo(group, true);
int32 nHTabs, nVTabs;
status_t status;
status = archive.FindInt32("htab_count", &nHTabs);
if (status != B_OK)
return status;
status = archive.FindInt32("vtab_count", &nVTabs);
if (status != B_OK)
return status;
vector<BReference<Tab> > tempHTabs;
for (int i = 0; i < nHTabs; i++) {
BReference<Tab> tab = group->_AddHorizontalTab();
if (!tab)
return B_NO_MEMORY;
tempHTabs.push_back(tab);
}
vector<BReference<Tab> > tempVTabs;
for (int i = 0; i < nVTabs; i++) {
BReference<Tab> tab = group->_AddVerticalTab();
if (!tab)
return B_NO_MEMORY;
tempVTabs.push_back(tab);
}
BMessage areaArchive;
for (int32 i = 0; archive.FindMessage("area", i, &areaArchive) == B_OK;
i++) {
uint32 leftTab, rightTab, topTab, bottomTab;
if (areaArchive.FindInt32("left_tab", (int32*)&leftTab) != B_OK
|| areaArchive.FindInt32("right_tab", (int32*)&rightTab) != B_OK
|| areaArchive.FindInt32("top_tab", (int32*)&topTab) != B_OK
|| areaArchive.FindInt32("bottom_tab", (int32*)&bottomTab) != B_OK)
return B_ERROR;
if (leftTab >= tempVTabs.size() || rightTab >= tempVTabs.size())
return B_BAD_VALUE;
if (topTab >= tempHTabs.size() || bottomTab >= tempHTabs.size())
return B_BAD_VALUE;
Tab* left = tempVTabs[leftTab];
Tab* right = tempVTabs[rightTab];
Tab* top = tempHTabs[topTab];
Tab* bottom = tempHTabs[bottomTab];
// adding windows to area
int64 windowId;
WindowArea* area = NULL;
for (int32 i = 0;
areaArchive.FindInt64("window", i, &windowId) == B_OK; i++) {
SATWindow* window = sat->FindSATWindow(windowId);
if (!window)
continue;
if (area == NULL) {
if (!group->AddWindow(window, left, top, right, bottom))
return B_ERROR;
area = window->GetWindowArea();
} else {
if (!group->AddWindow(window, area))
return B_ERROR;
}
}
}
return B_OK;
}
status_t
SATGroup::ArchiveGroup(BMessage& archive)
{
archive.AddInt32("htab_count", fHorizontalTabs.CountItems());
archive.AddInt32("vtab_count", fVerticalTabs.CountItems());
for (int i = 0; i < fWindowAreaList.CountItems(); i++) {
WindowArea* area = fWindowAreaList.ItemAt(i);
int32 leftTab = fVerticalTabs.IndexOf(area->LeftTab());
int32 rightTab = fVerticalTabs.IndexOf(area->RightTab());
int32 topTab = fHorizontalTabs.IndexOf(area->TopTab());
int32 bottomTab = fHorizontalTabs.IndexOf(area->BottomTab());
BMessage areaMessage;
areaMessage.AddInt32("left_tab", leftTab);
areaMessage.AddInt32("right_tab", rightTab);
areaMessage.AddInt32("top_tab", topTab);
areaMessage.AddInt32("bottom_tab", bottomTab);
const SATWindowList& windowList = area->WindowList();
for (int a = 0; a < windowList.CountItems(); a++)
areaMessage.AddInt64("window", windowList.ItemAt(a)->Id());
archive.AddMessage("area", &areaMessage);
}
return B_OK;
}
BReference<Tab> BReference<Tab>
SATGroup::_AddHorizontalTab(float position) SATGroup::_AddHorizontalTab(float position)
{ {
@@ -860,20 +980,19 @@ SATGroup::_FindTab(const TabList& list, float position)
void void
SATGroup::_SplitGroupIfNecessary(SATWindow* removedWindow) SATGroup::_SplitGroupIfNecessary(WindowArea* removedArea)
{ {
// if there are windows stacked in the area we don't need to split // if there are windows stacked in the area we don't need to split
WindowArea* area = removedWindow->GetWindowArea(); if (!removedArea || removedArea->WindowList().CountItems() > 1)
if (!area || area->WindowList().CountItems() > 1)
return; return;
WindowAreaList neighbourWindows; WindowAreaList neighbourWindows;
_FillNeighbourList(neighbourWindows, removedWindow->GetWindowArea()); _FillNeighbourList(neighbourWindows, removedArea);
bool ownGroupProcessed = false; bool ownGroupProcessed = false;
WindowAreaList newGroup; WindowAreaList newGroup;
while (_FindConnectedGroup(neighbourWindows, removedWindow, newGroup)) { while (_FindConnectedGroup(neighbourWindows, removedArea, newGroup)) {
STRACE_SAT("Connected group found; %i windows:\n", STRACE_SAT("Connected group found; %i windows:\n",
(int)newGroup.CountItems()); (int)newGroup.CountItems());
for (int i = 0; i < newGroup.CountItems(); i++) { for (int i = 0; i < newGroup.CountItems(); i++) {
@@ -903,8 +1022,6 @@ void
SATGroup::_FillNeighbourList(WindowAreaList& neighbourWindows, SATGroup::_FillNeighbourList(WindowAreaList& neighbourWindows,
WindowArea* area) WindowArea* area)
{ {
if (!area)
return;
_LeftNeighbours(neighbourWindows, area); _LeftNeighbours(neighbourWindows, area);
_RightNeighbours(neighbourWindows, area); _RightNeighbours(neighbourWindows, area);
_TopNeighbours(neighbourWindows, area); _TopNeighbours(neighbourWindows, area);
@@ -1018,19 +1135,16 @@ SATGroup::_BottomNeighbours(WindowAreaList& neighbourWindows,
bool bool
SATGroup::_FindConnectedGroup(WindowAreaList& seedList, SATGroup::_FindConnectedGroup(WindowAreaList& seedList, WindowArea* removedArea,
SATWindow* removedWindow, WindowAreaList& newGroup) WindowAreaList& newGroup)
{ {
if (seedList.CountItems() == 0) if (seedList.CountItems() == 0)
return false; return false;
WindowArea* vetoArea = removedWindow->GetWindowArea();
if (!vetoArea)
return false;
WindowArea* area = seedList.RemoveItemAt(0); WindowArea* area = seedList.RemoveItemAt(0);
newGroup.AddItem(area); newGroup.AddItem(area);
_FollowSeed(area, vetoArea, seedList, newGroup); _FollowSeed(area, removedArea, seedList, newGroup);
return true; return true;
} }
+12 -3
View File
@@ -133,7 +133,7 @@ public:
Crossing* rightBottom); Crossing* rightBottom);
~WindowArea(); ~WindowArea();
bool SetGroup(SATGroup* group); bool SetGroup(SATGroup* group);
const SATWindowList& WindowList() { return fWindowList; } const SATWindowList& WindowList() { return fWindowList; }
const SATWindowList& LayerOrder() { return fWindowLayerOrder; } const SATWindowList& LayerOrder() { return fWindowLayerOrder; }
@@ -200,6 +200,9 @@ private:
typedef BObjectList<WindowArea> WindowAreaList; typedef BObjectList<WindowArea> WindowAreaList;
typedef BObjectList<Tab> TabList; typedef BObjectList<Tab> TabList;
class BMessage;
class StackAndTile;
class SATGroup : public BReferenceable { class SATGroup : public BReferenceable {
public: public:
@@ -233,6 +236,12 @@ public:
Tab* FindHorizontalTab(float position); Tab* FindHorizontalTab(float position);
Tab* FindVerticalTab(float position); Tab* FindVerticalTab(float position);
void WindowAreaRemoved(WindowArea* area);
static status_t RestoreGroup(const BMessage& archive,
StackAndTile* sat);
status_t ArchiveGroup(BMessage& archive);
private: private:
BReference<Tab> _AddHorizontalTab(float position = 0); BReference<Tab> _AddHorizontalTab(float position = 0);
BReference<Tab> _AddVerticalTab(float position = 0); BReference<Tab> _AddVerticalTab(float position = 0);
@@ -243,7 +252,7 @@ private:
Tab* _FindTab(const TabList& list, float position); Tab* _FindTab(const TabList& list, float position);
void _SplitGroupIfNecessary( void _SplitGroupIfNecessary(
SATWindow* removedWindow); WindowArea* removedArea);
void _FillNeighbourList( void _FillNeighbourList(
WindowAreaList& neighbourWindows, WindowAreaList& neighbourWindows,
WindowArea* area); WindowArea* area);
@@ -260,7 +269,7 @@ private:
WindowAreaList& neighbourWindows, WindowAreaList& neighbourWindows,
WindowArea* window); WindowArea* window);
bool _FindConnectedGroup(WindowAreaList& seedList, bool _FindConnectedGroup(WindowAreaList& seedList,
SATWindow* removedWindow, WindowArea* removedArea,
WindowAreaList& newGroup); WindowAreaList& newGroup);
void _FollowSeed(WindowArea* area, WindowArea* veto, void _FollowSeed(WindowArea* area, WindowArea* veto,
WindowAreaList& seedList, WindowAreaList& seedList,
@@ -289,6 +289,8 @@ SATWindow::SATWindow(StackAndTile* sat, Window* window)
fSATTiling(this), fSATTiling(this),
fShutdown(false) fShutdown(false)
{ {
fId = _GenerateId();
fDesktop = fWindow->Desktop(); fDesktop = fWindow->Desktop();
fGroupCookie = &fOwnGroupCookie; fGroupCookie = &fOwnGroupCookie;
@@ -680,6 +682,29 @@ SATWindow::TabLocationMoved(float location, bool shifting)
} }
uint64
SATWindow::Id()
{
return fId;
}
bool
SATWindow::SetSettings(const BMessage& message)
{
if (message.FindInt64("window_id", (int64*)&fId) != B_OK)
return false;
return true;
}
void
SATWindow::GetSettings(BMessage& message)
{
message.AddInt64("window_id", fId);
}
void void
SATWindow::_InitGroup() SATWindow::_InitGroup()
{ {
@@ -744,3 +769,13 @@ SATWindow::_UpdateSizeLimits()
fGroupCookie->SetSizeLimits(minWidth, B_SIZE_UNLIMITED, minHeight, fGroupCookie->SetSizeLimits(minWidth, B_SIZE_UNLIMITED, minHeight,
B_SIZE_UNLIMITED); B_SIZE_UNLIMITED);
} }
uint64
SATWindow::_GenerateId()
{
bigtime_t time = real_time_clock_usecs();
srand(time);
int16 randNumber = rand();
return (time & ~0xFFFF) | randNumber;
}
@@ -128,9 +128,14 @@ public:
bool SetStackedTabMoving(bool moving = true); bool SetStackedTabMoving(bool moving = true);
void TabLocationMoved(float location, bool shifting); void TabLocationMoved(float location, bool shifting);
uint64 Id();
bool SetSettings(const BMessage& message);
void GetSettings(BMessage& message);
private: private:
void _InitGroup(); void _InitGroup();
void _UpdateSizeLimits(); void _UpdateSizeLimits();
uint64 _GenerateId();
Window* fWindow; Window* fWindow;
StackAndTile* fStackAndTile; StackAndTile* fStackAndTile;
@@ -158,6 +163,8 @@ private:
float fOriginalWidth; float fOriginalWidth;
float fOriginalHeight; float fOriginalHeight;
uint64 fId;
}; };
@@ -334,8 +334,7 @@ StackAndTile::SetDecoratorSettings(Window* window, const BMessage& settings)
if (!satWindow) if (!satWindow)
return false; return false;
//return satWindow->SetSettings(settings); return satWindow->SetSettings(settings);
return false;
} }
@@ -346,7 +345,7 @@ StackAndTile::GetDecoratorSettings(Window* window, BMessage& settings)
if (!satWindow) if (!satWindow)
return; return;
//satWindow->GetSettings(&settings); satWindow->GetSettings(settings);
} }
@@ -358,16 +357,26 @@ StackAndTile::GetSATWindow(Window* window)
if (it != fSATWindowMap.end()) if (it != fSATWindowMap.end())
return it->second; return it->second;
// for now don't create window on the fly
return NULL;
// If we don't know this window, memory allocation might has been failed // If we don't know this window, memory allocation might has been failed
// previously. Try to add window now // previously. Try to add the window now.
/* SATWindow* satWindow = new (std::nothrow)SATWindow( SATWindow* satWindow = new (std::nothrow)SATWindow(this, window);
window, this);
if (satWindow) if (satWindow)
fSATWindowMap[window] = satWindow; fSATWindowMap[window] = satWindow;
return satWindow;*/ return satWindow;
}
SATWindow*
StackAndTile::FindSATWindow(uint64 id)
{
for (SATWindowMap::const_iterator it = fSATWindowMap.begin();
it != fSATWindowMap.end(); it++) {
SATWindow* window = it->second;
if (window->Id() == id)
return window;
}
return NULL;
} }
@@ -89,6 +89,7 @@ public:
{ return fSATKeyPressed; } { return fSATKeyPressed; }
SATWindow* GetSATWindow(Window* window); SATWindow* GetSATWindow(Window* window);
SATWindow* FindSATWindow(uint64 id);
private: private:
void _StartSAT(); void _StartSAT();