From 02b6c95990a4fd1647d63898cfbe0ee79e11e008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 20 Aug 2009 09:45:54 +0000 Subject: [PATCH] * VirtualScreen::RestoreConfiguration() now also takes care of collecting the screens that actually changed their resolution, which simplifies the code in Desktop considerably. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32537 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/Desktop.cpp | 23 +++++++-------- src/servers/app/VirtualScreen.cpp | 47 +++++++++++++++++++++++++++---- src/servers/app/VirtualScreen.h | 3 +- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 9cfd5acd6f..ee3a104b61 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -930,6 +930,7 @@ Desktop::SetWorkspace(int32 index) _SendFakeMouseMoved(); } + /*! Changes the current workspace to the one specified by \a index. You must hold the all window lock when calling this method. */ @@ -996,18 +997,18 @@ Desktop::_SetWorkspace(int32 index) fPreviousWorkspace = fCurrentWorkspace; fCurrentWorkspace = index; - // Change the display mode, if needed - // TODO: this needs to be done for all screens - display_mode previousMode, newMode; - fVirtualScreen.ScreenAt(0)->GetMode(&previousMode); - fVirtualScreen.RestoreConfiguration(*this, - fSettings->WorkspacesMessage(index)); - fVirtualScreen.ScreenAt(0)->GetMode(&newMode); - // We only need to invalidate the entire desktop if we changed display modes - if (memcmp(&previousMode, &newMode, sizeof(display_mode))) - ScreenChanged(fVirtualScreen.ScreenAt(0), false); + // Change the display modes, if needed - // show windows, and include them in the changed region - but only + uint32 changedScreens; + fVirtualScreen.RestoreConfiguration(*this, + fSettings->WorkspacesMessage(index), &changedScreens); + + for (int32 i = 0; changedScreens != 0; i++, changedScreens /= 2) { + if ((changedScreens & (1 << i)) != 0) + ScreenChanged(fVirtualScreen.ScreenAt(i), false); + } + + // Show windows, and include them in the changed region - but only // those that were not visible before (or whose position changed) WindowList windows(kWorkingList); diff --git a/src/servers/app/VirtualScreen.cpp b/src/servers/app/VirtualScreen.cpp index 55f3edadb5..7e0a1b0ccc 100644 --- a/src/servers/app/VirtualScreen.cpp +++ b/src/servers/app/VirtualScreen.cpp @@ -53,8 +53,33 @@ VirtualScreen::_Reset() status_t -VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings) +VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings, + uint32* _changedScreens) { + // Remember previous screen modes + + typedef std::map ScreenModeMap; + ScreenModeMap previousModes; + bool previousModesFailed = false; + + if (_changedScreens != NULL) { + *_changedScreens = 0; + + try { + for (int32 i = 0; i < fScreenList.CountItems(); i++) { + Screen* screen = fScreenList.ItemAt(i)->screen; + + display_mode mode; + screen->GetMode(&mode); + + previousModes.insert(std::make_pair(screen, mode)); + } + } catch (...) { + previousModesFailed = true; + *_changedScreens = ~0L; + } + } + _Reset(); // Copy current Desktop workspace settings @@ -64,7 +89,7 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings) ScreenList list; status_t status = gScreenManager->AcquireScreens(&desktop, NULL, 0, false, list); - if (status < B_OK) { + if (status != B_OK) { // TODO: we would try again here with force == true return status; } @@ -73,6 +98,17 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings) Screen* screen = list.ItemAt(i); AddScreen(screen); + + if (!previousModesFailed && _changedScreens != NULL) { + // Figure out which screens have changed their mode + display_mode mode; + screen->GetMode(&mode); + + ScreenModeMap::const_iterator found = previousModes.find(screen); + if (found != previousModes.end() + && memcmp(&mode, &found->second, sizeof(display_mode))) + *_changedScreens |= 1 << i; + } } return B_OK; @@ -147,11 +183,12 @@ VirtualScreen::AddScreen(Screen* screen) status = screen->SetMode(*mode, true); // TODO: named settings will get lost if setting the mode failed! } - if (status < B_OK) { - // TODO: more intelligent standard mode (monitor preference, desktop default, ...) + if (status != B_OK) { status_t status = screen->SetPreferredMode(); - if (status != B_OK) + if (status != B_OK) { + // TODO: more intelligent standard mode (desktop default, ...) status = screen->SetBestMode(1024, 768, B_RGB32, 60.f); + } if (status != B_OK) screen->SetBestMode(800, 600, B_RGB32, 60.f, false); } diff --git a/src/servers/app/VirtualScreen.h b/src/servers/app/VirtualScreen.h index 3e7ef5dc44..9845186aec 100644 --- a/src/servers/app/VirtualScreen.h +++ b/src/servers/app/VirtualScreen.h @@ -32,7 +32,8 @@ class VirtualScreen { { return fHWInterface; } status_t RestoreConfiguration(Desktop& desktop, - const BMessage* settings); + const BMessage* settings, + uint32* _changedScreens = NULL); status_t StoreConfiguration(BMessage& settings); status_t AddScreen(Screen* screen);