If a window is removed from a group by the user make sure that the window is under the mouse cursor.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39713 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler
2010-12-03 02:29:13 +00:00
parent 92998b409f
commit f149f7aa88
5 changed files with 81 additions and 24 deletions
@@ -710,7 +710,7 @@ SATGroup::AddWindow(SATWindow* window, WindowArea* area, SATWindow* after)
bool bool
SATGroup::RemoveWindow(SATWindow* window) SATGroup::RemoveWindow(SATWindow* window, bool stayBelowMouse)
{ {
if (!fSATWindowList.RemoveItem(window)) if (!fSATWindowList.RemoveItem(window))
return false; return false;
@@ -722,7 +722,7 @@ SATGroup::RemoveWindow(SATWindow* window)
for (int i = 0; i < CountItems(); i++) for (int i = 0; i < CountItems(); i++)
WindowAt(i)->DoGroupLayout(); WindowAt(i)->DoGroupLayout();
window->RemovedFromGroup(this); window->RemovedFromGroup(this, stayBelowMouse);
// Do nothing after removing the window from the group because this // Do nothing after removing the window from the group because this
// could have released the last reference and destroyed ourself. // could have released the last reference and destroyed ourself.
return true; return true;
@@ -223,7 +223,10 @@ public:
/*! Add a window to an existing window area. */ /*! Add a window to an existing window area. */
bool AddWindow(SATWindow* window, WindowArea* area, bool AddWindow(SATWindow* window, WindowArea* area,
SATWindow* after = NULL); 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(); int32 CountItems();
SATWindow* WindowAt(int32 index); SATWindow* WindowAt(int32 index);
@@ -400,28 +400,14 @@ SATWindow::AddedToGroup(SATGroup* group, WindowArea* area)
bool bool
SATWindow::RemovedFromGroup(SATGroup* group) SATWindow::RemovedFromGroup(SATGroup* group, bool stayBelowMouse)
{ {
STRACE_SAT("SATWindow::RemovedFromGroup group: %p window %s\n", group, STRACE_SAT("SATWindow::RemovedFromGroup group: %p window %s\n", group,
fWindow->Title()); fWindow->Title());
fWindow->SetSizeLimits(fOriginalMinWidth, fOriginalMaxWidth, _RestoreOriginalSize(stayBelowMouse);
fOriginalMinHeight, fOriginalMaxHeight); if (group->CountItems() == 1)
BRect frame = fWindow->Frame(); group->WindowAt(0)->_RestoreOriginalSize(false);
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 (fShutdown) { if (fShutdown) {
fGroupCookie->Uninit(); fGroupCookie->Uninit();
@@ -778,3 +764,67 @@ SATWindow::_GenerateId()
int16 randNumber = rand(); int16 randNumber = rand();
return (time & ~0xFFFF) | randNumber; 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);
}
}
}
@@ -96,7 +96,8 @@ public:
// hook function called from SATGroup // hook function called from SATGroup
bool AddedToGroup(SATGroup* group, WindowArea* area); bool AddedToGroup(SATGroup* group, WindowArea* area);
bool RemovedFromGroup(SATGroup* group); bool RemovedFromGroup(SATGroup* group,
bool stayBelowMouse);
void RemovedFromArea(WindowArea* area); void RemovedFromArea(WindowArea* area);
bool StackWindow(SATWindow* child); bool StackWindow(SATWindow* child);
@@ -139,6 +140,9 @@ private:
void _UpdateSizeLimits(); void _UpdateSizeLimits();
uint64 _GenerateId(); uint64 _GenerateId();
void _RestoreOriginalSize(
bool stayBelowMouse = true);
Window* fWindow; Window* fWindow;
StackAndTile* fStackAndTile; StackAndTile* fStackAndTile;
Desktop* fDesktop; Desktop* fDesktop;
@@ -101,7 +101,7 @@ StackingEventHandler::HandleMessage(SATWindow* sender,
SATWindow* candidate = stackAndTile->GetSATWindow(window); SATWindow* candidate = stackAndTile->GetSATWindow(window);
if (!candidate) if (!candidate)
return false; return false;
if (!group->RemoveWindow(candidate)) if (!group->RemoveWindow(candidate, false))
return false; return false;
break; break;
} }
@@ -121,7 +121,7 @@ StackingEventHandler::HandleMessage(SATWindow* sender,
break; break;
} }
if (!group->RemoveWindow(removeWindow)) if (!group->RemoveWindow(removeWindow, false))
return false; return false;
ServerWindow* window = removeWindow->GetWindow()->ServerWindow(); ServerWindow* window = removeWindow->GetWindow()->ServerWindow();