* 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

View File

@ -317,7 +317,7 @@ Desktop::Desktop(uid_t userID)
fAllWindows(kAllWindowList),
fSubsetWindows(kSubsetList),
fFocusList(kFocusList),
fWorkspacesLayer(NULL),
fWorkspacesViews(false),
fActiveScreen(NULL),
fWindowLock("window lock"),
@ -1255,10 +1255,49 @@ Desktop::_WindowHasModal(WindowLayer* window)
void
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;
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;
}
if ((window->Flags() & kWorkspacesWindowFlag) != 0) {
if (window->HasWorkspacesViews()) {
// find workspaces layer in view hierarchy
fWorkspacesLayer = dynamic_cast<WorkspacesLayer*>(
window->TopLayer()->FindView(kWorkspacesViewFlag));
window->FindWorkspacesViews(fWorkspacesViews);
}
UnlockAllWindows();
@ -1662,11 +1700,17 @@ Desktop::HideWindow(WindowLayer* window)
} else
_WindowChanged(window);
if (fWorkspacesLayer != NULL)
fWorkspacesLayer->WindowRemoved(window);
_WindowRemoved(window);
if ((window->Flags() & kWorkspacesWindowFlag) != 0)
fWorkspacesLayer = NULL;
if (window->HasWorkspacesViews()) {
// remove workspaces views from this window
BObjectList<WorkspacesLayer> list(false);
window->FindWorkspacesViews(list);
while (WorkspacesLayer* view = list.RemoveItemAt(0)) {
fWorkspacesViews.RemoveItem(view);
}
}
UnlockAllWindows();

View File

