Implement the missing pieces to handle per workspace display mode support.

Adjust Workspace view to correctly scale each workspace based on the 
resolution of that workspace. This exposes one or two anomalies in other
places in the app_server code though which I wasn't able to track down.
This fixes ticket #693.




git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28785 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Rene Gollent
2008-12-09 02:50:23 +00:00
parent fbbf64a410
commit 27c43a2d8f
7 changed files with 84 additions and 30 deletions
+3 -6
View File
@@ -246,12 +246,8 @@ ScreenWindow::ScreenWindow(ScreenSettings *settings)
BMenuItem *item = new BMenuItem("Current Workspace",
new BMessage(WORKSPACE_CHECK_MSG));
// TODO: since per workspace settings is unimplemented (Ticket #693)
// we force the menu to "All Workspaces" for now
fAllWorkspacesItem->SetMarked(true);
item->SetEnabled(false);
popUpMenu->AddItem(item);
fAllWorkspacesItem->SetMarked(true);
BMenuField* workspaceMenuField = new BMenuField(BRect(0, 0, 100, 15),
"WorkspaceMenu", NULL, popUpMenu, true);
@@ -1008,7 +1004,8 @@ ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const
void
ScreenWindow::_CheckApplyEnabled()
{
fApplyButton->SetEnabled(fSelected != fActive);
fApplyButton->SetEnabled(fSelected != fActive
|| fAllWorkspacesItem->IsMarked());
fRevertButton->SetEnabled(count_workspaces() != fOriginalWorkspaceCount
|| fSelected != fOriginal);
}
+50 -9
View File
@@ -878,6 +878,29 @@ Desktop::SetWorkspacesCount(int32 newCount)
}
/*!
Returns the virtual screen frame of the workspace specified by \a index.
*/
BRect
Desktop::WorkspaceFrame(int32 index) const
{
BRect frame;
if (index == fCurrentWorkspace)
frame = fVirtualScreen.Frame();
else if (index >= 0 && index < fSettings->WorkspacesCount()) {
BMessage screenData;
int32 width;
int32 height;
fSettings->WorkspacesMessage(index)->FindMessage("screen", &screenData);
if (screenData.FindInt32("width", &width) != B_OK || screenData.FindInt32("height", &height) != B_OK)
frame = fVirtualScreen.Frame();
else
frame.Set(0.0, 0.0, width - 1, height - 1);
}
return frame;
}
/*!
Changes the current workspace to the one specified by \a index.
*/
@@ -913,7 +936,6 @@ 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.
*/
@@ -923,6 +945,13 @@ Desktop::_SetWorkspace(int32 index)
int32 previousIndex = fCurrentWorkspace;
rgb_color previousColor = fWorkspaces[fCurrentWorkspace].Color();
bool movedMouseEventWindow = false;
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);
if (fMouseEventWindow != NULL) {
if (fMouseEventWindow->IsNormal()) {
@@ -1095,7 +1124,8 @@ Desktop::ScreenChanged(Screen* screen, bool makeDefault)
BRegion dirty(screen->Frame());
// update our cached screen region
fScreenRegion.Set(screen->Frame());
gInputManager->UpdateScreenBounds(screen->Frame());
BRegion background;
_RebuildClippingForAllWindows(background);
@@ -1122,17 +1152,28 @@ Desktop::ScreenChanged(Screen* screen, bool makeDefault)
fVirtualScreen.UpdateFrame();
if (makeDefault) {
// store settings
BMessage settings;
fVirtualScreen.StoreConfiguration(settings);
fWorkspaces[fCurrentWorkspace].StoreConfiguration(settings);
fSettings->SetWorkspacesMessage(fCurrentWorkspace, settings);
fSettings->Save(kWorkspacesSettings);
StoreConfiguration(fCurrentWorkspace);
}
}
status_t
Desktop::StoreConfiguration(int32 workspace)
{
if (workspace >= 0 && workspace < fSettings->WorkspacesCount()) {
// store settings
BMessage settings;
fVirtualScreen.StoreConfiguration(settings);
fWorkspaces[workspace].StoreConfiguration(settings);
fSettings->SetWorkspacesMessage(workspace, settings);
fSettings->Save(kWorkspacesSettings);
return B_OK;
}
return B_BAD_VALUE;
}
// #pragma mark - Methods for Window manipulation
+2 -2
View File
@@ -91,12 +91,11 @@ class Desktop : public MessageLooper, public ScreenOwner {
void GetLastMouseState(BPoint* position,
int32* buttons) const;
// for use by ServerWindow
void ScreenChanged(Screen* screen, bool makeDefault);
void ScreenRemoved(Screen* screen) {}
void ScreenAdded(Screen* screen) {}
bool ReleaseScreen(Screen* screen) { return false; }
status_t StoreConfiguration(int32 workspace);
const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; }
DrawingEngine* GetDrawingEngine() const
@@ -113,6 +112,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
Workspace::Private& WorkspaceAt(int32 index)
{ return fWorkspaces[index]; }
status_t SetWorkspacesCount(int32 newCount);
BRect WorkspaceFrame(int32 index) const;
// Window methods
+6 -2
View File
@@ -22,7 +22,6 @@
#include <stdlib.h>
#include <stdio.h>
static float
get_mode_frequency(const display_mode& mode)
{
@@ -91,6 +90,12 @@ Screen::Shutdown()
status_t
Screen::SetMode(const display_mode& mode, bool makeDefault)
{
display_mode current;
GetMode(&current);
current.flags = mode.flags;
if (!memcmp(&mode, &current, sizeof(display_mode)))
return B_OK;
gBitmapManager->SuspendOverlays();
status_t status = fHWInterface->SetMode(mode);
@@ -162,7 +167,6 @@ Screen::SetBestMode(uint16 width, uint16 height, uint32 colorSpace,
* mode.timing.v_total / 10 * int32(frequency * 10)) / 1000;
adjusted = true;
}
status = SetMode(mode, false);
if (status < B_OK && adjusted) {
// try again with the unchanged mode
+21 -10
View File
@@ -2167,7 +2167,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// 2) workspace index
// 3) display_mode to set
// 4) 'makeDefault' boolean
// TODO: See above: workspaces support, etc.
screen_id id;
link.Read<screen_id>(&id);
@@ -2183,15 +2182,27 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
if (status == B_OK && fDesktop->LockAllWindows()) {
display_mode oldMode;
fDesktop->ScreenAt(0)->GetMode(&oldMode);
if (memcmp(&oldMode, &mode, sizeof(display_mode))) {
status = fDesktop->ScreenAt(0)->SetMode(mode, makeDefault);
if (status == B_OK) {
gInputManager->UpdateScreenBounds(fDesktop->ScreenAt(0)->Frame());
fDesktop->ScreenChanged(fDesktop->ScreenAt(0), makeDefault);
}
} else
status = B_OK;
if (workspace == (uint32)fDesktop->CurrentWorkspace()) {
fDesktop->ScreenAt(0)->GetMode(&oldMode);
if (memcmp(&oldMode, &mode, sizeof(display_mode))) {
status = fDesktop->ScreenAt(0)->SetMode(mode, makeDefault);
if (status == B_OK) {
fDesktop->ScreenChanged(fDesktop->ScreenAt(0), makeDefault);
}
} else
status = B_OK;
} else {
// this is perhaps not ideal - it assumes that if the
// workspace is not the active one, then pull the
// configuration from active and store it to the specified
// workspace. This is safer since it's assumed that the
// active workspace has a display mode that's usable,
// but at the same time the API implies that you can set
// a non-visible workspace to whatever mode you like
// TODO: decide what to do here.
if (makeDefault)
fDesktop->StoreConfiguration(workspace);
}
fDesktop->UnlockAllWindows();
} else
status = B_ERROR;
+1
View File
@@ -167,6 +167,7 @@ VirtualScreen::AddScreen(Screen* screen)
fDrawingEngine = screen->GetDrawingEngine();
fHWInterface = screen->HWInterface();
fFrame = screen->Frame();
item->frame = fFrame;
fScreenList.AddItem(item);
+1 -1
View File
@@ -80,7 +80,7 @@ WorkspacesView::_GetGrid(int32& columns, int32& rows)
BRect
WorkspacesView::_ScreenFrame(int32 i)
{
return Window()->Desktop()->VirtualScreen().Frame();
return Window()->Desktop()->WorkspaceFrame(i);
}