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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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(¤t);
|
||||
current.flags = mode.flags;
|
||||
if (!memcmp(&mode, ¤t, 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -167,6 +167,7 @@ VirtualScreen::AddScreen(Screen* screen)
|
||||
fDrawingEngine = screen->GetDrawingEngine();
|
||||
fHWInterface = screen->HWInterface();
|
||||
fFrame = screen->Frame();
|
||||
item->frame = fFrame;
|
||||
|
||||
fScreenList.AddItem(item);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user