Massive RootLayer & Workspace tearing:

* workspace switch and subset windows functionality temporarily removed
  (away with that mess!).
* no more RevealWMState() - we now have methods like ActivateWindow()
  and SendWindowBehind() that do all the work - just a little cleaner
  and with less overhead.
* Workspace is now a pretty passive class - it only stores configurations
  of the windows and screens.
* added an evil work-around for a locking problem (in RootLayer::_SetFocus()).
* I'll plan to move pretty much all of the remaining root layer functionality
  to Desktop - so that the all regions lock is only held in case clipping
  regions are affected.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15207 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-28 23:36:59 +00:00
parent 8fc80f17d9
commit 27adb96962
14 changed files with 707 additions and 3069 deletions
+59 -196
View File
@@ -98,19 +98,8 @@ KeyboardFilter::Filter(BMessage* message, BHandler** /*_target*/)
#endif #endif
{ {
STRACE(("Set Workspace %ld\n", key - 1)); STRACE(("Set Workspace %ld\n", key - 1));
RootLayer* root = fDesktop->RootLayer();
root->Lock(); fDesktop->SetWorkspace(key - 2);
root->SetActiveWorkspace(key - 2);
#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER
// to draw the current Workspace index on screen.
BRegion region(VisibleRegion());
fDesktop->GetDrawingEngine()->ConstrainClippingRegion(&region);
root->Draw(region.Frame());
fDesktop->GetDrawingEngine()->ConstrainClippingRegion(NULL);
#endif
root->Unlock();
return B_SKIP_MESSAGE; return B_SKIP_MESSAGE;
} }
} }
@@ -188,7 +177,7 @@ Desktop::Init()
// TODO: add user identity to the name // TODO: add user identity to the name
char name[32]; char name[32];
sprintf(name, "RootLayer %d", 1); sprintf(name, "RootLayer %d", 1);
fRootLayer = new ::RootLayer(name, 4, this, GetDrawingEngine()); fRootLayer = new ::RootLayer(name, this, GetDrawingEngine());
#if TEST_MODE #if TEST_MODE
gInputManager->AddStream(new InputServerStream); gInputManager->AddStream(new InputServerStream);
@@ -436,20 +425,13 @@ Desktop::_ActivateApp(team_id team)
int32 windowCount = WindowList().CountItems(); int32 windowCount = WindowList().CountItems();
for (int32 i = 0; i < windowCount; ++i) { for (int32 i = 0; i < windowCount; ++i) {
// is this layer in fact a WindowLayer? // is this layer in fact a WindowLayer?
WindowLayer *winBorder = WindowList().ItemAt(i); WindowLayer *windowLayer = WindowList().ItemAt(i);
// if winBorder is valid and not hidden, then we've found our target // if winBorder is valid and not hidden, then we've found our target
if (winBorder != NULL && !winBorder->IsHidden() if (windowLayer != NULL && !windowLayer->IsHidden()
&& winBorder->App()->ClientTeam() == team) { && windowLayer->App()->ClientTeam() == team) {
if (fRootLayer->Lock()) { fRootLayer->ActivateWindow(windowLayer);
fRootLayer->SetActive(winBorder); return B_OK;
fRootLayer->Unlock();
if (fRootLayer->Active() == winBorder)
return B_OK;
status = B_ERROR;
}
} }
} }
@@ -480,6 +462,19 @@ Desktop::BroadcastToAllApps(int32 code)
} }
void
Desktop::SetWorkspace(int32 index)
{
BAutolock _(this);
DesktopSettings settings(this);
if (index < 0 || index >= settings.WorkspacesCount())
return;
fRootLayer->SetWorkspace(index, fWorkspaces[index]);
}
void void
Desktop::ScreenChanged(Screen* screen) Desktop::ScreenChanged(Screen* screen)
{ {
@@ -506,204 +501,72 @@ Desktop::ScreenChanged(Screen* screen)
void void
Desktop::AddWindowLayer(WindowLayer *winBorder) Desktop::ActivateWindow(WindowLayer* windowLayer)
{ {
if (!winBorder) fRootLayer->ActivateWindow(windowLayer);
return; }
int32 feel = winBorder->Feel();
// we are ServerApp thread, we need to lock RootLayer here. void
RootLayer()->Lock(); Desktop::SendBehindWindow(WindowLayer* windowLayer, WindowLayer* front)
{
fRootLayer->SendBehindWindow(windowLayer, front);
}
// we're playing with window list. lock first.
void
Desktop::SetWindowWorkspaces(WindowLayer* windowLayer, uint32 workspaces)
{
BAutolock _(this);
windowLayer->SetWorkspaces(workspaces);
// is the window still visible on screen?
bool remove = (workspaces & (1UL << CurrentWorkspace())) == 0;
if (remove && windowLayer->Parent() != NULL) {
// the window is no longer visible on screen
fRootLayer->RemoveWindowLayer(windowLayer);
} else if (!remove && windowLayer->Parent() == NULL) {
// the window is now visible on screen
fRootLayer->AddWindowLayer(windowLayer);
}
}
void
Desktop::AddWindowLayer(WindowLayer *windowLayer)
{
Lock(); Lock();
if (fWindowLayerList.HasItem(winBorder)) { if (fWindowLayerList.HasItem(windowLayer)) {
Unlock(); Unlock();
RootLayer()->Unlock();
debugger("AddWindowLayer: WindowLayer already in Desktop list\n"); debugger("AddWindowLayer: WindowLayer already in Desktop list\n");
return; return;
} }
// we have a new window. store a record of it. fWindowLayerList.AddItem(windowLayer);
fWindowLayerList.AddItem(winBorder);
// add FLOATING_APP windows to the local list of all normal windows.
// This is to keep the order all floating windows (app or subset) when we go from
// one normal window to another.
if (feel == B_FLOATING_APP_WINDOW_FEEL || feel == B_NORMAL_WINDOW_FEEL) {
WindowLayer *wb = NULL;
int32 count = fWindowLayerList.CountItems();
int32 feelToLookFor = (feel == B_NORMAL_WINDOW_FEEL ?
B_FLOATING_APP_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL);
for (int32 i = 0; i < count; i++) {
wb = (WindowLayer *)fWindowLayerList.ItemAt(i);
if (wb->App()->ClientTeam() == winBorder->App()->ClientTeam()
&& wb->Feel() == feelToLookFor) {
// R2: RootLayer comparison is needed.
feel == B_NORMAL_WINDOW_FEEL ?
winBorder->fSubWindowList.AddWindowLayer(wb) :
wb->fSubWindowList.AddWindowLayer(winBorder);
}
}
}
// add application's list of modal windows.
if (feel == B_MODAL_APP_WINDOW_FEEL) {
winBorder->App()->fAppSubWindowList.AddWindowLayer(winBorder);
}
// send WindowLayer to be added to workspaces
RootLayer()->AddWindowLayer(winBorder);
// hey, unlock!
Unlock(); Unlock();
RootLayer()->Unlock(); RootLayer()->AddWindowLayer(windowLayer);
} }
void void
Desktop::RemoveWindowLayer(WindowLayer *winBorder) Desktop::RemoveWindowLayer(WindowLayer *windowLayer)
{ {
if (!winBorder)
return;
// we are ServerApp thread, we need to lock RootLayer here.
RootLayer()->Lock();
// we're playing with window list. lock first.
Lock(); Lock();
fWindowLayerList.RemoveItem(windowLayer);
// remove from main WindowLayer list.
if (fWindowLayerList.RemoveItem(winBorder)) {
int32 feel = winBorder->Feel();
// floating app/subset and modal_subset windows require special atention because
// they are/may_be added to the list of a lot normal windows.
if (feel == B_FLOATING_SUBSET_WINDOW_FEEL
|| feel == B_MODAL_SUBSET_WINDOW_FEEL
|| feel == B_FLOATING_APP_WINDOW_FEEL)
{
WindowLayer *wb = NULL;
int32 count = fWindowLayerList.CountItems();
for (int32 i = 0; i < count; i++) {
wb = (WindowLayer*)fWindowLayerList.ItemAt(i);
if (wb->Feel() == B_NORMAL_WINDOW_FEEL
&& wb->App()->ClientTeam() == winBorder->App()->ClientTeam()) {
// R2: RootLayer comparison is needed. We'll see.
wb->fSubWindowList.RemoveItem(winBorder);
}
}
}
// remove from application's list
if (feel == B_MODAL_APP_WINDOW_FEEL) {
winBorder->App()->fAppSubWindowList.RemoveItem(winBorder);
}
} else {
Unlock();
RootLayer()->Unlock();
debugger("RemoveWindowLayer: WindowLayer not found in Desktop list\n");
return;
}
// Tell to winBorder's RootLayer about this.
RootLayer()->RemoveWindowLayer(winBorder);
Unlock(); Unlock();
RootLayer()->Unlock();
}
RootLayer()->RemoveWindowLayer(windowLayer);
void
Desktop::AddWindowLayerToSubset(WindowLayer *winBorder, WindowLayer *toWindowLayer)
{
// NOTE: we can safely lock the entire method body, because this method is called from
// RootLayer's thread only.
// we're playing with window list. lock first.
Lock();
if (!winBorder || !toWindowLayer
|| !fWindowLayerList.HasItem(winBorder)
|| !fWindowLayerList.HasItem(toWindowLayer)) {
Unlock();
debugger("AddWindowLayerToSubset: NULL WindowLayer or not found in Desktop list\n");
return;
}
if ((winBorder->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL
|| winBorder->Feel() == B_MODAL_SUBSET_WINDOW_FEEL)
&& toWindowLayer->Feel() == B_NORMAL_WINDOW_FEEL
&& toWindowLayer->App()->ClientTeam() == winBorder->App()->ClientTeam()
&& !toWindowLayer->fSubWindowList.HasItem(winBorder)) {
// add to normal_window's list
toWindowLayer->fSubWindowList.AddWindowLayer(winBorder);
} else {
Unlock();
debugger("AddWindowLayerToSubset: you must add a subset_window to a normal_window's subset with the same team_id\n");
return;
}
// send WindowLayer to be added to workspaces, if not already in there.
RootLayer()->AddSubsetWindowLayer(winBorder, toWindowLayer);
Unlock();
}
void
Desktop::RemoveWindowLayerFromSubset(WindowLayer *winBorder, WindowLayer *fromWindowLayer)
{
// NOTE: we can safely lock the entire method body, because this method is called from
// RootLayer's thread only.
// we're playing with window list. lock first.
Lock();
if (!winBorder || !fromWindowLayer
|| !fWindowLayerList.HasItem(winBorder)
|| !fWindowLayerList.HasItem(fromWindowLayer)) {
Unlock();
debugger("RemoveWindowLayerFromSubset: NULL WindowLayer or not found in Desktop list\n");
return;
}
// remove WindowLayer from workspace, if needed - some other windows may still have it in their subset
RootLayer()->RemoveSubsetWindowLayer(winBorder, fromWindowLayer);
if (fromWindowLayer->Feel() == B_NORMAL_WINDOW_FEEL) {
//remove from this normal_window's subset.
fromWindowLayer->fSubWindowList.RemoveItem(winBorder);
} else {
Unlock();
debugger("RemoveWindowLayerFromSubset: you must remove a subset_window from a normal_window's subset\n");
return;
}
Unlock();
} }
void void
Desktop::SetWindowLayerFeel(WindowLayer *winBorder, uint32 feel) Desktop::SetWindowLayerFeel(WindowLayer *winBorder, uint32 feel)
{ {
// NOTE: this method is called from RootLayer thread only // TODO: implement
// we're playing with window list. lock first.
Lock();
RemoveWindowLayer(winBorder);
winBorder->QuietlySetFeel(feel);
AddWindowLayer(winBorder);
Unlock();
} }
+77 -60
View File
@@ -7,8 +7,8 @@
* Stephan Aßmus <[email protected]> * Stephan Aßmus <[email protected]>
* Axel Dörfler, [email protected] * Axel Dörfler, [email protected]
*/ */
#ifndef _DESKTOP_H_ #ifndef DESKTOP_H
#define _DESKTOP_H_ #define DESKTOP_H
#include "CursorManager.h" #include "CursorManager.h"
@@ -18,6 +18,7 @@
#include "VirtualScreen.h" #include "VirtualScreen.h"
#include "DesktopSettings.h" #include "DesktopSettings.h"
#include "MessageLooper.h" #include "MessageLooper.h"
#include "Workspace.h"
#include <InterfaceDefs.h> #include <InterfaceDefs.h>
#include <List.h> #include <List.h>
@@ -41,87 +42,103 @@ namespace BPrivate {
class Desktop : public MessageLooper, public ScreenOwner { class Desktop : public MessageLooper, public ScreenOwner {
public: public:
// startup methods
Desktop(uid_t userID); Desktop(uid_t userID);
virtual ~Desktop(); virtual ~Desktop();
void Init(); void Init();
uid_t UserID() const { return fUserID; } uid_t UserID() const { return fUserID; }
virtual port_id MessagePort() const { return fMessagePort; } virtual port_id MessagePort() const { return fMessagePort; }
::EventDispatcher& EventDispatcher() { return fEventDispatcher; } ::EventDispatcher& EventDispatcher() { return fEventDispatcher; }
void BroadcastToAllApps(int32 code); void BroadcastToAllApps(int32 code);
// Methods for multiple monitors. // Screen and drawing related methods
inline Screen* ScreenAt(int32 index) const
Screen* ScreenAt(int32 index) const
{ return fActiveScreen; } { return fActiveScreen; }
inline Screen* ActiveScreen() const Screen* ActiveScreen() const
{ return fActiveScreen; } { return fActiveScreen; }
inline ::RootLayer* RootLayer() const { return fRootLayer; } ::RootLayer* RootLayer() const { return fRootLayer; }
inline CursorManager& GetCursorManager() { return fCursorManager; } CursorManager& GetCursorManager() { return fCursorManager; }
void ScreenChanged(Screen* screen); void ScreenChanged(Screen* screen);
virtual void ScreenRemoved(Screen* screen) {} void ScreenRemoved(Screen* screen) {}
virtual void ScreenAdded(Screen* screen) {} void ScreenAdded(Screen* screen) {}
virtual bool ReleaseScreen(Screen* screen) { return false; } bool ReleaseScreen(Screen* screen) { return false; }
const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; } const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; }
inline DrawingEngine* GetDrawingEngine() const DrawingEngine* GetDrawingEngine() const
{ return fVirtualScreen.DrawingEngine(); } { return fVirtualScreen.DrawingEngine(); }
inline ::HWInterface* HWInterface() const ::HWInterface* HWInterface() const
{ return fVirtualScreen.HWInterface(); } { return fVirtualScreen.HWInterface(); }
// Methods for layer(WindowLayer) manipulation. // Workspace methods
void AddWindowLayer(WindowLayer *winBorder);
void RemoveWindowLayer(WindowLayer *winBorder);
void SetWindowLayerFeel(WindowLayer *winBorder,
uint32 feel);
void AddWindowLayerToSubset(WindowLayer *winBorder,
WindowLayer *toWindowLayer);
void RemoveWindowLayerFromSubset(WindowLayer *winBorder,
WindowLayer *fromWindowLayer);
WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID); void SetWorkspace(int32 index);
//WindowLayer* FindWindowLayerByServerToken(int32 token); int32 CurrentWorkspace()
{ return fCurrentWorkspace; }
::Workspace& WorkspaceAt(int32 index)
{ return fWorkspaces[index]; }
// get list of registed windows // WindowLayer methods
const BObjectList<WindowLayer>& WindowList() const;
void WriteWindowList(team_id team, BPrivate::LinkSender& sender); void ActivateWindow(WindowLayer* window);
void WriteWindowInfo(int32 serverToken, BPrivate::LinkSender& sender); void SendBehindWindow(WindowLayer* window, WindowLayer* front);
private: void SetWindowWorkspaces(WindowLayer* window, uint32 workspaces);
status_t _ActivateApp(team_id team);
virtual void _GetLooperName(char* name, size_t size);
virtual void _PrepareQuit();
virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
private: void AddWindowLayer(WindowLayer *windowLayer);
friend class DesktopSettings; void RemoveWindowLayer(WindowLayer *windowLayer);
void SetWindowLayerFeel(WindowLayer *windowLayer,
uint32 feel);
uid_t fUserID; WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID);
::VirtualScreen fVirtualScreen; //WindowLayer* FindWindowLayerByServerToken(int32 token);
DesktopSettings::Private* fSettings;
port_id fMessagePort;
::EventDispatcher fEventDispatcher;
port_id fInputPort;
BLocker fAppListLock; // get list of registed windows
BList fAppList; const BObjectList<WindowLayer>& WindowList() const;
sem_id fShutdownSemaphore; void WriteWindowList(team_id team,
int32 fShutdownCount; BPrivate::LinkSender& sender);
void WriteWindowInfo(int32 serverToken,
BPrivate::LinkSender& sender);
BObjectList<WindowLayer> fWindowLayerList; private:
status_t _ActivateApp(team_id team);
void _GetLooperName(char* name, size_t size);
void _PrepareQuit();
void _DispatchMessage(int32 code,
BPrivate::LinkReceiver &link);
::RootLayer* fRootLayer; private:
Screen* fActiveScreen; friend class DesktopSettings;
CursorManager fCursorManager; uid_t fUserID;
::VirtualScreen fVirtualScreen;
DesktopSettings::Private* fSettings;
port_id fMessagePort;
::EventDispatcher fEventDispatcher;
port_id fInputPort;
BLocker fAppListLock;
BList fAppList;
sem_id fShutdownSemaphore;
int32 fShutdownCount;
::Workspace fWorkspaces[32];//kMaxWorkspaces];
int32 fCurrentWorkspace;
BObjectList<WindowLayer> fWindowLayerList;
::RootLayer* fRootLayer;
Screen* fActiveScreen;
CursorManager fCursorManager;
}; };
#endif // _DESKTOP_H_ #endif // DESKTOP_H
File diff suppressed because it is too large Load Diff
+68 -81
View File
@@ -40,116 +40,103 @@ namespace BPrivate {
class UtilityBitmap; class UtilityBitmap;
#endif #endif
/*!
\class RootLayer RootLayer.h
\brief Class used for the top layer of each workspace's Layer tree
RootLayers are used to head up the top of each Layer tree and reimplement certain
Layer functions to act accordingly. There is only one for each workspace class.
*/
class RootLayer : public Layer { class RootLayer : public Layer {
public: public:
RootLayer(const char *name, int32 workspaceCount, RootLayer(const char *name, Desktop *desktop,
Desktop *desktop, DrawingEngine *driver); DrawingEngine *driver);
virtual ~RootLayer(void); virtual ~RootLayer();
Desktop* GetDesktop() const { return fDesktop; } Desktop* GetDesktop() const { return fDesktop; }
virtual void MoveBy(float x, float y); virtual void MoveBy(float x, float y);
virtual void ResizeBy(float x, float y); virtual void ResizeBy(float x, float y);
virtual void ScrollBy(float x, float y) virtual void ScrollBy(float x, float y)
{ /* not allowed */ } { /* not allowed */ }
void HideWindowLayer(WindowLayer* windowLayer); void HideWindowLayer(WindowLayer* windowLayer);
void ShowWindowLayer(WindowLayer* windowLayer); void ShowWindowLayer(WindowLayer* windowLayer, bool toFront = true);
void SetWindowLayerWorskpaces(WindowLayer *windowLayer,
uint32 oldIndex, uint32 newIndex);
void RevealNewWMState(Workspace::State &oldWMState); // void RevealNewWMState(Workspace::State &oldWMState);
// TODO: we need to replace Winborder* with Layer* bool SetFocus(WindowLayer* focus);
inline WindowLayer* Focus() const { return fWMState.Focus; } WindowLayer* Focus() const { return fFocus; }
inline WindowLayer* Front() const { return fWMState.Front; } WindowLayer* Front() const { return fFront; }
inline WindowLayer* Active() const { return fWMState.Focus; } WindowLayer* Back() const { return fBack; }
bool SetActive(WindowLayer* newActive, bool activate = true);
inline void SetWorkspaceCount(int32 wksCount); void SetWorkspace(int32 index, Workspace& workspace);
inline int32 WorkspaceCount() const { return fWsCount; } void SetWorkspacesLayer(Layer* layer) { fWorkspacesLayer = layer; }
inline Workspace* WorkspaceAt(int32 index) const { return fWorkspace[index]; } Layer* WorkspacesLayer() const { return fWorkspacesLayer; }
inline Workspace* ActiveWorkspace() const { return fWorkspace[fActiveWksIndex]; }
inline int32 ActiveWorkspaceIndex() const { return fActiveWksIndex; }
bool SetActiveWorkspace(int32 index);
void ReadWorkspaceData(const char *path); #if 0
void SaveWorkspaceData(const char *path); void SetBGColor(const RGBColor &col);
RGBColor BGColor(void) const;
#endif
void SetWorkspacesLayer(Layer* layer) { fWorkspacesLayer = layer; } void SetDragMessage(BMessage *msg);
Layer* WorkspacesLayer() const { return fWorkspacesLayer; } BMessage* DragMessage() const;
void SetBGColor(const RGBColor &col);
RGBColor BGColor(void) const;
void SetDragMessage(BMessage *msg); void SetMouseEventLayer(Layer* layer);
BMessage* DragMessage(void) const;
void SetMouseEventLayer(Layer* layer); void LayerRemoved(Layer* layer);
void LayerRemoved(Layer* layer); // Other methods
bool Lock() { return fAllRegionsLock.Lock(); }
void Unlock() { fAllRegionsLock.Unlock(); }
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
// Other methods void ActivateWindow(WindowLayer* window);
bool Lock() { return fAllRegionsLock.Lock(); } void SendBehindWindow(WindowLayer* window, WindowLayer* front);
void Unlock() { fAllRegionsLock.Unlock(); }
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
void ChangeWindowLayerFeel(WindowLayer *windowLayer, int32 newFeel); void SetWindowLayerFeel(WindowLayer *windowLayer, int32 newFeel);
void SetWindowLayerLook(WindowLayer *windowLayer, int32 newLook);
void MarkForRedraw(const BRegion &dirty); void MarkForRedraw(const BRegion &dirty);
void TriggerRedraw(); void TriggerRedraw();
virtual void Draw(const BRect &r); void Draw(const BRect &r);
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); } thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
private: void AddWindowLayer(WindowLayer* windowLayer);
friend class Desktop; void RemoveWindowLayer(WindowLayer* windowLayer);
// these are meant for Desktop class only! void MouseEventHandler(BMessage *msg);
void AddWindowLayer(WindowLayer* windowLayer);
void RemoveWindowLayer(WindowLayer* windowLayer);
void AddSubsetWindowLayer(WindowLayer *windowLayer, WindowLayer *toWindowLayer);
void RemoveSubsetWindowLayer(WindowLayer *windowLayer, WindowLayer *fromWindowLayer);
void MouseEventHandler(BMessage *msg); private:
Layer* _ChildAt(BPoint where); bool _SetFocus(WindowLayer* focus, BRegion& update);
void _SetFront(WindowLayer* front, BRegion& update);
void _UpdateBack();
void _UpdateFront();
void _UpdateFronts();
Desktop* fDesktop; void _WindowsChanged(BRegion& region);
BMessage* fDragMessage; void _UpdateWorkspace(Workspace& workspace);
Layer* fMouseEventLayer;
uint32 fSavedEventMask; Layer* _ChildAt(BPoint where);
uint32 fSavedEventOptions;
BLocker fAllRegionsLock; Desktop* fDesktop;
BMessage* fDragMessage;
Layer* fMouseEventLayer;
BRegion fDirtyForRedraw; BLocker fAllRegionsLock;
int32 fActiveWksIndex; BRegion fDirtyForRedraw;
int32 fWsCount;
Workspace** fWorkspace;
Layer* fWorkspacesLayer;
// TODO: fWMState MUST be associated with a surface. This is the case now int32 fWorkspace;
// with RootLayer, but after Axel's refractoring this should go in RGBColor fColor;
// WorkspaceLayer, I think. Layer* fWorkspacesLayer;
Workspace::State fWMState;
WindowLayer* fFocus;
WindowLayer* fFront;
WindowLayer* fBack;
#if ON_SCREEN_DEBUGGING_INFO #if ON_SCREEN_DEBUGGING_INFO
friend class DebugInfoManager; friend class DebugInfoManager;
void AddDebugInfo(const char* string); void AddDebugInfo(const char* string);
BString fDebugInfo; BString fDebugInfo;
#endif #endif
#if DISPLAY_HAIKU_LOGO #if DISPLAY_HAIKU_LOGO
UtilityBitmap* fLogoBitmap; UtilityBitmap* fLogoBitmap;
#endif #endif
}; };
+15 -34
View File
@@ -849,18 +849,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
{ {
STRACE(("ServerApp %s: get current workspace\n", Signature())); STRACE(("ServerApp %s: get current workspace\n", Signature()));
// TODO: Locking this way is not nice fLink.StartMessage(B_OK);
RootLayer *root = fDesktop->RootLayer(); fLink.Attach<int32>(fDesktop->CurrentWorkspace());
root->Lock();
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<int32>(root->ActiveWorkspaceIndex());
fLink.Flush(); fLink.Flush();
root->Unlock();
break; break;
} }
case AS_ACTIVATE_WORKSPACE: case AS_ACTIVATE_WORKSPACE:
{ {
STRACE(("ServerApp %s: activate workspace\n", Signature())); STRACE(("ServerApp %s: activate workspace\n", Signature()));
@@ -868,15 +862,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// TODO: See above // TODO: See above
int32 index; int32 index;
link.Read<int32>(&index); link.Read<int32>(&index);
RootLayer *root = fDesktop->RootLayer();
root->Lock(); fDesktop->SetWorkspace(index);
root->SetActiveWorkspace(index);
root->Unlock();
// no reply
break; break;
} }
case AS_SHOW_CURSOR: case AS_SHOW_CURSOR:
{ {
STRACE(("ServerApp %s: Show Cursor\n", Signature())); STRACE(("ServerApp %s: Show Cursor\n", Signature()));
@@ -2188,31 +2178,22 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
{ {
STRACE(("ServerApp %s: get desktop color\n", Signature())); STRACE(("ServerApp %s: get desktop color\n", Signature()));
uint32 workspaceIndex; uint32 index;
link.Read<uint32>(&workspaceIndex); link.Read<uint32>(&index);
// ToDo: locking is probably wrong - why the hell is there no (safe) fLink.StartMessage(B_OK);
// way to get to the workspace object directly? fDesktop->Lock();
RootLayer *root = fDesktop->RootLayer();
root->Lock();
Workspace *workspace;
// we're nice to our children (and also take the default case // we're nice to our children (and also take the default case
// into account which asks for the current workspace) // into account which asks for the current workspace)
if (workspaceIndex > (uint32)root->WorkspaceCount()) if (index >= (uint32)kMaxWorkspaces)
workspace = root->ActiveWorkspace(); index = fDesktop->CurrentWorkspace();
else
workspace = root->WorkspaceAt(workspaceIndex);
if (workspace != NULL) { Workspace& workspace = fDesktop->WorkspaceAt(index);
fLink.StartMessage(B_OK); fLink.Attach<rgb_color>(workspace.Color().GetColor32());
fLink.Attach<rgb_color>(workspace->BGColor().GetColor32());
} else
fLink.StartMessage(B_ERROR);
fDesktop->Unlock();
fLink.Flush(); fLink.Flush();
root->Unlock();
break; break;
} }
-4
View File
@@ -14,7 +14,6 @@
#include "MessageLooper.h" #include "MessageLooper.h"
#include "SubWindowList.h"
#include "BGet++.h" #include "BGet++.h"
#include <String.h> #include <String.h>
@@ -78,9 +77,6 @@ class ServerApp : public MessageLooper {
BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; } BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; }
// ToDo: public?
SubWindowList fAppSubWindowList;
private: private:
virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
virtual void _MessageLooper(); virtual void _MessageLooper();
+65 -95
View File
@@ -294,13 +294,11 @@ ServerWindow::Show()
return; return;
RootLayer* rootLayer = fWindowLayer->GetRootLayer(); RootLayer* rootLayer = fWindowLayer->GetRootLayer();
if (rootLayer && rootLayer->Lock()) { if (rootLayer)
rootLayer->ShowWindowLayer(fWindowLayer); rootLayer->ShowWindowLayer(fWindowLayer);
rootLayer->Unlock();
}
if (fDirectWindowData != NULL) if (fDirectWindowData != NULL)
HandleDirectConnection(B_DIRECT_START|B_BUFFER_RESET); HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESET);
} }
@@ -316,12 +314,10 @@ ServerWindow::Hide()
if (fDirectWindowData != NULL) if (fDirectWindowData != NULL)
HandleDirectConnection(B_DIRECT_STOP); HandleDirectConnection(B_DIRECT_STOP);
RootLayer* rootLayer = fWindowLayer->GetRootLayer(); RootLayer* rootLayer = fWindowLayer->GetRootLayer();
if (rootLayer && rootLayer->Lock()) { if (rootLayer)
rootLayer->HideWindowLayer(fWindowLayer); rootLayer->HideWindowLayer(fWindowLayer);
rootLayer->Unlock();
}
} }
@@ -404,23 +400,6 @@ ServerWindow::NotifyZoom()
SendMessageToClient(&msg); SendMessageToClient(&msg);
} }
/*!
\brief Notifies window of a change in screen resolution
\param frame Size of the new resolution
\param color_space Color space of the new screen mode
*/
void
ServerWindow::NotifyScreenModeChanged(const BRect frame, const color_space colorSpace)
{
STRACE(("ServerWindow %s: ScreenModeChanged\n", fTitle));
BMessage msg(B_SCREEN_CHANGED);
msg.AddRect("frame", frame);
msg.AddInt32("mode", (int32)colorSpace);
SendMessageToClient(&msg);
}
void void
ServerWindow::GetInfo(window_info& info) ServerWindow::GetInfo(window_info& info)
@@ -696,7 +675,8 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
if (rootLayer) { if (rootLayer) {
rootLayer->LayerRemoved(fCurrentLayer); rootLayer->LayerRemoved(fCurrentLayer);
rootLayer->TriggerRedraw(); if (!fCurrentLayer->IsHidden())
rootLayer->TriggerRedraw();
} }
if (fCurrentLayer->EventMask() != 0) { if (fCurrentLayer->EventMask() != 0) {
@@ -992,7 +972,7 @@ if (rootLayer)
rootLayer->Lock(); rootLayer->Lock();
fCurrentLayer->SetViewColor(RGBColor(c)); fCurrentLayer->SetViewColor(RGBColor(c));
if (rootLayer) { if (rootLayer && !fCurrentLayer->IsHidden()) {
rootLayer->MarkForRedraw(fCurrentLayer->VisibleRegion()); rootLayer->MarkForRedraw(fCurrentLayer->VisibleRegion());
rootLayer->TriggerRedraw(); rootLayer->TriggerRedraw();
} }
@@ -1177,7 +1157,7 @@ if (rootLayer)
link.Read<BRect>(&invalRect); link.Read<BRect>(&invalRect);
if (rootLayer) { if (rootLayer && !fCurrentLayer->IsHidden()) {
BRect converted(invalRect.LeftTop(), invalRect.RightBottom()); BRect converted(invalRect.LeftTop(), invalRect.RightBottom());
fCurrentLayer->ConvertToScreen(&converted); fCurrentLayer->ConvertToScreen(&converted);
@@ -1206,13 +1186,12 @@ if (rootLayer)
invalidReg.Include(rect); invalidReg.Include(rect);
} }
if (rootLayer) { if (rootLayer && !fCurrentLayer->IsHidden()) {
fCurrentLayer->ConvertToScreen(&invalidReg); fCurrentLayer->ConvertToScreen(&invalidReg);
rootLayer->MarkForRedraw(invalidReg); rootLayer->MarkForRedraw(invalidReg);
rootLayer->TriggerRedraw(); rootLayer->TriggerRedraw();
} }
break; break;
} }
case AS_BEGIN_UPDATE: case AS_BEGIN_UPDATE:
@@ -1239,41 +1218,6 @@ if (rootLayer)
STRACE(("ServerWindow %s: Message Delete_Layer_Root unimplemented\n", Title())); STRACE(("ServerWindow %s: Message Delete_Layer_Root unimplemented\n", Title()));
break; break;
} }
case AS_SHOW_WINDOW:
{
STRACE(("ServerWindow %s: Message AS_SHOW_WINDOW\n", Title()));
Show();
break;
}
case AS_HIDE_WINDOW:
{
STRACE(("ServerWindow %s: Message AS_HIDE_WINDOW\n", Title()));
Hide();
break;
}
case AS_SEND_BEHIND:
{
STRACE(("ServerWindow %s: Message Send_Behind unimplemented\n", Title()));
int32 token;
team_id teamID;
status_t status = B_NAME_NOT_FOUND;
link.Read<int32>(&token);
link.Read<team_id>(&teamID);
WindowLayer *behindOf;
if ((behindOf = fDesktop->FindWindowLayerByClientToken(token, teamID)) != NULL) {
fWindowLayer->GetRootLayer()->Lock();
// TODO: move to back ATM. Fix this later!
fWindowLayer->GetRootLayer()->SetActive(fWindowLayer, false);
fWindowLayer->GetRootLayer()->Unlock();
status = B_OK;
}
fLink.StartMessage(status);
fLink.Flush();
break;
}
case AS_BEGIN_TRANSACTION: case AS_BEGIN_TRANSACTION:
{ {
STRACE(("ServerWindow %s: Message AS_BEGIN_TRANSACTION unimplemented\n", STRACE(("ServerWindow %s: Message AS_BEGIN_TRANSACTION unimplemented\n",
@@ -1333,16 +1277,14 @@ if (rootLayer)
link.Read<int32>(&mainToken); link.Read<int32>(&mainToken);
link.Read(&teamID, sizeof(team_id)); link.Read(&teamID, sizeof(team_id));
windowLayer = fDesktop->FindWindowLayerByClientToken(mainToken, teamID); windowLayer = NULL; //fDesktop->FindWindowLayerByClientToken(mainToken, teamID);
if (windowLayer) { if (windowLayer) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Flush(); fLink.Flush();
fWindowLayer->GetRootLayer()->Lock(); //fDesktop->AddWindowLayerToSubset(fWindowLayer, windowLayer);
fDesktop->AddWindowLayerToSubset(fWindowLayer, windowLayer);
fWindowLayer->GetRootLayer()->Unlock();
} else { } else {
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
} }
break; break;
@@ -1357,16 +1299,14 @@ if (rootLayer)
link.Read<int32>(&mainToken); link.Read<int32>(&mainToken);
link.Read(&teamID, sizeof(team_id)); link.Read(&teamID, sizeof(team_id));
windowLayer = fDesktop->FindWindowLayerByClientToken(mainToken, teamID); windowLayer = NULL; //fDesktop->FindWindowLayerByClientToken(mainToken, teamID);
if (windowLayer) { if (windowLayer) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Flush(); fLink.Flush();
fWindowLayer->GetRootLayer()->Lock(); //fDesktop->RemoveWindowLayerFromSubset(fWindowLayer, windowLayer);
fDesktop->RemoveWindowLayerFromSubset(fWindowLayer, windowLayer);
fWindowLayer->GetRootLayer()->Unlock();
} else { } else {
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
} }
break; break;
@@ -1420,10 +1360,7 @@ if (rootLayer)
uint32 newWorkspaces; uint32 newWorkspaces;
link.Read<uint32>(&newWorkspaces); link.Read<uint32>(&newWorkspaces);
fWindowLayer->GetRootLayer()->Lock(); fDesktop->SetWindowWorkspaces(fWindowLayer, newWorkspaces);
fWindowLayer->GetRootLayer()->SetWindowLayerWorskpaces(fWindowLayer,
fWindowLayer->Workspaces(), newWorkspaces);
fWindowLayer->GetRootLayer()->Unlock();
break; break;
} }
case AS_WINDOW_RESIZE: case AS_WINDOW_RESIZE:
@@ -1485,19 +1422,6 @@ if (rootLayer)
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_ACTIVATE_WINDOW:
{
DTRACE(("ServerWindow %s: Message AS_ACTIVATE_WINDOW: Layer: %s\n", Title(), fCurrentLayer->Name()));
bool activate = true;
link.Read<bool>(&activate);
if (rootLayer && rootLayer->Lock()) {
rootLayer->SetActive(fWindowLayer, activate);
rootLayer->Unlock();
}
break;
}
// Some BView drawing messages, but which don't need clipping // Some BView drawing messages, but which don't need clipping
case AS_LAYER_SET_HIGH_COLOR: case AS_LAYER_SET_HIGH_COLOR:
{ {
@@ -2129,6 +2053,52 @@ ServerWindow::_MessageLooper()
CRITICAL("ServerWindow: a window must be hidden before it's deleted\n"); CRITICAL("ServerWindow: a window must be hidden before it's deleted\n");
break; break;
// TODO: these are here temporarily, as they don't lock the root layer
case AS_SHOW_WINDOW:
STRACE(("ServerWindow %s: Message AS_SHOW_WINDOW\n", Title()));
Show();
break;
case AS_HIDE_WINDOW:
STRACE(("ServerWindow %s: Message AS_HIDE_WINDOW\n", Title()));
Hide();
break;
case AS_ACTIVATE_WINDOW:
{
DTRACE(("ServerWindow %s: Message AS_ACTIVATE_WINDOW: Layer: %s\n", Title(), fCurrentLayer->Name()));
bool activate = true;
receiver.Read<bool>(&activate);
if (activate)
fDesktop->ActivateWindow(fWindowLayer);
else
fDesktop->SendBehindWindow(fWindowLayer, NULL);
break;
}
case AS_SEND_BEHIND:
{
STRACE(("ServerWindow %s: Message Send_Behind unimplemented\n", Title()));
int32 token;
team_id teamID;
status_t status;
receiver.Read<int32>(&token);
receiver.Read<team_id>(&teamID);
WindowLayer *behindOf;
if ((behindOf = fDesktop->FindWindowLayerByClientToken(token, teamID)) != NULL) {
fDesktop->SendBehindWindow(fWindowLayer, behindOf);
status = B_OK;
} else
status = B_NAME_NOT_FOUND;
fLink.StartMessage(status);
fLink.Flush();
break;
}
case B_QUIT_REQUESTED: case B_QUIT_REQUESTED:
STRACE(("ServerWindow %s received quit request\n", Title())); STRACE(("ServerWindow %s received quit request\n", Title()));
NotifyQuitRequested(); NotifyQuitRequested();
-6
View File
@@ -14,7 +14,6 @@
#include "MessageLooper.h" #include "MessageLooper.h"
#include "SubWindowList.h"
#include <PortLink.h> #include <PortLink.h>
#include <TokenSpace.h> #include <TokenSpace.h>
@@ -68,8 +67,6 @@ public:
void NotifyQuitRequested(); void NotifyQuitRequested();
void NotifyMinimize(bool minimize); void NotifyMinimize(bool minimize);
void NotifyZoom(); void NotifyZoom();
void NotifyScreenModeChanged(const BRect frame,
const color_space cspace);
// util methods. // util methods.
const BMessenger& FocusMessenger() const { return fFocusMessenger; } const BMessenger& FocusMessenger() const { return fFocusMessenger; }
@@ -103,9 +100,6 @@ public:
void GetInfo(window_info& info); void GetInfo(window_info& info);
// ToDo: public??
SubWindowList fSubWindowList;
private: private:
// methods for retrieving and creating a tree strcture of Layers. // methods for retrieving and creating a tree strcture of Layers.
Layer* CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent); Layer* CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent);
+2 -2
View File
@@ -17,8 +17,8 @@ class WindowLayer;
class SubWindowList : public BList { class SubWindowList : public BList {
public: public:
SubWindowList(void); SubWindowList();
virtual ~SubWindowList(void); virtual ~SubWindowList();
void AddWindowLayer(WindowLayer *windowLayer); void AddWindowLayer(WindowLayer *windowLayer);
+23 -16
View File
@@ -117,6 +117,7 @@ WindowLayer::WindowLayer(const BRect &frame,
if (window->App()->GetDesktop()->ScreenAt(0)) { if (window->App()->GetDesktop()->ScreenAt(0)) {
window->App()->GetDesktop()->ScreenAt(0)->GetMode(width, height, colorSpace, frequency); window->App()->GetDesktop()->ScreenAt(0)->GetMode(width, height, colorSpace, frequency);
// TODO: MOVE THIS AWAY!!! RemoveBy contains calls to virtual methods! Also, there is not TopLayer()! // TODO: MOVE THIS AWAY!!! RemoveBy contains calls to virtual methods! Also, there is not TopLayer()!
fFrame.OffsetTo(B_ORIGIN);
WindowLayer::ResizeBy(width - frame.Width(), height - frame.Height()); WindowLayer::ResizeBy(width - frame.Width(), height - frame.Height());
} }
} }
@@ -390,6 +391,8 @@ WindowLayer::GetSizeLimits(float* minWidth, float* maxWidth,
void void
WindowLayer::MouseDown(BMessage *msg, BPoint where) WindowLayer::MouseDown(BMessage *msg, BPoint where)
{ {
Desktop* desktop = Window()->App()->GetDesktop();
// default action is to drag the WindowLayer // default action is to drag the WindowLayer
Layer *target = LayerAt(where); Layer *target = LayerAt(where);
if (target == this) { if (target == this) {
@@ -449,19 +452,19 @@ WindowLayer::MouseDown(BMessage *msg, BPoint where)
// based on what the Decorator returned, properly place this window. // based on what the Decorator returned, properly place this window.
if (action == DEC_MOVETOBACK) { if (action == DEC_MOVETOBACK) {
GetRootLayer()->SetActive(this, false); desktop->SendBehindWindow(this, NULL);
} else { } else {
GetRootLayer()->SetMouseEventLayer(this); GetRootLayer()->SetMouseEventLayer(this);
GetRootLayer()->SetActive(this); desktop->ActivateWindow(this);
} }
} else if (target != NULL) { } else if (target != NULL) {
// clicking a simple Layer. // clicking a simple Layer.
if (GetRootLayer()->ActiveWorkspace()->Focus() != this) { if (GetRootLayer()->Focus() != this) {
DesktopSettings desktopSettings(GetRootLayer()->GetDesktop()); DesktopSettings desktopSettings(desktop);
// not in FFM mode? // not in FFM mode?
if (desktopSettings.MouseMode() == B_NORMAL_MOUSE) if (desktopSettings.MouseMode() == B_NORMAL_MOUSE)
GetRootLayer()->SetActive(this); desktop->ActivateWindow(this);
if ((WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK) == 0) if ((WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK) == 0)
return; return;
@@ -554,17 +557,11 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where)
fLastMousePosition = where; fLastMousePosition = where;
// change focus in FFM mode // change focus in FFM mode
DesktopSettings desktopSettings(GetRootLayer()->GetDesktop()); Desktop* desktop = Window()->App()->GetDesktop();
// TODO: Focus should be a RootLayer option/feature, NOT a Workspace one!!! DesktopSettings desktopSettings(desktop);
WindowLayer* exFocus = GetRootLayer()->Focus();
if (desktopSettings.MouseMode() != B_NORMAL_MOUSE && exFocus != this) { if (desktopSettings.MouseMode() != B_NORMAL_MOUSE && GetRootLayer()->Focus() != this)
GetRootLayer()->ActiveWorkspace()->AttemptToSetFocus(this); GetRootLayer()->SetFocus(this);
// Workspace::SetFocus() *attempts* to set a new focus WindowLayer, it may not succeed
// if (exFocus != Focus()) {
// TODO: invalidate border area and send message to client for the widgets to light up
// What message? Is there a message on Focus change?
// }
}
Layer* target = LayerAt(where); Layer* target = LayerAt(where);
if (target != NULL && target != this) { if (target != NULL && target != this) {
@@ -668,6 +665,16 @@ WindowLayer::UpdateScreen()
} }
bool
WindowLayer::SupportsFront()
{
if (fFeel == kDesktopWindowFeel)
return false;
return true;
}
void void
WindowLayer::QuietlySetFeel(int32 feel) WindowLayer::QuietlySetFeel(int32 feel)
{ {
+4
View File
@@ -107,6 +107,10 @@ class WindowLayer : public Layer {
inline int32 Level() const { return fLevel; } inline int32 Level() const { return fLevel; }
inline uint32 WindowFlags() const { return fWindowFlags; } inline uint32 WindowFlags() const { return fWindowFlags; }
inline uint32 Workspaces() const { return fWorkspaces; } inline uint32 Workspaces() const { return fWorkspaces; }
void SetWorkspaces(uint32 workspaces)
{ fWorkspaces = workspaces; }
bool SupportsFront();
// 0.0 -> left .... 1.0 -> right // 0.0 -> left .... 1.0 -> right
void SetTabLocation(float location); void SetTabLocation(float location);
File diff suppressed because it is too large Load Diff
+42 -141
View File
@@ -1,166 +1,67 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2005, Haiku, Inc. * Copyright 2005, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * Axel Dörfler, axeld@pinc-software.de
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the #ifndef WORKSPACE_H
// Software is furnished to do so, subject to the following conditions: #define WORKSPACE_H
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// File Name: Workspace.h
// Author: Adi Oanca <[email protected]>
// Description: Tracks workspaces
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Notes: IMPORTANT WARNING
// This object does not use any locking mechanism. It is designed
// to be used only by RootLayer class. DO NOT USE from another class!
//------------------------------------------------------------------------------
#ifndef _WORKSPACE_H_
#define _WORKSPACE_H_
#include <SupportDefs.h>
#include <Locker.h>
#include <Accelerant.h>
#include "RGBColor.h" #include "RGBColor.h"
#include <ObjectList.h>
#include <String.h>
class RootLayer;
class WindowLayer; class WindowLayer;
struct ListData
{ struct display_info {
bool isFree; BString identifier;
WindowLayer *layerPtr; BPoint origin;
ListData *upperItem; display_mode mode;
ListData *lowerItem;
}; };
class Workspace { class Workspace {
public: public:
class State { Workspace();
public: ~Workspace();
State() : Front(NULL), Focus(NULL), WindowList(50) { }
void PrintToStream(); void SetWindows(const BObjectList<WindowLayer>& windows);
bool AddWindow(WindowLayer* window);
void RemoveWindow(WindowLayer* window);
WindowLayer* Front; int32 CountWindows() const { return fWindows.CountItems(); }
WindowLayer* Focus; WindowLayer* WindowAt(int32 index) const { return fWindows.ItemAt(index); }
BList WindowList;
};
Workspace( const int32 ID,
const uint32 colorspace,
const RGBColor& BGColor);
~Workspace();
int32 ID() const { return fID; } // displays
void AddWindowLayer(WindowLayer *winBorder); void SetDisplaysFromDesktop(Desktop* desktop);
void RemoveWindowLayer(WindowLayer *winBorder);
bool HasWindowLayer(const WindowLayer *winBorder) const;
WindowLayer* Focus() const; int32 CountDisplays() const { return fDisplays.CountItems(); }
WindowLayer* Front() const; const display_info* DisplayAt(int32 index) const { return fDisplays.ItemAt(index); }
WindowLayer* Active() const;
void GetState(Workspace::State *state) const;
bool AttemptToSetFront(WindowLayer *newFront);
int32 AttemptToSetFocus(WindowLayer *newFocus);
bool AttemptToMoveToBack(WindowLayer *newBack);
bool AttemptToActivate(WindowLayer *toActivate);
bool GetWindowLayerList(void **list, int32 *itemCount ) const; // configuration
bool MoveToBack(WindowLayer *newLast); const RGBColor& Color() const { return fColor; }
bool MoveToFront(WindowLayer *newFront, bool doNotDisturb = false); void SetColor(const RGBColor& color);
bool HideWindowLayer(WindowLayer *winBorder); void SetSettings(BMessage& settings);
bool ShowWindowLayer(WindowLayer *winBorder, bool userBusy = false); void GetSettings(BMessage& settings);
// resolution related methods.
status_t SetDisplayMode(const display_mode &mode);
status_t GetDisplayMode(display_mode &mode) const;
void SetBGColor(const RGBColor &c);
RGBColor BGColor(void) const;
// settings related methods
void GetSettings(const BMessage &msg);
void GetDefaultSettings(void);
void PutSettings(BMessage *msg, const uint8 &index) const;
static void PutDefaultSettings(BMessage *msg, const uint8 &index);
// debug methods
void PrintToStream(void) const;
void PrintItem(ListData *item) const;
private:
void InsertItem(ListData *item, ListData *before);
void RemoveItem(ListData *item);
ListData* HasItem(const ListData *item, int32 *index = NULL) const;
ListData* HasItem(const WindowLayer *layer, int32 *index = NULL) const;
int32 IndexOf(const ListData *item) const;
bool placeToBack(ListData *newLast);
void placeInFront(ListData *item, const bool userBusy);
int32 _SetFocus(ListData *newFocusItem);
bool removeAndPlaceBefore(const WindowLayer *wb, ListData *beforeItem);
bool removeAndPlaceBefore(ListData *item, ListData *beforeItem);
WindowLayer* searchFirstMainWindow(WindowLayer *wb) const;
WindowLayer* searchANormalWindow(WindowLayer *wb) const;
bool windowHasVisibleModals(const WindowLayer *winBorder) const;
ListData* putModalsInFront(ListData *item);
void putFloatingInFront(ListData *item);
void saveFloatingWindows(ListData *itemNormal);
ListData* findNextFront() const;
class MemoryPool
{
public:
MemoryPool();
~MemoryPool();
ListData* GetCleanMemory(WindowLayer* winborder);
void ReleaseMemory(ListData* mem);
private: private:
void expandBuffer(int32 start); void _SetDefaults();
ListData *buffer;
int32 count;
};
int32 fID; BObjectList<WindowLayer> fWindows;
RGBColor fBGColor; WindowLayer* fFront;
WindowLayer* fFocus;
// first visible onscreen BObjectList<display_info> fDisplays;
ListData *fBottomItem;
// the last visible(or covered by other Layers) RGBColor fColor;
ListData *fTopItem;
// the focus WindowLayer - for keyboard events
ListData *fFocusItem;
// pointer for which "big" actions are intended
ListData *fFrontItem;
// settings for each workspace
display_mode fDisplayMode;
MemoryPool fPool;
}; };
#endif #endif /* WORKSPACE_H */
+8 -8
View File
@@ -34,7 +34,7 @@ WorkspacesLayer::~WorkspacesLayer()
void void
WorkspacesLayer::_GetGrid(int32& columns, int32& rows) WorkspacesLayer::_GetGrid(int32& columns, int32& rows)
{ {
int32 count = GetRootLayer()->WorkspaceCount(); int32 count = 4; //GetRootLayer()->WorkspaceCount();
rows = 1; rows = 1;
for (int32 i = 2; i < count; i++) { for (int32 i = 2; i < count; i++) {
@@ -140,8 +140,8 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
{ {
BRect rect = _WorkspaceAt(index); BRect rect = _WorkspaceAt(index);
Workspace* workspace = GetRootLayer()->WorkspaceAt(index); Workspace* workspace = NULL;
bool active = workspace == GetRootLayer()->ActiveWorkspace(); bool active = index == 0;
if (active) { if (active) {
// draw active frame // draw active frame
RGBColor black(0, 0, 0); RGBColor black(0, 0, 0);
@@ -155,7 +155,7 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
// ToDo: fix me - workspaces must always exist, not only on first visit! // ToDo: fix me - workspaces must always exist, not only on first visit!
if (workspace != NULL) if (workspace != NULL)
color = workspace->BGColor(); color = workspace->Color();
else else
color.SetColor(51, 102, 152); color.SetColor(51, 102, 152);
@@ -171,9 +171,9 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
if (workspace != NULL) { if (workspace != NULL) {
WindowLayer* windows[256]; WindowLayer* windows[256];
int32 count = 256; int32 count = 0;
if (!workspace->GetWindowLayerList((void **)&windows, &count)) // if (!workspace->GetWindowLayerList((void **)&windows, &count))
return; // return;
uint16 width, height; uint16 width, height;
uint32 colorSpace; uint32 colorSpace;
@@ -244,7 +244,7 @@ WorkspacesLayer::Draw(const BRect& updateRect)
// draw workspaces // draw workspaces
int32 count = GetRootLayer()->WorkspaceCount(); int32 count = 4; //GetRootLayer()->WorkspaceCount();
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
_DrawWorkspace(i); _DrawWorkspace(i);