From 5712a788a13e2ac876f1374860801920a638dd29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 1 Jul 2005 07:58:22 +0000 Subject: [PATCH] WorkspacesLayer now makes use of DisplayDriver::ConstrainClippingRegion() in order to flicker less (which works, but it's not really that nice yet, as it currently only works for the background). The workspaces layer is now also invalidated if a new window appears on the screen or goes away (also when this happens in another workspace). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13379 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/RootLayer.cpp | 14 ++++++- src/servers/app/WorkspacesLayer.cpp | 64 ++++++++++++++++++----------- src/servers/app/WorkspacesLayer.h | 3 +- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index e5ca708798..c36d1ec49d 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -1996,9 +1996,14 @@ RootLayer::show_winBorder(WinBorder *winBorder) if (invalidate) show_final_scene(exFocus, exActive); + + if (WorkspacesLayer()) + GoRedraw(WorkspacesLayer(), fFullVisible); } -void RootLayer::hide_winBorder(WinBorder *winBorder) + +void +RootLayer::hide_winBorder(WinBorder *winBorder) { bool invalidate = false; bool invalid; @@ -2024,9 +2029,14 @@ void RootLayer::hide_winBorder(WinBorder *winBorder) if (invalidate) show_final_scene(exFocus, exActive); + + if (WorkspacesLayer()) + GoRedraw(WorkspacesLayer(), fFullVisible); } -void RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel) + +void +RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel) { bool isVisible = false; bool wasVisibleInActiveWorkspace = false; diff --git a/src/servers/app/WorkspacesLayer.cpp b/src/servers/app/WorkspacesLayer.cpp index 6f8b06ee31..167d14c827 100644 --- a/src/servers/app/WorkspacesLayer.cpp +++ b/src/servers/app/WorkspacesLayer.cpp @@ -76,12 +76,12 @@ WorkspacesLayer::_WindowFrame(const BRect& workspaceFrame, BRect frame = windowFrame; float factor = workspaceFrame.Width() / screenFrame.Width(); - frame.left *= factor; - frame.right *= factor; + frame.left = rintf(frame.left * factor); + frame.right = rintf(frame.right * factor); factor = workspaceFrame.Height() / screenFrame.Height(); - frame.top *= factor; - frame.bottom *= factor; + frame.top = rintf(frame.top * factor); + frame.bottom = rintf(frame.bottom * factor); frame.OffsetBy(workspaceFrame.LeftTop()); return frame; @@ -90,7 +90,8 @@ WorkspacesLayer::_WindowFrame(const BRect& workspaceFrame, void WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame, - const BRect& screenFrame, WinBorder* window) + const BRect& screenFrame, WinBorder* window, + BRegion& backgroundRegion) { BRect frame = _WindowFrame(workspaceFrame, screenFrame, window->Frame()); BRect tabFrame = _WindowFrame(workspaceFrame, screenFrame, @@ -99,8 +100,18 @@ WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame, // ToDo: let decorator do this! RGBColor yellow = window->GetDecorator()->GetColors().window_tab; - fDriver->StrokeLine(BPoint(tabFrame.left, frame.top - 1), - BPoint(tabFrame.right, frame.top - 1), yellow); + if (tabFrame.left < frame.left) + tabFrame.left = frame.left; + if (tabFrame.right >= frame.right) + tabFrame.right = frame.right - 1; + + tabFrame.top = frame.top - 1; + tabFrame.bottom = frame.top - 1; + + backgroundRegion.Exclude(tabFrame); + backgroundRegion.Exclude(frame); + + fDriver->StrokeLine(tabFrame.LeftTop(), tabFrame.RightBottom(), yellow); RGBColor gray(180, 180, 180); fDriver->StrokeRect(frame, gray); @@ -134,28 +145,35 @@ WorkspacesLayer::_DrawWorkspace(int32 index) else color.SetColor(51, 102, 152); - fDriver->FillRect(rect, color); - - if (workspace == NULL) - return; - // draw windows - WinBorder* windows[256]; - int32 count = 256; - if (!workspace->GetWinBorderList((void **)&windows, &count)) - return; + BRegion backgroundRegion = fVisible; + // ToDo: would be nice to get the real update region here - uint16 width, height; - uint32 colorSpace; - float frequency; - gDesktop->ScreenAt(0)->GetMode(width, height, colorSpace, frequency); + if (workspace != NULL) { + WinBorder* windows[256]; + int32 count = 256; + if (!workspace->GetWinBorderList((void **)&windows, &count)) + return; - BRect screenFrame(0, 0, width - 1, height - 1); + uint16 width, height; + uint32 colorSpace; + float frequency; + gDesktop->ScreenAt(0)->GetMode(width, height, colorSpace, frequency); + BRect screenFrame(0, 0, width - 1, height - 1); - for (int32 i = count; i-- > 0;) { - _DrawWindow(rect, screenFrame, windows[i]); + BRegion workspaceRegion(rect); + backgroundRegion.IntersectWith(&workspaceRegion); + fDriver->ConstrainClippingRegion(&backgroundRegion); + + for (int32 i = count; i-- > 0;) { + _DrawWindow(rect, screenFrame, windows[i], backgroundRegion); + } } + + fDriver->ConstrainClippingRegion(&backgroundRegion); + fDriver->FillRect(rect, color); + fDriver->ConstrainClippingRegion(&fVisible); } diff --git a/src/servers/app/WorkspacesLayer.h b/src/servers/app/WorkspacesLayer.h index d5e5dcd73b..0f59b895db 100644 --- a/src/servers/app/WorkspacesLayer.h +++ b/src/servers/app/WorkspacesLayer.h @@ -29,7 +29,8 @@ class WorkspacesLayer : public Layer { const BRect& screenFrame, const BRect& windowFrame); void _DrawWindow(const BRect& workspaceFrame, - const BRect& screenFrame, WinBorder* window); + const BRect& screenFrame, WinBorder* window, + BRegion& backgroundRegion); void _DrawWorkspace(int32 index); };