summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.cpp29
-rw-r--r--examples/webenginewidgets/demobrowser/browserapplication.h1
-rw-r--r--examples/webenginewidgets/demobrowser/edittreeview.cpp7
-rw-r--r--examples/webenginewidgets/demobrowser/history.cpp99
-rw-r--r--examples/webenginewidgets/demobrowser/history.h13
-rw-r--r--examples/webenginewidgets/demobrowser/tabwidget.cpp3
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp2
-rw-r--r--src/core/browser_context_adapter.cpp2
-rw-r--r--src/core/network_delegate_qt.cpp3
-rw-r--r--src/core/url_request_context_getter_qt.cpp171
-rw-r--r--src/core/url_request_context_getter_qt.h39
-rw-r--r--src/core/web_contents_adapter.cpp1
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc60
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp1
14 files changed, 315 insertions, 116 deletions
diff --git a/examples/webenginewidgets/demobrowser/browserapplication.cpp b/examples/webenginewidgets/demobrowser/browserapplication.cpp
index 0d5c54199..26764b93c 100644
--- a/examples/webenginewidgets/demobrowser/browserapplication.cpp
+++ b/examples/webenginewidgets/demobrowser/browserapplication.cpp
@@ -136,11 +136,7 @@ BrowserApplication::BrowserApplication(int &argc, char **argv)
socket.connectToServer(serverName);
if (socket.waitForConnected(500)) {
QTextStream stream(&socket);
- QStringList args = QCoreApplication::arguments();
- if (args.count() > 1)
- stream << args.last();
- else
- stream << QString();
+ stream << getCommandLineUrlArgument();
stream.flush();
socket.waitForBytesWritten();
return;
@@ -255,11 +251,13 @@ void BrowserApplication::postLaunch()
// newMainWindow() needs to be called in main() for this to happen
if (m_mainWindows.count() > 0) {
- QStringList args = QCoreApplication::arguments();
- if (args.count() > 1)
- mainWindow()->loadPage(args.last());
- else
+ const QString url = getCommandLineUrlArgument();
+ if (!url.isEmpty()) {
+ mainWindow()->loadPage(url);
+ } else {
mainWindow()->slotHome();
+ }
+
}
BrowserApplication::historyManager();
}
@@ -421,6 +419,19 @@ void BrowserApplication::installTranslator(const QString &name)
QApplication::installTranslator(translator);
}
+QString BrowserApplication::getCommandLineUrlArgument() const
+{
+ const QStringList args = QCoreApplication::arguments();
+ if (args.count() > 1) {
+ const QString lastArg = args.last();
+ const bool isValidUrl = QUrl::fromUserInput(lastArg).isValid();
+ if (isValidUrl)
+ return lastArg;
+ }
+
+ return QString();
+}
+
#if defined(Q_OS_OSX)
bool BrowserApplication::event(QEvent* event)
{
diff --git a/examples/webenginewidgets/demobrowser/browserapplication.h b/examples/webenginewidgets/demobrowser/browserapplication.h
index f509c67f7..5c75d41b3 100644
--- a/examples/webenginewidgets/demobrowser/browserapplication.h
+++ b/examples/webenginewidgets/demobrowser/browserapplication.h
@@ -119,6 +119,7 @@ private slots:
private:
void clean();
void installTranslator(const QString &name);
+ QString getCommandLineUrlArgument() const;
static HistoryManager *s_historyManager;
static DownloadManager *s_downloadManager;
diff --git a/examples/webenginewidgets/demobrowser/edittreeview.cpp b/examples/webenginewidgets/demobrowser/edittreeview.cpp
index 763fbec5c..f4c9a0d70 100644
--- a/examples/webenginewidgets/demobrowser/edittreeview.cpp
+++ b/examples/webenginewidgets/demobrowser/edittreeview.cpp
@@ -49,6 +49,8 @@
****************************************************************************/
#include "edittreeview.h"
+#include "browserapplication.h"
+#include "history.h"
#include <QtGui/QKeyEvent>
@@ -73,13 +75,12 @@ void EditTreeView::removeOne()
if (!model())
return;
QModelIndex ci = currentIndex();
- int row = ci.row();
- model()->removeRow(row, ci.parent());
+ BrowserApplication::historyManager()->removeHistoryEntry(model()->data(ci,HistoryModel::UrlStringRole).toString());
}
void EditTreeView::removeAll()
{
if (!model())
return;
- model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex());
+ BrowserApplication::historyManager()->clear();
}
diff --git a/examples/webenginewidgets/demobrowser/history.cpp b/examples/webenginewidgets/demobrowser/history.cpp
index aaab44ac8..188490aca 100644
--- a/examples/webenginewidgets/demobrowser/history.cpp
+++ b/examples/webenginewidgets/demobrowser/history.cpp
@@ -101,7 +101,7 @@ HistoryManager::~HistoryManager()
m_saveTimer->saveIfNeccessary();
}
-QList<HistoryItem> HistoryManager::history() const
+QList<HistoryItem> &HistoryManager::history()
{
return m_history;
}
@@ -120,6 +120,15 @@ void HistoryManager::addHistoryEntry(const QString &url)
addHistoryItem(item);
}
+void HistoryManager::removeHistoryEntry(const QString &url)
+{
+ QUrl cleanUrl(url);
+ cleanUrl.setPassword(QString());
+ cleanUrl.setHost(cleanUrl.host().toLower());
+ HistoryItem item(cleanUrl.toString(), QDateTime::currentDateTime());
+ removeHistoryItem(item);
+}
+
void HistoryManager::setHistory(const QList<HistoryItem> &history, bool loadedAndSorted)
{
m_history = history;
@@ -173,7 +182,7 @@ void HistoryManager::checkForExpired()
}
if (nextTimeout > 0)
break;
- HistoryItem item = m_history.takeLast();
+ const HistoryItem& item = m_history.last();
// remove from saved file also
m_lastSavedUrl = QString();
emit entryRemoved(item);
@@ -188,12 +197,21 @@ void HistoryManager::addHistoryItem(const HistoryItem &item)
if (BrowserApplication::instance()->privateBrowsing())
return;
- m_history.prepend(item);
emit entryAdded(item);
if (m_history.count() == 1)
checkForExpired();
}
+void HistoryManager::removeHistoryItem(const HistoryItem &item)
+{
+ for (int i = m_history.count() - 1 ; i >= 0; --i) {
+ if (item.url == m_history.at(i).url) {
+ //delete all related entries with that url
+ emit entryRemoved(m_history.at(i));
+ }
+ }
+}
+
void HistoryManager::updateHistoryItem(const QUrl &url, const QString &title)
{
for (int i = 0; i < m_history.count(); ++i) {
@@ -224,7 +242,6 @@ void HistoryManager::setHistoryLimit(int limit)
void HistoryManager::clear()
{
- m_history.clear();
m_lastSavedUrl = QString();
emit historyReset();
m_saveTimer->changeOccurred();
@@ -374,10 +391,10 @@ HistoryModel::HistoryModel(HistoryManager *history, QObject *parent)
connect(m_history, SIGNAL(historyReset()),
this, SLOT(historyReset()));
connect(m_history, SIGNAL(entryRemoved(HistoryItem)),
- this, SLOT(historyReset()));
+ this, SLOT(entryRemoved(HistoryItem)));
connect(m_history, SIGNAL(entryAdded(HistoryItem)),
- this, SLOT(entryAdded()));
+ this, SLOT(entryAdded(HistoryItem)));
connect(m_history, SIGNAL(entryUpdated(int)),
this, SLOT(entryUpdated(int)));
}
@@ -385,15 +402,26 @@ HistoryModel::HistoryModel(HistoryManager *history, QObject *parent)
void HistoryModel::historyReset()
{
beginResetModel();
+ m_history->history().clear();
endResetModel();
}
-void HistoryModel::entryAdded()
+void HistoryModel::entryAdded(const HistoryItem &item)
{
beginInsertRows(QModelIndex(), 0, 0);
+ m_history->history().prepend(item);
endInsertRows();
}
+void HistoryModel::entryRemoved(const HistoryItem &item)
+{
+ int index = m_history->history().indexOf(item);
+ Q_ASSERT(index > -1);
+ beginRemoveRows(QModelIndex(),index, index);
+ m_history->history().takeAt(index);
+ endRemoveRows();
+}
+
void HistoryModel::entryUpdated(int offset)
{
QModelIndex idx = index(offset, 0);
@@ -468,12 +496,9 @@ bool HistoryModel::removeRows(int row, int count, const QModelIndex &parent)
return false;
int lastRow = row + count - 1;
beginRemoveRows(parent, row, lastRow);
- QList<HistoryItem> lst = m_history->history();
+ QList<HistoryItem> &lst = m_history->history();
for (int i = lastRow; i >= row; --i)
lst.removeAt(i);
- disconnect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset()));
- m_history->setHistory(lst);
- connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset()));
endRemoveRows();
return true;
}
@@ -664,8 +689,6 @@ TreeProxyModel::TreeProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
bool TreeProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
- if (!source_parent.isValid())
- return true;
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
@@ -678,14 +701,16 @@ HistoryDialog::HistoryDialog(QWidget *parent, HistoryManager *setHistory) : QDia
tree->setUniformRowHeights(true);
tree->setSelectionBehavior(QAbstractItemView::SelectRows);
tree->setTextElideMode(Qt::ElideMiddle);
- QAbstractItemModel *model = history->historyTreeModel();
+ QAbstractItemModel *model = history->historyFilterModel();
TreeProxyModel *proxyModel = new TreeProxyModel(this);
connect(search, SIGNAL(textChanged(QString)),
proxyModel, SLOT(setFilterFixedString(QString)));
connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeOne()));
- connect(removeAllButton, SIGNAL(clicked()), history, SLOT(clear()));
+ connect(removeAllButton, SIGNAL(clicked()), tree, SLOT(removeAll()));
proxyModel->setSourceModel(model);
+ proxyModel->setFilterKeyColumn(1);
tree->setModel(proxyModel);
+ tree->setSortingEnabled(true);
tree->setExpanded(proxyModel->index(0, 0), true);
tree->setAlternatingRowColors(true);
QFontMetrics fm(font());
@@ -739,25 +764,13 @@ HistoryFilterModel::HistoryFilterModel(QAbstractItemModel *sourceModel, QObject
setSourceModel(sourceModel);
}
-int HistoryFilterModel::historyLocation(const QString &url) const
-{
- load();
- if (!m_historyHash.contains(url))
- return 0;
- return sourceModel()->rowCount() - m_historyHash.value(url);
-}
-
-QVariant HistoryFilterModel::data(const QModelIndex &index, int role) const
-{
- return QAbstractProxyModel::data(index, role);
-}
-
void HistoryFilterModel::setSourceModel(QAbstractItemModel *newSourceModel)
{
+ beginResetModel();
if (sourceModel()) {
disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset()));
disconnect(sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(dataChanged(QModelIndex,QModelIndex)));
+ this, SLOT(sourceDataChanged(QModelIndex,QModelIndex)));
disconnect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(sourceRowsInserted(QModelIndex,int,int)));
disconnect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
@@ -767,7 +780,6 @@ void HistoryFilterModel::setSourceModel(QAbstractItemModel *newSourceModel)
QAbstractProxyModel::setSourceModel(newSourceModel);
if (sourceModel()) {
- m_loaded = false;
connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset()));
connect(sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(sourceDataChanged(QModelIndex,QModelIndex)));
@@ -776,6 +788,8 @@ void HistoryFilterModel::setSourceModel(QAbstractItemModel *newSourceModel)
connect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(sourceRowsRemoved(QModelIndex,int,int)));
}
+ load();
+ endResetModel();
}
void HistoryFilterModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
@@ -790,14 +804,13 @@ QVariant HistoryFilterModel::headerData(int section, Qt::Orientation orientation
void HistoryFilterModel::sourceReset()
{
- m_loaded = false;
beginResetModel();
+ load();
endResetModel();
}
int HistoryFilterModel::rowCount(const QModelIndex &parent) const
{
- load();
if (parent.isValid())
return 0;
return m_historyHash.count();
@@ -810,14 +823,12 @@ int HistoryFilterModel::columnCount(const QModelIndex &parent) const
QModelIndex HistoryFilterModel::mapToSource(const QModelIndex &proxyIndex) const
{
- load();
int sourceRow = sourceModel()->rowCount() - proxyIndex.internalId();
return sourceModel()->index(sourceRow, proxyIndex.column());
}
QModelIndex HistoryFilterModel::mapFromSource(const QModelIndex &sourceIndex) const
{
- load();
QString url = sourceIndex.data(HistoryModel::UrlStringRole).toString();
if (!m_historyHash.contains(url))
return QModelIndex();
@@ -843,7 +854,6 @@ QModelIndex HistoryFilterModel::mapFromSource(const QModelIndex &sourceIndex) co
QModelIndex HistoryFilterModel::index(int row, int column, const QModelIndex &parent) const
{
- load();
if (row < 0 || row >= rowCount(parent)
|| column < 0 || column >= columnCount(parent))
return QModelIndex();
@@ -858,8 +868,6 @@ QModelIndex HistoryFilterModel::parent(const QModelIndex &) const
void HistoryFilterModel::load() const
{
- if (m_loaded)
- return;
m_sourceRow.clear();
m_historyHash.clear();
m_historyHash.reserve(sourceModel()->rowCount());
@@ -871,15 +879,12 @@ void HistoryFilterModel::load() const
m_historyHash[url] = sourceModel()->rowCount() - i;
}
}
- m_loaded = true;
}
void HistoryFilterModel::sourceRowsInserted(const QModelIndex &parent, int start, int end)
{
Q_ASSERT(start == end && start == 0);
Q_UNUSED(end);
- if (!m_loaded)
- return;
QModelIndex idx = sourceModel()->index(start, 0, parent);
QString url = idx.data(HistoryModel::UrlStringRole).toString();
if (m_historyHash.contains(url)) {
@@ -1184,6 +1189,7 @@ bool HistoryTreeModel::removeRows(int row, int count, const QModelIndex &parent)
void HistoryTreeModel::setSourceModel(QAbstractItemModel *newSourceModel)
{
+ beginResetModel();
if (sourceModel()) {
disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset()));
disconnect(sourceModel(), SIGNAL(layoutChanged()), this, SLOT(sourceReset()));
@@ -1191,6 +1197,8 @@ void HistoryTreeModel::setSourceModel(QAbstractItemModel *newSourceModel)
this, SLOT(sourceRowsInserted(QModelIndex,int,int)));
disconnect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(sourceRowsRemoved(QModelIndex,int,int)));
+ disconnect(sourceModel(), &QAbstractItemModel::dataChanged, this,
+ &HistoryTreeModel::sourceDataChanged);
}
QAbstractProxyModel::setSourceModel(newSourceModel);
@@ -1202,9 +1210,9 @@ void HistoryTreeModel::setSourceModel(QAbstractItemModel *newSourceModel)
this, SLOT(sourceRowsInserted(QModelIndex,int,int)));
connect(sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(sourceRowsRemoved(QModelIndex,int,int)));
+ connect(sourceModel(), &QAbstractItemModel::dataChanged, this,
+ &HistoryTreeModel::sourceDataChanged);
}
-
- beginResetModel();
endResetModel();
}
@@ -1293,3 +1301,10 @@ void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, i
endRemoveRows();
}
}
+
+void HistoryTreeModel::sourceDataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight,
+ const QVector<int> roles)
+{
+ emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight), roles);
+}
diff --git a/examples/webenginewidgets/demobrowser/history.h b/examples/webenginewidgets/demobrowser/history.h
index 0ae5a7bf7..6d7da5e6d 100644
--- a/examples/webenginewidgets/demobrowser/history.h
+++ b/examples/webenginewidgets/demobrowser/history.h
@@ -103,14 +103,16 @@ public:
~HistoryManager();
bool historyContains(const QString &url) const;
+
void addHistoryEntry(const QString &url);
+ void removeHistoryEntry(const QString &url);
void updateHistoryItem(const QUrl &url, const QString &title);
int historyLimit() const;
void setHistoryLimit(int limit);
- QList<HistoryItem> history() const;
+ QList<HistoryItem>& history();
void setHistory(const QList<HistoryItem> &history, bool loadedAndSorted = false);
// History manager keeps around these models for use by the completer and other classes
@@ -128,6 +130,7 @@ private slots:
protected:
void addHistoryItem(const HistoryItem &item);
+ void removeHistoryItem(const HistoryItem &item);
private:
void load();
@@ -149,7 +152,8 @@ class HistoryModel : public QAbstractTableModel
public slots:
void historyReset();
- void entryAdded();
+ void entryAdded(const HistoryItem &item);
+ void entryRemoved(const HistoryItem &item);
void entryUpdated(int offset);
public:
@@ -185,7 +189,6 @@ public:
inline bool historyContains(const QString &url) const
{ load(); return m_historyHash.contains(url); }
- int historyLocation(const QString &url) const;
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
@@ -196,7 +199,6 @@ public:
QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const;
QModelIndex parent(const QModelIndex& index= QModelIndex()) const;
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
private slots:
void sourceReset();
@@ -314,7 +316,8 @@ private slots:
void sourceReset();
void sourceRowsInserted(const QModelIndex &parent, int start, int end);
void sourceRowsRemoved(const QModelIndex &parent, int start, int end);
-
+ void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QVector<int> roles);
private:
int sourceDateRow(int row) const;
mutable QList<int> m_sourceRowCache;
diff --git a/examples/webenginewidgets/demobrowser/tabwidget.cpp b/examples/webenginewidgets/demobrowser/tabwidget.cpp
index 3b56d115b..e684d3757 100644
--- a/examples/webenginewidgets/demobrowser/tabwidget.cpp
+++ b/examples/webenginewidgets/demobrowser/tabwidget.cpp
@@ -782,6 +782,9 @@ void TabWidget::webViewUrlChanged(const QUrl &url)
int index = webViewIndex(webView);
if (-1 != index) {
m_tabBar->setTabData(index, url);
+ HistoryManager *manager = BrowserApplication::historyManager();
+ if (url.isValid())
+ manager->addHistoryEntry(url.toString());
}
emit tabsChanged();
}
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index 8f004777f..f5d1e6d39 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -79,9 +79,11 @@ QWEBENGINE_PRIVATE_EXPORT void initialize()
return;
}
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 1))
// Bail out silently if the user did not construct a QGuiApplication.
if (!qobject_cast<QGuiApplication *>(app))
return;
+#endif
if (app->thread() != QThread::currentThread()) {
qFatal("QtWebEngine::initialize() must be called from the Qt gui thread.");
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index fe667c570..ba9d671ae 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -151,6 +151,8 @@ QWebEngineUrlRequestInterceptor *BrowserContextAdapter::requestInterceptor()
void BrowserContextAdapter::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
{
m_requestInterceptor = interceptor;
+ if (m_browserContext->url_request_getter_.get())
+ m_browserContext->url_request_getter_->updateRequestInterceptor();
}
void BrowserContextAdapter::addClient(BrowserContextAdapterClient *adapterClient)
diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp
index b1a2faf8d..ff0e8320c 100644
--- a/src/core/network_delegate_qt.cpp
+++ b/src/core/network_delegate_qt.cpp
@@ -90,7 +90,6 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::C
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_requestContextGetter);
- Q_ASSERT(m_requestContextGetter->m_browserContext);
const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request);
@@ -104,7 +103,7 @@ int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::C
const QUrl qUrl = toQt(request->url());
- QWebEngineUrlRequestInterceptor* interceptor = m_requestContextGetter->m_browserContext->requestInterceptor();
+ QWebEngineUrlRequestInterceptor* interceptor = m_requestContextGetter->m_requestInterceptor;
if (interceptor) {
QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType)
, static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType)
diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp
index afbb66b95..579e33b66 100644
--- a/src/core/url_request_context_getter_qt.cpp
+++ b/src/core/url_request_context_getter_qt.cpp
@@ -91,14 +91,23 @@ using content::BrowserThread;
URLRequestContextGetterQt::URLRequestContextGetterQt(QSharedPointer<BrowserContextAdapter> browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors)
: m_ignoreCertificateErrors(false)
+ , m_mutex(QMutex::Recursive)
+ , m_contextInitialized(false)
+ , m_updateAllStorage(false)
+ , m_updateCookieStore(false)
+ , m_updateHttpCache(false)
+ , m_updateJobFactory(true)
+ , m_updateUserAgent(false)
, m_browserContext(browserContext)
, m_baseJobFactory(0)
, m_cookieDelegate(new CookieMonsterDelegateQt())
, m_requestInterceptors(std::move(request_interceptors))
{
std::swap(m_protocolHandlers, *protocolHandlers);
- m_cookieDelegate->setClient(m_browserContext->cookieStore());
+ QMutexLocker lock(&m_mutex);
+ m_cookieDelegate->setClient(browserContext->cookieStore());
+ setFullConfiguration(browserContext);
updateStorageSettings();
}
@@ -108,6 +117,23 @@ URLRequestContextGetterQt::~URLRequestContextGetterQt()
delete m_proxyConfigService.fetchAndStoreAcquire(0);
}
+
+void URLRequestContextGetterQt::setFullConfiguration(QSharedPointer<BrowserContextAdapter> browserContext)
+{
+ if (!browserContext)
+ return;
+
+ m_requestInterceptor = browserContext->requestInterceptor();
+ m_persistentCookiesPolicy = browserContext->persistentCookiesPolicy();
+ m_cookiesPath = browserContext->cookiesPath();
+ m_httpAcceptLanguage = browserContext->httpAcceptLanguage();
+ m_httpUserAgent = browserContext->httpUserAgent();
+ m_httpCacheType = browserContext->httpCacheType();
+ m_httpCachePath = browserContext->httpCachePath();
+ m_httpCacheMaxSize = browserContext->httpCacheMaxSize();
+ m_customUrlSchemes = browserContext->customUrlSchemes();
+}
+
net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
@@ -117,8 +143,10 @@ net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
m_networkDelegate.reset(new NetworkDelegateQt(this));
m_urlRequestContext->set_network_delegate(m_networkDelegate.get());
- generateStorage();
+ QMutexLocker lock(&m_mutex);
+ generateAllStorage();
generateJobFactory();
+ m_contextInitialized = true;
}
return m_urlRequestContext.get();
@@ -127,24 +155,31 @@ net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext()
void URLRequestContextGetterQt::updateStorageSettings()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- // m_proxyConfigService having a non-null value is used to indicate
- // storage is already being updated.
- if (!m_proxyConfigService.loadAcquire()) {
+
+ QMutexLocker lock(&m_mutex);
+ setFullConfiguration(m_browserContext.toStrongRef());
+
+ if (!m_updateAllStorage) {
+ m_updateAllStorage = true;
// We must create the proxy config service on the UI loop on Linux because it
// must synchronously run on the glib message loop. This will be passed to
// the URLRequestContextStorage on the IO thread in GetURLRequestContext().
- m_proxyConfigService.storeRelease(new ProxyConfigServiceQt(net::ProxyService::CreateSystemProxyConfigService(
- content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
- content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
- )));
- if (m_storage) {
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this));
- }
+ Q_ASSERT(m_proxyConfigService == 0);
+ m_proxyConfigService =
+ new ProxyConfigServiceQt(
+ net::ProxyService::CreateSystemProxyConfigService(
+ content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
+ content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)
+ ));
+ if (m_contextInitialized)
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateAllStorage, this));
}
}
void URLRequestContextGetterQt::cancelAllUrlRequests()
{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_urlRequestContext);
std::set<const net::URLRequest*>* url_requests = m_urlRequestContext->url_requests();
@@ -158,6 +193,17 @@ void URLRequestContextGetterQt::cancelAllUrlRequests()
}
+void URLRequestContextGetterQt::generateAllStorage()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
+ QMutexLocker lock(&m_mutex);
+ generateStorage();
+ generateCookieStore();
+ generateUserAgent();
+ generateHttpCache();
+ m_updateAllStorage = false;
+}
+
void URLRequestContextGetterQt::generateStorage()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
@@ -175,8 +221,6 @@ void URLRequestContextGetterQt::generateStorage()
net::ProxyConfigService *proxyConfigService = m_proxyConfigService.fetchAndStoreAcquire(0);
Q_ASSERT(proxyConfigService);
- generateCookieStore();
- generateUserAgent();
m_storage->set_channel_id_service(scoped_ptr<net::ChannelIDService>(new net::ChannelIDService(
new net::DefaultChannelIDStore(NULL),
@@ -207,16 +251,20 @@ void URLRequestContextGetterQt::generateStorage()
// Give |m_storage| ownership at the end in case it's |mapped_host_resolver|.
m_storage->set_host_resolver(std::move(host_resolver));
-
- generateHttpCache();
}
void URLRequestContextGetterQt::updateCookieStore()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- // Do not trigger an update if another is already triggered, or we are not yet initialized.
- if (m_urlRequestContext && !m_proxyConfigService && !m_updateCookieStore.fetchAndStoreRelaxed(1))
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateCookieStore, this));
+ QMutexLocker lock(&m_mutex);
+ m_httpAcceptLanguage = m_browserContext.data()->httpAcceptLanguage();
+ m_httpUserAgent = m_browserContext.data()->httpUserAgent();
+
+ if (m_contextInitialized && !m_updateAllStorage && !m_updateCookieStore) {
+ m_updateCookieStore = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateCookieStore, this));
+ }
}
void URLRequestContextGetterQt::generateCookieStore()
@@ -224,14 +272,16 @@ void URLRequestContextGetterQt::generateCookieStore()
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_storage);
- m_updateCookieStore = 0;
+
+ QMutexLocker lock(&m_mutex);
+ m_updateCookieStore = false;
// Unset it first to get a chance to destroy and flush the old cookie store before opening a new on possibly the same file.
m_storage->set_cookie_store(0);
m_cookieDelegate->setCookieMonster(0);
net::CookieStore* cookieStore = 0;
- switch (m_browserContext->persistentCookiesPolicy()) {
+ switch (m_persistentCookiesPolicy) {
case BrowserContextAdapter::NoPersistentCookies:
cookieStore =
content::CreateCookieStore(content::CookieStoreConfig(
@@ -244,7 +294,7 @@ void URLRequestContextGetterQt::generateCookieStore()
case BrowserContextAdapter::AllowPersistentCookies:
cookieStore =
content::CreateCookieStore(content::CookieStoreConfig(
- toFilePath(m_browserContext->cookiesPath()),
+ toFilePath(m_cookiesPath),
content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES,
NULL,
m_cookieDelegate.get())
@@ -253,7 +303,7 @@ void URLRequestContextGetterQt::generateCookieStore()
case BrowserContextAdapter::ForcePersistentCookies:
cookieStore =
content::CreateCookieStore(content::CookieStoreConfig(
- toFilePath(m_browserContext->cookiesPath()),
+ toFilePath(m_cookiesPath),
content::CookieStoreConfig::RESTORED_SESSION_COOKIES,
NULL,
m_cookieDelegate.get())
@@ -270,9 +320,15 @@ void URLRequestContextGetterQt::generateCookieStore()
void URLRequestContextGetterQt::updateUserAgent()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- // Do not trigger an update if all storage settings are already being updated
- if (m_urlRequestContext && !m_proxyConfigService)
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateUserAgent, this));
+ QMutexLocker lock(&m_mutex);
+ m_httpAcceptLanguage = m_browserContext.data()->httpAcceptLanguage();
+ m_httpUserAgent = m_browserContext.data()->httpUserAgent();
+
+ if (m_contextInitialized && !m_updateAllStorage && !m_updateUserAgent) {
+ m_updateUserAgent = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateUserAgent, this));
+ }
}
void URLRequestContextGetterQt::generateUserAgent()
@@ -281,26 +337,48 @@ void URLRequestContextGetterQt::generateUserAgent()
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_storage);
+ QMutexLocker lock(&m_mutex);
+ m_updateUserAgent = true;
+
m_storage->set_http_user_agent_settings(scoped_ptr<net::HttpUserAgentSettings>(
- new net::StaticHttpUserAgentSettings(m_browserContext->httpAcceptLanguage().toStdString(), m_browserContext->httpUserAgent().toStdString())));
+ new net::StaticHttpUserAgentSettings(m_httpAcceptLanguage.toStdString(), m_httpUserAgent.toStdString())));
}
void URLRequestContextGetterQt::updateHttpCache()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- // Do not trigger a new update if another is already triggered
- if (m_urlRequestContext && !m_proxyConfigService && !m_updateHttpCache.fetchAndStoreRelaxed(1))
- content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateHttpCache, this));
+ QMutexLocker lock(&m_mutex);
+ m_httpCacheType = m_browserContext.data()->httpCacheType();
+ m_httpCachePath = m_browserContext.data()->httpCachePath();
+ m_httpCacheMaxSize = m_browserContext.data()->httpCacheMaxSize();
+
+ if (m_contextInitialized && !m_updateAllStorage && !m_updateHttpCache) {
+ m_updateHttpCache = true;
+ content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&URLRequestContextGetterQt::generateHttpCache, this));
+ }
}
void URLRequestContextGetterQt::updateJobFactory()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_customUrlSchemes = m_browserContext.data()->customUrlSchemes();
- if (m_urlRequestContext && !m_updateJobFactory.fetchAndStoreRelaxed(1))
+ if (m_contextInitialized && !m_updateJobFactory) {
+ m_updateJobFactory = true;
content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
- base::Bind(&URLRequestContextGetterQt::regenerateJobFactory,
- this, m_browserContext->customUrlSchemes()));
+ base::Bind(&URLRequestContextGetterQt::regenerateJobFactory, this));
+ }
+}
+
+void URLRequestContextGetterQt::updateRequestInterceptor()
+{
+ Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ QMutexLocker lock(&m_mutex);
+ m_requestInterceptor = m_browserContext.data()->requestInterceptor();
+
+ // We in this case do not need to regenerate any Chromium classes.
}
static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second)
@@ -355,15 +433,18 @@ void URLRequestContextGetterQt::generateHttpCache()
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_storage);
+ QMutexLocker lock(&m_mutex);
+ m_updateHttpCache = false;
+
net::HttpCache::DefaultBackend* main_backend = 0;
- switch (m_browserContext->httpCacheType()) {
+ switch (m_httpCacheType) {
case BrowserContextAdapter::MemoryHttpCache:
main_backend =
new net::HttpCache::DefaultBackend(
net::MEMORY_CACHE,
net::CACHE_BACKEND_DEFAULT,
base::FilePath(),
- m_browserContext->httpCacheMaxSize(),
+ m_httpCacheMaxSize,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)
);
break;
@@ -372,8 +453,8 @@ void URLRequestContextGetterQt::generateHttpCache()
new net::HttpCache::DefaultBackend(
net::DISK_CACHE,
net::CACHE_BACKEND_DEFAULT,
- toFilePath(m_browserContext->httpCachePath()),
- m_browserContext->httpCacheMaxSize(),
+ toFilePath(m_httpCachePath),
+ m_httpCacheMaxSize,
BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE)
);
break;
@@ -393,7 +474,6 @@ void URLRequestContextGetterQt::generateHttpCache()
cache = new net::HttpCache(m_httpNetworkSession.get(), scoped_ptr<net::HttpCache::DefaultBackend>(main_backend), false);
m_storage->set_http_transaction_factory(scoped_ptr<net::HttpCache>(cache));
- m_updateHttpCache = 0;
}
void URLRequestContextGetterQt::clearHttpCache()
@@ -419,6 +499,9 @@ void URLRequestContextGetterQt::generateJobFactory()
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(!m_jobFactory);
+ QMutexLocker lock(&m_mutex);
+ m_updateJobFactory = false;
+
scoped_ptr<net::URLRequestJobFactoryImpl> jobFactory(new net::URLRequestJobFactoryImpl());
{
@@ -437,7 +520,7 @@ void URLRequestContextGetterQt::generateJobFactory()
jobFactory->SetProtocolHandler(url::kFtpScheme,
scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::FtpProtocolHandler(new net::FtpNetworkLayer(m_urlRequestContext->host_resolver()))));
- m_installedCustomSchemes = m_browserContext->customUrlSchemes();
+ m_installedCustomSchemes = m_customUrlSchemes;
Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) {
jobFactory->SetProtocolHandler(scheme.toStdString(), scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new CustomProtocolHandler(m_browserContext)));
}
@@ -457,22 +540,24 @@ void URLRequestContextGetterQt::generateJobFactory()
m_urlRequestContext->set_job_factory(m_jobFactory.get());
}
-void URLRequestContextGetterQt::regenerateJobFactory(const QList<QByteArray> customSchemes)
+void URLRequestContextGetterQt::regenerateJobFactory()
{
Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
Q_ASSERT(m_urlRequestContext);
Q_ASSERT(m_jobFactory);
Q_ASSERT(m_baseJobFactory);
- m_updateJobFactory.storeRelease(0);
- if (customSchemes == m_installedCustomSchemes)
+ QMutexLocker lock(&m_mutex);
+ m_updateJobFactory = false;
+
+ if (m_customUrlSchemes == m_installedCustomSchemes)
return;
Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) {
m_baseJobFactory->SetProtocolHandler(scheme.toStdString(), nullptr);
}
- m_installedCustomSchemes = customSchemes;
+ m_installedCustomSchemes = m_customUrlSchemes;
Q_FOREACH (const QByteArray &scheme, m_installedCustomSchemes) {
m_baseJobFactory->SetProtocolHandler(scheme.toStdString(), scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new CustomProtocolHandler(m_browserContext)));
}
diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h
index 7078c7a44..eca956ea6 100644
--- a/src/core/url_request_context_getter_qt.h
+++ b/src/core/url_request_context_getter_qt.h
@@ -55,9 +55,10 @@
#include "cookie_monster_delegate_qt.h"
#include "network_delegate_qt.h"
+#include "browser_context_adapter.h"
-#include <QtCore/qglobal.h>
#include <QtCore/qatomic.h>
+#include <QtCore/qmutex.h>
#include <QtCore/qsharedpointer.h>
namespace net {
@@ -67,8 +68,7 @@ class ProxyConfigService;
namespace QtWebEngineCore {
-class BrowserContextAdapter;
-
+// FIXME: This class should be split into a URLRequestContextGetter and a ProfileIOData, similar to what chrome does.
class URLRequestContextGetterQt : public net::URLRequestContextGetter {
public:
URLRequestContextGetterQt(QSharedPointer<BrowserContextAdapter> browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors);
@@ -83,26 +83,36 @@ public:
void updateHttpCache();
void clearHttpCache();
void updateJobFactory();
+ void updateRequestInterceptor();
private:
virtual ~URLRequestContextGetterQt();
// Called on the IO thread:
+ void generateAllStorage();
void generateStorage();
void generateCookieStore();
void generateHttpCache();
void generateUserAgent();
void generateJobFactory();
- void regenerateJobFactory(const QList<QByteArray> customSchemes);
+ void regenerateJobFactory();
void clearCurrentCacheBackend();
void cancelAllUrlRequests();
net::HttpNetworkSession::Params generateNetworkSessionParams();
+ void setFullConfiguration(QSharedPointer<BrowserContextAdapter> browserContext);
+
bool m_ignoreCertificateErrors;
- QAtomicInt m_updateCookieStore;
- QAtomicInt m_updateHttpCache;
- QAtomicInt m_updateJobFactory;
- QSharedPointer<BrowserContextAdapter> m_browserContext;
+
+ QMutex m_mutex;
+ bool m_contextInitialized;
+ bool m_updateAllStorage;
+ bool m_updateCookieStore;
+ bool m_updateHttpCache;
+ bool m_updateJobFactory;
+ bool m_updateUserAgent;
+
+ QWeakPointer<BrowserContextAdapter> m_browserContext;
content::ProtocolHandlerMap m_protocolHandlers;
QAtomicPointer<net::ProxyConfigService> m_proxyConfigService;
@@ -115,7 +125,20 @@ private:
scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate;
content::URLRequestInterceptorScopedVector m_requestInterceptors;
scoped_ptr<net::HttpNetworkSession> m_httpNetworkSession;
+
QList<QByteArray> m_installedCustomSchemes;
+ QWebEngineUrlRequestInterceptor* m_requestInterceptor;
+
+ // Configuration values to setup URLRequestContext in IO thread, copied from browserContext
+ // FIXME: Should later be moved to a separate ProfileIOData class.
+ BrowserContextAdapter::PersistentCookiesPolicy m_persistentCookiesPolicy;
+ QString m_cookiesPath;
+ QString m_httpAcceptLanguage;
+ QString m_httpUserAgent;
+ BrowserContextAdapter::HttpCacheType m_httpCacheType;
+ QString m_httpCachePath;
+ int m_httpCacheMaxSize;
+ QList<QByteArray> m_customUrlSchemes;
friend class NetworkDelegateQt;
};
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 116cd704e..82d21696c 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -520,6 +520,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
d->webContents->GetController().LoadURLWithParams(params);
d->webContents->Focus();
+ d->webContents->Unselect();
}
void WebContentsAdapter::save()
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index dec9d0407..4bb449016 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -46,6 +46,8 @@
\section1 Building Qt WebEngine from Source
+ Static builds are not supported.
+
The requirements for building Qt 5 modules from source are listed separately for each supported
platform:
@@ -58,13 +60,63 @@
In addition, the following tools are required for building the \l {Qt WebEngine} module:
\list
- \li Windows: Visual Studio 2013 or Visual Studio 2015
- \li Linux: Clang or GCC version 4.7 or later
- \li OS X: Xcode version 5.1 or later on OS X 10.9 or later
+ \li \l {All Platforms}
+ \li \l {Windows}
+ \li \l {Linux}
+ \li \l {OS X}
+ \endlist
+
+ The tests for skipping the Qt WebEngine build are located in the
+ \c qtwebengine repository, in the \c tools\qmake\mkspecs subdirectory.
+ They can be found by searching for \c skipBuild.
+
+ \section2 All Platforms
+
+ On all platforms, the following tools are required:
+
+ \list
+ \li \l Python 2.7 or later
+ \li Bison, Flex
+ \li GPerf
+ \endlist
+
+ \section2 Windows
+
+ On Windows, Visual Studio 2013 or Visual Studio 2015 is required.
+
+ \section2 Linux
+
+ On Linux, Clang or GCC version 4.7 or later is required.
+
+ Qt WebEngine requires \c pkg-config to detect most of its dependencies. The
+ following \c pkg-config files are required:
+
+ \list
+ \li \c dbus-1
+ \li \c fontconfig
\endlist
+ If Qt was configured for \c xcb, the following \c pkg-config files are also
+ required:
+
+ \list
+ \li \c libdrm
+ \li \c xcomposite
+ \li \c xcursor
+ \li \c xi
+ \li \c xrandr
+ \li \c xscrnsaver
+ \li \c xtst
+ \endlist
+
+ Further, development packages for \c khr and \c libcap need to be installed.
+
+ \section2 OS X
+
+ On OS X, Xcode version 5.1 or later on OS X 10.9 or later is required.
+
\note Qt WebEngine cannot be built for the 32-bit mode of OS X (using the
- macx-clang-32 mkspec).
+ \c macx-clang-32 \c mkspec).
\section1 Pepper Plugin API Support
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 396e6950d..6171391e3 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -321,6 +321,7 @@ bool QWebEngineView::event(QEvent *ev)
void QWebEngineView::contextMenuEvent(QContextMenuEvent *event)
{
QMenu *menu = page()->createStandardContextMenu();
+ connect(menu, &QMenu::aboutToHide, menu, &QObject::deleteLater);
menu->popup(event->globalPos());
}