Changed the way DesktopSettings work:

* Removed the DesktopSettings lock itself - it's not really needed at all,
  and causes some trouble with a clean locking design. This may even have
  fixed bug #757, at least I couldn't reproduce it anymore.
* There is now a class for read-only access that requires you to have locked
  the desktop (either read or write).
* There is now another class LockedDesktopSettings that allows you to set
  settings (and only that) - when you're changing the settings, you must not
  have read locked the desktop (ie. hold the single window lock). The class
  will obtain a write lock, but write locks can be nested.
* Moved SetWorkspacesCount() into the Desktop class.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18646 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2006-08-26 15:13:08 +00:00
parent 1213a0db75
commit a17c3a48b8
7 changed files with 234 additions and 155 deletions

View File

@ -74,6 +74,9 @@ Decorator *
DecorInfo::Instantiate(Desktop* desktop, BRect rect, const char *title,
window_look look, uint32 flags)
{
if (desktop->LockSingleWindow() == NULL)
return NULL;
DesktopSettings settings(desktop);
Decorator *decorator;
@ -83,9 +86,12 @@ DecorInfo::Instantiate(Desktop* desktop, BRect rect, const char *title,
else
decorator = new DefaultDecorator(settings, rect, look, flags);
} catch (...) {
desktop->UnlockSingleWindow();
return NULL;
}
desktop->UnlockSingleWindow();
decorator->SetDriver(desktop->GetDrawingEngine());
decorator->SetTitle(title);

View File

@ -349,7 +349,7 @@ Desktop::Init()
if (fSharedReadOnlyArea < B_OK)
return fSharedReadOnlyArea;
fSettings = new DesktopSettings::Private(fServerReadOnlyMemory);
fSettings = new DesktopSettingsPrivate(fServerReadOnlyMemory);
for (int32 i = 0; i < kMaxWorkspaces; i++) {
_Windows(i).SetIndex(i);
@ -717,15 +717,39 @@ Desktop::StoreWorkspaceConfiguration(int32 index)
}
void
Desktop::UpdateWorkspaces()
status_t
Desktop::SetWorkspacesCount(int32 newCount)
{
// TODO: maybe this should be replaced by a SetWorkspacesCount() method
if (newCount < 1 || newCount > kMaxWorkspaces)
return B_BAD_VALUE;
_WindowChanged(NULL);
if (!LockAllWindows())
return B_ERROR;
fSettings->SetWorkspacesCount(newCount);
// either update the workspaces window, or switch to
// the last available workspace - which will update
// the workspaces window automatically
bool workspaceChanged = CurrentWorkspace() >= newCount;
if (workspaceChanged)
_SetWorkspace(newCount - 1);
else
_WindowChanged(NULL);
UnlockAllWindows();
if (workspaceChanged)
_SendFakeMouseMoved();
return B_OK;
}
/*!
Changes the current workspace to the one specified by \a index.
You must not hold any window lock when calling this method.
*/
void
Desktop::SetWorkspace(int32 index)
{
@ -737,6 +761,20 @@ Desktop::SetWorkspace(int32 index)
return;
}
_SetWorkspace(index);
UnlockAllWindows();
_SendFakeMouseMoved();
}
/*!
Changes the current workspace to the one specified by \a index.
You must hold the all window lock when calling this method.
*/
void
Desktop::_SetWorkspace(int32 index)
{
int32 previousIndex = fCurrentWorkspace;
RGBColor previousColor = fWorkspaces[fCurrentWorkspace].Color();
bool movedMouseEventWindow = false;
@ -864,10 +902,6 @@ Desktop::SetWorkspace(int32 index)
if (previousColor != fWorkspaces[fCurrentWorkspace].Color())
RedrawBackground();
UnlockAllWindows();
_SendFakeMouseMoved();
}
@ -1056,6 +1090,9 @@ Desktop::_WindowHasModal(WindowLayer* window)
}
/*!
You must at least hold a single window lock when calling this method.
*/
void
Desktop::_WindowChanged(WindowLayer* window)
{

View File

@ -97,7 +97,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
{ return fCurrentWorkspace; }
Workspace::Private& WorkspaceAt(int32 index)
{ return fWorkspaces[index]; }
void UpdateWorkspaces();
status_t SetWorkspacesCount(int32 newCount);
// WindowLayer methods
@ -180,6 +180,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
BPrivate::LinkSender& sender);
private:
void _SetWorkspace(int32 index);
void _ShowWindow(WindowLayer* window,
bool affectsOtherWindows = true);
void _HideWindow(WindowLayer* window);
@ -218,10 +219,11 @@ class Desktop : public MessageLooper, public ScreenOwner {
private:
friend class DesktopSettings;
friend class LockedDesktopSettings;
uid_t fUserID;
::VirtualScreen fVirtualScreen;
DesktopSettings::Private* fSettings;
DesktopSettingsPrivate* fSettings;
port_id fMessagePort;
::EventDispatcher fEventDispatcher;
port_id fInputPort;

View File

@ -23,8 +23,8 @@
#include <Path.h>
DesktopSettings::Private::Private(server_read_only_memory* shared)
: BLocker("DesktopSettings_Private"),
DesktopSettingsPrivate::DesktopSettingsPrivate(server_read_only_memory* shared)
:
fShared(*shared)
{
// if the on-disk settings are not complete, the defaults will be kept
@ -33,13 +33,13 @@ DesktopSettings::Private::Private(server_read_only_memory* shared)
}
DesktopSettings::Private::~Private()
DesktopSettingsPrivate::~DesktopSettingsPrivate()
{
}
void
DesktopSettings::Private::_SetDefaults()
DesktopSettingsPrivate::_SetDefaults()
{
fPlainFont = *gFontManager->DefaultPlainFont();
fBoldFont = *gFontManager->DefaultBoldFont();
@ -73,7 +73,7 @@ DesktopSettings::Private::_SetDefaults()
status_t
DesktopSettings::Private::_GetPath(BPath& path)
DesktopSettingsPrivate::_GetPath(BPath& path)
{
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
if (status < B_OK)
@ -88,7 +88,7 @@ DesktopSettings::Private::_GetPath(BPath& path)
status_t
DesktopSettings::Private::_Load()
DesktopSettingsPrivate::_Load()
{
// TODO: add support for old app_server_settings file as well
@ -224,7 +224,7 @@ DesktopSettings::Private::_Load()
status_t
DesktopSettings::Private::Save(uint32 mask)
DesktopSettingsPrivate::Save(uint32 mask)
{
BPath basePath;
status_t status = _GetPath(basePath);
@ -314,7 +314,7 @@ DesktopSettings::Private::Save(uint32 mask)
void
DesktopSettings::Private::SetDefaultPlainFont(const ServerFont &font)
DesktopSettingsPrivate::SetDefaultPlainFont(const ServerFont &font)
{
fPlainFont = font;
Save(kFontSettings);
@ -322,14 +322,14 @@ DesktopSettings::Private::SetDefaultPlainFont(const ServerFont &font)
const ServerFont &
DesktopSettings::Private::DefaultPlainFont() const
DesktopSettingsPrivate::DefaultPlainFont() const
{
return fPlainFont;
}
void
DesktopSettings::Private::SetDefaultBoldFont(const ServerFont &font)
DesktopSettingsPrivate::SetDefaultBoldFont(const ServerFont &font)
{
fBoldFont = font;
Save(kFontSettings);
@ -337,14 +337,14 @@ DesktopSettings::Private::SetDefaultBoldFont(const ServerFont &font)
const ServerFont &
DesktopSettings::Private::DefaultBoldFont() const
DesktopSettingsPrivate::DefaultBoldFont() const
{
return fBoldFont;
}
void
DesktopSettings::Private::SetDefaultFixedFont(const ServerFont &font)
DesktopSettingsPrivate::SetDefaultFixedFont(const ServerFont &font)
{
fFixedFont = font;
Save(kFontSettings);
@ -352,14 +352,14 @@ DesktopSettings::Private::SetDefaultFixedFont(const ServerFont &font)
const ServerFont &
DesktopSettings::Private::DefaultFixedFont() const
DesktopSettingsPrivate::DefaultFixedFont() const
{
return fFixedFont;
}
void
DesktopSettings::Private::SetScrollBarInfo(const scroll_bar_info& info)
DesktopSettingsPrivate::SetScrollBarInfo(const scroll_bar_info& info)
{
fScrollBarInfo = info;
Save(kAppearanceSettings);
@ -367,14 +367,14 @@ DesktopSettings::Private::SetScrollBarInfo(const scroll_bar_info& info)
const scroll_bar_info&
DesktopSettings::Private::ScrollBarInfo() const
DesktopSettingsPrivate::ScrollBarInfo() const
{
return fScrollBarInfo;
}
void
DesktopSettings::Private::SetMenuInfo(const menu_info& info)
DesktopSettingsPrivate::SetMenuInfo(const menu_info& info)
{
fMenuInfo = info;
Save(kAppearanceSettings);
@ -382,14 +382,14 @@ DesktopSettings::Private::SetMenuInfo(const menu_info& info)
const menu_info&
DesktopSettings::Private::MenuInfo() const
DesktopSettingsPrivate::MenuInfo() const
{
return fMenuInfo;
}
void
DesktopSettings::Private::SetMouseMode(const mode_mouse mode)
DesktopSettingsPrivate::SetMouseMode(const mode_mouse mode)
{
fMouseMode = mode;
Save(kMouseSettings);
@ -397,21 +397,21 @@ DesktopSettings::Private::SetMouseMode(const mode_mouse mode)
mode_mouse
DesktopSettings::Private::MouseMode() const
DesktopSettingsPrivate::MouseMode() const
{
return fMouseMode;
}
bool
DesktopSettings::Private::FocusFollowsMouse() const
DesktopSettingsPrivate::FocusFollowsMouse() const
{
return MouseMode() != B_NORMAL_MOUSE;
}
void
DesktopSettings::Private::SetWorkspacesCount(int32 number)
DesktopSettingsPrivate::SetWorkspacesCount(int32 number)
{
if (number < 1)
number = 1;
@ -423,14 +423,14 @@ DesktopSettings::Private::SetWorkspacesCount(int32 number)
int32
DesktopSettings::Private::WorkspacesCount() const
DesktopSettingsPrivate::WorkspacesCount() const
{
return fWorkspacesCount;
}
void
DesktopSettings::Private::SetWorkspacesMessage(int32 index, BMessage& message)
DesktopSettingsPrivate::SetWorkspacesMessage(int32 index, BMessage& message)
{
if (index < 0 || index > kMaxWorkspaces)
return;
@ -440,7 +440,7 @@ DesktopSettings::Private::SetWorkspacesMessage(int32 index, BMessage& message)
const BMessage*
DesktopSettings::Private::WorkspacesMessage(int32 index) const
DesktopSettingsPrivate::WorkspacesMessage(int32 index) const
{
if (index < 0 || index > kMaxWorkspaces)
return NULL;
@ -449,27 +449,15 @@ DesktopSettings::Private::WorkspacesMessage(int32 index) const
}
// #pragma mark -
// #pragma mark - read access
DesktopSettings::DesktopSettings(Desktop* desktop)
:
fSettings(desktop->fSettings)
{
fSettings = desktop->fSettings;
fSettings->Lock();
}
DesktopSettings::~DesktopSettings()
{
fSettings->Unlock();
}
void
DesktopSettings::SetDefaultPlainFont(const ServerFont &font)
{
fSettings->SetDefaultPlainFont(font);
if (!desktop->fWindowLock.IsReadLocked() && !desktop->fWindowLock.IsWriteLocked())
debugger("desktop not locked when trying to access settings");
}
@ -480,13 +468,6 @@ DesktopSettings::GetDefaultPlainFont(ServerFont &font) const
}
void
DesktopSettings::SetDefaultBoldFont(const ServerFont &font)
{
fSettings->SetDefaultBoldFont(font);
}
void
DesktopSettings::GetDefaultBoldFont(ServerFont &font) const
{
@ -494,13 +475,6 @@ DesktopSettings::GetDefaultBoldFont(ServerFont &font) const
}
void
DesktopSettings::SetDefaultFixedFont(const ServerFont &font)
{
fSettings->SetDefaultFixedFont(font);
}
void
DesktopSettings::GetDefaultFixedFont(ServerFont &font) const
{
@ -508,13 +482,6 @@ DesktopSettings::GetDefaultFixedFont(ServerFont &font) const
}
void
DesktopSettings::SetScrollBarInfo(const scroll_bar_info& info)
{
fSettings->SetScrollBarInfo(info);
}
void
DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const
{
@ -522,13 +489,6 @@ DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const
}
void
DesktopSettings::SetMenuInfo(const menu_info& info)
{
fSettings->SetMenuInfo(info);
}
void
DesktopSettings::GetMenuInfo(menu_info& info) const
{
@ -536,13 +496,6 @@ DesktopSettings::GetMenuInfo(menu_info& info) const
}
void
DesktopSettings::SetMouseMode(const mode_mouse mode)
{
fSettings->SetMouseMode(mode);
}
mode_mouse
DesktopSettings::MouseMode() const
{
@ -557,13 +510,6 @@ DesktopSettings::FocusFollowsMouse() const
}
void
DesktopSettings::SetWorkspacesCount(int32 number)
{
fSettings->SetWorkspacesCount(number);
}
int32
DesktopSettings::WorkspacesCount() const
{
@ -571,16 +517,76 @@ DesktopSettings::WorkspacesCount() const
}
void
DesktopSettings::SetWorkspacesMessage(int32 index, BMessage& message)
{
fSettings->SetWorkspacesMessage(index, message);
}
const BMessage*
DesktopSettings::WorkspacesMessage(int32 index) const
{
return fSettings->WorkspacesMessage(index);
}
// #pragma mark - write access
LockedDesktopSettings::LockedDesktopSettings(Desktop* desktop)
:
fSettings(desktop->fSettings),
fDesktop(desktop)
{
// TODO: this only works in MultiLocker's DEBUG mode
#if 0
if (desktop->fWindowLock.IsReadLocked())
debugger("desktop read locked when trying to change settings");
#endif
fDesktop->LockAllWindows();
}
LockedDesktopSettings::~LockedDesktopSettings()
{
fDesktop->UnlockAllWindows();
}
void
LockedDesktopSettings::SetDefaultPlainFont(const ServerFont &font)
{
fSettings->SetDefaultPlainFont(font);
}
void
LockedDesktopSettings::SetDefaultBoldFont(const ServerFont &font)
{
fSettings->SetDefaultBoldFont(font);
}
void
LockedDesktopSettings::SetDefaultFixedFont(const ServerFont &font)
{
fSettings->SetDefaultFixedFont(font);
}
void
LockedDesktopSettings::SetScrollBarInfo(const scroll_bar_info& info)
{
fSettings->SetScrollBarInfo(info);
}
void
LockedDesktopSettings::SetMenuInfo(const menu_info& info)
{
fSettings->SetMenuInfo(info);
}
void
LockedDesktopSettings::SetMouseMode(const mode_mouse mode)
{
fSettings->SetMouseMode(mode);
}

View File

@ -14,6 +14,7 @@
#include <Message.h>
class Desktop;
class DesktopSettingsPrivate;
class ServerFont;
@ -30,40 +31,47 @@ enum {
class DesktopSettings {
public:
DesktopSettings(Desktop* desktop);
~DesktopSettings();
status_t Save(uint32 mask = kAllSettings);
void SetDefaultPlainFont(const ServerFont& font);
void GetDefaultPlainFont(ServerFont& font) const;
void SetDefaultBoldFont(const ServerFont& font);
void GetDefaultBoldFont(ServerFont& font) const;
void SetDefaultFixedFont(const ServerFont& font);
void GetDefaultFixedFont(ServerFont& font) const;
void SetScrollBarInfo(const scroll_bar_info& info);
void GetScrollBarInfo(scroll_bar_info& info) const;
void SetMenuInfo(const menu_info& info);
void GetMenuInfo(menu_info& info) const;
void SetMouseMode(mode_mouse mode);
mode_mouse MouseMode() const;
bool FocusFollowsMouse() const;
void SetWorkspacesCount(int32 number);
int32 WorkspacesCount() const;
void SetWorkspacesMessage(int32 index, BMessage& message);
const BMessage* WorkspacesMessage(int32 index) const;
private:
class Private;
friend class Desktop;
// friend class Desktop;
Private* fSettings;
DesktopSettingsPrivate* fSettings;
};
class LockedDesktopSettings {
public:
LockedDesktopSettings(Desktop* desktop);
~LockedDesktopSettings();
void SetDefaultPlainFont(const ServerFont& font);
void SetDefaultBoldFont(const ServerFont& font);
void SetDefaultFixedFont(const ServerFont& font);
void SetScrollBarInfo(const scroll_bar_info& info);
void SetMenuInfo(const menu_info& info);
void SetMouseMode(mode_mouse mode);
private:
// friend class Desktop;
DesktopSettingsPrivate* fSettings;
Desktop* fDesktop;
};
#endif /* DESKTOP_SETTINGS_H */

View File

@ -17,10 +17,10 @@
struct server_read_only_memory;
class DesktopSettings::Private : public BLocker {
class DesktopSettingsPrivate {
public:
Private(server_read_only_memory* shared);
~Private();
DesktopSettingsPrivate(server_read_only_memory* shared);
~DesktopSettingsPrivate();
status_t Save(uint32 mask = kAllSettings);

View File

@ -757,30 +757,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
case AS_COUNT_WORKSPACES:
{
DesktopSettings settings(fDesktop);
if (fDesktop->LockSingleWindow()) {
DesktopSettings settings(fDesktop);
fLink.StartMessage(B_OK);
fLink.Attach<int32>(settings.WorkspacesCount());
fDesktop->UnlockSingleWindow();
} else
fLink.StartMessage(B_ERROR);
fLink.StartMessage(B_OK);
fLink.Attach<int32>(settings.WorkspacesCount());
fLink.Flush();
break;
}
case AS_SET_WORKSPACE_COUNT:
{
DesktopSettings settings(fDesktop);
int32 newCount;
if (link.Read<int32>(&newCount) == B_OK) {
settings.SetWorkspacesCount(newCount);
// either update the workspaces window, or switch to
// the last available workspace - which will update
// the workspaces window automatically
if (fDesktop->CurrentWorkspace() >= newCount)
fDesktop->SetWorkspace(newCount - 1);
else
fDesktop->UpdateWorkspaces();
}
if (link.Read<int32>(&newCount) == B_OK)
fDesktop->SetWorkspacesCount(newCount);
break;
}
@ -795,7 +789,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
case AS_ACTIVATE_WORKSPACE:
{
STRACE(("ServerApp %s: activate workspace\n", Signature()));
// TODO: See above
int32 index;
link.Read<int32>(&index);
@ -944,13 +938,19 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
case AS_GET_SCROLLBAR_INFO:
{
STRACE(("ServerApp %s: Get ScrollBar info\n", Signature()));
scroll_bar_info info;
DesktopSettings settings(fDesktop);
settings.GetScrollBarInfo(info);
if (fDesktop->LockSingleWindow()) {
scroll_bar_info info;
DesktopSettings settings(fDesktop);
settings.GetScrollBarInfo(info);
fLink.StartMessage(B_OK);
fLink.Attach<scroll_bar_info>(info);
fLink.Flush();
fLink.StartMessage(B_OK);
fLink.Attach<scroll_bar_info>(info);
fDesktop->UnlockSingleWindow();
} else
fLink.StartMessage(B_ERROR);
fLink.Flush();
break;
}
case AS_SET_SCROLLBAR_INFO:
@ -960,7 +960,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// 1) scroll_bar_info scroll bar info structure
scroll_bar_info info;
if (link.Read<scroll_bar_info>(&info) == B_OK) {
DesktopSettings settings(fDesktop);
LockedDesktopSettings settings(fDesktop);
settings.SetScrollBarInfo(info);
}
@ -972,12 +972,18 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
case AS_GET_MENU_INFO:
{
STRACE(("ServerApp %s: Get menu info\n", Signature()));
menu_info info;
DesktopSettings settings(fDesktop);
settings.GetMenuInfo(info);
if (fDesktop->LockSingleWindow()) {
menu_info info;
DesktopSettings settings(fDesktop);
settings.GetMenuInfo(info);
fLink.StartMessage(B_OK);
fLink.Attach<menu_info>(info);
fDesktop->UnlockSingleWindow();
} else
fLink.StartMessage(B_ERROR);
fLink.StartMessage(B_OK);
fLink.Attach<menu_info>(info);
fLink.Flush();
break;
}
@ -986,7 +992,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
STRACE(("ServerApp %s: Set menu info\n", Signature()));
menu_info info;
if (link.Read<menu_info>(&info) == B_OK) {
DesktopSettings settings(fDesktop);
LockedDesktopSettings settings(fDesktop);
settings.SetMenuInfo(info);
// TODO: SetMenuInfo() should do some validity check, so
// that the answer we're giving can actually be useful
@ -1004,7 +1010,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// 1) enum mode_mouse FFM mouse mode
mode_mouse mouseMode;
if (link.Read<mode_mouse>(&mouseMode) == B_OK) {
DesktopSettings settings(fDesktop);
LockedDesktopSettings settings(fDesktop);
settings.SetMouseMode(mouseMode);
}
break;
@ -1012,10 +1018,17 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
case AS_GET_MOUSE_MODE:
{
STRACE(("ServerApp %s: Get Focus Follows Mouse mode\n", Signature()));
DesktopSettings settings(fDesktop);
if (fDesktop->LockSingleWindow()) {
DesktopSettings settings(fDesktop);
fLink.StartMessage(B_OK);
fLink.Attach<mode_mouse>(settings.MouseMode());
fDesktop->UnlockSingleWindow();
} else
fLink.StartMessage(B_ERROR);
fLink.StartMessage(B_OK);
fLink.Attach<mode_mouse>(settings.MouseMode());
fLink.Flush();
break;
}
@ -1044,7 +1057,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
FontStyle* style = gFontManager->GetStyle(familyName, styleName);
if (style != NULL) {
ServerFont font(*style, size);
DesktopSettings settings(fDesktop);
LockedDesktopSettings settings(fDesktop);
if (!strcmp(type, "plain"))
settings.SetDefaultPlainFont(font);
@ -1102,6 +1115,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// 4) uint16 - face flags
// 5) uint32 - font flags
if (!fDesktop->LockSingleWindow()) {
fLink.StartMessage(B_OK);
fLink.Flush();
break;
}
DesktopSettings settings(fDesktop);
fLink.StartMessage(B_OK);
@ -1129,6 +1148,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
fLink.Attach<uint32>(font.Flags());
}
fDesktop->UnlockSingleWindow();
fLink.Flush();
break;
}