Skip to content

Commit

Permalink
Move stacked windows to a different workspace correctly.
Browse files Browse the repository at this point in the history
When moving a window of a stacked window group to a different workspace all windows in the stack have to be moved. This fixes #8855.
  • Loading branch information
czeidler committed Nov 6, 2012
1 parent 8ddec5b commit 6078d89
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 24 deletions.
61 changes: 41 additions & 20 deletions src/servers/app/Desktop.cpp
Expand Up @@ -1357,21 +1357,30 @@ Desktop::MoveWindowBy(Window* window, float x, float y, int32 workspace)
AutoWriteLocker _(fWindowLock);

Window* topWindow = window->TopLayerStackWindow();
if (topWindow)
if (topWindow != NULL)
window = topWindow;

if (workspace == -1)
workspace = fCurrentWorkspace;
if (!window->IsVisible() || workspace != fCurrentWorkspace) {
if (workspace != fCurrentWorkspace) {
// move the window on another workspace - this doesn't change it's
// current position
if (window->Anchor(workspace).position == kInvalidWindowPosition)
window->Anchor(workspace).position = window->Frame().LeftTop();

window->Anchor(workspace).position += BPoint(x, y);
window->SetCurrentWorkspace(workspace);
_WindowChanged(window);
WindowStack* stack = window->GetWindowStack();
if (stack != NULL) {
for (int32 s = 0; s < stack->CountWindows(); s++) {
Window* stackWindow = stack->WindowAt(s);
// move the window on another workspace - this doesn't
// change it's current position
if (stackWindow->Anchor(workspace).position
== kInvalidWindowPosition) {
stackWindow->Anchor(workspace).position
= stackWindow->Frame().LeftTop();
}

stackWindow->Anchor(workspace).position += BPoint(x, y);
stackWindow->SetCurrentWorkspace(workspace);
_WindowChanged(stackWindow);
}
}
} else
window->MoveBy((int32)x, (int32)y);

Expand Down Expand Up @@ -1532,11 +1541,16 @@ Desktop::SetWindowWorkspaces(Window* window, uint32 workspaces)
if (window->IsNormal() && workspaces == B_CURRENT_WORKSPACE)
workspaces = workspace_to_workspaces(CurrentWorkspace());

uint32 oldWorkspaces = window->Workspaces();

window->WorkspacesChanged(oldWorkspaces, workspaces);
_ChangeWindowWorkspaces(window, oldWorkspaces, workspaces);
WindowStack* stack = window->GetWindowStack();
if (stack != NULL) {
for (int32 s = 0; s < stack->CountWindows(); s++) {
window = stack->LayerOrder().ItemAt(s);

uint32 oldWorkspaces = window->Workspaces();
window->WorkspacesChanged(oldWorkspaces, workspaces);
_ChangeWindowWorkspaces(window, oldWorkspaces, workspaces);
}
}
UnlockAllWindows();
}

Expand Down Expand Up @@ -3415,18 +3429,25 @@ Desktop::_SetWorkspace(int32 index, bool moveFocusWindow)
// But only normal windows are following
uint32 oldWorkspaces = movedWindow->Workspaces();

_Windows(previousIndex).RemoveWindow(movedWindow);
_Windows(index).AddWindow(movedWindow,
movedWindow->Frontmost(_Windows(index).FirstWindow(),
index));
WindowStack* stack = movedWindow->GetWindowStack();
if (stack != NULL) {
for (int32 s = 0; s < stack->CountWindows(); s++) {
Window* stackWindow = stack->LayerOrder().ItemAt(s);

_Windows(previousIndex).RemoveWindow(stackWindow);
_Windows(index).AddWindow(stackWindow,
stackWindow->Frontmost(
_Windows(index).FirstWindow(), index));

// send B_WORKSPACES_CHANGED message
stackWindow->WorkspacesChanged(oldWorkspaces,
stackWindow->Workspaces());
}
}
// TODO: subset windows will always flicker this way

movedMouseEventWindow = true;

// send B_WORKSPACES_CHANGED message
movedWindow->WorkspacesChanged(oldWorkspaces,
movedWindow->Workspaces());
NotifyWindowWorkspacesChanged(movedWindow,
movedWindow->Workspaces());
} else {
Expand Down
11 changes: 7 additions & 4 deletions src/servers/app/stackandtile/StackAndTile.cpp
Expand Up @@ -368,10 +368,13 @@ StackAndTile::WindowWorkspacesChanged(Window* window, uint32 workspaces)
if (desktop == NULL)
return;

for (int i = 0; i < group->CountItems(); i++) {
SATWindow* listWindow = group->WindowAt(i);
if (listWindow != satWindow)
desktop->SetWindowWorkspaces(listWindow->GetWindow(), workspaces);
const WindowAreaList& areaList = group->GetAreaList();
for (int32 i = 0; i < areaList.CountItems(); i++) {
WindowArea* area = areaList.ItemAt(i);
if (area->WindowList().HasItem(satWindow))
continue;
SATWindow* topWindow = area->TopWindow();
desktop->SetWindowWorkspaces(topWindow->GetWindow(), workspaces);
}
}

Expand Down

0 comments on commit 6078d89

Please sign in to comment.