Author: czeidler Date: 2010-12-03 03:29:13 +0100 (Fri, 03 Dec 2010) New Revision: 39713 Changeset: http://dev.haiku-os.org/changeset/39713 Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.cpp haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.h haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.cpp haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.h haiku/trunk/src/add-ons/decorators/SATDecorator/Stacking.cpp Log: If a window is removed from a group by the user make sure that the window is under the mouse cursor. Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.cpp =================================================================== --- haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.cpp 2010-12-03 00:45:29 UTC (rev 39712) +++ haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.cpp 2010-12-03 02:29:13 UTC (rev 39713) @@ -710,7 +710,7 @@ bool -SATGroup::RemoveWindow(SATWindow* window) +SATGroup::RemoveWindow(SATWindow* window, bool stayBelowMouse) { if (!fSATWindowList.RemoveItem(window)) return false; @@ -722,7 +722,7 @@ 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; Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.h =================================================================== --- haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.h 2010-12-03 00:45:29 UTC (rev 39712) +++ haiku/trunk/src/add-ons/decorators/SATDecorator/SATGroup.h 2010-12-03 02:29:13 UTC (rev 39713) @@ -223,7 +223,10 @@ /*! 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); Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.cpp =================================================================== --- haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.cpp 2010-12-03 00:45:29 UTC (rev 39712) +++ haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.cpp 2010-12-03 02:29:13 UTC (rev 39713) @@ -400,28 +400,14 @@ 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 @@ 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); + } + } +} Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.h =================================================================== --- haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.h 2010-12-03 00:45:29 UTC (rev 39712) +++ haiku/trunk/src/add-ons/decorators/SATDecorator/SATWindow.h 2010-12-03 02:29:13 UTC (rev 39713) @@ -96,7 +96,8 @@ // 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 @@ void _UpdateSizeLimits(); uint64 _GenerateId(); + void _RestoreOriginalSize( + bool stayBelowMouse = true); + Window* fWindow; StackAndTile* fStackAndTile; Desktop* fDesktop; Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/Stacking.cpp =================================================================== --- haiku/trunk/src/add-ons/decorators/SATDecorator/Stacking.cpp 2010-12-03 00:45:29 UTC (rev 39712) +++ haiku/trunk/src/add-ons/decorators/SATDecorator/Stacking.cpp 2010-12-03 02:29:13 UTC (rev 39713) @@ -101,7 +101,7 @@ 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 @@ break; } - if (!group->RemoveWindow(removeWindow)) + if (!group->RemoveWindow(removeWindow, false)) return false; ServerWindow* window = removeWindow->GetWindow()->ServerWindow();