Web+: implement a simple session management system.
When quitting the app or closing the last window, all windows and tabs are stored in a "Session" file. This is reloaded when the browser starts, allowing to restore all windows and tabs. Limitations: the page content and navigation history are not saved. The file is written only at exit so this can't be used for crash recovery (but you can make a backup of your default session). Fixes #6680.
This commit is contained in:
@@ -77,6 +77,7 @@ BrowserApp::BrowserApp()
|
|||||||
fInitialized(false),
|
fInitialized(false),
|
||||||
fSettings(NULL),
|
fSettings(NULL),
|
||||||
fCookies(NULL),
|
fCookies(NULL),
|
||||||
|
fSession(NULL),
|
||||||
fContext(NULL),
|
fContext(NULL),
|
||||||
fDownloadWindow(NULL),
|
fDownloadWindow(NULL),
|
||||||
fSettingsWindow(NULL),
|
fSettingsWindow(NULL),
|
||||||
@@ -92,6 +93,11 @@ BrowserApp::BrowserApp()
|
|||||||
fContext = new BUrlContext();
|
fContext = new BUrlContext();
|
||||||
fContext->SetCookieJar(BNetworkCookieJar(&cookieArchive));
|
fContext->SetCookieJar(BNetworkCookieJar(&cookieArchive));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
BString sessionStorePath = kApplicationName;
|
||||||
|
sessionStorePath << "/Session";
|
||||||
|
fSession = new SettingsMessage(B_USER_SETTINGS_DIRECTORY,
|
||||||
|
sessionStorePath.String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -100,6 +106,7 @@ BrowserApp::~BrowserApp()
|
|||||||
delete fLaunchRefsMessage;
|
delete fLaunchRefsMessage;
|
||||||
delete fSettings;
|
delete fSettings;
|
||||||
delete fCookies;
|
delete fCookies;
|
||||||
|
delete fSession;
|
||||||
delete fContext;
|
delete fContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +230,29 @@ BrowserApp::ReadyToRun()
|
|||||||
delete fLaunchRefsMessage;
|
delete fLaunchRefsMessage;
|
||||||
fLaunchRefsMessage = NULL;
|
fLaunchRefsMessage = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BMessage archivedWindow;
|
||||||
|
for (int i = 0; fSession->FindMessage("window", i, &archivedWindow) == B_OK;
|
||||||
|
i++) {
|
||||||
|
|
||||||
|
BRect frame = archivedWindow.FindRect("window frame");
|
||||||
|
BString url;
|
||||||
|
archivedWindow.FindString("tab", 0, &url);
|
||||||
|
BrowserWindow* window = new(std::nothrow) BrowserWindow(frame,
|
||||||
|
fSettings, url, fContext);
|
||||||
|
|
||||||
|
if (window != NULL) {
|
||||||
|
window->Show();
|
||||||
|
|
||||||
|
for (int j = 1; archivedWindow.FindString("tab", j, &url) == B_OK;
|
||||||
|
j++) {
|
||||||
|
printf("Create %d:%d\n", i, j);
|
||||||
|
_CreateNewTab(window, url, false);
|
||||||
|
pagesCreated++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pagesCreated == 0)
|
if (pagesCreated == 0)
|
||||||
_CreateNewWindow("", fullscreen);
|
_CreateNewWindow("", fullscreen);
|
||||||
|
|
||||||
@@ -267,8 +297,11 @@ BrowserApp::MessageReceived(BMessage* message)
|
|||||||
case WINDOW_CLOSED:
|
case WINDOW_CLOSED:
|
||||||
fWindowCount--;
|
fWindowCount--;
|
||||||
message->FindRect("window frame", &fLastWindowFrame);
|
message->FindRect("window frame", &fLastWindowFrame);
|
||||||
if (fWindowCount <= 0)
|
if (fWindowCount <= 0) {
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
BMessage* message = new BMessage(B_QUIT_REQUESTED);
|
||||||
|
message->AddMessage("window", DetachCurrentMessage());
|
||||||
|
PostMessage(message);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHOW_DOWNLOAD_WINDOW:
|
case SHOW_DOWNLOAD_WINDOW:
|
||||||
@@ -333,19 +366,36 @@ BrowserApp::QuitRequested()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; BWindow* window = WindowAt(i); i++) {
|
fSession->MakeEmpty();
|
||||||
BrowserWindow* webWindow = dynamic_cast<BrowserWindow*>(window);
|
|
||||||
if (!webWindow)
|
/* See if we got here because the last window is already closed.
|
||||||
continue;
|
* In that case we only need to save that one, which is already archived */
|
||||||
if (!webWindow->Lock())
|
BMessage* message = CurrentMessage();
|
||||||
continue;
|
BMessage windowMessage;
|
||||||
if (webWindow->QuitRequested()) {
|
|
||||||
fLastWindowFrame = webWindow->WindowFrame();
|
status_t ret = message->FindMessage("window", &windowMessage);
|
||||||
webWindow->Quit();
|
if (ret == B_OK) {
|
||||||
i--;
|
fSession->AddMessage("window", &windowMessage);
|
||||||
} else {
|
} else {
|
||||||
webWindow->Unlock();
|
for (int i = 0; BWindow* window = WindowAt(i); i++) {
|
||||||
return false;
|
BrowserWindow* webWindow = dynamic_cast<BrowserWindow*>(window);
|
||||||
|
if (!webWindow)
|
||||||
|
continue;
|
||||||
|
if (!webWindow->Lock())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BMessage windowArchive;
|
||||||
|
webWindow->Archive(&windowArchive, true);
|
||||||
|
fSession->AddMessage("window", &windowArchive);
|
||||||
|
|
||||||
|
if (webWindow->QuitRequested()) {
|
||||||
|
fLastWindowFrame = webWindow->WindowFrame();
|
||||||
|
webWindow->Quit();
|
||||||
|
i--;
|
||||||
|
} else {
|
||||||
|
webWindow->Unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ private:
|
|||||||
|
|
||||||
SettingsMessage* fSettings;
|
SettingsMessage* fSettings;
|
||||||
SettingsMessage* fCookies;
|
SettingsMessage* fCookies;
|
||||||
|
SettingsMessage* fSession;
|
||||||
BUrlContext* fContext;
|
BUrlContext* fContext;
|
||||||
|
|
||||||
DownloadWindow* fDownloadWindow;
|
DownloadWindow* fDownloadWindow;
|
||||||
|
|||||||
@@ -1186,18 +1186,39 @@ BrowserWindow::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BrowserWindow::Archive(BMessage* archive, bool deep) const
|
||||||
|
{
|
||||||
|
status_t ret = archive->AddRect("window frame", Frame());
|
||||||
|
|
||||||
|
for (int i = 0; i < fTabManager->CountTabs(); i++) {
|
||||||
|
BWebView* view = dynamic_cast<BWebView*>(fTabManager->ViewForTab(i));
|
||||||
|
if (view == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == B_OK)
|
||||||
|
ret = archive->AddString("tab", view->MainFrameURL());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BrowserWindow::QuitRequested()
|
BrowserWindow::QuitRequested()
|
||||||
{
|
{
|
||||||
// TODO: Check for modified form data and ask user for confirmation, etc.
|
// TODO: Check for modified form data and ask user for confirmation, etc.
|
||||||
|
|
||||||
|
BMessage message(WINDOW_CLOSED);
|
||||||
|
Archive(&message);
|
||||||
|
|
||||||
// Iterate over all tabs to delete all BWebViews.
|
// Iterate over all tabs to delete all BWebViews.
|
||||||
// Do this here, so WebKit tear down happens earlier.
|
// Do this here, so WebKit tear down happens earlier.
|
||||||
SetCurrentWebView(NULL);
|
SetCurrentWebView(NULL);
|
||||||
while (fTabManager->CountTabs() > 0)
|
while (fTabManager->CountTabs() > 0)
|
||||||
_ShutdownTab(0);
|
_ShutdownTab(0);
|
||||||
|
|
||||||
BMessage message(WINDOW_CLOSED);
|
|
||||||
message.AddRect("window frame", WindowFrame());
|
message.AddRect("window frame", WindowFrame());
|
||||||
be_app->PostMessage(&message);
|
be_app->PostMessage(&message);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ public:
|
|||||||
virtual void DispatchMessage(BMessage* message,
|
virtual void DispatchMessage(BMessage* message,
|
||||||
BHandler* target);
|
BHandler* target);
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual status_t Archive(BMessage* archive, bool deep =true) const;
|
||||||
virtual bool QuitRequested();
|
virtual bool QuitRequested();
|
||||||
virtual void MenusBeginning();
|
virtual void MenusBeginning();
|
||||||
virtual void MenusEnded();
|
virtual void MenusEnded();
|
||||||
|
|||||||
Reference in New Issue
Block a user