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:
Clemens Zeidler 2010-11-17 04:38:48 +00:00
parent f72d191b12
commit a5cf354a27
3 changed files with 124 additions and 1 deletions

View File

@ -29,6 +29,10 @@ namespace BPrivate {
}
void restore_window_geometry(BWindow* window, const BMessage* windowGeometry);
void save_window_geometry(const BWindow* window, BMessage* windowGeometry);
class BApplication : public BLooper {
public:
BApplication(const char* signature);
@ -91,6 +95,12 @@ public:
class Private;
protected:
// Session Manager
bool HasBeenRestored();
virtual status_t RestoreState(const BMessage* state);
virtual status_t SaveState(BMessage* state) const;
private:
typedef BLooper _inherited;
@ -145,8 +155,9 @@ private:
BMessageRunner* fPulseRunner;
status_t fInitError;
void* fServerReadOnlyMemory;
uint32 _reserved[12];
uint32 _reserved[11];
uint32 fHasBeenRestored;
bool fReadyToRunCalled;
};

View File

@ -14,6 +14,10 @@
struct server_read_only_memory;
const uint32 kRestoreStateMsg = '_RSM';
const uint32 kSaveStateMsg = '_SSM';
class BApplication::Private {
public:
static inline BPrivate::PortLink *ServerLink()

View File

@ -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() {}