diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp index 5ad932303..c1651b92f 100644 --- a/src/lib/app/browserwindow.cpp +++ b/src/lib/app/browserwindow.cpp @@ -51,7 +51,6 @@ #include "navigationcontainer.h" #include "settings.h" #include "qzsettings.h" -#include "webtab.h" #include "speeddial.h" #include "menubar.h" #include "bookmarkstools.h" @@ -86,6 +85,109 @@ #include #endif +BrowserWindow::SavedWindow::SavedWindow() +{ +} + +BrowserWindow::SavedWindow::SavedWindow(BrowserWindow *window) +{ + windowState = window->isFullScreen() ? QByteArray() : window->saveState(); + windowGeometry = window->saveGeometry(); +#ifdef QZ_WS_X11 + virtualDesktop = window->getCurrentVirtualDesktop(); +#endif + + const int tabsCount = window->tabWidget()->count(); + tabs.reserve(tabsCount); + for (int i = 0; i < tabsCount; ++i) { + TabbedWebView *webView = window->weView(i); + if (!webView) { + continue; + } + WebTab* webTab = webView->webTab(); + if (!webTab) { + continue; + } + WebTab::SavedTab tab(webTab); + if (!tab.isValid()) { + continue; + } + if (webTab->isCurrentTab()) { + currentTab = tabs.size(); + } + tabs.append(tab); + } +} + +bool BrowserWindow::SavedWindow::isValid() const +{ + return currentTab > -1; +} + +void BrowserWindow::SavedWindow::clear() +{ + windowState.clear(); + windowGeometry.clear(); + virtualDesktop = -1; + currentTab = -1; + tabs.clear(); +} + +QDataStream &operator<<(QDataStream &stream, const BrowserWindow::SavedWindow &window) +{ + QByteArray tabsState; + QByteArray windowState; + +#ifdef QZ_WS_X11 + QDataStream stream1(&windowState, QIODevice::WriteOnly); + stream1 << window.windowState; + stream1 << window.virtualDesktop; +#else + windowState = window.windowState; +#endif + + QDataStream stream2(&tabsState, QIODevice::WriteOnly); + stream2 << window.tabs.count(); + for (const WebTab::SavedTab &tab : qAsConst(window.tabs)) { + stream2 << tab; + } + stream2 << window.currentTab; + + stream << tabsState; + stream << windowState; + return stream; +} + +QDataStream &operator>>(QDataStream &stream, BrowserWindow::SavedWindow &window) +{ + QByteArray tabsState; + QByteArray windowState; + + stream >> tabsState; + stream >> windowState; + +#ifdef QZ_WS_X11 + QDataStream stream1(&windowState, QIODevice::ReadOnly); + stream1 >> window.windowState; + stream1 >> window.virtualDesktop; +#else + window.windowState = windowState; +#endif + + int tabsCount = -1; + QDataStream stream2(&tabsState, QIODevice::ReadOnly); + stream2 >> tabsCount; + window.tabs.reserve(tabsCount); + for (int i = 0; i < tabsCount; ++i) { + WebTab::SavedTab tab; + stream2 >> tab; + window.tabs.append(tab); + } + stream2 >> window.currentTab; + + return stream; +} + BrowserWindow::BrowserWindow(Qz::BrowserWindowType type, const QUrl &startUrl) : QMainWindow(0) , m_startUrl(startUrl) @@ -886,11 +988,15 @@ void BrowserWindow::addDeleteOnCloseWidget(QWidget* widget) } } -void BrowserWindow::restoreWindowState(const RestoreManager::WindowData &d) +void BrowserWindow::restoreWindow(const SavedWindow &window) { - restoreState(d.windowState); + restoreState(window.windowState); + restoreGeometry(window.windowGeometry); +#ifdef QZ_WS_X11 + moveToVirtualDesktop(window.virtualDesktop); +#endif show(); // Window has to be visible before adding QWebEngineView's - m_tabWidget->restoreState(d.tabsState, d.currentTab); + m_tabWidget->restoreState(window.tabs, window.currentTab); updateStartupFocus(); } @@ -1426,39 +1532,6 @@ void BrowserWindow::closeTab() } } -QByteArray BrowserWindow::saveState(int version) const -{ -#ifdef QZ_WS_X11 - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - - stream << QMainWindow::saveState(version); - stream << getCurrentVirtualDesktop(); - - return data; -#else - return QMainWindow::saveState(version); -#endif -} - -bool BrowserWindow::restoreState(const QByteArray &state, int version) -{ -#ifdef QZ_WS_X11 - QByteArray windowState; - int desktopId = -1; - - QDataStream stream(state); - stream >> windowState; - stream >> desktopId; - - moveToVirtualDesktop(desktopId); - - return QMainWindow::restoreState(windowState, version); -#else - return QMainWindow::restoreState(state, version); -#endif -} - #ifdef QZ_WS_X11 int BrowserWindow::getCurrentVirtualDesktop() const { diff --git a/src/lib/app/browserwindow.h b/src/lib/app/browserwindow.h index 39782e503..894fe1967 100644 --- a/src/lib/app/browserwindow.h +++ b/src/lib/app/browserwindow.h @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2017 David Rosca +* Copyright (C) 2010-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ #include #include -#include "restoremanager.h" +#include "webtab.h" #include "qzcommon.h" class QLabel; @@ -41,8 +41,8 @@ class BookmarksMenu; class BookmarksToolbar; class AutoFill; class MainApplication; -class WebTab; class WebView; +class WebPage; class AdBlockIcon; class SideBar; class SideBarManager; @@ -58,13 +58,30 @@ class FALKON_EXPORT BrowserWindow : public QMainWindow Q_OBJECT public: + struct SavedWindow { + QByteArray windowState; + QByteArray windowGeometry; + int virtualDesktop = -1; + int currentTab = -1; + QVector tabs; + + SavedWindow(); + SavedWindow(BrowserWindow *window); + + bool isValid() const; + void clear(); + + friend QUPZILLA_EXPORT QDataStream &operator<<(QDataStream &stream, const SavedWindow &window); + friend QUPZILLA_EXPORT QDataStream &operator>>(QDataStream &stream, SavedWindow &window); + }; + explicit BrowserWindow(Qz::BrowserWindowType type, const QUrl &url = QUrl()); ~BrowserWindow(); void setStartTab(WebTab* tab); void setStartPage(WebPage* page); - void restoreWindowState(const RestoreManager::WindowData &d); + void restoreWindow(const SavedWindow &window); void saveSideBarWidth(); bool fullScreenNavigationVisible() const; @@ -85,9 +102,6 @@ public: SideBar* addSideBar(); - QByteArray saveState(int version = 0) const; - bool restoreState(const QByteArray &state, int version = 0); - TabbedWebView* weView() const; TabbedWebView* weView(int index) const; diff --git a/src/lib/app/mainapplication.cpp b/src/lib/app/mainapplication.cpp index fb103c0b3..7eb40bea7 100644 --- a/src/lib/app/mainapplication.cpp +++ b/src/lib/app/mainapplication.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2017 David Rosca +* Copyright (C) 2010-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -423,28 +423,15 @@ void MainApplication::openSession(BrowserWindow* window, RestoreData &restoreDat if (window->tabWidget()->normalTabsCount() > 1) { // This can only happen when recovering crashed session! - // - // Don't restore tabs in current window as user already opened - // some new tabs. - BrowserWindow* newWin = createWindow(Qz::BW_OtherRestoredWindow); - newWin->restoreWindowState(restoreData.at(0)); - restoreData.remove(0); - } - else { - // QTabWidget::count() - count of tabs is not updated after closing - // recovery tab ... - // update: it seems with ComboTabBar QTabWidget::count() is updated, - // we add pinnedTabCounts to currentTab! - int tabCount = window->tabWidget()->pinnedTabsCount(); - RestoreManager::WindowData data = restoreData.at(0); - data.currentTab += tabCount; - restoreData.remove(0); - window->restoreWindowState(data); + // Don't restore tabs in current window as user already opened some new tabs. + createWindow(Qz::BW_OtherRestoredWindow)->restoreWindow(restoreData.takeAt(0)); + } else { + window->restoreWindow(restoreData.takeAt(0)); } - foreach (const RestoreManager::WindowData &data, restoreData) { + foreach (const BrowserWindow::SavedWindow &data, restoreData) { BrowserWindow* window = createWindow(Qz::BW_OtherRestoredWindow); - window->restoreWindowState(data); + window->restoreWindow(data); } restoreOverrideCursor(); @@ -725,14 +712,8 @@ QByteArray MainApplication::saveState() const stream << Qz::sessionVersion; stream << m_windows.count(); - foreach (BrowserWindow* w, m_windows) { - stream << w->tabWidget()->saveState(); - if (w->isFullScreen()) { - stream << QByteArray(); - } - else { - stream << w->saveState(); - } + for (BrowserWindow *window : qAsConst(m_windows)) { + stream << BrowserWindow::SavedWindow(window); } return data; diff --git a/src/lib/session/recoveryjsobject.cpp b/src/lib/session/recoveryjsobject.cpp index 02e81e1a4..897e2bd84 100644 --- a/src/lib/session/recoveryjsobject.cpp +++ b/src/lib/session/recoveryjsobject.cpp @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2015-2017 David Rosca +* Copyright (C) 2015-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,10 +45,10 @@ QJsonArray RecoveryJsObject::restoreData() const QJsonArray out; int i = 0; - Q_FOREACH (const RestoreManager::WindowData &w, m_manager->restoreData()) { + Q_FOREACH (const BrowserWindow::SavedWindow &w, m_manager->restoreData()) { int j = 0; QJsonArray tabs; - Q_FOREACH (const WebTab::SavedTab &t, w.tabsState) { + Q_FOREACH (const WebTab::SavedTab &t, w.tabs) { const QIcon icon = t.icon.isNull() ? IconProvider::emptyWebIcon() : t.icon; QJsonObject tab; tab[QSL("tab")] = j; @@ -93,29 +93,29 @@ void RecoveryJsObject::restoreSession(const QStringList &excludeWin, const QStri int win = excludeWin.at(i).toInt(); int tab = excludeTab.at(i).toInt(); - if (!QzTools::containsIndex(data, win) || !QzTools::containsIndex(data.at(win).tabsState, tab)) + if (!QzTools::containsIndex(data, win) || !QzTools::containsIndex(data.at(win).tabs, tab)) continue; - RestoreManager::WindowData &wd = data[win]; + BrowserWindow::SavedWindow &wd = data[win]; - wd.tabsState.remove(tab); + wd.tabs.remove(tab); if (wd.currentTab >= tab) --wd.currentTab; - if (wd.tabsState.isEmpty()) { + if (wd.tabs.isEmpty()) { data.remove(win); continue; } if (wd.currentTab < 0) - wd.currentTab = wd.tabsState.size() - 1; + wd.currentTab = wd.tabs.size() - 1; } BrowserWindow *window = getBrowserWindow(); if (!window) return; - if (!mApp->restoreSession(window , data)) + if (!mApp->restoreSession(window, data)) startNewSession(); } diff --git a/src/lib/session/restoremanager.cpp b/src/lib/session/restoremanager.cpp index 16d88334d..61cc8a8ba 100644 --- a/src/lib/session/restoremanager.cpp +++ b/src/lib/session/restoremanager.cpp @@ -1,7 +1,7 @@ /* ============================================================ * Falkon - Qt web browser * Copyright (C) 2010-2014 Franz Fellner -* David Rosca +* Copyright (C) 2010-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -49,7 +49,7 @@ QObject *RestoreManager::recoveryObject(WebPage *page) return m_recoveryObject; } -void RestoreManager::createFromFile(const QString &file, QVector &data) +void RestoreManager::createFromFile(const QString &file, RestoreData &data) { if (!QFile::exists(file)) { return; @@ -68,40 +68,12 @@ void RestoreManager::createFromFile(const QString &file, QVector &da int windowCount; stream >> windowCount; + data.reserve(windowCount); - for (int win = 0; win < windowCount; ++win) { - QByteArray tabState; - QByteArray windowState; - stream >> tabState; - stream >> windowState; - - WindowData wd; - wd.windowState = windowState; - - QDataStream tabStream(tabState); - if (tabStream.atEnd()) { - continue; - } - - QVector tabs; - int tabListCount = 0; - tabStream >> tabListCount; - for (int i = 0; i < tabListCount; ++i) { - WebTab::SavedTab tab; - tabStream >> tab; - tabs.append(tab); - } - - if (tabs.count() == 0) - continue; - - wd.tabsState = tabs; - - int currentTab; - tabStream >> currentTab; - wd.currentTab = currentTab; - - data.append(wd); + for (int i = 0; i < windowCount; ++i) { + BrowserWindow::SavedWindow window; + stream >> window; + data.append(window); } } diff --git a/src/lib/session/restoremanager.h b/src/lib/session/restoremanager.h index 880a18cda..10f6cd426 100644 --- a/src/lib/session/restoremanager.h +++ b/src/lib/session/restoremanager.h @@ -1,7 +1,7 @@ /* ============================================================ * Falkon - Qt web browser * Copyright (C) 2010-2014 Franz Fellner -* David Rosca +* Copyright (C) 2010-2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,40 +19,32 @@ #ifndef RESTOREMANAGER_H #define RESTOREMANAGER_H -#include "webtab.h" #include "qzcommon.h" +#include "browserwindow.h" class WebPage; class RecoveryJsObject; +using RestoreData = QVector; + class FALKON_EXPORT RestoreManager { public: - struct WindowData { - int currentTab; - QByteArray windowState; - QVector tabsState; - }; - explicit RestoreManager(const QString &file); virtual ~RestoreManager(); bool isValid() const; - QVector restoreData() const; + RestoreData restoreData() const; QObject *recoveryObject(WebPage *page); - static void createFromFile(const QString &file, QVector &data); + static void createFromFile(const QString &file, RestoreData &data); + private: void createFromFile(const QString &file); RecoveryJsObject *m_recoveryObject; - QVector m_data; + RestoreData m_data; }; -typedef QVector RestoreData; - -// Hint to QVector to use std::realloc on item moving -Q_DECLARE_TYPEINFO(RestoreManager::WindowData, Q_MOVABLE_TYPE); - #endif // RESTOREMANAGER_H diff --git a/src/lib/session/sessionmanager.cpp b/src/lib/session/sessionmanager.cpp index 920aa261a..c2b8ecf82 100644 --- a/src/lib/session/sessionmanager.cpp +++ b/src/lib/session/sessionmanager.cpp @@ -1,6 +1,7 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2017 Razi Alavizadeh +* Copyright (C) 2017 Razi Alavizadeh +* Copyright (C) 2018 David Rosca * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -86,7 +87,7 @@ void SessionManager::openSession(QString sessionFilePath, SessionFlags flags) return; } - QVector sessionData; + RestoreData sessionData; RestoreManager::createFromFile(sessionFilePath, sessionData); if (sessionData.isEmpty()) @@ -278,7 +279,7 @@ void SessionManager::fillSessionsMetaDataListIfNeeded() for (int i = 0; i < sessionFiles.size(); ++i) { const QFileInfo &fileInfo = sessionFiles.at(i); - QVector data; + RestoreData data; RestoreManager::createFromFile(fileInfo.absoluteFilePath(), data); if (data.isEmpty()) diff --git a/src/lib/tabwidget/tabwidget.cpp b/src/lib/tabwidget/tabwidget.cpp index 95569b928..6966c1e8c 100644 --- a/src/lib/tabwidget/tabwidget.cpp +++ b/src/lib/tabwidget/tabwidget.cpp @@ -765,40 +765,6 @@ QList TabWidget::allTabs(bool withPinned) return allTabs; } -QByteArray TabWidget::saveState() -{ - int currentTabIndex = 0; - QVector tabList; - - for (int i = 0; i < count(); ++i) { - WebTab* webTab = weTab(i); - if (!webTab) - continue; - - WebTab::SavedTab tab(webTab); - if (!tab.isValid()) - continue; - - tabList.append(tab); - - if (webTab->isCurrentTab()) - currentTabIndex = tabList.size() - 1; - } - - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - - stream << tabList.count(); - - foreach (const WebTab::SavedTab &tab, tabList) { - stream << tab; - } - - stream << currentTabIndex; - - return data; -} - bool TabWidget::restoreState(const QVector &tabs, int currentTab) { for (int i = 0; i < tabs.size(); ++i) { diff --git a/src/lib/tabwidget/tabwidget.h b/src/lib/tabwidget/tabwidget.h index c238aa34e..541fdf9e2 100644 --- a/src/lib/tabwidget/tabwidget.h +++ b/src/lib/tabwidget/tabwidget.h @@ -69,7 +69,6 @@ public: explicit TabWidget(BrowserWindow* mainclass, QWidget* parent = 0); ~TabWidget(); - QByteArray saveState(); bool restoreState(const QVector &tabs, int currentTab); void closeRecoveryTab();