Fixed two dirty region problems of the workspace switching code:

* If two intersecting windows didn't change their position but their 
  order, the dirty region wouldn't contain the region that would need
  to be updated because of that order change. This fixes bug #827.
* When a hidden window was on the new workspace (but not on the old one),
  its region would be included in the dirty region, but shouldn't have
  been. This caused the app_server to update a larger region than 
  necessary.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23398 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-01-11 14:04:53 +00:00
parent f293c7cb52
commit 45d0ea5605

View File

@ -921,6 +921,9 @@ Desktop::_SetWorkspace(int32 index)
// show windows, and include them in the changed region - but only
// those that were not visible before (or whose position changed)
WindowList windows(kWorkingList);
BList previousRegions;
for (WindowLayer* window = _Windows(index).FirstWindow();
window != NULL; window = window->NextWindow(index)) {
BPoint position = window->Anchor(index).position;
@ -953,6 +956,17 @@ Desktop::_SetWorkspace(int32 index)
BPoint offset = position - window->Frame().LeftTop();
MoveWindowBy(window, offset.x, offset.y);
// TODO: be a bit smarter than this...
} else {
// We need to remember the previous visible region of the
// window if they changed their order
BRegion* region = new (std::nothrow)
BRegion(window->VisibleRegion());
if (region != NULL) {
if (previousRegions.AddItem(region))
windows.AddWindow(window);
else
delete region;
}
}
}
@ -969,7 +983,7 @@ Desktop::_SetWorkspace(int32 index)
// send B_WORKSPACE_ACTIVATED message
window->WorkspaceActivated(index, true);
if (window->InWorkspace(previousIndex)
if (window->InWorkspace(previousIndex) || window->IsHidden()
|| (window == fMouseEventWindow && fMouseEventWindow->IsNormal())
|| (!window->IsNormal() && window->HasInSubset(fMouseEventWindow))) {
// this window was visible before, and is already handled in the above loop
@ -979,14 +993,33 @@ Desktop::_SetWorkspace(int32 index)
dirty.Include(&window->VisibleRegion());
}
// Catch order changes in the new workspaces window list
int32 i = 0;
for (WindowLayer* window = windows.FirstWindow(); window != NULL;
window = window->NextWindow(kWorkingList), i++) {
BRegion* region = (BRegion*)previousRegions.ItemAt(i);
region->ExclusiveInclude(&window->VisibleRegion());
dirty.Include(region);
delete region;
}
// Set new focus to the front window, but keep focus to a floating
// window if still visible
if (!_Windows(index).HasWindow(FocusWindow()) || !FocusWindow()->IsFloating())
SetFocusWindow(FrontWindow());
_WindowChanged(NULL);
_WindowChanged(NULL);
MarkDirty(dirty);
#if 0
// Show the dirty regions of this workspace switch
if (GetDrawingEngine()->LockParallelAccess()) {
GetDrawingEngine()->FillRegion(dirty, (rgb_color){255, 0, 0});
GetDrawingEngine()->UnlockParallelAccess();
snooze(100000);
}
#endif
if (previousColor != fWorkspaces[fCurrentWorkspace].Color())
RedrawBackground();
}