From 8302ea16430afc414807c5251f04f129172e8995 Mon Sep 17 00:00:00 2001 From: Andrea Diamantini Date: Thu, 13 Oct 2011 00:58:30 +0200 Subject: Fix crash on private mode store/restore This commit, while does not perfectly fix the issue, "workaround" it a lot to fix crashes on private mode enter/exit - improve session store/restore - improve session manager code - calm down kDebug messages - applies code style CCBUG: 268328 --- src/application.cpp | 27 +++++++++++----- src/mainview.h | 5 ++- src/sessionmanager.cpp | 84 +++++++++++++++++++++++++++++++++++++++---------- src/sessionmanager.h | 15 +++++++-- src/urlbar/listitem.cpp | 1 - 5 files changed, 103 insertions(+), 29 deletions(-) diff --git a/src/application.cpp b/src/application.cpp index 39879e4c..6f9df43a 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -691,27 +691,38 @@ void Application::setPrivateBrowsingMode(bool b) return; } + sessionManager()->setSessionManagementEnabled(false); settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); _privateBrowsingAction->setChecked(true); + loadUrl(KUrl("about:home"), Rekonq::NewWindow); + + MainWindow *activeOne = m_mainWindows.at(0).data(); + Q_FOREACH(const QWeakPointer &w, m_mainWindows) { - w.data()->close(); + if (w.data() != activeOne) + w.data()->close(); } - loadUrl(KUrl("about:home"), Rekonq::NewWindow); } else { - Q_FOREACH(const QWeakPointer &w, m_mainWindows) - { - w.data()->close(); - } - settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); _privateBrowsingAction->setChecked(false); - if (!sessionManager()->restoreSessionFromScratch()) + int newWindows = sessionManager()->restoreSavedSession(); + if (newWindows == 0) + { loadUrl(KUrl("about:home"), Rekonq::NewWindow); + newWindows++; + } + + for (int i = newWindows; i < m_mainWindows.count(); ++i) + { + m_mainWindows.at(i).data()->close(); + } + + sessionManager()->setSessionManagementEnabled(true); } } diff --git a/src/mainview.h b/src/mainview.h index 8bd66161..9d5bc8c9 100644 --- a/src/mainview.h +++ b/src/mainview.h @@ -105,7 +105,10 @@ public: return m_recentlyClosedTabs; } - inline int originalWidthHint() const { return m_originalWidthHint; }; + inline int originalWidthHint() const + { + return m_originalWidthHint; + }; Q_SIGNALS: // current tab signals diff --git a/src/sessionmanager.cpp b/src/sessionmanager.cpp index 0548db3d..04b67a89 100644 --- a/src/sessionmanager.cpp +++ b/src/sessionmanager.cpp @@ -46,7 +46,8 @@ SessionManager::SessionManager(QObject *parent) : QObject(parent) - , m_safe(false) + , m_safe(true) + , m_isSessionEnabled(false) { m_sessionFilePath = KStandardDirs::locateLocal("appdata" , "session"); } @@ -54,8 +55,9 @@ SessionManager::SessionManager(QObject *parent) void SessionManager::saveSession() { - if (!m_safe || QWebSettings::globalSettings()->testAttribute(QWebSettings::PrivateBrowsingEnabled)) + if (!m_isSessionEnabled || !m_safe) return; + m_safe = false; kDebug() << "SAVING SESSION..."; @@ -95,9 +97,11 @@ void SessionManager::saveSession() } session.appendChild(window); } + QTextStream TextStream(&sessionFile); document.save(TextStream, 2); sessionFile.close(); + m_safe = true; return; } @@ -114,8 +118,9 @@ bool SessionManager::restoreSessionFromScratch() return false; } - bool windowAlreadyOpen = rApp->mainWindowList().count(); - MainWindowList wl; + bool windowAlreadyOpen = (rApp->mainWindowList().count() == 0) ? false : true; + if (!windowAlreadyOpen) + rApp->newMainWindow(false); QDomDocument document("session"); if (!document.setContent(&sessionFile, false)) @@ -129,15 +134,7 @@ bool SessionManager::restoreSessionFromScratch() QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); int currentTab = 0; - if (windowAlreadyOpen) - windowAlreadyOpen = false; - else - rApp->newMainWindow(false); - - wl = rApp->mainWindowList(); //get the latest windowlist - if (wl.count() == 0) - continue; - MainView *mv = wl.at(0).data()->mainView(); //last mainwindow created will be first one in mainwindow list + MainView *mv = rApp->mainWindowList().at(0).data()->mainView(); //last mainwindow created will be first one in mainwindow list for (unsigned int tabNo = 0; tabNo < window.elementsByTagName("tab").length(); tabNo++) { @@ -168,8 +165,6 @@ bool SessionManager::restoreSessionFromScratch() void SessionManager::restoreCrashedSession() { - setSessionManagementEnabled(true); - QFile sessionFile(m_sessionFilePath); if (!sessionFile.exists()) { @@ -190,8 +185,6 @@ void SessionManager::restoreCrashedSession() return; } - setSessionManagementEnabled(false); - for (unsigned int winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) { QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); @@ -225,6 +218,63 @@ void SessionManager::restoreCrashedSession() } +int SessionManager::restoreSavedSession() +{ + QFile sessionFile(m_sessionFilePath); + if (!sessionFile.exists()) + { + kDebug() << "Unable to find session file" << sessionFile.fileName(); + return 0; + } + + if (!sessionFile.open(QFile::ReadOnly)) + { + kDebug() << "Unable to open session file" << sessionFile.fileName(); + return 0; + } + + QDomDocument document("session"); + if (!document.setContent(&sessionFile, false)) + { + kDebug() << "Unable to parse session file" << sessionFile.fileName(); + return 0; + } + + unsigned int winNo; + + for (winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) + { + QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); + int currentTab = 0; + + MainView *mv = rApp->newMainWindow()->mainView(); + + for (unsigned int tabNo = 0; tabNo < window.elementsByTagName("tab").length(); tabNo++) + { + QDomElement tab = window.elementsByTagName("tab").at(tabNo).toElement(); + if (tab.hasAttribute("currentTab")) + currentTab = tabNo; + + WebView *view = (tabNo == 0) ? mv->webTab(0)->view() : mv->newWebTab()->view(); + + QDomCDATASection historySection = tab.firstChild().toCDATASection(); + QByteArray history = QByteArray::fromBase64(historySection.data().toAscii()); + + QDataStream readingStream(&history, QIODevice::ReadOnly); + readingStream >> *(view->history()); + + // Get sure about urls are loaded + KUrl u = KUrl(tab.attribute("url")); + if (u.protocol() == QL1S("about")) + view->load(u); + } + mv->tabBar()->setCurrentIndex(currentTab); + } + + return winNo; +} + + QList SessionManager::closedSites() { QList list; diff --git a/src/sessionmanager.h b/src/sessionmanager.h index ae6caaa2..d0d7efde 100644 --- a/src/sessionmanager.h +++ b/src/sessionmanager.h @@ -42,7 +42,7 @@ class TabHistory; /** - * Session Management + * Session Management: Needs clean up :) */ class REKONQ_TESTS_EXPORT SessionManager : public QObject { @@ -52,21 +52,32 @@ public: inline void setSessionManagementEnabled(bool on) { - m_safe = on; + m_isSessionEnabled = on; } QList closedSites(); + // This method restores session + // while turning back from Private mode + int restoreSavedSession(); + public Q_SLOTS: + // This method restores session + // on restart when restore at startup is chosen bool restoreSessionFromScratch(); private Q_SLOTS: void saveSession(); + + // This method restores session + // after a crash void restoreCrashedSession(); private: QString m_sessionFilePath; + bool m_safe; + bool m_isSessionEnabled; }; diff --git a/src/urlbar/listitem.cpp b/src/urlbar/listitem.cpp index 7860d535..a8561ca3 100644 --- a/src/urlbar/listitem.cpp +++ b/src/urlbar/listitem.cpp @@ -492,7 +492,6 @@ KAction *EngineBar::newEngineAction(KService::Ptr engine, KService::Ptr selected QUrl u = engine->property("Query").toUrl(); KUrl url = KUrl(u.toString(QUrl::RemovePath | QUrl::RemoveQuery)); - kDebug() << "Engine NAME: " << engine->name() << " URL: " << url; KAction *a = new KAction(rApp->iconManager()->iconForUrl(url), engine->name(), this); a->setCheckable(true); if (engine->desktopEntryName() == selectedEngine->desktopEntryName()) a->setChecked(true); -- cgit v1.2.1