Add protected RestoreState, SaveState functions to BApplication. HasBeenRestored can be used to check in ReadyToRun if the RestoreState function has been called. The default implementation just store the window geometry and the decorator settings. Subclass implementations can use the global restore_window_geometry, save_window_geometry function for convenience. Please review. Will commit a simple session manager tomorrow.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39462 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,6 +31,8 @@
|
||||
#include <RegistrarDefs.h>
|
||||
#include <Resources.h>
|
||||
#include <Roster.h>
|
||||
#include <Screen.h>
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <AppMisc.h>
|
||||
@@ -48,6 +50,46 @@
|
||||
using namespace BPrivate;
|
||||
|
||||
|
||||
void
|
||||
restore_window_geometry(BWindow* window, const BMessage* windowGeometry)
|
||||
{
|
||||
BRect frame;
|
||||
status_t status = windowGeometry->FindRect("frame", &frame);
|
||||
if (status == B_OK) {
|
||||
// make sure window is on the screen
|
||||
BScreen screen;
|
||||
BRect screenFrame = screen.Frame();
|
||||
if (screenFrame.right < frame.left || screenFrame.bottom < frame.top)
|
||||
frame.OffsetBy(-frame.top, -frame.left);
|
||||
|
||||
window->MoveTo(frame.LeftTop());
|
||||
window->ResizeTo(frame.Width(), frame.Height());
|
||||
}
|
||||
|
||||
uint32 workspaces;
|
||||
status = windowGeometry->FindInt32("workspaces", (int32*)&workspaces);
|
||||
if (status == B_OK)
|
||||
window->SetWorkspaces(workspaces);
|
||||
|
||||
BMessage decoratroSettings;
|
||||
status = windowGeometry->FindMessage("decorator_settings",
|
||||
&decoratroSettings);
|
||||
if (status == B_OK)
|
||||
window->SetDecoratorSettings(decoratroSettings);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
save_window_geometry(const BWindow* window, BMessage* windowGeometry)
|
||||
{
|
||||
windowGeometry->AddRect("frame", window->Frame());
|
||||
windowGeometry->AddInt32("workspaces", window->Workspaces());
|
||||
BMessage decoratroSettings;
|
||||
if (window->GetDecoratorSettings(&decoratroSettings) == B_OK)
|
||||
windowGeometry->AddMessage("decorator_settings", &decoratroSettings);
|
||||
}
|
||||
|
||||
|
||||
BApplication *be_app = NULL;
|
||||
BMessenger be_app_messenger;
|
||||
|
||||
@@ -274,6 +316,7 @@ BApplication::_InitData(const char *signature, bool initGUI, status_t *_error)
|
||||
fServerAllocator = NULL;
|
||||
fInitialWorkspace = 0;
|
||||
//fDraggedMessage = NULL;
|
||||
fHasBeenRestored = 0;
|
||||
fReadyToRunCalled = false;
|
||||
|
||||
// initially, there is no pulse
|
||||
@@ -572,6 +615,8 @@ BApplication::ReadyToRun()
|
||||
// supposed to be implemented by subclasses
|
||||
}
|
||||
|
||||
#include "ApplicationPrivate.h"
|
||||
|
||||
|
||||
void
|
||||
BApplication::MessageReceived(BMessage *message)
|
||||
@@ -597,6 +642,19 @@ BApplication::MessageReceived(BMessage *message)
|
||||
be_roster->ActivateApp(Team());
|
||||
break;
|
||||
|
||||
case kRestoreStateMsg:
|
||||
if (RestoreState(message) == B_OK)
|
||||
fHasBeenRestored = 1;
|
||||
break;
|
||||
|
||||
case kSaveStateMsg:
|
||||
{
|
||||
BMessage state;
|
||||
if (SaveState(&state) == B_OK)
|
||||
message->SendReply(&state);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
BLooper::MessageReceived(message);
|
||||
break;
|
||||
@@ -1028,6 +1086,56 @@ BApplication::Perform(perform_code d, void *arg)
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BApplication::HasBeenRestored()
|
||||
{
|
||||
return fHasBeenRestored != 0;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BApplication::RestoreState(const BMessage* state)
|
||||
{
|
||||
int32 i = 0;
|
||||
while (true) {
|
||||
BMessage windowState;
|
||||
if (state->FindMessage("window", i, &windowState) != B_OK)
|
||||
break;
|
||||
i++;
|
||||
|
||||
BString title;
|
||||
if (windowState.FindString("title", &title) != B_OK)
|
||||
continue;
|
||||
|
||||
for (int i = 0; i < CountWindows(); i++) {
|
||||
BWindow* window = WindowAt(i);
|
||||
if (title != window->Title())
|
||||
continue;
|
||||
restore_window_geometry(window, &windowState);
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BApplication::SaveState(BMessage* state) const
|
||||
{
|
||||
// just store all window positions
|
||||
for (int i = 0; i < CountWindows(); i++) {
|
||||
BWindow* window = WindowAt(i);
|
||||
|
||||
BMessage windowState;
|
||||
save_window_geometry(window, &windowState);
|
||||
windowState.AddString("title", window->Title());
|
||||
state->AddMessage("window", &windowState);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void BApplication::_ReservedApplication1() {}
|
||||
void BApplication::_ReservedApplication2() {}
|
||||
void BApplication::_ReservedApplication3() {}
|
||||
|
||||
Reference in New Issue
Block a user