Introduce a new DecorAddOn class which provide the DecorManager with the needed Decorator, WindowBehaviour and DesktopListener.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37857 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
bd06a41c3a
commit
b6ba2290fc
@ -21,87 +21,55 @@
|
||||
|
||||
#include "AppServer.h"
|
||||
#include "DefaultDecorator.h"
|
||||
#include "DefaultWindowBehaviour.h"
|
||||
#include "Desktop.h"
|
||||
#include "DesktopSettings.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "Window.h"
|
||||
|
||||
typedef float get_version(void);
|
||||
typedef Decorator* create_decorator(DesktopSettings& desktopSettings, BRect rect,
|
||||
window_look look, uint32 flags);
|
||||
typedef DecorAddOn* create_decor_addon(image_id id, const char* name);
|
||||
|
||||
// Globals
|
||||
DecorManager gDecorManager;
|
||||
|
||||
|
||||
// This is a class used only by the DecorManager to track all the decorators in memory
|
||||
class DecorInfo {
|
||||
public:
|
||||
DecorInfo(image_id id, const char* name,
|
||||
create_decorator* allocator = NULL);
|
||||
~DecorInfo();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
image_id ID() const { return fID; }
|
||||
const char* Name() const { return fName.String(); }
|
||||
|
||||
Decorator* Instantiate(Desktop* desktop, DrawingEngine* engine,
|
||||
BRect rect, const char* title,
|
||||
window_look look, uint32 flags);
|
||||
|
||||
private:
|
||||
image_id fID;
|
||||
BString fName;
|
||||
create_decorator* fAllocator;
|
||||
};
|
||||
|
||||
|
||||
DecorInfo::DecorInfo(image_id id, const char* name, create_decorator* allocator)
|
||||
DecorAddOn::DecorAddOn(image_id id, const char* name)
|
||||
:
|
||||
fID(id),
|
||||
fName(name),
|
||||
fAllocator(allocator)
|
||||
fImageID(id),
|
||||
fName(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DecorInfo::~DecorInfo()
|
||||
DecorAddOn::~DecorAddOn()
|
||||
{
|
||||
// Do nothing. Normal programming practice would say that one should unload
|
||||
// the object's associate image_id. However, there is some funkiness with
|
||||
// the R5 kernel in which addons aren't unloaded when unload_add_on() is
|
||||
// called -- perhaps it's lazy unloading or something. In any event, it
|
||||
// causes crashes which are *extremely* hard to track down to this.
|
||||
|
||||
// Considering the usage of DecorInfo and DecorManager, we can live with
|
||||
// this because the app_server will not the DecorManager is freed only
|
||||
// when the app_server quits. It's not pretty, but it gets the job done.
|
||||
|
||||
}
|
||||
|
||||
|
||||
Decorator *
|
||||
DecorInfo::Instantiate(Desktop* desktop, DrawingEngine* engine, BRect rect,
|
||||
const char *title, window_look look, uint32 flags)
|
||||
status_t
|
||||
DecorAddOn::InitCheck() const
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
Decorator*
|
||||
DecorAddOn::AllocateDecorator(Desktop* desktop, DrawingEngine* engine,
|
||||
BRect rect, const char* title, window_look look, uint32 flags)
|
||||
{
|
||||
if (!desktop->LockSingleWindow())
|
||||
return NULL;
|
||||
|
||||
DesktopSettings settings(desktop);
|
||||
Decorator *decorator;
|
||||
|
||||
try {
|
||||
if (fAllocator != NULL)
|
||||
decorator = fAllocator(settings, rect, look, flags);
|
||||
else
|
||||
decorator = new DefaultDecorator(settings, rect, look, flags);
|
||||
} catch (...) {
|
||||
desktop->UnlockSingleWindow();
|
||||
return NULL;
|
||||
}
|
||||
Decorator* decorator;
|
||||
decorator = _AllocateDecorator(settings, rect, look, flags);
|
||||
|
||||
desktop->UnlockSingleWindow();
|
||||
|
||||
if (!decorator)
|
||||
return NULL;
|
||||
decorator->SetDrawingEngine(engine);
|
||||
decorator->SetTitle(title);
|
||||
|
||||
@ -109,17 +77,38 @@ DecorInfo::Instantiate(Desktop* desktop, DrawingEngine* engine, BRect rect,
|
||||
}
|
||||
|
||||
|
||||
WindowBehaviour*
|
||||
DecorAddOn::AllocateWindowBehaviour(Window* window)
|
||||
{
|
||||
return new (std::nothrow)DefaultWindowBehaviour(window);
|
||||
}
|
||||
|
||||
|
||||
const DesktopListenerList&
|
||||
DecorAddOn::GetDesktopListeners()
|
||||
{
|
||||
return fDesktopListeners;
|
||||
}
|
||||
|
||||
|
||||
Decorator*
|
||||
DecorAddOn::_AllocateDecorator(DesktopSettings& settings, BRect rect,
|
||||
window_look look, uint32 flags)
|
||||
{
|
||||
return new (std::nothrow)DefaultDecorator(settings, rect, look, flags);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
DecorManager::DecorManager()
|
||||
:
|
||||
fDecorList(0),
|
||||
fDefaultDecorAddOn(-1, "Default"),
|
||||
fCurrentDecor(NULL)
|
||||
{
|
||||
// Start with the default decorator - index is always 0
|
||||
DecorInfo *defaultDecor = new DecorInfo(-1, "Default", NULL);
|
||||
fDecorList.AddItem(defaultDecor);
|
||||
fDecorList.AddItem(&fDefaultDecorAddOn);
|
||||
|
||||
// Add any on disk
|
||||
RescanDecorators();
|
||||
@ -127,7 +116,7 @@ DecorManager::DecorManager()
|
||||
_LoadSettingsFromDisk();
|
||||
|
||||
if (!fCurrentDecor)
|
||||
fCurrentDecor = (DecorInfo*)fDecorList.ItemAt(0L);
|
||||
fCurrentDecor = fDecorList.ItemAt(0L);
|
||||
}
|
||||
|
||||
|
||||
@ -170,18 +159,25 @@ DecorManager::RescanDecorators()
|
||||
// to do so. If we *did* do anything with decorator versions, the
|
||||
// assignment would go here.
|
||||
|
||||
create_decorator* createFunc;
|
||||
create_decor_addon* createFunc;
|
||||
|
||||
// Get the instantiation function
|
||||
status_t status = get_image_symbol(image, "instantiate_decorator",
|
||||
status_t status = get_image_symbol(image, "instantiate_decor_addon",
|
||||
B_SYMBOL_TYPE_TEXT, (void**)&createFunc);
|
||||
if (status != B_OK) {
|
||||
unload_add_on(image);
|
||||
continue;
|
||||
}
|
||||
|
||||
DecorAddOn* addon = createFunc(image, ref.name);
|
||||
|
||||
// TODO: unload images until they are actually used!
|
||||
fDecorList.AddItem(new DecorInfo(image, ref.name, createFunc));
|
||||
if (!addon || addon->InitCheck() != B_OK
|
||||
|| !fDecorList.AddItem(addon)) {
|
||||
unload_add_on(image);
|
||||
delete addon;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,11 +195,31 @@ DecorManager::AllocateDecorator(Desktop* desktop, DrawingEngine* engine,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fCurrentDecor->Instantiate(desktop, engine, rect, title,
|
||||
return fCurrentDecor->AllocateDecorator(desktop, engine, rect, title,
|
||||
look, flags);
|
||||
}
|
||||
|
||||
|
||||
WindowBehaviour*
|
||||
DecorManager::AllocateWindowBehaviour(Window* window)
|
||||
{
|
||||
if (!fCurrentDecor) {
|
||||
// We should *never* be here. If we do, it's a bug.
|
||||
debugger("DecorManager::AllocateDecorator has a NULL decorator");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fCurrentDecor->AllocateWindowBehaviour(window);
|
||||
}
|
||||
|
||||
|
||||
const DesktopListenerList&
|
||||
DecorManager::GetDesktopListeners()
|
||||
{
|
||||
return fCurrentDecor->GetDesktopListeners();
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
DecorManager::CountDecorators() const
|
||||
{
|
||||
@ -221,11 +237,11 @@ DecorManager::GetDecorator() const
|
||||
bool
|
||||
DecorManager::SetDecorator(int32 index, Desktop* desktop)
|
||||
{
|
||||
DecorInfo* newDecInfo = (DecorInfo*)fDecorList.ItemAt(index);
|
||||
DecorAddOn* newDecor = fDecorList.ItemAt(index);
|
||||
|
||||
if (newDecInfo) {
|
||||
fCurrentDecor = newDecInfo;
|
||||
desktop->ReloadAllDecorators();
|
||||
if (newDecor) {
|
||||
fCurrentDecor = newDecor;
|
||||
desktop->ReloadDecor();
|
||||
_SaveSettingsToDisk();
|
||||
return true;
|
||||
}
|
||||
@ -248,9 +264,9 @@ DecorManager::SetR5Decorator(int32 value)
|
||||
return false;
|
||||
}
|
||||
|
||||
DecorInfo *newDecInfo = _FindDecor(string.String());
|
||||
if (newDecInfo) {
|
||||
fCurrentDecor = newDecInfo;
|
||||
DecorAddOn *newDecor = _FindDecor(string);
|
||||
if (newDecor) {
|
||||
fCurrentDecor = newDecor;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -258,40 +274,43 @@ DecorManager::SetR5Decorator(int32 value)
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
BString
|
||||
DecorManager::GetDecoratorName(int32 index)
|
||||
{
|
||||
DecorInfo *info = fDecorList.ItemAt(index);
|
||||
if (info)
|
||||
return info->Name();
|
||||
DecorAddOn *decor = fDecorList.ItemAt(index);
|
||||
if (decor)
|
||||
return decor->Name();
|
||||
|
||||
return NULL;
|
||||
return BString("");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DecorManager::_EmptyList()
|
||||
{
|
||||
for (int32 i = 0; i < fDecorList.CountItems(); i++) {
|
||||
delete fDecorList.ItemAt(i);;
|
||||
for (int32 i = 1; i < fDecorList.CountItems(); i++) {
|
||||
unload_add_on(fDecorList.ItemAt(i)->ImageID());
|
||||
delete fDecorList.ItemAt(i);
|
||||
}
|
||||
|
||||
fDecorList.MakeEmpty();
|
||||
fCurrentDecor = NULL;
|
||||
fDecorList.AddItem(&fDefaultDecorAddOn);
|
||||
|
||||
fCurrentDecor = &fDefaultDecorAddOn;
|
||||
}
|
||||
|
||||
|
||||
DecorInfo*
|
||||
DecorManager::_FindDecor(const char *name)
|
||||
DecorAddOn*
|
||||
DecorManager::_FindDecor(BString name)
|
||||
{
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
for (int32 i = 0; i < fDecorList.CountItems(); i++) {
|
||||
DecorInfo* info = fDecorList.ItemAt(i);
|
||||
DecorAddOn* decor = fDecorList.ItemAt(i);
|
||||
|
||||
if (strcmp(name, info->Name()) == 0)
|
||||
return info;
|
||||
if (decor->Name() == name)
|
||||
return decor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -321,7 +340,7 @@ DecorManager::_LoadSettingsFromDisk()
|
||||
if (settings.Unflatten(&file) == B_OK) {
|
||||
BString itemtext;
|
||||
if (settings.FindString("decorator", &itemtext) == B_OK) {
|
||||
DecorInfo* decor = _FindDecor(itemtext.String());
|
||||
DecorAddOn* decor = _FindDecor(itemtext);
|
||||
if (decor) {
|
||||
fCurrentDecor = decor;
|
||||
return true;
|
||||
|
@ -20,7 +20,46 @@
|
||||
|
||||
class DecorInfo;
|
||||
class Desktop;
|
||||
class DesktopListener;
|
||||
class DrawingEngine;
|
||||
class Window;
|
||||
class WindowBehaviour;
|
||||
|
||||
|
||||
typedef BObjectList<DesktopListener> DesktopListenerList;
|
||||
|
||||
|
||||
class DecorAddOn
|
||||
{
|
||||
public:
|
||||
DecorAddOn(image_id id, const char* name);
|
||||
virtual ~DecorAddOn();
|
||||
|
||||
virtual status_t InitCheck() const;
|
||||
|
||||
image_id ImageID() const { return fImageID; }
|
||||
BString Name() const { return fName; }
|
||||
|
||||
Decorator* AllocateDecorator(Desktop* desktop,
|
||||
DrawingEngine* engine, BRect rect,
|
||||
const char* title, window_look look,
|
||||
uint32 flags);
|
||||
|
||||
virtual float Version() { return 1.0; }
|
||||
virtual WindowBehaviour* AllocateWindowBehaviour(Window* window);
|
||||
|
||||
virtual const DesktopListenerList& GetDesktopListeners();
|
||||
|
||||
protected:
|
||||
virtual Decorator* _AllocateDecorator(DesktopSettings& settings,
|
||||
BRect rect, window_look look, uint32 flags);
|
||||
|
||||
DesktopListenerList fDesktopListeners;
|
||||
|
||||
private:
|
||||
image_id fImageID;
|
||||
BString fName;
|
||||
};
|
||||
|
||||
|
||||
class DecorManager
|
||||
@ -36,13 +75,15 @@ public:
|
||||
BRect rect,
|
||||
const char* title, window_look look,
|
||||
uint32 flags);
|
||||
WindowBehaviour* AllocateWindowBehaviour(Window* window);
|
||||
const DesktopListenerList& GetDesktopListeners();
|
||||
|
||||
int32 CountDecorators() const;
|
||||
|
||||
int32 GetDecorator() const;
|
||||
bool SetDecorator(int32 index, Desktop* desktop);
|
||||
bool SetR5Decorator(int32 value);
|
||||
const char* GetDecoratorName(int32 index);
|
||||
BString GetDecoratorName(int32 index);
|
||||
|
||||
// TODO: Implement this method once the rest of the necessary infrastructure
|
||||
// is in place
|
||||
@ -50,13 +91,14 @@ public:
|
||||
|
||||
private:
|
||||
void _EmptyList();
|
||||
DecorInfo* _FindDecor(const char *name);
|
||||
DecorAddOn* _FindDecor(BString name);
|
||||
|
||||
bool _LoadSettingsFromDisk();
|
||||
bool _SaveSettingsToDisk();
|
||||
|
||||
BObjectList<DecorInfo> fDecorList;
|
||||
DecorInfo* fCurrentDecor;
|
||||
BObjectList<DecorAddOn> fDecorList;
|
||||
DecorAddOn fDefaultDecorAddOn;
|
||||
DecorAddOn* fCurrentDecor;
|
||||
};
|
||||
|
||||
extern DecorManager gDecorManager;
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <WindowInfo.h>
|
||||
|
||||
#include "AppServer.h"
|
||||
#include "DecorManager.h"
|
||||
#include "DesktopSettingsPrivate.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "HWInterface.h"
|
||||
@ -1901,17 +1902,29 @@ Desktop::RedrawBackground()
|
||||
|
||||
|
||||
void
|
||||
Desktop::ReloadAllDecorators()
|
||||
Desktop::ReloadDecor()
|
||||
{
|
||||
AutoWriteLocker _(fWindowLock);
|
||||
|
||||
// TODO it is assumed all listeners are registered by one decor
|
||||
// unregister old listeners
|
||||
const DesktopListenerDLList& currentListeners = GetDesktopListenerList();
|
||||
for (DesktopListener* listener = currentListeners.First();
|
||||
listener != NULL; listener = currentListeners.GetNext(listener))
|
||||
UnregisterListener(listener);
|
||||
// register new listeners
|
||||
const DesktopListenerList& newListeners
|
||||
= gDecorManager.GetDesktopListeners();
|
||||
for (int i = 0; i < newListeners.CountItems(); i++)
|
||||
RegisterListener(newListeners.ItemAt(i));
|
||||
|
||||
for (int32 i = 0; i < kMaxWorkspaces; i++) {
|
||||
for (Window* window = _Windows(i).LastWindow(); window;
|
||||
window = window->PreviousWindow(i)) {
|
||||
BRegion oldBorder;
|
||||
window->GetBorderRegion(&oldBorder);
|
||||
|
||||
window->ReloadDecorator();
|
||||
window->ReloadDecor();
|
||||
|
||||
BRegion border;
|
||||
window->GetBorderRegion(&border);
|
||||
|
@ -14,6 +14,14 @@
|
||||
#define DESKTOP_H
|
||||
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <List.h>
|
||||
#include <Menu.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Region.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "CursorManager.h"
|
||||
#include "DesktopListener.h"
|
||||
#include "DesktopSettings.h"
|
||||
@ -27,15 +35,6 @@
|
||||
#include "Workspace.h"
|
||||
#include "WorkspacePrivate.h"
|
||||
|
||||
#include <ObjectList.h>
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <List.h>
|
||||
#include <Menu.h>
|
||||
#include <Region.h>
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
#define USE_MULTI_LOCKER 1
|
||||
|
||||
@ -233,7 +232,7 @@ public:
|
||||
void Redraw();
|
||||
void RedrawBackground();
|
||||
|
||||
void ReloadAllDecorators();
|
||||
void ReloadDecor();
|
||||
|
||||
BRegion& BackgroundRegion()
|
||||
{ return fBackgroundRegion; }
|
||||
|
@ -37,6 +37,13 @@ DesktopObservable::UnregisterListener(DesktopListener* listener)
|
||||
}
|
||||
|
||||
|
||||
const DesktopListenerDLList&
|
||||
DesktopObservable::GetDesktopListenerList()
|
||||
{
|
||||
return fDesktopListenerList;
|
||||
}
|
||||
|
||||
|
||||
#define FOR_ALL_DESKTOP_LISTENER \
|
||||
for (DesktopListener* listener = fDesktopListenerList.First(); \
|
||||
listener != NULL; listener = fDesktopListenerList.GetNext(listener))
|
||||
|
@ -55,7 +55,7 @@ class DesktopListener : public DoublyLinkedListLinkImpl<DesktopListener>
|
||||
};
|
||||
|
||||
|
||||
typedef DoublyLinkedList<DesktopListener> DesktopListenerList;
|
||||
typedef DoublyLinkedList<DesktopListener> DesktopListenerDLList;
|
||||
|
||||
|
||||
class DesktopObservable
|
||||
@ -65,6 +65,7 @@ class DesktopObservable
|
||||
|
||||
void RegisterListener(DesktopListener* listener);
|
||||
void UnregisterListener(DesktopListener* listener);
|
||||
const DesktopListenerDLList& GetDesktopListenerList();
|
||||
|
||||
void InvokeAddWindow(Window* window);
|
||||
void InvokeRemoveWindow(Window* window);
|
||||
@ -104,10 +105,10 @@ class DesktopObservable
|
||||
bool& fInvoking;
|
||||
};
|
||||
|
||||
DesktopListenerList fDesktopListenerList;
|
||||
DesktopListenerDLList fDesktopListenerList;
|
||||
|
||||
// prevent recursive invokes
|
||||
bool fWeAreInvoking;
|
||||
bool fWeAreInvoking;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -10,20 +10,18 @@
|
||||
* Brecht Machiels <brecht@mos6581.org>
|
||||
* Clemens Zeidler <haiku@clemens-zeidler.de>
|
||||
*/
|
||||
|
||||
|
||||
#include "Window.h"
|
||||
|
||||
#include "Decorator.h"
|
||||
#include "DecorManager.h"
|
||||
#include "Desktop.h"
|
||||
#include "DefaultWindowBehaviour.h"
|
||||
#include "DrawingEngine.h"
|
||||
#include "HWInterface.h"
|
||||
#include "MessagePrivate.h"
|
||||
#include "PortLink.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerWindow.h"
|
||||
#include "WindowBehaviour.h"
|
||||
#include "Workspace.h"
|
||||
#include "WorkspacesView.h"
|
||||
|
||||
@ -135,7 +133,7 @@ Window::Window(const BRect& frame, const char *name,
|
||||
&fMaxWidth, &fMaxHeight);
|
||||
}
|
||||
}
|
||||
fWindowBehaviour = new (std::nothrow)DefaultWindowBehaviour(this);
|
||||
fWindowBehaviour = gDecorManager.AllocateWindowBehaviour(this);
|
||||
|
||||
// do we need to change our size to let the decorator fit?
|
||||
// _ResizeBy() will adapt the frame for validity before resizing
|
||||
@ -542,17 +540,35 @@ Window::PreviousWindow(int32 index) const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Window::ReloadDecorator()
|
||||
bool
|
||||
Window::ReloadDecor()
|
||||
{
|
||||
::Decorator* decorator = NULL;
|
||||
WindowBehaviour* windowBehaviour = NULL;
|
||||
|
||||
if (fLook != B_NO_BORDER_WINDOW_LOOK) {
|
||||
delete fDecorator;
|
||||
// we need a new decorator
|
||||
fDecorator = gDecorManager.AllocateDecorator(fDesktop, fDrawingEngine,
|
||||
decorator = gDecorManager.AllocateDecorator(fDesktop, fDrawingEngine,
|
||||
Frame(), Title(), fLook, fFlags);
|
||||
if (!decorator)
|
||||
return false;
|
||||
if (IsFocus())
|
||||
fDecorator->SetFocus(true);
|
||||
decorator->SetFocus(true);
|
||||
}
|
||||
|
||||
windowBehaviour = gDecorManager.AllocateWindowBehaviour(this);
|
||||
if (!windowBehaviour) {
|
||||
delete decorator;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete fDecorator;
|
||||
fDecorator = decorator;
|
||||
|
||||
delete fWindowBehaviour;
|
||||
fWindowBehaviour = windowBehaviour;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,12 +10,10 @@
|
||||
* Brecht Machiels <brecht@mos6581.org>
|
||||
* Clemens Zeidler <haiku@clemens-zeidler.de>
|
||||
*/
|
||||
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
|
||||
#include "Decorator.h"
|
||||
#include "RegionPool.h"
|
||||
#include "ServerWindow.h"
|
||||
#include "View.h"
|
||||
@ -71,7 +69,7 @@ public:
|
||||
::EventTarget& EventTarget() const
|
||||
{ return fWindow->EventTarget(); }
|
||||
|
||||
void ReloadDecorator();
|
||||
bool ReloadDecor();
|
||||
|
||||
void SetScreen(const ::Screen* screen);
|
||||
const ::Screen* Screen() const;
|
||||
|
Loading…
Reference in New Issue
Block a user