@ -181,6 +181,9 @@ class Desktop : public MessageLooper, public ScreenOwner {
void RedrawBackground();
void StoreWorkspaceConfiguration(int32 index);
void AddWorkspacesView(WorkspacesLayer* view);
void RemoveWorkspacesView(WorkspacesLayer* view);
void MinimizeApplication(team_id team);
void BringApplicationToFront(team_id team);
void WindowAction(int32 windowToken, int32 action);
@ -220,6 +223,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
bool _WindowHasModal(WindowLayer* window);
void _WindowChanged(WindowLayer* window);
void _WindowRemoved(WindowLayer* window);
void _GetLooperName(char* name, size_t size);
void _PrepareQuit();
@ -254,7 +258,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
WindowList fAllWindows;
WindowList fSubsetWindows;
WindowList fFocusList;
WorkspacesLayer* fWorkspacesLayer;
BObjectList<WorkspacesLayer> fWorkspacesViews;
Screen* fActiveScreen;

View File

@ -562,10 +562,7 @@ ServerWindow::_CreateLayerTree(BPrivate::LinkReceiver &link, ViewLayer **_parent
ViewLayer* newLayer;
if ((fWindowLayer->Flags() & kWorkspacesWindowFlag) != 0
&& (flags & kWorkspacesViewFlag) != 0) {
// TODO: there can currently only be one of these views per desktop!
// TODO: get rid of the kWorkspacesWindowFlag
if ((flags & kWorkspacesViewFlag) != 0) {
newLayer = new (nothrow) WorkspacesLayer(frame, scrollingOffset, name,
token, resizeMask, flags);
} else {

View File

@ -206,9 +206,9 @@ ViewLayer::AddChild(ViewLayer* layer)
printf("ViewLayer::AddChild() - ViewLayer already has a parent\n");
return;
}
layer->fParent = this;
if (!fLastChild) {
// no children yet
fFirstChild = layer;
@ -376,19 +376,20 @@ ViewLayer::MarkAt(DrawingEngine* engine, const BPoint& where, int32 level)
#endif
ViewLayer*
ViewLayer::FindView(uint32 flags)
void
ViewLayer::FindViews(uint32 flags, BObjectList<ViewLayer>& list, int32& left)
{
if ((Flags() & flags) == flags)
return this;
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
ViewLayer* layer = child->FindView(flags);
if (layer != NULL)
return layer;
if ((Flags() & flags) == flags) {
list.AddItem(this);
left--;
return;
}
return NULL;
for (ViewLayer* child = FirstChild(); child; child = child->NextSibling()) {
child->FindViews(flags, list, left);
if (left == 0)
break;
}
}

View File

@ -16,6 +16,7 @@
#include "IntRect.h"
#include <GraphicsDefs.h>
#include <ObjectList.h>
#include <Region.h>
#include <String.h>
@ -76,8 +77,8 @@ class ViewLayer {
// clips to each views bounds
void ConvertToVisibleInTopView(IntRect* bounds) const;
void AttachedToWindow(WindowLayer* window);
void DetachedFromWindow();
virtual void AttachedToWindow(WindowLayer* window);
virtual void DetachedFromWindow();
WindowLayer* Window() const { return fWindow; }
// tree stuff
@ -100,7 +101,8 @@ class ViewLayer {
uint32 CountChildren(bool deep = false) const;
void CollectTokensForChildren(BList* tokenMap) const;
ViewLayer* FindView(uint32 flags);
void FindViews(uint32 flags,
BObjectList<ViewLayer>& list, int32& left);
ViewLayer* ViewAt(const BPoint& where);

View File

@ -25,6 +25,7 @@
#include "Workspace.h"
#include "WorkspacesLayer.h"
#include <ViewPrivate.h>
#include <WindowPrivate.h>
#include <Debug.h>
@ -126,7 +127,9 @@ WindowLayer::WindowLayer(const BRect& frame, const char *name,
fMinWidth(1),
fMaxWidth(32768),
fMinHeight(1),
fMaxHeight(32768)
fMaxHeight(32768),
fWorkspacesViewCount(0)
{
// make sure our arguments are valid
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.
A modal or floating window may be visible on a workscreen if one

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.
*
* Author: DarkWyrm <bpmagic@columbus.rr.com>
* Adi Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
* Axel Dörfler, axeld@pinc-software.de
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Adi Oanca <adioanca@gmail.com>
* Stephan Aßmus <superstippi@gmx.de>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef WINDOW_LAYER_H
#define WINDOW_LAYER_H
@ -30,7 +31,7 @@ class Decorator;
class Desktop;
class DrawingEngine;
class EventDispatcher;
class WindowLayer;
class WorkspacesLayer;
// TODO: move this into a proper place
#define AS_REDRAW 'rdrw'
@ -41,7 +42,7 @@ enum {
};
class WindowLayer {
public:
public:
WindowLayer(const BRect& frame,
const char *name, window_look look,
window_feel feel, uint32 flags,
@ -208,6 +209,15 @@ class WindowLayer {
bool SameSubset(WindowLayer* window);
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 IsValidFeel(window_feel feel);
static bool IsModalFeel(window_feel feel);
@ -216,7 +226,7 @@ class WindowLayer {
static uint32 ValidWindowFlags();
static uint32 ValidWindowFlags(window_feel feel);
protected:
protected:
friend class Desktop;
// TODO: for now (list management)
@ -298,7 +308,7 @@ class WindowLayer {
// redraw requests from the Desktop will go
// into the pending update session.
class UpdateSession {
public:
public:
UpdateSession();
virtual ~UpdateSession();
@ -320,7 +330,7 @@ class WindowLayer {
inline bool IsRequest() const
{ return fCause & UPDATE_REQUEST; }
private:
private:
BRegion fDirtyRegion;
bool fInUse;
uint8 fCause;
@ -352,6 +362,8 @@ class WindowLayer {
int32 fMaxWidth;
int32 fMinHeight;
int32 fMaxHeight;
int32 fWorkspacesViewCount;
};
#endif // WINDOW_LAYER_H

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2007, Haiku Inc.
* Copyright 2005-2008, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -33,7 +33,26 @@ WorkspacesLayer::WorkspacesLayer(BRect frame, BPoint scrollingOffset,
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();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2006, Haiku Inc.
* Copyright 2005-2008, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -15,47 +15,50 @@ class WindowLayer;
class WorkspacesLayer : public ViewLayer {
public:
WorkspacesLayer(BRect frame, BPoint scrollingOffset, const char* name,
int32 token, uint32 resize, uint32 flags);
virtual ~WorkspacesLayer();
public:
WorkspacesLayer(BRect frame, BPoint scrollingOffset,
const char* name, int32 token, uint32 resize,
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* windowContentClipping,
bool deep = false);
BRegion* windowContentClipping, bool deep = false);
virtual void MouseDown(BMessage* message, BPoint where);
virtual void MouseUp(BMessage* message, BPoint where);
virtual void MouseMoved(BMessage* message, BPoint where);
virtual void MouseDown(BMessage* message, BPoint where);
virtual void MouseUp(BMessage* message, BPoint where);
virtual void MouseMoved(BMessage* message, BPoint where);
void WindowChanged(WindowLayer* window);
void WindowRemoved(WindowLayer* window);
void WindowChanged(WindowLayer* window);
void WindowRemoved(WindowLayer* window);
private:
void _GetGrid(int32& columns, int32& rows);
BRect _ScreenFrame(int32 index);
BRect _WorkspaceAt(int32 index);
BRect _WorkspaceAt(BPoint where, int32& index);
BRect _WindowFrame(const BRect& workspaceFrame,
const BRect& screenFrame, const BRect& windowFrame,
BPoint windowPosition);
private:
void _GetGrid(int32& columns, int32& rows);
BRect _ScreenFrame(int32 index);
BRect _WorkspaceAt(int32 index);
BRect _WorkspaceAt(BPoint where, int32& index);
BRect _WindowFrame(const BRect& workspaceFrame,
const BRect& screenFrame, const BRect& windowFrame,
BPoint windowPosition);
void _DrawWindow(DrawingEngine* drawingEngine, const BRect& workspaceFrame,
const BRect& screenFrame, WindowLayer* window,
BPoint windowPosition, BRegion& backgroundRegion,
bool active);
void _DrawWorkspace(DrawingEngine* drawingEngine, BRegion& redraw,
int32 index);
void _DrawWindow(DrawingEngine* drawingEngine,
const BRect& workspaceFrame, const BRect& screenFrame,
WindowLayer* window, BPoint windowPosition,
BRegion& backgroundRegion, bool active);
void _DrawWorkspace(DrawingEngine* drawingEngine,
BRegion& redraw, int32 index);
void _DarkenColor(rgb_color& color) const;
void _Invalidate() const;
void _DarkenColor(rgb_color& color) const;
void _Invalidate() const;
private:
WindowLayer* fSelectedWindow;
int32 fSelectedWorkspace;
bool fHasMoved;
BPoint fLeftTopOffset;
private:
WindowLayer* fSelectedWindow;
int32 fSelectedWorkspace;
bool fHasMoved;
BPoint fLeftTopOffset;
};
#endif // WORKSPACES_LAYER_H