diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 3d507241c0..1009a2a039 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -802,7 +802,7 @@ Desktop::WriteWindowList(team_id team, BPrivate::LinkSender& sender) // write list - sender.StartMessage(SERVER_TRUE); + sender.StartMessage(B_OK); sender.Attach(count); for (int32 i = 0; i < fWindowLayerList.CountItems(); i++) { diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index 34ffa5fa0a..1f2b6c564b 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -19,6 +19,7 @@ #include "DesktopSettings.h" #include "MessageLooper.h" #include "Workspace.h" +#include "WorkspacePrivate.h" #include #include @@ -81,7 +82,7 @@ class Desktop : public MessageLooper, public ScreenOwner { void SetWorkspace(int32 index); int32 CurrentWorkspace() { return fCurrentWorkspace; } - ::Workspace& WorkspaceAt(int32 index) + Workspace::Private& WorkspaceAt(int32 index) { return fWorkspaces[index]; } // WindowLayer methods @@ -136,7 +137,7 @@ class Desktop : public MessageLooper, public ScreenOwner { sem_id fShutdownSemaphore; int32 fShutdownCount; - ::Workspace fWorkspaces[32];//kMaxWorkspaces]; + ::Workspace::Private fWorkspaces[32]; int32 fCurrentWorkspace; BObjectList fWindowLayerList; diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index e1447f9c81..5053ba1600 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -24,7 +24,7 @@ #include "ServerScreen.h" #include "ServerWindow.h" #include "WindowLayer.h" -#include "Workspace.h" +#include "WorkspacePrivate.h" #include "WorkspacesLayer.h" #include @@ -361,7 +361,7 @@ RootLayer::RemoveWindowLayer(WindowLayer* windowLayer) void -RootLayer::_UpdateWorkspace(Workspace& workspace) +RootLayer::_UpdateWorkspace(Workspace::Private& workspace) { fColor = workspace.Color(); @@ -372,8 +372,8 @@ RootLayer::_UpdateWorkspace(Workspace& workspace) void -RootLayer::SetWorkspace(int32 index, Workspace& previousWorkspace, - Workspace& workspace) +RootLayer::SetWorkspace(int32 index, Workspace::Private& previousWorkspace, + Workspace::Private& workspace) { BAutolock _(fAllRegionsLock); diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index b5648f04a9..8f82a6aeba 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -62,8 +62,9 @@ class RootLayer : public Layer { WindowLayer* Front() const { return fFront; } WindowLayer* Back() const { return fBack; } - void SetWorkspace(int32 index, Workspace& previousWorkspace, - Workspace& workspace); + void SetWorkspace(int32 index, + Workspace::Private& previousWorkspace, + Workspace::Private& workspace); void SetDragMessage(BMessage *msg); BMessage* DragMessage() const; @@ -104,7 +105,7 @@ class RootLayer : public Layer { void _UpdateFronts(); void _WindowsChanged(BRegion& region); - void _UpdateWorkspace(Workspace& workspace); + void _UpdateWorkspace(Workspace::Private& workspace); Desktop* fDesktop; BMessage* fDragMessage; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 57eb50b4ed..7a4a98a767 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -2189,7 +2189,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (index >= (uint32)kMaxWorkspaces) index = fDesktop->CurrentWorkspace(); - Workspace& workspace = fDesktop->WorkspaceAt(index); + Workspace workspace(*fDesktop, index); fLink.Attach(workspace.Color().GetColor32()); fDesktop->Unlock(); diff --git a/src/servers/app/Workspace.cpp b/src/servers/app/Workspace.cpp index f195a00ae0..8c7c2090d8 100644 --- a/src/servers/app/Workspace.cpp +++ b/src/servers/app/Workspace.cpp @@ -20,7 +20,7 @@ static RGBColor kDefaultColor = RGBColor(51, 102, 152); const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY); -Workspace::Workspace() +Workspace::Private::Private() : fWindows(20, true) // this list owns its items @@ -29,13 +29,13 @@ Workspace::Workspace() } -Workspace::~Workspace() +Workspace::Private::~Private() { } bool -Workspace::AddWindow(WindowLayer* window, BPoint* position) +Workspace::Private::AddWindow(WindowLayer* window, BPoint* position) { window_layer_info* info = new (nothrow) window_layer_info; if (info == NULL) @@ -53,7 +53,7 @@ Workspace::AddWindow(WindowLayer* window, BPoint* position) void -Workspace::RemoveWindow(WindowLayer* window) +Workspace::Private::RemoveWindow(WindowLayer* window) { for (int32 i = fWindows.CountItems(); i-- > 0;) { window_layer_info* info = fWindows.ItemAt(i); @@ -68,7 +68,7 @@ Workspace::RemoveWindow(WindowLayer* window) void -Workspace::RemoveWindowAt(int32 index) +Workspace::Private::RemoveWindowAt(int32 index) { window_layer_info* info = fWindows.RemoveItemAt(index); delete info; @@ -76,33 +76,95 @@ Workspace::RemoveWindowAt(int32 index) void -Workspace::SetDisplaysFromDesktop(Desktop* desktop) +Workspace::Private::SetDisplaysFromDesktop(Desktop* desktop) { } void -Workspace::SetColor(const RGBColor& color) +Workspace::Private::SetColor(const RGBColor& color) { fColor = color; } void -Workspace::SetSettings(BMessage& settings) +Workspace::Private::SetSettings(BMessage& settings) { } void -Workspace::GetSettings(BMessage& settings) +Workspace::Private::GetSettings(BMessage& settings) { } void -Workspace::_SetDefaults() +Workspace::Private::_SetDefaults() { fColor.SetColor(kDefaultColor); } + +// #pragma mark - + + +Workspace::Workspace(Desktop& desktop, int32 index) + : + fWorkspace(desktop.WorkspaceAt(index)), + fDesktop(desktop), + fCurrentWorkspace(index == desktop.CurrentWorkspace()) +{ + fDesktop.Lock(); + RewindWindows(); +} + + +Workspace::~Workspace() +{ + fDesktop.Unlock(); +} + + +const RGBColor& +Workspace::Color() const +{ + return fWorkspace.Color(); +} + + +status_t +Workspace::GetNextWindow(WindowLayer*& _window, BPoint& _leftTop) +{ + if (fCurrentWorkspace) { + if (fCurrent == NULL) + fCurrent = (WindowLayer*)fDesktop.RootLayer()->FirstChild(); + else + fCurrent = (WindowLayer*)fCurrent->NextLayer(); + + if (fCurrent == NULL) + return B_ENTRY_NOT_FOUND; + + _window = fCurrent; + _leftTop = fCurrent->Frame().LeftTop(); + return B_OK; + } + + window_layer_info* info = fWorkspace.WindowAt(fIndex++); + if (info == NULL) + return B_ENTRY_NOT_FOUND; + + _window = info->window; + _leftTop = info->position; + return B_OK; +} + + +void +Workspace::RewindWindows() +{ + fIndex = 0; + fCurrent = NULL; +} + diff --git a/src/servers/app/Workspace.h b/src/servers/app/Workspace.h index 7b32a90a98..c16197a1d1 100644 --- a/src/servers/app/Workspace.h +++ b/src/servers/app/Workspace.h @@ -9,66 +9,35 @@ #define WORKSPACE_H -#include "RGBColor.h" - -#include -#include +#include +class Desktop; +class RGBColor; class RootLayer; class WindowLayer; -struct display_info { - BString identifier; - BPoint origin; - display_mode mode; -}; - -struct window_layer_info { - BPoint position; - WindowLayer* window; -}; - class Workspace { public: - Workspace(); + Workspace(Desktop& desktop, int32 index); ~Workspace(); - bool AddWindow(WindowLayer* window, BPoint* point = NULL); - void RemoveWindow(WindowLayer* window); - void RemoveWindowAt(int32 index); + const RGBColor& Color() const; + bool IsCurrent() const + { return fCurrentWorkspace; } - int32 CountWindows() const { return fWindows.CountItems(); } - window_layer_info* WindowAt(int32 index) const { return fWindows.ItemAt(index); } + status_t GetNextWindow(WindowLayer*& _window, BPoint& _leftTop); + void RewindWindows(); - // displays - - void SetDisplaysFromDesktop(Desktop* desktop); - - int32 CountDisplays() const { return fDisplays.CountItems(); } - const display_info* DisplayAt(int32 index) const { return fDisplays.ItemAt(index); } - - // configuration - - const RGBColor& Color() const { return fColor; } - void SetColor(const RGBColor& color); - - void SetSettings(BMessage& settings); - void GetSettings(BMessage& settings); + class Private; private: - void _SetDefaults(); - - BObjectList fWindows; - WindowLayer* fFront; - WindowLayer* fFocus; - - BObjectList fDisplays; - - RGBColor fColor; + Workspace::Private& fWorkspace; + Desktop& fDesktop; + int32 fIndex; + WindowLayer* fCurrent; + bool fCurrentWorkspace; }; -extern const BPoint kInvalidWindowPosition; - #endif /* WORKSPACE_H */ diff --git a/src/servers/app/WorkspacePrivate.h b/src/servers/app/WorkspacePrivate.h new file mode 100644 index 0000000000..3fa2846013 --- /dev/null +++ b/src/servers/app/WorkspacePrivate.h @@ -0,0 +1,75 @@ +/* + * Copyright 2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef WORKSPACE_PRIVATE_H +#define WORKSPACE_PRIVATE_H + + +#include "RGBColor.h" +#include "Workspace.h" + +#include +#include + + +class RootLayer; +class WindowLayer; + + +struct display_info { + BString identifier; + BPoint origin; + display_mode mode; +}; + +struct window_layer_info { + BPoint position; + WindowLayer* window; +}; + +class Workspace::Private { + public: + Private(); + ~Private(); + + bool AddWindow(WindowLayer* window, BPoint* point = NULL); + void RemoveWindow(WindowLayer* window); + void RemoveWindowAt(int32 index); + + int32 CountWindows() const { return fWindows.CountItems(); } + window_layer_info* WindowAt(int32 index) const { return fWindows.ItemAt(index); } + + // displays + + void SetDisplaysFromDesktop(Desktop* desktop); + + int32 CountDisplays() const { return fDisplays.CountItems(); } + const display_info* DisplayAt(int32 index) const { return fDisplays.ItemAt(index); } + + // configuration + + const RGBColor& Color() const { return fColor; } + void SetColor(const RGBColor& color); + + void SetSettings(BMessage& settings); + void GetSettings(BMessage& settings); + + private: + void _SetDefaults(); + + BObjectList fWindows; + WindowLayer* fFront; + WindowLayer* fFocus; + + BObjectList fDisplays; + + RGBColor fColor; +}; + +extern const BPoint kInvalidWindowPosition; + +#endif /* WORKSPACE_PRIVATE_H */ diff --git a/src/servers/app/WorkspacesLayer.cpp b/src/servers/app/WorkspacesLayer.cpp index 123fbf41d8..5f5408258a 100644 --- a/src/servers/app/WorkspacesLayer.cpp +++ b/src/servers/app/WorkspacesLayer.cpp @@ -76,9 +76,11 @@ WorkspacesLayer::_WorkspaceAt(int32 i) BRect WorkspacesLayer::_WindowFrame(const BRect& workspaceFrame, - const BRect& screenFrame, const BRect& windowFrame) + const BRect& screenFrame, const BRect& windowFrame, + BPoint windowPosition) { BRect frame = windowFrame; + frame.OffsetTo(windowPosition); float factor = workspaceFrame.Width() / screenFrame.Width(); frame.left = rintf(frame.left * factor); @@ -95,15 +97,18 @@ WorkspacesLayer::_WindowFrame(const BRect& workspaceFrame, void WorkspacesLayer::_DrawWindow(const BRect& workspaceFrame, - const BRect& screenFrame, WindowLayer* window, + const BRect& screenFrame, WindowLayer* window, BPoint windowPosition, BRegion& backgroundRegion, bool active) { if (window->Feel() == kDesktopWindowFeel) return; - BRect frame = _WindowFrame(workspaceFrame, screenFrame, window->Frame()); - BRect tabFrame = _WindowFrame(workspaceFrame, screenFrame, - window->GetDecorator()->GetTabRect()); + BPoint offset = window->Frame().LeftTop() - windowPosition; + BRect frame = _WindowFrame(workspaceFrame, screenFrame, window->Frame(), + windowPosition); + BRect tabFrame = window->GetDecorator()->GetTabRect(); + tabFrame = _WindowFrame(workspaceFrame, screenFrame, + tabFrame, tabFrame.LeftTop() - offset); // ToDo: let decorator do this! RGBColor yellow = window->GetDecorator()->GetColors().window_tab; @@ -141,56 +146,46 @@ WorkspacesLayer::_DrawWorkspace(int32 index) { BRect rect = _WorkspaceAt(index); - Workspace* workspace = NULL; - bool active = index == Window()->Desktop()->CurrentWorkspace(); + Workspace workspace(*Window()->Desktop(), index); + bool active = workspace.IsCurrent(); if (active) { // draw active frame RGBColor black(0, 0, 0); GetDrawingEngine()->StrokeRect(rect, black); } - // draw background - rect.InsetBy(1, 1); - RGBColor color; - // ToDo: fix me - workspaces must always exist, not only on first visit! - if (workspace != NULL) - color = workspace->Color(); - else - color.SetColor(51, 102, 152); - - if (!active) { + RGBColor color = workspace.Color(); + if (!active) _DarkenColor(color); - } // draw windows BRegion backgroundRegion = VisibleRegion(); - // ToDo: would be nice to get the real update region here + // ToDo: would be nice to get the real update region here - if (workspace != NULL) { - WindowLayer* windows[256]; - int32 count = 0; -// if (!workspace->GetWindowLayerList((void **)&windows, &count)) -// return; + uint16 width, height; + uint32 colorSpace; + float frequency; + Window()->Desktop()->ScreenAt(0)->GetMode(width, height, + colorSpace, frequency); + BRect screenFrame(0, 0, width - 1, height - 1); - uint16 width, height; - uint32 colorSpace; - float frequency; - GetRootLayer()->GetDesktop()->ScreenAt(0)->GetMode(width, height, colorSpace, frequency); - BRect screenFrame(0, 0, width - 1, height - 1); + BRegion workspaceRegion(rect); + backgroundRegion.IntersectWith(&workspaceRegion); + GetDrawingEngine()->ConstrainClippingRegion(&backgroundRegion); - BRegion workspaceRegion(rect); - backgroundRegion.IntersectWith(&workspaceRegion); - GetDrawingEngine()->ConstrainClippingRegion(&backgroundRegion); - - for (int32 i = count; i-- > 0;) { - _DrawWindow(rect, screenFrame, windows[i], backgroundRegion, active); - } + WindowLayer* window; + BPoint leftTop; + while (workspace.GetNextWindow(window, leftTop) == B_OK) { + _DrawWindow(rect, screenFrame, window, leftTop, + backgroundRegion, active); } + // draw background + GetDrawingEngine()->ConstrainClippingRegion(&backgroundRegion); GetDrawingEngine()->FillRect(rect, color); @@ -245,14 +240,28 @@ WorkspacesLayer::Draw(const BRect& updateRect) // draw workspaces - int32 count; - { - DesktopSettings settings(Window()->Desktop()); - count = settings.WorkspacesCount(); - } - - for (int32 i = 0; i < count; i++) { + for (int32 i = rows * columns; i-- > 0;) { _DrawWorkspace(i); } } + +void +WorkspacesLayer::MouseDown(BMessage* message, BPoint where, int32* _viewToken) +{ + int32 columns, rows; + _GetGrid(columns, rows); + + for (int32 i = columns * rows; i-- > 0;) { + BRect rect = _WorkspaceAt(i); + + if (rect.Contains(where)) { + Window()->Desktop()->SetWorkspace(i); + break; + } + } + + Layer::MouseDown(message, where, _viewToken); +} + + diff --git a/src/servers/app/WorkspacesLayer.h b/src/servers/app/WorkspacesLayer.h index 24f27d608c..b86c4c0ae0 100644 --- a/src/servers/app/WorkspacesLayer.h +++ b/src/servers/app/WorkspacesLayer.h @@ -21,16 +21,19 @@ class WorkspacesLayer : public Layer { virtual ~WorkspacesLayer(); virtual void Draw(const BRect& updateRect); + virtual void MouseDown(BMessage* message, BPoint where, int32* _viewToken); private: void _GetGrid(int32& columns, int32& rows); BRect _WorkspaceAt(int32 i); BRect _WindowFrame(const BRect& workspaceFrame, - const BRect& screenFrame, const BRect& windowFrame); + const BRect& screenFrame, const BRect& windowFrame, + BPoint windowPosition); void _DrawWindow(const BRect& workspaceFrame, const BRect& screenFrame, WindowLayer* window, - BRegion& backgroundRegion, bool active); + BPoint windowPosition, BRegion& backgroundRegion, + bool active); void _DrawWorkspace(int32 index); void _DarkenColor(RGBColor& color) const;