diff --git a/headers/private/interface/StackAndTilePrivate.h b/headers/private/interface/StackAndTilePrivate.h new file mode 100644 index 0000000000..9425a321aa --- /dev/null +++ b/headers/private/interface/StackAndTilePrivate.h @@ -0,0 +1,22 @@ +#ifndef STACK_AND_TILE_PRIVATE_H +#define STACK_AND_TILE_PRIVATE_H + +namespace BPrivate { + + +const int32 kMagicSATIdentifier = 'SATI'; + + +enum sat_messages { + kAddWindowToStack, + kRemoveWindowFromStack, + kRemoveWindowFromStackAt, + kCountWindowsOnStack, + kWindowOnStackAt, + kStackHasWindow +}; + +}; + + +#endif diff --git a/src/add-ons/decorators/SATDecorator/SATDecorator.cpp b/src/add-ons/decorators/SATDecorator/SATDecorator.cpp index a14bad3ee3..281544dda3 100644 --- a/src/add-ons/decorators/SATDecorator/SATDecorator.cpp +++ b/src/add-ons/decorators/SATDecorator/SATDecorator.cpp @@ -16,7 +16,7 @@ #include "DrawingEngine.h" -#define DEBUG_SATDECORATOR +//#define DEBUG_SATDECORATOR #ifdef DEBUG_SATDECORATOR # define STRACE(x) debug_printf x #else diff --git a/src/add-ons/decorators/SATDecorator/SATWindow.cpp b/src/add-ons/decorators/SATDecorator/SATWindow.cpp index bd619a1ee6..bc7e471f8e 100644 --- a/src/add-ons/decorators/SATDecorator/SATWindow.cpp +++ b/src/add-ons/decorators/SATDecorator/SATWindow.cpp @@ -11,9 +11,13 @@ #include #include "SATGroup.h" +#include "ServerApp.h" #include "Window.h" +using namespace BPrivate; + + SATWindow::SATWindow(StackAndTile* sat, Window* window) : fWindow(window), @@ -71,6 +75,13 @@ SATWindow::GetGroup() } +bool +SATWindow::HandleMessage(SATWindow* sender, BPrivate::ServerLink& link) +{ + return StackingEventHandler::HandleMessage(sender, link); +} + + bool SATWindow::PropagateToGroup(SATGroup* group, WindowArea* area) { @@ -126,6 +137,27 @@ SATWindow::RemovedFromGroup(SATGroup* group) } +bool +SATWindow::StackWindow(SATWindow* child) +{ + SATGroup* group = GetGroup(); + WindowArea* area = GetWindowArea(); + if (!group || !area) + return false; + + bool status = group->AddWindow(child, area, this); + + if (status) { + area->WindowList().ItemAt(0)->SetStackedMode(true); + // for the case we are the first added window + child->SetStackedMode(true); + } + + DoGroupLayout(); + return true; +} + + void SATWindow::RemovedFromArea(WindowArea* area) { diff --git a/src/add-ons/decorators/SATDecorator/SATWindow.h b/src/add-ons/decorators/SATDecorator/SATWindow.h index 33f25931f5..a09bc51a7f 100644 --- a/src/add-ons/decorators/SATDecorator/SATWindow.h +++ b/src/add-ons/decorators/SATDecorator/SATWindow.h @@ -72,10 +72,16 @@ public: Window* GetWindow() { return fWindow; } SATDecorator* GetDecorator() { return fDecorator; } + StackAndTile* GetStackAndTile() { return fStackAndTile; } + Desktop* GetDesktop() { return fDesktop; } //! Can be NULL if memory allocation failed! SATGroup* GetGroup(); WindowArea* GetWindowArea() { return fGroupCookie->GetWindowArea(); } + + bool HandleMessage(SATWindow* sender, + BPrivate::ServerLink& link); + bool PropagateToGroup(SATGroup* group, WindowArea* area); //! Move the window to the tab's position. @@ -86,6 +92,8 @@ public: bool RemovedFromGroup(SATGroup* group); void RemovedFromArea(WindowArea* area); + bool StackWindow(SATWindow* child); + void FindSnappingCandidates(); bool JoinCandidates(); void DoGroupLayout(); diff --git a/src/add-ons/decorators/SATDecorator/StackAndTile.cpp b/src/add-ons/decorators/SATDecorator/StackAndTile.cpp index 0f871f3bb2..ea0caec49c 100644 --- a/src/add-ons/decorators/SATDecorator/StackAndTile.cpp +++ b/src/add-ons/decorators/SATDecorator/StackAndTile.cpp @@ -10,6 +10,8 @@ #include +#include "StackAndTilePrivate.h" + #include "Desktop.h" #include "SATWindow.h" #include "Tiling.h" @@ -35,6 +37,13 @@ StackAndTile::~StackAndTile() } +int32 +StackAndTile::Identifier() +{ + return BPrivate::kMagicSATIdentifier; +} + + void StackAndTile::ListenerRegistered(Desktop* desktop) { @@ -57,6 +66,17 @@ StackAndTile::ListenerUnregistered() } +bool +StackAndTile::HandleMessage(Window* sender, BPrivate::ServerLink& link) +{ + SATWindow* satWindow = GetSATWindow(sender); + if (!satWindow) + return false; + + return satWindow->HandleMessage(satWindow, link); +} + + void StackAndTile::WindowAdded(Window* window) { diff --git a/src/add-ons/decorators/SATDecorator/StackAndTile.h b/src/add-ons/decorators/SATDecorator/StackAndTile.h index 54adfd084a..694a48f895 100644 --- a/src/add-ons/decorators/SATDecorator/StackAndTile.h +++ b/src/add-ons/decorators/SATDecorator/StackAndTile.h @@ -19,7 +19,7 @@ #include "WindowList.h" -#define DEBUG_STACK_AND_TILE +//#define DEBUG_STACK_AND_TILE #ifdef DEBUG_STACK_AND_TILE # define STRACE_SAT(x...) debug_printf("SAT: "x) @@ -40,10 +40,15 @@ public: StackAndTile(); virtual ~StackAndTile(); + virtual int32 Identifier(); + // DesktopListener hooks virtual void ListenerRegistered(Desktop* desktop); virtual void ListenerUnregistered(); + virtual bool HandleMessage(Window* sender, + BPrivate::ServerLink& link); + virtual void WindowAdded(Window* window); virtual void WindowRemoved(Window* window); diff --git a/src/add-ons/decorators/SATDecorator/Stacking.cpp b/src/add-ons/decorators/SATDecorator/Stacking.cpp index f6c6770937..0c95817a43 100644 --- a/src/add-ons/decorators/SATDecorator/Stacking.cpp +++ b/src/add-ons/decorators/SATDecorator/Stacking.cpp @@ -10,6 +10,8 @@ #include +#include "StackAndTilePrivate.h" + #include "SATWindow.h" #include "Window.h" @@ -23,6 +25,178 @@ #endif +using namespace BPrivate; + + +bool +StackingEventHandler::HandleMessage(SATWindow* sender, + BPrivate::ServerLink& link) +{ + Desktop* desktop = sender->GetDesktop(); + StackAndTile* stackAndTile = sender->GetStackAndTile(); + + int32 what; + link.Read(&what); + + switch (what) { + case kAddWindowToStack: + { + port_id port; + int32 token; + team_id team; + link.Read(&port); + link.Read(&token); + link.Read(&team); + int32 position; + if (link.Read(&position) != B_OK) + return false; + + WindowArea* area = sender->GetWindowArea(); + if (!area) + return false; + if (position < 0) + position = area->WindowList().CountItems() - 1; + + SATWindow* parent = area->WindowList().ItemAt(position); + Window* window = desktop->WindowForClientLooperPort(port); + if (!parent || !window) { + link.StartMessage(B_BAD_VALUE); + link.Flush(); + break; + } + + SATWindow* candidate = stackAndTile->GetSATWindow(window); + if (!candidate) + return false; + if (!parent->StackWindow(candidate)) + return false; + + link.StartMessage(B_OK); + link.Flush(); + break; + } + case kRemoveWindowFromStack: + { + port_id port; + int32 token; + team_id team; + link.Read(&port); + link.Read(&token); + if (link.Read(&team) != B_OK) + return false; + + SATGroup* group = sender->GetGroup(); + if (!group) + return false; + + Window* window = desktop->WindowForClientLooperPort(port); + if (!window) { + link.StartMessage(B_BAD_VALUE); + link.Flush(); + break; + } + SATWindow* candidate = stackAndTile->GetSATWindow(window); + if (!candidate) + return false; + if (!group->RemoveWindow(candidate)) + return false; + break; + } + case kRemoveWindowFromStackAt: + { + int32 position; + if (link.Read(&position) != B_OK) + return false; + SATGroup* group = sender->GetGroup(); + WindowArea* area = sender->GetWindowArea(); + if (!area || !group) + return false; + SATWindow* removeWindow = area->WindowList().ItemAt(position); + if (!removeWindow) { + link.StartMessage(B_BAD_VALUE); + link.Flush(); + break; + } + + if (!group->RemoveWindow(removeWindow)) + return false; + + ServerWindow* window = removeWindow->GetWindow()->ServerWindow(); + link.StartMessage(B_OK); + link.Attach(window->ClientLooperPort()); + link.Attach(window->ClientToken()); + link.Attach(window->ClientTeam()); + link.Flush(); + break; + } + case kCountWindowsOnStack: + { + WindowArea* area = sender->GetWindowArea(); + if (!area) + return false; + link.StartMessage(B_OK); + link.Attach(area->WindowList().CountItems()); + link.Flush(); + break; + } + case kWindowOnStackAt: + { + int32 position; + if (link.Read(&position) != B_OK) + return false; + WindowArea* area = sender->GetWindowArea(); + if (!area) + return false; + SATWindow* satWindow = area->WindowList().ItemAt(position); + if (!satWindow) { + link.StartMessage(B_BAD_VALUE); + link.Flush(); + break; + } + + ServerWindow* window = satWindow->GetWindow()->ServerWindow(); + link.StartMessage(B_OK); + link.Attach(window->ClientLooperPort()); + link.Attach(window->ClientToken()); + link.Attach(window->ClientTeam()); + link.Flush(); + break; + } + case kStackHasWindow: + { + port_id port; + int32 token; + team_id team; + link.Read(&port); + link.Read(&token); + if (link.Read(&team) != B_OK) + return false; + + Window* window = desktop->WindowForClientLooperPort(port); + if (!window) { + link.StartMessage(B_BAD_VALUE); + link.Flush(); + break; + } + SATWindow* candidate = stackAndTile->GetSATWindow(window); + if (!candidate) + return false; + + WindowArea* area = sender->GetWindowArea(); + if (!area) + return false; + link.StartMessage(B_OK); + link.Attach(area->WindowList().HasItem(candidate)); + link.Flush(); + break; + } + default: + return false; + } + return true; +} + + SATStacking::SATStacking(SATWindow* window) : fSATWindow(window), @@ -68,24 +242,11 @@ SATStacking::JoinCandidates() { if (!fStackingCandidate) return false; - SATGroup* group = fStackingCandidate->GetGroup(); - WindowArea* area = fStackingCandidate->GetWindowArea(); - if (!group || !area) { - _ClearSearchResult(); - return false; - } - bool status = group->AddWindow(fSATWindow, area, fStackingCandidate); + bool result = fStackingCandidate->StackWindow(fSATWindow); - if (status) { - area->WindowList().ItemAt(0)->SetStackedMode(true); - // for the case we are the first added window - fSATWindow->SetStackedMode(true); - } - - fStackingCandidate->DoGroupLayout(); _ClearSearchResult(); - return status; + return result; } diff --git a/src/add-ons/decorators/SATDecorator/Stacking.h b/src/add-ons/decorators/SATDecorator/Stacking.h index 9b94e20d15..fe4c43bda8 100644 --- a/src/add-ons/decorators/SATDecorator/Stacking.h +++ b/src/add-ons/decorators/SATDecorator/Stacking.h @@ -15,6 +15,14 @@ class SATWindow; +class StackingEventHandler +{ +public: + static bool HandleMessage(SATWindow* sender, + BPrivate::ServerLink& link); +}; + + class SATStacking : public SATSnappingBehaviour { public: SATStacking(SATWindow* window);