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
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;
@@ -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);
@@ -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);
}
}
}
@@ -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;
@@ -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();