diff --git a/src/add-ons/decorators/SATDecorator/SATGroup.cpp b/src/add-ons/decorators/SATDecorator/SATGroup.cpp index 199091afb4..be855bdf17 100644 --- a/src/add-ons/decorators/SATDecorator/SATGroup.cpp +++ b/src/add-ons/decorators/SATDecorator/SATGroup.cpp @@ -710,7 +710,7 @@ SATGroup::AddWindow(SATWindow* window, WindowArea* area, SATWindow* after) bool -SATGroup::RemoveWindow(SATWindow* window) +SATGroup::RemoveWindow(SATWindow* window, bool stayBelowMouse) { if (!fSATWindowList.RemoveItem(window)) return false; @@ -722,7 +722,7 @@ SATGroup::RemoveWindow(SATWindow* window) for (int i = 0; i < CountItems(); i++) WindowAt(i)->DoGroupLayout(); - window->RemovedFromGroup(this); + window->RemovedFromGroup(this, stayBelowMouse); // Do nothing after removing the window from the group because this // could have released the last reference and destroyed ourself. return true; diff --git a/src/add-ons/decorators/SATDecorator/SATGroup.h b/src/add-ons/decorators/SATDecorator/SATGroup.h index df2b625094..1ebd394a53 100644 --- a/src/add-ons/decorators/SATDecorator/SATGroup.h +++ b/src/add-ons/decorators/SATDecorator/SATGroup.h @@ -223,7 +223,10 @@ public: /*! Add a window to an existing window area. */ bool AddWindow(SATWindow* window, WindowArea* area, SATWindow* after = NULL); - bool RemoveWindow(SATWindow* window); + /*! If stayBelowMouse is true move the removed window below the + cursor if necessary. */ + bool RemoveWindow(SATWindow* window, + bool stayBelowMouse = true); int32 CountItems(); SATWindow* WindowAt(int32 index); diff --git a/src/add-ons/decorators/SATDecorator/SATWindow.cpp b/src/add-ons/decorators/SATDecorator/SATWindow.cpp index 0d6e8ac883..80e5a47f6c 100644 --- a/src/add-ons/decorators/SATDecorator/SATWindow.cpp +++ b/src/add-ons/decorators/SATDecorator/SATWindow.cpp @@ -400,28 +400,14 @@ SATWindow::AddedToGroup(SATGroup* group, WindowArea* area) bool -SATWindow::RemovedFromGroup(SATGroup* group) +SATWindow::RemovedFromGroup(SATGroup* group, bool stayBelowMouse) { STRACE_SAT("SATWindow::RemovedFromGroup group: %p window %s\n", group, fWindow->Title()); - fWindow->SetSizeLimits(fOriginalMinWidth, fOriginalMaxWidth, - fOriginalMinHeight, fOriginalMaxHeight); - BRect frame = fWindow->Frame(); - float x = 0, y = 0; - if (fWindow->Look() == B_MODAL_WINDOW_LOOK - || fWindow->Look() == B_BORDERED_WINDOW_LOOK - || fWindow->Look() == B_NO_BORDER_WINDOW_LOOK - || (fWindow->Flags() & B_NOT_RESIZABLE) != 0) { - x = fOriginalWidth - frame.Width(); - y = fOriginalHeight - frame.Height(); - } else { - if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0) - x = fOriginalWidth - frame.Width(); - if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0) - y = fOriginalHeight - frame.Height(); - } - fDesktop->ResizeWindowBy(fWindow, x, y); + _RestoreOriginalSize(stayBelowMouse); + if (group->CountItems() == 1) + group->WindowAt(0)->_RestoreOriginalSize(false); if (fShutdown) { fGroupCookie->Uninit(); @@ -778,3 +764,67 @@ SATWindow::_GenerateId() int16 randNumber = rand(); return (time & ~0xFFFF) | randNumber; } + +void +SATWindow::_RestoreOriginalSize(bool stayBelowMouse) +{ + // restore size + fWindow->SetSizeLimits(fOriginalMinWidth, fOriginalMaxWidth, + fOriginalMinHeight, fOriginalMaxHeight); + BRect frame = fWindow->Frame(); + float x = 0, y = 0; + if (fWindow->Look() == B_MODAL_WINDOW_LOOK + || fWindow->Look() == B_BORDERED_WINDOW_LOOK + || fWindow->Look() == B_NO_BORDER_WINDOW_LOOK + || (fWindow->Flags() & B_NOT_RESIZABLE) != 0) { + x = fOriginalWidth - frame.Width(); + y = fOriginalHeight - frame.Height(); + } else { + if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0) + x = fOriginalWidth - frame.Width(); + if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0) + y = fOriginalHeight - frame.Height(); + } + fDesktop->ResizeWindowBy(fWindow, x, y); + + if (!stayBelowMouse) + return; + // verify that the window stays below the mouse + BPoint mousePosition; + int32 buttons; + fDesktop->GetLastMouseState(&mousePosition, &buttons); + SATDecorator* decorator = GetDecorator(); + if (decorator) { + BRect tabRect = decorator->TabRect(); + if (mousePosition.y < tabRect.bottom + && mousePosition.x <= frame.right + decorator->BorderWidth() +1 + && mousePosition.x >= frame.left + decorator->BorderWidth()) { + // verify mouse stays on the tab + float deltaX = 0; + if (tabRect.right < mousePosition.x) + deltaX = mousePosition.x - tabRect.right + 20; + else if (tabRect.left > mousePosition.x) + deltaX = mousePosition.x - tabRect.left - 20; + fDesktop->MoveWindowBy(fWindow, deltaX, 0); + } else { + // verify mouse stays on the border + float deltaX = 0; + float deltaY = 0; + BRect newFrame = fWindow->Frame(); + if (x != 0 && mousePosition.x > frame.left + && mousePosition.x > newFrame.right) { + deltaX = mousePosition.x - newFrame.right; + if (mousePosition.x > frame.right) + deltaX -= mousePosition.x - frame.right; + } + if (y != 0 && mousePosition.y > frame.top + && mousePosition.y > newFrame.bottom) { + deltaY = mousePosition.y - newFrame.bottom; + if (mousePosition.y > frame.bottom) + deltaY -= mousePosition.y - frame.bottom; + } + + fDesktop->MoveWindowBy(fWindow, deltaX, deltaY); + } + } +} diff --git a/src/add-ons/decorators/SATDecorator/SATWindow.h b/src/add-ons/decorators/SATDecorator/SATWindow.h index 6741780335..3f21e213c7 100644 --- a/src/add-ons/decorators/SATDecorator/SATWindow.h +++ b/src/add-ons/decorators/SATDecorator/SATWindow.h @@ -96,7 +96,8 @@ public: // hook function called from SATGroup bool AddedToGroup(SATGroup* group, WindowArea* area); - bool RemovedFromGroup(SATGroup* group); + bool RemovedFromGroup(SATGroup* group, + bool stayBelowMouse); void RemovedFromArea(WindowArea* area); bool StackWindow(SATWindow* child); @@ -139,6 +140,9 @@ private: void _UpdateSizeLimits(); uint64 _GenerateId(); + void _RestoreOriginalSize( + bool stayBelowMouse = true); + Window* fWindow; StackAndTile* fStackAndTile; Desktop* fDesktop; diff --git a/src/add-ons/decorators/SATDecorator/Stacking.cpp b/src/add-ons/decorators/SATDecorator/Stacking.cpp index 951be05a85..47196768ad 100644 --- a/src/add-ons/decorators/SATDecorator/Stacking.cpp +++ b/src/add-ons/decorators/SATDecorator/Stacking.cpp @@ -101,7 +101,7 @@ StackingEventHandler::HandleMessage(SATWindow* sender, SATWindow* candidate = stackAndTile->GetSATWindow(window); if (!candidate) return false; - if (!group->RemoveWindow(candidate)) + if (!group->RemoveWindow(candidate, false)) return false; break; } @@ -121,7 +121,7 @@ StackingEventHandler::HandleMessage(SATWindow* sender, break; } - if (!group->RemoveWindow(removeWindow)) + if (!group->RemoveWindow(removeWindow, false)) return false; ServerWindow* window = removeWindow->GetWindow()->ServerWindow();