diff options
Diffstat (limited to 'src/core')
35 files changed, 378 insertions, 115 deletions
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro index d11994e98..19b67876c 100644 --- a/src/core/api/core_api.pro +++ b/src/core/api/core_api.pro @@ -5,6 +5,7 @@ TEMPLATE = lib CONFIG += staticlib c++11 QT += network core-private +QT_PRIVATE += webenginecoreheaders-private # Don't create .prl file for this intermediate library because # their contents get used when linking against them, breaking @@ -42,6 +43,7 @@ HEADERS = \ qwebengineurlschemehandler.h SOURCES = \ + qtwebenginecoreglobal.cpp \ qwebenginecookiestore.cpp \ qwebengineurlrequestinfo.cpp \ qwebengineurlrequestjob.cpp \ diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp new file mode 100644 index 000000000..0e857d7d9 --- /dev/null +++ b/src/core/api/qtwebenginecoreglobal.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtwebenginecoreglobal_p.h" + +#include <QGuiApplication> +#include <QOpenGLContext> +#include <QThread> + +QT_BEGIN_NAMESPACE +Q_GUI_EXPORT void qt_gl_set_global_share_context(QOpenGLContext *context); +Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); +QT_END_NAMESPACE + +namespace QtWebEngineCore { + +static QOpenGLContext *shareContext; + +static void deleteShareContext() +{ + delete shareContext; + shareContext = 0; +} + +// ### Qt 6: unify this logic and Qt::AA_ShareOpenGLContexts. +// QtWebEngine::initialize was introduced first and meant to be called +// after the QGuiApplication creation, when AA_ShareOpenGLContexts fills +// the same need but the flag has to be set earlier. + +QWEBENGINE_PRIVATE_EXPORT void initialize() +{ +#ifdef Q_OS_WIN32 + qputenv("QT_D3DCREATE_MULTITHREADED", "1"); +#endif + + // No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts). + if (qt_gl_global_share_context()) + return; + + QCoreApplication *app = QCoreApplication::instance(); + if (!app) { + qFatal("QtWebEngine::initialize() must be called after the construction of the application object."); + return; + } + if (app->thread() != QThread::currentThread()) { + qFatal("QtWebEngine::initialize() must be called from the Qt gui thread."); + return; + } + + if (shareContext) + return; + + shareContext = new QOpenGLContext; + shareContext->create(); + qAddPostRoutine(deleteShareContext); + qt_gl_set_global_share_context(shareContext); + + // Classes like QOpenGLWidget check for the attribute + app->setAttribute(Qt::AA_ShareOpenGLContexts); +} +} // namespace QtWebEngineCore diff --git a/src/core/api/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal.h index 16daaab7d..a17b355eb 100644 --- a/src/core/api/qtwebenginecoreglobal.h +++ b/src/core/api/qtwebenginecoreglobal.h @@ -39,6 +39,8 @@ #include <QtCore/qglobal.h> +QT_BEGIN_NAMESPACE + #if defined(BUILDING_CHROMIUM) # define QWEBENGINE_EXPORT Q_DECL_EXPORT #else @@ -47,4 +49,6 @@ #define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match"); +QT_END_NAMESPACE + #endif // QTWEBENGINECOREGLOBAL_H diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h index b675438f5..a8758df7d 100644 --- a/src/core/api/qwebenginecallback.h +++ b/src/core/api/qwebenginecallback.h @@ -37,7 +37,7 @@ #ifndef QWEBENGINECALLBACK_H #define QWEBENGINECALLBACK_H -#include "qtwebenginecoreglobal.h" +#include <QtWebEngineCore/qtwebenginecoreglobal.h> #include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE #include <QtCore/qshareddata.h> diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h index 9bc9b9727..348fed464 100644 --- a/src/core/api/qwebenginecallback_p.h +++ b/src/core/api/qwebenginecallback_p.h @@ -37,6 +37,17 @@ #ifndef QWEBENGINECALLBACK_P_H #define QWEBENGINECALLBACK_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qtwebenginecoreglobal_p.h" #include "qwebenginecallback.h" diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp index 51753e87b..2938eddbd 100644 --- a/src/core/api/qwebenginecookiestore.cpp +++ b/src/core/api/qwebenginecookiestore.cpp @@ -46,13 +46,12 @@ QT_BEGIN_NAMESPACE using namespace QtWebEngineCore; -QWebEngineCookieStorePrivate::QWebEngineCookieStorePrivate(QWebEngineCookieStore* q) +QWebEngineCookieStorePrivate::QWebEngineCookieStorePrivate() : m_nextCallbackId(CallbackDirectory::ReservedCallbackIdsEnd) , m_deleteSessionCookiesPending(false) , m_deleteAllCookiesPending(false) , m_getAllCookiesPending(false) , delegate(0) - , q_ptr(q) { } @@ -89,6 +88,14 @@ void QWebEngineCookieStorePrivate::processPendingUserCookies() m_pendingUserCookies.clear(); } +void QWebEngineCookieStorePrivate::rejectPendingUserCookies() +{ + m_getAllCookiesPending = false; + m_deleteAllCookiesPending = false; + m_deleteSessionCookiesPending = false; + m_pendingUserCookies.clear(); +} + void QWebEngineCookieStorePrivate::setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie, const QUrl &origin) { const quint64 currentCallbackId = callback ? m_nextCallbackId++ : static_cast<quint64>(CallbackDirectory::NoCallbackId); @@ -246,8 +253,7 @@ bool QWebEngineCookieStorePrivate::canSetCookie(const QUrl &firstPartyUrl, const */ QWebEngineCookieStore::QWebEngineCookieStore(QObject *parent) - : QObject(parent) - , d_ptr(new QWebEngineCookieStorePrivate(this)) + : QObject(*new QWebEngineCookieStorePrivate, parent) { } diff --git a/src/core/api/qwebenginecookiestore.h b/src/core/api/qwebenginecookiestore.h index 6cbe399f2..b78f885ef 100644 --- a/src/core/api/qwebenginecookiestore.h +++ b/src/core/api/qwebenginecookiestore.h @@ -37,8 +37,8 @@ #ifndef QWEBENGINECOOKIESTORE_H #define QWEBENGINECOOKIESTORE_H -#include "qtwebenginecoreglobal.h" -#include "qwebenginecallback.h" +#include <QtWebEngineCore/qtwebenginecoreglobal.h> +#include <QtWebEngineCore/qwebenginecallback.h> #include <QtCore/qobject.h> #include <QtCore/qscopedpointer.h> @@ -94,7 +94,6 @@ private: friend class QtWebEngineCore::CookieMonsterDelegateQt; Q_DISABLE_COPY(QWebEngineCookieStore) Q_DECLARE_PRIVATE(QWebEngineCookieStore) - QScopedPointer<QWebEngineCookieStorePrivate> d_ptr; }; QT_END_NAMESPACE diff --git a/src/core/api/qwebenginecookiestore_p.h b/src/core/api/qwebenginecookiestore_p.h index d773c0d3e..348dcd69f 100644 --- a/src/core/api/qwebenginecookiestore_p.h +++ b/src/core/api/qwebenginecookiestore_p.h @@ -56,6 +56,7 @@ #include <QVector> #include <QNetworkCookie> #include <QUrl> +#include <QtCore/private/qobject_p.h> namespace QtWebEngineCore { class CookieMonsterDelegateQt; @@ -63,7 +64,9 @@ class CookieMonsterDelegateQt; QT_BEGIN_NAMESPACE -class QWEBENGINE_PRIVATE_EXPORT QWebEngineCookieStorePrivate { +class QWEBENGINE_PRIVATE_EXPORT QWebEngineCookieStorePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QWebEngineCookieStore) struct CookieData { quint64 callbackId; QNetworkCookie cookie; @@ -71,7 +74,6 @@ class QWEBENGINE_PRIVATE_EXPORT QWebEngineCookieStorePrivate { }; friend class QTypeInfo<CookieData>; public: - Q_DECLARE_PUBLIC(QWebEngineCookieStore) QtWebEngineCore::CallbackDirectory callbackDirectory; QWebEngineCallback<QWebEngineCookieStore::FilterRequest&> filterCallback; QVector<CookieData> m_pendingUserCookies; @@ -81,11 +83,11 @@ public: bool m_getAllCookiesPending; QtWebEngineCore::CookieMonsterDelegateQt *delegate; - QWebEngineCookieStore *q_ptr; - QWebEngineCookieStorePrivate(QWebEngineCookieStore *q); + QWebEngineCookieStorePrivate(); void processPendingUserCookies(); + void rejectPendingUserCookies(); void setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie, const QUrl &origin); void deleteCookie(const QNetworkCookie &cookie, const QUrl &url); void deleteSessionCookies(); diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp index 79801d190..db5627acb 100644 --- a/src/core/api/qwebengineurlrequestinfo.cpp +++ b/src/core/api/qwebengineurlrequestinfo.cpp @@ -236,6 +236,9 @@ QByteArray QWebEngineUrlRequestInfo::requestMethod() const return d->method; } +/*! + \internal +*/ bool QWebEngineUrlRequestInfo::changed() const { Q_D(const QWebEngineUrlRequestInfo); diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h index 008df7751..9a13b3faf 100644 --- a/src/core/api/qwebengineurlrequestinfo.h +++ b/src/core/api/qwebengineurlrequestinfo.h @@ -37,7 +37,7 @@ #ifndef QWEBENGINEURLREQUESTINFO_H #define QWEBENGINEURLREQUESTINFO_H -#include "qtwebenginecoreglobal.h" +#include <QtWebEngineCore/qtwebenginecoreglobal.h> #include <QtCore/qscopedpointer.h> #include <QtCore/qurl.h> diff --git a/src/core/api/qwebengineurlrequestinfo_p.h b/src/core/api/qwebengineurlrequestinfo_p.h index df5f18d6e..c78a93613 100644 --- a/src/core/api/qwebengineurlrequestinfo_p.h +++ b/src/core/api/qwebengineurlrequestinfo_p.h @@ -37,6 +37,17 @@ #ifndef QWEBENGINEURLREQUESTINFO_P_H #define QWEBENGINEURLREQUESTINFO_P_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "qtwebenginecoreglobal_p.h" #include "qwebengineurlrequestinfo.h" diff --git a/src/core/api/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h index 372ee9066..a3b7cf979 100644 --- a/src/core/api/qwebengineurlrequestinterceptor.h +++ b/src/core/api/qwebengineurlrequestinterceptor.h @@ -37,8 +37,8 @@ #ifndef QWEBENINGEURLREQUESTINTERCEPTOR_H #define QWEBENINGEURLREQUESTINTERCEPTOR_H -#include "qtwebenginecoreglobal.h" -#include "qwebengineurlrequestinfo.h" +#include <QtWebEngineCore/qtwebenginecoreglobal.h> +#include <QtWebEngineCore/qwebengineurlrequestinfo.h> #include <QtCore/qbytearray.h> #include <QtCore/qhash.h> diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h index fc9f4d911..922299fd9 100644 --- a/src/core/api/qwebengineurlrequestjob.h +++ b/src/core/api/qwebengineurlrequestjob.h @@ -37,7 +37,7 @@ #ifndef QWEBENGINEURLREQUESTJOB_H #define QWEBENGINEURLREQUESTJOB_H -#include "qtwebenginecoreglobal.h" +#include <QtWebEngineCore/qtwebenginecoreglobal.h> #include <QtCore/qbytearray.h> #include <QtCore/qobject.h> diff --git a/src/core/api/qwebengineurlschemehandler.h b/src/core/api/qwebengineurlschemehandler.h index fa24987c5..d9fc15250 100644 --- a/src/core/api/qwebengineurlschemehandler.h +++ b/src/core/api/qwebengineurlschemehandler.h @@ -37,7 +37,7 @@ #ifndef QWEBENGINEURLSCHEMEHANDLER_H #define QWEBENGINEURLSCHEMEHANDLER_H -#include "qtwebenginecoreglobal.h" +#include <QtWebEngineCore/qtwebenginecoreglobal.h> #include <QtCore/qobject.h> diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index 7d2d0478f..a8f704995 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -52,7 +52,6 @@ #include <QCoreApplication> #include <QDir> #include <QString> -#include <QStringBuilder> #include <QStandardPaths> #include <numeric> diff --git a/src/core/browser_context_adapter_client.h b/src/core/browser_context_adapter_client.h index d237b25a1..5c0674a0a 100644 --- a/src/core/browser_context_adapter_client.h +++ b/src/core/browser_context_adapter_client.h @@ -72,6 +72,7 @@ public: const int state; const qint64 totalBytes; const qint64 receivedBytes; + const QString mimeType; QString path; int savePageFormat; diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp index 28486cced..d21f963a9 100644 --- a/src/core/browser_context_qt.cpp +++ b/src/core/browser_context_qt.cpp @@ -147,9 +147,9 @@ content::PermissionManager *BrowserContextQt::GetPermissionManager() return permissionManager.get(); } -net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers) +net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) { - url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers); + url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers, request_interceptors.Pass()); return url_request_getter_.get(); } diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h index eccd684a3..9deb42b56 100644 --- a/src/core/browser_context_qt.h +++ b/src/core/browser_context_qt.h @@ -72,7 +72,7 @@ public: virtual storage::SpecialStoragePolicy *GetSpecialStoragePolicy() Q_DECL_OVERRIDE; virtual content::PushMessagingService* GetPushMessagingService() Q_DECL_OVERRIDE; virtual content::SSLHostStateDelegate* GetSSLHostStateDelegate() Q_DECL_OVERRIDE; - net::URLRequestContextGetter *CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers); + net::URLRequestContextGetter *CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors); virtual scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(const base::FilePath& partition_path) Q_DECL_OVERRIDE; virtual content::PermissionManager *GetPermissionManager() Q_DECL_OVERRIDE; diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index c51996c78..61e0f3399 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -383,7 +383,7 @@ content::AccessTokenStore *ContentBrowserClientQt::CreateAccessTokenStore() net::URLRequestContextGetter* ContentBrowserClientQt::CreateRequestContext(content::BrowserContext* browser_context, content::ProtocolHandlerMap* protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptors) { - return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers); + return static_cast<BrowserContextQt*>(browser_context)->CreateRequestContext(protocol_handlers, request_interceptors.Pass()); } content::QuotaPermissionContext *ContentBrowserClientQt::CreateQuotaPermissionContext() diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 59991d558..8d7ea397b 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -49,7 +49,6 @@ #include <QCoreApplication> #include <QFile> -#include <QStringBuilder> #if defined(ENABLE_PLUGINS) #include "content/public/common/pepper_plugin_info.h" @@ -105,20 +104,14 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, cons void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins) { QStringList pluginPaths; -#if defined(Q_OS_WIN) && defined(Q_PROCESSOR_X86_32) +#if defined(Q_OS_WIN) QString winDir = QDir::fromNativeSeparators(qgetenv("WINDIR")); if (winDir.isEmpty()) winDir = QString::fromLatin1("C:/Windows"); - - const QStringList pluginDirs = { winDir + "/SysWOW64/Macromed/Flash", - winDir + "/System32/Macromed/Flash" }; - const QStringList nameFilters("pepflashplayer*.dll"); - Q_FOREACH (const QString &dirPath, pluginDirs) { - QDir pluginDir(dirPath); - pluginDir.setFilter(QDir::Files); - Q_FOREACH (const QFileInfo &info, pluginDir.entryInfoList(nameFilters)) - pluginPaths << info.absoluteFilePath(); - } + QDir pluginDir(winDir + "/System32/Macromed/Flash"); + pluginDir.setFilter(QDir::Files); + Q_FOREACH (const QFileInfo &info, pluginDir.entryInfoList(QStringList("pepflashplayer*.dll"))) + pluginPaths << info.absoluteFilePath(); #endif #if defined(Q_OS_OSX) pluginPaths << "/Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin"; // Mac OS X @@ -132,7 +125,6 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins) if (!QFile(*it).exists()) continue; plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string())); - return; } } @@ -159,7 +151,6 @@ void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* p #endif #include <QCoreApplication> -#include <QStringBuilder> namespace QtWebEngineCore { diff --git a/src/core/cookie_monster_delegate_qt.cpp b/src/core/cookie_monster_delegate_qt.cpp index a81670a6c..3689d54d7 100644 --- a/src/core/cookie_monster_delegate_qt.cpp +++ b/src/core/cookie_monster_delegate_qt.cpp @@ -44,8 +44,6 @@ #include "api/qwebenginecookiestore_p.h" #include "type_conversion.h" -#include <QStringBuilder> - namespace QtWebEngineCore { static GURL sourceUrlForCookie(const QNetworkCookie &cookie) { @@ -139,10 +137,18 @@ void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId) void CookieMonsterDelegateQt::setCookieMonster(net::CookieMonster* monster) { + if (!monster && !m_cookieMonster) + return; + m_cookieMonster = monster; - if (m_client) + if (!m_client) + return; + + if (monster) m_client->d_func()->processPendingUserCookies(); + else + m_client->d_func()->rejectPendingUserCookies(); } void CookieMonsterDelegateQt::setClient(QWebEngineCookieStore *client) @@ -152,7 +158,7 @@ void CookieMonsterDelegateQt::setClient(QWebEngineCookieStore *client) if (!m_client) return; - m_client->d_ptr->delegate = this; + m_client->d_func()->delegate = this; if (hasCookieMonster()) m_client->d_func()->processPendingUserCookies(); @@ -163,14 +169,14 @@ bool CookieMonsterDelegateQt::canSetCookie(const QUrl &firstPartyUrl, const QByt if (!m_client) return true; - return m_client->d_ptr->canSetCookie(firstPartyUrl, cookieLine, url); + return m_client->d_func()->canSetCookie(firstPartyUrl, cookieLine, url); } void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) { if (!m_client) return; - m_client->d_ptr->onCookieChanged(toQt(cookie), removed); + m_client->d_func()->onCookieChanged(toQt(cookie), removed); } } diff --git a/src/core/core.pro b/src/core/core.pro index 7ddad4ed6..09eee496f 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -1,8 +1,13 @@ TEMPLATE = subdirs +# core_headers is a dummy module to syncqt the headers so we can +# use them by later targets +core_headers.file = core_headers.pro + # core_gyp_generator.pro is a dummy .pro file that is used by qmake # to generate our main .gyp file core_gyp_generator.file = core_gyp_generator.pro +core_gyp_generator.depends = core_headers # gyp_run.pro calls gyp through gyp_qtwebengine on the qmake step, and ninja on the make step. gyp_run.file = gyp_run.pro @@ -31,5 +36,6 @@ SUBDIRS += core_gyp_generator } SUBDIRS += gyp_run \ + core_headers \ core_api \ core_module diff --git a/src/core/core_common.pri b/src/core/core_common.pri index 1ea4e1862..9c29aea71 100644 --- a/src/core/core_common.pri +++ b/src/core/core_common.pri @@ -3,7 +3,7 @@ TARGET = QtWebEngineCore QT += qml quick webchannel -QT_PRIVATE += quick-private gui-private core-private +QT_PRIVATE += quick-private gui-private core-private webenginecoreheaders-private # Make QtCreator happy. CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir() diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro index f950c773b..7145d8e04 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_gyp_generator.pro @@ -11,6 +11,7 @@ include(core_common.pri) # Defining keywords such as 'signal' clashes with the chromium code base. DEFINES += QT_NO_KEYWORDS \ + QT_USE_QSTRINGBUILDER \ Q_FORWARD_DECLARE_OBJC_CLASS=QT_FORWARD_DECLARE_CLASS \ QTWEBENGINEPROCESS_NAME=\\\"$$QTWEBENGINEPROCESS_NAME\\\" \ QTWEBENGINECORE_VERSION_STR=\\\"$$MODULE_VERSION\\\" \ diff --git a/src/core/core_headers.pro b/src/core/core_headers.pro new file mode 100644 index 000000000..ebafe58ec --- /dev/null +++ b/src/core/core_headers.pro @@ -0,0 +1,5 @@ +TARGET = QtWebEngineCore +CONFIG += no_private_module header_module internal_module +MODULE = webenginecoreheaders + +load(qt_module) diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 68d46cd5a..b001fef06 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -70,14 +70,14 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat locales.CONFIG += no_check_exist locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales resources.CONFIG += no_check_exist - resources.path = $$[QT_INSTALL_DATA] + resources.path = $$[QT_INSTALL_DATA]/resources icu.CONFIG += no_check_exist - icu.path = $$[QT_INSTALL_DATA] + icu.path = $$[QT_INSTALL_DATA]/resources INSTALLS += icu locales resources } !contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) { - ICU_TARGET = $$shell_path($$[QT_INSTALL_DATA/get]/icudtl.dat) + ICU_TARGET = $$shell_path($$[QT_INSTALL_DATA/get]/resources/icudtl.dat) ICU_FILE = $$shell_path($$OUT_PWD/$$getConfigDir()/icudtl.dat) icu_rule.target = $$ICU_TARGET unix: icu_rule.commands = if [ -e $$ICU_FILE ] ; then $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET ; fi diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index b6de27ca8..454e1ff49 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -46,6 +46,7 @@ #include <QFile> #include <QFileInfo> #include <QMap> +#include <QMimeDatabase> #include <QStandardPaths> #include "browser_context_adapter.h" @@ -108,23 +109,28 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i return true; } - std::string suggestedFilename = item->GetSuggestedFilename(); + QString suggestedFilename = toQt(item->GetSuggestedFilename()); + QString mimeTypeString = toQt(item->GetMimeType()); - if (suggestedFilename.empty()) - suggestedFilename = net::HttpContentDisposition(item->GetContentDisposition(), std::string()).filename(); + if (suggestedFilename.isEmpty()) + suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), std::string()).filename()); - if (suggestedFilename.empty()) - suggestedFilename = item->GetTargetFilePath().AsUTF8Unsafe(); + if (suggestedFilename.isEmpty()) + suggestedFilename = toQt(item->GetTargetFilePath().AsUTF8Unsafe()); - if (suggestedFilename.empty()) - suggestedFilename = item->GetURL().ExtractFileName(); + if (suggestedFilename.isEmpty()) + suggestedFilename = toQt(item->GetURL().ExtractFileName()); - if (suggestedFilename.empty()) - suggestedFilename = "qwe_download"; + if (suggestedFilename.isEmpty()) { + suggestedFilename = QStringLiteral("qwe_download"); + QMimeType mimeType = QMimeDatabase().mimeTypeForName(mimeTypeString); + if (mimeType.isValid() && !mimeType.preferredSuffix().isEmpty()) + suggestedFilename += QStringLiteral(".") + mimeType.preferredSuffix(); + } QDir defaultDownloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); - QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(QString::fromStdString(suggestedFilename))); + QFileInfo suggestedFile(defaultDownloadDirectory.absoluteFilePath(suggestedFilename)); QString suggestedFilePath = suggestedFile.absoluteFilePath(); QString tmpFileBase = QString("%1%2%3").arg(suggestedFile.absolutePath()).arg(QDir::separator()).arg(suggestedFile.baseName()); @@ -145,6 +151,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i item->GetState(), item->GetTotalBytes(), item->GetReceivedBytes(), + mimeTypeString, suggestedFilePath, BrowserContextAdapterClient::UnknownSavePageFormat, false /* accepted */ @@ -214,6 +221,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content content::DownloadItem::IN_PROGRESS, 0, /* totalBytes */ 0, /* receivedBytes */ + QStringLiteral("application/x-mimearchive"), suggestedFilePath, BrowserContextAdapterClient::MimeHtmlSaveFormat, false /* accepted */ @@ -249,6 +257,7 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *downloa download->GetState(), download->GetTotalBytes(), download->GetReceivedBytes(), + toQt(download->GetMimeType()), QString(), BrowserContextAdapterClient::UnknownSavePageFormat, true /* accepted */ diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro index 79e1dca64..dea1a2225 100644 --- a/src/core/gyp_run.pro +++ b/src/core/gyp_run.pro @@ -28,6 +28,8 @@ force_debug_info { else: GYP_CONFIG += release_extra_cflags=-g } +!warnings_are_errors: GYP_CONFIG += disable_fatal_linker_warnings=1 + # Copy this logic from qt_module.prf so that ninja can run according # to the same rules as the final module linking in core_module.pro. !host_build:if(win32|mac):!macx-xcode { diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 5d4ac72cd..cade9aa8a 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -739,6 +739,10 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) Focus(); // Fall through. case QEvent::MouseButtonRelease: case QEvent::MouseMove: + // Skip second MouseMove event when a window is being adopted, so that Chromium + // can properly handle further move events. + if (m_adapterClient->isBeingAdopted()) + return false; handleMouseEvent(static_cast<QMouseEvent*>(event)); break; case QEvent::KeyPress: diff --git a/src/core/resources/resources.gyp b/src/core/resources/resources.gyp index 6c61f1daf..157b78780 100644 --- a/src/core/resources/resources.gyp +++ b/src/core/resources/resources.gyp @@ -78,15 +78,15 @@ ['qt_install_data != ""', { 'copies': [ { - 'destination': '<(qt_install_data)', + 'destination': '<(qt_install_data)/resources', 'files': [ '<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources.pak' ], }, { - 'destination': '<(qt_install_data)', + 'destination': '<(qt_install_data)/resources', 'files': [ '<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_100p.pak' ], }, { - 'destination': '<(qt_install_data)', + 'destination': '<(qt_install_data)/resources', 'files': [ '<(SHARED_INTERMEDIATE_DIR)/repack/qtwebengine_resources_200p.pak' ], }, ], diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 4a2a63348..ed3378b21 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -65,6 +65,7 @@ #include "net/url_request/data_protocol_handler.h" #include "net/url_request/file_protocol_handler.h" #include "net/url_request/ftp_protocol_handler.h" +#include "net/url_request/url_request_intercepting_job_factory.h" #include "net/ftp/ftp_network_layer.h" #include "api/qwebengineurlschemehandler.h" @@ -85,10 +86,11 @@ static const char kQrcSchemeQt[] = "qrc"; using content::BrowserThread; -URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers) +URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors) : m_ignoreCertificateErrors(false) , m_browserContext(browserContext) , m_cookieDelegate(new CookieMonsterDelegateQt()) + , m_requestInterceptors(request_interceptors.Pass()) { std::swap(m_protocolHandlers, *protocolHandlers); @@ -131,22 +133,29 @@ void URLRequestContextGetterQt::updateStorageSettings() } } -void URLRequestContextGetterQt::generateStorage() +void URLRequestContextGetterQt::cancelAllUrlRequests() { Q_ASSERT(m_urlRequestContext); - if (m_storage) { - // We must stop all requests before deleting their backends. - std::set<const net::URLRequest*>* url_requests = m_urlRequestContext->url_requests(); - std::set<const net::URLRequest*>::const_iterator it = url_requests->begin(); - std::set<const net::URLRequest*>::const_iterator end = url_requests->end(); - for ( ; it != end; ++it) { - net::URLRequest* request = const_cast<net::URLRequest*>(*it); - if (request) - request->Cancel(); - } + std::set<const net::URLRequest*>* url_requests = m_urlRequestContext->url_requests(); + std::set<const net::URLRequest*>::const_iterator it = url_requests->begin(); + std::set<const net::URLRequest*>::const_iterator end = url_requests->end(); + for ( ; it != end; ++it) { + net::URLRequest* request = const_cast<net::URLRequest*>(*it); + if (request) + request->Cancel(); } +} + +void URLRequestContextGetterQt::generateStorage() +{ + Q_ASSERT(m_urlRequestContext); + + // We must stop all requests before deleting their backends. + if (m_storage) + cancelAllUrlRequests(); + m_storage.reset(new net::URLRequestContextStorage(m_urlRequestContext.get())); net::ProxyConfigService *proxyConfigService = m_proxyConfigService.fetchAndStoreAcquire(0); @@ -202,7 +211,7 @@ void URLRequestContextGetterQt::generateCookieStore() Q_ASSERT(m_storage); m_updateCookieStore = 0; - // Unset it first to get a chance to destroy and flush the old cookie store before before opening a new on possibly the same file. + // 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); m_cookieDelegate->setClient(m_browserContext->cookieStore()); @@ -286,11 +295,56 @@ void URLRequestContextGetterQt::updateHttpCache() } } +static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, const net::HttpNetworkSession::Params &second) +{ + if (first.transport_security_state != second.transport_security_state) + return false; + if (first.cert_verifier != second.cert_verifier) + return false; + if (first.channel_id_service != second.channel_id_service) + return false; + if (first.proxy_service != second.proxy_service) + return false; + if (first.ssl_config_service != second.ssl_config_service) + return false; + if (first.http_auth_handler_factory != second.http_auth_handler_factory) + return false; + if (first.network_delegate != second.network_delegate) + return false; + if (first.http_server_properties.get() != second.http_server_properties.get()) + return false; + if (first.ignore_certificate_errors != second.ignore_certificate_errors) + return false; + if (first.host_resolver != second.host_resolver) + return false; + + return true; +} + +net::HttpNetworkSession::Params URLRequestContextGetterQt::generateNetworkSessionParams() +{ + Q_ASSERT(m_urlRequestContext); + + net::HttpNetworkSession::Params network_session_params; + + network_session_params.transport_security_state = m_urlRequestContext->transport_security_state(); + network_session_params.cert_verifier = m_urlRequestContext->cert_verifier(); + network_session_params.channel_id_service = m_urlRequestContext->channel_id_service(); + network_session_params.proxy_service = m_urlRequestContext->proxy_service(); + network_session_params.ssl_config_service = m_urlRequestContext->ssl_config_service(); + network_session_params.http_auth_handler_factory = m_urlRequestContext->http_auth_handler_factory(); + network_session_params.network_delegate = m_networkDelegate.get(); + network_session_params.http_server_properties = m_urlRequestContext->http_server_properties(); + network_session_params.ignore_certificate_errors = m_ignoreCertificateErrors; + network_session_params.host_resolver = m_urlRequestContext->host_resolver(); + + return network_session_params; +} + void URLRequestContextGetterQt::generateHttpCache() { Q_ASSERT(m_urlRequestContext); Q_ASSERT(m_storage); - m_updateHttpCache = 0; net::HttpCache::DefaultBackend* main_backend = 0; switch (m_browserContext->httpCacheType()) { @@ -316,19 +370,21 @@ void URLRequestContextGetterQt::generateHttpCache() break; } - net::HttpNetworkSession::Params network_session_params; - network_session_params.transport_security_state = m_urlRequestContext->transport_security_state(); - network_session_params.cert_verifier = m_urlRequestContext->cert_verifier(); - network_session_params.channel_id_service = m_urlRequestContext->channel_id_service(); - network_session_params.proxy_service = m_urlRequestContext->proxy_service(); - network_session_params.ssl_config_service = m_urlRequestContext->ssl_config_service(); - network_session_params.http_auth_handler_factory = m_urlRequestContext->http_auth_handler_factory(); - network_session_params.network_delegate = m_networkDelegate.get(); - network_session_params.http_server_properties = m_urlRequestContext->http_server_properties(); - network_session_params.ignore_certificate_errors = m_ignoreCertificateErrors; - network_session_params.host_resolver = m_urlRequestContext->host_resolver(); + net::HttpCache *cache = 0; + net::HttpNetworkSession *network_session = 0; + net::HttpNetworkSession::Params network_session_params = generateNetworkSessionParams(); + + if (m_urlRequestContext->http_transaction_factory()) + network_session = m_urlRequestContext->http_transaction_factory()->GetSession(); + + if (!network_session || !doNetworkSessionParamsMatch(network_session_params, network_session->params())) { + cancelAllUrlRequests(); + cache = new net::HttpCache(network_session_params, main_backend); + } else + cache = new net::HttpCache(network_session, main_backend); - m_storage->set_http_transaction_factory(scoped_ptr<net::HttpCache>(new net::HttpCache(network_session_params, main_backend))); + m_storage->set_http_transaction_factory(scoped_ptr<net::HttpCache>(cache)); + m_updateHttpCache = 0; } void URLRequestContextGetterQt::clearHttpCache() @@ -352,28 +408,39 @@ void URLRequestContextGetterQt::generateJobFactory() { Q_ASSERT(m_urlRequestContext); Q_ASSERT(!m_jobFactory); - m_jobFactory.reset(new net::URLRequestJobFactoryImpl()); + + scoped_ptr<net::URLRequestJobFactoryImpl> jobFactory(new net::URLRequestJobFactoryImpl()); { // Chromium has a few protocol handlers ready for us, only pick blob: and throw away the rest. content::ProtocolHandlerMap::iterator it = m_protocolHandlers.find(url::kBlobScheme); Q_ASSERT(it != m_protocolHandlers.end()); - m_jobFactory->SetProtocolHandler(it->first, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(it->second.release())); + jobFactory->SetProtocolHandler(it->first, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(it->second.release())); m_protocolHandlers.clear(); } - m_jobFactory->SetProtocolHandler(url::kDataScheme, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::DataProtocolHandler())); - m_jobFactory->SetProtocolHandler(url::kFileScheme, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::FileProtocolHandler( + jobFactory->SetProtocolHandler(url::kDataScheme, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::DataProtocolHandler())); + jobFactory->SetProtocolHandler(url::kFileScheme, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::FileProtocolHandler( content::BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior( base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)))); - m_jobFactory->SetProtocolHandler(kQrcSchemeQt, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new QrcProtocolHandlerQt())); - m_jobFactory->SetProtocolHandler(url::kFtpScheme, + jobFactory->SetProtocolHandler(kQrcSchemeQt, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new QrcProtocolHandlerQt())); + jobFactory->SetProtocolHandler(url::kFtpScheme, scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new net::FtpProtocolHandler(new net::FtpNetworkLayer(m_urlRequestContext->host_resolver())))); QHash<QByteArray, QWebEngineUrlSchemeHandler*>::const_iterator it = m_browserContext->customUrlSchemeHandlers().constBegin(); const QHash<QByteArray, QWebEngineUrlSchemeHandler*>::const_iterator end = m_browserContext->customUrlSchemeHandlers().constEnd(); for (; it != end; ++it) - m_jobFactory->SetProtocolHandler(it.key().toStdString(), scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new CustomProtocolHandler(it.value()))); + jobFactory->SetProtocolHandler(it.key().toStdString(), scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(new CustomProtocolHandler(it.value()))); + + // Set up interceptors in the reverse order. + scoped_ptr<net::URLRequestJobFactory> topJobFactory = jobFactory.Pass(); + + for (content::URLRequestInterceptorScopedVector::reverse_iterator i = m_requestInterceptors.rbegin(); i != m_requestInterceptors.rend(); ++i) + topJobFactory.reset(new net::URLRequestInterceptingJobFactory(topJobFactory.Pass(), make_scoped_ptr(*i))); + + m_requestInterceptors.weak_clear(); + + m_jobFactory = topJobFactory.Pass(); m_urlRequestContext->set_job_factory(m_jobFactory.get()); } diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h index 9c355082d..3c0a2ee19 100644 --- a/src/core/url_request_context_getter_qt.h +++ b/src/core/url_request_context_getter_qt.h @@ -45,6 +45,7 @@ #include "base/single_thread_task_runner.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/url_constants.h" +#include "net/http/http_network_session.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_job_factory_impl.h" #include "net/proxy/dhcp_proxy_script_fetcher_factory.h" @@ -66,7 +67,7 @@ class BrowserContextAdapter; class URLRequestContextGetterQt : public net::URLRequestContextGetter { public: - explicit URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers); + explicit URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers, content::URLRequestInterceptorScopedVector request_interceptors); virtual net::URLRequestContext *GetURLRequestContext() Q_DECL_OVERRIDE; virtual scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner() const Q_DECL_OVERRIDE; @@ -88,6 +89,8 @@ private: void generateUserAgent(); void generateJobFactory(); void clearCurrentCacheBackend(); + void cancelAllUrlRequests(); + net::HttpNetworkSession::Params generateNetworkSessionParams(); bool m_ignoreCertificateErrors; QAtomicInt m_updateCookieStore; @@ -99,9 +102,11 @@ private: scoped_ptr<net::URLRequestContext> m_urlRequestContext; scoped_ptr<NetworkDelegateQt> m_networkDelegate; scoped_ptr<net::URLRequestContextStorage> m_storage; - scoped_ptr<net::URLRequestJobFactoryImpl> m_jobFactory; + scoped_ptr<net::URLRequestJobFactory> m_jobFactory; scoped_ptr<net::DhcpProxyScriptFetcherFactory> m_dhcpProxyScriptFetcherFactory; scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate; + content::URLRequestInterceptorScopedVector m_requestInterceptors; + friend class NetworkDelegateQt; }; diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index b19cc5241..d3eae2b00 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -213,6 +213,7 @@ public: virtual void focusContainer() = 0; virtual void unhandledKeyEvent(QKeyEvent *event) = 0; virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition, bool userGesture, const QRect & initialGeometry) = 0; + virtual bool isBeingAdopted() = 0; virtual void close() = 0; virtual void windowCloseRejected() = 0; virtual bool contextMenuRequested(const WebEngineContextMenuData&) = 0; diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 4d1cbf3d4..dabee9179 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -84,6 +84,12 @@ #include <QVector> #include <qpa/qplatformnativeinterface.h> +using namespace QtWebEngineCore; + +QT_BEGIN_NAMESPACE +Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); +QT_END_NAMESPACE + namespace { scoped_refptr<QtWebEngineCore::WebEngineContext> sContext; @@ -100,7 +106,7 @@ void destroyContext() bool usingANGLE() { #if defined(Q_OS_WIN) - return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES; + return qt_gl_global_share_context()->isOpenGLES(); #else return false; #endif @@ -246,14 +252,12 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kDisableGpu); } else { const char *glType = 0; - switch (QOpenGLContext::openGLModuleType()) { - case QOpenGLContext::LibGL: - glType = gfx::kGLImplementationDesktopName; - break; - case QOpenGLContext::LibGLES: + if (qt_gl_global_share_context()->isOpenGLES()) { glType = gfx::kGLImplementationEGLName; - break; + } else { + glType = gfx::kGLImplementationDesktopName; } + parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType); } diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index bc030d8f7..8ec18c87d 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -52,7 +52,6 @@ #include <QLibraryInfo> #include <QStandardPaths> #include <QString> -#include <QStringBuilder> #ifndef QTWEBENGINEPROCESS_NAME #error "No name defined for QtWebEngine's process" @@ -203,26 +202,57 @@ QString localesPath() #endif } -QString libraryDataPath() +QString icuDataPath() { #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) return getResourcesPath(frameworkBundle()); #else static bool initialized = false; - static QString potentialDataPath = QLibraryInfo::location(QLibraryInfo::DataPath); + static QString potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/resources"); if (!initialized) { initialized = true; - if (!QFileInfo::exists(potentialDataPath)) { - qWarning("Qt WebEngine data directory not found at location %s. Trying application directory...", qPrintable(potentialDataPath)); - potentialDataPath = QCoreApplication::applicationDirPath(); + if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) { + qWarning("Qt WebEngine ICU data not found at %s. Trying parent directory...", qPrintable(potentialResourcesPath)); + potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath); } - if (!QFileInfo::exists(potentialDataPath)) { - qWarning("Qt WebEngine data directory not found at location %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialDataPath)); - potentialDataPath = fallbackDir(); + if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) { + qWarning("Qt WebEngine ICU data not found at %s. Trying application directory...", qPrintable(potentialResourcesPath)); + potentialResourcesPath = QCoreApplication::applicationDirPath(); + } + if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/icudtl.dat"))) { + qWarning("Qt WebEngine ICU data not found at %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialResourcesPath)); + potentialResourcesPath = fallbackDir(); + } + } + + return potentialResourcesPath; +#endif +} + +QString resourcesDataPath() +{ +#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) + return getResourcesPath(frameworkBundle()); +#else + static bool initialized = false; + static QString potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/resources"); + if (!initialized) { + initialized = true; + if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) { + qWarning("Qt WebEngine resources not found at %s. Trying parent directory...", qPrintable(potentialResourcesPath)); + potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath); + } + if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) { + qWarning("Qt WebEngine resources not found at %s. Trying application directory...", qPrintable(potentialResourcesPath)); + potentialResourcesPath = QCoreApplication::applicationDirPath(); + } + if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) { + qWarning("Qt WebEngine resources not found at %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialResourcesPath)); + potentialResourcesPath = fallbackDir(); } } - return potentialDataPath; + return potentialResourcesPath; #endif } } // namespace @@ -232,11 +262,11 @@ base::FilePath WebEngineLibraryInfo::getPath(int key) QString directory; switch (key) { case QT_RESOURCES_PAK: - return toFilePath(libraryDataPath() % QLatin1String("/qtwebengine_resources.pak")); + return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources.pak")); case QT_RESOURCES_100P_PAK: - return toFilePath(libraryDataPath() % QLatin1String("/qtwebengine_resources_100p.pak")); + return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_100p.pak")); case QT_RESOURCES_200P_PAK: - return toFilePath(libraryDataPath() % QLatin1String("/qtwebengine_resources_200p.pak")); + return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_200p.pak")); case base::FILE_EXE: case content::CHILD_PROCESS_EXE: return toFilePath(subProcessPath()); @@ -252,7 +282,7 @@ base::FilePath WebEngineLibraryInfo::getPath(int key) directory = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); break; case base::DIR_QT_LIBRARY_DATA: - return toFilePath(libraryDataPath()); + return toFilePath(icuDataPath()); case content::DIR_MEDIA_LIBS: return toFilePath(pluginsPath()); case ui::DIR_LOCALES: |