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:
parent
8fc80f17d9
commit
27adb96962
@ -98,19 +98,8 @@ KeyboardFilter::Filter(BMessage* message, BHandler** /*_target*/)
|
||||
#endif
|
||||
{
|
||||
STRACE(("Set Workspace %ld\n", key - 1));
|
||||
RootLayer* root = fDesktop->RootLayer();
|
||||
|
||||
root->Lock();
|
||||
root->SetActiveWorkspace(key - 2);
|
||||
|
||||
#ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER
|
||||
// to draw the current Workspace index on screen.
|
||||
BRegion region(VisibleRegion());
|
||||
fDesktop->GetDrawingEngine()->ConstrainClippingRegion(®ion);
|
||||
root->Draw(region.Frame());
|
||||
fDesktop->GetDrawingEngine()->ConstrainClippingRegion(NULL);
|
||||
#endif
|
||||
root->Unlock();
|
||||
fDesktop->SetWorkspace(key - 2);
|
||||
return B_SKIP_MESSAGE;
|
||||
}
|
||||
}
|
||||
@ -188,7 +177,7 @@ Desktop::Init()
|
||||
// TODO: add user identity to the name
|
||||
char name[32];
|
||||
sprintf(name, "RootLayer %d", 1);
|
||||
fRootLayer = new ::RootLayer(name, 4, this, GetDrawingEngine());
|
||||
fRootLayer = new ::RootLayer(name, this, GetDrawingEngine());
|
||||
|
||||
#if TEST_MODE
|
||||
gInputManager->AddStream(new InputServerStream);
|
||||
@ -436,20 +425,13 @@ Desktop::_ActivateApp(team_id team)
|
||||
int32 windowCount = WindowList().CountItems();
|
||||
for (int32 i = 0; i < windowCount; ++i) {
|
||||
// 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 != NULL && !winBorder->IsHidden()
|
||||
&& winBorder->App()->ClientTeam() == team) {
|
||||
if (fRootLayer->Lock()) {
|
||||
fRootLayer->SetActive(winBorder);
|
||||
fRootLayer->Unlock();
|
||||
|
||||
if (fRootLayer->Active() == winBorder)
|
||||
return B_OK;
|
||||
|
||||
status = B_ERROR;
|
||||
}
|
||||
if (windowLayer != NULL && !windowLayer->IsHidden()
|
||||
&& windowLayer->App()->ClientTeam() == team) {
|
||||
fRootLayer->ActivateWindow(windowLayer);
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
Desktop::ScreenChanged(Screen* screen)
|
||||
{
|
||||
@ -506,204 +501,72 @@ Desktop::ScreenChanged(Screen* screen)
|
||||
|
||||
|
||||
void
|
||||
Desktop::AddWindowLayer(WindowLayer *winBorder)
|
||||
Desktop::ActivateWindow(WindowLayer* windowLayer)
|
||||
{
|
||||
if (!winBorder)
|
||||
return;
|
||||
fRootLayer->ActivateWindow(windowLayer);
|
||||
}
|
||||
|
||||
int32 feel = winBorder->Feel();
|
||||
|
||||
// we are ServerApp thread, we need to lock RootLayer here.
|
||||
RootLayer()->Lock();
|
||||
void
|
||||
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();
|
||||
|
||||
if (fWindowLayerList.HasItem(winBorder)) {
|
||||
if (fWindowLayerList.HasItem(windowLayer)) {
|
||||
Unlock();
|
||||
RootLayer()->Unlock();
|
||||
debugger("AddWindowLayer: WindowLayer already in Desktop list\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// we have a new window. store a record of it.
|
||||
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!
|
||||
fWindowLayerList.AddItem(windowLayer);
|
||||
Unlock();
|
||||
|
||||
RootLayer()->Unlock();
|
||||
RootLayer()->AddWindowLayer(windowLayer);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
|
||||
// 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);
|
||||
|
||||
fWindowLayerList.RemoveItem(windowLayer);
|
||||
Unlock();
|
||||
RootLayer()->Unlock();
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
RootLayer()->RemoveWindowLayer(windowLayer);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Desktop::SetWindowLayerFeel(WindowLayer *winBorder, uint32 feel)
|
||||
{
|
||||
// NOTE: this method is called from RootLayer thread only
|
||||
|
||||
// we're playing with window list. lock first.
|
||||
Lock();
|
||||
|
||||
RemoveWindowLayer(winBorder);
|
||||
winBorder->QuietlySetFeel(feel);
|
||||
AddWindowLayer(winBorder);
|
||||
|
||||
Unlock();
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef _DESKTOP_H_
|
||||
#define _DESKTOP_H_
|
||||
#ifndef DESKTOP_H
|
||||
#define DESKTOP_H
|
||||
|
||||
|
||||
#include "CursorManager.h"
|
||||
@ -18,6 +18,7 @@
|
||||
#include "VirtualScreen.h"
|
||||
#include "DesktopSettings.h"
|
||||
#include "MessageLooper.h"
|
||||
#include "Workspace.h"
|
||||
|
||||
#include <InterfaceDefs.h>
|
||||
#include <List.h>
|
||||
@ -41,87 +42,103 @@ namespace BPrivate {
|
||||
|
||||
|
||||
class Desktop : public MessageLooper, public ScreenOwner {
|
||||
public:
|
||||
// startup methods
|
||||
public:
|
||||
Desktop(uid_t userID);
|
||||
virtual ~Desktop();
|
||||
virtual ~Desktop();
|
||||
|
||||
void Init();
|
||||
void Init();
|
||||
|
||||
uid_t UserID() const { return fUserID; }
|
||||
virtual port_id MessagePort() const { return fMessagePort; }
|
||||
uid_t UserID() const { return fUserID; }
|
||||
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.
|
||||
inline Screen* ScreenAt(int32 index) const
|
||||
// Screen and drawing related methods
|
||||
|
||||
Screen* ScreenAt(int32 index) const
|
||||
{ return fActiveScreen; }
|
||||
inline Screen* ActiveScreen() const
|
||||
Screen* ActiveScreen() const
|
||||
{ return fActiveScreen; }
|
||||
inline ::RootLayer* RootLayer() const { return fRootLayer; }
|
||||
inline CursorManager& GetCursorManager() { return fCursorManager; }
|
||||
::RootLayer* RootLayer() const { return fRootLayer; }
|
||||
CursorManager& GetCursorManager() { return fCursorManager; }
|
||||
|
||||
void ScreenChanged(Screen* screen);
|
||||
void ScreenChanged(Screen* screen);
|
||||
|
||||
virtual void ScreenRemoved(Screen* screen) {}
|
||||
virtual void ScreenAdded(Screen* screen) {}
|
||||
virtual bool ReleaseScreen(Screen* screen) { return false; }
|
||||
void ScreenRemoved(Screen* screen) {}
|
||||
void ScreenAdded(Screen* screen) {}
|
||||
bool ReleaseScreen(Screen* screen) { return false; }
|
||||
|
||||
const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; }
|
||||
inline DrawingEngine* GetDrawingEngine() const
|
||||
const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; }
|
||||
DrawingEngine* GetDrawingEngine() const
|
||||
{ return fVirtualScreen.DrawingEngine(); }
|
||||
inline ::HWInterface* HWInterface() const
|
||||
::HWInterface* HWInterface() const
|
||||
{ return fVirtualScreen.HWInterface(); }
|
||||
|
||||
// Methods for layer(WindowLayer) manipulation.
|
||||
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);
|
||||
// Workspace methods
|
||||
|
||||
WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID);
|
||||
//WindowLayer* FindWindowLayerByServerToken(int32 token);
|
||||
void SetWorkspace(int32 index);
|
||||
int32 CurrentWorkspace()
|
||||
{ return fCurrentWorkspace; }
|
||||
::Workspace& WorkspaceAt(int32 index)
|
||||
{ return fWorkspaces[index]; }
|
||||
|
||||
// get list of registed windows
|
||||
const BObjectList<WindowLayer>& WindowList() const;
|
||||
// WindowLayer methods
|
||||
|
||||
void WriteWindowList(team_id team, BPrivate::LinkSender& sender);
|
||||
void WriteWindowInfo(int32 serverToken, BPrivate::LinkSender& sender);
|
||||
void ActivateWindow(WindowLayer* window);
|
||||
void SendBehindWindow(WindowLayer* window, WindowLayer* front);
|
||||
|
||||
private:
|
||||
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);
|
||||
void SetWindowWorkspaces(WindowLayer* window, uint32 workspaces);
|
||||
|
||||
private:
|
||||
friend class DesktopSettings;
|
||||
void AddWindowLayer(WindowLayer *windowLayer);
|
||||
void RemoveWindowLayer(WindowLayer *windowLayer);
|
||||
void SetWindowLayerFeel(WindowLayer *windowLayer,
|
||||
uint32 feel);
|
||||
|
||||
uid_t fUserID;
|
||||
::VirtualScreen fVirtualScreen;
|
||||
DesktopSettings::Private* fSettings;
|
||||
port_id fMessagePort;
|
||||
::EventDispatcher fEventDispatcher;
|
||||
port_id fInputPort;
|
||||
WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID);
|
||||
//WindowLayer* FindWindowLayerByServerToken(int32 token);
|
||||
|
||||
BLocker fAppListLock;
|
||||
BList fAppList;
|
||||
// get list of registed windows
|
||||
const BObjectList<WindowLayer>& WindowList() const;
|
||||
|
||||
sem_id fShutdownSemaphore;
|
||||
int32 fShutdownCount;
|
||||
void WriteWindowList(team_id team,
|
||||
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;
|
||||
Screen* fActiveScreen;
|
||||
|
||||
CursorManager fCursorManager;
|
||||
private:
|
||||
friend class DesktopSettings;
|
||||
|
||||
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
@ -40,116 +40,103 @@ namespace BPrivate {
|
||||
class UtilityBitmap;
|
||||
#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 {
|
||||
public:
|
||||
RootLayer(const char *name, int32 workspaceCount,
|
||||
Desktop *desktop, DrawingEngine *driver);
|
||||
virtual ~RootLayer(void);
|
||||
public:
|
||||
RootLayer(const char *name, Desktop *desktop,
|
||||
DrawingEngine *driver);
|
||||
virtual ~RootLayer();
|
||||
|
||||
Desktop* GetDesktop() const { return fDesktop; }
|
||||
Desktop* GetDesktop() const { return fDesktop; }
|
||||
|
||||
virtual void MoveBy(float x, float y);
|
||||
virtual void ResizeBy(float x, float y);
|
||||
virtual void ScrollBy(float x, float y)
|
||||
{ /* not allowed */ }
|
||||
virtual void MoveBy(float x, float y);
|
||||
virtual void ResizeBy(float x, float y);
|
||||
virtual void ScrollBy(float x, float y)
|
||||
{ /* not allowed */ }
|
||||
|
||||
void HideWindowLayer(WindowLayer* windowLayer);
|
||||
void ShowWindowLayer(WindowLayer* windowLayer);
|
||||
void SetWindowLayerWorskpaces(WindowLayer *windowLayer,
|
||||
uint32 oldIndex, uint32 newIndex);
|
||||
void HideWindowLayer(WindowLayer* windowLayer);
|
||||
void ShowWindowLayer(WindowLayer* windowLayer, bool toFront = true);
|
||||
|
||||
void RevealNewWMState(Workspace::State &oldWMState);
|
||||
// TODO: we need to replace Winborder* with Layer*
|
||||
inline WindowLayer* Focus() const { return fWMState.Focus; }
|
||||
inline WindowLayer* Front() const { return fWMState.Front; }
|
||||
inline WindowLayer* Active() const { return fWMState.Focus; }
|
||||
bool SetActive(WindowLayer* newActive, bool activate = true);
|
||||
// void RevealNewWMState(Workspace::State &oldWMState);
|
||||
bool SetFocus(WindowLayer* focus);
|
||||
WindowLayer* Focus() const { return fFocus; }
|
||||
WindowLayer* Front() const { return fFront; }
|
||||
WindowLayer* Back() const { return fBack; }
|
||||
|
||||
inline void SetWorkspaceCount(int32 wksCount);
|
||||
inline int32 WorkspaceCount() const { return fWsCount; }
|
||||
inline Workspace* WorkspaceAt(int32 index) const { return fWorkspace[index]; }
|
||||
inline Workspace* ActiveWorkspace() const { return fWorkspace[fActiveWksIndex]; }
|
||||
inline int32 ActiveWorkspaceIndex() const { return fActiveWksIndex; }
|
||||
bool SetActiveWorkspace(int32 index);
|
||||
void SetWorkspace(int32 index, Workspace& workspace);
|
||||
void SetWorkspacesLayer(Layer* layer) { fWorkspacesLayer = layer; }
|
||||
Layer* WorkspacesLayer() const { return fWorkspacesLayer; }
|
||||
|
||||
void ReadWorkspaceData(const char *path);
|
||||
void SaveWorkspaceData(const char *path);
|
||||
#if 0
|
||||
void SetBGColor(const RGBColor &col);
|
||||
RGBColor BGColor(void) const;
|
||||
#endif
|
||||
|
||||
void SetWorkspacesLayer(Layer* layer) { fWorkspacesLayer = layer; }
|
||||
Layer* WorkspacesLayer() const { return fWorkspacesLayer; }
|
||||
|
||||
void SetBGColor(const RGBColor &col);
|
||||
RGBColor BGColor(void) const;
|
||||
void SetDragMessage(BMessage *msg);
|
||||
BMessage* DragMessage() const;
|
||||
|
||||
void SetDragMessage(BMessage *msg);
|
||||
BMessage* DragMessage(void) const;
|
||||
void SetMouseEventLayer(Layer* layer);
|
||||
|
||||
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
|
||||
bool Lock() { return fAllRegionsLock.Lock(); }
|
||||
void Unlock() { fAllRegionsLock.Unlock(); }
|
||||
bool IsLocked() { return fAllRegionsLock.IsLocked(); }
|
||||
void ActivateWindow(WindowLayer* window);
|
||||
void SendBehindWindow(WindowLayer* window, WindowLayer* front);
|
||||
|
||||
void ChangeWindowLayerFeel(WindowLayer *windowLayer, int32 newFeel);
|
||||
void SetWindowLayerFeel(WindowLayer *windowLayer, int32 newFeel);
|
||||
void SetWindowLayerLook(WindowLayer *windowLayer, int32 newLook);
|
||||
|
||||
void MarkForRedraw(const BRegion &dirty);
|
||||
void TriggerRedraw();
|
||||
void MarkForRedraw(const BRegion &dirty);
|
||||
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:
|
||||
friend class Desktop;
|
||||
void AddWindowLayer(WindowLayer* windowLayer);
|
||||
void RemoveWindowLayer(WindowLayer* windowLayer);
|
||||
|
||||
// these are meant for Desktop class only!
|
||||
void AddWindowLayer(WindowLayer* windowLayer);
|
||||
void RemoveWindowLayer(WindowLayer* windowLayer);
|
||||
void AddSubsetWindowLayer(WindowLayer *windowLayer, WindowLayer *toWindowLayer);
|
||||
void RemoveSubsetWindowLayer(WindowLayer *windowLayer, WindowLayer *fromWindowLayer);
|
||||
void MouseEventHandler(BMessage *msg);
|
||||
|
||||
void MouseEventHandler(BMessage *msg);
|
||||
Layer* _ChildAt(BPoint where);
|
||||
private:
|
||||
bool _SetFocus(WindowLayer* focus, BRegion& update);
|
||||
void _SetFront(WindowLayer* front, BRegion& update);
|
||||
void _UpdateBack();
|
||||
void _UpdateFront();
|
||||
void _UpdateFronts();
|
||||
|
||||
Desktop* fDesktop;
|
||||
BMessage* fDragMessage;
|
||||
Layer* fMouseEventLayer;
|
||||
void _WindowsChanged(BRegion& region);
|
||||
void _UpdateWorkspace(Workspace& workspace);
|
||||
|
||||
uint32 fSavedEventMask;
|
||||
uint32 fSavedEventOptions;
|
||||
Layer* _ChildAt(BPoint where);
|
||||
|
||||
BLocker fAllRegionsLock;
|
||||
Desktop* fDesktop;
|
||||
BMessage* fDragMessage;
|
||||
Layer* fMouseEventLayer;
|
||||
|
||||
BRegion fDirtyForRedraw;
|
||||
BLocker fAllRegionsLock;
|
||||
|
||||
int32 fActiveWksIndex;
|
||||
int32 fWsCount;
|
||||
Workspace** fWorkspace;
|
||||
Layer* fWorkspacesLayer;
|
||||
BRegion fDirtyForRedraw;
|
||||
|
||||
// TODO: fWMState MUST be associated with a surface. This is the case now
|
||||
// with RootLayer, but after Axel's refractoring this should go in
|
||||
// WorkspaceLayer, I think.
|
||||
Workspace::State fWMState;
|
||||
int32 fWorkspace;
|
||||
RGBColor fColor;
|
||||
Layer* fWorkspacesLayer;
|
||||
|
||||
WindowLayer* fFocus;
|
||||
WindowLayer* fFront;
|
||||
WindowLayer* fBack;
|
||||
|
||||
#if ON_SCREEN_DEBUGGING_INFO
|
||||
friend class DebugInfoManager;
|
||||
void AddDebugInfo(const char* string);
|
||||
BString fDebugInfo;
|
||||
friend class DebugInfoManager;
|
||||
void AddDebugInfo(const char* string);
|
||||
BString fDebugInfo;
|
||||
#endif
|
||||
#if DISPLAY_HAIKU_LOGO
|
||||
UtilityBitmap* fLogoBitmap;
|
||||
UtilityBitmap* fLogoBitmap;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -849,18 +849,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
{
|
||||
STRACE(("ServerApp %s: get current workspace\n", Signature()));
|
||||
|
||||
// TODO: Locking this way is not nice
|
||||
RootLayer *root = fDesktop->RootLayer();
|
||||
root->Lock();
|
||||
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.Attach<int32>(root->ActiveWorkspaceIndex());
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<int32>(fDesktop->CurrentWorkspace());
|
||||
fLink.Flush();
|
||||
|
||||
root->Unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case AS_ACTIVATE_WORKSPACE:
|
||||
{
|
||||
STRACE(("ServerApp %s: activate workspace\n", Signature()));
|
||||
@ -868,15 +862,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
// TODO: See above
|
||||
int32 index;
|
||||
link.Read<int32>(&index);
|
||||
RootLayer *root = fDesktop->RootLayer();
|
||||
root->Lock();
|
||||
root->SetActiveWorkspace(index);
|
||||
root->Unlock();
|
||||
// no reply
|
||||
|
||||
|
||||
fDesktop->SetWorkspace(index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case AS_SHOW_CURSOR:
|
||||
{
|
||||
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()));
|
||||
|
||||
uint32 workspaceIndex;
|
||||
link.Read<uint32>(&workspaceIndex);
|
||||
uint32 index;
|
||||
link.Read<uint32>(&index);
|
||||
|
||||
// ToDo: locking is probably wrong - why the hell is there no (safe)
|
||||
// way to get to the workspace object directly?
|
||||
RootLayer *root = fDesktop->RootLayer();
|
||||
root->Lock();
|
||||
|
||||
Workspace *workspace;
|
||||
fLink.StartMessage(B_OK);
|
||||
fDesktop->Lock();
|
||||
|
||||
// we're nice to our children (and also take the default case
|
||||
// into account which asks for the current workspace)
|
||||
if (workspaceIndex > (uint32)root->WorkspaceCount())
|
||||
workspace = root->ActiveWorkspace();
|
||||
else
|
||||
workspace = root->WorkspaceAt(workspaceIndex);
|
||||
if (index >= (uint32)kMaxWorkspaces)
|
||||
index = fDesktop->CurrentWorkspace();
|
||||
|
||||
if (workspace != NULL) {
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Attach<rgb_color>(workspace->BGColor().GetColor32());
|
||||
} else
|
||||
fLink.StartMessage(B_ERROR);
|
||||
Workspace& workspace = fDesktop->WorkspaceAt(index);
|
||||
fLink.Attach<rgb_color>(workspace.Color().GetColor32());
|
||||
|
||||
fDesktop->Unlock();
|
||||
fLink.Flush();
|
||||
root->Unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
|
||||
#include "MessageLooper.h"
|
||||
#include "SubWindowList.h"
|
||||
#include "BGet++.h"
|
||||
|
||||
#include <String.h>
|
||||
@ -78,9 +77,6 @@ class ServerApp : public MessageLooper {
|
||||
|
||||
BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; }
|
||||
|
||||
// ToDo: public?
|
||||
SubWindowList fAppSubWindowList;
|
||||
|
||||
private:
|
||||
virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
|
||||
virtual void _MessageLooper();
|
||||
|
@ -294,13 +294,11 @@ ServerWindow::Show()
|
||||
return;
|
||||
|
||||
RootLayer* rootLayer = fWindowLayer->GetRootLayer();
|
||||
if (rootLayer && rootLayer->Lock()) {
|
||||
if (rootLayer)
|
||||
rootLayer->ShowWindowLayer(fWindowLayer);
|
||||
rootLayer->Unlock();
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
HandleDirectConnection(B_DIRECT_STOP);
|
||||
|
||||
|
||||
RootLayer* rootLayer = fWindowLayer->GetRootLayer();
|
||||
if (rootLayer && rootLayer->Lock()) {
|
||||
if (rootLayer)
|
||||
rootLayer->HideWindowLayer(fWindowLayer);
|
||||
rootLayer->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -404,23 +400,6 @@ ServerWindow::NotifyZoom()
|
||||
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
|
||||
ServerWindow::GetInfo(window_info& info)
|
||||
@ -696,7 +675,8 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
|
||||
if (rootLayer) {
|
||||
rootLayer->LayerRemoved(fCurrentLayer);
|
||||
rootLayer->TriggerRedraw();
|
||||
if (!fCurrentLayer->IsHidden())
|
||||
rootLayer->TriggerRedraw();
|
||||
}
|
||||
|
||||
if (fCurrentLayer->EventMask() != 0) {
|
||||
@ -992,7 +972,7 @@ if (rootLayer)
|
||||
rootLayer->Lock();
|
||||
fCurrentLayer->SetViewColor(RGBColor(c));
|
||||
|
||||
if (rootLayer) {
|
||||
if (rootLayer && !fCurrentLayer->IsHidden()) {
|
||||
rootLayer->MarkForRedraw(fCurrentLayer->VisibleRegion());
|
||||
rootLayer->TriggerRedraw();
|
||||
}
|
||||
@ -1177,7 +1157,7 @@ if (rootLayer)
|
||||
|
||||
link.Read<BRect>(&invalRect);
|
||||
|
||||
if (rootLayer) {
|
||||
if (rootLayer && !fCurrentLayer->IsHidden()) {
|
||||
BRect converted(invalRect.LeftTop(), invalRect.RightBottom());
|
||||
|
||||
fCurrentLayer->ConvertToScreen(&converted);
|
||||
@ -1206,13 +1186,12 @@ if (rootLayer)
|
||||
invalidReg.Include(rect);
|
||||
}
|
||||
|
||||
if (rootLayer) {
|
||||
if (rootLayer && !fCurrentLayer->IsHidden()) {
|
||||
fCurrentLayer->ConvertToScreen(&invalidReg);
|
||||
|
||||
rootLayer->MarkForRedraw(invalidReg);
|
||||
rootLayer->TriggerRedraw();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_BEGIN_UPDATE:
|
||||
@ -1239,41 +1218,6 @@ if (rootLayer)
|
||||
STRACE(("ServerWindow %s: Message Delete_Layer_Root unimplemented\n", Title()));
|
||||
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:
|
||||
{
|
||||
STRACE(("ServerWindow %s: Message AS_BEGIN_TRANSACTION unimplemented\n",
|
||||
@ -1333,16 +1277,14 @@ if (rootLayer)
|
||||
link.Read<int32>(&mainToken);
|
||||
link.Read(&teamID, sizeof(team_id));
|
||||
|
||||
windowLayer = fDesktop->FindWindowLayerByClientToken(mainToken, teamID);
|
||||
windowLayer = NULL; //fDesktop->FindWindowLayerByClientToken(mainToken, teamID);
|
||||
if (windowLayer) {
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Flush();
|
||||
|
||||
fWindowLayer->GetRootLayer()->Lock();
|
||||
fDesktop->AddWindowLayerToSubset(fWindowLayer, windowLayer);
|
||||
fWindowLayer->GetRootLayer()->Unlock();
|
||||
//fDesktop->AddWindowLayerToSubset(fWindowLayer, windowLayer);
|
||||
} else {
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_ERROR);
|
||||
fLink.Flush();
|
||||
}
|
||||
break;
|
||||
@ -1357,16 +1299,14 @@ if (rootLayer)
|
||||
link.Read<int32>(&mainToken);
|
||||
link.Read(&teamID, sizeof(team_id));
|
||||
|
||||
windowLayer = fDesktop->FindWindowLayerByClientToken(mainToken, teamID);
|
||||
windowLayer = NULL; //fDesktop->FindWindowLayerByClientToken(mainToken, teamID);
|
||||
if (windowLayer) {
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.StartMessage(B_OK);
|
||||
fLink.Flush();
|
||||
|
||||
fWindowLayer->GetRootLayer()->Lock();
|
||||
fDesktop->RemoveWindowLayerFromSubset(fWindowLayer, windowLayer);
|
||||
fWindowLayer->GetRootLayer()->Unlock();
|
||||
//fDesktop->RemoveWindowLayerFromSubset(fWindowLayer, windowLayer);
|
||||
} else {
|
||||
fLink.StartMessage(SERVER_FALSE);
|
||||
fLink.StartMessage(B_ERROR);
|
||||
fLink.Flush();
|
||||
}
|
||||
break;
|
||||
@ -1420,10 +1360,7 @@ if (rootLayer)
|
||||
uint32 newWorkspaces;
|
||||
link.Read<uint32>(&newWorkspaces);
|
||||
|
||||
fWindowLayer->GetRootLayer()->Lock();
|
||||
fWindowLayer->GetRootLayer()->SetWindowLayerWorskpaces(fWindowLayer,
|
||||
fWindowLayer->Workspaces(), newWorkspaces);
|
||||
fWindowLayer->GetRootLayer()->Unlock();
|
||||
fDesktop->SetWindowWorkspaces(fWindowLayer, newWorkspaces);
|
||||
break;
|
||||
}
|
||||
case AS_WINDOW_RESIZE:
|
||||
@ -1485,19 +1422,6 @@ if (rootLayer)
|
||||
fLink.Flush();
|
||||
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
|
||||
case AS_LAYER_SET_HIGH_COLOR:
|
||||
{
|
||||
@ -2129,6 +2053,52 @@ ServerWindow::_MessageLooper()
|
||||
CRITICAL("ServerWindow: a window must be hidden before it's deleted\n");
|
||||
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:
|
||||
STRACE(("ServerWindow %s received quit request\n", Title()));
|
||||
NotifyQuitRequested();
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
|
||||
#include "MessageLooper.h"
|
||||
#include "SubWindowList.h"
|
||||
|
||||
#include <PortLink.h>
|
||||
#include <TokenSpace.h>
|
||||
@ -68,8 +67,6 @@ public:
|
||||
void NotifyQuitRequested();
|
||||
void NotifyMinimize(bool minimize);
|
||||
void NotifyZoom();
|
||||
void NotifyScreenModeChanged(const BRect frame,
|
||||
const color_space cspace);
|
||||
|
||||
// util methods.
|
||||
const BMessenger& FocusMessenger() const { return fFocusMessenger; }
|
||||
@ -103,9 +100,6 @@ public:
|
||||
|
||||
void GetInfo(window_info& info);
|
||||
|
||||
// ToDo: public??
|
||||
SubWindowList fSubWindowList;
|
||||
|
||||
private:
|
||||
// methods for retrieving and creating a tree strcture of Layers.
|
||||
Layer* CreateLayerTree(BPrivate::LinkReceiver &link, Layer **_parent);
|
||||
|
@ -17,8 +17,8 @@ class WindowLayer;
|
||||
|
||||
class SubWindowList : public BList {
|
||||
public:
|
||||
SubWindowList(void);
|
||||
virtual ~SubWindowList(void);
|
||||
SubWindowList();
|
||||
virtual ~SubWindowList();
|
||||
|
||||
void AddWindowLayer(WindowLayer *windowLayer);
|
||||
|
||||
|
@ -117,6 +117,7 @@ WindowLayer::WindowLayer(const BRect &frame,
|
||||
if (window->App()->GetDesktop()->ScreenAt(0)) {
|
||||
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()!
|
||||
fFrame.OffsetTo(B_ORIGIN);
|
||||
WindowLayer::ResizeBy(width - frame.Width(), height - frame.Height());
|
||||
}
|
||||
}
|
||||
@ -390,6 +391,8 @@ WindowLayer::GetSizeLimits(float* minWidth, float* maxWidth,
|
||||
void
|
||||
WindowLayer::MouseDown(BMessage *msg, BPoint where)
|
||||
{
|
||||
Desktop* desktop = Window()->App()->GetDesktop();
|
||||
|
||||
// default action is to drag the WindowLayer
|
||||
Layer *target = LayerAt(where);
|
||||
if (target == this) {
|
||||
@ -449,19 +452,19 @@ WindowLayer::MouseDown(BMessage *msg, BPoint where)
|
||||
|
||||
// based on what the Decorator returned, properly place this window.
|
||||
if (action == DEC_MOVETOBACK) {
|
||||
GetRootLayer()->SetActive(this, false);
|
||||
desktop->SendBehindWindow(this, NULL);
|
||||
} else {
|
||||
GetRootLayer()->SetMouseEventLayer(this);
|
||||
GetRootLayer()->SetActive(this);
|
||||
desktop->ActivateWindow(this);
|
||||
}
|
||||
} else if (target != NULL) {
|
||||
// clicking a simple Layer.
|
||||
if (GetRootLayer()->ActiveWorkspace()->Focus() != this) {
|
||||
DesktopSettings desktopSettings(GetRootLayer()->GetDesktop());
|
||||
if (GetRootLayer()->Focus() != this) {
|
||||
DesktopSettings desktopSettings(desktop);
|
||||
|
||||
// not in FFM mode?
|
||||
if (desktopSettings.MouseMode() == B_NORMAL_MOUSE)
|
||||
GetRootLayer()->SetActive(this);
|
||||
desktop->ActivateWindow(this);
|
||||
|
||||
if ((WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK) == 0)
|
||||
return;
|
||||
@ -554,17 +557,11 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where)
|
||||
fLastMousePosition = where;
|
||||
|
||||
// change focus in FFM mode
|
||||
DesktopSettings desktopSettings(GetRootLayer()->GetDesktop());
|
||||
// TODO: Focus should be a RootLayer option/feature, NOT a Workspace one!!!
|
||||
WindowLayer* exFocus = GetRootLayer()->Focus();
|
||||
if (desktopSettings.MouseMode() != B_NORMAL_MOUSE && exFocus != this) {
|
||||
GetRootLayer()->ActiveWorkspace()->AttemptToSetFocus(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?
|
||||
// }
|
||||
}
|
||||
Desktop* desktop = Window()->App()->GetDesktop();
|
||||
DesktopSettings desktopSettings(desktop);
|
||||
|
||||
if (desktopSettings.MouseMode() != B_NORMAL_MOUSE && GetRootLayer()->Focus() != this)
|
||||
GetRootLayer()->SetFocus(this);
|
||||
|
||||
Layer* target = LayerAt(where);
|
||||
if (target != NULL && target != this) {
|
||||
@ -668,6 +665,16 @@ WindowLayer::UpdateScreen()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WindowLayer::SupportsFront()
|
||||
{
|
||||
if (fFeel == kDesktopWindowFeel)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WindowLayer::QuietlySetFeel(int32 feel)
|
||||
{
|
||||
|
@ -107,6 +107,10 @@ class WindowLayer : public Layer {
|
||||
inline int32 Level() const { return fLevel; }
|
||||
inline uint32 WindowFlags() const { return fWindowFlags; }
|
||||
inline uint32 Workspaces() const { return fWorkspaces; }
|
||||
void SetWorkspaces(uint32 workspaces)
|
||||
{ fWorkspaces = workspaces; }
|
||||
|
||||
bool SupportsFront();
|
||||
|
||||
// 0.0 -> left .... 1.0 -> right
|
||||
void SetTabLocation(float location);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,166 +1,67 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2005, Haiku, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// 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 <adioanca@cotty.iren.com>
|
||||
// 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_
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef WORKSPACE_H
|
||||
#define WORKSPACE_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <Locker.h>
|
||||
#include <Accelerant.h>
|
||||
|
||||
#include "RGBColor.h"
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class RootLayer;
|
||||
class WindowLayer;
|
||||
|
||||
struct ListData
|
||||
{
|
||||
bool isFree;
|
||||
WindowLayer *layerPtr;
|
||||
ListData *upperItem;
|
||||
ListData *lowerItem;
|
||||
|
||||
struct display_info {
|
||||
BString identifier;
|
||||
BPoint origin;
|
||||
display_mode mode;
|
||||
};
|
||||
|
||||
class Workspace {
|
||||
public:
|
||||
class State {
|
||||
public:
|
||||
State() : Front(NULL), Focus(NULL), WindowList(50) { }
|
||||
Workspace();
|
||||
~Workspace();
|
||||
|
||||
void PrintToStream();
|
||||
void SetWindows(const BObjectList<WindowLayer>& windows);
|
||||
bool AddWindow(WindowLayer* window);
|
||||
void RemoveWindow(WindowLayer* window);
|
||||
|
||||
WindowLayer* Front;
|
||||
WindowLayer* Focus;
|
||||
BList WindowList;
|
||||
};
|
||||
Workspace( const int32 ID,
|
||||
const uint32 colorspace,
|
||||
const RGBColor& BGColor);
|
||||
~Workspace();
|
||||
int32 CountWindows() const { return fWindows.CountItems(); }
|
||||
WindowLayer* WindowAt(int32 index) const { return fWindows.ItemAt(index); }
|
||||
|
||||
int32 ID() const { return fID; }
|
||||
// displays
|
||||
|
||||
void AddWindowLayer(WindowLayer *winBorder);
|
||||
void RemoveWindowLayer(WindowLayer *winBorder);
|
||||
bool HasWindowLayer(const WindowLayer *winBorder) const;
|
||||
void SetDisplaysFromDesktop(Desktop* desktop);
|
||||
|
||||
WindowLayer* Focus() const;
|
||||
WindowLayer* Front() const;
|
||||
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);
|
||||
int32 CountDisplays() const { return fDisplays.CountItems(); }
|
||||
const display_info* DisplayAt(int32 index) const { return fDisplays.ItemAt(index); }
|
||||
|
||||
bool GetWindowLayerList(void **list, int32 *itemCount ) const;
|
||||
// configuration
|
||||
|
||||
bool MoveToBack(WindowLayer *newLast);
|
||||
bool MoveToFront(WindowLayer *newFront, bool doNotDisturb = false);
|
||||
const RGBColor& Color() const { return fColor; }
|
||||
void SetColor(const RGBColor& color);
|
||||
|
||||
bool HideWindowLayer(WindowLayer *winBorder);
|
||||
bool ShowWindowLayer(WindowLayer *winBorder, bool userBusy = false);
|
||||
void SetSettings(BMessage& settings);
|
||||
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:
|
||||
void expandBuffer(int32 start);
|
||||
ListData *buffer;
|
||||
int32 count;
|
||||
};
|
||||
void _SetDefaults();
|
||||
|
||||
int32 fID;
|
||||
RGBColor fBGColor;
|
||||
BObjectList<WindowLayer> fWindows;
|
||||
WindowLayer* fFront;
|
||||
WindowLayer* fFocus;
|
||||
|
||||
// first visible onscreen
|
||||
ListData *fBottomItem;
|
||||
BObjectList<display_info> fDisplays;
|
||||
|
||||
// the last visible(or covered by other Layers)
|
||||
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;
|
||||
RGBColor fColor;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* WORKSPACE_H */
|
||||
|
@ -34,7 +34,7 @@ WorkspacesLayer::~WorkspacesLayer()
|
||||
void
|
||||
WorkspacesLayer::_GetGrid(int32& columns, int32& rows)
|
||||
{
|
||||
int32 count = GetRootLayer()->WorkspaceCount();
|
||||
int32 count = 4; //GetRootLayer()->WorkspaceCount();
|
||||
|
||||
rows = 1;
|
||||
for (int32 i = 2; i < count; i++) {
|
||||
@ -140,8 +140,8 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
|
||||
{
|
||||
BRect rect = _WorkspaceAt(index);
|
||||
|
||||
Workspace* workspace = GetRootLayer()->WorkspaceAt(index);
|
||||
bool active = workspace == GetRootLayer()->ActiveWorkspace();
|
||||
Workspace* workspace = NULL;
|
||||
bool active = index == 0;
|
||||
if (active) {
|
||||
// draw active frame
|
||||
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!
|
||||
if (workspace != NULL)
|
||||
color = workspace->BGColor();
|
||||
color = workspace->Color();
|
||||
else
|
||||
color.SetColor(51, 102, 152);
|
||||
|
||||
@ -171,9 +171,9 @@ WorkspacesLayer::_DrawWorkspace(int32 index)
|
||||
|
||||
if (workspace != NULL) {
|
||||
WindowLayer* windows[256];
|
||||
int32 count = 256;
|
||||
if (!workspace->GetWindowLayerList((void **)&windows, &count))
|
||||
return;
|
||||
int32 count = 0;
|
||||
// if (!workspace->GetWindowLayerList((void **)&windows, &count))
|
||||
// return;
|
||||
|
||||
uint16 width, height;
|
||||
uint32 colorSpace;
|
||||
@ -244,7 +244,7 @@ WorkspacesLayer::Draw(const BRect& updateRect)
|
||||
|
||||
// draw workspaces
|
||||
|
||||
int32 count = GetRootLayer()->WorkspaceCount();
|
||||
int32 count = 4; //GetRootLayer()->WorkspaceCount();
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
_DrawWorkspace(i);
|
||||
|
Loading…
Reference in New Issue
Block a user