* 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:
+70
-16
@@ -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.
|
||||
You must hold the all window lock when calling this method.
|
||||
*/
|
||||
@@ -998,15 +1015,7 @@ Desktop::_SetWorkspace(int32 index)
|
||||
fCurrentWorkspace = index;
|
||||
|
||||
// Change the display modes, if needed
|
||||
|
||||
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));
|
||||
}
|
||||
_SetCurrentWorkspaceConfiguration();
|
||||
|
||||
// Show windows, and include them in the changed region - but only
|
||||
// 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)))
|
||||
return B_OK;
|
||||
|
||||
// Set the new one
|
||||
|
||||
status_t status = screen->SetMode(mode);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
} else {
|
||||
// retrieve from settings
|
||||
screen_configuration* configuration
|
||||
@@ -1153,12 +1168,6 @@ Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode,
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Set the new one
|
||||
|
||||
status_t status = screen->SetMode(mode);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
// Update our configurations
|
||||
|
||||
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, ¤t->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
|
||||
Desktop::ScreenChanged(Screen* screen)
|
||||
{
|
||||
ASSERT(fWindowLock.IsWriteLocked());
|
||||
ASSERT_MULTI_WRITE_LOCKED(fWindowLock);
|
||||
|
||||
// the entire screen is dirty, because we're actually
|
||||
// operating on an all new buffer in memory
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace BPrivate {
|
||||
|
||||
|
||||
class Desktop : public MessageLooper, public ScreenOwner {
|
||||
public:
|
||||
public:
|
||||
Desktop(uid_t userID);
|
||||
virtual ~Desktop();
|
||||
|
||||
@@ -103,19 +103,21 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
display_mode& mode);
|
||||
status_t GetScreenFrame(int32 workspace, int32 id,
|
||||
BRect& frame);
|
||||
void RevertScreenModes(uint32 workspaces);
|
||||
|
||||
void ScreenChanged(Screen* screen);
|
||||
|
||||
const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; }
|
||||
const ::VirtualScreen& VirtualScreen() const
|
||||
{ return fVirtualScreen; }
|
||||
DrawingEngine* GetDrawingEngine() const
|
||||
{ return fVirtualScreen.DrawingEngine(); }
|
||||
::HWInterface* HWInterface() const
|
||||
{ return fVirtualScreen.HWInterface(); }
|
||||
|
||||
// ScreenOwner implementation
|
||||
void ScreenRemoved(Screen* screen) {}
|
||||
void ScreenAdded(Screen* screen) {}
|
||||
bool ReleaseScreen(Screen* screen) { return false; }
|
||||
virtual void ScreenRemoved(Screen* screen) {}
|
||||
virtual void ScreenAdded(Screen* screen) {}
|
||||
virtual bool ReleaseScreen(Screen* screen) { return false; }
|
||||
|
||||
// Workspace methods
|
||||
|
||||
@@ -236,8 +238,9 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
void WriteWindowOrder(int32 workspace,
|
||||
BPrivate::LinkSender& sender);
|
||||
|
||||
private:
|
||||
private:
|
||||
void _LaunchInputServer();
|
||||
void _SetCurrentWorkspaceConfiguration();
|
||||
void _SetWorkspace(int32 index);
|
||||
void _ShowWindow(Window* window,
|
||||
bool affectsOtherWindows = true);
|
||||
@@ -281,7 +284,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
WindowList& _CurrentWindows();
|
||||
WindowList& _Windows(int32 index);
|
||||
|
||||
private:
|
||||
private:
|
||||
friend class DesktopSettings;
|
||||
friend class LockedDesktopSettings;
|
||||
|
||||
|
||||
@@ -143,18 +143,14 @@ ScreenConfigurations::Set(int32 id, const monitor_info* info,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ScreenConfigurations::Update(int32 id, const display_mode& mode)
|
||||
void
|
||||
ScreenConfigurations::Remove(screen_configuration* configuration)
|
||||
{
|
||||
screen_configuration* configuration = CurrentByID(id);
|
||||
if (configuration == NULL)
|
||||
return B_BAD_VALUE;
|
||||
return;
|
||||
|
||||
configuration->is_current = true;
|
||||
|
||||
memcpy(&configuration->mode, &mode, sizeof(display_mode));
|
||||
|
||||
return B_OK;
|
||||
fConfigurations.RemoveItem(configuration);
|
||||
// this also deletes the configuration
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
status_t Set(int32 id, const monitor_info* info,
|
||||
const BRect& frame,
|
||||
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 Restore(const BMessage& settings);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <FontPrivate.h>
|
||||
#include <MessengerPrivate.h>
|
||||
#include <PrivateScreen.h>
|
||||
#include <RosterPrivate.h>
|
||||
#include <ServerProtocol.h>
|
||||
#include <WindowPrivate.h>
|
||||
@@ -95,6 +96,7 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
|
||||
fSignature(signature),
|
||||
fClientTeam(clientTeam),
|
||||
fWindowListLock("window list"),
|
||||
fTemporaryDisplayModeChange(0),
|
||||
fAppCursor(NULL),
|
||||
fViewCursor(NULL),
|
||||
fCursorHideLevel(0),
|
||||
@@ -185,6 +187,8 @@ ServerApp::~ServerApp()
|
||||
fWindowListLock.Lock();
|
||||
}
|
||||
|
||||
fDesktop->RevertScreenModes(fTemporaryDisplayModeChange);
|
||||
|
||||
for (int32 i = fBitmapList.CountItems(); i-- > 0;) {
|
||||
gBitmapManager->DeleteBitmap((ServerBitmap*)fBitmapList.ItemAt(i));
|
||||
}
|
||||
@@ -2319,6 +2323,20 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
status = fDesktop->SetScreenMode(workspace, id, mode,
|
||||
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.Flush();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2006, Haiku.
|
||||
* Copyright 2001-2009, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -43,8 +43,7 @@ public:
|
||||
ServerApp(Desktop* desktop,
|
||||
port_id clientAppPort,
|
||||
port_id clientLooperPort,
|
||||
team_id clientTeamID,
|
||||
int32 handlerID,
|
||||
team_id clientTeamID, int32 handlerID,
|
||||
const char* signature);
|
||||
virtual ~ServerApp();
|
||||
|
||||
@@ -105,6 +104,7 @@ private:
|
||||
|
||||
bool _HasWindowUnderMouse();
|
||||
|
||||
private:
|
||||
port_id fMessagePort;
|
||||
port_id fClientReplyPort;
|
||||
// our BApplication's event port
|
||||
@@ -128,6 +128,7 @@ private:
|
||||
BPrivate::BTokenSpace fViewTokens;
|
||||
|
||||
int32 fInitialWorkspace;
|
||||
uint32 fTemporaryDisplayModeChange;
|
||||
|
||||
// NOTE: Bitmaps and Pictures are stored globally, but ServerApps
|
||||
// remember which ones they own so that they can destroy them when
|
||||
|
||||
Reference in New Issue
Block a user