* The Desktop is now maintaining a list of workspaces views, and supports

more than one of them at the time.
* Changed ViewLayer::FindView() to FindViews() that collects all views
  with the given flag set, not just the first one.
* Made ViewLayer::AttachedToWindow() and DetachFromWindow() virtual,
  WorkspacesLayer now overloads them to register itself with the window and
  the desktop.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24300 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-03-08 11:42:20 +00:00
parent e0d6d2fe80
commit 2c184b20ed
9 changed files with 173 additions and 77 deletions
+54 -10
View File
@@ -317,7 +317,7 @@ Desktop::Desktop(uid_t userID)
fAllWindows(kAllWindowList), fAllWindows(kAllWindowList),
fSubsetWindows(kSubsetList), fSubsetWindows(kSubsetList),
fFocusList(kFocusList), fFocusList(kFocusList),
fWorkspacesLayer(NULL), fWorkspacesViews(false),
fActiveScreen(NULL), fActiveScreen(NULL),
fWindowLock("window lock"), fWindowLock("window lock"),
@@ -1255,10 +1255,49 @@ Desktop::_WindowHasModal(WindowLayer* window)
void void
Desktop::_WindowChanged(WindowLayer* window) Desktop::_WindowChanged(WindowLayer* window)
{ {
if (fWorkspacesLayer == NULL) for (uint32 i = fWorkspacesViews.CountItems(); i-- > 0;) {
WorkspacesLayer* view = fWorkspacesViews.ItemAt(i);
view->WindowChanged(window);
}
}
/*!
You must at least hold a single window lock when calling this method.
*/
void
Desktop::_WindowRemoved(WindowLayer* window)
{
for (uint32 i = fWorkspacesViews.CountItems(); i-- > 0;) {
WorkspacesLayer* view = fWorkspacesViews.ItemAt(i);
view->WindowRemoved(window);
}
}
void
Desktop::AddWorkspacesView(WorkspacesLayer* view)
{
if (view->Window() == NULL || view->Window()->IsHidden())
return; return;
fWorkspacesLayer->WindowChanged(window); if (!LockAllWindows())
return;
if (!fWorkspacesViews.HasItem(view))
fWorkspacesViews.AddItem(view);
UnlockAllWindows();
}
void
Desktop::RemoveWorkspacesView(WorkspacesLayer* view)
{
if (!LockAllWindows())
return;
fWorkspacesViews.RemoveItem(view);
UnlockAllWindows();
} }
@@ -1621,10 +1660,9 @@ Desktop::ShowWindow(WindowLayer* window)
return; return;
} }
if ((window->Flags() & kWorkspacesWindowFlag) != 0) { if (window->HasWorkspacesViews()) {
// find workspaces layer in view hierarchy // find workspaces layer in view hierarchy
fWorkspacesLayer = dynamic_cast<WorkspacesLayer*>( window->FindWorkspacesViews(fWorkspacesViews);
window->TopLayer()->FindView(kWorkspacesViewFlag));
} }
UnlockAllWindows(); UnlockAllWindows();
@@ -1662,11 +1700,17 @@ Desktop::HideWindow(WindowLayer* window)
} else } else
_WindowChanged(window); _WindowChanged(window);
if (fWorkspacesLayer != NULL) _WindowRemoved(window);
fWorkspacesLayer->WindowRemoved(window);
if ((window->Flags() & kWorkspacesWindowFlag) != 0) if (window->HasWorkspacesViews()) {
fWorkspacesLayer = NULL; // remove workspaces views from this window
BObjectList<WorkspacesLayer> list(false);
window->FindWorkspacesViews(list);
while (WorkspacesLayer* view = list.RemoveItemAt(0)) {
fWorkspacesViews.RemoveItem(view);
}
}
UnlockAllWindows(); UnlockAllWindows();
+5 -1
View File
@@ -181,6 +181,9 @@ class Desktop : public MessageLooper, public ScreenOwner {
void RedrawBackground(); void RedrawBackground();
void StoreWorkspaceConfiguration(int32 index); void StoreWorkspaceConfiguration(int32 index);
void AddWorkspacesView(WorkspacesLayer* view);
void RemoveWorkspacesView(WorkspacesLayer* view);
void MinimizeApplication(team_id team); void MinimizeApplication(team_id team);
void BringApplicationToFront(team_id team); void BringApplicationToFront(team_id team);
void WindowAction(int32 windowToken, int32 action); void WindowAction(int32 windowToken, int32 action);
@@ -220,6 +223,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
bool _WindowHasModal(WindowLayer* window); bool _WindowHasModal(WindowLayer* window);
void _WindowChanged(WindowLayer* window); void _WindowChanged(WindowLayer* window);
void _WindowRemoved(WindowLayer* window);
void _GetLooperName(char* name, size_t size); void _GetLooperName(char* name, size_t size);
void _PrepareQuit(); void _PrepareQuit();
@@ -254,7 +258,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
WindowList fAllWindows; WindowList fAllWindows;
WindowList fSubsetWindows; WindowList fSubsetWindows;
WindowList fFocusList; WindowList fFocusList;
WorkspacesLayer* fWorkspacesLayer; BObjectList<WorkspacesLayer> fWorkspacesViews;
Screen* fActiveScreen; Screen* fActiveScreen;
+1 -4
View File
@@ -562,10 +562,7 @@ ServerWindow::_CreateLayerTree(BPrivate::LinkReceiver &link, ViewLayer **_parent
ViewLayer* newLayer; ViewLayer* newLayer;
if ((fWindowLayer->Flags() & kWorkspacesWindowFlag) != 0 if ((flags & kWorkspacesViewFlag) != 0) {
&& (flags & kWorkspacesViewFlag) != 0) {
// TODO: there can currently only be one of these views per desktop!
// TODO: get rid of the kWorkspacesWindowFlag
newLayer = new (nothrow) WorkspacesLayer(frame, scrollingOffset, name, newLayer = new (nothrow) WorkspacesLayer(frame, scrollingOffset, name,
token, resizeMask, flags); token, resizeMask, flags);
} else { } else {
+13 -12
View File
@@ -206,9 +206,9 @@ ViewLayer::AddChild(ViewLayer* layer)
printf("ViewLayer::AddChild() - ViewLayer already has a parent\n"); printf("ViewLayer::AddChild() - ViewLayer already has a parent\n");
return; return;
} }
layer->fParent = this; layer->fParent = this;
if (!fLastChild) { if (!fLastChild) {
// no children yet // no children yet
fFirstChild = layer; fFirstChild = layer;
@@ -376,19 +376,20 @@ ViewLayer::MarkAt(DrawingEngine* engine, const BPoint& where, int32 level)
#endif #endif
ViewLayer* void
ViewLayer::FindView(uint32 flags) ViewLayer::FindViews(uint32 flags, BObjectList<ViewLayer>& list, int32& left)
{ {
if ((Flags() & flags) == flags) if ((Flags() & flags) == flags) {
return this; list.AddItem(this);
left--;
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) { return;
ViewLayer* layer = child->FindView(flags);
if (layer != NULL)
return layer;
} }
return NULL; for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
child->FindViews(flags, list, left);
if (left == 0)
break;
}
} }
+5 -3
View File
@@ -16,6 +16,7 @@
#include "IntRect.h" #include "IntRect.h"
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
#include <ObjectList.h>
#include <Region.h> #include <Region.h>
#include <String.h> #include <String.h>
@@ -76,8 +77,8 @@ class ViewLayer {
// clips to each views bounds // clips to each views bounds
void ConvertToVisibleInTopView(IntRect* bounds) const; void ConvertToVisibleInTopView(IntRect* bounds) const;
void AttachedToWindow(WindowLayer* window); virtual void AttachedToWindow(WindowLayer* window);
void DetachedFromWindow(); virtual void DetachedFromWindow();
WindowLayer* Window() const { return fWindow; } WindowLayer* Window() const { return fWindow; }
// tree stuff // tree stuff
@@ -100,7 +101,8 @@ class ViewLayer {
uint32 CountChildren(bool deep = false) const; uint32 CountChildren(bool deep = false) const;
void CollectTokensForChildren(BList* tokenMap) const; void CollectTokensForChildren(BList* tokenMap) const;
ViewLayer* FindView(uint32 flags); void FindViews(uint32 flags,
BObjectList<ViewLayer>& list, int32& left);
ViewLayer* ViewAt(const BPoint& where); ViewLayer* ViewAt(const BPoint& where);
+15 -1
View File
@@ -25,6 +25,7 @@
#include "Workspace.h" #include "Workspace.h"
#include "WorkspacesLayer.h" #include "WorkspacesLayer.h"
#include <ViewPrivate.h>
#include <WindowPrivate.h> #include <WindowPrivate.h>
#include <Debug.h> #include <Debug.h>
@@ -126,7 +127,9 @@ WindowLayer::WindowLayer(const BRect& frame, const char *name,
fMinWidth(1), fMinWidth(1),
fMaxWidth(32768), fMaxWidth(32768),
fMinHeight(1), fMinHeight(1),
fMaxHeight(32768) fMaxHeight(32768),
fWorkspacesViewCount(0)
{ {
// make sure our arguments are valid // make sure our arguments are valid
if (!IsValidLook(fLook)) if (!IsValidLook(fLook))
@@ -1525,6 +1528,17 @@ WindowLayer::HasInSubset(const WindowLayer* window) const
} }
/*! \brief Collects all workspaces views in this window and puts it into \a list
*/
void
WindowLayer::FindWorkspacesViews(BObjectList<WorkspacesLayer>& list) const
{
int32 count = fWorkspacesViewCount;
TopLayer()->FindViews(kWorkspacesViewFlag, (BObjectList<ViewLayer>&)list,
count);
}
/*! \brief Returns on which workspaces the window should be visible. /*! \brief Returns on which workspaces the window should be visible.
A modal or floating window may be visible on a workscreen if one A modal or floating window may be visible on a workscreen if one
+22 -10
View File
@@ -1,11 +1,12 @@
/* /*
* Copyright (c) 2001-2006, Haiku, Inc. * Copyright (c) 2001-2008, Haiku, Inc.
* Distributed under the terms of the MIT license. * Distributed under the terms of the MIT license.
* *
* Author: DarkWyrm <bpmagic@columbus.rr.com> * Authors:
* Adi Oanca <adioanca@gmail.com> * DarkWyrm <bpmagic@columbus.rr.com>
* Stephan Aßmus <superstippi@gmx.de> * Adi Oanca <adioanca@gmail.com>
* Axel Dörfler, axeld@pinc-software.de * Stephan Aßmus <superstippi@gmx.de>
* Axel Dörfler, axeld@pinc-software.de
*/ */
#ifndef WINDOW_LAYER_H #ifndef WINDOW_LAYER_H
#define WINDOW_LAYER_H #define WINDOW_LAYER_H
@@ -30,7 +31,7 @@ class Decorator;
class Desktop; class Desktop;
class DrawingEngine; class DrawingEngine;
class EventDispatcher; class EventDispatcher;
class WindowLayer; class WorkspacesLayer;
// TODO: move this into a proper place // TODO: move this into a proper place
#define AS_REDRAW 'rdrw' #define AS_REDRAW 'rdrw'
@@ -41,7 +42,7 @@ enum {
}; };
class WindowLayer { class WindowLayer {
public: public:
WindowLayer(const BRect& frame, WindowLayer(const BRect& frame,
const char *name, window_look look, const char *name, window_look look,
window_feel feel, uint32 flags, window_feel feel, uint32 flags,
@@ -208,6 +209,15 @@ class WindowLayer {
bool SameSubset(WindowLayer* window); bool SameSubset(WindowLayer* window);
uint32 SubsetWorkspaces() const; uint32 SubsetWorkspaces() const;
bool HasWorkspacesViews() const
{ return fWorkspacesViewCount != 0; }
void AddWorkspacesView()
{ fWorkspacesViewCount++; }
void RemoveWorkspacesView()
{ fWorkspacesViewCount--; }
void FindWorkspacesViews(
BObjectList<WorkspacesLayer>& list) const;
static bool IsValidLook(window_look look); static bool IsValidLook(window_look look);
static bool IsValidFeel(window_feel feel); static bool IsValidFeel(window_feel feel);
static bool IsModalFeel(window_feel feel); static bool IsModalFeel(window_feel feel);
@@ -216,7 +226,7 @@ class WindowLayer {
static uint32 ValidWindowFlags(); static uint32 ValidWindowFlags();
static uint32 ValidWindowFlags(window_feel feel); static uint32 ValidWindowFlags(window_feel feel);
protected: protected:
friend class Desktop; friend class Desktop;
// TODO: for now (list management) // TODO: for now (list management)
@@ -298,7 +308,7 @@ class WindowLayer {
// redraw requests from the Desktop will go // redraw requests from the Desktop will go
// into the pending update session. // into the pending update session.
class UpdateSession { class UpdateSession {
public: public:
UpdateSession(); UpdateSession();
virtual ~UpdateSession(); virtual ~UpdateSession();
@@ -320,7 +330,7 @@ class WindowLayer {
inline bool IsRequest() const inline bool IsRequest() const
{ return fCause & UPDATE_REQUEST; } { return fCause & UPDATE_REQUEST; }
private: private:
BRegion fDirtyRegion; BRegion fDirtyRegion;
bool fInUse; bool fInUse;
uint8 fCause; uint8 fCause;
@@ -352,6 +362,8 @@ class WindowLayer {
int32 fMaxWidth; int32 fMaxWidth;
int32 fMinHeight; int32 fMinHeight;
int32 fMaxHeight; int32 fMaxHeight;
int32 fWorkspacesViewCount;
}; };
#endif // WINDOW_LAYER_H #endif // WINDOW_LAYER_H
+21 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2007, Haiku Inc. * Copyright 2005-2008, Haiku Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -33,7 +33,26 @@ WorkspacesLayer::WorkspacesLayer(BRect frame, BPoint scrollingOffset,
WorkspacesLayer::~WorkspacesLayer() WorkspacesLayer::~WorkspacesLayer()
{ {
// TODO: we actually need to tell the Desktop that we're gone }
void
WorkspacesLayer::AttachedToWindow(WindowLayer* window)
{
ViewLayer::AttachedToWindow(window);
window->AddWorkspacesView();
window->Desktop()->AddWorkspacesView(this);
}
void
WorkspacesLayer::DetachedFromWindow()
{
fWindow->Desktop()->RemoveWorkspacesView(this);
fWindow->RemoveWorkspacesView();
ViewLayer::DetachedFromWindow();
} }
+37 -34
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2006, Haiku Inc. * Copyright 2005-2008, Haiku Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -15,47 +15,50 @@ class WindowLayer;
class WorkspacesLayer : public ViewLayer { class WorkspacesLayer : public ViewLayer {
public: public:
WorkspacesLayer(BRect frame, BPoint scrollingOffset, const char* name, WorkspacesLayer(BRect frame, BPoint scrollingOffset,
int32 token, uint32 resize, uint32 flags); const char* name, int32 token, uint32 resize,
virtual ~WorkspacesLayer(); uint32 flags);
virtual ~WorkspacesLayer();
virtual void Draw(DrawingEngine* drawingEngine, virtual void AttachedToWindow(WindowLayer* window);
virtual void DetachedFromWindow();
virtual void Draw(DrawingEngine* drawingEngine,
BRegion* effectiveClipping, BRegion* effectiveClipping,
BRegion* windowContentClipping, BRegion* windowContentClipping, bool deep = false);
bool deep = false);
virtual void MouseDown(BMessage* message, BPoint where); virtual void MouseDown(BMessage* message, BPoint where);
virtual void MouseUp(BMessage* message, BPoint where); virtual void MouseUp(BMessage* message, BPoint where);
virtual void MouseMoved(BMessage* message, BPoint where); virtual void MouseMoved(BMessage* message, BPoint where);
void WindowChanged(WindowLayer* window); void WindowChanged(WindowLayer* window);
void WindowRemoved(WindowLayer* window); void WindowRemoved(WindowLayer* window);
private: private:
void _GetGrid(int32& columns, int32& rows); void _GetGrid(int32& columns, int32& rows);
BRect _ScreenFrame(int32 index); BRect _ScreenFrame(int32 index);
BRect _WorkspaceAt(int32 index); BRect _WorkspaceAt(int32 index);
BRect _WorkspaceAt(BPoint where, int32& index); BRect _WorkspaceAt(BPoint where, int32& index);
BRect _WindowFrame(const BRect& workspaceFrame, BRect _WindowFrame(const BRect& workspaceFrame,
const BRect& screenFrame, const BRect& windowFrame, const BRect& screenFrame, const BRect& windowFrame,
BPoint windowPosition); BPoint windowPosition);
void _DrawWindow(DrawingEngine* drawingEngine, const BRect& workspaceFrame, void _DrawWindow(DrawingEngine* drawingEngine,
const BRect& screenFrame, WindowLayer* window, const BRect& workspaceFrame, const BRect& screenFrame,
BPoint windowPosition, BRegion& backgroundRegion, WindowLayer* window, BPoint windowPosition,
bool active); BRegion& backgroundRegion, bool active);
void _DrawWorkspace(DrawingEngine* drawingEngine, BRegion& redraw, void _DrawWorkspace(DrawingEngine* drawingEngine,
int32 index); BRegion& redraw, int32 index);
void _DarkenColor(rgb_color& color) const; void _DarkenColor(rgb_color& color) const;
void _Invalidate() const; void _Invalidate() const;
private: private:
WindowLayer* fSelectedWindow; WindowLayer* fSelectedWindow;
int32 fSelectedWorkspace; int32 fSelectedWorkspace;
bool fHasMoved; bool fHasMoved;
BPoint fLeftTopOffset; BPoint fLeftTopOffset;
}; };
#endif // WORKSPACES_LAYER_H #endif // WORKSPACES_LAYER_H