* ServerApp now maintains a mask of workspaces with temporary mode settings,

and reverts the modes if the app goes away (ie. if it crashes).
* Desktop::SetScreenMode() also set the mode on the current screen, even if
  it should have been set on another screen.
* Cleaned up the Desktop.h header.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32564 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-08-21 12:57:24 +00:00
parent c1df12d278
commit 5e3f4c41a6
6 changed files with 260 additions and 188 deletions
+70 -16
View File
@@ -931,6 +931,23 @@ Desktop::SetWorkspace(int32 index)
} }
void
Desktop::_SetCurrentWorkspaceConfiguration()
{
ASSERT_MULTI_WRITE_LOCKED(fWindowLock);
uint32 changedScreens;
fVirtualScreen.SetConfiguration(*this,
fWorkspaces[fCurrentWorkspace].CurrentScreenConfiguration(),
&changedScreens);
for (int32 i = 0; changedScreens != 0; i++, changedScreens /= 2) {
if ((changedScreens & (1 << i)) != 0)
ScreenChanged(fVirtualScreen.ScreenAt(i));
}
}
/*! Changes the current workspace to the one specified by \a index. /*! Changes the current workspace to the one specified by \a index.
You must hold the all window lock when calling this method. You must hold the all window lock when calling this method.
*/ */
@@ -998,15 +1015,7 @@ Desktop::_SetWorkspace(int32 index)
fCurrentWorkspace = index; fCurrentWorkspace = index;
// Change the display modes, if needed // Change the display modes, if needed
_SetCurrentWorkspaceConfiguration();
uint32 changedScreens;
fVirtualScreen.SetConfiguration(*this,
fWorkspaces[index].CurrentScreenConfiguration(), &changedScreens);
for (int32 i = 0; changedScreens != 0; i++, changedScreens /= 2) {
if ((changedScreens & (1 << i)) != 0)
ScreenChanged(fVirtualScreen.ScreenAt(i));
}
// Show windows, and include them in the changed region - but only // Show windows, and include them in the changed region - but only
// those that were not visible before (or whose position changed) // those that were not visible before (or whose position changed)
@@ -1143,6 +1152,12 @@ Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
if (!memcmp(&oldMode, &mode, sizeof(display_mode))) if (!memcmp(&oldMode, &mode, sizeof(display_mode)))
return B_OK; return B_OK;
// Set the new one
status_t status = screen->SetMode(mode);
if (status != B_OK)
return status;
} else { } else {
// retrieve from settings // retrieve from settings
screen_configuration* configuration screen_configuration* configuration
@@ -1153,12 +1168,6 @@ Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
return B_OK; return B_OK;
} }
// Set the new one
status_t status = screen->SetMode(mode);
if (status != B_OK)
return status;
// Update our configurations // Update our configurations
monitor_info info; monitor_info info;
@@ -1241,10 +1250,55 @@ Desktop::GetScreenFrame(int32 workspace, int32 id, BRect& frame)
} }
void
Desktop::RevertScreenModes(uint32 workspaces)
{
if (workspaces == 0)
return;
AutoWriteLocker _(fWindowLock);
for (int32 workspace = 0; workspace < kMaxWorkspaces; workspace++) {
if ((workspaces & (1U << workspace)) == 0)
continue;
// Revert all screens on this workspace
// TODO: ideally, we would know which screens to revert - this way, too
// many of them could be reverted
for (int32 index = 0; index < fVirtualScreen.CountScreens(); index++) {
Screen* screen = fVirtualScreen.ScreenAt(index);
// retrieve configurations
screen_configuration* stored = fWorkspaces[workspace]
.StoredScreenConfiguration().CurrentByID(screen->ID());
screen_configuration* current = fWorkspaces[workspace]
.CurrentScreenConfiguration().CurrentByID(screen->ID());
if ((stored != NULL && current != NULL
&& !memcmp(&stored->mode, &current->mode,
sizeof(display_mode)))
|| (stored == NULL && current == NULL))
continue;
if (stored == NULL) {
fWorkspaces[workspace].CurrentScreenConfiguration()
.Remove(current);
if (workspace == fCurrentWorkspace)
_SetCurrentWorkspaceConfiguration();
} else
SetScreenMode(workspace, screen->ID(), stored->mode, false);
}
}
}
void void
Desktop::ScreenChanged(Screen* screen) Desktop::ScreenChanged(Screen* screen)
{ {
ASSERT(fWindowLock.IsWriteLocked()); ASSERT_MULTI_WRITE_LOCKED(fWindowLock);
// the entire screen is dirty, because we're actually // the entire screen is dirty, because we're actually
// operating on an all new buffer in memory // operating on an all new buffer in memory
+10 -7
View File
@@ -58,7 +58,7 @@ namespace BPrivate {
class Desktop : public MessageLooper, public ScreenOwner { class Desktop : public MessageLooper, public ScreenOwner {
public: public:
Desktop(uid_t userID); Desktop(uid_t userID);
virtual ~Desktop(); virtual ~Desktop();
@@ -103,19 +103,21 @@ class Desktop : public MessageLooper, public ScreenOwner {
display_mode& mode); display_mode& mode);
status_t GetScreenFrame(int32 workspace, int32 id, status_t GetScreenFrame(int32 workspace, int32 id,
BRect& frame); BRect& frame);
void RevertScreenModes(uint32 workspaces);
void ScreenChanged(Screen* screen); void ScreenChanged(Screen* screen);
const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; } const ::VirtualScreen& VirtualScreen() const
{ return fVirtualScreen; }
DrawingEngine* GetDrawingEngine() const DrawingEngine* GetDrawingEngine() const
{ return fVirtualScreen.DrawingEngine(); } { return fVirtualScreen.DrawingEngine(); }
::HWInterface* HWInterface() const ::HWInterface* HWInterface() const
{ return fVirtualScreen.HWInterface(); } { return fVirtualScreen.HWInterface(); }
// ScreenOwner implementation // ScreenOwner implementation
void ScreenRemoved(Screen* screen) {} virtual void ScreenRemoved(Screen* screen) {}
void ScreenAdded(Screen* screen) {} virtual void ScreenAdded(Screen* screen) {}
bool ReleaseScreen(Screen* screen) { return false; } virtual bool ReleaseScreen(Screen* screen) { return false; }
// Workspace methods // Workspace methods
@@ -236,8 +238,9 @@ class Desktop : public MessageLooper, public ScreenOwner {
void WriteWindowOrder(int32 workspace, void WriteWindowOrder(int32 workspace,
BPrivate::LinkSender& sender); BPrivate::LinkSender& sender);
private: private:
void _LaunchInputServer(); void _LaunchInputServer();
void _SetCurrentWorkspaceConfiguration();
void _SetWorkspace(int32 index); void _SetWorkspace(int32 index);
void _ShowWindow(Window* window, void _ShowWindow(Window* window,
bool affectsOtherWindows = true); bool affectsOtherWindows = true);
@@ -281,7 +284,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
WindowList& _CurrentWindows(); WindowList& _CurrentWindows();
WindowList& _Windows(int32 index); WindowList& _Windows(int32 index);
private: private:
friend class DesktopSettings; friend class DesktopSettings;
friend class LockedDesktopSettings; friend class LockedDesktopSettings;
+5 -9
View File
@@ -143,18 +143,14 @@ ScreenConfigurations::Set(int32 id, const monitor_info* info,
} }
status_t void
ScreenConfigurations::Update(int32 id, const display_mode& mode) ScreenConfigurations::Remove(screen_configuration* configuration)
{ {
screen_configuration* configuration = CurrentByID(id);
if (configuration == NULL) if (configuration == NULL)
return B_BAD_VALUE; return;
configuration->is_current = true; fConfigurations.RemoveItem(configuration);
// this also deletes the configuration
memcpy(&configuration->mode, &mode, sizeof(display_mode));
return B_OK;
} }
+1 -1
View File
@@ -37,7 +37,7 @@ public:
status_t Set(int32 id, const monitor_info* info, status_t Set(int32 id, const monitor_info* info,
const BRect& frame, const BRect& frame,
const display_mode& mode); const display_mode& mode);
status_t Update(int32 id, const display_mode& mode); void Remove(screen_configuration* configuration);
status_t Store(BMessage& settings) const; status_t Store(BMessage& settings) const;
status_t Restore(const BMessage& settings); status_t Restore(const BMessage& settings);
+18
View File
@@ -36,6 +36,7 @@
#include <FontPrivate.h> #include <FontPrivate.h>
#include <MessengerPrivate.h> #include <MessengerPrivate.h>
#include <PrivateScreen.h>
#include <RosterPrivate.h> #include <RosterPrivate.h>
#include <ServerProtocol.h> #include <ServerProtocol.h>
#include <WindowPrivate.h> #include <WindowPrivate.h>
@@ -95,6 +96,7 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
fSignature(signature), fSignature(signature),
fClientTeam(clientTeam), fClientTeam(clientTeam),
fWindowListLock("window list"), fWindowListLock("window list"),
fTemporaryDisplayModeChange(0),
fAppCursor(NULL), fAppCursor(NULL),
fViewCursor(NULL), fViewCursor(NULL),
fCursorHideLevel(0), fCursorHideLevel(0),
@@ -185,6 +187,8 @@ ServerApp::~ServerApp()
fWindowListLock.Lock(); fWindowListLock.Lock();
} }
fDesktop->RevertScreenModes(fTemporaryDisplayModeChange);
for (int32 i = fBitmapList.CountItems(); i-- > 0;) { for (int32 i = fBitmapList.CountItems(); i-- > 0;) {
gBitmapManager->DeleteBitmap((ServerBitmap*)fBitmapList.ItemAt(i)); gBitmapManager->DeleteBitmap((ServerBitmap*)fBitmapList.ItemAt(i));
} }
@@ -2319,6 +2323,20 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
status = fDesktop->SetScreenMode(workspace, id, mode, status = fDesktop->SetScreenMode(workspace, id, mode,
makeDefault); makeDefault);
} }
if (status == B_OK) {
if (workspace == (uint32)B_CURRENT_WORKSPACE_INDEX
&& fDesktop->LockSingleWindow()) {
workspace = fDesktop->CurrentWorkspace();
fDesktop->UnlockSingleWindow();
}
if (!makeDefault) {
// Memorize the screen change, so that it can be reverted
// later
fTemporaryDisplayModeChange |= 1 << workspace;
} else
fTemporaryDisplayModeChange &= ~(1 << workspace);
}
fLink.StartMessage(status); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
+4 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2006, Haiku. * Copyright 2001-2009, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -43,8 +43,7 @@ public:
ServerApp(Desktop* desktop, ServerApp(Desktop* desktop,
port_id clientAppPort, port_id clientAppPort,
port_id clientLooperPort, port_id clientLooperPort,
team_id clientTeamID, team_id clientTeamID, int32 handlerID,
int32 handlerID,
const char* signature); const char* signature);
virtual ~ServerApp(); virtual ~ServerApp();
@@ -105,6 +104,7 @@ private:
bool _HasWindowUnderMouse(); bool _HasWindowUnderMouse();
private:
port_id fMessagePort; port_id fMessagePort;
port_id fClientReplyPort; port_id fClientReplyPort;
// our BApplication's event port // our BApplication's event port
@@ -128,6 +128,7 @@ private:
BPrivate::BTokenSpace fViewTokens; BPrivate::BTokenSpace fViewTokens;
int32 fInitialWorkspace; int32 fInitialWorkspace;
uint32 fTemporaryDisplayModeChange;
// NOTE: Bitmaps and Pictures are stored globally, but ServerApps // NOTE: Bitmaps and Pictures are stored globally, but ServerApps
// remember which ones they own so that they can destroy them when // remember which ones they own so that they can destroy them when