From 33a2c9aed3ee621c91853570087b500c830792e0 Mon Sep 17 00:00:00 2001 From: Tamas Zakor Date: Fri, 26 Jul 2019 12:24:08 +0200 Subject: Fix quick download directory auto test on Windows Change-Id: Ib4668e5a21d9062ea3b1b760aec319aa9c7fdbd8 Reviewed-by: Allan Sandfeld Jensen --- tests/auto/quick/qmltests/data/tst_download.qml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml index ff57c76c7..c38018ffd 100644 --- a/tests/auto/quick/qmltests/data/tst_download.qml +++ b/tests/auto/quick/qmltests/data/tst_download.qml @@ -53,7 +53,10 @@ TestWebEngineView { function urlToPath(url) { var path = url.toString() - path = path.replace(/^(file:\/{2})/,"") + if (Qt.platform.os !== "windows") + path = path.replace(/^(file:\/{2})/, "") + else + path = path.replace(/^(file:\/{3})/, "") return path } @@ -90,14 +93,9 @@ TestWebEngineView { download.cancel() } else { totalBytes = download.totalBytes - download.downloadDirectory = testDownloadProfile.downloadPath - download.downloadFileName = "testfile.zip" - if (downloadDirectory.length != 0) - download.downloadDirectory = testDownloadProfile.downloadPath + downloadDirectory - - if (downloadFileName.length != 0) - download.downloadFileName = downloadFileName + download.downloadDirectory = downloadDirectory.length != 0 ? testDownloadProfile.downloadPath + downloadDirectory : testDownloadProfile.downloadPath + download.downloadFileName = downloadFileName.length != 0 ? downloadFileName : "testfile.zip" download.accept() } @@ -125,6 +123,9 @@ TestWebEngineView { downloadDirectoryChanged = 0 downloadFileNameChanged = 0 downloadPathChanged = 0 + downloadDirectory = "" + downloadFileName = "" + downloadedPath = "" } function test_downloadRequest() { @@ -203,8 +204,8 @@ TestWebEngineView { tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress); compare(downloadedPath, testDownloadProfile.downloadPath + downloadDirectory + downloadFileName); compare(downloadDirectoryChanged, 1); - compare(downloadFileNameChanged, 3); - compare(downloadPathChanged, 4); + compare(downloadFileNameChanged, 1); + compare(downloadPathChanged, 2); downloadFinishedSpy.wait(); compare(totalBytes, receivedBytes); tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted); -- cgit v1.2.1 From f383f899cba71c02f2fcacd7f54b17a50f8e33d0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 28 Jun 2019 16:43:43 +0200 Subject: Port from QMutex::Recursive to QRecursiveMutex Also port from QMutexLocker to std::lock_guard, as the former will not support QRecursiveMutex going forward. Add a guard for Qt < 5.14 to fall back to the old implementation, as this module has to compile against the latest LTS, too. Change-Id: Ib247135326ed199fd5fc783e906e7e3018687570 Reviewed-by: Allan Sandfeld Jensen --- src/core/profile_io_data_qt.cpp | 37 +++++++++++----------- src/core/profile_io_data_qt.h | 7 +++- .../qwebengineprofile/tst_qwebengineprofile.cpp | 17 +++++++--- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp index 9a5058a5a..38fe56f7d 100644 --- a/src/core/profile_io_data_qt.cpp +++ b/src/core/profile_io_data_qt.cpp @@ -100,6 +100,8 @@ #include "net/cert_net/cert_net_fetcher_impl.h" #endif +#include + namespace QtWebEngineCore { static bool doNetworkSessionParamsMatch(const net::HttpNetworkSession::Params &first, @@ -164,7 +166,6 @@ ProfileIODataQt::ProfileIODataQt(ProfileQt *profile) #if QT_CONFIG(ssl) m_clientCertificateStoreData(new ClientCertificateStoreData), #endif - m_mutex(QMutex::Recursive), m_removerObserver(this), m_weakPtrFactory(this) { @@ -243,7 +244,7 @@ void ProfileIODataQt::initializeOnIOThread() m_urlRequestContext->set_enable_brotli(base::FeatureList::IsEnabled(features::kBrotliEncoding)); // this binds factory to io thread m_weakPtr = m_weakPtrFactory.GetWeakPtr(); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); generateAllStorage(); generateJobFactory(); setGlobalCertificateVerification(); @@ -283,7 +284,7 @@ void ProfileIODataQt::cancelAllUrlRequests() void ProfileIODataQt::generateAllStorage() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); generateStorage(); generateCookieStore(); generateUserAgent(); @@ -390,7 +391,7 @@ void ProfileIODataQt::generateCookieStore() Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); Q_ASSERT(m_urlRequestContext); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); // FIXME: Add code to remove the old database. m_storage->set_channel_id_service( @@ -443,7 +444,7 @@ void ProfileIODataQt::generateUserAgent() Q_ASSERT(m_urlRequestContext); Q_ASSERT(m_storage); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_storage->set_http_user_agent_settings(std::unique_ptr( new net::StaticHttpUserAgentSettings(m_httpAcceptLanguage.toStdString(), m_httpUserAgent.toStdString()))); @@ -455,7 +456,7 @@ void ProfileIODataQt::generateHttpCache() Q_ASSERT(m_urlRequestContext); Q_ASSERT(m_storage); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); net::HttpCache::DefaultBackend* main_backend = 0; switch (m_httpCacheType) { @@ -508,7 +509,7 @@ void ProfileIODataQt::generateJobFactory() Q_ASSERT(m_urlRequestContext); Q_ASSERT(!m_jobFactory); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_updateJobFactory = false; std::unique_ptr jobFactory(new net::URLRequestJobFactoryImpl()); @@ -563,7 +564,7 @@ void ProfileIODataQt::regenerateJobFactory() Q_ASSERT(m_jobFactory); Q_ASSERT(m_baseJobFactory); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_updateJobFactory = false; if (m_customUrlSchemes == m_installedCustomSchemes) @@ -584,7 +585,7 @@ void ProfileIODataQt::regenerateJobFactory() void ProfileIODataQt::setGlobalCertificateVerification() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); if (m_useForGlobalCertificateVerification) { #if defined(USE_NSS_CERTS) // Set request context used by NSS for OCSP requests. @@ -623,7 +624,7 @@ void ProfileIODataQt::setFullConfiguration() void ProfileIODataQt::requestStorageGeneration() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); if (m_initialized && !m_updateAllStorage) { m_updateAllStorage = true; createProxyConfig(); @@ -636,7 +637,7 @@ void ProfileIODataQt::requestStorageGeneration() { void ProfileIODataQt::createProxyConfig() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); // 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(). @@ -657,7 +658,7 @@ void ProfileIODataQt::updateStorageSettings() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); setFullConfiguration(); base::Token groupId = content::BrowserContext::GetServiceInstanceGroupFor(m_profile); @@ -672,7 +673,7 @@ void ProfileIODataQt::updateStorageSettings() void ProfileIODataQt::updateCookieStore() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_persistentCookiesPolicy = m_profileAdapter->persistentCookiesPolicy(); m_cookiesPath = m_profileAdapter->cookiesPath(); if (!m_pendingStorageRequestGeneration) @@ -682,7 +683,7 @@ void ProfileIODataQt::updateCookieStore() void ProfileIODataQt::updateUserAgent() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_httpAcceptLanguage = m_profileAdapter->httpAcceptLanguage(); m_httpUserAgent = m_profileAdapter->httpUserAgent(); if (!m_pendingStorageRequestGeneration) @@ -692,7 +693,7 @@ void ProfileIODataQt::updateUserAgent() void ProfileIODataQt::updateHttpCache() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_httpCacheType = m_profileAdapter->httpCacheType(); m_httpCachePath = m_profileAdapter->httpCachePath(); m_httpCacheMaxSize = m_profileAdapter->httpCacheMaxSize(); @@ -716,7 +717,7 @@ void ProfileIODataQt::updateHttpCache() void ProfileIODataQt::updateJobFactory() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_customUrlSchemes = m_profileAdapter->customUrlSchemes(); @@ -730,7 +731,7 @@ void ProfileIODataQt::updateJobFactory() void ProfileIODataQt::updateRequestInterceptor() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_requestInterceptor = m_profileAdapter->requestInterceptor(); m_hasPageInterceptors = m_profileAdapter->hasPageRequestInterceptor(); // We in this case do not need to regenerate any Chromium classes. @@ -772,7 +773,7 @@ bool ProfileIODataQt::canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) void ProfileIODataQt::updateUsedForGlobalCertificateVerification() { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_useForGlobalCertificateVerification = m_profileAdapter->isUsedForGlobalCertificateVerification(); if (m_useForGlobalCertificateVerification) diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h index f2dc67f44..4a5b9f77d 100644 --- a/src/core/profile_io_data_qt.h +++ b/src/core/profile_io_data_qt.h @@ -177,7 +177,12 @@ private: QList m_customUrlSchemes; QList m_installedCustomSchemes; QWebEngineUrlRequestInterceptor* m_requestInterceptor = nullptr; - QMutex m_mutex; +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + QMutex m_mutex{QMutex::Recursive}; + using QRecursiveMutex = QMutex; +#else + QRecursiveMutex m_mutex; +#endif int m_httpCacheMaxSize = 0; bool m_initialized = false; bool m_updateAllStorage = false; diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 8b75067ee..dd059791d 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -40,6 +40,8 @@ #include #include +#include + class tst_QWebEngineProfile : public QObject { Q_OBJECT @@ -255,18 +257,18 @@ public: bool isSequential() const override { return true; } qint64 bytesAvailable() const override { - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); return m_bytesAvailable; } bool atEnd() const override { - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); return (m_data.size() >= 1000 && m_bytesRead >= 1000); } protected: void timerEvent(QTimerEvent *) override { - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); m_bytesAvailable += 200; m_data.append(200, 'c'); emit readyRead(); @@ -278,7 +280,7 @@ protected: qint64 readData(char *data, qint64 maxlen) override { - QMutexLocker lock(&m_mutex); + const std::lock_guard lock(m_mutex); qint64 len = qMin(qint64(m_bytesAvailable), maxlen); if (len) { memcpy(data, m_data.constData() + m_bytesRead, len); @@ -295,7 +297,12 @@ protected: } private: - mutable QMutex m_mutex{QMutex::Recursive}; +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) + mutable QMutex m_mutex{QMutex::Recursive} + using QRecursiveMutex = QMutex; +#else + mutable QRecursiveMutex m_mutex; +#endif QByteArray m_data; QBasicTimer m_timer; int m_bytesRead; -- cgit v1.2.1 From 23b24fb49a9115151ea086afd271fdf9bb36fda0 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 6 Aug 2019 18:24:45 +0200 Subject: Add webenginewidgets to configure system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make webeninge-qml webengine-widgets features indpendent of webenginecore. Change-Id: I11c1bfaf4a15e4cb3acf2751b367f2c92a7ac833 Reviewed-by: Michael Brüning --- configure.json | 3 ++- src/core/configure.json | 17 ----------------- src/src.pro | 4 +++- src/webengine/configure.json | 13 ++++++++++++- src/webenginewidgets/configure.json | 28 ++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 src/webenginewidgets/configure.json diff --git a/configure.json b/configure.json index 60b7342f7..9c49729be 100644 --- a/configure.json +++ b/configure.json @@ -1,6 +1,7 @@ { "subconfigs": [ "src/core", - "src/webengine" + "src/webengine", + "src/webenginewidgets" ] } diff --git a/src/core/configure.json b/src/core/configure.json index 66e39ddc2..d3e0f87e0 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -28,8 +28,6 @@ "webengine-v8-snapshot": "boolean", "webengine-webchannel": "boolean", "webengine-kerberos": "boolean", - "webengine-widgets": "boolean", - "webengine-qml": "boolean", "alsa": { "type": "boolean", "name": "webengine-alsa" }, "pulseaudio": { "type": "boolean", "name": "webengine-pulseaudio" }, "ffmpeg": { "type": "enum", "name": "webengine-system-ffmpeg", "values": { "system": "yes", "qt": "no" } }, @@ -684,19 +682,6 @@ "condition": "config.linux && features.webengine-embedded-build && arch.arm && tests.webengine-arm-thumb", "output": [ "privateFeature" ] }, - "webengine-widgets": { - "label": "Qt WebEngine Widgets", - "purpose": "Provides WebEngine Widgets support.", - "section": "WebEngine", - "condition": "module.widgets", - "output": [ "privateFeature" ] - }, - "webengine-qml": { - "label": "Qt WebEngine Qml", - "purpose": "Provides WebEngine Qml support.", - "section": "WebEngine", - "output": [ "privateFeature" ] - }, "webengine-full-debug-info": { "label": "Full debug information", "purpose": "Enables debug information for Blink and V8.", @@ -761,8 +746,6 @@ { "section": "Qt WebEngineCore", "entries": [ - "webengine-widgets", - "webengine-qml", "webengine-embedded-build", "webengine-full-debug-info", "webengine-pepper-plugins", diff --git a/src/src.pro b/src/src.pro index 30562686a..8bf014dea 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,5 +1,7 @@ include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -QT_FOR_CONFIG += webenginecore webenginecore-private +include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) +include($$QTWEBENGINE_OUT_ROOT/src/webenginewidgets/qtwebenginewidgets-config.pri) +QT_FOR_CONFIG += webenginecore webenginecore-private webengine-private webenginewidgets-private TEMPLATE = subdirs diff --git a/src/webengine/configure.json b/src/webengine/configure.json index ec5ad34d9..ebe1ddb2b 100644 --- a/src/webengine/configure.json +++ b/src/webengine/configure.json @@ -1,9 +1,20 @@ { "module": "webengine", + "condition": "module.webenginecore && features.webengine-qml", "depends": [ "webenginecore-private" ], + "commandline": { + "options": { + "webengine-qml": "boolean" + } + }, "features": { + "webengine-qml": { + "label": "Support Qt WebEngine Qml", + "purpose": "Provides WebEngine Qml support.", + "output": [ "privateFeature" ] + }, "webengine-ui-delegates": { "label": "UI Delegates", "section": "WebEngine", @@ -18,8 +29,8 @@ "summary": [ { "section": "Qt WebEngineQml", - "condition": "features.webengine-qml", "entries": [ + "webengine-qml", "webengine-ui-delegates", "webengine-testsupport" ] diff --git a/src/webenginewidgets/configure.json b/src/webenginewidgets/configure.json new file mode 100644 index 000000000..a27faf78d --- /dev/null +++ b/src/webenginewidgets/configure.json @@ -0,0 +1,28 @@ +{ + "module": "webenginewidgets", + "condition": "module.webenginecore && features.webengine-widgets", + "depends": [ + "webenginecore-private" + ], + "commandline": { + "options": { + "webengine-widgets": "boolean" + } + }, + "features": { + "webengine-widgets": { + "label": "Support Qt WebEngine Widgets", + "purpose": "Provides WebEngine Widgets support.", + "condition": "module.widgets", + "output": [ "privateFeature" ] + } + }, + "summary": [ + { + "section": "Qt WebEngineWidgets", + "entries": [ + "webengine-widgets" + ] + } + ] +} -- cgit v1.2.1 From 414a61978932a6525bb15c2d6c06bd5e3be6608a Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 6 Aug 2019 18:45:24 +0200 Subject: Move alsa test to configure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ifdd476c0b58763be009d208a5f9d4c23305b6baa Reviewed-by: Jörg Bornemann --- config.tests/alsa/alsa.pro | 2 -- config.tests/alsa/alsatest.cpp | 37 ------------------------------------- src/core/configure.json | 20 ++++++++++++++------ 3 files changed, 14 insertions(+), 45 deletions(-) delete mode 100644 config.tests/alsa/alsa.pro delete mode 100644 config.tests/alsa/alsatest.cpp diff --git a/config.tests/alsa/alsa.pro b/config.tests/alsa/alsa.pro deleted file mode 100644 index 7322b6fb8..000000000 --- a/config.tests/alsa/alsa.pro +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES = alsatest.cpp - diff --git a/config.tests/alsa/alsatest.cpp b/config.tests/alsa/alsatest.cpp deleted file mode 100644 index 0b0ca71ec..000000000 --- a/config.tests/alsa/alsatest.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#if SND_LIB_VERSION < 0x1000a // 1.0.10 -#error "Alsa version found too old, require >= 1.0.10" -#endif - -int main(int argc, char **argv) -{ -} - diff --git a/src/core/configure.json b/src/core/configure.json index d3e0f87e0..345434090 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -43,6 +43,19 @@ }, "libraries": { + "webengine-alsa": { + "label": "alsa", + "test": { + "tail": [ + "#if SND_LIB_VERSION < 0x1000a // 1.0.10", + "#error Alsa version found too old, require >= 1.0.10", + "#endif" + ] + }, + "headers" : ["alsa/asoundlib.h"], + "sources" : [{ "type": "pkgConfig", "args": "alsa" } + ] + }, "webengine-dbus": { "label": "d-bus", "sources": [ @@ -236,11 +249,6 @@ } }, "tests" : { - "webengine-alsa": { - "label": "alsa", - "test": "alsa", - "type": "compile" - }, "webengine-host-compiler": { "label": "host compiler", "test": "hostcompiler", @@ -465,7 +473,7 @@ }, "webengine-alsa": { "label": "Use ALSA", - "condition": "config.unix && tests.webengine-alsa", + "condition": "config.unix && libs.webengine-alsa", "output": [ "privateFeature" ] }, "webengine-v8-snapshot": { -- cgit v1.2.1 From 5a515d40dc05e24db448da93e4149baffcd25d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Tue, 13 Aug 2019 13:45:51 +0200 Subject: Fix missing semicolon in tst_qwebengineprofile.cpp Change-Id: Iaf4e0acf2097308fe988350a10441c7313cb2bb3 Reviewed-by: Allan Sandfeld Jensen --- tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index dd059791d..0fc494a36 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -298,7 +298,7 @@ protected: private: #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) - mutable QMutex m_mutex{QMutex::Recursive} + mutable QMutex m_mutex{QMutex::Recursive}; using QRecursiveMutex = QMutex; #else mutable QRecursiveMutex m_mutex; -- cgit v1.2.1 From 7cf74af07eb7b44052357cf733d6f03f0112dc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Tue, 13 Aug 2019 15:18:17 +0200 Subject: Fix typos in header guards Those must have slipped through review and CI, but the compiler warned about them. Change-Id: I5f3e7d36ccc66c14b8be20f2499df9aa7a6813e1 Reviewed-by: Leander Beernaert Reviewed-by: Allan Sandfeld Jensen --- src/core/pref_service_adapter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/pref_service_adapter.h b/src/core/pref_service_adapter.h index 83f6a322e..1c7c44a96 100644 --- a/src/core/pref_service_adapter.h +++ b/src/core/pref_service_adapter.h @@ -38,8 +38,8 @@ ** ****************************************************************************/ -#ifndef PREF_SRVICE_ADAPTER_H -#define PREF_SERIVE_ADAPTER_H +#ifndef PREF_SERVICE_ADAPTER_H +#define PREF_SERVICE_ADAPTER_H #include "components/prefs/pref_service.h" #include "qtwebenginecoreglobal_p.h" @@ -82,4 +82,4 @@ private: } -#endif // PREF_SERIVE_ADAPTER_H +#endif // PREF_SERVICE_ADAPTER_H -- cgit v1.2.1 From 7cade5688f6a0bde067dc496cedcb8de14662116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Tue, 13 Aug 2019 17:30:20 +0200 Subject: Use QWeakPointer::toStrongRef().data() to get the raw pointer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a deprecation warning because QWeakPointer::data is deprecated from 5.14 onwards. Change-Id: I09b356b172cb9ffef880d6b97b4c6a9646203942 Reviewed-by: Jüri Valdmann --- src/core/web_contents_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index ee0b8cc39..052a71905 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -694,7 +694,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) } auto navigate = [](QWeakPointer weakAdapter, const content::NavigationController::LoadURLParams ¶ms) { - WebContentsAdapter *adapter = weakAdapter.data(); + WebContentsAdapter *adapter = weakAdapter.toStrongRef().data(); if (!adapter) return; adapter->webContents()->GetController().LoadURLWithParams(params); -- cgit v1.2.1 From 8b45a0998c6f4cf28ebb51e816018a2a7416bdfd Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 7 Aug 2019 10:39:58 +0200 Subject: Move xml2,glibc test to configure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I047f04a48d489730922093a9929e3609524dd06f Reviewed-by: Jörg Bornemann --- config.tests/glibc/glibc.cpp | 38 -------------------------------------- config.tests/glibc/glibc.pro | 5 ----- config.tests/xml2/xml2.cpp | 37 ------------------------------------- config.tests/xml2/xml2.pro | 3 --- src/core/configure.json | 39 ++++++++++++++++++++++++--------------- 5 files changed, 24 insertions(+), 98 deletions(-) delete mode 100644 config.tests/glibc/glibc.cpp delete mode 100644 config.tests/glibc/glibc.pro delete mode 100644 config.tests/xml2/xml2.cpp delete mode 100644 config.tests/xml2/xml2.pro diff --git a/config.tests/glibc/glibc.cpp b/config.tests/glibc/glibc.cpp deleted file mode 100644 index e78994b64..000000000 --- a/config.tests/glibc/glibc.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 27 -#error glibc versions below 2.27 are not supported -#endif - -int main(int , char **) { - return 0; -} - diff --git a/config.tests/glibc/glibc.pro b/config.tests/glibc/glibc.pro deleted file mode 100644 index f72bfb804..000000000 --- a/config.tests/glibc/glibc.pro +++ /dev/null @@ -1,5 +0,0 @@ -TARGET = glibc -SOURCES = glibc.cpp -CONFIG -= qt -CONFIG += console - diff --git a/config.tests/xml2/xml2.cpp b/config.tests/xml2/xml2.cpp deleted file mode 100644 index 497653d9c..000000000 --- a/config.tests/xml2/xml2.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#if !defined(LIBXML_ICU_ENABLED) -#error "libxml icu not enabled" -#endif - -int main(int argc, char **argv) -{ -} - diff --git a/config.tests/xml2/xml2.pro b/config.tests/xml2/xml2.pro deleted file mode 100644 index 6fad45f2f..000000000 --- a/config.tests/xml2/xml2.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES = xml2.cpp -CONFIG += link_pkgconfig -PKGCONFIG += libxml-2.0 diff --git a/src/core/configure.json b/src/core/configure.json index 345434090..b4d39696f 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -128,12 +128,6 @@ { "type": "pkgConfig", "args": "libevent" } ] }, - "webengine-libxml2": { - "label": "libxml2 and libxslt", - "sources": [ - { "type": "pkgConfig", "args": "libxml-2.0 libxslt" } - ] - }, "webengine-jsoncpp": { "label": "jsoncpp", "sources": [ @@ -216,6 +210,21 @@ "-ljpeg" ] }, + "webengine-libxml2": { + "label": "compatible libxml2 and libxslt", + "type": "compile", + "test": { + "tail": [ + "#if !defined(LIBXML_ICU_ENABLED)", + "#error libxml icu not enabled", + "#endif" + ] + }, + "headers": "libxml/xmlversion.h", + "sources": [ + { "type": "pkgConfig", "args": "libxml-2.0 libxslt" } + ] + }, "webengine-lcms2": { "label": "lcms2", "sources": [ @@ -321,12 +330,14 @@ "webengine-glibc": { "label": "glibc > 2.26", "type": "compile", - "test": "glibc" - }, - "webengine-libxml2-compatible": { - "label" : "compatible system libxml2", - "test" : "xml2", - "type": "compile" + "test": { + "include": "features.h", + "tail": [ + "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 27", + "#error glibc versions below 2.27 are not supported", + "#endif" + ] + } }, "webengine-sanitizer": { "label" : "sanitizer support", @@ -636,9 +647,7 @@ }, "webengine-system-libxml2": { "label": "libxml2 and libxslt", - "condition": "config.unix - && libs.webengine-libxml2 - && tests.webengine-libxml2-compatible", + "condition": "config.unix && libs.webengine-libxml2", "output": [ "privateFeature" ] }, "webengine-system-lcms2" : { -- cgit v1.2.1 From 63b6f748f1073599845d57ee4f73aecad8182a33 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 7 Aug 2019 15:24:20 +0200 Subject: Move snappy test to configure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I585e7f9aa19d03ca164e9419e55997526aeaca86 Reviewed-by: Jörg Bornemann --- config.tests/snappy/snappy.cpp | 36 ------------------------------------ config.tests/snappy/snappy.pro | 3 --- src/core/configure.json | 20 ++++++++++++++------ 3 files changed, 14 insertions(+), 45 deletions(-) delete mode 100644 config.tests/snappy/snappy.cpp delete mode 100644 config.tests/snappy/snappy.pro diff --git a/config.tests/snappy/snappy.cpp b/config.tests/snappy/snappy.cpp deleted file mode 100644 index d52c73bd0..000000000 --- a/config.tests/snappy/snappy.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - snappy::Source* src = 0; - snappy::Sink* sink = 0; - return 0; -} diff --git a/config.tests/snappy/snappy.pro b/config.tests/snappy/snappy.pro deleted file mode 100644 index 890174a13..000000000 --- a/config.tests/snappy/snappy.pro +++ /dev/null @@ -1,3 +0,0 @@ -linux:SOURCES += snappy.cpp -LIBS += -lsnappy -CONFIG -= qt diff --git a/src/core/configure.json b/src/core/configure.json index b4d39696f..0ee556cfb 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -250,6 +250,19 @@ { "type": "pkgConfig", "args": "freetype2" } ] }, + "webengine-snappy": { + "label": "snappy", + "test": { + "main": [ + "snappy::Source *src = 0;", + "snappy::Sink *sink = 0;" + ] + }, + "headers": "snappy.h", + "sources": [ + "-lsnappy" + ] + }, "webengine-x11" : { "label" : "x11", "sources": [ @@ -274,11 +287,6 @@ "test": "libvpx", "type": "compile" }, - "webengine-snappy": { - "label": "snappy", - "test": "snappy", - "type": "compile" - }, "webengine-winversion": { "label": "winversion", "test": "winversion", @@ -510,7 +518,7 @@ }, "webengine-system-snappy" : { "label": "snappy", - "condition": "config.unix && tests.webengine-snappy", + "condition": "config.unix && libs.webengine-snappy", "output": [ "privateFeature" ] }, "webengine-winversion" : { -- cgit v1.2.1 From b92aa117eb84a4023eca7f9e4def7a71f603b586 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 7 Aug 2019 17:37:08 +0200 Subject: Move libvpx test to configure Change-Id: I669b9d4cc28765b134386752d1fc14d14fa5b1dc Reviewed-by: Allan Sandfeld Jensen --- config.tests/libvpx/libvpx.cpp | 41 ----------------------------------------- config.tests/libvpx/libvpx.pro | 4 ---- src/core/configure.json | 22 ++++++++++++++++------ 3 files changed, 16 insertions(+), 51 deletions(-) delete mode 100644 config.tests/libvpx/libvpx.cpp delete mode 100644 config.tests/libvpx/libvpx.pro diff --git a/config.tests/libvpx/libvpx.cpp b/config.tests/libvpx/libvpx.cpp deleted file mode 100644 index 06c34476b..000000000 --- a/config.tests/libvpx/libvpx.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - vpx_codec_cx_pkt pkt; - // Members added (as ints) by - // https://chromium-review.googlesource.com/c/webm/libvpx/+/798222 - // And changed to int arrays by - // https://chromium-review.googlesource.com/c/webm/libvpx/+/879089 - pkt.data.frame.width[0] = 0u; - pkt.data.frame.height[0] = 0u; - return 0; -} diff --git a/config.tests/libvpx/libvpx.pro b/config.tests/libvpx/libvpx.pro deleted file mode 100644 index 13ce13647..000000000 --- a/config.tests/libvpx/libvpx.pro +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES += libvpx.cpp -CONFIG += link_pkgconfig -PKGCONFIG += vpx -CONFIG -= qt diff --git a/src/core/configure.json b/src/core/configure.json index 0ee556cfb..3e7968d41 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -268,6 +268,21 @@ "sources": [ { "type": "pkgConfig", "args": "x11" } ] + }, + "webengine-libvpx": { + "label": "libvpx", + "test": { + "main": [ + "vpx_codec_cx_pkt pkt;", + "pkt.data.frame.width[0] = 0u;", + "pkt.data.frame.height[0] = 0u;" + ] + }, + "headers": "vpx/vpx_encoder.h", + "sources": [ + { "type": "pkgConfig", "args": "vpx" }, + "-lvpx" + ] } }, "tests" : { @@ -282,11 +297,6 @@ "test": "khr", "type": "compile" }, - "webengine-libvpx": { - "label": "libvpx", - "test": "libvpx", - "type": "compile" - }, "webengine-winversion": { "label": "winversion", "test": "winversion", @@ -513,7 +523,7 @@ }, "webengine-system-libvpx" : { "label": "libvpx", - "condition": "config.unix && tests.webengine-libvpx", + "condition": "config.unix && libs.webengine-libvpx", "output": [ "privateFeature" ] }, "webengine-system-snappy" : { -- cgit v1.2.1 From f45e938472f64e9bf2d38a2000e9e93db52016d9 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 7 Aug 2019 18:10:21 +0200 Subject: Move khr test to configure Change-Id: Ic213555705f12a46283c62410bf9a477f03c05c0 Reviewed-by: Allan Sandfeld Jensen --- config.tests/khr/khr.cpp | 34 ---------------------------------- config.tests/khr/khr.pro | 6 ------ src/core/configure.json | 10 ++++++++-- 3 files changed, 8 insertions(+), 42 deletions(-) delete mode 100644 config.tests/khr/khr.cpp delete mode 100644 config.tests/khr/khr.pro diff --git a/config.tests/khr/khr.cpp b/config.tests/khr/khr.cpp deleted file mode 100644 index df81bd6b2..000000000 --- a/config.tests/khr/khr.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - return 0; -} diff --git a/config.tests/khr/khr.pro b/config.tests/khr/khr.pro deleted file mode 100644 index b8e935f5a..000000000 --- a/config.tests/khr/khr.pro +++ /dev/null @@ -1,6 +0,0 @@ -!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL -!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL - -CONFIG-=qt - -linux:SOURCES += khr.cpp diff --git a/src/core/configure.json b/src/core/configure.json index 3e7968d41..7ec1b0714 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -294,8 +294,14 @@ }, "webengine-khr": { "label": "khr", - "test": "khr", - "type": "compile" + "type": "compile", + "test": { + "include": "KHR/khrplatform.h", + "qmake" : [ + "!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL", + "!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL" + ] + } }, "webengine-winversion": { "label": "winversion", -- cgit v1.2.1 From 113f866f4d0d60f11de0aa6cb19b5e20e64695d9 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 7 Aug 2019 18:17:07 +0200 Subject: Move re2 test to configure Change-Id: I76aa5c544a5930982e1d1b0ed28a75e88ec65e48 Reviewed-by: Allan Sandfeld Jensen --- config.tests/re2/re2.cpp | 36 ------------------------------------ config.tests/re2/re2.pro | 3 --- src/core/configure.json | 24 ++++++++++++++++-------- 3 files changed, 16 insertions(+), 47 deletions(-) delete mode 100644 config.tests/re2/re2.cpp delete mode 100644 config.tests/re2/re2.pro diff --git a/config.tests/re2/re2.cpp b/config.tests/re2/re2.cpp deleted file mode 100644 index bd3b80a82..000000000 --- a/config.tests/re2/re2.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -int main(int, char **) -{ - std::string s("dummytest"); - RE2 re2(s); - return 0; -} diff --git a/config.tests/re2/re2.pro b/config.tests/re2/re2.pro deleted file mode 100644 index b1a26d918..000000000 --- a/config.tests/re2/re2.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES += re2.cpp -LIBS += -lre2 -CONFIG -= qt diff --git a/src/core/configure.json b/src/core/configure.json index 7ec1b0714..14211a2f1 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -146,12 +146,25 @@ { "type": "pkgConfig", "args": "poppler-cpp" } ] }, - "pulseaudio": { + "webengine-pulseaudio": { "label": "pulseaudio >= 0.9.10", "sources": [ { "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" } ] }, + "webengine-re2": { + "label": "re2", + "test" : { + "main": [ + "std::string s;", + "RE2 re2(s);" + ] + }, + "headers": "re2/re2.h", + "sources": [ + { "type": "pkgConfig", "args": "re2" } + ] + }, "webengine-icu": { "label": "icu >= 63", "sources": [ @@ -346,11 +359,6 @@ "label": "embedded", "type": "embedded" }, - "webengine-re2": { - "label": "re2", - "test": "re2", - "type": "compile" - }, "webengine-glibc": { "label": "glibc > 2.26", "type": "compile", @@ -550,7 +558,7 @@ "webengine-pulseaudio": { "label": "Use PulseAudio", "autoDetect": "config.unix", - "condition": "libs.pulseaudio", + "condition": "libs.webengine-pulseaudio", "output": [ "privateFeature" ] }, "webengine-pepper-plugins": { @@ -650,7 +658,7 @@ "webengine-system-re2": { "label": "re2", "autoDetect": "config.unix", - "condition": "tests.webengine-re2", + "condition": "libs.webengine-re2", "output": [ "privateFeature" ] }, "webengine-system-ninja": { -- cgit v1.2.1 From f7197bd7e106fb3dc875616e26a22e131ed733e4 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 7 Aug 2019 18:26:29 +0200 Subject: Move winversion test to configure Change-Id: I5e0544415298b0e6b10e55f91d93d05eef81ccc4 Reviewed-by: Allan Sandfeld Jensen --- config.tests/winversion/winversion.cpp | 36 ---------------------------------- config.tests/winversion/winversion.pro | 3 --- src/core/configure.json | 10 ++++++++-- 3 files changed, 8 insertions(+), 41 deletions(-) delete mode 100644 config.tests/winversion/winversion.cpp delete mode 100644 config.tests/winversion/winversion.pro diff --git a/config.tests/winversion/winversion.cpp b/config.tests/winversion/winversion.cpp deleted file mode 100644 index e9a4cff59..000000000 --- a/config.tests/winversion/winversion.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** 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 https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#if !defined(__clang__) && _MSC_FULL_VER < 191426428 -#error unsupported Visual Studio version -#endif - -int main(int, char **) -{ - return 0; -} diff --git a/config.tests/winversion/winversion.pro b/config.tests/winversion/winversion.pro deleted file mode 100644 index dc501a2f6..000000000 --- a/config.tests/winversion/winversion.pro +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG-=qt -CONFIG+=console -win32: SOURCES += winversion.cpp diff --git a/src/core/configure.json b/src/core/configure.json index 14211a2f1..d868e7f12 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -318,8 +318,14 @@ }, "webengine-winversion": { "label": "winversion", - "test": "winversion", - "type": "compile" + "type": "compile", + "test": { + "head" : [ + "#if !defined(__clang__) && _MSC_FULL_VER < 191426428", + "#error unsupported Visual Studio version", + "#endif" + ] + } }, "webengine-protoc": { "label": "protoc", -- cgit v1.2.1 From de16c27bfd3bf74a2588523dbd017fac833f90f5 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Aug 2019 08:56:27 +0200 Subject: WebContentsAdapter: don't use toStrongRef().data() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's an anti-pattern. Even though we don't expect other threads to destroy the last QSP while we use the pointer obtained from QWeakPointer, play it safe and use QWeakPointer idiomatically: as a non-owning reference, to be converted to an owning one for the duration of our use of the payload object. Amends 7cade5688f6a0bde067dc496cedcb8de14662116. Change-Id: Ib1c136569c27f413a4a78bfc35784032c53522a9 Reviewed-by: Michael Brüning --- src/core/web_contents_adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 052a71905..2831ec159 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -694,7 +694,7 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request) } auto navigate = [](QWeakPointer weakAdapter, const content::NavigationController::LoadURLParams ¶ms) { - WebContentsAdapter *adapter = weakAdapter.toStrongRef().data(); + const auto adapter = weakAdapter.toStrongRef(); if (!adapter) return; adapter->webContents()->GetController().LoadURLWithParams(params); -- cgit v1.2.1 From ee7ac44d4c8903ac7c169d82999474365e361f91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Tue, 13 Aug 2019 17:22:04 +0200 Subject: Fix warning about extra semicolon for Q_DECLARE_FLAGS statement Reduces the number of warnings a bit more. Change-Id: I0da60354758f494fd32be08a2db8600d56e2ac92 Reviewed-by: Allan Sandfeld Jensen --- src/core/favicon_manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h index df74f6303..a8247d15f 100644 --- a/src/core/favicon_manager.h +++ b/src/core/favicon_manager.h @@ -90,7 +90,7 @@ public: TouchIcon = 1 << 1, TouchPrecomposedIcon = 1 << 2 }; - Q_DECLARE_FLAGS(FaviconTypeFlags, FaviconTypeFlag); + Q_DECLARE_FLAGS(FaviconTypeFlags, FaviconTypeFlag) FaviconInfo(); FaviconInfo(const FaviconInfo &); -- cgit v1.2.1 From e9ed235b9f2cd5987ea24575234fb0ce2b58f753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Tue, 13 Aug 2019 14:49:58 +0200 Subject: Use RenderFrameMetadata for scroll position and contents size Needed for using viz display compositor since SubmitCompositorFrame will not be called any more. Also move the loadVisuallyCommitted call to the Compositor's callback. Task-number: QTBUG-71885 Change-Id: I062b3466671cc6af35877f2ff6995ea290cdf9de Reviewed-by: Allan Sandfeld Jensen --- src/core/render_widget_host_view_qt.cpp | 52 +++++++++++++++++++++------------ src/core/render_widget_host_view_qt.h | 7 +++-- src/core/web_contents_delegate_qt.cpp | 8 +---- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 0242506ee..21e9e9041 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -305,6 +305,8 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget config.tap_slop = ui::GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click(); config.enable_longpress_drag_selection = false; m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config)); + + host()->render_frame_metadata_provider()->ReportAllFrameSubmissionsForTesting(true); } RenderWidgetHostViewQt::~RenderWidgetHostViewQt() @@ -669,11 +671,6 @@ void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom: void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, base::Optional) { - bool scrollOffsetChanged = (m_lastScrollOffset != frame.metadata.root_scroll_offset); - bool contentsSizeChanged = (m_lastContentsSize != frame.metadata.root_layer_size); - m_lastScrollOffset = frame.metadata.root_scroll_offset; - m_lastContentsSize = frame.metadata.root_layer_size; - // Force to process swap messages uint32_t frame_token = frame.metadata.frame_token; if (frame_token) @@ -681,19 +678,7 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo m_compositor->submitFrame( std::move(frame), - base::BindOnce(&RenderWidgetHostViewQtDelegate::update, base::Unretained(m_delegate.get()))); - - if (m_loadVisuallyCommittedState == NotCommitted) { - m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap; - } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) { - m_adapterClient->loadVisuallyCommitted(); - m_loadVisuallyCommittedState = NotCommitted; - } - - if (scrollOffsetChanged) - m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset)); - if (contentsSizeChanged) - m_adapterClient->updateContentsSize(toQt(m_lastContentsSize)); + base::BindOnce(&RenderWidgetHostViewQt::callUpdate, base::Unretained(this))); } void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo *results) @@ -914,6 +899,28 @@ void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::Rende synchronizeVisualProperties(metadata.local_surface_id_allocation); } +void RenderWidgetHostViewQt::OnDidFirstVisuallyNonEmptyPaint() +{ + if (m_loadVisuallyCommittedState == NotCommitted) { + m_loadVisuallyCommittedState = DidFirstVisuallyNonEmptyPaint; + } else if (m_loadVisuallyCommittedState == DidFirstCompositorFrameSwap) { + m_adapterClient->loadVisuallyCommitted(); + m_loadVisuallyCommittedState = NotCommitted; + } +} + +void RenderWidgetHostViewQt::callUpdate() +{ + m_delegate->update(); + + if (m_loadVisuallyCommittedState == NotCommitted) { + m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap; + } else if (m_loadVisuallyCommittedState == DidFirstVisuallyNonEmptyPaint) { + m_adapterClient->loadVisuallyCommitted(); + m_loadVisuallyCommittedState = NotCommitted; + } +} + QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode) { return m_compositor->updatePaintNode(oldNode, m_delegate.get()); @@ -1729,6 +1736,15 @@ void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation() m_selectionEnd = metadata.selection.end; m_touchSelectionControllerClient->UpdateClientSelectionBounds(m_selectionStart, m_selectionEnd); } + + gfx::Vector2dF scrollOffset = metadata.root_scroll_offset.value_or(gfx::Vector2dF()); + gfx::SizeF contentsSize = metadata.root_layer_size; + std::swap(m_lastScrollOffset, scrollOffset); + std::swap(m_lastContentsSize, contentsSize); + if (scrollOffset != m_lastScrollOffset) + m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset)); + if (contentsSize != m_lastContentsSize) + m_adapterClient->updateContentsSize(toQt(m_lastContentsSize)); } void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional &childSurfaceId) diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 91d5b8610..50a430d84 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -215,8 +215,9 @@ public: // Overridden from content::BrowserAccessibilityDelegate content::BrowserAccessibilityManager* CreateBrowserAccessibilityManager(content::BrowserAccessibilityDelegate* delegate, bool for_root_frame) override; - LoadVisuallyCommittedState getLoadVisuallyCommittedState() const { return m_loadVisuallyCommittedState; } - void setLoadVisuallyCommittedState(LoadVisuallyCommittedState state) { m_loadVisuallyCommittedState = state; } + + // Called from WebContentsDelegateQt + void OnDidFirstVisuallyNonEmptyPaint(); // Overridden from content::RenderFrameMetadataProvider::Observer void OnRenderFrameMetadataChangedAfterActivation() override; @@ -241,6 +242,8 @@ private: void synchronizeVisualProperties(const base::Optional &childSurfaceId); + void callUpdate(); + // Geometry of the view in screen DIPs. gfx::Rect m_viewRectInDips; // Geometry of the window, including frame, in screen DIPs. diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index f18617f8e..f4812f9db 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -623,13 +623,7 @@ void WebContentsDelegateQt::DidFirstVisuallyNonEmptyPaint() if (!rwhv) return; - RenderWidgetHostViewQt::LoadVisuallyCommittedState loadVisuallyCommittedState = rwhv->getLoadVisuallyCommittedState(); - if (loadVisuallyCommittedState == RenderWidgetHostViewQt::NotCommitted) { - rwhv->setLoadVisuallyCommittedState(RenderWidgetHostViewQt::DidFirstVisuallyNonEmptyPaint); - } else if (loadVisuallyCommittedState == RenderWidgetHostViewQt::DidFirstCompositorFrameSwap) { - m_viewClient->loadVisuallyCommitted(); - rwhv->setLoadVisuallyCommittedState(RenderWidgetHostViewQt::NotCommitted); - } + rwhv->OnDidFirstVisuallyNonEmptyPaint(); } void WebContentsDelegateQt::ActivateContents(content::WebContents* contents) -- cgit v1.2.1 From f0c471d9e2f3e9808cbf8c57bee533e8254ad1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Tue, 13 Aug 2019 14:57:05 +0200 Subject: Use ui::Compositor Needs corresponding 3rdparty change. Fixes: QTBUG-71885 Change-Id: I791bc3da5a7a66e03470e9e05bf25a997101b018 Reviewed-by: Allan Sandfeld Jensen --- examples/webengine/minimal/main.cpp | 1 + src/3rdparty | 2 +- src/core/compositor/compositor_resource_fence.cpp | 8 +- src/core/compositor/compositor_resource_fence.h | 2 +- src/core/compositor/display_consumer.h | 62 +++++ src/core/compositor/display_frame_sink.cpp | 140 ++++++++++ src/core/compositor/display_frame_sink.h | 77 ++++++ src/core/compositor/display_gl_output_surface.cpp | 292 +++++++++++++++++++++ src/core/compositor/display_gl_output_surface.h | 148 +++++++++++ .../compositor/display_gl_output_surface_qsg.cpp | 121 +++++++++ src/core/compositor/display_overrides.cpp | 80 ++++++ src/core/compositor/display_producer.h | 69 +++++ .../compositor/display_software_output_surface.cpp | 173 ++++++++++++ .../compositor/display_software_output_surface.h | 62 +++++ src/core/core_chromium.pri | 11 +- src/core/delegated_frame_host_client_qt.cpp | 91 +++++++ src/core/delegated_frame_host_client_qt.h | 73 ++++++ src/core/render_widget_host_view_qt.cpp | 141 +++++++++- src/core/render_widget_host_view_qt.h | 25 +- src/core/web_engine_context.cpp | 29 +- 20 files changed, 1574 insertions(+), 33 deletions(-) create mode 100644 src/core/compositor/display_consumer.h create mode 100644 src/core/compositor/display_frame_sink.cpp create mode 100644 src/core/compositor/display_frame_sink.h create mode 100644 src/core/compositor/display_gl_output_surface.cpp create mode 100644 src/core/compositor/display_gl_output_surface.h create mode 100644 src/core/compositor/display_gl_output_surface_qsg.cpp create mode 100644 src/core/compositor/display_overrides.cpp create mode 100644 src/core/compositor/display_producer.h create mode 100644 src/core/compositor/display_software_output_surface.cpp create mode 100644 src/core/compositor/display_software_output_surface.h create mode 100644 src/core/delegated_frame_host_client_qt.cpp create mode 100644 src/core/delegated_frame_host_client_qt.h diff --git a/examples/webengine/minimal/main.cpp b/examples/webengine/minimal/main.cpp index 9db6ea6aa..8bcd0e0e9 100644 --- a/examples/webengine/minimal/main.cpp +++ b/examples/webengine/minimal/main.cpp @@ -56,6 +56,7 @@ int main(int argc, char *argv[]) { QCoreApplication::setOrganizationName("QtExamples"); QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QGuiApplication app(argc, argv); QtWebEngine::initialize(); diff --git a/src/3rdparty b/src/3rdparty index f5613a4bc..feccbb4ea 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit f5613a4bc321972b8f72654d4c4bc9ba0c36ffbe +Subproject commit feccbb4ea7fa685dcd013f5a3f6c14ea768636c9 diff --git a/src/core/compositor/compositor_resource_fence.cpp b/src/core/compositor/compositor_resource_fence.cpp index 7fc5fbfb2..4179395d6 100644 --- a/src/core/compositor/compositor_resource_fence.cpp +++ b/src/core/compositor/compositor_resource_fence.cpp @@ -146,12 +146,12 @@ void CompositorResourceFence::release() } // static -scoped_refptr CompositorResourceFence::create() +scoped_refptr CompositorResourceFence::create(std::unique_ptr glFence) { - if (gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) { - std::unique_ptr glFence{gl::GLFence::Create()}; + if (!glFence && gl::GLContext::GetCurrent() && gl::GLFence::IsSupported()) + glFence = gl::GLFence::Create(); + if (glFence) return base::MakeRefCounted(glFence->Transfer()); - } return nullptr; } diff --git a/src/core/compositor/compositor_resource_fence.h b/src/core/compositor/compositor_resource_fence.h index 1c2ea3695..196297f78 100644 --- a/src/core/compositor/compositor_resource_fence.h +++ b/src/core/compositor/compositor_resource_fence.h @@ -60,7 +60,7 @@ public: void release(); // May be used only by GPU thread. - static scoped_refptr create(); + static scoped_refptr create(std::unique_ptr glFence = nullptr); private: gl::TransferableFence m_sync; diff --git a/src/core/compositor/display_consumer.h b/src/core/compositor/display_consumer.h new file mode 100644 index 000000000..d220088ad --- /dev/null +++ b/src/core/compositor/display_consumer.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DISPLAY_CONSUMER_H +#define DISPLAY_CONSUMER_H + +#include "qtwebenginecoreglobal_p.h" + +namespace QtWebEngineCore { + +// Receives composited frames for display. +class DisplayConsumer +{ +public: + // Schedule a call to updatePaintNode soon. + // + // Called on the consumer thread. + virtual void scheduleUpdate() = 0; + +protected: + ~DisplayConsumer() {} +}; + +} // namespace QtWebEngineCore + +#endif // !DISPLAY_CONSUMER_H diff --git a/src/core/compositor/display_frame_sink.cpp b/src/core/compositor/display_frame_sink.cpp new file mode 100644 index 000000000..945600299 --- /dev/null +++ b/src/core/compositor/display_frame_sink.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "display_frame_sink.h" + +#include + +namespace QtWebEngineCore { + +namespace { + +class DisplayFrameSinkMap +{ +public: + static DisplayFrameSinkMap *instance() + { + static DisplayFrameSinkMap map; + return ↦ + } + + scoped_refptr findOrCreate(viz::FrameSinkId frameSinkId) + { + QMutexLocker locker(&m_mutex); + auto it = m_map.find(frameSinkId); + if (it == m_map.end()) + it = m_map.insert(frameSinkId, new DisplayFrameSink(frameSinkId)); + return *it; + } + + void remove(viz::FrameSinkId frameSinkId) + { + QMutexLocker locker(&m_mutex); + m_map.remove(frameSinkId); + } + +private: + mutable QMutex m_mutex; + QMap m_map; +}; + +} // namespace + +// static +scoped_refptr DisplayFrameSink::findOrCreate(viz::FrameSinkId frameSinkId) +{ + return DisplayFrameSinkMap::instance()->findOrCreate(frameSinkId); +} + +DisplayFrameSink::DisplayFrameSink(viz::FrameSinkId frameSinkId) + : m_frameSinkId(frameSinkId) +{ + DCHECK(m_frameSinkId.is_valid()); +} + +DisplayFrameSink::~DisplayFrameSink() +{ + DisplayFrameSinkMap::instance()->remove(m_frameSinkId); +} + +void DisplayFrameSink::connect(DisplayConsumer *consumer) +{ + QMutexLocker locker(&m_mutex); + DCHECK(m_consumer == nullptr); + m_consumer = consumer; +} + +void DisplayFrameSink::connect(DisplayProducer *producer) +{ + QMutexLocker locker(&m_mutex); + DCHECK(m_producer == nullptr); + m_producer = producer; +} + +void DisplayFrameSink::disconnect(DisplayConsumer *consumer) +{ + QMutexLocker locker(&m_mutex); + DCHECK(m_consumer == consumer); + m_consumer = nullptr; +} + +void DisplayFrameSink::disconnect(DisplayProducer *producer) +{ + QMutexLocker locker(&m_mutex); + DCHECK(m_producer == producer); + m_producer = nullptr; +} + +void DisplayFrameSink::scheduleUpdate() +{ + QMutexLocker locker(&m_mutex); + if (m_consumer) + m_consumer->scheduleUpdate(); +} + +QSGNode *DisplayFrameSink::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) +{ + QMutexLocker locker(&m_mutex); + QSGNode *newNode = oldNode; + if (m_producer) + newNode = m_producer->updatePaintNode(oldNode, delegate); + return newNode; +} + +} // namespace QtWebEngineCore diff --git a/src/core/compositor/display_frame_sink.h b/src/core/compositor/display_frame_sink.h new file mode 100644 index 000000000..f620dc4f2 --- /dev/null +++ b/src/core/compositor/display_frame_sink.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DISPLAY_FRAME_SINK_H +#define DISPLAY_FRAME_SINK_H + +#include "display_consumer.h" +#include "display_producer.h" + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_refptr.h" +#include "components/viz/common/surfaces/frame_sink_id.h" + +#include + +namespace QtWebEngineCore { + +// Connects a DisplayConsumer with a DisplayProducer. +class DisplayFrameSink final : public base::RefCountedThreadSafe +{ +public: + static scoped_refptr findOrCreate(viz::FrameSinkId frameSinkId); + DisplayFrameSink(viz::FrameSinkId frameSinkId); + ~DisplayFrameSink(); + void connect(DisplayConsumer *consumer); + void connect(DisplayProducer *producer); + void disconnect(DisplayConsumer *consumer); + void disconnect(DisplayProducer *producer); + void scheduleUpdate(); + QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate); + +private: + const viz::FrameSinkId m_frameSinkId; + mutable QMutex m_mutex; + DisplayProducer *m_producer = nullptr; + DisplayConsumer *m_consumer = nullptr; +}; + +} // namespace QtWebEngineCore + +#endif // !DISPLAY_FRAME_SINK_H diff --git a/src/core/compositor/display_gl_output_surface.cpp b/src/core/compositor/display_gl_output_surface.cpp new file mode 100644 index 000000000..5a78b8322 --- /dev/null +++ b/src/core/compositor/display_gl_output_surface.cpp @@ -0,0 +1,292 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "display_gl_output_surface.h" + +#include "chromium_gpu_helper.h" + +#include "base/threading/thread_task_runner_handle.h" +#include "components/viz/service/display/display.h" +#include "components/viz/service/display/output_surface_frame.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/client/gles2_interface.h" +#include "gpu/command_buffer/service/mailbox_manager.h" +#include "gpu/command_buffer/service/texture_base.h" +#include "gpu/ipc/in_process_command_buffer.h" +#include "ui/gl/color_space_utils.h" + +namespace QtWebEngineCore { + +DisplayGLOutputSurface::DisplayGLOutputSurface( + scoped_refptr contextProvider, + viz::UpdateVSyncParametersCallback callback) + : OutputSurface(contextProvider) + , m_commandBuffer(contextProvider->command_buffer()) + , m_gl(contextProvider->ContextGL()) +{ + capabilities_.uses_default_gl_framebuffer = false; + m_gl->GenFramebuffers(1, &m_fboId); + contextProvider->SetUpdateVSyncParametersCallback(std::move(callback)); +} + +DisplayGLOutputSurface::~DisplayGLOutputSurface() +{ + m_gl->DeleteFramebuffers(1, &m_fboId); + if (m_sink) + m_sink->disconnect(this); +} + +// Called from viz::Display::Initialize. +void DisplayGLOutputSurface::BindToClient(viz::OutputSurfaceClient *client) +{ + m_display = static_cast(client); + m_sink = DisplayFrameSink::findOrCreate(m_display->frame_sink_id()); + m_sink->connect(this); +} + +// Triggered by ui::Compositor::SetVisible(true). +void DisplayGLOutputSurface::EnsureBackbuffer() +{ +} + +// Triggered by ui::Compositor::SetVisible(false). Framebuffer must be cleared. +void DisplayGLOutputSurface::DiscardBackbuffer() +{ + NOTIMPLEMENTED(); + // m_gl->DiscardBackbufferCHROMIUM(); +} + +// Called from viz::DirectRenderer::DrawFrame before rendering starts, but only +// if the parameters differ from the previous Reshape call. +// +// Parameters: +// +// - sizeInPixels comes from ui::Compositor::SetScaleAndSize via +// viz::HostContextFactoryPrivate::ResizeDisplay. +// +// - devicePixelRatio comes from viz::CompositorFrame::device_scale_factor() +// via viz::RootCompositorFrameSinkImpl::SubmitCompositorFrame and +// viz::Display::SetLocalSurfaceId. +// +// - colorSpace and hasAlpha correspond to the color_space and +// has_transparent_background properties of the root viz::RenderPass. +// +// - useStencil should create a stencil buffer, but this is only needed for +// overdraw feedback (--show-overdraw-feedback), so it's safe to ignore. +// Accordingly, capabilities_.supports_stencil should be set to false. +// +void DisplayGLOutputSurface::Reshape(const gfx::Size &sizeInPixels, + float devicePixelRatio, + const gfx::ColorSpace &colorSpace, + bool hasAlpha, + bool /*useStencil*/) +{ + m_currentShape = Shape{sizeInPixels, devicePixelRatio, colorSpace, hasAlpha}; + m_gl->ResizeCHROMIUM(sizeInPixels.width(), sizeInPixels.height(), devicePixelRatio, + gl::ColorSpaceUtils::GetGLColorSpace(colorSpace), hasAlpha); +} + +std::unique_ptr DisplayGLOutputSurface::makeBuffer(const Shape &shape) +{ + std::unique_ptr buffer = std::make_unique(this); + buffer->shape = shape; + m_gl->GenTextures(1, &buffer->clientId); + m_gl->BindTexture(GL_TEXTURE_2D, buffer->clientId); + m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + m_gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + uint32_t width = shape.sizeInPixels.width(); + uint32_t height = shape.sizeInPixels.height(); + uint32_t format = shape.hasAlpha ? GL_RGBA : GL_RGB; + m_gl->TexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr); + return buffer; +} + +void DisplayGLOutputSurface::deleteBufferResources(Buffer *buffer) +{ + m_gl->DeleteTextures(1, &buffer->clientId); +} + +// Called by viz::GLRenderer during rendering whenever it switches to the root +// render pass. +void DisplayGLOutputSurface::BindFramebuffer() +{ + if (!m_backBuffer || m_backBuffer->shape != m_currentShape) + m_backBuffer = makeBuffer(m_currentShape); + + m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId); + m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_backBuffer->clientId, 0); +} + +// Called from viz::Display::DrawAndSwap after rendering. +// +// Parameters: +// +// - frame.size is the same as the size given to Reshape. +// +// - frame.sub_buffer_rect and frame.content_bounds are never used since these +// are only enabled if gl::GLSurface::SupportsPostSubBuffer() or +// gl::GLSurface::SupportsSwapBuffersWithBounds() are true, respectively, +// but this not the case for any offscreen gl::GLSurface. +// +// - frame.latency_info is viz::CompositorFrame::metadata.latency_info. +void DisplayGLOutputSurface::SwapBuffers(viz::OutputSurfaceFrame frame) +{ + DCHECK(frame.size == m_currentShape.sizeInPixels); + DCHECK(!frame.sub_buffer_rect.has_value()); + DCHECK(frame.content_bounds.empty()); + DCHECK(m_backBuffer); + + m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fboId); + m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + gpu::SyncToken syncToken; + m_gl->GenSyncTokenCHROMIUM(syncToken.GetData()); + + unsigned int clientId = m_backBuffer->clientId; + + // Now some thread-hopping: + // + // - We start here on the viz thread (client side of command buffer). + // + // - Then we'll jump to the gpu thread (service side of command buffer) to + // get the real OpenGL texture id. + // + // - Then we'll get a call from the Qt Quick Scene Graph thread (could be + // a separate thread or the main thread). + // + // - Finally we'll return to the viz thread to acknowledge the swap. + + { + QMutexLocker locker(&m_mutex); + m_taskRunner = base::ThreadTaskRunnerHandle::Get(); + m_middleBuffer = std::move(m_backBuffer); + m_middleBuffer->serviceId = 0; + } + + m_commandBuffer->GetTextureQt( + clientId, + base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnGpuThread, base::Unretained(this)), + std::vector{syncToken}); +} + +void DisplayGLOutputSurface::swapBuffersOnGpuThread(unsigned int id, std::unique_ptr fence) +{ + { + QMutexLocker locker(&m_mutex); + m_middleBuffer->serviceId = id; + m_middleBuffer->fence = CompositorResourceFence::create(std::move(fence)); + } + + m_sink->scheduleUpdate(); +} + +void DisplayGLOutputSurface::swapBuffersOnVizThread() +{ + { + QMutexLocker locker(&m_mutex); + m_backBuffer = std::move(m_middleBuffer); + } + + m_display->DidReceiveSwapBuffersAck(); + m_display->DidReceivePresentationFeedback( + gfx::PresentationFeedback(base::TimeTicks::Now(), base::TimeDelta(), + gfx::PresentationFeedback::Flags::kVSync)); +} + +void DisplayGLOutputSurface::SetDrawRectangle(const gfx::Rect &) +{ +} + +// Returning nullptr here effectively disables viz::OverlayProcessor. +viz::OverlayCandidateValidator *DisplayGLOutputSurface::GetOverlayCandidateValidator() const +{ + return nullptr; +} + +// Returning true here will cause viz::GLRenderer to try to render the output +// surface as an overlay plane (see viz::DirectRenderer::DrawFrame and +// viz::GLRenderer::ScheduleOverlays). +bool DisplayGLOutputSurface::IsDisplayedAsOverlayPlane() const +{ + return false; +} + +// Only used if IsDisplayedAsOverlayPlane was true (called from +// viz::GLRenderer::ScheduleOverlays). +unsigned DisplayGLOutputSurface::GetOverlayTextureId() const +{ + return 0; +} + +// Only used if IsDisplayedAsOverlayPlane was true (called from +// viz::DirectRender::DrawFrame). +gfx::BufferFormat DisplayGLOutputSurface::GetOverlayBufferFormat() const +{ + return gfx::BufferFormat(); +} + +// Called by viz::GLRenderer but always false in all implementations except for +// android_webview::ParentOutputSurface. +bool DisplayGLOutputSurface::HasExternalStencilTest() const +{ + return false; +} + +// Only called if HasExternalStencilTest was true. Dead code? +void DisplayGLOutputSurface::ApplyExternalStencil() +{ + NOTREACHED(); +} + +// Called from GLRenderer::GetFramebufferCopyTextureFormat when using +// glCopyTexSubImage2D on our framebuffer. +uint32_t DisplayGLOutputSurface::GetFramebufferCopyTextureFormat() +{ + return GL_RGBA; +} + +// Called from viz::DirectRenderer::DrawFrame, only used for overlays. +unsigned DisplayGLOutputSurface::UpdateGpuFence() +{ + NOTREACHED(); + return 0; +} + +} // namespace QtWebEngineCore diff --git a/src/core/compositor/display_gl_output_surface.h b/src/core/compositor/display_gl_output_surface.h new file mode 100644 index 000000000..c42a6630a --- /dev/null +++ b/src/core/compositor/display_gl_output_surface.h @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DISPLAY_GL_OUTPUT_SURFACE_H +#define DISPLAY_GL_OUTPUT_SURFACE_H + +#include "compositor_resource_fence.h" +#include "display_frame_sink.h" + +#include "components/viz/common/display/update_vsync_parameters_callback.h" +#include "components/viz/service/display/output_surface.h" +#include "components/viz/service/display_embedder/viz_process_context_provider.h" +#include "gpu/command_buffer/common/mailbox.h" +#include "gpu/command_buffer/common/sync_token.h" + +namespace viz { +class Display; +class SyntheticBeginFrameSource; +} // namespace viz + +namespace QtWebEngineCore { + +// NOTE: Some methods are defined in display_gl_output_surface_qsg.cpp due +// to conflicts between Qt & Chromium OpenGL APIs. +class DisplayGLOutputSurface final : public viz::OutputSurface, public DisplayProducer +{ +public: + DisplayGLOutputSurface( + scoped_refptr contextProvider, + viz::UpdateVSyncParametersCallback callback); + ~DisplayGLOutputSurface() override; + + // Overridden from viz::OutputSurface. + void BindToClient(viz::OutputSurfaceClient *client) override; + void EnsureBackbuffer() override; + void DiscardBackbuffer() override; + void BindFramebuffer() override; + void SetDrawRectangle(const gfx::Rect &drawRect) override; + viz::OverlayCandidateValidator *GetOverlayCandidateValidator() const override; + bool IsDisplayedAsOverlayPlane() const override; + unsigned GetOverlayTextureId() const override; + gfx::BufferFormat GetOverlayBufferFormat() const override; + void Reshape(const gfx::Size &size, + float devicePixelRatio, + const gfx::ColorSpace &colorSpace, + bool hasAlpha, + bool useStencil) override; + bool HasExternalStencilTest() const override; + void ApplyExternalStencil() override; + uint32_t GetFramebufferCopyTextureFormat() override; + void SwapBuffers(viz::OutputSurfaceFrame frame) override; + unsigned UpdateGpuFence() override; + + // Overridden from DisplayProducer. + QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override; + +private: + struct Shape + { + gfx::Size sizeInPixels; + float devicePixelRatio; + gfx::ColorSpace colorSpace; + bool hasAlpha; + + bool operator==(const Shape &that) const + { + return (sizeInPixels == that.sizeInPixels && + devicePixelRatio == that.devicePixelRatio && + colorSpace == that.colorSpace && + hasAlpha == that.hasAlpha); + } + bool operator!=(const Shape &that) const { return !(*this == that); } + }; + + struct Buffer + { + DisplayGLOutputSurface *parent; + Shape shape; + uint32_t clientId = 0; + uint32_t serviceId = 0; + scoped_refptr fence; + + Buffer(DisplayGLOutputSurface *parent) : parent(parent) {} + ~Buffer() { parent->deleteBufferResources(this); } + }; + + class Texture; + + void swapBuffersOnGpuThread(unsigned int id, std::unique_ptr fence); + void swapBuffersOnVizThread(); + + std::unique_ptr makeBuffer(const Shape &shape); + void deleteBufferResources(Buffer *buffer); + void attachBuffer(); + void detachBuffer(); + + gpu::InProcessCommandBuffer *const m_commandBuffer; + gpu::gles2::GLES2Interface *const m_gl; + mutable QMutex m_mutex; + uint32_t m_fboId = 0; + viz::Display *m_display = nullptr; + scoped_refptr m_sink; + Shape m_currentShape; + std::unique_ptr m_backBuffer; + std::unique_ptr m_middleBuffer; + std::unique_ptr m_frontBuffer; + scoped_refptr m_taskRunner; +}; + +} // namespace QtWebEngineCore + +#endif // !DISPLAY_GL_OUTPUT_SURFACE_H diff --git a/src/core/compositor/display_gl_output_surface_qsg.cpp b/src/core/compositor/display_gl_output_surface_qsg.cpp new file mode 100644 index 000000000..2f7b3de84 --- /dev/null +++ b/src/core/compositor/display_gl_output_surface_qsg.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "display_gl_output_surface.h" + +#include "compositor_resource_fence.h" +#include "render_widget_host_view_qt_delegate.h" +#include "type_conversion.h" + +#include +#include +#include + +namespace QtWebEngineCore { + +class DisplayGLOutputSurface::Texture final : public QSGTexture +{ +public: + Texture(uint32_t id, QSize sizeInPixels, bool hasAlphaChannel, scoped_refptr fence) + : m_id(id) + , m_sizeInPixels(sizeInPixels) + , m_hasAlphaChannel(hasAlphaChannel) + , m_fence(std::move(fence)) + { + } + + // QSGTexture: + int textureId() const override { return m_id; } + QSize textureSize() const override { return m_sizeInPixels; } + bool hasAlphaChannel() const override { return m_hasAlphaChannel; } + bool hasMipmaps() const override { return false; } + void bind() override + { + if (m_fence) { + m_fence->wait(); + m_fence.reset(); + } + + QOpenGLContext *context = QOpenGLContext::currentContext(); + QOpenGLFunctions *funcs = context->functions(); + funcs->glBindTexture(GL_TEXTURE_2D, m_id); + } + +private: + uint32_t m_id; + QSize m_sizeInPixels; + bool m_hasAlphaChannel; + scoped_refptr m_fence; +}; + +QSGNode *DisplayGLOutputSurface::updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) +{ + { + QMutexLocker locker(&m_mutex); + if (m_middleBuffer && m_middleBuffer->serviceId) { + std::swap(m_middleBuffer, m_frontBuffer); + m_taskRunner->PostTask( + FROM_HERE, + base::BindOnce(&DisplayGLOutputSurface::swapBuffersOnVizThread, base::Unretained(this))); + m_taskRunner.reset(); + } + } + + if (!m_frontBuffer) + return oldNode; + + auto node = static_cast(oldNode); + if (!node) + node = delegate->createImageNode(); + + QSize sizeInPixels = toQt(m_frontBuffer->shape.sizeInPixels); + QSizeF sizeInDips = QSizeF(sizeInPixels) / m_frontBuffer->shape.devicePixelRatio; + QRectF rectInDips(QPointF(0, 0), sizeInDips); + node->setRect(rectInDips); + node->setOwnsTexture(true); + node->setTexture(new Texture(m_frontBuffer->serviceId, + sizeInPixels, + m_frontBuffer->shape.hasAlpha, + m_frontBuffer->fence)); + node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically); + + return node; +} + +} // namespace QtWebEngineCore diff --git a/src/core/compositor/display_overrides.cpp b/src/core/compositor/display_overrides.cpp new file mode 100644 index 000000000..4547bb04b --- /dev/null +++ b/src/core/compositor/display_overrides.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "display_gl_output_surface.h" +#include "display_software_output_surface.h" + +#include "components/viz/service/display_embedder/gpu_display_provider.h" +#include "gpu/ipc/in_process_command_buffer.h" + +std::unique_ptr +viz::GpuDisplayProvider::CreateGLOutputSurface( + scoped_refptr context_provider, + UpdateVSyncParametersCallback update_vsync_callback) +{ + return std::make_unique( + std::move(context_provider), std::move(update_vsync_callback)); +} + +std::unique_ptr +viz::GpuDisplayProvider::CreateSoftwareOutputSurface( + UpdateVSyncParametersCallback update_vsync_callback) +{ + return std::make_unique(std::move(update_vsync_callback)); +} + +void gpu::InProcessCommandBuffer::GetTextureQt( + unsigned int client_id, + GetTextureCallback callback, + const std::vector& sync_token_fences) +{ + ScheduleGpuTask(base::BindOnce(&InProcessCommandBuffer::GetTextureQtOnGpuThread, + gpu_thread_weak_ptr_factory_.GetWeakPtr(), + client_id, + std::move(callback)), + sync_token_fences); +} + +void gpu::InProcessCommandBuffer::GetTextureQtOnGpuThread( + unsigned int client_id, GetTextureCallback callback) +{ + MakeCurrent(); + gpu::TextureBase *texture = decoder_->GetTextureBase(client_id); + std::move(callback).Run(texture ? texture->service_id() : 0, gl::GLFence::Create()); +} diff --git a/src/core/compositor/display_producer.h b/src/core/compositor/display_producer.h new file mode 100644 index 000000000..5de09d2d2 --- /dev/null +++ b/src/core/compositor/display_producer.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DISPLAY_PRODUCER_H +#define DISPLAY_PRODUCER_H + +#include "qtwebenginecoreglobal_p.h" + +QT_BEGIN_NAMESPACE +class QSGNode; +QT_END_NAMESPACE + +namespace QtWebEngineCore { +class RenderWidgetHostViewQtDelegate; + +// Produces composited frames for display. +class DisplayProducer +{ +public: + // Generate scene graph nodes for the current frame. + // + // If this is a scheduled update (that is, scheduleUpdate was called + // earlier), then updatePaintNode will generate nodes for a new frame. + // Otherwise, it will just regenerate nodes for the old frame. + virtual QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) = 0; + +protected: + ~DisplayProducer() {} +}; + +} // namespace QtWebEngineCore + +#endif // !DISPLAY_PRODUCER_H diff --git a/src/core/compositor/display_software_output_surface.cpp b/src/core/compositor/display_software_output_surface.cpp new file mode 100644 index 000000000..13f8e8f38 --- /dev/null +++ b/src/core/compositor/display_software_output_surface.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "display_software_output_surface.h" + +#include "display_frame_sink.h" +#include "render_widget_host_view_qt_delegate.h" +#include "type_conversion.h" + +#include "base/threading/thread_task_runner_handle.h" +#include "components/viz/service/display/display.h" +#include "components/viz/service/display/output_surface_frame.h" + +#include +#include +#include + +namespace QtWebEngineCore { + +class DisplaySoftwareOutputSurface::Device final : public viz::SoftwareOutputDevice, public DisplayProducer +{ +public: + ~Device(); + + // Called from DisplaySoftwareOutputSurface. + void bind(viz::FrameSinkId frameSinkId); + + // Overridden from viz::SoftwareOutputDevice. + void Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) override; + void OnSwapBuffers(base::OnceClosure swapCompletionCallback) override; + + // Overridden from DisplayProducer. + QSGNode *updatePaintNode(QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) override; + +private: + mutable QMutex m_mutex; + scoped_refptr m_sink; + float m_devicePixelRatio = 1.0; + scoped_refptr m_taskRunner; + base::OnceClosure m_swapCompletionCallback; + QImage m_image; + float m_imageDevicePixelRatio = 1.0; +}; + +DisplaySoftwareOutputSurface::Device::~Device() +{ + if (m_sink) + m_sink->disconnect(this); +} + +void DisplaySoftwareOutputSurface::Device::bind(viz::FrameSinkId frameSinkId) +{ + m_sink = DisplayFrameSink::findOrCreate(frameSinkId); + m_sink->connect(this); +} + +void DisplaySoftwareOutputSurface::Device::Resize(const gfx::Size &sizeInPixels, float devicePixelRatio) +{ + if (viewport_pixel_size_ == sizeInPixels && m_devicePixelRatio == devicePixelRatio) + return; + m_devicePixelRatio = devicePixelRatio; + viewport_pixel_size_ = sizeInPixels; + surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(sizeInPixels.width(), sizeInPixels.height())); +} + +void DisplaySoftwareOutputSurface::Device::OnSwapBuffers(base::OnceClosure swapCompletionCallback) +{ + QMutexLocker locker(&m_mutex); + m_taskRunner = base::ThreadTaskRunnerHandle::Get(); + m_swapCompletionCallback = std::move(swapCompletionCallback); + m_sink->scheduleUpdate(); +} + +inline QImage::Format imageFormat(SkColorType colorType) +{ + switch (colorType) { + case kBGRA_8888_SkColorType: + return QImage::Format_ARGB32_Premultiplied; + case kRGBA_8888_SkColorType: + return QImage::Format_RGBA8888_Premultiplied; + default: + Q_UNREACHABLE(); + return QImage::Format_ARGB32_Premultiplied; + } +} + +QSGNode *DisplaySoftwareOutputSurface::Device::updatePaintNode( + QSGNode *oldNode, RenderWidgetHostViewQtDelegate *delegate) +{ + QMutexLocker locker(&m_mutex); + + // Delete old node to make sure refcount of m_image is at most 1. + delete oldNode; + QSGImageNode *node = delegate->createImageNode(); + + if (m_swapCompletionCallback) { + SkPixmap skPixmap; + surface_->peekPixels(&skPixmap); + QImage image(reinterpret_cast(skPixmap.addr()), + viewport_pixel_size_.width(), viewport_pixel_size_.height(), + skPixmap.rowBytes(), imageFormat(skPixmap.colorType())); + if (m_image.size() == image.size()) { + QRect damageRect = toQt(damage_rect_); + QPainter(&m_image).drawImage(damageRect, image, damageRect); + } else { + m_image = image; + m_image.detach(); + } + m_imageDevicePixelRatio = m_devicePixelRatio; + m_taskRunner->PostTask(FROM_HERE, std::move(m_swapCompletionCallback)); + m_taskRunner.reset(); + } + + QSizeF sizeInDips = QSizeF(m_image.size()) / m_imageDevicePixelRatio; + node->setRect(QRectF(QPointF(0, 0), sizeInDips)); + node->setOwnsTexture(true); + node->setTexture(delegate->createTextureFromImage(m_image)); + + return node; +} + +DisplaySoftwareOutputSurface::DisplaySoftwareOutputSurface(viz::UpdateVSyncParametersCallback callback) + : SoftwareOutputSurface(std::make_unique(), std::move(callback)) +{} + +DisplaySoftwareOutputSurface::~DisplaySoftwareOutputSurface() {} + +// Called from viz::Display::Initialize. +void DisplaySoftwareOutputSurface::BindToClient(viz::OutputSurfaceClient *client) +{ + auto display = static_cast(client); + auto device = static_cast(software_device()); + device->bind(display->frame_sink_id()); + SoftwareOutputSurface::BindToClient(client); +} + +} // namespace QtWebEngineCore diff --git a/src/core/compositor/display_software_output_surface.h b/src/core/compositor/display_software_output_surface.h new file mode 100644 index 000000000..6707c74dc --- /dev/null +++ b/src/core/compositor/display_software_output_surface.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DISPLAY_SOFTWARE_OUTPUT_SURFACE_H +#define DISPLAY_SOFTWARE_OUTPUT_SURFACE_H + +#include "components/viz/service/display_embedder/software_output_surface.h" + +namespace QtWebEngineCore { + +class DisplaySoftwareOutputSurface final : public viz::SoftwareOutputSurface +{ +public: + DisplaySoftwareOutputSurface(viz::UpdateVSyncParametersCallback callback); + ~DisplaySoftwareOutputSurface() override; + + // Overridden from viz::SoftwareOutputSurface. + void BindToClient(viz::OutputSurfaceClient *client) override; + +private: + class Device; +}; + +} // namespace QtWebEngineCore + +#endif // !DISPLAY_SOFTWARE_OUTPUT_SURFACE_H diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index 908387788..bc39f8e15 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -59,10 +59,14 @@ SOURCES = \ compositor/compositor_resource_tracker.cpp \ compositor/content_gpu_client_qt.cpp \ compositor/delegated_frame_node.cpp \ + compositor/display_frame_sink.cpp \ + compositor/display_overrides.cpp \ + compositor/display_software_output_surface.cpp \ content_client_qt.cpp \ content_browser_client_qt.cpp \ content_main_delegate_qt.cpp \ content_utility_client_qt.cpp \ + delegated_frame_host_client_qt.cpp \ desktop_screen_qt.cpp \ devtools_frontend_qt.cpp \ devtools_manager_delegate_qt.cpp \ @@ -163,10 +167,13 @@ HEADERS = \ compositor/compositor_resource_tracker.h \ compositor/content_gpu_client_qt.h \ compositor/delegated_frame_node.h \ + compositor/display_frame_sink.h \ + compositor/display_software_output_surface.h \ content_client_qt.h \ content_browser_client_qt.h \ content_main_delegate_qt.h \ content_utility_client_qt.h \ + delegated_frame_host_client_qt.h \ desktop_screen_qt.h \ devtools_frontend_qt.h \ devtools_manager_delegate_qt.h \ @@ -292,11 +299,13 @@ qtConfig(webengine-printing-and-pdf) { contains(QT_CONFIG, opengl) { SOURCES += \ compositor/compositor_resource_fence.cpp \ + compositor/display_gl_output_surface.cpp \ + compositor/display_gl_output_surface_qsg.cpp \ compositor/stream_video_node.cpp \ compositor/yuv_video_node.cpp - HEADERS += \ compositor/compositor_resource_fence.h \ + compositor/display_gl_output_surface.h \ compositor/stream_video_node.h \ compositor/yuv_video_node.h } diff --git a/src/core/delegated_frame_host_client_qt.cpp b/src/core/delegated_frame_host_client_qt.cpp new file mode 100644 index 000000000..d3f5a4ade --- /dev/null +++ b/src/core/delegated_frame_host_client_qt.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "delegated_frame_host_client_qt.h" + +#include "render_widget_host_view_qt.h" + +namespace QtWebEngineCore { + +ui::Layer *DelegatedFrameHostClientQt::DelegatedFrameHostGetLayer() const +{ + return p->m_rootLayer.get(); +} + +bool DelegatedFrameHostClientQt::DelegatedFrameHostIsVisible() const +{ + return !p->host()->is_hidden(); +} + +SkColor DelegatedFrameHostClientQt::DelegatedFrameHostGetGutterColor() const +{ + return p->GetBackgroundColor().value_or(SK_ColorWHITE); +} + +void DelegatedFrameHostClientQt::OnBeginFrame(base::TimeTicks frame_time) +{ + p->host()->ProgressFlingIfNeeded(frame_time); +} + +void DelegatedFrameHostClientQt::OnFrameTokenChanged(uint32_t frame_token) +{ + p->OnFrameTokenChangedForView(frame_token); +} + +float DelegatedFrameHostClientQt::GetDeviceScaleFactor() const +{ + return p->m_screenInfo.device_scale_factor; +} + +void DelegatedFrameHostClientQt::InvalidateLocalSurfaceIdOnEviction() +{ + p->m_dfhLocalSurfaceIdAllocator.Invalidate(); +} + +std::vector DelegatedFrameHostClientQt::CollectSurfaceIdsForEviction() +{ + return p->host()->CollectSurfaceIdsForEviction(); +} + +bool DelegatedFrameHostClientQt::ShouldShowStaleContentOnEviction() +{ + return p->host()->ShouldShowStaleContentOnEviction(); +} + +} // namespace QtWebEngineCore diff --git a/src/core/delegated_frame_host_client_qt.h b/src/core/delegated_frame_host_client_qt.h new file mode 100644 index 000000000..b5dc6eb59 --- /dev/null +++ b/src/core/delegated_frame_host_client_qt.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DELEGATED_FRAME_HOST_CLIENT_QT_H +#define DELEGATED_FRAME_HOST_CLIENT_QT_H + +#include "qtwebenginecoreglobal_p.h" + +#include "content/browser/renderer_host/delegated_frame_host.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" + +namespace QtWebEngineCore { + +class RenderWidgetHostViewQt; +class DelegatedFrameHostClientQt : public content::DelegatedFrameHostClient +{ +public: + explicit DelegatedFrameHostClientQt(RenderWidgetHostViewQt *p) : p(p) {} + + // Overridden from content::DelegatedFrameHostClient + ui::Layer *DelegatedFrameHostGetLayer() const override; + bool DelegatedFrameHostIsVisible() const override; + SkColor DelegatedFrameHostGetGutterColor() const override; + void OnBeginFrame(base::TimeTicks frame_time) override; + void OnFrameTokenChanged(uint32_t frame_token) override; + float GetDeviceScaleFactor() const override; + void InvalidateLocalSurfaceIdOnEviction() override; + std::vector CollectSurfaceIdsForEviction() override; + bool ShouldShowStaleContentOnEviction() override; + +private: + RenderWidgetHostViewQt *p; +}; + +} // namespace QtWebEngineCore + +#endif // !DELEGATED_FRAME_HOST_CLIENT_QT_H diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 21e9e9041..2918fd8bc 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -51,6 +51,9 @@ #include "web_contents_adapter_client.h" #include "web_event_factory.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/viz/common/features.h" +#include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" #include "components/viz/host/host_frame_sink_manager.h" #include "content/browser/compositor/surface_utils.h" @@ -271,10 +274,12 @@ static content::ScreenInfo screenInfoFromQScreen(QScreen *screen) RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget) : content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget) + , m_taskRunner(base::ThreadTaskRunnerHandle::Get()) , m_gestureProvider(QtGestureProviderConfig(), this) , m_sendMotionActionDown(false) , m_touchMotionStarted(false) - , m_compositor(new Compositor(widget)) + , m_enableViz(features::IsVizDisplayCompositorEnabled()) + , m_visible(false) , m_loadVisuallyCommittedState(NotCommitted) , m_adapterClient(0) , m_imeInProgress(false) @@ -288,14 +293,39 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget , m_mouseWheelPhaseHandler(this) , m_frameSinkId(host()->GetFrameSinkId()) { - host()->SetView(this); - if (GetTextInputManager()) GetTextInputManager()->AddObserver(this); const QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext(); m_imeHasHiddenTextCapability = context && context->hasCapability(QPlatformInputContext::HiddenTextCapability); + if (m_enableViz) { + m_rootLayer.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); + m_rootLayer->SetColor(SK_ColorTRANSPARENT); + + m_delegatedFrameHost.reset(new content::DelegatedFrameHost( + host()->GetFrameSinkId(), + &m_delegatedFrameHostClient, + true /* should_register_frame_sink_id */)); + + content::ImageTransportFactory *imageTransportFactory = content::ImageTransportFactory::GetInstance(); + ui::ContextFactory *contextFactory = imageTransportFactory->GetContextFactory(); + ui::ContextFactoryPrivate *contextFactoryPrivate = imageTransportFactory->GetContextFactoryPrivate(); + m_uiCompositor.reset(new ui::Compositor( + contextFactoryPrivate->AllocateFrameSinkId(), + contextFactory, + contextFactoryPrivate, + m_taskRunner, + false /* enable_pixel_canvas */)); + m_uiCompositor->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); // null means offscreen + m_uiCompositor->SetRootLayer(m_rootLayer.get()); + + m_displayFrameSink = DisplayFrameSink::findOrCreate(m_uiCompositor->frame_sink_id()); + m_displayFrameSink->connect(this); + } else { + m_compositor.reset(new Compositor(widget)); + } + if (host()->delegate() && host()->delegate()->GetInputEventRouter()) host()->delegate()->GetInputEventRouter()->AddFrameSinkIdOwner(GetFrameSinkId(), this); @@ -307,12 +337,20 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget m_touchSelectionController.reset(new ui::TouchSelectionController(m_touchSelectionControllerClient.get(), config)); host()->render_frame_metadata_provider()->ReportAllFrameSubmissionsForTesting(true); + + // May call SetNeedsBeginFrames + host()->SetView(this); } RenderWidgetHostViewQt::~RenderWidgetHostViewQt() { + m_delegate.reset(); + QObject::disconnect(m_adapterClientDestroyedConnection); + if (m_enableViz) + m_displayFrameSink->disconnect(this); + if (text_input_manager_) text_input_manager_->RemoveObserver(this); @@ -406,6 +444,8 @@ bool RenderWidgetHostViewQt::HasFocus() bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy() { + if (m_enableViz) + return m_delegatedFrameHost->CanCopyFromCompositingSurface(); return true; } @@ -413,6 +453,11 @@ void RenderWidgetHostViewQt::CopyFromSurface(const gfx::Rect &src_rect, const gfx::Size &output_size, base::OnceCallback callback) { + if (m_enableViz) { + m_delegatedFrameHost->CopyFromCompositingSurface(src_rect, output_size, std::move(callback)); + return; + } + QImage image; if (m_delegate->copySurface(toQt(src_rect), toQt(output_size), image)) std::move(callback).Run(toSkBitmap(image)); @@ -443,6 +488,18 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() void RenderWidgetHostViewQt::UpdateBackgroundColor() { + if (m_enableViz) { + DCHECK(GetBackgroundColor()); + SkColor color = *GetBackgroundColor(); + bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE; + m_rootLayer->SetFillsBoundsOpaquely(opaque); + m_rootLayer->SetColor(color); + m_uiCompositor->SetBackgroundColor(color); + m_delegate->setClearColor(toQt(color)); + host()->Send(new RenderViewObserverQt_SetBackgroundColor(host()->GetRoutingID(), color)); + return; + } + auto color = GetBackgroundColor(); if (color) { m_delegate->setClearColor(toQt(*color)); @@ -664,13 +721,16 @@ void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_te m_adapterClient->setToolTip(toQt(tooltip_text)); } -void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom::CompositorFrameSinkClient *frameSink) +void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom::CompositorFrameSinkClient *frameSinkClient) { - m_compositor->setFrameSinkClient(frameSink); + DCHECK(!m_enableViz); + m_compositor->setFrameSinkClient(frameSinkClient); } -void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, base::Optional) +void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, base::Optional hit_test_region_list) { + DCHECK(!m_enableViz); + // Force to process swap messages uint32_t frame_token = frame.metadata.frame_token; if (frame_token) @@ -891,7 +951,7 @@ viz::ScopedSurfaceIdAllocator RenderWidgetHostViewQt::DidUpdateVisualProperties( base::OnceCallback allocation_task = base::BindOnce(&RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete, base::Unretained(this), metadata); - return viz::ScopedSurfaceIdAllocator(std::move(allocation_task)); + return viz::ScopedSurfaceIdAllocator(&m_dfhLocalSurfaceIdAllocator, std::move(allocation_task)); } void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::RenderFrameMetadata &metadata) @@ -909,6 +969,14 @@ void RenderWidgetHostViewQt::OnDidFirstVisuallyNonEmptyPaint() } } +void RenderWidgetHostViewQt::scheduleUpdate() +{ + DCHECK(m_enableViz); + m_taskRunner->PostTask( + FROM_HERE, + base::BindOnce(&RenderWidgetHostViewQt::callUpdate, m_weakPtrFactory.GetWeakPtr())); +} + void RenderWidgetHostViewQt::callUpdate() { m_delegate->update(); @@ -923,17 +991,39 @@ void RenderWidgetHostViewQt::callUpdate() QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode) { + if (m_enableViz) + return m_displayFrameSink->updatePaintNode(oldNode, m_delegate.get()); return m_compositor->updatePaintNode(oldNode, m_delegate.get()); } void RenderWidgetHostViewQt::notifyShown() { - host()->WasShown(false); + if (m_enableViz) { + if (m_visible) + return; + m_visible = true; + m_delegatedFrameHost->AttachToCompositor(m_uiCompositor.get()); + m_delegatedFrameHost->WasShown(GetLocalSurfaceIdAllocation().local_surface_id(), + m_viewRectInDips.size(), + false /* record_presentation_time */); + host()->WasShown(false); + } else { + host()->WasShown(false); + } } void RenderWidgetHostViewQt::notifyHidden() { - host()->WasHidden(); + if (m_enableViz) { + if (!m_visible) + return; + m_visible = false; + host()->WasHidden(); + m_delegatedFrameHost->WasHidden(); + m_delegatedFrameHost->DetachFromCompositor(); + } else { + host()->WasHidden(); + } } void RenderWidgetHostViewQt::visualPropertiesChanged() @@ -1651,6 +1741,7 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev) void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames) { + DCHECK(!m_enableViz); m_compositor->setNeedsBeginFrames(needs_begin_frames); } @@ -1690,26 +1781,35 @@ void RenderWidgetHostViewQt::SetWantsAnimateOnlyBeginFrames() viz::SurfaceId RenderWidgetHostViewQt::GetCurrentSurfaceId() const { + if (m_enableViz) + return m_delegatedFrameHost->GetCurrentSurfaceId(); return viz::SurfaceId(); } const viz::FrameSinkId &RenderWidgetHostViewQt::GetFrameSinkId() const { + if (m_enableViz) + return m_delegatedFrameHost->frame_sink_id(); return m_frameSinkId; } const viz::LocalSurfaceIdAllocation &RenderWidgetHostViewQt::GetLocalSurfaceIdAllocation() const { - return m_localSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation(); + return m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation(); } void RenderWidgetHostViewQt::TakeFallbackContentFrom(content::RenderWidgetHostView *view) { DCHECK(!static_cast(view)->IsRenderWidgetHostViewChildFrame()); DCHECK(!static_cast(view)->IsRenderWidgetHostViewGuest()); - base::Optional color = view->GetBackgroundColor(); + RenderWidgetHostViewQt *viewQt = static_cast(view); + base::Optional color = viewQt->GetBackgroundColor(); if (color) SetBackgroundColor(*color); + if (m_enableViz) { + m_delegatedFrameHost->TakeFallbackContentFrom(viewQt->m_delegatedFrameHost.get()); + host()->GetContentRenderingTimeoutFrom(viewQt->host()); + } } void RenderWidgetHostViewQt::EnsureSurfaceSynchronizedForWebTest() @@ -1750,9 +1850,24 @@ void RenderWidgetHostViewQt::OnRenderFrameMetadataChangedAfterActivation() void RenderWidgetHostViewQt::synchronizeVisualProperties(const base::Optional &childSurfaceId) { if (childSurfaceId) - m_localSurfaceIdAllocator.UpdateFromChild(*childSurfaceId); + m_dfhLocalSurfaceIdAllocator.UpdateFromChild(*childSurfaceId); else - m_localSurfaceIdAllocator.GenerateId(); + m_dfhLocalSurfaceIdAllocator.GenerateId(); + + if (m_enableViz) { + gfx::Size viewSizeInDips = GetRequestedRendererSize(); + gfx::Size viewSizeInPixels = GetCompositorViewportPixelSize(); + m_rootLayer->SetBounds(gfx::Rect(gfx::Point(), viewSizeInPixels)); + m_uiCompositorLocalSurfaceIdAllocator.GenerateId(); + m_uiCompositor->SetScaleAndSize( + m_screenInfo.device_scale_factor, + viewSizeInPixels, + m_uiCompositorLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation()); + m_delegatedFrameHost->EmbedSurface( + m_dfhLocalSurfaceIdAllocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id(), + viewSizeInDips, + cc::DeadlinePolicy::UseDefaultDeadline()); + } host()->SynchronizeVisualProperties(); } diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 50a430d84..5935f477a 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -40,10 +40,11 @@ #ifndef RENDER_WIDGET_HOST_VIEW_QT_H #define RENDER_WIDGET_HOST_VIEW_QT_H +#include "compositor/display_frame_sink.h" +#include "delegated_frame_host_client_qt.h" #include "render_widget_host_view_qt_delegate.h" #include "base/memory/weak_ptr.h" -#include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/resources/transferable_resource.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "components/viz/host/host_frame_sink_client.h" @@ -53,7 +54,7 @@ #include "content/browser/renderer_host/text_input_manager.h" #include "gpu/ipc/common/gpu_messages.h" #include "ui/events/gesture_detection/filtered_gesture_provider.h" -#include "qtwebenginecoreglobal_p.h" + #include #include #include @@ -104,6 +105,7 @@ class RenderWidgetHostViewQt , public RenderWidgetHostViewQtDelegateClient , public base::SupportsWeakPtr , public content::TextInputManager::Observer + , public DisplayConsumer { public: enum LoadVisuallyCommittedState { @@ -222,6 +224,9 @@ public: // Overridden from content::RenderFrameMetadataProvider::Observer void OnRenderFrameMetadataChangedAfterActivation() override; + // Overridden from DisplayConsumer + void scheduleUpdate() override; + gfx::SizeF lastContentsSize() const { return m_lastContentsSize; } gfx::Vector2dF lastScrollOffset() const { return m_lastScrollOffset; } @@ -231,6 +236,8 @@ public: ui::TextInputType getTextInputType() const; private: + friend class DelegatedFrameHostClientQt; + void processMotionEvent(const ui::MotionEvent &motionEvent); void clearPreviousTouchMotionState(); QList mapTouchPointIds(const QList &inputPoints); @@ -250,6 +257,8 @@ private: gfx::Rect m_windowRectInDips; content::ScreenInfo m_screenInfo; + scoped_refptr m_taskRunner; + ui::FilteredGestureProvider m_gestureProvider; base::TimeDelta m_eventsToNowDelta; bool m_sendMotionActionDown; @@ -258,6 +267,13 @@ private: QList m_previousTouchPoints; std::unique_ptr m_delegate; + const bool m_enableViz; + bool m_visible; + DelegatedFrameHostClientQt m_delegatedFrameHostClient{this}; + std::unique_ptr m_delegatedFrameHost; + std::unique_ptr m_rootLayer; + std::unique_ptr m_uiCompositor; + scoped_refptr m_displayFrameSink; std::unique_ptr m_compositor; LoadVisuallyCommittedState m_loadVisuallyCommittedState; @@ -271,7 +287,8 @@ private: gfx::Vector2dF m_lastScrollOffset; gfx::SizeF m_lastContentsSize; - viz::ParentLocalSurfaceIdAllocator m_localSurfaceIdAllocator; + viz::ParentLocalSurfaceIdAllocator m_dfhLocalSurfaceIdAllocator; + viz::ParentLocalSurfaceIdAllocator m_uiCompositorLocalSurfaceIdAllocator; uint m_imState; int m_anchorPositionWithinSelection; @@ -293,6 +310,8 @@ private: std::unique_ptr m_touchSelectionController; gfx::SelectionBound m_selectionStart; gfx::SelectionBound m_selectionEnd; + + base::WeakPtrFactory m_weakPtrFactory{this}; }; } // namespace QtWebEngineCore diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index a988040ee..a42565c2b 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -488,6 +488,16 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext); #endif + bool threadedGpu = true; +#ifndef QT_NO_OPENGL + threadedGpu = QOpenGLContext::supportsThreadedOpenGL(); +#endif + + bool enableViz = ((threadedGpu && !parsedCommandLine->HasSwitch("disable-viz-display-compositor")) + || parsedCommandLine->HasSwitch("enable-viz-display-compositor")); + parsedCommandLine->RemoveSwitch("disable-viz-display-compositor"); + parsedCommandLine->RemoveSwitch("enable-viz-display-compositor"); + std::string disableFeatures; std::string enableFeatures; // Needed to allow navigations within pages that were set using setHtml(). One example is @@ -495,10 +505,6 @@ WebEngineContext::WebEngineContext() // This is deprecated behavior, and will be removed in a future Chromium version, as per // upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422. appendToFeatureList(enableFeatures, features::kAllowContentInitiatedDataUrlNavigations.name); - // Surface synchronization breaks our current graphics integration (since 65) - appendToFeatureList(disableFeatures, features::kEnableSurfaceSynchronization.name); - // Viz Display Compositor is enabled by default since 73. Doesn't work for us (also implies SurfaceSynchronization) - appendToFeatureList(disableFeatures, features::kVizDisplayCompositor.name); // The video-capture service is not functioning at this moment (since 69) appendToFeatureList(disableFeatures, features::kMojoVideoCapture.name); // Breaks WebEngineNewViewRequest.userInitiated API (since 73) @@ -506,8 +512,6 @@ WebEngineContext::WebEngineContext() // We do not yet support the network-service, but it is enabled by default since 75. appendToFeatureList(disableFeatures, network::features::kNetworkService.name); - // VideoSurfaceLayer is enabled by default since 75. We don't support it. - appendToFeatureList(disableFeatures, media::kUseSurfaceLayerForVideo.name); // BlinkGenPropertyTrees is enabled by default in 75, but causes regressions. appendToFeatureList(disableFeatures, blink::features::kBlinkGenPropertyTrees.name); @@ -531,6 +535,15 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing); } + if (!enableViz) { + // Surface synchronization breaks our current graphics integration (since 65) + appendToFeatureList(disableFeatures, features::kEnableSurfaceSynchronization.name); + // Viz Display Compositor is enabled by default since 73. Doesn't work for us (also implies SurfaceSynchronization) + appendToFeatureList(disableFeatures, features::kVizDisplayCompositor.name); + // VideoSurfaceLayer is enabled by default since 75. We don't support it. + appendToFeatureList(disableFeatures, media::kUseSurfaceLayerForVideo.name); + } + appendToFeatureSwitch(parsedCommandLine, switches::kDisableFeatures, disableFeatures); appendToFeatureSwitch(parsedCommandLine, switches::kEnableFeatures, enableFeatures); base::FeatureList::InitializeInstance( @@ -619,10 +632,6 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kDisableGpu); } - bool threadedGpu = true; -#ifndef QT_NO_OPENGL - threadedGpu = QOpenGLContext::supportsThreadedOpenGL(); -#endif registerMainThreadFactories(threadedGpu); SetContentClient(new ContentClientQt); -- cgit v1.2.1 From 55a4c28542c6dc9e4a4edc0aab7043feef2ab0d2 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Thu, 11 Jul 2019 13:15:39 +0200 Subject: Refactor findText handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move most of the findText logic to the QtWebEngineCore::FindTextHelper class. This change also separates findText callbacks in the new class for getting rid of the request ID conversion and make it easier to remove them in Qt6. Task-number: QTBUG-50420 Change-Id: I348cedd0f90a49f9b360165c46319aeed2c236c0 Reviewed-by: Jüri Valdmann --- src/core/core_chromium.pri | 2 + src/core/find_text_helper.cpp | 165 +++++++++++++++++++++ src/core/find_text_helper.h | 99 +++++++++++++ src/core/web_contents_adapter.cpp | 50 +------ src/core/web_contents_adapter.h | 5 +- src/core/web_contents_adapter_client.h | 1 - src/core/web_contents_delegate_qt.cpp | 19 +-- src/core/web_contents_delegate_qt.h | 9 +- src/webengine/api/qquickwebengineview.cpp | 28 +--- src/webengine/api/qquickwebengineview_p_p.h | 1 - src/webenginewidgets/api/qwebenginepage.cpp | 22 +-- src/webenginewidgets/api/qwebenginepage_p.h | 1 - .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 23 +++ 13 files changed, 319 insertions(+), 106 deletions(-) create mode 100644 src/core/find_text_helper.cpp create mode 100644 src/core/find_text_helper.h diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index bc39f8e15..810ec9a0f 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -73,6 +73,7 @@ SOURCES = \ download_manager_delegate_qt.cpp \ favicon_manager.cpp \ file_picker_controller.cpp \ + find_text_helper.cpp \ javascript_dialog_controller.cpp \ javascript_dialog_manager_qt.cpp \ login_delegate_qt.cpp \ @@ -180,6 +181,7 @@ HEADERS = \ download_manager_delegate_qt.h \ favicon_manager.h \ file_picker_controller.h \ + find_text_helper.h \ global_descriptors_qt.h \ javascript_dialog_controller_p.h \ javascript_dialog_controller.h \ diff --git a/src/core/find_text_helper.cpp b/src/core/find_text_helper.cpp new file mode 100644 index 000000000..5fb56dacc --- /dev/null +++ b/src/core/find_text_helper.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "find_text_helper.h" +#include "type_conversion.h" + +#include "content/public/browser/web_contents.h" +#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" + +namespace QtWebEngineCore { + +// static +int FindTextHelper::m_findRequestIdCounter = -1; + +FindTextHelper::FindTextHelper(content::WebContents *webContents) + : m_webContents(webContents) + , m_currentFindRequestId(m_findRequestIdCounter++) + , m_lastCompletedFindRequestId(m_currentFindRequestId) +{ +} + +FindTextHelper::~FindTextHelper() +{ + if (isFindTextInProgress()) + stopFinding(); +} + +void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QWebEngineCallback resultCallback) +{ + if (findText.isEmpty()) { + stopFinding(); + m_widgetCallbacks.invokeEmpty(resultCallback); + return; + } + + startFinding(findText, caseSensitively, findBackward); + m_widgetCallbacks.registerCallback(m_currentFindRequestId, resultCallback); +} + +void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QJSValue &resultCallback) +{ + if (findText.isEmpty()) { + stopFinding(); + if (!resultCallback.isUndefined()) { + QJSValueList args; + args.append(QJSValue(0)); + const_cast(resultCallback).call(args); + } + return; + } + + startFinding(findText, caseSensitively, findBackward); + if (!resultCallback.isUndefined()) + m_quickCallbacks.insert(m_currentFindRequestId, resultCallback); +} + +void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, bool findBackward) +{ + if (findText.isEmpty()) { + stopFinding(); + return; + } + + if (m_currentFindRequestId > m_lastCompletedFindRequestId) { + // There are cases where the render process will overwrite a previous request + // with the new search and we'll have a dangling callback, leaving the application + // waiting for it forever. + // Assume that any unfinished find has been unsuccessful when a new one is started + // to cover that case. + invokeResultCallback(m_currentFindRequestId, 0); + } + + blink::mojom::FindOptionsPtr options = blink::mojom::FindOptions::New(); + options->forward = !findBackward; + options->match_case = caseSensitively; + options->find_next = findText == m_previousFindText; + m_previousFindText = findText; + + m_currentFindRequestId = m_findRequestIdCounter++; + m_webContents->Find(m_currentFindRequestId, toString16(findText), std::move(options)); +} + +void FindTextHelper::stopFinding() +{ + m_lastCompletedFindRequestId = m_currentFindRequestId; + m_previousFindText = QString(); + m_webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION); +} + +bool FindTextHelper::isFindTextInProgress() const +{ + return m_currentFindRequestId != m_lastCompletedFindRequestId; +} + +void FindTextHelper::handleFindReply(content::WebContents *source, int requestId, int numberOfMatches, + const gfx::Rect &selectionRect, int activeMatchOrdinal, bool finalUpdate) +{ + Q_UNUSED(selectionRect); + Q_UNUSED(activeMatchOrdinal); + + Q_ASSERT(source == m_webContents); + + if (!finalUpdate || requestId <= m_lastCompletedFindRequestId) + return; + + Q_ASSERT(m_currentFindRequestId == requestId); + m_lastCompletedFindRequestId = requestId; + invokeResultCallback(requestId, numberOfMatches); +} + +void FindTextHelper::handleLoadCommitted() +{ + // Make sure that we don't set the findNext WebFindOptions on a new frame. + m_previousFindText = QString(); +} + +void FindTextHelper::invokeResultCallback(int requestId, int numberOfMatches) +{ + if (m_quickCallbacks.contains(requestId)) { + QJSValue resultCallback = m_quickCallbacks.take(requestId); + QJSValueList args; + args.append(QJSValue(numberOfMatches)); + resultCallback.call(args); + } else { + m_widgetCallbacks.invoke(requestId, numberOfMatches > 0); + } +} + +} // namespace QtWebEngineCore diff --git a/src/core/find_text_helper.h b/src/core/find_text_helper.h new file mode 100644 index 000000000..17e76ecc7 --- /dev/null +++ b/src/core/find_text_helper.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// 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. +// + +#ifndef FIND_TEXT_HELPER_H +#define FIND_TEXT_HELPER_H + +#include "qtwebenginecoreglobal_p.h" + +#include "qwebenginecallback_p.h" +#include + +namespace content { +class WebContents; +} + +namespace gfx { +class Rect; +} + +namespace QtWebEngineCore { + +class Q_WEBENGINECORE_PRIVATE_EXPORT FindTextHelper { +public: + FindTextHelper(content::WebContents *webContents); + ~FindTextHelper(); + + void startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QWebEngineCallback resultCallback); + void startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QJSValue &resultCallback); + void startFinding(const QString &findText, bool caseSensitively, bool findBackward); + void stopFinding(); + bool isFindTextInProgress() const; + void handleFindReply(content::WebContents *source, int requestId, int numberOfMatches, const gfx::Rect &selectionRect, int activeMatchOrdinal, bool finalUpdate); + void handleLoadCommitted(); + +private: + void invokeResultCallback(int requestId, int numberOfMatches); + + content::WebContents *m_webContents; + + static int m_findRequestIdCounter; + int m_currentFindRequestId; + int m_lastCompletedFindRequestId; + + QString m_previousFindText; + + QMap m_quickCallbacks; + CallbackDirectory m_widgetCallbacks; +}; + +} // namespace QtWebEngineCore + +#endif // FIND_TEXT_HELPER_H diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 2831ec159..85e63c5a4 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -86,7 +86,6 @@ #include "content/public/common/web_preferences.h" #include "content/public/common/webrtc_ip_handling_policy.h" #include "extensions/buildflags/buildflags.h" -#include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" #include "third_party/blink/public/web/web_media_player_action.h" #include "printing/buildflags/buildflags.h" #include "ui/base/clipboard/clipboard.h" @@ -416,7 +415,6 @@ WebContentsAdapter::WebContentsAdapter() #endif , m_adapterClient(nullptr) , m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) - , m_lastFindRequestId(0) , m_currentDropAction(blink::kWebDragOperationNone) , m_devToolsFrontend(nullptr) { @@ -433,7 +431,6 @@ WebContentsAdapter::WebContentsAdapter(std::unique_ptr web #endif , m_adapterClient(nullptr) , m_nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) - , m_lastFindRequestId(0) , m_currentDropAction(blink::kWebDragOperationNone) , m_devToolsFrontend(nullptr) { @@ -1046,41 +1043,6 @@ quint64 WebContentsAdapter::fetchDocumentInnerText() return m_nextRequestId++; } -quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitively, bool findBackward) -{ - CHECK_INITIALIZED(0); - if (m_lastFindRequestId > m_webContentsDelegate->lastReceivedFindReply()) { - // There are cases where the render process will overwrite a previous request - // with the new search and we'll have a dangling callback, leaving the application - // waiting for it forever. - // Assume that any unfinished find has been unsuccessful when a new one is started - // to cover that case. - m_webContentsDelegate->setLastReceivedFindReply(m_lastFindRequestId); - m_adapterClient->didFindText(m_lastFindRequestId, 0); - } - - blink::mojom::FindOptionsPtr options = blink::mojom::FindOptions::New(); - options->forward = !findBackward; - options->match_case = caseSensitively; - options->find_next = subString == m_webContentsDelegate->lastSearchedString(); - m_webContentsDelegate->setLastSearchedString(subString); - - // Find already allows a request ID as input, but only as an int. - // Use the same counter but mod it to MAX_INT, this keeps the same likeliness of request ID clashing. - int shrunkRequestId = m_nextRequestId++ & 0x7fffffff; - m_webContents->Find(shrunkRequestId, toString16(subString), std::move(options)); - m_lastFindRequestId = shrunkRequestId; - return shrunkRequestId; -} - -void WebContentsAdapter::stopFinding() -{ - CHECK_INITIALIZED(); - m_webContentsDelegate->setLastReceivedFindReply(m_lastFindRequestId); - m_webContentsDelegate->setLastSearchedString(QString()); - m_webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION); -} - void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & webPreferences) { CHECK_INITIALIZED(); @@ -1696,12 +1658,6 @@ void WebContentsAdapter::focusIfNecessary() m_webContents->Focus(); } -bool WebContentsAdapter::isFindTextInProgress() const -{ - CHECK_INITIALIZED(false); - return m_lastFindRequestId != m_webContentsDelegate->lastReceivedFindReply(); -} - bool WebContentsAdapter::hasFocusedFrame() const { CHECK_INITIALIZED(false); @@ -1745,6 +1701,12 @@ FaviconManager *WebContentsAdapter::faviconManager() return m_webContentsDelegate->faviconManager(); } +FindTextHelper *WebContentsAdapter::findTextHelper() +{ + CHECK_INITIALIZED(nullptr); + return m_webContentsDelegate->findTextHelper(); +} + void WebContentsAdapter::viewSource() { CHECK_INITIALIZED(); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index baf9d241c..11f8f9cb1 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -85,6 +85,7 @@ namespace QtWebEngineCore { class DevToolsFrontendQt; class FaviconManager; +class FindTextHelper; class MessagePassingInterface; class ProfileQt; class RenderViewObserverHostQt; @@ -158,8 +159,6 @@ public: quint64 runJavaScriptCallbackResult(const QString &javaScript, quint32 worldId); quint64 fetchDocumentMarkup(); quint64 fetchDocumentInnerText(); - quint64 findText(const QString &subString, bool caseSensitively, bool findBackward); - void stopFinding(); void updateWebPreferences(const content::WebPreferences &webPreferences); void download(const QUrl &url, const QString &suggestedFileName, const QUrl &referrerUrl = QUrl(), @@ -205,6 +204,7 @@ public: void setWebChannel(QWebChannel *, uint worldId); #endif FaviconManager *faviconManager(); + FindTextHelper *findTextHelper(); QPointF lastScrollOffset() const; QSizeF lastContentsSize() const; @@ -263,7 +263,6 @@ private: #endif WebContentsAdapterClient *m_adapterClient; quint64 m_nextRequestId; - int m_lastFindRequestId; std::unique_ptr m_currentDropData; uint m_currentDropAction; bool m_updateDragActionCalled; diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index d53568215..4743c1ed7 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -461,7 +461,6 @@ public: virtual void didRunJavaScript(quint64 requestId, const QVariant& result) = 0; virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0; virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0; - virtual void didFindText(quint64 requestId, int matchCount) = 0; virtual void didPrintPage(quint64 requestId, QSharedPointer) = 0; virtual void didPrintPageToPdf(const QString &filePath, bool success) = 0; virtual bool passOnFocus(bool reverse) = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index f4812f9db..e3015d5f6 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -102,8 +102,8 @@ static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptCo WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient) : m_viewClient(adapterClient) - , m_lastReceivedFindReply(0) , m_faviconManager(new FaviconManager(webContents, adapterClient)) + , m_findTextHelper(new FindTextHelper(webContents)) , m_lastLoadProgress(-1) , m_loadingState(determineLoadingState(webContents)) , m_didStartLoadingSeen(m_loadingState == LoadingState::Loading) @@ -350,9 +350,7 @@ void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool void WebContentsDelegateQt::EmitLoadCommitted() { - // Make sure that we don't set the findNext WebFindOptions on a new frame. - m_lastSearchedString = QString(); - + m_findTextHelper->handleLoadCommitted(); m_viewClient->loadCommitted(); m_viewClient->updateNavigationActions(); } @@ -577,13 +575,7 @@ bool WebContentsDelegateQt::DidAddMessageToConsole(content::WebContents *source, void WebContentsDelegateQt::FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) { - Q_UNUSED(source) - Q_UNUSED(selection_rect) - Q_UNUSED(active_match_ordinal) - if (final_update && request_id > m_lastReceivedFindReply) { - m_lastReceivedFindReply = request_id; - m_viewClient->didFindText(request_id, number_of_matches); - } + m_findTextHelper->handleFindReply(source, request_id, number_of_matches, selection_rect, active_match_ordinal, final_update); } void WebContentsDelegateQt::RequestMediaAccessPermission(content::WebContents *web_contents, const content::MediaStreamRequest &request, content::MediaResponseCallback callback) @@ -792,6 +784,11 @@ FaviconManager *WebContentsDelegateQt::faviconManager() return m_faviconManager.data(); } +FindTextHelper *WebContentsDelegateQt::findTextHelper() +{ + return m_findTextHelper.data(); +} + WebEngineSettings *WebContentsDelegateQt::webEngineSettings() const { return m_viewClient->webEngineSettings(); } diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 00b715c30..f1d5ed76c 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -50,6 +50,7 @@ #include "color_chooser_controller.h" #include "favicon_manager.h" +#include "find_text_helper.h" #include "javascript_dialog_manager_qt.h" #include @@ -112,10 +113,6 @@ class WebContentsDelegateQt : public content::WebContentsDelegate public: WebContentsDelegateQt(content::WebContents*, WebContentsAdapterClient *adapterClient); ~WebContentsDelegateQt(); - QString lastSearchedString() const { return m_lastSearchedString; } - void setLastSearchedString(const QString &s) { m_lastSearchedString = s; } - int lastReceivedFindReply() const { return m_lastReceivedFindReply; } - void setLastReceivedFindReply(int id) { m_lastReceivedFindReply = id; } QUrl url() const { return m_url; } QString title() const { return m_title; } @@ -178,6 +175,7 @@ public: void requestUserNotificationPermission(const QUrl &requestingOrigin); void launchExternalURL(const QUrl &url, ui::PageTransition page_transition, bool is_main_frame, bool has_user_gesture); FaviconManager *faviconManager(); + FindTextHelper *findTextHelper(); void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; } const SavePageInfo &savePageInfo() { return m_savePageInfo; } @@ -213,10 +211,9 @@ private: int &streamCount(blink::MediaStreamType type); WebContentsAdapterClient *m_viewClient; - QString m_lastSearchedString; - int m_lastReceivedFindReply; QVector m_loadingErrorFrameList; QScopedPointer m_faviconManager; + QScopedPointer m_findTextHelper; SavePageInfo m_savePageInfo; QSharedPointer m_filePickerController; QUrl m_initialTargetUrl; diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 30283dc03..f340ebd33 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -43,6 +43,7 @@ #include "profile_adapter.h" #include "certificate_error_controller.h" #include "file_picker_controller.h" +#include "find_text_helper.h" #include "javascript_dialog_controller.h" #include "touch_selection_menu_controller.h" @@ -164,7 +165,6 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate() { Q_ASSERT(m_profileInitialized); m_profile->d_ptr->removeWebContentsAdapterClient(this); - adapter->stopFinding(); if (faviconProvider) faviconProvider->detach(q_ptr); // q_ptr->d_ptr might be null due to destroy() @@ -273,8 +273,8 @@ void QQuickWebEngineViewPrivate::navigationRequested(int navigationType, const Q Q_EMIT q->navigationRequested(&navigationRequest); navigationRequestAction = navigationRequest.action(); - if ((navigationRequestAction == WebContentsAdapterClient::AcceptRequest) && adapter->isFindTextInProgress()) - adapter->stopFinding(); + if ((navigationRequestAction == WebContentsAdapterClient::AcceptRequest) && adapter->findTextHelper()->isFindTextInProgress()) + adapter->findTextHelper()->stopFinding(); } void QQuickWebEngineViewPrivate::javascriptDialog(QSharedPointer dialog) @@ -1185,14 +1185,6 @@ void QQuickWebEngineViewPrivate::didRunJavaScript(quint64 requestId, const QVari callback.call(args); } -void QQuickWebEngineViewPrivate::didFindText(quint64 requestId, int matchCount) -{ - QJSValue callback = m_callbacks.take(requestId); - QJSValueList args; - args.append(QJSValue(matchCount)); - callback.call(args); -} - void QQuickWebEngineViewPrivate::didPrintPage(quint64 requestId, QSharedPointer result) { Q_Q(QQuickWebEngineView); @@ -1464,18 +1456,8 @@ void QQuickWebEngineView::findText(const QString &subString, FindFlags options, Q_D(QQuickWebEngineView); if (!d->adapter->isInitialized()) return; - if (subString.isEmpty()) { - d->adapter->stopFinding(); - if (!callback.isUndefined()) { - QJSValueList args; - args.append(QJSValue(0)); - const_cast(callback).call(args); - } - } else { - quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward); - if (!callback.isUndefined()) - d->m_callbacks.insert(requestId, callback); - } + + d->adapter->findTextHelper()->startFinding(subString, options & FindCaseSensitively, options & FindBackward, callback); } QQuickWebEngineHistory *QQuickWebEngineView::navigationHistory() const diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index e0f2595ec..7a1916d82 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -133,7 +133,6 @@ public: void didRunJavaScript(quint64, const QVariant&) override; void didFetchDocumentMarkup(quint64, const QString&) override { } void didFetchDocumentInnerText(quint64, const QString&) override { } - void didFindText(quint64, int) override; void didPrintPage(quint64 requestId, QSharedPointer) override; void didPrintPageToPdf(const QString &filePath, bool success) override; bool passOnFocus(bool reverse) override; diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index e990170eb..29566f021 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -45,6 +45,7 @@ #include "certificate_error_controller.h" #include "color_chooser_controller.h" #include "favicon_manager.h" +#include "find_text_helper.h" #include "file_picker_controller.h" #include "javascript_dialog_controller.h" #if QT_CONFIG(webengine_printing_and_pdf) @@ -420,11 +421,6 @@ void QWebEnginePagePrivate::didFetchDocumentInnerText(quint64 requestId, const Q m_callbacks.invoke(requestId, result); } -void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount) -{ - m_callbacks.invoke(requestId, matchCount > 0); -} - void QWebEnginePagePrivate::didPrintPage(quint64 requestId, QSharedPointer result) { #if QT_CONFIG(webengine_printing_and_pdf) @@ -963,7 +959,6 @@ QWebEnginePage::~QWebEnginePage() if (d_ptr) { // d_ptr might be exceptionally null if profile adapter got deleted first setDevToolsPage(nullptr); - d_ptr->adapter->stopFinding(); QWebEnginePagePrivate::bindPageAndView(this, nullptr); QWebEnginePagePrivate::bindPageAndWidget(this, nullptr); } @@ -1592,16 +1587,11 @@ void QWebEnginePage::findText(const QString &subString, FindFlags options, const { Q_D(QWebEnginePage); if (!d->adapter->isInitialized()) { - d->m_callbacks.invokeEmpty(resultCallback); + QtWebEngineCore::CallbackDirectory().invokeEmpty(resultCallback); return; } - if (subString.isEmpty()) { - d->adapter->stopFinding(); - d->m_callbacks.invokeEmpty(resultCallback); - } else { - quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward); - d->m_callbacks.registerCallback(requestId, resultCallback); - } + + d->adapter->findTextHelper()->startFinding(subString, options & FindCaseSensitively, options & FindBackward, resultCallback); } /*! @@ -1652,8 +1642,8 @@ void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl & { Q_Q(QWebEnginePage); bool accepted = q->acceptNavigationRequest(url, static_cast(navigationType), isMainFrame); - if (accepted && adapter->isFindTextInProgress()) - adapter->stopFinding(); + if (accepted && adapter->findTextHelper()->isFindTextInProgress()) + adapter->findTextHelper()->stopFinding(); navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest; } diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index acf95a265..a8cde8199 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -127,7 +127,6 @@ public: void didRunJavaScript(quint64 requestId, const QVariant& result) override; void didFetchDocumentMarkup(quint64 requestId, const QString& result) override; void didFetchDocumentInnerText(quint64 requestId, const QString& result) override; - void didFindText(quint64 requestId, int matchCount) override; void didPrintPage(quint64 requestId, QSharedPointer result) override; void didPrintPageToPdf(const QString &filePath, bool success) override; bool passOnFocus(bool reverse) override; diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 713feca6d..7e9815298 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -127,6 +127,7 @@ private Q_SLOTS: void findText(); void findTextResult(); void findTextSuccessiveShouldCallAllCallbacks(); + void findTextCalledOnMatch(); void deleteQWebEngineViewTwice(); void loadSignalsOrder_data(); void loadSignalsOrder(); @@ -1024,6 +1025,28 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks() QVERIFY(spy5.wasCalled()); } +void tst_QWebEnginePage::findTextCalledOnMatch() +{ + QSignalSpy loadSpy(m_view->page(), &QWebEnginePage::loadFinished); + + // findText will abort in blink if the view has an empty size. + m_view->resize(800, 600); + m_view->show(); + m_view->setHtml(QString("
foo bar
")); + QTRY_COMPARE(loadSpy.count(), 1); + + bool callbackCalled = false; + m_view->page()->findText("foo", 0, [this, &callbackCalled](bool found) { + QVERIFY(found); + + m_view->page()->findText("bar", 0, [&callbackCalled](bool found) { + QVERIFY(found); + callbackCalled = true; + }); + }); + QTRY_VERIFY(callbackCalled); +} + static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows) { const auto tlws = QGuiApplication::topLevelWindows(); -- cgit v1.2.1 From a6abc01319798e2175914323273e91927516eba0 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Fri, 12 Jul 2019 13:39:06 +0200 Subject: Introduce findTextFinished signal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a replacement for the callbacks. Also introduces QWebEngineFindTextResult class what is common for the Quick and Widget APIs. This makes possible to provide extra information about the match, eg. the number of matches and the index of the currently highlighted match. [ChangeLog][QtWebEngine][WebEngineView] Introduces findTextFinished signal and FindTextResult type to provide extra information about the result of a text search. [ChangeLog][QtWebEngineWidgets][QWebEnginePage] Introduces findTextFinished signal and QWebEngineFindTextResult class to provide extra information about the result of a text search. Task-number: QTBUG-50420 Change-Id: Icb9737d2f596e6bc0fc5733144eeeaf2a77aab02 Reviewed-by: Jüri Valdmann --- .../webengine/quicknanobrowser/BrowserWindow.qml | 59 ++++++++- examples/webengine/quicknanobrowser/FindBar.qml | 146 +++++++++++++++++++++ .../quicknanobrowser/quicknanobrowser.pro | 1 + examples/webengine/quicknanobrowser/resources.qrc | 1 + .../simplebrowser/browserwindow.cpp | 18 ++- .../webenginewidgets/simplebrowser/browserwindow.h | 1 + .../webenginewidgets/simplebrowser/tabwidget.cpp | 4 + .../webenginewidgets/simplebrowser/tabwidget.h | 1 + src/core/api/core_api.pro | 2 + src/core/api/qwebenginefindtextresult.cpp | 116 ++++++++++++++++ src/core/api/qwebenginefindtextresult.h | 81 ++++++++++++ src/core/find_text_helper.cpp | 10 +- src/core/find_text_helper.h | 5 +- src/core/web_contents_adapter_client.h | 2 + src/core/web_contents_delegate_qt.cpp | 2 +- src/webengine/api/qquickwebengineview.cpp | 7 + src/webengine/api/qquickwebengineview_p.h | 2 + src/webengine/api/qquickwebengineview_p_p.h | 2 + src/webengine/doc/src/webengineview_lgpl.qdoc | 43 ++++++ src/webengine/plugin/plugin.cpp | 3 + src/webenginewidgets/api/qwebenginepage.cpp | 18 +++ src/webenginewidgets/api/qwebenginepage.h | 3 + src/webenginewidgets/api/qwebenginepage_p.h | 2 + .../doc/src/qwebenginepage_lgpl.qdoc | 3 + tests/auto/quick/publicapi/tst_publicapi.cpp | 5 + tests/auto/quick/qmltests/data/tst_findText.qml | 84 ++++++++++++ .../widgets/qwebenginepage/tst_qwebenginepage.cpp | 113 ++++++++++++++-- 27 files changed, 713 insertions(+), 21 deletions(-) create mode 100644 examples/webengine/quicknanobrowser/FindBar.qml create mode 100644 src/core/api/qwebenginefindtextresult.cpp create mode 100644 src/core/api/qwebenginefindtextresult.h diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml index 088b23e59..39a13df59 100644 --- a/examples/webengine/quicknanobrowser/BrowserWindow.qml +++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml @@ -57,7 +57,7 @@ import QtQuick.Controls.Styles 1.0 import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.0 import QtQuick.Window 2.1 -import QtWebEngine 1.10 +import QtWebEngine 1.11 ApplicationWindow { id: browserWindow @@ -73,6 +73,10 @@ ApplicationWindow { // Make sure the Qt.WindowFullscreenButtonHint is set on OS X. Component.onCompleted: flags = flags | Qt.WindowFullscreenButtonHint + onCurrentWebViewChanged: { + findBar.reset(); + } + // Create a styleItem to determine the platform. // When using style "mac", ToolButtons are not supposed to accept focus. QQCPrivate.StyleItem { id: styleItem } @@ -136,6 +140,9 @@ ApplicationWindow { fullScreenNotification.hide(); currentWebView.triggerWebAction(WebEngineView.ExitFullScreen); } + + if (findBar.visible) + findBar.visible = false; } } Action { @@ -187,6 +194,21 @@ ApplicationWindow { shortcut: StandardKey.Forward onTriggered: currentWebView.triggerWebAction(WebEngineView.Forward) } + Action { + shortcut: StandardKey.Find + onTriggered: { + if (!findBar.visible) + findBar.visible = true; + } + } + Action { + shortcut: StandardKey.FindNext + onTriggered: findBar.findNext() + } + Action { + shortcut: StandardKey.FindPrevious + onTriggered: findBar.findPrevious() + } toolBar: ToolBar { id: navigationBar @@ -553,6 +575,19 @@ ApplicationWindow { selection.certificates[0].select(); } + onFindTextFinished: function(result) { + if (!findBar.visible) + findBar.visible = true; + + findBar.numberOfMatches = result.numberOfMatches; + findBar.activeMatchOrdinal = result.activeMatchOrdinal; + } + + onLoadingChanged: function(loadRequest) { + if (loadRequest.status == WebEngineView.LoadStartedStatus) + findBar.reset(); + } + Timer { id: reloadTimer interval: 0 @@ -625,6 +660,28 @@ ApplicationWindow { download.accept(); } + FindBar { + id: findBar + visible: false + anchors.right: parent.right + anchors.rightMargin: 10 + anchors.top: parent.top + + onFindNext: { + if (text) + currentWebView && currentWebView.findText(text); + else if (!visible) + visible = true; + } + onFindPrevious: { + if (text) + currentWebView && currentWebView.findText(text, WebEngineView.FindBackward); + else if (!visible) + visible = true; + } + } + + Rectangle { id: statusBubble color: "oldlace" diff --git a/examples/webengine/quicknanobrowser/FindBar.qml b/examples/webengine/quicknanobrowser/FindBar.qml new file mode 100644 index 000000000..2d673592a --- /dev/null +++ b/examples/webengine/quicknanobrowser/FindBar.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.0 + +Rectangle { + id: root + + property int numberOfMatches: 0 + property int activeMatchOrdinal: 0 + property alias text: findTextField.text + + function reset() { + numberOfMatches = 0; + activeMatchOrdinal = 0; + visible = false; + } + + signal findNext() + signal findPrevious() + + width: 250 + height: 35 + radius: 2 + + border.width: 1 + border.color: "black" + color: "white" + + onVisibleChanged: { + if (visible) + findTextField.forceActiveFocus(); + } + + + RowLayout { + anchors.fill: parent + anchors.topMargin: 5 + anchors.bottomMargin: 5 + anchors.leftMargin: 10 + anchors.rightMargin: 10 + + spacing: 5 + + Rectangle { + Layout.fillWidth: true + Layout.fillHeight: true + + TextField { + id: findTextField + anchors.fill: parent + + style: TextFieldStyle { + background: Rectangle { + color: "transparent" + } + } + + onAccepted: root.findNext() + onTextChanged: root.findNext() + onActiveFocusChanged: activeFocus ? selectAll() : deselect() + } + } + + Label { + text: activeMatchOrdinal + "/" + numberOfMatches + visible: findTextField.text != "" + } + + Rectangle { + border.width: 1 + border.color: "#ddd" + width: 2 + height: parent.height + anchors.topMargin: 5 + anchors.bottomMargin: 5 + } + + ToolButton { + text: "<" + enabled: numberOfMatches > 0 + onClicked: root.findPrevious() + } + + ToolButton { + text: ">" + enabled: numberOfMatches > 0 + onClicked: root.findNext() + } + + ToolButton { + text: "x" + onClicked: root.visible = false + } + } +} diff --git a/examples/webengine/quicknanobrowser/quicknanobrowser.pro b/examples/webengine/quicknanobrowser/quicknanobrowser.pro index 5a27f5fd4..922cf79e2 100644 --- a/examples/webengine/quicknanobrowser/quicknanobrowser.pro +++ b/examples/webengine/quicknanobrowser/quicknanobrowser.pro @@ -10,6 +10,7 @@ OTHER_FILES += ApplicationRoot.qml \ BrowserDialog.qml \ BrowserWindow.qml \ DownloadView.qml \ + FindBar.qml \ FullScreenNotification.qml RESOURCES += resources.qrc diff --git a/examples/webengine/quicknanobrowser/resources.qrc b/examples/webengine/quicknanobrowser/resources.qrc index c6270897d..50ea05f5e 100644 --- a/examples/webengine/quicknanobrowser/resources.qrc +++ b/examples/webengine/quicknanobrowser/resources.qrc @@ -4,6 +4,7 @@ BrowserDialog.qml BrowserWindow.qml DownloadView.qml + FindBar.qml FullScreenNotification.qml diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp index 5d00cd19a..2bb9045b0 100644 --- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp +++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool forDevTools) @@ -129,6 +130,7 @@ BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool connect(m_urlLineEdit, &QLineEdit::returnPressed, [this]() { m_tabWidget->setUrl(QUrl::fromUserInput(m_urlLineEdit->text())); }); + connect(m_tabWidget, &TabWidget::findTextFinished, this, &BrowserWindow::handleFindTextFinished); QAction *focusUrlLineEditAction = new QAction(this); addAction(focusUrlLineEditAction); @@ -460,10 +462,7 @@ void BrowserWindow::handleFindActionTriggered() m_lastSearch, &ok); if (ok && !search.isEmpty()) { m_lastSearch = search; - currentTab()->findText(m_lastSearch, 0, [this](bool found) { - if (!found) - statusBar()->showMessage(tr("\"%1\" not found.").arg(m_lastSearch)); - }); + currentTab()->findText(m_lastSearch); } } @@ -526,3 +525,14 @@ void BrowserWindow::handleDevToolsRequested(QWebEnginePage *source) source->setDevToolsPage(m_browser->createDevToolsWindow()->currentTab()->page()); source->triggerAction(QWebEnginePage::InspectElement); } + +void BrowserWindow::handleFindTextFinished(const QWebEngineFindTextResult &result) +{ + if (result.numberOfMatches() == 0) { + statusBar()->showMessage(tr("\"%1\" not found.").arg(m_lastSearch)); + } else { + statusBar()->showMessage(tr("\"%1\" found: %2/%3").arg(m_lastSearch, + QString::number(result.activeMatchOrdinal()), + QString::number(result.numberOfMatches()))); + } +} diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.h b/examples/webenginewidgets/simplebrowser/browserwindow.h index 8f328b751..11a655469 100644 --- a/examples/webenginewidgets/simplebrowser/browserwindow.h +++ b/examples/webenginewidgets/simplebrowser/browserwindow.h @@ -88,6 +88,7 @@ private slots: void handleWebViewTitleChanged(const QString &title); void handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled); void handleDevToolsRequested(QWebEnginePage *source); + void handleFindTextFinished(const QWebEngineFindTextResult &result); private: QMenu *createFileMenu(TabWidget *tabWidget); diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp index 369bebfd9..3b6d84ebe 100644 --- a/examples/webenginewidgets/simplebrowser/tabwidget.cpp +++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp @@ -200,6 +200,10 @@ void TabWidget::setupView(WebView *webView) closeTab(index); }); connect(webView, &WebView::devToolsRequested, this, &TabWidget::devToolsRequested); + connect(webPage, &QWebEnginePage::findTextFinished, [this, webView](const QWebEngineFindTextResult &result) { + if (currentIndex() == indexOf(webView)) + emit findTextFinished(result); + }); } WebView *TabWidget::createTab() diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.h b/examples/webenginewidgets/simplebrowser/tabwidget.h index bf83781df..fba61d44f 100644 --- a/examples/webenginewidgets/simplebrowser/tabwidget.h +++ b/examples/webenginewidgets/simplebrowser/tabwidget.h @@ -78,6 +78,7 @@ signals: void favIconChanged(const QIcon &icon); void webActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled); void devToolsRequested(QWebEnginePage *source); + void findTextFinished(const QWebEngineFindTextResult &result); public slots: // current tab/page slots diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro index 326d4481f..5e8b8387e 100644 --- a/src/core/api/core_api.pro +++ b/src/core/api/core_api.pro @@ -37,6 +37,7 @@ HEADERS = \ qtwebenginecoreglobal_p.h \ qwebenginecookiestore.h \ qwebenginecookiestore_p.h \ + qwebenginefindtextresult.h \ qwebenginehttprequest.h \ qwebenginemessagepumpscheduler_p.h \ qwebenginenotification.h \ @@ -53,6 +54,7 @@ SOURCES = \ qtwebenginecoreglobal.cpp \ qwebengineclientcertificatestore.cpp \ qwebenginecookiestore.cpp \ + qwebenginefindtextresult.cpp \ qwebenginehttprequest.cpp \ qwebenginemessagepumpscheduler.cpp \ qwebenginenotification.cpp \ diff --git a/src/core/api/qwebenginefindtextresult.cpp b/src/core/api/qwebenginefindtextresult.cpp new file mode 100644 index 000000000..ce1be359e --- /dev/null +++ b/src/core/api/qwebenginefindtextresult.cpp @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwebenginefindtextresult.h" + +QT_BEGIN_NAMESPACE + +class QWebEngineFindTextResultPrivate : public QSharedData { +public: + int numberOfMatches = 0; + int activeMatchOrdinal = 0; +}; + +/*! + \class QWebEngineFindTextResult + \brief The QWebEngineFindTextResult class encapsulates the result of a string search on a page. + \since 5.14 + + \inmodule QtWebEngineCore + + Results are passed to the user in the + \l QWebEnginePage::findTextFinished() and + \l{WebEngineView::findTextFinished()}{WebEngineView.findTextFinished()} signals. +*/ + +/*! \internal +*/ +QWebEngineFindTextResult::QWebEngineFindTextResult() + : d(new QWebEngineFindTextResultPrivate) +{} + +/*! \internal +*/ +QWebEngineFindTextResult::QWebEngineFindTextResult(int numberOfMatches, int activeMatchOrdinal) + : d(new QWebEngineFindTextResultPrivate) +{ + d->numberOfMatches = numberOfMatches; + d->activeMatchOrdinal = activeMatchOrdinal; +} + +/*! \internal +*/ +QWebEngineFindTextResult::QWebEngineFindTextResult(const QWebEngineFindTextResult &other) + : d(other.d) +{} + +/*! \internal +*/ +QWebEngineFindTextResult &QWebEngineFindTextResult::operator=(const QWebEngineFindTextResult &other) +{ + d = other.d; + return *this; +} + +/*! \internal +*/ +QWebEngineFindTextResult::~QWebEngineFindTextResult() +{} + +/*! + \property QWebEngineFindTextResult::numberOfMatches + \brief The number of matches found. +*/ +int QWebEngineFindTextResult::numberOfMatches() const +{ + return d->numberOfMatches; +} + +/*! + \property QWebEngineFindTextResult::activeMatchOrdinal + \brief The index of the currently highlighted match. +*/ +int QWebEngineFindTextResult::activeMatchOrdinal() const +{ + return d->activeMatchOrdinal; +} + +QT_END_NAMESPACE + +#include "moc_qwebenginefindtextresult.cpp" diff --git a/src/core/api/qwebenginefindtextresult.h b/src/core/api/qwebenginefindtextresult.h new file mode 100644 index 000000000..073a8135f --- /dev/null +++ b/src/core/api/qwebenginefindtextresult.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINEFINDTEXTRESULT_H +#define QWEBENGINEFINDTEXTRESULT_H + +#include +#include +#include + +namespace QtWebEngineCore { +class FindTextHelper; +} + +QT_BEGIN_NAMESPACE + +class QWebEngineFindTextResultPrivate; + +class Q_WEBENGINECORE_EXPORT QWebEngineFindTextResult { + Q_GADGET + Q_PROPERTY(int numberOfMatches READ numberOfMatches CONSTANT FINAL) + Q_PROPERTY(int activeMatchOrdinal READ activeMatchOrdinal CONSTANT FINAL) + +public: + int numberOfMatches() const; + int activeMatchOrdinal() const; + + QWebEngineFindTextResult(); + QWebEngineFindTextResult(const QWebEngineFindTextResult &other); + QWebEngineFindTextResult &operator=(const QWebEngineFindTextResult &other); + ~QWebEngineFindTextResult(); + +private: + QWebEngineFindTextResult(int numberOfMatches, int activeMatchOrdinal); + + QSharedDataPointer d; + + friend class QtWebEngineCore::FindTextHelper; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QWebEngineFindTextResult) + +#endif // QWEBENGINEFINDTEXTRESULT_H diff --git a/src/core/find_text_helper.cpp b/src/core/find_text_helper.cpp index 5fb56dacc..effda529f 100644 --- a/src/core/find_text_helper.cpp +++ b/src/core/find_text_helper.cpp @@ -38,7 +38,9 @@ ****************************************************************************/ #include "find_text_helper.h" +#include "qwebenginefindtextresult.h" #include "type_conversion.h" +#include "web_contents_adapter_client.h" #include "content/public/browser/web_contents.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" @@ -48,8 +50,9 @@ namespace QtWebEngineCore { // static int FindTextHelper::m_findRequestIdCounter = -1; -FindTextHelper::FindTextHelper(content::WebContents *webContents) +FindTextHelper::FindTextHelper(content::WebContents *webContents, WebContentsAdapterClient *viewClient) : m_webContents(webContents) + , m_viewClient(viewClient) , m_currentFindRequestId(m_findRequestIdCounter++) , m_lastCompletedFindRequestId(m_currentFindRequestId) { @@ -65,6 +68,7 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, { if (findText.isEmpty()) { stopFinding(); + m_viewClient->findTextFinished(QWebEngineFindTextResult()); m_widgetCallbacks.invokeEmpty(resultCallback); return; } @@ -77,6 +81,7 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, { if (findText.isEmpty()) { stopFinding(); + m_viewClient->findTextFinished(QWebEngineFindTextResult()); if (!resultCallback.isUndefined()) { QJSValueList args; args.append(QJSValue(0)); @@ -103,6 +108,7 @@ void FindTextHelper::startFinding(const QString &findText, bool caseSensitively, // waiting for it forever. // Assume that any unfinished find has been unsuccessful when a new one is started // to cover that case. + m_viewClient->findTextFinished(QWebEngineFindTextResult()); invokeResultCallback(m_currentFindRequestId, 0); } @@ -132,7 +138,6 @@ void FindTextHelper::handleFindReply(content::WebContents *source, int requestId const gfx::Rect &selectionRect, int activeMatchOrdinal, bool finalUpdate) { Q_UNUSED(selectionRect); - Q_UNUSED(activeMatchOrdinal); Q_ASSERT(source == m_webContents); @@ -141,6 +146,7 @@ void FindTextHelper::handleFindReply(content::WebContents *source, int requestId Q_ASSERT(m_currentFindRequestId == requestId); m_lastCompletedFindRequestId = requestId; + m_viewClient->findTextFinished(QWebEngineFindTextResult(numberOfMatches, activeMatchOrdinal)); invokeResultCallback(requestId, numberOfMatches); } diff --git a/src/core/find_text_helper.h b/src/core/find_text_helper.h index 17e76ecc7..e8f186272 100644 --- a/src/core/find_text_helper.h +++ b/src/core/find_text_helper.h @@ -66,9 +66,11 @@ class Rect; namespace QtWebEngineCore { +class WebContentsAdapterClient; + class Q_WEBENGINECORE_PRIVATE_EXPORT FindTextHelper { public: - FindTextHelper(content::WebContents *webContents); + FindTextHelper(content::WebContents *webContents, WebContentsAdapterClient *viewClient); ~FindTextHelper(); void startFinding(const QString &findText, bool caseSensitively, bool findBackward, const QWebEngineCallback resultCallback); @@ -83,6 +85,7 @@ private: void invokeResultCallback(int requestId, int numberOfMatches); content::WebContents *m_webContents; + WebContentsAdapterClient *m_viewClient; static int m_findRequestIdCounter; int m_currentFindRequestId; diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 4743c1ed7..4bdb55b4c 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -64,6 +64,7 @@ QT_FORWARD_DECLARE_CLASS(CertificateErrorController) QT_FORWARD_DECLARE_CLASS(ClientCertSelectController) QT_FORWARD_DECLARE_CLASS(QKeyEvent) QT_FORWARD_DECLARE_CLASS(QVariant) +QT_FORWARD_DECLARE_CLASS(QWebEngineFindTextResult) QT_FORWARD_DECLARE_CLASS(QWebEngineQuotaRequest) QT_FORWARD_DECLARE_CLASS(QWebEngineRegisterProtocolHandlerRequest) QT_FORWARD_DECLARE_CLASS(QWebEngineUrlRequestInfo) @@ -498,6 +499,7 @@ public: virtual TouchHandleDrawableClient *createTouchHandle(const QMap &images) = 0; virtual void showTouchSelectionMenu(TouchSelectionMenuController *menuController, const QRect &bounds, const QSize &handleSize) = 0; virtual void hideTouchSelectionMenu() = 0; + virtual void findTextFinished(const QWebEngineFindTextResult &result) = 0; virtual ProfileAdapter *profileAdapter() = 0; virtual WebContentsAdapter* webContentsAdapter() = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index e3015d5f6..9855e3859 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -103,7 +103,7 @@ static WebContentsAdapterClient::JavaScriptConsoleMessageLevel mapToJavascriptCo WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient) : m_viewClient(adapterClient) , m_faviconManager(new FaviconManager(webContents, adapterClient)) - , m_findTextHelper(new FindTextHelper(webContents)) + , m_findTextHelper(new FindTextHelper(webContents, adapterClient)) , m_lastLoadProgress(-1) , m_loadingState(determineLoadingState(webContents)) , m_didStartLoadingSeen(m_loadingState == LoadingState::Loading) diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index f340ebd33..58d950cd9 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -62,6 +62,7 @@ #include "qquickwebenginesettings_p.h" #include "qquickwebenginescript_p.h" #include "qquickwebenginetouchhandleprovider_p_p.h" +#include "qwebenginefindtextresult.h" #include "qwebenginequotarequest.h" #include "qwebengineregisterprotocolhandlerrequest.h" @@ -699,6 +700,12 @@ void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegate *n bindViewAndWidget(q, static_cast(newWidgetBase)); } +void QQuickWebEngineViewPrivate::findTextFinished(const QWebEngineFindTextResult &result) +{ + Q_Q(QQuickWebEngineView); + Q_EMIT q->findTextFinished(result); +} + WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const { return m_settings->d_ptr.data(); diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index 3c8e1d9ec..4a88e3c28 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -79,6 +79,7 @@ class QQuickWebEngineSettings; class QQuickWebEngineTooltipRequest; class QQuickWebEngineFormValidationMessageRequest; class QQuickWebEngineViewPrivate; +class QWebEngineFindTextResult; class QWebEngineQuotaRequest; class QWebEngineRegisterProtocolHandlerRequest; @@ -574,6 +575,7 @@ Q_SIGNALS: Q_REVISION(10) void tooltipRequested(QQuickWebEngineTooltipRequest *request); Q_REVISION(11) void lifecycleStateChanged(LifecycleState state); Q_REVISION(11) void recommendedStateChanged(LifecycleState state); + Q_REVISION(11) void findTextFinished(const QWebEngineFindTextResult &result); #if QT_CONFIG(webengine_testsupport) void testSupportChanged(); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 7a1916d82..df6843ac3 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -80,6 +80,7 @@ class QQuickWebEngineSettings; class QQuickWebEngineFaviconProvider; class QQuickWebEngineProfilePrivate; class QQuickWebEngineTouchHandleProvider; +class QWebEngineFindTextResult; QQuickWebEngineView::WebAction editorActionForKeyEvent(QKeyEvent* event); @@ -169,6 +170,7 @@ public: QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override; void printRequested() override; void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidgetBase) override; + void findTextFinished(const QWebEngineFindTextResult &result) override; void updateAction(QQuickWebEngineView::WebAction) const; void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents); diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc index 1c4328d01..8f03774c8 100644 --- a/src/webengine/doc/src/webengineview_lgpl.qdoc +++ b/src/webengine/doc/src/webengineview_lgpl.qdoc @@ -414,26 +414,33 @@ \qmlmethod void WebEngineView::findText(string subString) \since QtWebEngine 1.1 Finds the specified string, \a subString, in the page. + The findTextFinished() signal is emitted when a string search is completed. To clear the search highlight, just pass an empty string. + + \sa findTextFinished() */ /*! \qmlmethod void WebEngineView::findText(string subString, FindFlags options) \since QtWebEngine 1.1 Finds the specified string, \a subString, in the page, using the given \a options. + The findTextFinished() signal is emitted when a string search is completed. To clear the search highlight, just pass an empty string. \code findText("Qt", WebEngineView.FindBackward | WebEngineView.FindCaseSensitively); \endcode + + \sa findTextFinished() */ /*! \qmlmethod void WebEngineView::findText(string subString, FindFlags options, variant resultCallback) \since QtWebEngine 1.1 Finds the specified string, \a subString, in the page, using the given \a options. + The findTextFinished() signal is emitted when a string search is completed. To clear the search highlight, just pass an empty string. @@ -447,6 +454,8 @@ console.log("Qt was found!"); }); \endcode + + \sa findTextFinished() */ /*! @@ -1569,5 +1578,39 @@ resource state is however completely safe. \sa lifecycleState, {WebEngine Lifecycle Example} +*/ + +/*! + \qmltype FindTextResult + \instantiates QWebEngineFindTextResult + \inqmlmodule QtWebEngine + \since QtWebEngine 1.11 + + \brief A utility type for encapsulating the result of a string search on a page. + + \sa WebEngineView::findTextFinished() +*/ + +/*! + \qmlproperty int FindTextResult::numberOfMatches + \readonly + + \brief The number of matches found. +*/ + +/*! + \qmlproperty int FindTextResult::activeMatchOrdinal + \readonly + + \brief The index of the currently highlighted match. +*/ + +/*! + \qmlsignal WebEngineView::findTextFinished(FindTextResult result) + \since QtWebEngine 1.11 + + This signal is emitted when a string search on a page is completed. \a result is + the result of the string search. + \sa findText(), FindTextResult */ diff --git a/src/webengine/plugin/plugin.cpp b/src/webengine/plugin/plugin.cpp index ad49d6543..e47a46a95 100644 --- a/src/webengine/plugin/plugin.cpp +++ b/src/webengine/plugin/plugin.cpp @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -170,6 +171,8 @@ public: qmlRegisterUncreatableType(uri, 1, 9, "WebEngineNotification", msgUncreatableType("WebEngineNotification")); qmlRegisterUncreatableType(uri, 1, 10, "TooltipRequest", msgUncreatableType("TooltipRequest")); + qRegisterMetaType(); + qmlRegisterUncreatableType(uri, 1, 11, "FindTextResult", msgUncreatableType("FindTextResult")); } private: diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 29566f021..c9e9177b7 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -52,6 +52,7 @@ #include "printer_worker.h" #endif #include "qwebenginecertificateerror.h" +#include "qwebenginefindtextresult.h" #include "qwebenginefullscreenrequest.h" #include "qwebenginehistory.h" #include "qwebenginehistory_p.h" @@ -171,6 +172,7 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); // See setVisible(). wasShownTimer.setSingleShot(true); @@ -698,6 +700,12 @@ void QWebEnginePagePrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWid bindPageAndWidget(q, static_cast(newWidgetBase)); } +void QWebEnginePagePrivate::findTextFinished(const QWebEngineFindTextResult &result) +{ + Q_Q(QWebEnginePage); + Q_EMIT q->findTextFinished(result); +} + void QWebEnginePagePrivate::ensureInitialized() const { if (!adapter->isInitialized()) @@ -797,6 +805,16 @@ QWebEnginePage::QWebEnginePage(QObject* parent) d->adapter->setClient(d); } +/*! + \fn void QWebEnginePage::findTextFinished(const QWebEngineFindTextResult &result) + \since 5.14 + + This signal is emitted when a search string search on a page is completed. \a result is + the result of the string search. + + \sa findText() +*/ + /*! \fn void QWebEnginePage::printRequested() \since 5.12 diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index 736d7ed69..cd012ea70 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -62,6 +62,7 @@ class QWebChannel; class QWebEngineCertificateError; class QWebEngineClientCertificateSelection; class QWebEngineContextMenuData; +class QWebEngineFindTextResult; class QWebEngineFullScreenRequest; class QWebEngineHistory; class QWebEnginePage; @@ -369,6 +370,8 @@ Q_SIGNALS: void lifecycleStateChanged(LifecycleState state); void recommendedStateChanged(LifecycleState state); + void findTextFinished(const QWebEngineFindTextResult &result); + protected: virtual QWebEnginePage *createWindow(WebWindowType type); virtual QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes); diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index a8cde8199..fae97b9fa 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -72,6 +72,7 @@ class WebContentsAdapter; } QT_BEGIN_NAMESPACE +class QWebEngineFindTextResult; class QWebEngineHistory; class QWebEnginePage; class QWebEngineProfile; @@ -162,6 +163,7 @@ public: ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; } void interceptRequest(QWebEngineUrlRequestInfo &) override; void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidget) override; + void findTextFinished(const QWebEngineFindTextResult &result) override; QtWebEngineCore::ProfileAdapter *profileAdapter() override; QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override; diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index 99bbc5162..64fe4c9cd 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -489,6 +489,7 @@ /*! \fn void QWebEnginePage::findText(const QString &subString, QWebEnginePage::FindFlags options = FindFlags(), const QWebEngineCallback &resultCallback = QWebEngineCallback()) Finds the specified string, \a subString, in the page, using the given \a options. + The findTextFinished() signal is emitted when a string search is completed. To clear the search highlight, just pass an empty string. @@ -501,6 +502,8 @@ For example: \snippet qtwebengine_qwebenginepage_snippet.cpp 0 + + \sa findTextFinished() */ /*! diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index f464d58d0..9f7dfa8ad 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,7 @@ static const QList typesToCheck = QList knownEnumNames = QList(); @@ -276,6 +278,8 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineFileDialogRequest.dialogAccept(QStringList) --> void" << "QQuickWebEngineFileDialogRequest.dialogReject() --> void" << "QQuickWebEngineFileDialogRequest.mode --> FileMode" + << "QWebEngineFindTextResult.numberOfMatches --> int" + << "QWebEngineFindTextResult.activeMatchOrdinal --> int" << "QQuickWebEngineFormValidationMessageRequest.Hide --> RequestType" << "QQuickWebEngineFormValidationMessageRequest.Move --> RequestType" << "QQuickWebEngineFormValidationMessageRequest.Show --> RequestType" @@ -694,6 +698,7 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineView.findText(QString) --> void" << "QQuickWebEngineView.findText(QString,FindFlags) --> void" << "QQuickWebEngineView.findText(QString,FindFlags,QJSValue) --> void" + << "QQuickWebEngineView.findTextFinished(QWebEngineFindTextResult) --> void" << "QQuickWebEngineView.formValidationMessageRequested(QQuickWebEngineFormValidationMessageRequest*) --> void" << "QQuickWebEngineView.fullScreenCancelled() --> void" << "QQuickWebEngineView.fullScreenRequested(QQuickWebEngineFullScreenRequest) --> void" diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml index 14053a675..040d324e6 100644 --- a/tests/auto/quick/qmltests/data/tst_findText.qml +++ b/tests/auto/quick/qmltests/data/tst_findText.qml @@ -38,9 +38,16 @@ TestWebEngineView { property int matchCount: 0 property bool findFailed: false + SignalSpy { + id: findTextSpy + target: webEngineView + signalName: "findTextFinished" + } + function clear() { findFailed = false matchCount = -1 + findTextSpy.clear() } function findCallbackCalled() { return matchCount != -1 } @@ -104,6 +111,9 @@ TestWebEngineView { webEngineView.findText("Hello", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 1) verify(!findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 1) } function test_findTextCaseInsensitive() { @@ -115,6 +125,9 @@ TestWebEngineView { webEngineView.findText("heLLo", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 1) verify(!findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 1) } function test_findTextManyMatches() { @@ -126,6 +139,9 @@ TestWebEngineView { webEngineView.findText("bla", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 100, 20000) verify(!findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 100) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 1) } @@ -138,6 +154,9 @@ TestWebEngineView { webEngineView.findText("heLLo", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 0) verify(findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 0) } function test_findTextNotFound() { @@ -149,6 +168,9 @@ TestWebEngineView { webEngineView.findText("string-that-is-not-threre", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 0) verify(findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 0) } function test_findTextAfterNotFound() { @@ -160,6 +182,9 @@ TestWebEngineView { webEngineView.findText("hello", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 0) verify(findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 0) webEngineView.url = Qt.resolvedUrl("test1.html") verify(webEngineView.waitForLoadSucceeded()) @@ -168,6 +193,9 @@ TestWebEngineView { webEngineView.findText("hello", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 1) verify(!findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 1) } function test_findTextInModifiedDOMAfterNotFound() { @@ -182,6 +210,9 @@ TestWebEngineView { webEngineView.findText("hello", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 0, 20000) verify(findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 0) runJavaScript("document.body.innerHTML = 'blahellobla'"); tryVerify(function() { return getBodyInnerHTML() == "blahellobla"; }, 20000); @@ -190,6 +221,9 @@ TestWebEngineView { webEngineView.findText("hello", findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, "matchCount", 1) verify(!findFailed) + tryCompare(findTextSpy, "count", 1) + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1) + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 1) } function test_findTextInterruptedByLoad() { @@ -227,5 +261,55 @@ TestWebEngineView { webEngineView.findText('New page', findFlags, webEngineView.findTextCallback) tryCompare(webEngineView, 'matchCount', 1) } + + function test_findTextActiveMatchOrdinal() { + webEngineView.loadHtml( + "" + + "foo bar foo bar foo" + + ""); + verify(webEngineView.waitForLoadSucceeded()); + + // Iterate over all "foo" matches. + webEngineView.clear(); + for (var i = 1; i <= 3; ++i) { + webEngineView.findText("foo"); + findTextSpy.wait(); + compare(findTextSpy.count, i); + compare(findTextSpy.signalArguments[i-1][0].numberOfMatches, 3); + compare(findTextSpy.signalArguments[i-1][0].activeMatchOrdinal, i); + } + + // The last match is followed by the fist one. + webEngineView.clear(); + webEngineView.findText("foo"); + findTextSpy.wait(); + compare(findTextSpy.count, 1); + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 3); + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 1); + + // The first match is preceded by the last one. + webEngineView.clear(); + webEngineView.findText("foo", WebEngineView.FindBackward); + findTextSpy.wait(); + compare(findTextSpy.count, 1); + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 3); + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 3); + + // Finding another word resets the activeMatchOrdinal. + webEngineView.clear(); + webEngineView.findText("bar"); + findTextSpy.wait(); + compare(findTextSpy.count, 1); + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 2); + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 1); + + // If no match activeMatchOrdinal is 0. + webEngineView.clear(); + webEngineView.findText("bla"); + findTextSpy.wait(); + compare(findTextSpy.count, 1); + compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0); + compare(findTextSpy.signalArguments[0][0].activeMatchOrdinal, 0); + } } } diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 7e9815298..dbb15ba10 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -128,6 +129,7 @@ private Q_SLOTS: void findTextResult(); void findTextSuccessiveShouldCallAllCallbacks(); void findTextCalledOnMatch(); + void findTextActiveMatchOrdinal(); void deleteQWebEngineViewTwice(); void loadSignalsOrder_data(); void loadSignalsOrder(); @@ -942,18 +944,24 @@ void tst_QWebEnginePage::findText() // Invoking a stopFinding operation will not change or clear the currently selected text, // if nothing was found beforehand. { - CallbackSpy spy; - m_view->findText("", 0, spy.ref()); - QVERIFY(spy.wasCalled()); + CallbackSpy callbackSpy; + QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished); + m_view->findText("", 0, callbackSpy.ref()); + QVERIFY(callbackSpy.wasCalled()); + QCOMPARE(signalSpy.count(), 1); QTRY_COMPARE(m_view->selectedText(), QString("foo bar")); } // Invoking a startFinding operation with text that won't be found, will clear the current // selection. { - CallbackSpy spy; - m_view->findText("Will not be found", 0, spy.ref()); - QCOMPARE(spy.waitForResult(), false); + CallbackSpy callbackSpy; + QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished); + m_view->findText("Will not be found", 0, callbackSpy.ref()); + QCOMPARE(callbackSpy.waitForResult(), false); + QTRY_COMPARE(signalSpy.count(), 1); + auto result = signalSpy.takeFirst().value(0).value(); + QCOMPARE(result.numberOfMatches(), 0); QTRY_VERIFY(m_view->selectedText().isEmpty()); } @@ -964,24 +972,36 @@ void tst_QWebEnginePage::findText() // Invoking a startFinding operation with text that will be found, will clear the current // selection as well. { - CallbackSpy spy; - m_view->findText("foo", 0, spy.ref()); - QVERIFY(spy.waitForResult()); + CallbackSpy callbackSpy; + QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished); + m_view->findText("foo", 0, callbackSpy.ref()); + QVERIFY(callbackSpy.waitForResult()); + QTRY_COMPARE(signalSpy.count(), 1); QTRY_VERIFY(m_view->selectedText().isEmpty()); } // Invoking a stopFinding operation after text was found, will set the selected text to the // found text. { - CallbackSpy spy; - m_view->findText("", 0, spy.ref()); - QTRY_VERIFY(spy.wasCalled()); + CallbackSpy callbackSpy; + QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished); + m_view->findText("", 0, callbackSpy.ref()); + QTRY_VERIFY(callbackSpy.wasCalled()); + QTRY_COMPARE(signalSpy.count(), 1); QTRY_COMPARE(m_view->selectedText(), QString("foo")); } } void tst_QWebEnginePage::findTextResult() { + QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished); + auto signalResult = [&findTextSpy]() -> QVector { + if (findTextSpy.count() != 1) + return QVector({-1, -1}); + auto r = findTextSpy.takeFirst().value(0).value(); + return QVector({ r.numberOfMatches(), r.activeMatchOrdinal() }); + }; + // findText will abort in blink if the view has an empty size. m_view->resize(800, 600); m_view->show(); @@ -991,15 +1011,21 @@ void tst_QWebEnginePage::findTextResult() QTRY_COMPARE(loadSpy.count(), 1); QCOMPARE(findTextSync(m_page, ""), false); + QCOMPARE(signalResult(), QVector({0, 0})); const QStringList words = { "foo", "bar" }; for (const QString &subString : words) { QCOMPARE(findTextSync(m_page, subString), true); + QCOMPARE(signalResult(), QVector({1, 1})); + QCOMPARE(findTextSync(m_page, ""), false); + QCOMPARE(signalResult(), QVector({0, 0})); } QCOMPARE(findTextSync(m_page, "blahhh"), false); + QCOMPARE(signalResult(), QVector({0, 0})); QCOMPARE(findTextSync(m_page, ""), false); + QCOMPARE(signalResult(), QVector({0, 0})); } void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks() @@ -1035,6 +1061,7 @@ void tst_QWebEnginePage::findTextCalledOnMatch() m_view->setHtml(QString("
foo bar
")); QTRY_COMPARE(loadSpy.count(), 1); + // CALLBACK bool callbackCalled = false; m_view->page()->findText("foo", 0, [this, &callbackCalled](bool found) { QVERIFY(found); @@ -1045,6 +1072,68 @@ void tst_QWebEnginePage::findTextCalledOnMatch() }); }); QTRY_VERIFY(callbackCalled); + + // SIGNAL + int findTextFinishedCount = 0; + connect(m_view->page(), &QWebEnginePage::findTextFinished, [this, &findTextFinishedCount](QWebEngineFindTextResult result) { + QCOMPARE(result.numberOfMatches(), 1); + if (findTextFinishedCount == 0) + m_view->page()->findText("bar"); + findTextFinishedCount++; + }); + + m_view->page()->findText("foo"); + QTRY_COMPARE(findTextFinishedCount, 2); +} + +void tst_QWebEnginePage::findTextActiveMatchOrdinal() +{ + QSignalSpy loadSpy(m_view->page(), &QWebEnginePage::loadFinished); + QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished); + QWebEngineFindTextResult result; + + // findText will abort in blink if the view has an empty size. + m_view->resize(800, 600); + m_view->show(); + m_view->setHtml(QString("
foo bar foo bar foo
")); + QTRY_COMPARE(loadSpy.count(), 1); + + // Iterate over all "foo" matches. + for (int i = 1; i <= 3; ++i) { + m_view->page()->findText("foo", 0); + QTRY_COMPARE(findTextSpy.count(), 1); + result = findTextSpy.takeFirst().value(0).value(); + QCOMPARE(result.numberOfMatches(), 3); + QCOMPARE(result.activeMatchOrdinal(), i); + } + + // The last match is followed by the fist one. + m_view->page()->findText("foo", 0); + QTRY_COMPARE(findTextSpy.count(), 1); + result = findTextSpy.takeFirst().value(0).value(); + QCOMPARE(result.numberOfMatches(), 3); + QCOMPARE(result.activeMatchOrdinal(), 1); + + // The first match is preceded by the last one. + m_view->page()->findText("foo", QWebEnginePage::FindBackward); + QTRY_COMPARE(findTextSpy.count(), 1); + result = findTextSpy.takeFirst().value(0).value(); + QCOMPARE(result.numberOfMatches(), 3); + QCOMPARE(result.activeMatchOrdinal(), 3); + + // Finding another word resets the activeMatchOrdinal. + m_view->page()->findText("bar", 0); + QTRY_COMPARE(findTextSpy.count(), 1); + result = findTextSpy.takeFirst().value(0).value(); + QCOMPARE(result.numberOfMatches(), 2); + QCOMPARE(result.activeMatchOrdinal(), 1); + + // If no match activeMatchOrdinal is 0. + m_view->page()->findText("bla", 0); + QTRY_COMPARE(findTextSpy.count(), 1); + result = findTextSpy.takeFirst().value(0).value(); + QCOMPARE(result.numberOfMatches(), 0); + QCOMPARE(result.activeMatchOrdinal(), 0); } static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows) -- cgit v1.2.1 From 1bb41f149bf2d3ad63442ae6058a4446344123c9 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 27 Aug 2019 10:53:36 +0200 Subject: Doc: Describe QWebEngineUrlRequestInfo::ResourceTypeNavigationPreload Change-Id: Ifbcfc6313914883a8e2566399a009ae449fface3 Reviewed-by: Allan Sandfeld Jensen --- src/core/api/qwebengineurlrequestinfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp index e2101fd02..957a99788 100644 --- a/src/core/api/qwebengineurlrequestinfo.cpp +++ b/src/core/api/qwebengineurlrequestinfo.cpp @@ -185,7 +185,9 @@ QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPriva \value ResourceTypeCspReport A report of Content Security Policy (CSP) violations. CSP reports are in JSON format and they are delivered by HTTP POST requests to specified servers. (Added in Qt 5.7) - \value ResourceTypePluginResource A resource requested by a plugin. (Added in Qt 5.7) + \value ResourceTypePluginResource A resource requested by a plugin. (Added in Qt 5.7) + \value ResourceTypeNavigationPreload A service worker navigation preload + request. (Added in Qt 5.14) \value ResourceTypeUnknown Unknown request type. \note For forward compatibility all values not matched should be treated as unknown, -- cgit v1.2.1 From 8969e421e460c0577f934956fc42b7f35caaeafa Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 27 Aug 2019 11:22:32 +0200 Subject: Doc: Edit docs for QWebEngineUrlRequestInfo::initiator() Fixed the grammar and added \since 5.14. Change-Id: Iab9b4898c761366f640300445aa21913523a58e2 Reviewed-by: Tamas Zakor Reviewed-by: Kai Koehne --- src/core/api/qwebengineurlrequestinfo.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp index 957a99788..2aa43a318 100644 --- a/src/core/api/qwebengineurlrequestinfo.cpp +++ b/src/core/api/qwebengineurlrequestinfo.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWebEngine module of the Qt Toolkit. @@ -250,8 +250,10 @@ QUrl QWebEngineUrlRequestInfo::firstPartyUrl() const } /*! - Returns the origin url of the document which initiated - the navigation when a frame navigates another frame. + Returns the origin URL of the document that initiated + the navigation of a frame to another frame. + + \since 5.14 */ QUrl QWebEngineUrlRequestInfo::initiator() const -- cgit v1.2.1 From 48c85451adf1d530bccf9bfb542abb3211f0bf36 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 27 Aug 2019 13:25:39 +0200 Subject: Doc: Mark QWebEngineDownloadItem::setPath() obsolete Mention the functions that replace the obsolete path() and setPath() functions and fix QDoc issues in their docs. Change-Id: I3497113760386e54e397bbe9c2149c355c22a3ec Reviewed-by: Kai Koehne --- src/webenginewidgets/api/qwebenginedownloaditem.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp index 7ce572e2f..7b0cfe074 100644 --- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp +++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWebEngine module of the Qt Toolkit. @@ -124,8 +124,9 @@ static inline QWebEngineDownloadItem::DownloadInterruptReason toDownloadInterrup then the download request will be automatically rejected and nothing will be written to disk. - \note Some properties, like the \l path under which the file will be saved, - can only be changed before calling accept(). + \note Some properties, such as setting the path and file name where the file + will be saved (see \l downloadDirectory() and \l downloadFileName()), can + only be changed before calling accept(). \section2 Object Life Cycle @@ -510,6 +511,10 @@ QString QWebEngineDownloadItem::mimeType() const /*! \obsolete + + Use \l suggestedFileName(), \l downloadDirectory(), and + \l downloadFileName() instead. + Returns the full target path where data is being downloaded to. The path includes the file name. The default suggested path is the standard download location @@ -523,6 +528,10 @@ QString QWebEngineDownloadItem::path() const } /*! + \obsolete + + Use \l setDownloadDirectory() and \l setDownloadFileName() instead. + Sets the full target path to download the file to. The \a path should also include the file name. The download path can only be set in response @@ -572,7 +581,7 @@ QString QWebEngineDownloadItem::downloadDirectory() const /*! \since 5.14 - Sets the directory path to download the file to. + Sets \a directory as the directory path to download the file to. The download directory path can only be set in response to the QWebEngineProfile::downloadRequested() signal before the download is accepted. Past that point, this function has no effect on the @@ -598,7 +607,7 @@ void QWebEngineDownloadItem::setDownloadDirectory(QString directory) /*! \since 5.14 - Returns the suggested file name. + Returns the file name to download the file to. */ QString QWebEngineDownloadItem::downloadFileName() const @@ -610,7 +619,7 @@ QString QWebEngineDownloadItem::downloadFileName() const /*! \since 5.14 - Sets the file name to download the file to. + Sets \a fileName as the file name to download the file to. The download file name can only be set in response to the QWebEngineProfile::downloadRequested() signal before the download is accepted. Past that point, this function has no effect on the -- cgit v1.2.1 From 8213ea60bacb91ddfa1594e1f515abe2cfbde621 Mon Sep 17 00:00:00 2001 From: Tamas Zakor Date: Tue, 13 Aug 2019 13:52:21 +0200 Subject: Fix tst_QWebEngineScript::loadEvents() If the page load takes more than 500ms the Deferred injection point will be triggered before the load finish event. Fix the test to handle this situation. Change-Id: If6ad9250127650630ef96c35c79ce6bfe73ecf95 Reviewed-by: Allan Sandfeld Jensen --- .../qwebenginescript/tst_qwebenginescript.cpp | 83 ++++++++++++++-------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp index 1ba9c13e8..90361f2c9 100644 --- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp +++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp @@ -30,6 +30,26 @@ #include #endif +static bool verifyOrder(QStringList orderList) +{ + QStringList expected = { + "DocumentCreation", + "DOMContentLoaded", + "DocumentReady", + "load", + "Deferred" + }; + + if (orderList.at(4) == "load (timeout)") { + if (orderList.at(3) != "Deferred") + return false; + expected[3] = "Deferred"; + expected[4] = "load (timeout)"; + } + + return orderList == expected; +} + class tst_QWebEngineScript: public QObject { Q_OBJECT @@ -101,15 +121,28 @@ void tst_QWebEngineScript::loadEvents() script.setRunsOnSubFrames(true); if (injectionPoint == QWebEngineScript::DocumentCreation) { script.setSourceCode(QStringLiteral(R"( - var log = ["DocumentCreation"]; - for (let type of ["DOMContentLoaded", "load"]) { - window.addEventListener(type, () => log.push(type)); + var log = ['DocumentCreation']; + var timestamps = {'DocumentCreation': Date.now()}; + for (let type of ['DOMContentLoaded', 'load']) { + window.addEventListener(type, () => { + timestamps[type] = Date.now(); + if (type === 'load' && log.includes('Deferred') && timestamps['Deferred'] - timestamps['DOMContentLoaded'] > 500) + log.push(type + ' (timeout)'); + else + log.push(type); + }); } )")); } else if (injectionPoint == QWebEngineScript::DocumentReady) { - script.setSourceCode(QStringLiteral(R"(log.push("DocumentReady"))")); + script.setSourceCode(QStringLiteral(R"( + timestamps['DocumentReady'] = Date.now(); + log.push('DocumentReady'); + )")); } else { - script.setSourceCode(QStringLiteral(R"(log.push("Deferred"))")); + script.setSourceCode(QStringLiteral(R"( + timestamps['Deferred'] = Date.now(); + log.push('Deferred'); + )")); } return script; } @@ -144,46 +177,38 @@ void tst_QWebEngineScript::loadEvents() profile.pages.emplace_back(profile); Page &page = profile.pages.back(); - const QStringList expected = { - "DocumentCreation", - "DOMContentLoaded", - "DocumentReady", - "load", - "Deferred" - }; - // Single frame / setHtml page.setHtml(QStringLiteral("mr")); QTRY_COMPARE(page.spy.count(), 1); QCOMPARE(page.spy.takeFirst().value(0).toBool(), true); - QCOMPARE(page.eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList())); // After discard page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); page.setLifecycleState(QWebEnginePage::LifecycleState::Active); QTRY_COMPARE(page.spy.count(), 1); QCOMPARE(page.spy.takeFirst().value(0).toBool(), true); - QCOMPARE(page.eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList())); // Multiple frames page.load(QUrl("qrc:/resources/test_iframe_main.html")); QTRY_COMPARE(page.spy.count(), 1); QCOMPARE(page.spy.takeFirst().value(0).toBool(), true); - QCOMPARE(page.eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected); - QCOMPARE(page.eval("window[0].log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(page.eval("window[0].log", QWebEngineScript::ApplicationWorld).toStringList(), expected); - QCOMPARE(page.eval("window[0][0].log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(page.eval("window[0][0].log", QWebEngineScript::ApplicationWorld).toStringList(), expected); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window[0].log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window[0].log", QWebEngineScript::ApplicationWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window[0][0].log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window[0][0].log", QWebEngineScript::ApplicationWorld).toStringList())); // Cross-process navigation page.load(QUrl("chrome://gpu")); QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000); QCOMPARE(page.spy.takeFirst().value(0).toBool(), true); - QCOMPARE(page.eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList())); // Using window.open from JS QVERIFY(profile.pages.size() == 1); @@ -191,10 +216,10 @@ void tst_QWebEngineScript::loadEvents() QTRY_VERIFY(profile.pages.size() == 2); QTRY_COMPARE(profile.pages.front().spy.count(), 1); QTRY_COMPARE(profile.pages.back().spy.count(), 1); - QCOMPARE(profile.pages.front().eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(profile.pages.front().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected); - QCOMPARE(profile.pages.back().eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected); - QCOMPARE(profile.pages.back().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected); + QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList())); + QVERIFY(verifyOrder(profile.pages.back().eval("window.log", QWebEngineScript::MainWorld).toStringList())); + QVERIFY(verifyOrder(profile.pages.back().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList())); } void tst_QWebEngineScript::scriptWorld_data() -- cgit v1.2.1 From bf3753f02402b44455038c4fa2a897d41aadf850 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Wed, 14 Aug 2019 18:59:23 +0200 Subject: Allow deferring QWebEngineCertificateError handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce defer() method for halting URL load on certificate errors, and methods for rejecting and ignoring these errors subsequently in async manner. [ChangeLog][QtWebEngineWidgets][QWebEngineCertificateError] New methods for asynchronous decision on certificate error during load. Fixes: QTBUG-55110 Change-Id: Ib23eb568862ccc360208922a6a581f8e7edc4a7e Reviewed-by: Michael Brüning --- .../webenginewidgets/simplebrowser/webpage.cpp | 42 ++++--- .../api/qwebenginecertificateerror.cpp | 97 ++++++++++++++-- .../api/qwebenginecertificateerror.h | 19 +++- src/webenginewidgets/api/qwebenginepage.cpp | 8 +- src/webenginewidgets/api/qwebenginepage_p.h | 2 + .../doc/src/qwebenginepage_lgpl.qdoc | 2 + tests/auto/shared/https.pri | 4 + tests/auto/shared/httpserver.cpp | 31 ++++-- tests/auto/shared/httpserver.h | 13 ++- tests/auto/shared/httpsserver.h | 81 ++++++++++++++ tests/auto/shared/httpsserver.qrc | 6 + tests/auto/shared/resources/cert.pem | 34 ++++++ tests/auto/shared/resources/key.pem | 52 +++++++++ .../widgets/certificateerror/certificateerror.pro | 3 + .../certificateerror/tst_certificateerror.cpp | 122 +++++++++++++++++++++ tests/auto/widgets/widgets.pro | 1 + 16 files changed, 472 insertions(+), 45 deletions(-) create mode 100644 tests/auto/shared/https.pri create mode 100644 tests/auto/shared/httpsserver.h create mode 100644 tests/auto/shared/httpsserver.qrc create mode 100644 tests/auto/shared/resources/cert.pem create mode 100644 tests/auto/shared/resources/key.pem create mode 100644 tests/auto/widgets/certificateerror/certificateerror.pro create mode 100644 tests/auto/widgets/certificateerror/tst_certificateerror.cpp diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp index 99849c77d..2e49f651f 100644 --- a/examples/webenginewidgets/simplebrowser/webpage.cpp +++ b/examples/webenginewidgets/simplebrowser/webpage.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include WebPage::WebPage(QWebEngineProfile *profile, QObject *parent) @@ -74,22 +75,33 @@ WebPage::WebPage(QWebEngineProfile *profile, QObject *parent) bool WebPage::certificateError(const QWebEngineCertificateError &error) { QWidget *mainWindow = view()->window(); - if (error.isOverridable()) { - QDialog dialog(mainWindow); - dialog.setModal(true); - dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); - Ui::CertificateErrorDialog certificateDialog; - certificateDialog.setupUi(&dialog); - certificateDialog.m_iconLabel->setText(QString()); - QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, mainWindow)); - certificateDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32)); - certificateDialog.m_errorLabel->setText(error.errorDescription()); - dialog.setWindowTitle(tr("Certificate Error")); - return dialog.exec() == QDialog::Accepted; - } - QMessageBox::critical(mainWindow, tr("Certificate Error"), error.errorDescription()); - return false; + QWebEngineCertificateError deferredError = error; + deferredError.defer(); + + QTimer::singleShot(0, mainWindow, [mainWindow, error = std::move(deferredError)] () mutable { + if (!error.deferred()) { + QMessageBox::critical(mainWindow, tr("Certificate Error"), error.errorDescription()); + } else { + QDialog dialog(mainWindow); + dialog.setModal(true); + dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); + + Ui::CertificateErrorDialog certificateDialog; + certificateDialog.setupUi(&dialog); + certificateDialog.m_iconLabel->setText(QString()); + QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, mainWindow)); + certificateDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32)); + certificateDialog.m_errorLabel->setText(error.errorDescription()); + dialog.setWindowTitle(tr("Certificate Error")); + + if (dialog.exec() == QDialog::Accepted) + error.ignoreCertificateError(); + else + error.rejectCertificate(); + } + }); + return true; } void WebPage::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth) diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.cpp b/src/webenginewidgets/api/qwebenginecertificateerror.cpp index f04b73615..e8c7a4245 100644 --- a/src/webenginewidgets/api/qwebenginecertificateerror.cpp +++ b/src/webenginewidgets/api/qwebenginecertificateerror.cpp @@ -39,6 +39,8 @@ #include "qwebenginecertificateerror.h" +#include "certificate_error_controller.h" + QT_BEGIN_NAMESPACE /*! @@ -51,14 +53,37 @@ QT_BEGIN_NAMESPACE QWebEnginePage::certificateError(). */ -class QWebEngineCertificateErrorPrivate { +class QWebEngineCertificateErrorPrivate : public QSharedData { public: QWebEngineCertificateErrorPrivate(int error, QUrl url, bool overridable, QString errorDescription); + ~QWebEngineCertificateErrorPrivate() { + if (deferred && !answered) + rejectCertificate(); + } + + void resolveError(bool accept) { + if (answered) + return; + answered = true; + if (overridable) { + if (auto ctl = controller.lock()) + ctl->accept(accept); + } + } + + void ignoreCertificateError() { resolveError(true); } + void rejectCertificate() { resolveError(false); } + QWebEngineCertificateError::Error error; QUrl url; bool overridable; QString errorDescription; + + bool answered = false, deferred = false; + QWeakPointer controller; + + Q_DISABLE_COPY(QWebEngineCertificateErrorPrivate) }; QWebEngineCertificateErrorPrivate::QWebEngineCertificateErrorPrivate(int error, QUrl url, bool overridable, QString errorDescription) @@ -68,17 +93,30 @@ QWebEngineCertificateErrorPrivate::QWebEngineCertificateErrorPrivate(int error, , errorDescription(errorDescription) { } - /*! \internal */ QWebEngineCertificateError::QWebEngineCertificateError(int error, QUrl url, bool overridable, QString errorDescription) - : d_ptr(new QWebEngineCertificateErrorPrivate(error, url, overridable, errorDescription)) + : d(new QWebEngineCertificateErrorPrivate(error, url, overridable, errorDescription)) { } +/*! \internal +*/ +QWebEngineCertificateError::QWebEngineCertificateError(const QSharedPointer &controller) + : d(new QWebEngineCertificateErrorPrivate(controller->error(), controller->url(), + controller->overridable(), controller->errorString())) +{ + d->controller = controller; +} + +QWebEngineCertificateError::QWebEngineCertificateError(const QWebEngineCertificateError &other) = default; + +QWebEngineCertificateError& QWebEngineCertificateError::operator=(const QWebEngineCertificateError &other) = default; + /*! \internal */ QWebEngineCertificateError::~QWebEngineCertificateError() { + } /*! @@ -116,7 +154,6 @@ QWebEngineCertificateError::~QWebEngineCertificateError() */ bool QWebEngineCertificateError::isOverridable() const { - const Q_D(QWebEngineCertificateError); return d->overridable; } @@ -127,7 +164,6 @@ bool QWebEngineCertificateError::isOverridable() const */ QUrl QWebEngineCertificateError::url() const { - const Q_D(QWebEngineCertificateError); return d->url; } @@ -138,7 +174,6 @@ QUrl QWebEngineCertificateError::url() const */ QWebEngineCertificateError::Error QWebEngineCertificateError::error() const { - const Q_D(QWebEngineCertificateError); return d->error; } @@ -149,8 +184,56 @@ QWebEngineCertificateError::Error QWebEngineCertificateError::error() const */ QString QWebEngineCertificateError::errorDescription() const { - const Q_D(QWebEngineCertificateError); return d->errorDescription; } +/*! + Marks the certificate error for delayed handling. + + This function should be called when there is a need to postpone the decision whether to ignore a + certificate error, for example, while waiting for user input. When called, the function pauses the + URL request until ignoreCertificateError() or rejectCertificate() is called. + + \note It is only possible to defer overridable certificate errors. + + \sa isOverridable(), deferred() +*/ +void QWebEngineCertificateError::defer() +{ + if (isOverridable()) + d->deferred = true; +} + +/*! + Returns whether the decision for error handling was delayed and the URL load was halted. +*/ +bool QWebEngineCertificateError::deferred() const +{ + return d->deferred; +} + +/*! + Ignores the certificate error and continues the loading of the requested URL. +*/ +void QWebEngineCertificateError::ignoreCertificateError() +{ + d->ignoreCertificateError(); +} + +/*! + Rejects the certificate and aborts the loading of the requested URL. +*/ +void QWebEngineCertificateError::rejectCertificate() +{ + d->rejectCertificate(); +} + +/*! + Returns \c true if the error was explicitly rejected or accepted. +*/ +bool QWebEngineCertificateError::answered() const +{ + return d->answered; +} + QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.h b/src/webenginewidgets/api/qwebenginecertificateerror.h index 82ac281be..f8805e8a7 100644 --- a/src/webenginewidgets/api/qwebenginecertificateerror.h +++ b/src/webenginewidgets/api/qwebenginecertificateerror.h @@ -42,11 +42,12 @@ #include -#include +#include #include QT_BEGIN_NAMESPACE +class CertificateErrorController; class QWebEngineCertificateErrorPrivate; class QWEBENGINEWIDGETS_EXPORT QWebEngineCertificateError { @@ -78,10 +79,20 @@ public: bool isOverridable() const; QString errorDescription() const; + QWebEngineCertificateError(const QWebEngineCertificateError &other); + QWebEngineCertificateError& operator=(const QWebEngineCertificateError &other); + + void defer(); + bool deferred() const; + + void rejectCertificate(); + void ignoreCertificateError(); + bool answered() const; + private: - Q_DISABLE_COPY(QWebEngineCertificateError) - Q_DECLARE_PRIVATE(QWebEngineCertificateError) - QScopedPointer d_ptr; + friend class QWebEnginePagePrivate; + QWebEngineCertificateError(const QSharedPointer &controller); + QExplicitlySharedDataPointer d; }; QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index c9e9177b7..b22d47916 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -294,6 +294,7 @@ void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isError return; isLoading = true; + m_certificateErrorControllers.clear(); QTimer::singleShot(0, q, &QWebEnginePage::loadStarted); } @@ -1715,10 +1716,11 @@ void QWebEnginePagePrivate::allowCertificateError(const QSharedPointererror(), controller->url(), controller->overridable() && !controller->strictEnforcement(), controller->errorString()); + QWebEngineCertificateError error(controller); accepted = q->certificateError(error); - - if (error.isOverridable()) + if (error.deferred() && !error.answered()) + m_certificateErrorControllers.append(controller); + else if (!error.answered() && error.isOverridable()) controller->accept(accepted); } diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index fae97b9fa..2843f69c4 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -210,6 +210,8 @@ public: #if QT_CONFIG(webengine_printing_and_pdf) QPrinter *currentPrinter; #endif + + QList> m_certificateErrorControllers; }; class QContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index 64fe4c9cd..5536c0058 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -522,6 +522,8 @@ Return \c true to ignore the error and complete the request. Return \c false to stop loading the request. + \note If the error was successfully deferred then the returned value will be ignored. + \sa QWebEngineCertificateError */ diff --git a/tests/auto/shared/https.pri b/tests/auto/shared/https.pri new file mode 100644 index 000000000..ce4c147f7 --- /dev/null +++ b/tests/auto/shared/https.pri @@ -0,0 +1,4 @@ +include($$PWD/http.pri) + +HEADERS += $$PWD/httpsserver.h +RESOURCES += $$PWD/httpsserver.qrc diff --git a/tests/auto/shared/httpserver.cpp b/tests/auto/shared/httpserver.cpp index b85af9901..e282fc8b8 100644 --- a/tests/auto/shared/httpserver.cpp +++ b/tests/auto/shared/httpserver.cpp @@ -31,9 +31,21 @@ Q_LOGGING_CATEGORY(gHttpServerLog, "HttpServer") -HttpServer::HttpServer(QObject *parent) : QObject(parent) +HttpServer::HttpServer(QObject *parent) : HttpServer(new QTcpServer, "http", parent) { - connect(&m_tcpServer, &QTcpServer::newConnection, this, &HttpServer::handleNewConnection); +} + +HttpServer::HttpServer(QTcpServer *tcpServer, const QString &protocol, QObject *parent) + : QObject(parent), m_tcpServer(tcpServer) +{ + m_url.setHost(QStringLiteral("127.0.0.1")); + m_url.setScheme(protocol); + connect(tcpServer, &QTcpServer::newConnection, this, &HttpServer::handleNewConnection); +} + +HttpServer::~HttpServer() +{ + delete m_tcpServer; } bool HttpServer::start() @@ -41,21 +53,18 @@ bool HttpServer::start() m_error = false; m_expectingError = false; - if (!m_tcpServer.listen()) { - qCWarning(gHttpServerLog).noquote() << m_tcpServer.errorString(); + if (!m_tcpServer->listen()) { + qCWarning(gHttpServerLog).noquote() << m_tcpServer->errorString(); return false; } - m_url.setScheme(QStringLiteral("http")); - m_url.setHost(QStringLiteral("127.0.0.1")); - m_url.setPort(m_tcpServer.serverPort()); - + m_url.setPort(m_tcpServer->serverPort()); return true; } bool HttpServer::stop() { - m_tcpServer.close(); + m_tcpServer->close(); return m_error == m_expectingError; } @@ -73,12 +82,12 @@ QUrl HttpServer::url(const QString &path) const void HttpServer::handleNewConnection() { - auto rr = new HttpReqRep(m_tcpServer.nextPendingConnection(), this); + auto rr = new HttpReqRep(m_tcpServer->nextPendingConnection(), this); connect(rr, &HttpReqRep::requestReceived, [this, rr]() { Q_EMIT newRequest(rr); rr->close(); }); - connect(rr, &HttpReqRep::responseSent, [this, rr]() { + connect(rr, &HttpReqRep::responseSent, [rr]() { qCInfo(gHttpServerLog).noquote() << rr->requestMethod() << rr->requestPath() << rr->responseStatus() << rr->responseBody().size(); }); diff --git a/tests/auto/shared/httpserver.h b/tests/auto/shared/httpserver.h index b4649244e..57f824bb5 100644 --- a/tests/auto/shared/httpserver.h +++ b/tests/auto/shared/httpserver.h @@ -59,19 +59,22 @@ class HttpServer : public QObject Q_OBJECT public: explicit HttpServer(QObject *parent = nullptr); + explicit HttpServer(QTcpServer *server, const QString &protocol, QObject *parent = nullptr); + + ~HttpServer() override; // Must be called to start listening. // // Returns true if a TCP port has been successfully bound. - Q_REQUIRED_RESULT bool start(); + Q_INVOKABLE Q_REQUIRED_RESULT bool start(); // Stops listening and performs final error checks. - Q_REQUIRED_RESULT bool stop(); + Q_INVOKABLE Q_REQUIRED_RESULT bool stop(); - void setExpectError(bool b); + Q_INVOKABLE void setExpectError(bool b); // Full URL for given relative path - QUrl url(const QString &path = QStringLiteral("/")) const; + Q_INVOKABLE QUrl url(const QString &path = QStringLiteral("/")) const; Q_SIGNALS: // Emitted after a HTTP request has been successfully parsed. @@ -81,7 +84,7 @@ private Q_SLOTS: void handleNewConnection(); private: - QTcpServer m_tcpServer; + QTcpServer *m_tcpServer; QUrl m_url; bool m_error = false; bool m_expectingError = false; diff --git a/tests/auto/shared/httpsserver.h b/tests/auto/shared/httpsserver.h new file mode 100644 index 000000000..76287a7e5 --- /dev/null +++ b/tests/auto/shared/httpsserver.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef HTTPSSERVER_H +#define HTTPSSERVER_H + +#include "httpreqrep.h" +#include "httpserver.h" + +#include +#include +#include +#include +#include +#include + +struct SslTcpServer : QTcpServer +{ + SslTcpServer() { + sslconf.setLocalCertificate(QSslCertificate::fromPath(":/resources/cert.pem").first()); + sslconf.setPrivateKey(readKey(":/resources/key.pem")); + } + + void incomingConnection(qintptr d) override { + auto socket = new QSslSocket(this); + socket->setSslConfiguration(sslconf); + + if (!socket->setSocketDescriptor(d)) { + qWarning() << "Failed to setup ssl socket!"; + delete socket; + return; + } + + connect(socket, QOverload::of(&QSslSocket::error), + [] (QSslSocket::SocketError e) { qWarning() << "! Socket Error:" << e; }); + connect(socket, QOverload &>::of(&QSslSocket::sslErrors), + [] (const QList &le) { qWarning() << "! SSL Errors:\n" << le; }); + + addPendingConnection(socket); + socket->startServerEncryption(); + } + + QSslKey readKey(const QString &path) const { + QFile file(path); + file.open(QIODevice::ReadOnly); + return QSslKey(file.readAll(), QSsl::Rsa, QSsl::Pem); + } + + QSslConfiguration sslconf; +}; + +struct HttpsServer : HttpServer +{ + HttpsServer(QObject *parent = nullptr) : HttpServer(new SslTcpServer, "https", parent) { } +}; + +#endif diff --git a/tests/auto/shared/httpsserver.qrc b/tests/auto/shared/httpsserver.qrc new file mode 100644 index 000000000..ec57a1983 --- /dev/null +++ b/tests/auto/shared/httpsserver.qrc @@ -0,0 +1,6 @@ + + + resources/cert.pem + resources/key.pem + + diff --git a/tests/auto/shared/resources/cert.pem b/tests/auto/shared/resources/cert.pem new file mode 100644 index 000000000..518642d1d --- /dev/null +++ b/tests/auto/shared/resources/cert.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF3zCCA8egAwIBAgIULwmp8VArl0GVaR6HLEf/U1XNdJ8wDQYJKoZIhvcNAQEL +BQAwfzELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVy +bGluMQ0wCwYDVQQKDARUUXRDMQswCQYDVQQLDAJXRTESMBAGA1UEAwwJbG9jYWxo +b3N0MR4wHAYJKoZIhvcNAQkBFg9ibGFja2hvbGVAcXQuaW8wHhcNOTkxMjMxMjMw +MDAxWhcNMDAxMjMwMjMwMDAxWjB/MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVy +bGluMQ8wDQYDVQQHDAZCZXJsaW4xDTALBgNVBAoMBFRRdEMxCzAJBgNVBAsMAldF +MRIwEAYDVQQDDAlsb2NhbGhvc3QxHjAcBgkqhkiG9w0BCQEWD2JsYWNraG9sZUBx +dC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL15eV6DVSOFW093 +p1+FlqmneX4riOzJXiNNF8DI00+rkTv4hT37D6keJlMxLLDgq3o9YwJnGJkpxMSd +P9uvKGaIRb9hQd7WviXCMwX07Wz3BMIogKItJfY6nEk8dkCc/FPrhbk4CCKNoZkb +fGRv4jFoCCXL8yaffN5ii+L/xF2azaXwr4MOOJbG5810HWGYbrppBMtSQk4c1jXI +c0eVqOjnYtcFNCmoIyXwDdTynaRizNtUgeYRSaIBk/hXQGePDL35V0ARg2EbVGzL +sJKftJf4WBoprjX8xmfk72zYB0SF8g7uUXGWb6D5Q661c7REGB7Ha7uLIz74Pow3 +MmJVbz93YiEZ4onxDNke5AIgNrllhd1hk8WGBBN7i/8RmR2KRS24OEa2jQd0u8Lx +WvUsWpzWO5sSGN4vw1NA75fk8pKo80Jvhz2+1q2CeAEnkIhU2tsH301MWuHasrXJ +6HY1zp0IoeYRwtCof/nuTbC9BYM3782tmJ/6O7O8BQyOM3G/7+8hgyUC+mfSigcm +qVbpWbchSxBSHZ5DlMMHHHYJSxS0GAjSGx7fC4t7EBgZtnZyrLA12gYoGnh2kC5T +RgWtfwVdJgHKGRWfeMdOhu73GlWyj9iEN+BaT5LkPxiytb+y1RmRcPtqBofMKkpV +9D4X5iTQbAoXrdUztVcE5dBPm/VbAgMBAAGjUzBRMB0GA1UdDgQWBBSdQX4ziuSL +BPNR1d0v5X2QaMTeNjAfBgNVHSMEGDAWgBSdQX4ziuSLBPNR1d0v5X2QaMTeNjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAKqjEBoYk+t/qgTlGH +Ab+aSM7kfLvHtktpGT7Shh9hUyczcqROOpj/jVFvd+y1tFXglE+II65jAnCZ7neX +vJC+LbCMi7tggtInZR0QEYO9MiPaLXMA4UWf5UOgd0pDPu9pKTYd7suvPgTa/ApQ +M3MRUQcm//6ABwHH3JHtZoaqAOp75NguuyNyzda29wGY8onFs9LeibR2NlRVbwgT +u9SiqtPZj5mq20OAo0XynoR+D8y1l5wEDhzHadQRRk5gRq84rIt6iqYONdDynAYJ +gTxUVvRLWE3vFe1EmQbI+4nJ2iGbZ78W0bHVTxRb7MHGt7VTDWrzL95UdopfmvLD +KpYt2xzVLKc2prYGY1V464dZ2aPfMgSorJE8/U2z+2+ITd76xDFb2YaEAghzFZqb +lIIz23+BGinEhq18brW1XfMpd8+NKNkxrOsyvHANMmnRJvUoLfNn0YATQ5b3c0QM +7VUI7ddH40RBHSd6XuiaQVQtGyRtiKzC1G94syVdAWWq5aMPF90BZV0Am5kkM8B0 +yX6BsMWqMwCc8ZGgKq1oK3gOdnmzkmxqpgr+RhFpGwy9XYFTKv0QPW36DD9Pgpge +sMSafPouMdYc8c3HuTxh2ZwHLxpqyaKMGVN+LdzDbddsZzOiUKd7Bq9XpNtG2o9y +K+MCKRECBkh4ZvMxd3yEJAym0w== +-----END CERTIFICATE----- diff --git a/tests/auto/shared/resources/key.pem b/tests/auto/shared/resources/key.pem new file mode 100644 index 000000000..bd350d7fb --- /dev/null +++ b/tests/auto/shared/resources/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQC9eXleg1UjhVtP +d6dfhZapp3l+K4jsyV4jTRfAyNNPq5E7+IU9+w+pHiZTMSyw4Kt6PWMCZxiZKcTE +nT/bryhmiEW/YUHe1r4lwjMF9O1s9wTCKICiLSX2OpxJPHZAnPxT64W5OAgijaGZ +G3xkb+IxaAgly/Mmn3zeYovi/8Rdms2l8K+DDjiWxufNdB1hmG66aQTLUkJOHNY1 +yHNHlajo52LXBTQpqCMl8A3U8p2kYszbVIHmEUmiAZP4V0Bnjwy9+VdAEYNhG1Rs +y7CSn7SX+FgaKa41/MZn5O9s2AdEhfIO7lFxlm+g+UOutXO0RBgex2u7iyM++D6M +NzJiVW8/d2IhGeKJ8QzZHuQCIDa5ZYXdYZPFhgQTe4v/EZkdikUtuDhGto0HdLvC +8Vr1LFqc1jubEhjeL8NTQO+X5PKSqPNCb4c9vtatgngBJ5CIVNrbB99NTFrh2rK1 +yeh2Nc6dCKHmEcLQqH/57k2wvQWDN+/NrZif+juzvAUMjjNxv+/vIYMlAvpn0ooH +JqlW6Vm3IUsQUh2eQ5TDBxx2CUsUtBgI0hse3wuLexAYGbZ2cqywNdoGKBp4dpAu +U0YFrX8FXSYByhkVn3jHTobu9xpVso/YhDfgWk+S5D8YsrW/stUZkXD7agaHzCpK +VfQ+F+Yk0GwKF63VM7VXBOXQT5v1WwIDAQABAoICAGoOsM0inml/oBjfVSS21hqo +z+y72a0RGkyQPpd+0ilqU6VJ+usyuRVk9vbiM63eVJ3b9qvFoZM6OhYEH1aMuQSL +it8RRZnCgjUIex7+dlfj/RnhKf+dXf5x2EF2QorwVJ103ClNH+CXfrkBFaPyrJ4T +KVxeyP/5jh+88ahimjv7Btm328Z0E2DyfZYXRMr4VCKr3i8hIFQw+Aaq6TxMnXug +6UaKdyRKJUJ7GIL2Ox9k3l528y8gxiKU14rO7BILlIpSI3CNXQjiD2PGsFOiaagX +LtmWMxmtIDHPh+VZFthYUaHh7Fy0ZE+qtyP4FYf2BbpUzgzwWQ5KTliWHPHF+LqJ +Skg8B5LcnP0TwhCl0ZqOsADZk5HA5hlTH93A1Hr3zJvgXySU+X72/9+9n2V0C1Kg +JMaGaJs8Nz+MZqvmEcONTWXzSQccBxKbLN5X94CFS1k+A5cLOYTSPUtqz2jhvHsx +YrAxQdpVG8RR0jd+9PgWGlyXmxmvu7sJvMdrjxlNtrbEs92veK1vYiERy0/kXajK +ST7z3uaM0DDS4vEMCDYZ4ITA+Mt61P2QTprrHE5lDCKocbvkZK2koY4/xbiYk/sA +Qet2u9ulMgPLgEAfaiRAa6IZD6tkZLVNsfaI6pGtSx02gXVQIm3TkQbvBynlYorl +V6m+ardppIzvMulC9P+BAoIBAQD5u9UB1+jUBDlmMUtEZqL/+G4ERLF+rZGjsw46 +n+WjkdrMkhjFp2wderWHsxh9P+EiZzKmoD1w6OUnCwh4L0G2GxEqFlHGQk1UZb9o +/tkfNXA5ZbeOyL5zLdsvYrnv1TBItUNuOCOg8MgAHtxd1bxPO0BjvcYwuGJp8NpK +tCAX8fNIW7pm4Pi+gJpJQgaRtS4GhCSqlPsJvGtwvhDwP8opwNg7APGKP9ML/5dA +d7kVI46Gkyhb/vqVfJfWML0JcHFjch0KEgD3HmbUH4w2x15uf70koaWKl8K4xXbs +ADh2/RxX3zDUEg44dtMthc7RNde6eg+NrcNGpDnDe+35bkkRAoIBAQDCOpDxGkwA +iNJL7EUxfkvvETh5cYA/jtKBnM7Hmu0Pw9nvHgktZm5Bkq6UAeQyYQCR+WAba3Dl +Ik97WnB2hXKCAlkSa9pEILWU06KLauiKHXU8pV/uMXi2I13MjXhEQxVkvm0vCr+g +p0ZhXdsI/BY4KNne+VoPe9E9l1tEX32ryc8bJwJMqtT9/NxareWSwP/2juqO2EJz +KVZdl9exOQ4s8yCc7OzaMaHJVmCt+9G0jdniuEBDaH4QwmTDrZSUOcOYXCI2XDO3 ++SxS9gBbQmMiyka4FwzO/dZ2LaXxdzvd4SCi9FRNfej++5scYsKYh5m17kzmJDS7 +feCgvcNBVrerAoIBAQCqMwpb5ENo46we6q+KYYzreOu5+vshA7gDYg/rgngmP0xo +KZW6d30mpi+72SJykiukn8KUbxcQsZkjP9C44DQfoVjUXzvCLAO55lJKg42ESI5A +gANWy5eIthLwu49PVfM/SlI3dwlJMXCNLHsxdG6PbSlYEMlXAQMJgr2zNgm9aAdP +JDzoyqCcbNc54EbL3TgN9tdqbniczQ5IWzD+G+tzA1wa8myrtQ3n2nzB0haQwpfr +PbW+5QrxAGYW80aSfVC53tbNuzFvOggIv6t21e+UzXgh1A0XZJCwDtwawZe5+Izt +kk4b6mZIsyr/lnc6fECXdYLOI0O4DErV4MtyOGiRAoIBAQC6mnHucgla6hjBALpp +lqF1ieHsK3O/nIP6KqEvfFUNtGiJJx5CFAsRzM8VO8v16uQVWrVPIqZQPeqG5Jjw +Bb3B0mepHx2QHqzV045yy7+mEi80mN3Vhoom00um3rQRQTIonBth+r2op40itn1d +4HOoePb5Fi/EeHzK48O3qNagWT81IwE+j1Iawvkh1bieifZg92W632LYKXrkaKG9 +jsdjwCIxIh9cchqxyN8RyMHs6evPup1jJd0YVOtiZD4/OlAE7V+hQmwd8LL48Yfe +JaYBIr1W2C5iH9YPrEOl/Zvyy/wDEyJ7YOCdOTYIy4mR6ZVwCQawhVB0YbeSNz6E +Y8AJAoIBAQDQ5OAryjgPeqSPgwpWu2ce5LXsw27b8r4h8v3MevtKmZHL2CXz1VtL +hSwolTgSIHCm/U7zPXTb3nftXRXM/eHhEL/xhEkbvv4zGVLVsqPaKdpAxdYQCRn3 +drIOsc8n1L8VqLPoKTnK2+Ya0yZPt9M4aQQ6Nv/bZuRBF4+vj+GGdhQQ0EUGkx5N +lKsFgrQGVd6V4YNgVi9K1GtJLUd3mR7Vh7xvcdMOQkpbSZqXqe+lB1W2+nPaxTxU +TjPKSB0BXJMcKAMCmRgzx/61CPo83M4OYG5oltQSDskI4VeTLOI5nPi2MoXcVnX5 +zB9TRbOML1RSOJ+z+mbv7ONymoUI/Jf5 +-----END PRIVATE KEY----- diff --git a/tests/auto/widgets/certificateerror/certificateerror.pro b/tests/auto/widgets/certificateerror/certificateerror.pro new file mode 100644 index 000000000..73ba7515b --- /dev/null +++ b/tests/auto/widgets/certificateerror/certificateerror.pro @@ -0,0 +1,3 @@ +include(../tests.pri) +include(../../shared/https.pri) +QT *= core-private diff --git a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp new file mode 100644 index 000000000..b002dc363 --- /dev/null +++ b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** 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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include + +#include +#include +#include + +#include + +class tst_CertificateError : public QObject +{ + Q_OBJECT +public: + tst_CertificateError() { } + +private Q_SLOTS: + void handleError_data(); + void handleError(); +}; + +struct PageWithCertificateErrorHandler : QWebEnginePage +{ + PageWithCertificateErrorHandler(bool defer, bool accept, QObject *p = nullptr) + : QWebEnginePage(p), deferError(defer), acceptCertificate(accept) { + connect(this, &QWebEnginePage::loadFinished, [&] (bool result) { spyLoad(result); }); + } + + bool deferError, acceptCertificate; + + CallbackSpy spyLoad; + QScopedPointer error; + + bool certificateError(const QWebEngineCertificateError &e) override { + error.reset(new QWebEngineCertificateError(e)); + if (deferError) + error->defer(); + return acceptCertificate; + } +}; + +void tst_CertificateError::handleError_data() +{ + QTest::addColumn("deferError"); + QTest::addColumn("acceptCertificate"); + QTest::addColumn("expectedContent"); + QTest::addRow("Reject") << false << false << QString(); + QTest::addRow("DeferReject") << true << false << QString(); + QTest::addRow("DeferAccept") << true << true << "TEST"; +} + +void tst_CertificateError::handleError() +{ + HttpsServer server; + server.setExpectError(true); + QVERIFY(server.start()); + + connect(&server, &HttpsServer::newRequest, [&] (HttpReqRep *rr) { + rr->setResponseBody(QByteArrayLiteral("TEST")); + rr->sendResponse(); + }); + + QFETCH(bool, deferError); + QFETCH(bool, acceptCertificate); + QFETCH(QString, expectedContent); + + PageWithCertificateErrorHandler page(deferError, acceptCertificate); + page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); + + page.setUrl(server.url()); + QTRY_VERIFY(page.error); + QVERIFY(page.error->isOverridable()); + + if (deferError) { + QVERIFY(page.error->deferred()); + QVERIFY(!page.error->answered()); + QVERIFY(!page.spyLoad.wasCalled()); + QCOMPARE(toPlainTextSync(&page), QString()); + + if (acceptCertificate) + page.error->ignoreCertificateError(); + else + page.error->rejectCertificate(); + + QVERIFY(page.error->answered()); + page.error.reset(); + } + + bool loadResult = page.spyLoad.waitForResult(); + QVERIFY(page.spyLoad.wasCalled()); + QCOMPARE(loadResult, acceptCertificate); + QCOMPARE(toPlainTextSync(&page), expectedContent); +} + +QTEST_MAIN(tst_CertificateError) +#include diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro index 92159bf83..df553df55 100644 --- a/tests/auto/widgets/widgets.pro +++ b/tests/auto/widgets/widgets.pro @@ -4,6 +4,7 @@ QT_FOR_CONFIG += webenginecore webenginecore-private TEMPLATE = subdirs SUBDIRS += \ + certificateerror \ defaultsurfaceformat \ devtools \ faviconmanager \ -- cgit v1.2.1 From 8d045ce2a4cc65660bdf6ee8b555899c5c6119de Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Mon, 26 Aug 2019 13:46:35 +0200 Subject: Api to get certificate's chain on error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Expose certificate's chain on validation error starting with the immediate certificate and ending with the CA's certificate. [ChangeLog][QtWebEngineWidgets][QWebEngineCertificateError] New method to get the peer's chain of digital certificates. Fixes: QTBUG-51176 Change-Id: I799dfe9e44f9f2517f4691d175beee256114af79 Reviewed-by: Michael Brüning --- src/core/certificate_error_controller.cpp | 12 ++- src/core/certificate_error_controller.h | 2 + src/core/certificate_error_controller_p.h | 1 + src/core/type_conversion.cpp | 19 +++++ src/core/type_conversion.h | 7 ++ .../api/qwebenginecertificateerror.cpp | 12 +++ .../api/qwebenginecertificateerror.h | 3 + tests/auto/shared/httpsserver.h | 2 +- tests/auto/shared/resources/cert.pem | 94 ++++++++++++++-------- tests/auto/shared/resources/key.pem | 79 +++++++----------- .../certificateerror/tst_certificateerror.cpp | 4 + 11 files changed, 147 insertions(+), 88 deletions(-) diff --git a/src/core/certificate_error_controller.cpp b/src/core/certificate_error_controller.cpp index a747451df..71465a1af 100644 --- a/src/core/certificate_error_controller.cpp +++ b/src/core/certificate_error_controller.cpp @@ -90,9 +90,10 @@ CertificateErrorControllerPrivate::CertificateErrorControllerPrivate(int cert_er , strictEnforcement(strict_enforcement) , callback(cb) { - if (ssl_info.cert.get()) { - validStart = toQt(ssl_info.cert->valid_start()); - validExpiry = toQt(ssl_info.cert->valid_expiry()); + if (auto cert = ssl_info.cert.get()) { + validStart = toQt(cert->valid_start()); + validExpiry = toQt(cert->valid_expiry()); + chain = toCertificateChain(cert); } } @@ -186,4 +187,9 @@ QString CertificateErrorController::errorString() const return getQStringForMessageId(IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION); } +QList CertificateErrorController::chain() const +{ + return d->chain; +} + QT_END_NAMESPACE diff --git a/src/core/certificate_error_controller.h b/src/core/certificate_error_controller.h index 5bea61c9b..7f5300dc8 100644 --- a/src/core/certificate_error_controller.h +++ b/src/core/certificate_error_controller.h @@ -55,6 +55,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -95,6 +96,7 @@ public: QString errorString() const; QDateTime validStart() const; QDateTime validExpiry() const; + QList chain() const; void accept(bool); diff --git a/src/core/certificate_error_controller_p.h b/src/core/certificate_error_controller_p.h index abde9a7d5..f3b0c23fa 100644 --- a/src/core/certificate_error_controller_p.h +++ b/src/core/certificate_error_controller_p.h @@ -71,6 +71,7 @@ public: bool overridable; bool strictEnforcement; const base::Callback callback; + QList chain; }; QT_END_NAMESPACE diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp index 02d2db448..ddadeb9f2 100644 --- a/src/core/type_conversion.cpp +++ b/src/core/type_conversion.cpp @@ -40,11 +40,14 @@ #include "type_conversion.h" #include +#include +#include #include #include #include #include +#include namespace QtWebEngineCore { @@ -256,4 +259,20 @@ void convertToQt(const SkMatrix44 &m, QMatrix4x4 &c) c = qtMatrix; } +static QSslCertificate toCertificate(CRYPTO_BUFFER *buffer) +{ + auto derCert = net::x509_util::CryptoBufferAsStringPiece(buffer); + return QSslCertificate(QByteArray::fromRawData(derCert.data(), derCert.size()), QSsl::Der); +} + +QList toCertificateChain(net::X509Certificate *certificate) +{ + // from leaf to root as in QtNetwork + QList chain; + chain.append(toCertificate(certificate->cert_buffer())); + for (auto &&buffer : certificate->intermediate_buffers()) + chain.append(toCertificate(buffer.get())); + return chain; +} + } // namespace QtWebEngineCore diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index 7b1f1b4d6..dfd8e8fef 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -64,6 +64,7 @@ #include "url/gurl.h" QT_FORWARD_DECLARE_CLASS(QMatrix4x4) +QT_FORWARD_DECLARE_CLASS(QSslCertificate) namespace content { struct FaviconURL; @@ -73,6 +74,10 @@ namespace gfx { class ImageSkiaRep; } +namespace net { +class X509Certificate; +} + namespace QtWebEngineCore { inline QString toQt(const base::string16 &string) @@ -291,6 +296,8 @@ inline QStringList fromVector(const std::vector &vector) FaviconInfo toFaviconInfo(const content::FaviconURL &); +QList toCertificateChain(net::X509Certificate *certificate); + } // namespace QtWebEngineCore #endif // TYPE_CONVERSION_H diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.cpp b/src/webenginewidgets/api/qwebenginecertificateerror.cpp index e8c7a4245..a61d98f94 100644 --- a/src/webenginewidgets/api/qwebenginecertificateerror.cpp +++ b/src/webenginewidgets/api/qwebenginecertificateerror.cpp @@ -79,6 +79,7 @@ public: QUrl url; bool overridable; QString errorDescription; + QList chain; bool answered = false, deferred = false; QWeakPointer controller; @@ -106,6 +107,7 @@ QWebEngineCertificateError::QWebEngineCertificateError(const QSharedPointeroverridable(), controller->errorString())) { d->controller = controller; + d->chain = controller->chain(); } QWebEngineCertificateError::QWebEngineCertificateError(const QWebEngineCertificateError &other) = default; @@ -236,4 +238,14 @@ bool QWebEngineCertificateError::answered() const return d->answered; } +/*! + Returns the peer's chain of digital certificates + + Chain starts with the peer's immediate certificate and ending with the CA's certificate. +*/ +QList QWebEngineCertificateError::chain() const +{ + return d->chain; +} + QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qwebenginecertificateerror.h b/src/webenginewidgets/api/qwebenginecertificateerror.h index f8805e8a7..b2dd65a9f 100644 --- a/src/webenginewidgets/api/qwebenginecertificateerror.h +++ b/src/webenginewidgets/api/qwebenginecertificateerror.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -89,6 +90,8 @@ public: void ignoreCertificateError(); bool answered() const; + QList chain() const; + private: friend class QWebEnginePagePrivate; QWebEngineCertificateError(const QSharedPointer &controller); diff --git a/tests/auto/shared/httpsserver.h b/tests/auto/shared/httpsserver.h index 76287a7e5..32c8e8345 100644 --- a/tests/auto/shared/httpsserver.h +++ b/tests/auto/shared/httpsserver.h @@ -41,7 +41,7 @@ struct SslTcpServer : QTcpServer { SslTcpServer() { - sslconf.setLocalCertificate(QSslCertificate::fromPath(":/resources/cert.pem").first()); + sslconf.setLocalCertificateChain(QSslCertificate::fromPath(":/resources/cert.pem")); sslconf.setPrivateKey(readKey(":/resources/key.pem")); } diff --git a/tests/auto/shared/resources/cert.pem b/tests/auto/shared/resources/cert.pem index 518642d1d..3aaaf289c 100644 --- a/tests/auto/shared/resources/cert.pem +++ b/tests/auto/shared/resources/cert.pem @@ -1,34 +1,64 @@ -----BEGIN CERTIFICATE----- -MIIF3zCCA8egAwIBAgIULwmp8VArl0GVaR6HLEf/U1XNdJ8wDQYJKoZIhvcNAQEL -BQAwfzELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0GA1UEBwwGQmVy -bGluMQ0wCwYDVQQKDARUUXRDMQswCQYDVQQLDAJXRTESMBAGA1UEAwwJbG9jYWxo -b3N0MR4wHAYJKoZIhvcNAQkBFg9ibGFja2hvbGVAcXQuaW8wHhcNOTkxMjMxMjMw -MDAxWhcNMDAxMjMwMjMwMDAxWjB/MQswCQYDVQQGEwJERTEPMA0GA1UECAwGQmVy -bGluMQ8wDQYDVQQHDAZCZXJsaW4xDTALBgNVBAoMBFRRdEMxCzAJBgNVBAsMAldF -MRIwEAYDVQQDDAlsb2NhbGhvc3QxHjAcBgkqhkiG9w0BCQEWD2JsYWNraG9sZUBx -dC5pbzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL15eV6DVSOFW093 -p1+FlqmneX4riOzJXiNNF8DI00+rkTv4hT37D6keJlMxLLDgq3o9YwJnGJkpxMSd -P9uvKGaIRb9hQd7WviXCMwX07Wz3BMIogKItJfY6nEk8dkCc/FPrhbk4CCKNoZkb -fGRv4jFoCCXL8yaffN5ii+L/xF2azaXwr4MOOJbG5810HWGYbrppBMtSQk4c1jXI -c0eVqOjnYtcFNCmoIyXwDdTynaRizNtUgeYRSaIBk/hXQGePDL35V0ARg2EbVGzL -sJKftJf4WBoprjX8xmfk72zYB0SF8g7uUXGWb6D5Q661c7REGB7Ha7uLIz74Pow3 -MmJVbz93YiEZ4onxDNke5AIgNrllhd1hk8WGBBN7i/8RmR2KRS24OEa2jQd0u8Lx -WvUsWpzWO5sSGN4vw1NA75fk8pKo80Jvhz2+1q2CeAEnkIhU2tsH301MWuHasrXJ -6HY1zp0IoeYRwtCof/nuTbC9BYM3782tmJ/6O7O8BQyOM3G/7+8hgyUC+mfSigcm -qVbpWbchSxBSHZ5DlMMHHHYJSxS0GAjSGx7fC4t7EBgZtnZyrLA12gYoGnh2kC5T -RgWtfwVdJgHKGRWfeMdOhu73GlWyj9iEN+BaT5LkPxiytb+y1RmRcPtqBofMKkpV -9D4X5iTQbAoXrdUztVcE5dBPm/VbAgMBAAGjUzBRMB0GA1UdDgQWBBSdQX4ziuSL -BPNR1d0v5X2QaMTeNjAfBgNVHSMEGDAWgBSdQX4ziuSLBPNR1d0v5X2QaMTeNjAP -BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAKqjEBoYk+t/qgTlGH -Ab+aSM7kfLvHtktpGT7Shh9hUyczcqROOpj/jVFvd+y1tFXglE+II65jAnCZ7neX -vJC+LbCMi7tggtInZR0QEYO9MiPaLXMA4UWf5UOgd0pDPu9pKTYd7suvPgTa/ApQ -M3MRUQcm//6ABwHH3JHtZoaqAOp75NguuyNyzda29wGY8onFs9LeibR2NlRVbwgT -u9SiqtPZj5mq20OAo0XynoR+D8y1l5wEDhzHadQRRk5gRq84rIt6iqYONdDynAYJ -gTxUVvRLWE3vFe1EmQbI+4nJ2iGbZ78W0bHVTxRb7MHGt7VTDWrzL95UdopfmvLD -KpYt2xzVLKc2prYGY1V464dZ2aPfMgSorJE8/U2z+2+ITd76xDFb2YaEAghzFZqb -lIIz23+BGinEhq18brW1XfMpd8+NKNkxrOsyvHANMmnRJvUoLfNn0YATQ5b3c0QM -7VUI7ddH40RBHSd6XuiaQVQtGyRtiKzC1G94syVdAWWq5aMPF90BZV0Am5kkM8B0 -yX6BsMWqMwCc8ZGgKq1oK3gOdnmzkmxqpgr+RhFpGwy9XYFTKv0QPW36DD9Pgpge -sMSafPouMdYc8c3HuTxh2ZwHLxpqyaKMGVN+LdzDbddsZzOiUKd7Bq9XpNtG2o9y -K+MCKRECBkh4ZvMxd3yEJAym0w== +MIIEpDCCAoygAwIBAgIUO90aty9AMjvBvzfUhr1WwdBrKkMwDQYJKoZIhvcNAQEL +BQAwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEyMDAGA1UEAwwpQmFkU1NM +IEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTkwODI2MTQ0 +NDIxWhcNMTkwODI3MTQ0NDIxWjBjMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs +aWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEPMA0GA1UECgwGQmFkU1NM +MRYwFAYDVQQDDA0qLmJhZHNzbC50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAkybT/L4zJCqefpd+eYT6aQ0PtobQfFgP+n+z5wWoUxIAJnjb5ZW4 +7IJxka/2/ggzJOfrUBur54LkTfFQ+yX85eKYCuH0GLz+Rve50LDn0ya6qSgmEhDG +0bend2tMZY+Nl3B+5Ane1vua8hdJjv3ZO3e5UgpQwysL54eYyhEWWlbFWF11LhEd +MYp953UGLqoV4Mlw+Li8TmFwdKQx6icgBTuloXLzk9aUU+b6NbXdadNXkmzg09IC +sb8pnMXiF2P9Xm5rK0IoiRkSHxVnU12nQXh65Ns/2Dj5DcbHmVdvallfr4wnLeFP +UotysZnvFmE7FLMSr/eQfkTG+Jlb7ZhoGwIDAQABozQwMjAJBgNVHRMEAjAAMCUG +A1UdEQQeMByCDSouYmFkc3NsLnRlc3SCC2JhZHNzbC50ZXN0MA0GCSqGSIb3DQEB +CwUAA4ICAQA7Yc+QQzqSK15ibmaYrkqq+cumggsWLCprW8jvzhpWBt9IjToP5nsy +sKinYPoZR8jvZ1YVotcts7uQT7DkqeWkB+l+88c7gQdgujvBo6v9/g+jrXFKgsJD +IBmkho8hpd63Slqv2Yp4bYT20O5EvR9CQvwSkwTs+ylBNEs1Q+AbekxmBjuYUxHn +9xL4/GZ6ufoNv676iCoXo4mnDrCD8e8MRiZoU9Lq4G41HGiLWV0tM/M6BdVJYGzl +FcBg0ZKnQT9OCWEPRe3zyRS6a+MivPAzxS8z/kYaRN+C7H68Mib3xPDsEETz1MnO +uzGAPHAAgtYWYJi+CaaNWkgAv4n+UIQa0oyqPn4z5hLcsO+nMBws2Sg0mkQLilBX +N1ciCdVMi7sHKuLa7GVksq/RQrXnZcQhoYQRrZAaAHKbxyo/M2pNqmDiFJppdH7a +6Rj2vYf6ig/FXAzDGsDvf/tsGCxgJTFzGly+GsWVe40vyjfWHxWWDU/eGjfGO05k +Xzjm+kYGJnH2hfiIlX1Jeu/jjIodiSy31F0hvuKlJu8PfaQ7oo5neRzwRO6Wq9rR +7DMsQN6OtXGnnA+ogC0korA+aXev6wzbwYUhzMf1YTzEjrFNIXeIHsQSzq6lPcIE +JOly5wjyO/eNF7mpHyDX8brY6Hn+bgyDeKAmsUvhOCEXgaPpKlP4gQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGeTCCBGGgAwIBAgIUbVL7tFc7sgPIYnt+REVc0wiHdBcwDQYJKoZIhvcNAQEL +BQAwdzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEqMCgGA1UEAwwhQmFkU1NM +IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE5MDgyNjE0NDQyMFoXDTI5 +MDgyMzE0NDQyMFowfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEyMDAGA1UE +AwwpQmFkU1NMIEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgoU4q43DJEUyoAOeK31uyEgLn +s5CCd6XFmGp6wln0yupwmYRaDiCoSJ1qpmjYt+gIHpDAFS2ZzR4TbZORFirjY0cQ +6+IWwpBEQR0hOluWN99CqjdCxfuZwiTvTV3FQv1IJZ13g23Uh2xRbnrzC2muDHzT +4ZNM3aayvziMGY6n33aksEc6WMZb3p/Qn2OepeC7EzZiy4tXKPf9OaOPbae5aJWZ +bOzzydFLkV4UqZb5FfySt8toIivPeIlRCiPodWLb2y5DYUXyWBk1dpbIcVa/LusV +vsBELeJ+BFDRH1NHtwOrhOkZHKMr3SQ1YRlNDEeHUVmQkori397j9JjpPzScQJ6r +d/W4mGyzgRmguIy9IpKMbxX5/1A6c6l5q0HqMgPv84GWxlhav4xwsOf90iT2vLPZ +yllVCgCsCfvLEyVFhER18HAo8mTkQqKL7ZO96xXHgugA7dFN/C3BdC9kYP/GbAwd +J0R6qKrfSiyyk1VbjWfFdFH/G/bT9H0nrjMj5tCT4q/zDCb5HkBp3BOoyUKb9yyt +a1Cht/Iu3f1SlQzsrDBt9iMMCjXoNNAJcV7ZZ6HCxcWwfAwxgylQgq8UG60shxhn +CBPhcA8JM+mk2nghTU2pxwY/KpAd0H4/a79b0DE97dCOnNHzyP3tqP8RenG549B0 +gsNO60aG01k6P9jFuQIDAQABo4H0MIHxMB0GA1UdDgQWBBQgvWmDuYqQ6xX7y8xc +cgky1FO7jzCBtAYDVR0jBIGsMIGpgBTUGo+svIaoSMF/shILSbeiQ1zAQKF7pHkw +dzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNh +biBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEqMCgGA1UEAwwhQmFkU1NMIFJv +b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ghR1qCPxzkfCSCwMFHm98245f0pk0zAM +BgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAnGr6 +t1+KNGZV9hmAE3SyMzHRpgwtqIG4kl94A7Pz3CbA8+q7u7DW8l1GdaNx2J2wo+R5 +rJi02V5e7TNa7ZS5S9WGYHZ2y6QOjXuT28VMAPX+3HAgxk3RMxocpLpkPp8hhD/9 +S5KxA6AQDUN6av8E3xeuuWYWmTvAXNHK5ABXDFxxTp902ozNnZaSk2DxAUqcsOD4 +ago0IhRdkFGe1Q7F8gOxtlUL5owNL4uhRP8BbwOja2Gopn2+kA9CNqdwPI4Ipjlr +yo61oCqzy3RAXOUct8WAvybacADmJODAxDq9O5fAZuYZScjjj1ASowmbyDH/Wb9z ++WfiKKH4BfgOIukzK3I1M9wiSDefIodCFfEVXbdNudZj8f9Gw4RrZwkUuxDLeRWG +ReDtzAWq7G0Diw3uX40S4jaj3MeS6oHp2Nrj/VyjSRiYTeN/pnA9N0M5VuCYYvXD +f50rrigjQfOgb4TmnyJAjXWVkXW7Fa+ooLsbvlfr8wP8f31y1cgWPHTVIv6Kmug7 +Bg88k3x5gLTXmutDjseORonhGMRdAxHgJVf5aKfzdRpwXZTDZJXhsAz9OdlOhNZd +UrYo680QugA0V3H5D8Egbr2AUUSMDkn133COjeOIDknFxX3qDqeTzqLZCAEBIoKn +Adpix0jvG1Ys4Ayq6K2wQFdGFjtl6LsiGC7pWWU= -----END CERTIFICATE----- diff --git a/tests/auto/shared/resources/key.pem b/tests/auto/shared/resources/key.pem index bd350d7fb..89922679a 100644 --- a/tests/auto/shared/resources/key.pem +++ b/tests/auto/shared/resources/key.pem @@ -1,52 +1,27 @@ ------BEGIN PRIVATE KEY----- -MIIJRAIBADANBgkqhkiG9w0BAQEFAASCCS4wggkqAgEAAoICAQC9eXleg1UjhVtP -d6dfhZapp3l+K4jsyV4jTRfAyNNPq5E7+IU9+w+pHiZTMSyw4Kt6PWMCZxiZKcTE -nT/bryhmiEW/YUHe1r4lwjMF9O1s9wTCKICiLSX2OpxJPHZAnPxT64W5OAgijaGZ -G3xkb+IxaAgly/Mmn3zeYovi/8Rdms2l8K+DDjiWxufNdB1hmG66aQTLUkJOHNY1 -yHNHlajo52LXBTQpqCMl8A3U8p2kYszbVIHmEUmiAZP4V0Bnjwy9+VdAEYNhG1Rs -y7CSn7SX+FgaKa41/MZn5O9s2AdEhfIO7lFxlm+g+UOutXO0RBgex2u7iyM++D6M -NzJiVW8/d2IhGeKJ8QzZHuQCIDa5ZYXdYZPFhgQTe4v/EZkdikUtuDhGto0HdLvC -8Vr1LFqc1jubEhjeL8NTQO+X5PKSqPNCb4c9vtatgngBJ5CIVNrbB99NTFrh2rK1 -yeh2Nc6dCKHmEcLQqH/57k2wvQWDN+/NrZif+juzvAUMjjNxv+/vIYMlAvpn0ooH -JqlW6Vm3IUsQUh2eQ5TDBxx2CUsUtBgI0hse3wuLexAYGbZ2cqywNdoGKBp4dpAu -U0YFrX8FXSYByhkVn3jHTobu9xpVso/YhDfgWk+S5D8YsrW/stUZkXD7agaHzCpK -VfQ+F+Yk0GwKF63VM7VXBOXQT5v1WwIDAQABAoICAGoOsM0inml/oBjfVSS21hqo -z+y72a0RGkyQPpd+0ilqU6VJ+usyuRVk9vbiM63eVJ3b9qvFoZM6OhYEH1aMuQSL -it8RRZnCgjUIex7+dlfj/RnhKf+dXf5x2EF2QorwVJ103ClNH+CXfrkBFaPyrJ4T -KVxeyP/5jh+88ahimjv7Btm328Z0E2DyfZYXRMr4VCKr3i8hIFQw+Aaq6TxMnXug -6UaKdyRKJUJ7GIL2Ox9k3l528y8gxiKU14rO7BILlIpSI3CNXQjiD2PGsFOiaagX -LtmWMxmtIDHPh+VZFthYUaHh7Fy0ZE+qtyP4FYf2BbpUzgzwWQ5KTliWHPHF+LqJ -Skg8B5LcnP0TwhCl0ZqOsADZk5HA5hlTH93A1Hr3zJvgXySU+X72/9+9n2V0C1Kg -JMaGaJs8Nz+MZqvmEcONTWXzSQccBxKbLN5X94CFS1k+A5cLOYTSPUtqz2jhvHsx -YrAxQdpVG8RR0jd+9PgWGlyXmxmvu7sJvMdrjxlNtrbEs92veK1vYiERy0/kXajK -ST7z3uaM0DDS4vEMCDYZ4ITA+Mt61P2QTprrHE5lDCKocbvkZK2koY4/xbiYk/sA -Qet2u9ulMgPLgEAfaiRAa6IZD6tkZLVNsfaI6pGtSx02gXVQIm3TkQbvBynlYorl -V6m+ardppIzvMulC9P+BAoIBAQD5u9UB1+jUBDlmMUtEZqL/+G4ERLF+rZGjsw46 -n+WjkdrMkhjFp2wderWHsxh9P+EiZzKmoD1w6OUnCwh4L0G2GxEqFlHGQk1UZb9o -/tkfNXA5ZbeOyL5zLdsvYrnv1TBItUNuOCOg8MgAHtxd1bxPO0BjvcYwuGJp8NpK -tCAX8fNIW7pm4Pi+gJpJQgaRtS4GhCSqlPsJvGtwvhDwP8opwNg7APGKP9ML/5dA -d7kVI46Gkyhb/vqVfJfWML0JcHFjch0KEgD3HmbUH4w2x15uf70koaWKl8K4xXbs -ADh2/RxX3zDUEg44dtMthc7RNde6eg+NrcNGpDnDe+35bkkRAoIBAQDCOpDxGkwA -iNJL7EUxfkvvETh5cYA/jtKBnM7Hmu0Pw9nvHgktZm5Bkq6UAeQyYQCR+WAba3Dl -Ik97WnB2hXKCAlkSa9pEILWU06KLauiKHXU8pV/uMXi2I13MjXhEQxVkvm0vCr+g -p0ZhXdsI/BY4KNne+VoPe9E9l1tEX32ryc8bJwJMqtT9/NxareWSwP/2juqO2EJz -KVZdl9exOQ4s8yCc7OzaMaHJVmCt+9G0jdniuEBDaH4QwmTDrZSUOcOYXCI2XDO3 -+SxS9gBbQmMiyka4FwzO/dZ2LaXxdzvd4SCi9FRNfej++5scYsKYh5m17kzmJDS7 -feCgvcNBVrerAoIBAQCqMwpb5ENo46we6q+KYYzreOu5+vshA7gDYg/rgngmP0xo -KZW6d30mpi+72SJykiukn8KUbxcQsZkjP9C44DQfoVjUXzvCLAO55lJKg42ESI5A -gANWy5eIthLwu49PVfM/SlI3dwlJMXCNLHsxdG6PbSlYEMlXAQMJgr2zNgm9aAdP -JDzoyqCcbNc54EbL3TgN9tdqbniczQ5IWzD+G+tzA1wa8myrtQ3n2nzB0haQwpfr -PbW+5QrxAGYW80aSfVC53tbNuzFvOggIv6t21e+UzXgh1A0XZJCwDtwawZe5+Izt -kk4b6mZIsyr/lnc6fECXdYLOI0O4DErV4MtyOGiRAoIBAQC6mnHucgla6hjBALpp -lqF1ieHsK3O/nIP6KqEvfFUNtGiJJx5CFAsRzM8VO8v16uQVWrVPIqZQPeqG5Jjw -Bb3B0mepHx2QHqzV045yy7+mEi80mN3Vhoom00um3rQRQTIonBth+r2op40itn1d -4HOoePb5Fi/EeHzK48O3qNagWT81IwE+j1Iawvkh1bieifZg92W632LYKXrkaKG9 -jsdjwCIxIh9cchqxyN8RyMHs6evPup1jJd0YVOtiZD4/OlAE7V+hQmwd8LL48Yfe -JaYBIr1W2C5iH9YPrEOl/Zvyy/wDEyJ7YOCdOTYIy4mR6ZVwCQawhVB0YbeSNz6E -Y8AJAoIBAQDQ5OAryjgPeqSPgwpWu2ce5LXsw27b8r4h8v3MevtKmZHL2CXz1VtL -hSwolTgSIHCm/U7zPXTb3nftXRXM/eHhEL/xhEkbvv4zGVLVsqPaKdpAxdYQCRn3 -drIOsc8n1L8VqLPoKTnK2+Ya0yZPt9M4aQQ6Nv/bZuRBF4+vj+GGdhQQ0EUGkx5N -lKsFgrQGVd6V4YNgVi9K1GtJLUd3mR7Vh7xvcdMOQkpbSZqXqe+lB1W2+nPaxTxU -TjPKSB0BXJMcKAMCmRgzx/61CPo83M4OYG5oltQSDskI4VeTLOI5nPi2MoXcVnX5 -zB9TRbOML1RSOJ+z+mbv7ONymoUI/Jf5 ------END PRIVATE KEY----- +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAkybT/L4zJCqefpd+eYT6aQ0PtobQfFgP+n+z5wWoUxIAJnjb +5ZW47IJxka/2/ggzJOfrUBur54LkTfFQ+yX85eKYCuH0GLz+Rve50LDn0ya6qSgm +EhDG0bend2tMZY+Nl3B+5Ane1vua8hdJjv3ZO3e5UgpQwysL54eYyhEWWlbFWF11 +LhEdMYp953UGLqoV4Mlw+Li8TmFwdKQx6icgBTuloXLzk9aUU+b6NbXdadNXkmzg +09ICsb8pnMXiF2P9Xm5rK0IoiRkSHxVnU12nQXh65Ns/2Dj5DcbHmVdvallfr4wn +LeFPUotysZnvFmE7FLMSr/eQfkTG+Jlb7ZhoGwIDAQABAoIBADRXy3BL98UVo+tD +2ClBtBFKJBy5N9ADQyvH4SZ8TLO/423L7+xqpaz7eYppHWKfaBHorTuBnFRtquhO +vo+Xo63iPFMirMFf+NMlq2MgilYBoMQrE9+5N//BZECGWlaGCcekrH5RRIMUXLlg +rzm98lfE7pbQNIo39bQV97NpAJqBWPuoIvCrbRCysGoA5j7ptZ/EhSlC00eA7ybD +CeYHmh8NrsapKOTGb5u1v3paV8X/mH6vKmsVs7n6LC0opBxzM8eAHEAQ6h8rmz9H +y99FWDYha3lOS4SLkTnuRnNHOMLJajPq3Isu+BgzLWuRGnKZ3rmuUFwPNkCZTvsV +dTdBE4ECgYEAw6jBEil0e8Pc9sGqnz93e8qrYE9wSPso4q3BNJgTbN48kon6mqh7 +gQVgEP/75Th5YrJUrY9Pd/8H9uoMOxbDXgOXG/xNnhC0L+7aM8nhKlxCLndY1e56 +/YymYYH4+D9ZD2u526mK/nmCg2QGOkCVYYp7NXe/mA0g34drKjefmj8CgYEAwIhq +rZhlfAvQThSOqQA9zA7NXPDh4KzIjr8htVu5YvVcv5W2uhsni9DXFaloPnhuLdJ7 +MnPF2WqzQ9YqFrGn/9/OTqeE23f60ed04qLGM4BApb45y5Kw6sCPnWu7dMYfny9i +XeZA2A+ODmqVkrU+ZNVzqzS1krYyUP3exd1voyUCgYEAqPRARH6np3gqhqoVvA4C +D1OjSTdPrrWzSIriG5h2rbv6ck/Tp1l1zKPnoMZrrjRmHWQA2x61cNk4926DwUKW +0cgn5HKqU6P49Ks8oRvi48FnJNjKTXHxoqChy/GAHF4Xecl8ZMKy06v5l5v4BLVg +SSpb2n/dYl9z05IMaBhAKeECgYBKB2n1S6ah1q0GiLL92mDoiDyAYwKG8AjBkk40 +vIsAuNUruTYkQvKmuOsqohO6CXZb2hWSpZ9KZNN+3ucaCL9PDE/4QEM+W9iuQu/X +gLzy6npxAD6avtGVweq2ncjbMp7QB1ksP69pJDn74xGV8miGPuiVyNOUEMgyChtR +Oz6EnQKBgEth0w80CBg6b3NKuASoc/vC08njZQvWpe5xrzY2DL8epVKb1qf6+8SE +eX34cIcSaonEZ2g67MAeIG6jtmPwxWk4EYAsO1u4XiyziABkoNyLKVH4hZg61BsV +jL7R5UrUvBbhKLFOwkcB4Kwdwu7COB/UKa5XJBTMbuw1UTyxlUeI +-----END RSA PRIVATE KEY----- diff --git a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp index b002dc363..5fd765ed5 100644 --- a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp +++ b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp @@ -96,6 +96,10 @@ void tst_CertificateError::handleError() page.setUrl(server.url()); QTRY_VERIFY(page.error); QVERIFY(page.error->isOverridable()); + auto chain = page.error->chain(); + QCOMPARE(chain.size(), 2); + QCOMPARE(chain[0].serialNumber(), "3b:dd:1a:b7:2f:40:32:3b:c1:bf:37:d4:86:bd:56:c1:d0:6b:2a:43"); + QCOMPARE(chain[1].serialNumber(), "6d:52:fb:b4:57:3b:b2:03:c8:62:7b:7e:44:45:5c:d3:08:87:74:17"); if (deferError) { QVERIFY(page.error->deferred()); -- cgit v1.2.1 From 68539693fe022595b2e4fbecd448b2fca5e7d3e5 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Thu, 5 Sep 2019 14:42:54 +0200 Subject: Blacklist tst_QWebEnginePage::fullScreenRequested on Windows Task-number: QTBUG-78015 Change-Id: I9d1e2409897df6d5a36ab9a12d42224c2163df6b Reviewed-by: Liang Qi --- tests/auto/widgets/qwebenginepage/BLACKLIST | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST index 4e344c936..e6fad8b20 100644 --- a/tests/auto/widgets/qwebenginepage/BLACKLIST +++ b/tests/auto/widgets/qwebenginepage/BLACKLIST @@ -7,3 +7,6 @@ windows [runJavaScriptFromSlot] osx linux + +[fullScreenRequested] +windows -- cgit v1.2.1 From 047d61f188aae3fe3ebc689900b8a5c9fb6e901d Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Fri, 9 Aug 2019 17:40:29 +0200 Subject: Add webengine-core feature Create/split main configure for submodules. Now configure system knows when webenginecore module is not going to be built and the user gets the feedback after the configure step with the message: The following modules are not being compiled in this configuration: webenginecore webengine webenginewidgets If a module is not built also features are not populated, therefore some tests have to be moved to main configuration. This improves error reporting and prepares landing for QtPdf modules. Remove configure.prf and fix issues after config split. Add makefile call to report errors. Now calling make also reports issues. Task-number: QTBUG-75840 Task-number: QTBUG-76606 Change-Id: I76944df4c5db6f4954c464e3741a8054cb10b40e Reviewed-by: Allan Sandfeld Jensen --- configure.json | 328 +++++++++++++++++++++++++++++++++++++++++ configure.pri | 16 +- mkspecs/features/configure.prf | 103 ------------- mkspecs/features/functions.prf | 99 ++++++++++++- mkspecs/features/platform.prf | 4 +- qtwebengine.pro | 15 +- src/buildtools/gn.pro | 2 +- src/buildtools/ninja.pro | 2 +- src/core/config/common.pri | 6 +- src/core/config/windows.pri | 2 +- src/core/configure.json | 276 ++++++---------------------------- src/core/core_module.pro | 2 +- src/core/gn_run.pro | 3 +- src/src.pro | 59 +++++--- tests/auto/auto.pro | 8 +- tests/tests.pro | 6 +- 16 files changed, 543 insertions(+), 388 deletions(-) delete mode 100644 mkspecs/features/configure.prf diff --git a/configure.json b/configure.json index 9c49729be..4801beb94 100644 --- a/configure.json +++ b/configure.json @@ -1,7 +1,335 @@ { + "files": { + "privatePro": "src/qtwebengine-main-config.pri" + }, + "subconfigs": [ "src/core", "src/webengine", "src/webenginewidgets" + ], + "commandline": { + "options": { + "webengine-core": "boolean" + } + }, + "libraries": { + "webengine-dbus": { + "label": "d-bus", + "sources": [ + { "type": "pkgConfig", "args": "dbus-1" } + ] + }, + "webengine-fontconfig": { + "label": "fontconfig", + "sources": [ + { "type": "pkgConfig", "args": "fontconfig" } + ] + }, + "webengine-libdrm": { + "label": "libdrm", + "sources": [ + { "type": "pkgConfig", "args": "libdrm" } + ] + }, + "webengine-xcomposite": { + "label": "xcomposite", + "sources": [ + { "type": "pkgConfig", "args": "xcomposite" } + ] + }, + "webengine-xcursor": { + "label": "xcursor", + "sources": [ + { "type": "pkgConfig", "args": "xcursor" } + ] + }, + "webengine-xi": { + "label": "xi", + "sources": [ + { "type": "pkgConfig", "args": "xi" } + ] + }, + "webengine-xtst": { + "label": "xtst", + "sources": [ + { "type": "pkgConfig", "args": "xtst" } + ] + }, + "webengine-nss": { + "label": "nss >= 3.26", + "sources": [ + { "type": "pkgConfig", "args": "nss >= 3.26" } + ] + }, + "webengine-x11" : { + "label" : "x11", + "sources": [ + { "type": "pkgConfig", "args": "x11" } + ] + } + }, + + "testDir": "config.tests", + "tests" : { + "webengine-bison": { + "label": "bison", + "type": "detectBison" + }, + "webengine-flex": { + "label": "flex", + "type": "detectFlex" + }, + "webengine-gn": { + "label": "system gn", + "type": "detectGn" + }, + "webengine-glibc": { + "label": "glibc > 2.26", + "type": "compile", + "test": { + "include": "features.h", + "tail": [ + "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 27", + "#error glibc versions below 2.27 are not supported", + "#endif" + ] + } + }, + "webengine-gperf": { + "label": "gperf", + "type": "detectGperf" + }, + "webengine-khr": { + "label": "khr", + "type": "compile", + "test": { + "include": "KHR/khrplatform.h", + "qmake" : [ + "!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL", + "!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL" + ] + } + }, + "webengine-ninja": { + "label": "system ninja", + "type": "detectNinja" + }, + "webengine-python2": { + "label": "python2", + "type": "detectPython2", + "log": "location" + }, + "webengine-winversion": { + "label": "winversion", + "type": "compile", + "test": { + "head" : [ + "#if !defined(__clang__) && _MSC_FULL_VER < 191426428", + "#error unsupported Visual Studio version", + "#endif" + ] + } + }, + "webengine-host-pkg-config": { + "label": "host pkg-config", + "type": "detectHostPkgConfig", + "log": "path" + }, + "webengine-xcb": { + "label": "qtbase xcb", + "type": "detectXcb" + } + }, + "features": { + "webengine-core": { + "label": "Support Qt WebEngine Core", + "purpose": "Provides WebEngine Core support.", + "condition": "module.gui + && features.webengine-python2 + && features.webengine-gperf + && features.webengine-bison + && features.webengine-flex + && (!tests.webengine-xcb || features.webengine-ozone-x11)", + "output": [ "privateFeature" ] + }, + "webengine-python2": { + "label": "python2", + "condition": "tests.webengine-python2", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" } + ] + }, + "webengine-gperf": { + "label": "gperf", + "condition": "tests.webengine-gperf", + "output": [ "privateFeature" ] + }, + "webengine-bison": { + "label": "bison", + "condition": "tests.webengine-bison", + "output": [ "privateFeature" ] + }, + "webengine-flex": { + "label": "flex", + "condition": "tests.webengine-flex", + "output": [ "privateFeature" ] + }, + "webengine-system-ninja": { + "label": "Use System Ninja", + "condition": "tests.webengine-ninja", + "output": [ "privateFeature" ] + }, + "webengine-system-fontconfig": { + "label": "fontconfig", + "condition": "libs.webengine-fontconfig", + "output": [ "privateFeature" ] + }, + "webengine-system-dbus": { + "label": "dbus", + "condition": "libs.webengine-dbus", + "output": [ "privateFeature" ] + }, + "webengine-system-libdrm": { + "label": "libdrm", + "condition": "libs.webengine-libdrm", + "output": [ "privateFeature" ] + }, + "webengine-system-xcomposite": { + "label": "xcomposite", + "condition": "libs.webengine-xcomposite", + "output": [ "privateFeature" ] + }, + "webengine-system-xcursor": { + "label": "xcursor", + "condition": "libs.webengine-xcursor", + "output": [ "privateFeature" ] + }, + "webengine-system-xi": { + "label": "xi", + "condition": "libs.webengine-xi", + "output": [ "privateFeature" ] + }, + "webengine-system-xtst": { + "label": "xtst", + "condition": "libs.webengine-xtst", + "output": [ "privateFeature" ] + }, + "webengine-system-gn": { + "label": "Use System Gn", + "autoDetect": "false", + "condition": "tests.webengine-gn", + "output": [ "privateFeature" ] + }, + "webengine-system-khr" : { + "label": "khr", + "condition": "config.unix && tests.webengine-khr", + "output": [ "privateFeature" ] + }, + "webengine-system-nss": { + "label": "nss", + "condition": "config.unix && !config.darwin && libs.webengine-nss", + "output": [ "privateFeature" ] + }, + "webengine-system-glibc": { + "label": "glibc", + "condition": "config.linux && tests.webengine-glibc", + "output": [ "privateFeature" ] + }, + "webengine-system-x11" : { + "label": "x11", + "condition": "config.unix && libs.webengine-x11", + "output": [ "privateFeature" ] + }, + "webengine-host-pkg-config": { + "label": "host-pkg-config", + "condition": "config.unix && tests.webengine-host-pkg-config", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" } + ] + }, + "webengine-ozone-x11" : { + "label": "Support qpa-xcb", + "condition": "config.unix + && tests.webengine-xcb + && features.webengine-system-x11 + && features.webengine-system-libdrm + && features.webengine-system-xcomposite + && features.webengine-system-xcursor + && features.webengine-system-xi + && features.webengine-system-xtst", + "output": [ "privateFeature" ] + }, + "webengine-winversion" : { + "label": "winversion", + "condition": "config.win32 && tests.webengine-winversion", + "output": [ "privateFeature" ] + } + }, + "report": [ + { + "type": "warning", + "condition": "!module.gui", + "message": "QtWebEngine requires QtGui." + }, + { + "type": "warning", + "condition": "!features.webengine-python2", + "message": "Python version 2 (2.7.5 or later) is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "!features.webengine-gperf", + "message": "gperf is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "!features.webengine-bison", + "message": "bison is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "!features.webengine-flex", + "message": "flex is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "config.linux && !features.webengine-ozone-x11 && tests.webengine-xcb", + "message": "Could not find all necessary libraries for qpa-xcb support." + } + ], + "summary": [ + { + "section": "Build Tools", + "entries": [ + "webengine-system-ninja", + "webengine-system-gn" + ] + }, + { + "section": "Required system libraries", + "condition": "config.unix && !config.macos && features.webengine-core", + "entries": [ + "webengine-system-fontconfig", + "webengine-system-dbus", + "webengine-system-nss", + "webengine-system-khr", + "webengine-system-glibc" + ] + }, + { + "section": "Required system libraries for qpa-xcb", + "condition": "config.unix && !config.macos && features.webengine-core", + "entries": [ + "webengine-system-x11", + "webengine-system-libdrm", + "webengine-system-xcomposite", + "webengine-system-xcursor", + "webengine-system-xi", + "webengine-system-xtst" + ] + } ] } diff --git a/configure.pri b/configure.pri index 23f72c5c6..a90b06687 100644 --- a/configure.pri +++ b/configure.pri @@ -120,7 +120,7 @@ defineTest(qtConfTest_detectGn) { return(false) } -defineTest(qtConfTest_embedded) { +defineTest(qtConfTest_detectEmbedded) { lessThan(QT_MINOR_VERSION, 9) { cross_compile: return(true) return(false) @@ -129,6 +129,20 @@ defineTest(qtConfTest_embedded) { return(false) } +defineTest(qtConfTest_detectXcb) { + #workaround for for not working 'depends' in main configure when no 'module' + QT_FOR_CONFIG += gui-private + qtConfig(xcb): return(true) + return(false) +} + +defineTest(qtConfTest_detectDeveloperBuild) { + #workaround for for not working 'depends' in main configure when no 'module' + QT_FOR_CONFIG += core-private + qtConfig(private_tests): return(true) # enabled for developer-build + return(false) +} + defineTest(qtConfTest_detectHostPkgConfig) { PKG_CONFIG = $$qtConfPkgConfig(true) isEmpty(PKG_CONFIG) { diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf deleted file mode 100644 index cc84182b7..000000000 --- a/mkspecs/features/configure.prf +++ /dev/null @@ -1,103 +0,0 @@ -# Load configure.prf from qtbase first -load(configure) -load(functions) -load(platform) - -defineTest(runConfigure) { - !qtHaveModule(gui) { - skipBuild("QtWebEngine requires QtGui.") - return(false) - } - - !exists(src/3rdparty/chromium) { - skipBuild("Submodule qtwebengine-chromium does not exist. Run 'git submodule update --init'.") - return(false) - } - - WSPC = $$find(OUT_PWD, \\s) - !isEmpty(WSPC) { - skipBuild("QtWebEngine cannot be built in a path that contains whitespace characters.") - return(false) - } - - !isPlatformSupported() { - # make sure we have skipBuildReason - isEmpty(skipBuildReason): skipBuild("Unknow error. Platform unspported") - return(false) - } - - linux:contains(QT_CONFIG,no-pkg-config) { - skipBuild("pkg-config is required") - return(false) - } - - include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) - QT_FOR_CONFIG += webenginecore-private - - !qtConfig(webengine-v8-snapshot-support):qtConfig(webengine-v8-snapshot) { - skipBuild("V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work."\ - "Please make sure you have 32-bit devel environment installed, or "\ - "configure webengine with '-no-webengine-v8-snapshot'") - return(false) - } - - win32:!qtConfig(webengine-win-compiler64) { - skipBuild("Required 64-bit cross-building or native toolchain could not be found.") - return(false) - } - - !qtConfig(webengine-gperf) { - skipBuild("Required gperf could not be found.") - return(false) - } - !qtConfig(webengine-bison) { - skipBuild("Required bison could not be found.") - return(false) - } - !qtConfig(webengine-flex) { - skipBuild("Required flex could not be found.") - return(false) - } - !qtConfig(webengine-python2) { - skipBuild("A suitable version of python2 could not be found.") - return(false) - } - - sanitizer: !qtConfig(webengine-sanitizer) { - skipBuild("Chosen sanitizer configuration is not supported. Check config.log for details or use -feature-webengine-sanitizer to force build with the chosen sanitizer configuration.") - return(false); - } - - linux { - - !qtConfig(webengine-host-pkg-config) { - skipBuild("Host pkg-config is required") - return(false) - } - - !qtConfig(webengine-system-glibc) { - skipBuild("A suitable version >= 2.27 of libc could not be found.") - return(false) - } - - QT_FOR_CONFIG += gui-private - - !qtConfig(webengine-system-khr) { - skipBuild("khronos development headers appear to be missing (mesa/libegl1-mesa-dev)") - return(false) - } - - for(package, $$list("nss dbus fontconfig")) { - !qtConfig(webengine-system-$$package) { - skipBuild("A suitable version of $$package could not be found.") - return(false) - } - } - - !qtConfig(webengine-embedded-build): qtConfig(xcb) : !qtConfig(webengine-ozone-x11) { - skipBuild("Could not find all necessary libraries for qpa-xcb support") - return(false) - } - } -} - diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf index d3eda85b2..f858243e1 100644 --- a/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -96,16 +96,103 @@ defineReplace(gnOS) { return(unknown) } -defineTest(isDeveloperBuild) { - qtConfig(private_tests): return(true) # enabled for developer-build - return(false) -} - defineTest(skipBuild) { - skipBuildReason = "$$skipBuildReason $${EOL}$$1" + isEmpty(skipBuildReason): skipBuildReason = $$1 + else: skipBuildReason = "$$skipBuildReason $${EOL}$$1" export(skipBuildReason) } +defineTest(isWebEngineCoreBuild) { + !qtHaveModule(gui) { + skipBuild("QtWebEngine requires QtGui.") + return(false) + } + + !exists($$QTWEBENGINE_ROOT/src/3rdparty/chromium) { + skipBuild("Submodule qtwebengine-chromium does not exist. Run 'git submodule update --init'.") + return(false) + } + + WSPC = $$find(OUT_PWD, \\s) + !isEmpty(WSPC) { + skipBuild("QtWebEngine cannot be built in a path that contains whitespace characters.") + return(false) + } + + !isPlatformSupported() { + # make sure we have skipBuildReason + isEmpty(skipBuildReason): skipBuild("Unknow error. Platform unspported") + return(false) + } + + linux:contains(QT_CONFIG,no-pkg-config) { + skipBuild("pkg-config is required") + return(false) + } + + include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) + QT_FOR_CONFIG += webenginecore-private + + win32:!qtConfig(webengine-win-compiler64) { + skipBuild("Required 64-bit cross-building or native toolchain could not be found.") + return(false) + } + + !qtConfig(webengine-gperf) { + skipBuild("Required gperf could not be found.") + return(false) + } + !qtConfig(webengine-bison) { + skipBuild("Required bison could not be found.") + return(false) + } + !qtConfig(webengine-flex) { + skipBuild("Required flex could not be found.") + return(false) + } + !qtConfig(webengine-python2) { + skipBuild("A suitable version of python2 could not be found.") + return(false) + } + + sanitizer: !qtConfig(webengine-sanitizer) { + skipBuild("Chosen sanitizer configuration is not supported. Check config.log for details or use -feature-webengine-sanitizer to force build with the chosen sanitizer configuration.") + return(false); + } + + linux { + + !qtConfig(webengine-host-pkg-config) { + skipBuild("Host pkg-config is required") + return(false) + } + + !qtConfig(webengine-system-glibc) { + skipBuild("A suitable version >= 2.27 of libc could not be found.") + return(false) + } + + QT_FOR_CONFIG += gui-private + + !qtConfig(webengine-system-khr) { + skipBuild("khronos development headers appear to be missing (mesa/libegl1-mesa-dev)") + return(false) + } + + for(package, $$list("nss dbus fontconfig")) { + !qtConfig(webengine-system-$$package) { + skipBuild("A suitable version of $$package could not be found.") + return(false) + } + } + + qtConfig(xcb) : !qtConfig(webengine-ozone-x11) { + skipBuild("Could not find all necessary libraries for qpa-xcb support") + return(false) + } + } +} + defineReplace(pkgConfigHostExecutable) { wrapper_name = $$OUT_PWD/pkg-config-host_wrapper.sh wrapper_cmd = $$QMAKE_PKG_CONFIG_HOST diff --git a/mkspecs/features/platform.prf b/mkspecs/features/platform.prf index ef1c86d39..bdd81d337 100644 --- a/mkspecs/features/platform.prf +++ b/mkspecs/features/platform.prf @@ -1,5 +1,4 @@ -include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -QT_FOR_CONFIG += webenginecore-private +include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) defineTest(isQtMinimum) { !equals(QT_MAJOR_VERSION, $$1): return(false) @@ -24,6 +23,7 @@ defineTest(isPlatformSupported) { } isBuildingOnWin32() { skipBuild("Qt WebEngine on Windows must be built on a 64-bit machine.") + return(false) } !msvc|intel_icl { skipBuild("Qt WebEngine on Windows requires MSVC or Clang (MSVC mode).") diff --git a/qtwebengine.pro b/qtwebengine.pro index 620f451f1..6d4089b26 100644 --- a/qtwebengine.pro +++ b/qtwebengine.pro @@ -1,13 +1,6 @@ load(qt_parts) -load(configure) - -runConfigure() - -!isEmpty(skipBuildReason) { - SUBDIRS = - log($${skipBuildReason}$${EOL}) - log(QtWebEngine will not be built.$${EOL}) -} +load(functions) +load(platform) QMAKE_DISTCLEAN += .qmake.cache @@ -20,3 +13,7 @@ OTHER_FILES = \ config.tests/snappy/* \ config.tests/re2/* \ mkspecs/features/* + +!isWebEngineCoreBuild():!isEmpty(skipBuildReason):!build_pass { + log(QtWebEngine will not be built. $${skipBuildReason} $${EOL}) +} diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro index b6bf9cfc4..6b0a41fbe 100644 --- a/src/buildtools/gn.pro +++ b/src/buildtools/gn.pro @@ -3,7 +3,7 @@ option(host_build) !debug_and_release: CONFIG += release -include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) +include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) QT_FOR_CONFIG += webenginecore-private build_pass|!debug_and_release { diff --git a/src/buildtools/ninja.pro b/src/buildtools/ninja.pro index 6382d6cfb..dee285b7e 100644 --- a/src/buildtools/ninja.pro +++ b/src/buildtools/ninja.pro @@ -2,7 +2,7 @@ TEMPLATE = aux !debug_and_release: CONFIG += release -include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) +include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) QT_FOR_CONFIG += webenginecore-private build_pass|!debug_and_release { diff --git a/src/core/config/common.pri b/src/core/config/common.pri index edebdb33c..019b77c49 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -73,11 +73,11 @@ precompile_header { gn_args += enable_precompiled_headers=false } -CONFIG(release, debug|release):!isDeveloperBuild() { +CONFIG(release, debug|release):!qtConfig(webengine-developer-build) { gn_args += is_official_build=true } else { gn_args += is_official_build=false - !isDeveloperBuild(): gn_args += is_unsafe_developer_build=false + !qtConfig(webengine-developer-build): gn_args += is_unsafe_developer_build=false } CONFIG(release, debug|release) { @@ -116,7 +116,7 @@ optimize_size: gn_args += optimize_for_size=true sanitize_undefined: gn_args += is_ubsan=true is_ubsan_vptr=true } -qtConfig(webengine-v8-snapshot) { +qtConfig(webengine-v8-snapshot):qtConfig(webengine-v8-snapshot-support) { gn_args += v8_use_snapshot=true } else { gn_args += v8_use_snapshot=false diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri index 385faeed0..dfa40e9dc 100644 --- a/src/core/config/windows.pri +++ b/src/core/config/windows.pri @@ -22,7 +22,7 @@ clang_cl { gn_args += is_clang=false use_lld=false } -isDeveloperBuild() { +qtConfig(webengine-developer-build) { gn_args += \ is_win_fastlink=true diff --git a/src/core/configure.json b/src/core/configure.json index d868e7f12..a93132326 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -5,7 +5,7 @@ "gui-private", "printsupport" ], - "condition": "module.gui", + "condition": "features.webengine-core", "testDir": "../../config.tests", "commandline": { "options": { @@ -56,18 +56,6 @@ "sources" : [{ "type": "pkgConfig", "args": "alsa" } ] }, - "webengine-dbus": { - "label": "d-bus", - "sources": [ - { "type": "pkgConfig", "args": "dbus-1" } - ] - }, - "webengine-fontconfig": { - "label": "fontconfig", - "sources": [ - { "type": "pkgConfig", "args": "fontconfig" } - ] - }, "webengine-libdrm": { "label": "libdrm", "sources": [ @@ -189,12 +177,6 @@ { "type": "pkgConfig", "args": "libwebp libwebpmux libwebpdemux" } ] }, - "webengine-nss": { - "label": "nss >= 3.26", - "sources": [ - { "type": "pkgConfig", "args": "nss >= 3.26" } - ] - }, "webengine-png": { "label": "libpng >= 1.6.0", "sources": [ @@ -276,12 +258,6 @@ "-lsnappy" ] }, - "webengine-x11" : { - "label" : "x11", - "sources": [ - { "type": "pkgConfig", "args": "x11" } - ] - }, "webengine-libvpx": { "label": "libvpx", "test": { @@ -305,77 +281,22 @@ "host": "true", "type": "compile" }, - "webengine-khr": { - "label": "khr", - "type": "compile", - "test": { - "include": "KHR/khrplatform.h", - "qmake" : [ - "!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL", - "!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL" - ] - } - }, - "webengine-winversion": { - "label": "winversion", - "type": "compile", - "test": { - "head" : [ - "#if !defined(__clang__) && _MSC_FULL_VER < 191426428", - "#error unsupported Visual Studio version", - "#endif" - ] - } - }, "webengine-protoc": { "label": "protoc", "type": "detectProtoc" }, - "webengine-python2": { - "label": "python2", - "type": "detectPython2", - "log": "location" - }, "webengine-host-pkg-config": { "label": "host pkg-config", "type": "detectHostPkgConfig", "log": "path" }, - "webengine-gperf": { - "label": "gperf", - "type": "detectGperf" - }, - "webengine-bison": { - "label": "bison", - "type": "detectBison" - }, - "webengine-flex": { - "label": "flex", - "type": "detectFlex" - }, - "webengine-ninja": { - "label": "system ninja", - "type": "detectNinja" - }, - "webengine-gn": { - "label": "system gn", - "type": "detectGn" - }, "webengine-embedded-build": { - "label": "embedded", - "type": "embedded" + "label": "embedded build", + "type": "detectEmbedded" }, - "webengine-glibc": { - "label": "glibc > 2.26", - "type": "compile", - "test": { - "include": "features.h", - "tail": [ - "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 27", - "#error glibc versions below 2.27 are not supported", - "#endif" - ] - } + "webengine-developer-build": { + "label": "developer build", + "type": "detectDeveloperBuild" }, "webengine-sanitizer": { "label" : "sanitizer support", @@ -399,18 +320,7 @@ "flag": "-z,noexecstack" } }, - "features": { - "webengine-system-fontconfig": { - "label": "fontconfig", - "condition": "libs.webengine-fontconfig", - "output": [ "privateFeature" ] - }, - "webengine-system-dbus": { - "label": "dbus", - "condition": "libs.webengine-dbus", - "output": [ "privateFeature" ] - }, "webengine-system-libdrm": { "label": "libdrm", "condition": "libs.webengine-libdrm", @@ -481,37 +391,6 @@ "condition": "config.unix && features.system-jpeg && libs.webengine-jpeglib", "output": [ "privateFeature" ] }, - "webengine-python2": { - "label": "python2", - "condition": "tests.webengine-python2", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" } - ] - }, - "webengine-host-pkg-config": { - "label": "host-pkg-config", - "condition": "config.unix && tests.webengine-host-pkg-config", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" } - ] - }, - "webengine-gperf": { - "label": "gperf", - "condition": "tests.webengine-gperf", - "output": [ "privateFeature" ] - }, - "webengine-bison": { - "label": "bison", - "condition": "tests.webengine-bison", - "output": [ "privateFeature" ] - }, - "webengine-flex": { - "label": "flex", - "condition": "tests.webengine-flex", - "output": [ "privateFeature" ] - }, "webengine-embedded-build": { "label": "Embedded build", "purpose": "Enables the embedded build configuration.", @@ -520,6 +399,12 @@ "autoDetect": "tests.webengine-embedded-build", "output": [ "privateFeature" ] }, + "webengine-developer-build": { + "label": "Developer build", + "purpose": "Enables the developer build configuration.", + "autoDetect": "tests.webengine-developer-build", + "output": [ "privateFeature" ] + }, "webengine-alsa": { "label": "Use ALSA", "condition": "config.unix && libs.webengine-alsa", @@ -536,11 +421,6 @@ "condition": "!config.unix || !features.cross_compile || arch.arm64 || tests.webengine-host-compiler", "output": [ "privateFeature" ] }, - "webengine-system-khr" : { - "label": "khr", - "condition": "config.unix && tests.webengine-khr", - "output": [ "privateFeature" ] - }, "webengine-system-libvpx" : { "label": "libvpx", "condition": "config.unix && libs.webengine-libvpx", @@ -551,11 +431,6 @@ "condition": "config.unix && libs.webengine-snappy", "output": [ "privateFeature" ] }, - "webengine-winversion" : { - "label": "winversion", - "condition": "config.win32 && tests.webengine-winversion", - "output": [ "privateFeature" ] - }, "webengine-geolocation": { "label": "Geolocation", "condition": "module.positioning", @@ -632,11 +507,6 @@ "autoDetect": "!features.webengine-embedded-build", "output": [ "privateFeature" ] }, - "webengine-system-nss": { - "label": "nss", - "condition": "config.unix && !config.darwin && libs.webengine-nss", - "output": [ "privateFeature" ] - }, "webengine-system-libwebp": { "label": "libwebp, libwebpmux and libwebpdemux", "autoDetect": "config.unix", @@ -667,22 +537,6 @@ "condition": "libs.webengine-re2", "output": [ "privateFeature" ] }, - "webengine-system-ninja": { - "label": "Use System Ninja", - "condition": "tests.webengine-ninja", - "output": [ "privateFeature" ] - }, - "webengine-system-gn": { - "label": "Use System Gn", - "autoDetect": false, - "condition": "tests.webengine-gn", - "output": [ "privateFeature" ] - }, - "webengine-system-glibc": { - "label": "glibc", - "condition": "config.linux && tests.webengine-glibc", - "output": [ "privateFeature" ] - }, "webengine-system-libxml2": { "label": "libxml2 and libxslt", "condition": "config.unix && libs.webengine-libxml2", @@ -699,11 +553,6 @@ "condition": "config.unix && features.system-freetype && libs.webengine-freetype", "output": [ "privateFeature" ] }, - "webengine-system-x11" : { - "label": "x11", - "condition": "config.unix && libs.webengine-x11", - "output": [ "privateFeature" ] - }, "webengine-ozone-x11" : { "label": "Support qpa-xcb", "condition": "config.unix @@ -755,26 +604,6 @@ }, "report": [ - { - "type": "warning", - "condition": "!features.webengine-python2", - "message": "Python version 2 (2.7.5 or later) is required to build QtWebEngine." - }, - { - "type": "warning", - "condition": "!features.webengine-gperf", - "message": "gperf is required to build QtWebEngine." - }, - { - "type": "warning", - "condition": "!features.webengine-bison", - "message": "bison is required to build QtWebEngine." - }, - { - "type": "warning", - "condition": "!features.webengine-flex", - "message": "flex is required to build QtWebEngine." - }, { "type": "warning", "condition": "config.sanitizer && !tests.webengine-sanitizer && !features.webengine-sanitizer", @@ -794,14 +623,46 @@ "type": "warning", "condition": "config.linux && features.webengine-embedded-build && !features.webengine-system-ffmpeg && arch.arm && !features.webengine-arm-thumb", "message": "Thumb instruction set is required to build ffmpeg for QtWebEngine." + }, + { + "type": "warning", + "condition": "config.linux && features.webengine-v8-snapshot && !features.webengine-v8-snapshot-support", + "message": "V8 snapshot cannot be built. Most likely, the 32-bit host compiler does not work. Please make sure you have 32-bit devel environment installed." } ], "summary": [ + { + "section": "Optional system libraries used", + "condition": "config.unix", + "entries": [ + "webengine-system-re2", + "webengine-system-icu", + "webengine-system-libwebp", + "webengine-system-opus", + "webengine-system-ffmpeg", + "webengine-system-libvpx", + "webengine-system-snappy", + "webengine-system-glib", + "webengine-system-zlib", + "webengine-system-minizip", + "webengine-system-libevent", + "webengine-system-jsoncpp", + "webengine-system-protobuf", + "webengine-system-libxml2", + "webengine-system-lcms2", + "webengine-system-png", + "webengine-system-jpeg", + "webengine-system-harfbuzz", + "webengine-system-freetype" + ] + }, { "section": "Qt WebEngineCore", + "condition": "features.webengine-core", "entries": [ "webengine-embedded-build", + "webengine-developer-build", "webengine-full-debug-info", "webengine-pepper-plugins", "webengine-printing-and-pdf", @@ -809,7 +670,6 @@ "webengine-spellchecker", "webengine-native-spellchecker", "webengine-webrtc", - "webengine-system-ninja", "webengine-geolocation", "webengine-webchannel", "webengine-v8-snapshot", @@ -869,54 +729,6 @@ "type": "macosToolchainVersion", "args": "deploymentTarget", "condition": "config.macos" - }, - { - "section": "Optional system libraries used", - "condition": "config.unix", - "entries": [ - "webengine-system-re2", - "webengine-system-icu", - "webengine-system-libwebp", - "webengine-system-opus", - "webengine-system-ffmpeg", - "webengine-system-libvpx", - "webengine-system-snappy", - "webengine-system-glib", - "webengine-system-zlib", - "webengine-system-minizip", - "webengine-system-libevent", - "webengine-system-jsoncpp", - "webengine-system-protobuf", - "webengine-system-libxml2", - "webengine-system-lcms2", - "webengine-system-png", - "webengine-system-jpeg", - "webengine-system-harfbuzz", - "webengine-system-freetype" - ] - }, - { - "section": "Required system libraries", - "condition": "config.unix && !config.macos", - "entries": [ - "webengine-system-fontconfig", - "webengine-system-dbus", - "webengine-system-nss", - "webengine-system-khr", - "webengine-system-glibc" - ] - }, - { - "section": "Required system libraries for qpa-xcb", - "condition": "config.unix && !config.macos", - "entries": [ - "webengine-system-x11", - "webengine-system-libdrm", - "webengine-system-xcomposite", - "webengine-system-xcursor", - "webengine-system-xi", - "webengine-system-xtst" - ] } ] } diff --git a/src/core/core_module.pro b/src/core/core_module.pro index b220af4a5..4b9268e1a 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -63,7 +63,7 @@ CONFIG *= no_smart_library_merge osx { LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a } else: win32 { - !isDeveloperBuild() { + !qtConfig(webengine-developer-build) { # Remove unused functions and data in debug non-developer builds, because the binaries will # be smaller in the shipped packages. QMAKE_LFLAGS += /OPT:REF diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro index 0219a2be9..94c1ede1c 100644 --- a/src/core/gn_run.pro +++ b/src/core/gn_run.pro @@ -1,5 +1,6 @@ +include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -QT_FOR_CONFIG += webenginecore-private +QT_FOR_CONFIG += webenginecore-private core-private gui-private TEMPLATE = aux diff --git a/src/src.pro b/src/src.pro index 8bf014dea..1ace7a44b 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,34 +1,49 @@ -include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) -include($$QTWEBENGINE_OUT_ROOT/src/webenginewidgets/qtwebenginewidgets-config.pri) -QT_FOR_CONFIG += webenginecore webenginecore-private webengine-private webenginewidgets-private +load(platform) + +include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) TEMPLATE = subdirs -process.depends = core -webengine.depends = core -webenginewidgets.depends = core webengine -webengine_plugin.subdir = webengine/plugin -webengine_plugin.target = sub-webengine-plugin -webengine_plugin.depends = webengine +isWebEngineCoreBuild():qtConfig(webengine-core) { + include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) + include($$QTWEBENGINE_OUT_ROOT/src/webengine/qtwebengine-config.pri) + include($$QTWEBENGINE_OUT_ROOT/src/webenginewidgets/qtwebenginewidgets-config.pri) + QT_FOR_CONFIG += webenginecore webenginecore-private webengine-private webenginewidgets-private + + process.depends = core + webengine.depends = core + webenginewidgets.depends = core webengine + webengine_plugin.subdir = webengine/plugin + webengine_plugin.target = sub-webengine-plugin + webengine_plugin.depends = webengine -core.depends = buildtools + core.depends = buildtools -SUBDIRS += buildtools \ - core \ - process + SUBDIRS += buildtools \ + core \ + process -qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile { + qtConfig(webengine-spellchecker):!qtConfig(webengine-native-spellchecker):!cross_compile { SUBDIRS += qwebengine_convert_dict qwebengine_convert_dict.subdir = tools/qwebengine_convert_dict qwebengine_convert_dict.depends = core -} + } -qtConfig(webengine-qml) { - SUBDIRS += webengine -} + qtConfig(webengine-qml) { + SUBDIRS += webengine + } -qtConfig(webengine-widgets) { - SUBDIRS += plugins webenginewidgets - plugins.depends = webenginewidgets + qtConfig(webengine-widgets) { + SUBDIRS += plugins webenginewidgets + plugins.depends = webenginewidgets + } +} else { + !isEmpty(skipBuildReason):!build_pass { + log(QtWebEngine will not be built. $${skipBuildReason} $${EOL}) + errorbuild.commands = @echo QtWebEngine will not be built. $${skipBuildReason} + errorbuild.CONFIG = phony + QMAKE_EXTRA_TARGETS += errorbuild + first.depends += errorbuild + QMAKE_EXTRA_TARGETS += first + } } diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 06430cf8e..59bcd5aef 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,9 +1,9 @@ TEMPLATE = subdirs -SUBDIRS = quick +qtHaveModule(webengine) { + SUBDIRS += quick +} qtHaveModule(webenginewidgets) { - SUBDIRS += widgets -# core tests depend on widgets for now - SUBDIRS += core + SUBDIRS += core widgets } diff --git a/tests/tests.pro b/tests/tests.pro index 2922e5076..acb223640 100644 --- a/tests/tests.pro +++ b/tests/tests.pro @@ -1,3 +1,7 @@ TEMPLATE = subdirs -SUBDIRS += auto quicktestbrowser +SUBDIRS += auto + +qtHaveModule(webengine) { + SUBDIRS += quicktestbrowser +} -- cgit v1.2.1 From f7032b40a28f844e4a94633bbc077b1953ef0ed4 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Tue, 13 Aug 2019 15:37:15 +0200 Subject: Add jumbo builds to configure system Adds new feature webenigne-jumbo-build which indicates merge limit for jumbo build, usage: qmake -- --webengine-jumbo-build=8 Change-Id: I7607a83772b53f6db57eb12559989a91f991ce93 Reviewed-by: Allan Sandfeld Jensen --- configure.json | 22 ++++++++++++++++++++-- configure.pri | 20 ++++++++++++++++++++ src/core/config/common.pri | 13 +++++++++---- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/configure.json b/configure.json index 4801beb94..4b9288bbb 100644 --- a/configure.json +++ b/configure.json @@ -10,7 +10,8 @@ ], "commandline": { "options": { - "webengine-core": "boolean" + "webengine-core": "boolean", + "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"} } }, "libraries": { @@ -139,6 +140,11 @@ "webengine-xcb": { "label": "qtbase xcb", "type": "detectXcb" + }, + "webengine-jumbo-build": { + "label": "jumbo build merge limit", + "type": "detectJumboBuild", + "log": "merge_limit" } }, "features": { @@ -266,6 +272,14 @@ "label": "winversion", "condition": "config.win32 && tests.webengine-winversion", "output": [ "privateFeature" ] + }, + "webengine-jumbo-build": { + "label": "jumbo build merge batch", + "condition": "tests.webengine-jumbo-build", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_JUMBO_MERGE_LIMIT", "value": "tests.webengine-jumbo-build.merge_limit" } + ] } }, "report": [ @@ -305,7 +319,11 @@ "section": "Build Tools", "entries": [ "webengine-system-ninja", - "webengine-system-gn" + "webengine-system-gn", + { + "message": "Jumbo Build Merge Limit", + "type": "jumboBuild" + } ] }, { diff --git a/configure.pri b/configure.pri index a90b06687..f94624053 100644 --- a/configure.pri +++ b/configure.pri @@ -22,6 +22,26 @@ defineTest(isPythonVersionSupported) { return(false) } +defineTest(qtConfTest_detectJumboBuild) { + mergeLimit = $$eval(config.input.merge_limit) + mergeLimit = $$find(mergeLimit, "\\d") + isEmpty(mergeLimit): mergeLimit = 0 + qtLog("Setting jumbo build merge batch limit to $${mergeLimit}.") + $${1}.merge_limit = $$mergeLimit + export($${1}.merge_limit) + $${1}.cache += merge_limit + export($${1}.cache) + + return(true) +} + +defineTest(qtConfReport_jumboBuild) { + mergeLimit = $$eval(config.input.merge_limit) + mergeLimit = $$find(mergeLimit, "\d") + isEmpty(mergeLimit): mergeLimit = "no" + qtConfReportPadded($${1}, $$mergeLimit) +} + defineTest(qtConfTest_detectPython2) { python = $$qtConfFindInPath("python2$$EXE_SUFFIX") isEmpty(python) { diff --git a/src/core/config/common.pri b/src/core/config/common.pri index 019b77c49..df8aeb1cc 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -28,10 +28,15 @@ gn_args += \ safe_browsing_mode=0 \ optimize_webui=false -!win32: gn_args += \ - use_jumbo_build=true \ - jumbo_file_merge_limit=8 \ - jumbo_build_excluded="[\"browser\"]" +greaterThan(QMAKE_JUMBO_MERGE_LIMIT,0) { + gn_args += \ + use_jumbo_build=true \ + jumbo_file_merge_limit=$$QMAKE_JUMBO_MERGE_LIMIT +} + +!greaterThan(QMAKE_JUMBO_MERGE_LIMIT,8) { + gn_args += jumbo_build_excluded="[\"browser\"]" +} qtConfig(webengine-printing-and-pdf) { gn_args += enable_basic_printing=true enable_print_preview=true -- cgit v1.2.1 From 8684373c08a774a7ed23682a358de991b8775ddd Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 14 Aug 2019 12:05:50 +0200 Subject: Move main configure and move some tests from core to buildtools Processing configuration for gn when building qpdfcore module will require optional libraries resolved. Some libs are not needed, but this requires extra patching of gn build configs; so to keep things simple, just detect all the libs beforehand. Unfortunately using this for main configure goes bonkers. The issue here is that main configure resets features in global scope, which can break features coming from qtbase and results in bogus configurations in certain cases. Therefore move current configuration to buildtools and make everything else depend on this. Task-number: QTBUG-75840 Task-number: QTBUG-76606 Change-Id: Id87f5ba017541a2d5a2836510c6cabc5a19f92c6 Reviewed-by: Allan Sandfeld Jensen --- configure.json | 347 +------------------- configure.pri | 14 - mkspecs/features/functions.prf | 4 +- mkspecs/features/platform.prf | 3 +- src/buildtools/configure.json | 716 +++++++++++++++++++++++++++++++++++++++++ src/buildtools/gn.pro | 4 +- src/buildtools/ninja.pro | 4 +- src/core/config/common.pri | 3 +- src/core/configure.json | 381 +--------------------- src/core/core_common.pri | 3 +- src/core/gn_run.pro | 4 +- src/src.pro | 3 +- 12 files changed, 735 insertions(+), 751 deletions(-) create mode 100644 src/buildtools/configure.json diff --git a/configure.json b/configure.json index 4b9288bbb..8caad24f0 100644 --- a/configure.json +++ b/configure.json @@ -1,353 +1,8 @@ { - "files": { - "privatePro": "src/qtwebengine-main-config.pri" - }, - "subconfigs": [ + "src/buildtools", "src/core", "src/webengine", "src/webenginewidgets" - ], - "commandline": { - "options": { - "webengine-core": "boolean", - "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"} - } - }, - "libraries": { - "webengine-dbus": { - "label": "d-bus", - "sources": [ - { "type": "pkgConfig", "args": "dbus-1" } - ] - }, - "webengine-fontconfig": { - "label": "fontconfig", - "sources": [ - { "type": "pkgConfig", "args": "fontconfig" } - ] - }, - "webengine-libdrm": { - "label": "libdrm", - "sources": [ - { "type": "pkgConfig", "args": "libdrm" } - ] - }, - "webengine-xcomposite": { - "label": "xcomposite", - "sources": [ - { "type": "pkgConfig", "args": "xcomposite" } - ] - }, - "webengine-xcursor": { - "label": "xcursor", - "sources": [ - { "type": "pkgConfig", "args": "xcursor" } - ] - }, - "webengine-xi": { - "label": "xi", - "sources": [ - { "type": "pkgConfig", "args": "xi" } - ] - }, - "webengine-xtst": { - "label": "xtst", - "sources": [ - { "type": "pkgConfig", "args": "xtst" } - ] - }, - "webengine-nss": { - "label": "nss >= 3.26", - "sources": [ - { "type": "pkgConfig", "args": "nss >= 3.26" } - ] - }, - "webengine-x11" : { - "label" : "x11", - "sources": [ - { "type": "pkgConfig", "args": "x11" } - ] - } - }, - - "testDir": "config.tests", - "tests" : { - "webengine-bison": { - "label": "bison", - "type": "detectBison" - }, - "webengine-flex": { - "label": "flex", - "type": "detectFlex" - }, - "webengine-gn": { - "label": "system gn", - "type": "detectGn" - }, - "webengine-glibc": { - "label": "glibc > 2.26", - "type": "compile", - "test": { - "include": "features.h", - "tail": [ - "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 27", - "#error glibc versions below 2.27 are not supported", - "#endif" - ] - } - }, - "webengine-gperf": { - "label": "gperf", - "type": "detectGperf" - }, - "webengine-khr": { - "label": "khr", - "type": "compile", - "test": { - "include": "KHR/khrplatform.h", - "qmake" : [ - "!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL", - "!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL" - ] - } - }, - "webengine-ninja": { - "label": "system ninja", - "type": "detectNinja" - }, - "webengine-python2": { - "label": "python2", - "type": "detectPython2", - "log": "location" - }, - "webengine-winversion": { - "label": "winversion", - "type": "compile", - "test": { - "head" : [ - "#if !defined(__clang__) && _MSC_FULL_VER < 191426428", - "#error unsupported Visual Studio version", - "#endif" - ] - } - }, - "webengine-host-pkg-config": { - "label": "host pkg-config", - "type": "detectHostPkgConfig", - "log": "path" - }, - "webengine-xcb": { - "label": "qtbase xcb", - "type": "detectXcb" - }, - "webengine-jumbo-build": { - "label": "jumbo build merge limit", - "type": "detectJumboBuild", - "log": "merge_limit" - } - }, - "features": { - "webengine-core": { - "label": "Support Qt WebEngine Core", - "purpose": "Provides WebEngine Core support.", - "condition": "module.gui - && features.webengine-python2 - && features.webengine-gperf - && features.webengine-bison - && features.webengine-flex - && (!tests.webengine-xcb || features.webengine-ozone-x11)", - "output": [ "privateFeature" ] - }, - "webengine-python2": { - "label": "python2", - "condition": "tests.webengine-python2", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" } - ] - }, - "webengine-gperf": { - "label": "gperf", - "condition": "tests.webengine-gperf", - "output": [ "privateFeature" ] - }, - "webengine-bison": { - "label": "bison", - "condition": "tests.webengine-bison", - "output": [ "privateFeature" ] - }, - "webengine-flex": { - "label": "flex", - "condition": "tests.webengine-flex", - "output": [ "privateFeature" ] - }, - "webengine-system-ninja": { - "label": "Use System Ninja", - "condition": "tests.webengine-ninja", - "output": [ "privateFeature" ] - }, - "webengine-system-fontconfig": { - "label": "fontconfig", - "condition": "libs.webengine-fontconfig", - "output": [ "privateFeature" ] - }, - "webengine-system-dbus": { - "label": "dbus", - "condition": "libs.webengine-dbus", - "output": [ "privateFeature" ] - }, - "webengine-system-libdrm": { - "label": "libdrm", - "condition": "libs.webengine-libdrm", - "output": [ "privateFeature" ] - }, - "webengine-system-xcomposite": { - "label": "xcomposite", - "condition": "libs.webengine-xcomposite", - "output": [ "privateFeature" ] - }, - "webengine-system-xcursor": { - "label": "xcursor", - "condition": "libs.webengine-xcursor", - "output": [ "privateFeature" ] - }, - "webengine-system-xi": { - "label": "xi", - "condition": "libs.webengine-xi", - "output": [ "privateFeature" ] - }, - "webengine-system-xtst": { - "label": "xtst", - "condition": "libs.webengine-xtst", - "output": [ "privateFeature" ] - }, - "webengine-system-gn": { - "label": "Use System Gn", - "autoDetect": "false", - "condition": "tests.webengine-gn", - "output": [ "privateFeature" ] - }, - "webengine-system-khr" : { - "label": "khr", - "condition": "config.unix && tests.webengine-khr", - "output": [ "privateFeature" ] - }, - "webengine-system-nss": { - "label": "nss", - "condition": "config.unix && !config.darwin && libs.webengine-nss", - "output": [ "privateFeature" ] - }, - "webengine-system-glibc": { - "label": "glibc", - "condition": "config.linux && tests.webengine-glibc", - "output": [ "privateFeature" ] - }, - "webengine-system-x11" : { - "label": "x11", - "condition": "config.unix && libs.webengine-x11", - "output": [ "privateFeature" ] - }, - "webengine-host-pkg-config": { - "label": "host-pkg-config", - "condition": "config.unix && tests.webengine-host-pkg-config", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" } - ] - }, - "webengine-ozone-x11" : { - "label": "Support qpa-xcb", - "condition": "config.unix - && tests.webengine-xcb - && features.webengine-system-x11 - && features.webengine-system-libdrm - && features.webengine-system-xcomposite - && features.webengine-system-xcursor - && features.webengine-system-xi - && features.webengine-system-xtst", - "output": [ "privateFeature" ] - }, - "webengine-winversion" : { - "label": "winversion", - "condition": "config.win32 && tests.webengine-winversion", - "output": [ "privateFeature" ] - }, - "webengine-jumbo-build": { - "label": "jumbo build merge batch", - "condition": "tests.webengine-jumbo-build", - "output": [ - "privateFeature", - { "type": "varAssign", "name": "QMAKE_JUMBO_MERGE_LIMIT", "value": "tests.webengine-jumbo-build.merge_limit" } - ] - } - }, - "report": [ - { - "type": "warning", - "condition": "!module.gui", - "message": "QtWebEngine requires QtGui." - }, - { - "type": "warning", - "condition": "!features.webengine-python2", - "message": "Python version 2 (2.7.5 or later) is required to build QtWebEngine." - }, - { - "type": "warning", - "condition": "!features.webengine-gperf", - "message": "gperf is required to build QtWebEngine." - }, - { - "type": "warning", - "condition": "!features.webengine-bison", - "message": "bison is required to build QtWebEngine." - }, - { - "type": "warning", - "condition": "!features.webengine-flex", - "message": "flex is required to build QtWebEngine." - }, - { - "type": "warning", - "condition": "config.linux && !features.webengine-ozone-x11 && tests.webengine-xcb", - "message": "Could not find all necessary libraries for qpa-xcb support." - } - ], - "summary": [ - { - "section": "Build Tools", - "entries": [ - "webengine-system-ninja", - "webengine-system-gn", - { - "message": "Jumbo Build Merge Limit", - "type": "jumboBuild" - } - ] - }, - { - "section": "Required system libraries", - "condition": "config.unix && !config.macos && features.webengine-core", - "entries": [ - "webengine-system-fontconfig", - "webengine-system-dbus", - "webengine-system-nss", - "webengine-system-khr", - "webengine-system-glibc" - ] - }, - { - "section": "Required system libraries for qpa-xcb", - "condition": "config.unix && !config.macos && features.webengine-core", - "entries": [ - "webengine-system-x11", - "webengine-system-libdrm", - "webengine-system-xcomposite", - "webengine-system-xcursor", - "webengine-system-xi", - "webengine-system-xtst" - ] - } ] } diff --git a/configure.pri b/configure.pri index f94624053..196c9abb1 100644 --- a/configure.pri +++ b/configure.pri @@ -149,20 +149,6 @@ defineTest(qtConfTest_detectEmbedded) { return(false) } -defineTest(qtConfTest_detectXcb) { - #workaround for for not working 'depends' in main configure when no 'module' - QT_FOR_CONFIG += gui-private - qtConfig(xcb): return(true) - return(false) -} - -defineTest(qtConfTest_detectDeveloperBuild) { - #workaround for for not working 'depends' in main configure when no 'module' - QT_FOR_CONFIG += core-private - qtConfig(private_tests): return(true) # enabled for developer-build - return(false) -} - defineTest(qtConfTest_detectHostPkgConfig) { PKG_CONFIG = $$qtConfPkgConfig(true) isEmpty(PKG_CONFIG) { diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf index f858243e1..e6c74fc87 100644 --- a/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -130,8 +130,8 @@ defineTest(isWebEngineCoreBuild) { return(false) } - include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) - QT_FOR_CONFIG += webenginecore-private + include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) + QT_FOR_CONFIG += buildtools-private win32:!qtConfig(webengine-win-compiler64) { skipBuild("Required 64-bit cross-building or native toolchain could not be found.") diff --git a/mkspecs/features/platform.prf b/mkspecs/features/platform.prf index bdd81d337..97cf96a78 100644 --- a/mkspecs/features/platform.prf +++ b/mkspecs/features/platform.prf @@ -1,4 +1,5 @@ -include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) +QT_FOR_CONFIG += buildtools-private defineTest(isQtMinimum) { !equals(QT_MAJOR_VERSION, $$1): return(false) diff --git a/src/buildtools/configure.json b/src/buildtools/configure.json new file mode 100644 index 000000000..0060acac4 --- /dev/null +++ b/src/buildtools/configure.json @@ -0,0 +1,716 @@ +{ + "module": "buildtools", + "depends": [ + "core-private", + "gui-private", + "printsupport" + ], + "commandline": { + "options": { + "webengine-core": "boolean", + "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"} + } + }, + "libraries": { + "webengine-dbus": { + "label": "d-bus", + "sources": [ + { "type": "pkgConfig", "args": "dbus-1" } + ] + }, + "webengine-fontconfig": { + "label": "fontconfig", + "sources": [ + { "type": "pkgConfig", "args": "fontconfig" } + ] + }, + "webengine-libdrm": { + "label": "libdrm", + "sources": [ + { "type": "pkgConfig", "args": "libdrm" } + ] + }, + "webengine-xcomposite": { + "label": "xcomposite", + "sources": [ + { "type": "pkgConfig", "args": "xcomposite" } + ] + }, + "webengine-xcursor": { + "label": "xcursor", + "sources": [ + { "type": "pkgConfig", "args": "xcursor" } + ] + }, + "webengine-xi": { + "label": "xi", + "sources": [ + { "type": "pkgConfig", "args": "xi" } + ] + }, + "webengine-xtst": { + "label": "xtst", + "sources": [ + { "type": "pkgConfig", "args": "xtst" } + ] + }, + "webengine-nss": { + "label": "nss >= 3.26", + "sources": [ + { "type": "pkgConfig", "args": "nss >= 3.26" } + ] + }, + "webengine-x11" : { + "label" : "x11", + "sources": [ + { "type": "pkgConfig", "args": "x11" } + ] + }, + "webengine-glib": { + "label": "glib-2.0 >= 2.32.0", + "sources": [ + { "type": "pkgConfig", "args": "glib-2.0 >= 2.32.0" } + ] + }, + "webengine-harfbuzz": { + "label": "harfbuzz >= 2.2.0", + "sources": [ + { "type": "pkgConfig", "args": "harfbuzz >= 2.2.0" } + ] + }, + "webengine-jpeglib": { + "label": "compatible jpeglib", + "type": "compile", + "test": { + "head": [ + "#include ", + "#include ", + "extern \"C\" {", + " #include ", + "}" + ], + "main": [ + "JDIMENSION dummy;", + "jpeg_crop_scanline(nullptr, &dummy, &dummy);", + "jpeg_skip_scanlines(nullptr, dummy);" + ] + }, + "sources": [ + { "type": "pkgConfig", "args": "libjpeg" }, + "-ljpeg" + ] + }, + "webengine-jsoncpp": { + "label": "jsoncpp", + "sources": [ + { "type": "pkgConfig", "args": "jsoncpp" } + ] + }, + "webengine-libevent": { + "label": "libevent", + "sources": [ + { "type": "pkgConfig", "args": "libevent" } + ] + }, + "webengine-minizip": { + "label": "minizip", + "sources": [ + { "type": "pkgConfig", "args": "minizip" } + ] + }, + "webengine-png": { + "label": "libpng >= 1.6.0", + "sources": [ + { "type": "pkgConfig", "args": "libpng >= 1.6.0" } + ] + }, + "webengine-protobuf": { + "label": "protobuf", + "sources": [ + { "type": "pkgConfig", "args": "protobuf" } + ] + }, + "webengine-zlib": { + "label": "zlib", + "sources": [ + { "type": "pkgConfig", "args": "zlib" } + ] + }, + "webengine-re2": { + "label": "re2", + "test" : { + "main": [ + "std::string s;", + "RE2 re2(s);" + ] + }, + "headers": "re2/re2.h", + "sources": [ + { "type": "pkgConfig", "args": "re2" } + ] + }, + "webengine-icu": { + "label": "icu >= 63", + "sources": [ + { "type": "pkgConfig", "args": "icu-uc >= 63 icu-i18n >= 63" } + ] + }, + "webengine-webp": { + "label": "libwebp, libwebpmux and libwebpdemux", + "sources": [ + { "type": "pkgConfig", "args": "libwebp libwebpmux libwebpdemux" } + ] + }, + "webengine-lcms2": { + "label": "lcms2", + "sources": [ + { "type": "pkgConfig", "args": "lcms2" } + ] + }, + "webengine-freetype": { + "label": "freetype >= 2.4.2", + "test": { + "head": [ + "#include ", + "#include FT_FREETYPE_H", + "#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20402)", + "# error This version of freetype is too old.", + "#endif" + ], + "main": [ + "FT_Face ft_face = 0;", + "FT_Reference_Face(ft_face);" + ] + }, + "sources": [ + { "type": "pkgConfig", "args": "freetype2" } + ] + }, + "webengine-libxml2": { + "label": "compatible libxml2 and libxslt", + "type": "compile", + "test": { + "tail": [ + "#if !defined(LIBXML_ICU_ENABLED)", + "#error libxml icu not enabled", + "#endif" + ] + }, + "headers": "libxml/xmlversion.h", + "sources": [ + { "type": "pkgConfig", "args": "libxml-2.0 libxslt" } + ] + }, + "webengine-libdrm": { + "label": "libdrm", + "sources": [ + { "type": "pkgConfig", "args": "libdrm" } + ] + }, + "webengine-xcomposite": { + "label": "xcomposite", + "sources": [ + { "type": "pkgConfig", "args": "xcomposite" } + ] + }, + "webengine-xcursor": { + "label": "xcursor", + "sources": [ + { "type": "pkgConfig", "args": "xcursor" } + ] + }, + "webengine-xi": { + "label": "xi", + "sources": [ + { "type": "pkgConfig", "args": "xi" } + ] + }, + "webengine-xtst": { + "label": "xtst", + "sources": [ + { "type": "pkgConfig", "args": "xtst" } + ] + }, + "webengine-ffmpeg": { + "label": "libavcodec libavformat libavutil", + "sources": [ + { "type": "pkgConfig", "args": "libavcodec libavformat libavutil" } + ] + }, + "webengine-opus": { + "label": "opus", + "sources": [ + { "type": "pkgConfig", "args": "opus" } + ] + }, + "webengine-snappy": { + "label": "snappy", + "test": { + "main": [ + "snappy::Source *src = 0;", + "snappy::Sink *sink = 0;" + ] + }, + "headers": "snappy.h", + "sources": [ + "-lsnappy" + ] + }, + "webengine-libvpx": { + "label": "libvpx", + "test": { + "main": [ + "vpx_codec_cx_pkt pkt;", + "pkt.data.frame.width[0] = 0u;", + "pkt.data.frame.height[0] = 0u;" + ] + }, + "headers": "vpx/vpx_encoder.h", + "sources": [ + { "type": "pkgConfig", "args": "vpx" }, + "-lvpx" + ] + } + }, + + "testDir": "config.tests", + "tests" : { + "webengine-bison": { + "label": "bison", + "type": "detectBison" + }, + "webengine-flex": { + "label": "flex", + "type": "detectFlex" + }, + "webengine-gn": { + "label": "system gn", + "type": "detectGn" + }, + "webengine-glibc": { + "label": "glibc > 2.26", + "type": "compile", + "test": { + "include": "features.h", + "tail": [ + "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 27", + "#error glibc versions below 2.27 are not supported", + "#endif" + ] + } + }, + "webengine-gperf": { + "label": "gperf", + "type": "detectGperf" + }, + "webengine-khr": { + "label": "khr", + "type": "compile", + "test": { + "include": "KHR/khrplatform.h", + "qmake" : [ + "!isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL", + "!isEmpty(QMAKE_INCDIR_OPENGL): INCLUDEPATH += $$QMAKE_INCDIR_OPENGL" + ] + } + }, + "webengine-ninja": { + "label": "system ninja", + "type": "detectNinja" + }, + "webengine-python2": { + "label": "python2", + "type": "detectPython2", + "log": "location" + }, + "webengine-winversion": { + "label": "winversion", + "type": "compile", + "test": { + "head" : [ + "#if !defined(__clang__) && _MSC_FULL_VER < 191426428", + "#error unsupported Visual Studio version", + "#endif" + ] + } + }, + "webengine-host-pkg-config": { + "label": "host pkg-config", + "type": "detectHostPkgConfig", + "log": "path" + }, + "webengine-jumbo-build": { + "label": "jumbo build merge limit", + "type": "detectJumboBuild", + "log": "merge_limit" + }, + "webengine-protoc": { + "label": "protoc", + "type": "detectProtoc" + }, + "webengine-win-compiler64": { + "label": "64bit compiler", + "type": "isWindowsHostCompiler64" + } + }, + "features": { + "webengine-core": { + "label": "Support Qt WebEngine Core", + "purpose": "Provides WebEngine Core support.", + "condition": "module.gui + && features.webengine-python2 + && features.webengine-gperf + && features.webengine-bison + && features.webengine-flex + && (!features.xcb || features.webengine-ozone-x11)", + "output": [ "privateFeature" ] + }, + "webengine-python2": { + "label": "python2", + "condition": "tests.webengine-python2", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" } + ] + }, + "webengine-gperf": { + "label": "gperf", + "condition": "tests.webengine-gperf", + "output": [ "privateFeature" ] + }, + "webengine-bison": { + "label": "bison", + "condition": "tests.webengine-bison", + "output": [ "privateFeature" ] + }, + "webengine-flex": { + "label": "flex", + "condition": "tests.webengine-flex", + "output": [ "privateFeature" ] + }, + "webengine-system-ninja": { + "label": "Use System Ninja", + "condition": "tests.webengine-ninja", + "output": [ "privateFeature" ] + }, + "webengine-system-fontconfig": { + "label": "fontconfig", + "condition": "libs.webengine-fontconfig", + "output": [ "privateFeature" ] + }, + "webengine-system-dbus": { + "label": "dbus", + "condition": "libs.webengine-dbus", + "output": [ "privateFeature" ] + }, + "webengine-system-libdrm": { + "label": "libdrm", + "condition": "libs.webengine-libdrm", + "output": [ "privateFeature" ] + }, + "webengine-system-xcomposite": { + "label": "xcomposite", + "condition": "libs.webengine-xcomposite", + "output": [ "privateFeature" ] + }, + "webengine-system-xcursor": { + "label": "xcursor", + "condition": "libs.webengine-xcursor", + "output": [ "privateFeature" ] + }, + "webengine-system-xi": { + "label": "xi", + "condition": "libs.webengine-xi", + "output": [ "privateFeature" ] + }, + "webengine-system-xtst": { + "label": "xtst", + "condition": "libs.webengine-xtst", + "output": [ "privateFeature" ] + }, + "webengine-system-gn": { + "label": "Use System Gn", + "autoDetect": "false", + "condition": "tests.webengine-gn", + "output": [ "privateFeature" ] + }, + "webengine-system-khr" : { + "label": "khr", + "condition": "config.unix && tests.webengine-khr", + "output": [ "privateFeature" ] + }, + "webengine-system-nss": { + "label": "nss", + "condition": "config.unix && !config.darwin && libs.webengine-nss", + "output": [ "privateFeature" ] + }, + "webengine-system-glibc": { + "label": "glibc", + "condition": "config.linux && tests.webengine-glibc", + "output": [ "privateFeature" ] + }, + "webengine-system-x11" : { + "label": "x11", + "condition": "config.unix && libs.webengine-x11", + "output": [ "privateFeature" ] + }, + "webengine-host-pkg-config": { + "label": "host-pkg-config", + "condition": "config.unix && tests.webengine-host-pkg-config", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_PKG_CONFIG_HOST", "value": "tests.webengine-host-pkg-config.path" } + ] + }, + "webengine-ozone-x11" : { + "label": "Support qpa-xcb", + "condition": "config.unix + && features.xcb + && features.webengine-system-x11 + && features.webengine-system-libdrm + && features.webengine-system-xcomposite + && features.webengine-system-xcursor + && features.webengine-system-xi + && features.webengine-system-xtst", + "output": [ "privateFeature" ] + }, + "webengine-jumbo-build": { + "label": "jumbo build merge batch", + "condition": "tests.webengine-jumbo-build", + "output": [ + "privateFeature", + { "type": "varAssign", "name": "QMAKE_JUMBO_MERGE_LIMIT", "value": "tests.webengine-jumbo-build.merge_limit" } + ] + }, + "webengine-system-libdrm": { + "label": "libdrm", + "condition": "libs.webengine-libdrm", + "output": [ "privateFeature" ] + }, + "webengine-system-xcomposite": { + "label": "xcomposite", + "condition": "libs.webengine-xcomposite", + "output": [ "privateFeature" ] + }, + "webengine-system-xcursor": { + "label": "xcursor", + "condition": "libs.webengine-xcursor", + "output": [ "privateFeature" ] + }, + "webengine-system-xi": { + "label": "xi", + "condition": "libs.webengine-xi", + "output": [ "privateFeature" ] + }, + "webengine-system-xtst": { + "label": "xtst", + "condition": "libs.webengine-xtst", + "output": [ "privateFeature" ] + }, + "webengine-system-harfbuzz": { + "label": "harfbuzz", + "condition": "config.unix && features.system-harfbuzz && libs.webengine-harfbuzz", + "output": [ "privateFeature" ] + }, + "webengine-system-glib" : { + "label": "glib", + "condition": "config.unix && libs.webengine-glib", + "output": [ "privateFeature" ] + }, + "webengine-system-minizip" : { + "label": "minizip", + "condition": "config.unix && libs.webengine-minizip", + "output": [ "privateFeature" ] + }, + "webengine-system-zlib" : { + "label": "zlib", + "condition": "config.unix && features.system-zlib && libs.webengine-zlib", + "output": [ "privateFeature" ] + }, + "webengine-system-libevent" : { + "label": "libevent", + "condition": "config.unix && libs.webengine-libevent", + "output": [ "privateFeature" ] + }, + "webengine-system-jsoncpp" : { + "label": "jsoncpp", + "condition": "config.unix && libs.webengine-jsoncpp", + "output": [ "privateFeature" ] + }, + "webengine-system-protobuf" : { + "label": "protobuf", + "condition": "config.unix && libs.webengine-protobuf && tests.webengine-protoc", + "output": [ "privateFeature" ] + }, + "webengine-system-png" : { + "label": "png", + "condition": "config.unix && features.system-png && libs.webengine-png", + "output": [ "privateFeature" ] + }, + "webengine-system-jpeg" : { + "label": "JPEG", + "condition": "config.unix && features.system-jpeg && libs.webengine-jpeglib", + "output": [ "privateFeature" ] + }, + "webengine-system-re2": { + "label": "re2", + "condition": "config.unix && libs.webengine-re2", + "output": [ "privateFeature" ] + }, + "webengine-system-icu": { + "label": "icu", + "autoDetect": "false", + "condition": "libs.webengine-icu", + "output": [ "privateFeature" ] + }, + "webengine-system-libwebp": { + "label": "libwebp, libwebpmux and libwebpdemux", + "condition": "config.unix && libs.webengine-webp", + "output": [ "privateFeature" ] + }, + "webengine-system-opus": { + "label": "opus", + "condition": "config.unix && libs.webengine-opus", + "output": [ "privateFeature" ] + }, + "webengine-system-ffmpeg": { + "label": "ffmpeg", + "autoDetect": "false", + "condition": "libs.webengine-ffmpeg && features.webengine-system-opus && features.webengine-system-libwebp", + "output": [ "privateFeature" ] + }, + "webengine-system-libxml2": { + "label": "libxml2 and libxslt", + "condition": "config.unix && libs.webengine-libxml2", + "output": [ "privateFeature" ] + }, + "webengine-system-lcms2" : { + "label": "lcms2", + "condition": "config.unix && libs.webengine-lcms2", + "output": [ "privateFeature" ] + }, + "webengine-system-freetype" : { + "label": "freetype", + "condition": "config.unix && features.system-freetype && libs.webengine-freetype", + "output": [ "privateFeature" ] + }, + "webengine-system-libvpx" : { + "label": "libvpx", + "condition": "config.unix && libs.webengine-libvpx", + "output": [ "privateFeature" ] + }, + "webengine-system-snappy" : { + "label": "snappy", + "condition": "config.unix && libs.webengine-snappy", + "output": [ "privateFeature" ] + }, + "webengine-winversion" : { + "label": "winversion", + "condition": "config.win32 && tests.webengine-winversion", + "output": [ "privateFeature" ] + }, + "webengine-win-compiler64": { + "label": "64bit compiler", + "condition": "config.win32 && tests.webengine-win-compiler64", + "output": [ "privateFeature" ] + } + }, + "report": [ + { + "type": "warning", + "condition": "!module.gui", + "message": "QtWebEngine requires QtGui." + }, + { + "type": "warning", + "condition": "!features.webengine-python2", + "message": "Python version 2 (2.7.5 or later) is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "!features.webengine-gperf", + "message": "gperf is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "!features.webengine-bison", + "message": "bison is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "!features.webengine-flex", + "message": "flex is required to build QtWebEngine." + }, + { + "type": "warning", + "condition": "config.linux && !features.webengine-ozone-x11 && features.xcb", + "message": "Could not find all necessary libraries for qpa-xcb support." + }, + { + "type": "warning", + "condition": "config.win32 && !features.webengine-win-compiler64", + "message": "64-bit cross-building or native toolchain is required to build QtWebEngine." + } + ], + "summary": [ + { + "section": "Qt WebEngine Build Tools", + "entries": [ + "webengine-system-ninja", + "webengine-system-gn", + { + "message": "Jumbo Build Merge Limit", + "type": "jumboBuild" + }, + { + "section": "Required system libraries", + "condition": "config.unix && !config.macos && features.webengine-core", + "entries": [ + "webengine-system-fontconfig", + "webengine-system-dbus", + "webengine-system-nss", + "webengine-system-khr", + "webengine-system-glibc" + ] + }, + { + "section": "Required system libraries for qpa-xcb", + "condition": "config.unix && !config.macos && features.webengine-core", + "entries": [ + "webengine-system-x11", + "webengine-system-libdrm", + "webengine-system-xcomposite", + "webengine-system-xcursor", + "webengine-system-xi", + "webengine-system-xtst" + ] + }, + { + "section": "Optional system libraries used", + "condition": "config.unix", + "entries": [ + "webengine-system-re2", + "webengine-system-icu", + "webengine-system-libwebp", + "webengine-system-opus", + "webengine-system-ffmpeg", + "webengine-system-libvpx", + "webengine-system-snappy", + "webengine-system-glib", + "webengine-system-zlib", + "webengine-system-minizip", + "webengine-system-libevent", + "webengine-system-jsoncpp", + "webengine-system-protobuf", + "webengine-system-libxml2", + "webengine-system-lcms2", + "webengine-system-png", + "webengine-system-jpeg", + "webengine-system-harfbuzz", + "webengine-system-freetype" + ] + } + ] + } + ] +} diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro index 6b0a41fbe..033202e6e 100644 --- a/src/buildtools/gn.pro +++ b/src/buildtools/gn.pro @@ -3,8 +3,8 @@ option(host_build) !debug_and_release: CONFIG += release -include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) -QT_FOR_CONFIG += webenginecore-private +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) +QT_FOR_CONFIG += buildtools-private build_pass|!debug_and_release { !qtConfig(webengine-system-gn): CONFIG(release, debug|release) { diff --git a/src/buildtools/ninja.pro b/src/buildtools/ninja.pro index dee285b7e..66a6d5aa6 100644 --- a/src/buildtools/ninja.pro +++ b/src/buildtools/ninja.pro @@ -2,8 +2,8 @@ TEMPLATE = aux !debug_and_release: CONFIG += release -include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) -QT_FOR_CONFIG += webenginecore-private +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) +QT_FOR_CONFIG += buildtools-private build_pass|!debug_and_release { !qtConfig(webengine-system-ninja): CONFIG(release, debug|release) { diff --git a/src/core/config/common.pri b/src/core/config/common.pri index df8aeb1cc..1a54f1559 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -1,6 +1,7 @@ # Shared configuration for all our supported platforms +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -QT_FOR_CONFIG += webenginecore +QT_FOR_CONFIG += buildtools-private webenginecore webenginecore-private gn_args += \ use_qt=true \ diff --git a/src/core/configure.json b/src/core/configure.json index a93132326..cf01b9914 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -1,6 +1,7 @@ { "module": "webenginecore", "depends": [ + "buildtools-private", "core-private", "gui-private", "printsupport" @@ -56,78 +57,6 @@ "sources" : [{ "type": "pkgConfig", "args": "alsa" } ] }, - "webengine-libdrm": { - "label": "libdrm", - "sources": [ - { "type": "pkgConfig", "args": "libdrm" } - ] - }, - "webengine-xcomposite": { - "label": "xcomposite", - "sources": [ - { "type": "pkgConfig", "args": "xcomposite" } - ] - }, - "webengine-xcursor": { - "label": "xcursor", - "sources": [ - { "type": "pkgConfig", "args": "xcursor" } - ] - }, - "webengine-xi": { - "label": "xi", - "sources": [ - { "type": "pkgConfig", "args": "xi" } - ] - }, - "webengine-xtst": { - "label": "xtst", - "sources": [ - { "type": "pkgConfig", "args": "xtst" } - ] - }, - "webengine-harfbuzz": { - "label": "harfbuzz >= 2.2.0", - "sources": [ - { "type": "pkgConfig", "args": "harfbuzz >= 2.2.0" } - ] - }, - "webengine-glib": { - "label": "glib-2.0 >= 2.32.0", - "sources": [ - { "type": "pkgConfig", "args": "glib-2.0 >= 2.32.0" } - ] - }, - "webengine-zlib": { - "label": "zlib", - "sources": [ - { "type": "pkgConfig", "args": "zlib" } - ] - }, - "webengine-minizip": { - "label": "minizip", - "sources": [ - { "type": "pkgConfig", "args": "minizip" } - ] - }, - "webengine-libevent": { - "label": "libevent", - "sources": [ - { "type": "pkgConfig", "args": "libevent" } - ] - }, - "webengine-jsoncpp": { - "label": "jsoncpp", - "sources": [ - { "type": "pkgConfig", "args": "jsoncpp" } - ] - }, - "webengine-protobuf": { - "label": "protobuf", - "sources": [ - { "type": "pkgConfig", "args": "protobuf" } - ] - }, "webengine-poppler-cpp": { "label": "poppler-cpp", "sources": [ @@ -139,139 +68,6 @@ "sources": [ { "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" } ] - }, - "webengine-re2": { - "label": "re2", - "test" : { - "main": [ - "std::string s;", - "RE2 re2(s);" - ] - }, - "headers": "re2/re2.h", - "sources": [ - { "type": "pkgConfig", "args": "re2" } - ] - }, - "webengine-icu": { - "label": "icu >= 63", - "sources": [ - { "type": "pkgConfig", "args": "icu-uc >= 63 icu-i18n >= 63" } - ] - }, - "webengine-ffmpeg": { - "label": "libavcodec libavformat libavutil", - "sources": [ - { "type": "pkgConfig", "args": "libavcodec libavformat libavutil" } - ] - }, - "webengine-opus": { - "label": "opus", - "sources": [ - { "type": "pkgConfig", "args": "opus" } - ] - }, - "webengine-webp": { - "label": "libwebp, libwebpmux and libwebpdemux", - "sources": [ - { "type": "pkgConfig", "args": "libwebp libwebpmux libwebpdemux" } - ] - }, - "webengine-png": { - "label": "libpng >= 1.6.0", - "sources": [ - { "type": "pkgConfig", "args": "libpng >= 1.6.0" } - ] - }, - "webengine-jpeglib": { - "label": "compatible jpeglib", - "type": "compile", - "test": { - "head": [ - "#include ", - "#include ", - "extern \"C\" {", - " #include ", - "}" - ], - "main": [ - "JDIMENSION dummy;", - "jpeg_crop_scanline(nullptr, &dummy, &dummy);", - "jpeg_skip_scanlines(nullptr, dummy);" - ] - }, - "sources": [ - { "type": "pkgConfig", "args": "libjpeg" }, - "-ljpeg" - ] - }, - "webengine-libxml2": { - "label": "compatible libxml2 and libxslt", - "type": "compile", - "test": { - "tail": [ - "#if !defined(LIBXML_ICU_ENABLED)", - "#error libxml icu not enabled", - "#endif" - ] - }, - "headers": "libxml/xmlversion.h", - "sources": [ - { "type": "pkgConfig", "args": "libxml-2.0 libxslt" } - ] - }, - "webengine-lcms2": { - "label": "lcms2", - "sources": [ - { "type": "pkgConfig", "args": "lcms2" } - ] - }, - "webengine-freetype": { - "label": "freetype >= 2.4.2", - "test": { - "head": [ - "#include ", - "#include FT_FREETYPE_H", - "#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20402)", - "# error This version of freetype is too old.", - "#endif" - ], - "main": [ - "FT_Face ft_face = 0;", - "FT_Reference_Face(ft_face);" - ] - }, - "sources": [ - { "type": "pkgConfig", "args": "freetype2" } - ] - }, - "webengine-snappy": { - "label": "snappy", - "test": { - "main": [ - "snappy::Source *src = 0;", - "snappy::Sink *sink = 0;" - ] - }, - "headers": "snappy.h", - "sources": [ - "-lsnappy" - ] - }, - "webengine-libvpx": { - "label": "libvpx", - "test": { - "main": [ - "vpx_codec_cx_pkt pkt;", - "pkt.data.frame.width[0] = 0u;", - "pkt.data.frame.height[0] = 0u;" - ] - }, - "headers": "vpx/vpx_encoder.h", - "sources": [ - { "type": "pkgConfig", "args": "vpx" }, - "-lvpx" - ] } }, "tests" : { @@ -281,10 +77,6 @@ "host": "true", "type": "compile" }, - "webengine-protoc": { - "label": "protoc", - "type": "detectProtoc" - }, "webengine-host-pkg-config": { "label": "host pkg-config", "type": "detectHostPkgConfig", @@ -294,18 +86,10 @@ "label": "embedded build", "type": "detectEmbedded" }, - "webengine-developer-build": { - "label": "developer build", - "type": "detectDeveloperBuild" - }, "webengine-sanitizer": { "label" : "sanitizer support", "type": "isSanitizerSupported" }, - "webengine-win-compiler64": { - "label": "64bit compiler", - "type": "isWindowsHostCompiler64" - }, "webengine-arm-thumb" : { "label": "thumb instruction set", "type": "hasThumbFlag" @@ -321,76 +105,6 @@ } }, "features": { - "webengine-system-libdrm": { - "label": "libdrm", - "condition": "libs.webengine-libdrm", - "output": [ "privateFeature" ] - }, - "webengine-system-xcomposite": { - "label": "xcomposite", - "condition": "libs.webengine-xcomposite", - "output": [ "privateFeature" ] - }, - "webengine-system-xcursor": { - "label": "xcursor", - "condition": "libs.webengine-xcursor", - "output": [ "privateFeature" ] - }, - "webengine-system-xi": { - "label": "xi", - "condition": "libs.webengine-xi", - "output": [ "privateFeature" ] - }, - "webengine-system-xtst": { - "label": "xtst", - "condition": "libs.webengine-xtst", - "output": [ "privateFeature" ] - }, - "webengine-system-harfbuzz": { - "label": "harfbuzz", - "condition": "config.unix && features.system-harfbuzz && libs.webengine-harfbuzz", - "output": [ "privateFeature" ] - }, - "webengine-system-glib" : { - "label": "glib", - "condition": "config.unix && libs.webengine-glib", - "output": [ "privateFeature" ] - }, - "webengine-system-minizip" : { - "label": "minizip", - "condition": "config.unix && libs.webengine-minizip", - "output": [ "privateFeature" ] - }, - "webengine-system-zlib" : { - "label": "zlib", - "condition": "config.unix && features.system-zlib && libs.webengine-zlib", - "output": [ "privateFeature" ] - }, - "webengine-system-libevent" : { - "label": "libevent", - "condition": "config.unix && libs.webengine-libevent", - "output": [ "privateFeature" ] - }, - "webengine-system-jsoncpp" : { - "label": "jsoncpp", - "condition": "config.unix && libs.webengine-jsoncpp", - "output": [ "privateFeature" ] - }, - "webengine-system-protobuf" : { - "label": "protobuf", - "condition": "config.unix && libs.webengine-protobuf && tests.webengine-protoc", - "output": [ "privateFeature" ] - }, - "webengine-system-png" : { - "label": "png", - "condition": "config.unix && features.system-png && libs.webengine-png", - "output": [ "privateFeature" ] - }, - "webengine-system-jpeg" : { - "label": "JPEG", - "condition": "config.unix && features.system-jpeg && libs.webengine-jpeglib", - "output": [ "privateFeature" ] - }, "webengine-embedded-build": { "label": "Embedded build", "purpose": "Enables the embedded build configuration.", @@ -402,7 +116,7 @@ "webengine-developer-build": { "label": "Developer build", "purpose": "Enables the developer build configuration.", - "autoDetect": "tests.webengine-developer-build", + "autoDetect": "features.private_tests", "output": [ "privateFeature" ] }, "webengine-alsa": { @@ -421,16 +135,6 @@ "condition": "!config.unix || !features.cross_compile || arch.arm64 || tests.webengine-host-compiler", "output": [ "privateFeature" ] }, - "webengine-system-libvpx" : { - "label": "libvpx", - "condition": "config.unix && libs.webengine-libvpx", - "output": [ "privateFeature" ] - }, - "webengine-system-snappy" : { - "label": "snappy", - "condition": "config.unix && libs.webengine-snappy", - "output": [ "privateFeature" ] - }, "webengine-geolocation": { "label": "Geolocation", "condition": "module.positioning", @@ -507,52 +211,6 @@ "autoDetect": "!features.webengine-embedded-build", "output": [ "privateFeature" ] }, - "webengine-system-libwebp": { - "label": "libwebp, libwebpmux and libwebpdemux", - "autoDetect": "config.unix", - "condition": "libs.webengine-webp", - "output": [ "privateFeature" ] - }, - "webengine-system-opus": { - "label": "opus", - "autoDetect": "config.unix", - "condition": "libs.webengine-opus", - "output": [ "privateFeature" ] - }, - "webengine-system-ffmpeg": { - "label": "ffmpeg", - "autoDetect": false, - "condition": "libs.webengine-ffmpeg && features.webengine-system-opus && features.webengine-system-libwebp", - "output": [ "privateFeature" ] - }, - "webengine-system-icu": { - "label": "icu", - "autoDetect": false, - "condition": "libs.webengine-icu", - "output": [ "privateFeature" ] - }, - "webengine-system-re2": { - "label": "re2", - "autoDetect": "config.unix", - "condition": "libs.webengine-re2", - "output": [ "privateFeature" ] - }, - "webengine-system-libxml2": { - "label": "libxml2 and libxslt", - "condition": "config.unix && libs.webengine-libxml2", - "output": [ "privateFeature" ] - }, - "webengine-system-lcms2" : { - "label": "lcms2", - "autoDetect": "features.webengine-printing-and-pdf", - "condition": "config.unix && libs.webengine-lcms2", - "output": [ "privateFeature" ] - }, - "webengine-system-freetype" : { - "label": "freetype", - "condition": "config.unix && features.system-freetype && libs.webengine-freetype", - "output": [ "privateFeature" ] - }, "webengine-ozone-x11" : { "label": "Support qpa-xcb", "condition": "config.unix @@ -576,11 +234,6 @@ "condition": "libs.webengine-poppler-cpp", "output": [ "privateFeature" ] }, - "webengine-win-compiler64": { - "label": "64bit compiler", - "condition": "config.win32 && tests.webengine-win-compiler64", - "output": [ "privateFeature" ] - }, "webengine-arm-thumb": { "label": "Thumb instruction set", "condition": "config.linux && features.webengine-embedded-build && arch.arm && tests.webengine-arm-thumb", @@ -614,11 +267,6 @@ "condition": "config.unix && !features.webengine-host-pkg-config", "message": "host pkg-config not found" }, - { - "type": "warning", - "condition": "config.win32 && !features.webengine-win-compiler64", - "message": "64-bit cross-building or native toolchain is required to build QtWebEngine." - }, { "type": "warning", "condition": "config.linux && features.webengine-embedded-build && !features.webengine-system-ffmpeg && arch.arm && !features.webengine-arm-thumb", @@ -632,31 +280,6 @@ ], "summary": [ - { - "section": "Optional system libraries used", - "condition": "config.unix", - "entries": [ - "webengine-system-re2", - "webengine-system-icu", - "webengine-system-libwebp", - "webengine-system-opus", - "webengine-system-ffmpeg", - "webengine-system-libvpx", - "webengine-system-snappy", - "webengine-system-glib", - "webengine-system-zlib", - "webengine-system-minizip", - "webengine-system-libevent", - "webengine-system-jsoncpp", - "webengine-system-protobuf", - "webengine-system-libxml2", - "webengine-system-lcms2", - "webengine-system-png", - "webengine-system-jpeg", - "webengine-system-harfbuzz", - "webengine-system-freetype" - ] - }, { "section": "Qt WebEngineCore", "condition": "features.webengine-core", diff --git a/src/core/core_common.pri b/src/core/core_common.pri index c92278657..2a9dc90c0 100644 --- a/src/core/core_common.pri +++ b/src/core/core_common.pri @@ -1,5 +1,6 @@ +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -QT_FOR_CONFIG += webenginecore webenginecore-private +QT_FOR_CONFIG += buildtools-private webenginecore webenginecore-private # NOTE: The TARGET, QT, QT_PRIVATE variables are used in both core_module.pro and core_gyp_generator.pro # gyp/ninja will take care of the compilation, qmake/make will finish with linking and install. diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro index 94c1ede1c..377d8363c 100644 --- a/src/core/gn_run.pro +++ b/src/core/gn_run.pro @@ -1,6 +1,6 @@ -include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -QT_FOR_CONFIG += webenginecore-private core-private gui-private +QT_FOR_CONFIG += buildtools-private webenginecore-private core-private gui-private TEMPLATE = aux diff --git a/src/src.pro b/src/src.pro index 1ace7a44b..99967fd82 100644 --- a/src/src.pro +++ b/src/src.pro @@ -1,6 +1,7 @@ load(platform) -include($$QTWEBENGINE_OUT_ROOT/src/qtwebengine-main-config.pri) +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) +QT_FOR_CONFIG += buildtools-private TEMPLATE = subdirs -- cgit v1.2.1 From 19a73086082bdf99f6f7b3b389c5e3f0703de449 Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 14 Aug 2019 12:38:32 +0200 Subject: Move gn configs out of core Change-Id: Ib047e35191faa627211c759bff4e81bfaec3d685 Reviewed-by: Allan Sandfeld Jensen --- configure.pri | 2 +- mkspecs/features/functions.prf | 6 +- src/buildtools/config/common.pri | 139 ++++++++++++++++++++++++ src/buildtools/config/functions.pri | 8 ++ src/buildtools/config/linux.pri | 203 ++++++++++++++++++++++++++++++++++++ src/buildtools/config/mac_osx.pri | 39 +++++++ src/buildtools/config/windows.pri | 89 ++++++++++++++++ src/core/config/common.pri | 139 ------------------------ src/core/config/functions.pri | 8 -- src/core/config/linux.pri | 203 ------------------------------------ src/core/config/mac_osx.pri | 39 ------- src/core/config/windows.pri | 89 ---------------- 12 files changed, 482 insertions(+), 482 deletions(-) create mode 100644 src/buildtools/config/common.pri create mode 100644 src/buildtools/config/functions.pri create mode 100644 src/buildtools/config/linux.pri create mode 100644 src/buildtools/config/mac_osx.pri create mode 100644 src/buildtools/config/windows.pri delete mode 100644 src/core/config/common.pri delete mode 100644 src/core/config/functions.pri delete mode 100644 src/core/config/linux.pri delete mode 100644 src/core/config/mac_osx.pri delete mode 100644 src/core/config/windows.pri diff --git a/configure.pri b/configure.pri index 196c9abb1..eff7d8f61 100644 --- a/configure.pri +++ b/configure.pri @@ -1,4 +1,4 @@ -include(src/core/config/functions.pri) +include(src/buildtools/config/functions.pri) # this must be done outside any function QTWEBENGINE_SOURCE_TREE = $$PWD diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf index e6c74fc87..a301929dc 100644 --- a/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -70,9 +70,9 @@ defineReplace(gnPath) { } defineReplace(gnArgs) { - linux: include($$QTWEBENGINE_ROOT/src/core/config/linux.pri) - macos: include($$QTWEBENGINE_ROOT/src/core/config/mac_osx.pri) - win32: include($$QTWEBENGINE_ROOT/src/core/config/windows.pri) + linux: include($$QTWEBENGINE_ROOT/src/buildtools/config/linux.pri) + macos: include($$QTWEBENGINE_ROOT/src/buildtools/config/mac_osx.pri) + win32: include($$QTWEBENGINE_ROOT/src/buildtools/config/windows.pri) isEmpty(gn_args): error(No gn_args found please make sure you have valid configuration.) return($$gn_args) } diff --git a/src/buildtools/config/common.pri b/src/buildtools/config/common.pri new file mode 100644 index 000000000..1a54f1559 --- /dev/null +++ b/src/buildtools/config/common.pri @@ -0,0 +1,139 @@ +# Shared configuration for all our supported platforms +include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) +include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) +QT_FOR_CONFIG += buildtools-private webenginecore webenginecore-private + +gn_args += \ + use_qt=true \ + closure_compile=false \ + is_component_build=false \ + is_shared=true \ + enable_message_center=false \ + enable_mus=false \ + enable_nacl=false \ + enable_remoting=false \ + enable_reporting=false \ + enable_resource_whitelist_generation=false \ + enable_swiftshader=false \ + enable_web_auth=false \ + enable_web_speech=false \ + enable_widevine=true \ + has_native_accessibility=false \ + enable_debugallocation=false \ + use_allocator_shim=false \ + use_allocator=\"none\" \ + use_custom_libcxx=false \ + v8_use_external_startup_data=false \ + toolkit_views=false \ + treat_warnings_as_errors=false \ + safe_browsing_mode=0 \ + optimize_webui=false + +greaterThan(QMAKE_JUMBO_MERGE_LIMIT,0) { + gn_args += \ + use_jumbo_build=true \ + jumbo_file_merge_limit=$$QMAKE_JUMBO_MERGE_LIMIT +} + +!greaterThan(QMAKE_JUMBO_MERGE_LIMIT,8) { + gn_args += jumbo_build_excluded="[\"browser\"]" +} + +qtConfig(webengine-printing-and-pdf) { + gn_args += enable_basic_printing=true enable_print_preview=true + gn_args += enable_pdf=true +} else { + gn_args += enable_basic_printing=false enable_print_preview=false + gn_args += enable_pdf=false +} + +qtConfig(webengine-pepper-plugins) { + gn_args += enable_plugins=true +} else { + gn_args += enable_plugins=false +} + +qtConfig(webengine-spellchecker) { + gn_args += enable_spellcheck=true +} else { + gn_args += enable_spellcheck=false +} + +qtConfig(webengine-webrtc) { + gn_args += enable_webrtc=true +} else { + gn_args += enable_webrtc=false audio_processing_in_audio_service_supported=false +} + +qtConfig(webengine-proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" + +qtConfig(webengine-extensions) { + gn_args += enable_extensions=true +} else { + gn_args += enable_extensions=false +} + +precompile_header { + gn_args += enable_precompiled_headers=true +} else { + gn_args += enable_precompiled_headers=false +} + +CONFIG(release, debug|release):!qtConfig(webengine-developer-build) { + gn_args += is_official_build=true +} else { + gn_args += is_official_build=false + !qtConfig(webengine-developer-build): gn_args += is_unsafe_developer_build=false +} + +CONFIG(release, debug|release) { + gn_args += is_debug=false + force_debug_info { + # Level 1 is not enough to generate all Chromium debug symbols on Windows + msvc: gn_args += symbol_level=2 + else: gn_args += symbol_level=1 + } else { + gn_args += symbol_level=0 + } +} + +CONFIG(debug, debug|release) { + gn_args += is_debug=true + gn_args += use_debug_fission=false + # MSVC requires iterator debug to always match and Qt leaves it default on. + msvc: gn_args += enable_iterator_debugging=true + + # We also can not have optimized V8 binaries for MSVC as iterator debugging + # would mismatch. + msvc|v8base_debug: gn_args += v8_optimized_debug=false +} + +!webcore_debug: gn_args += blink_symbol_level=0 +!v8base_debug: gn_args += remove_v8base_debug_symbols=true + +# Compiling with -Os makes a huge difference in binary size +optimize_size: gn_args += optimize_for_size=true + +# We don't want to apply sanitizer options to the build tools (GN, dict convert, etc). +!host_build { + sanitize_address: gn_args += is_asan=true + sanitize_thread: gn_args += is_tsan=true + sanitize_memory: gn_args += is_msan=true + sanitize_undefined: gn_args += is_ubsan=true is_ubsan_vptr=true +} + +qtConfig(webengine-v8-snapshot):qtConfig(webengine-v8-snapshot-support) { + gn_args += v8_use_snapshot=true +} else { + gn_args += v8_use_snapshot=false +} + +qtConfig(webengine-kerberos) { + gn_args += use_kerberos=true +} else { + gn_args += use_kerberos=false +} + +ccache { + gn_args += cc_wrapper=\"ccache\" +} diff --git a/src/buildtools/config/functions.pri b/src/buildtools/config/functions.pri new file mode 100644 index 000000000..8c11faa16 --- /dev/null +++ b/src/buildtools/config/functions.pri @@ -0,0 +1,8 @@ +defineReplace(qtwebengine_extractCFlag) { + CFLAGS = $$QMAKE_CC $$QMAKE_CFLAGS + OPTION = $$find(CFLAGS, $$1) + OPTION = $$split(OPTION, =) + PARAM = $$member(OPTION, 1) + !isEmpty(PARAM): return ($$PARAM) + return ($$OPTION) +} diff --git a/src/buildtools/config/linux.pri b/src/buildtools/config/linux.pri new file mode 100644 index 000000000..998aedc40 --- /dev/null +++ b/src/buildtools/config/linux.pri @@ -0,0 +1,203 @@ +include(common.pri) +include(functions.pri) + +defineReplace(extractCFlag) { + return($$qtwebengine_extractCFlag($$1)) +} + +QT_FOR_CONFIG += gui-private webenginecore-private + +gn_args += \ + use_cups=false \ + use_gio=false \ + use_gnome_keyring=false \ + linux_use_bundled_binutils=false \ + use_udev=true \ + use_bundled_fontconfig=false \ + use_sysroot=false \ + enable_session_service=false \ + is_cfi=false \ + strip_absolute_paths_from_debug_symbols=false \ + toolkit_views=false \ + use_ozone=true \ + ozone_auto_platforms=false \ + ozone_platform_headless=false \ + ozone_platform_external=true \ + ozone_platform=\"qt\" \ + ozone_extra_path=\"$$QTWEBENGINE_ROOT/src/core/ozone/ozone_extra.gni\" + +qtConfig(webengine-embedded-build) { + gn_args += is_desktop_linux=false +} + +use_gold_linker: gn_args += use_gold=true +else: gn_args += use_gold=false + +use_lld_linker: gn_args += use_lld=true +else: gn_args += use_lld=false + +clang { + clang_full_path = $$which($${QMAKE_CXX}) + # Remove the "/bin/clang++" part. + clang_prefix = $$section(clang_full_path, /, 0, -3) + gn_args += \ + is_clang=true \ + clang_use_chrome_plugins=false \ + clang_use_default_sample_profile=false \ + clang_base_path=\"$${clang_prefix}\" + + linux-clang-libc++: gn_args += use_libcxx=true +} else { + gn_args += \ + is_clang=false +} + +cross_compile:!host_build { + TOOLCHAIN_SYSROOT = $$[QT_SYSROOT] + !isEmpty(TOOLCHAIN_SYSROOT): gn_args += target_sysroot=\"$${TOOLCHAIN_SYSROOT}\" +} + +contains(QT_ARCH, "arm") { + # Extract ARM specific compiler options that we have to pass to gn, + # but let gn figure out a default if an option is not present. + MTUNE = $$extractCFlag("-mtune=.*") + !isEmpty(MTUNE): gn_args += arm_tune=\"$$MTUNE\" + + MFLOAT = $$extractCFlag("-mfloat-abi=.*") + !isEmpty(MFLOAT): gn_args += arm_float_abi=\"$$MFLOAT\" + + MARCH = $$extractCFlag("-march=.*") + !isEmpty(MARCH): gn_args += arm_arch=\"$$MARCH\" + + MARMV = $$replace(MARCH, "armv",) + !isEmpty(MARMV) { + MARMV = $$split(MARMV,) + MARMV = $$member(MARMV, 0) + lessThan(MARMV, 6): error("$$MARCH architecture is not supported") + gn_args += arm_version=$$MARMV + } + + # TODO: use neon detection from qtbase + !lessThan(MARMV, 8) { + gn_args += arm_use_neon=true + } else { + MFPU = $$extractCFlag("-mfpu=.*") + !isEmpty(MFPU):contains(MFPU, ".*neon.*") { + gn_args += arm_use_neon=true + } else { + gn_args += arm_use_neon=false + # If the toolchain does not explicitly specify to use NEON instructions + # we use arm_neon_optional for ARMv7 + equals(MARMV, 7): gn_args += arm_optionally_use_neon=true + } + } + + qtConfig(webengine-arm-thumb) { + gn_args += arm_use_thumb=true # this adds -mthumb + } else { + gn_args += arm_use_thumb=false + !qtConfig(webengine-system-ffmpeg) { + # Fixme QTBUG-71772 + gn_args += media_use_ffmpeg=false + gn_args += use_webaudio_ffmpeg=false + } + } +} + +contains(QT_ARCH, "mips") { + MARCH = $$extractCFlag("-march=.*") + !isEmpty(MARCH) { + equals(MARCH, "mips32r6"): gn_args += mips_arch_variant=\"r6\" + else: equals(MARCH, "mips32r2"): gn_args += mips_arch_variant=\"r2\" + else: equals(MARCH, "mips32"): gn_args += mips_arch_variant=\"r1\" + } else { + contains(QMAKE_CFLAGS, "mips32r6"): gn_args += mips_arch_variant=\"r6\" + else: contains(QMAKE_CFLAGS, "mips32r2"): gn_args += mips_arch_variant=\"r2\" + else: contains(QMAKE_CFLAGS, "mips32"): gn_args += mips_arch_variant=\"r1\" + } + + contains(QMAKE_CFLAGS, "-mmsa"): gn_args += mips_use_msa=true + + contains(QMAKE_CFLAGS, "-mdsp2"): gn_args += mips_dsp_rev=2 + else: contains(QMAKE_CFLAGS, "-mdsp"): gn_args += mips_dsp_rev=1 +} + +host_build { + gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\" + GN_HOST_CPU = $$gnArch($$QT_ARCH) + gn_args += host_cpu=\"$$GN_HOST_CPU\" + # Don't bother trying to use system libraries in this case + gn_args += use_glib=false +} else { + gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:target\" + gn_args += host_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\" + GN_TARGET_CPU = $$gnArch($$QT_ARCH) + cross_compile { + gn_args += v8_snapshot_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:v8_snapshot\" + # FIXME: we should set host_cpu in case host-toolchain doesn't match os arch, + # but currently we don't it available at this point + gn_args += target_cpu=\"$$GN_TARGET_CPU\" + } else { + gn_args += host_cpu=\"$$GN_TARGET_CPU\" + } + !contains(QT_CONFIG, no-pkg-config) { + # Strip '>2 /dev/null' from $$pkgConfigExecutable() + PKGCONFIG = $$first($$list($$pkgConfigExecutable())) + gn_args += pkg_config=\"$$PKGCONFIG\" + PKG_CONFIG_HOST = $$(GN_PKG_CONFIG_HOST) + pkgConfigLibDir = $$(PKG_CONFIG_LIBDIR) + pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR) + isEmpty(PKG_CONFIG_HOST): cross_compile { + !isEmpty(pkgConfigLibDir)|!isEmpty(pkgConfigSysrootDir) { + PKG_CONFIG_HOST = $$pkgConfigHostExecutable() + } + } + isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = $$QMAKE_PKG_CONFIG_HOST + gn_args += host_pkg_config=\"$$PKG_CONFIG_HOST\" + } + + qtConfig(webengine-system-zlib) { + qtConfig(webengine-system-minizip): gn_args += use_system_zlib=true use_system_minizip=true + qtConfig(webengine-printing-and-pdf): gn_args += pdfium_use_system_zlib=true + } + qtConfig(webengine-system-png) { + gn_args += use_system_libpng=true + qtConfig(webengine-printing-and-pdf): gn_args += pdfium_use_system_libpng=true + } + qtConfig(webengine-system-jpeg): gn_args += use_system_libjpeg=true + qtConfig(webengine-system-freetype): gn_args += use_system_freetype=true + qtConfig(webengine-system-harfbuzz): gn_args += use_system_harfbuzz=true + !qtConfig(webengine-system-glib): gn_args += use_glib=false + qtConfig(webengine-pulseaudio) { + gn_args += use_pulseaudio=true + } else { + gn_args += use_pulseaudio=false + } + qtConfig(webengine-alsa) { + gn_args += use_alsa=true + } else { + gn_args += use_alsa=false + } + !packagesExist(libpci): gn_args += use_libpci=false + + qtConfig(webengine-ozone-x11) { + gn_args += ozone_platform_x11=true + packagesExist(xscrnsaver): gn_args += use_xscrnsaver=true + } + + qtConfig(webengine-system-libevent): gn_args += use_system_libevent=true + qtConfig(webengine-system-libwebp): gn_args += use_system_libwebp=true + qtConfig(webengine-system-libxml2): gn_args += use_system_libxml=true use_system_libxslt=true + qtConfig(webengine-system-opus): gn_args += use_system_opus=true + qtConfig(webengine-system-snappy): gn_args += use_system_snappy=true + qtConfig(webengine-system-libvpx): gn_args += use_system_libvpx=true + qtConfig(webengine-system-icu): gn_args += use_system_icu=true icu_use_data_file=false + qtConfig(webengine-system-ffmpeg): gn_args += use_system_ffmpeg=true + qtConfig(webengine-system-re2): gn_args += use_system_re2=true + qtConfig(webengine-system-lcms2): gn_args += use_system_lcms2=true + + # FIXME: + #qtConfig(webengine-system-protobuf): gn_args += use_system_protobuf=true + #qtConfig(webengine-system-jsoncpp): gn_args += use_system_jsoncpp=true + #qtConfig(webengine-system-libsrtp: gn_args += use_system_libsrtp=true +} diff --git a/src/buildtools/config/mac_osx.pri b/src/buildtools/config/mac_osx.pri new file mode 100644 index 000000000..3f2fe9c0a --- /dev/null +++ b/src/buildtools/config/mac_osx.pri @@ -0,0 +1,39 @@ +include(common.pri) +load(functions) + +# Reuse the cached sdk version value from mac/sdk.prf if available +# otherwise query for it. +QMAKE_MAC_SDK_VERSION = $$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.SDKVersion) +isEmpty(QMAKE_MAC_SDK_VERSION) { + QMAKE_MAC_SDK_VERSION = $$system("/usr/bin/xcodebuild -sdk $${QMAKE_MAC_SDK} -version SDKVersion 2>/dev/null") + isEmpty(QMAKE_MAC_SDK_VERSION): error("Could not resolve SDK version for \'$${QMAKE_MAC_SDK}\'") +} + +QMAKE_CLANG_DIR = "/usr" +QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX) +!isEmpty(QMAKE_CLANG_PATH) { + clang_dir = $$clean_path("$$dirname(QMAKE_CLANG_PATH)/../") + exists($$clang_dir): QMAKE_CLANG_DIR = $$clang_dir +} + +QMAKE_CLANG_PATH = "$${QMAKE_CLANG_DIR}/bin/clang++" +message("Using clang++ from $${QMAKE_CLANG_PATH}") +system("$${QMAKE_CLANG_PATH} --version") + + +gn_args += \ + is_clang=true \ + use_sysroot=false \ + use_system_xcode=true \ + clang_base_path=\"$${QMAKE_CLANG_DIR}\" \ + clang_use_chrome_plugins=false \ + mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \ + mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \ + use_external_popup_menu=false + +qtConfig(webengine-spellchecker) { + qtConfig(webengine-native-spellchecker): gn_args += use_browser_spellchecker=true + else: gn_args += use_browser_spellchecker=false +} else { + gn_args += use_browser_spellchecker=false +} diff --git a/src/buildtools/config/windows.pri b/src/buildtools/config/windows.pri new file mode 100644 index 000000000..dfa40e9dc --- /dev/null +++ b/src/buildtools/config/windows.pri @@ -0,0 +1,89 @@ +include(common.pri) + +gn_args += \ + use_sysroot=false \ + enable_session_service=false \ + ninja_use_custom_environment_files=false \ + is_multi_dll_chrome=false \ + win_linker_timing=true \ + com_init_check_hook_disabled=true + +clang_cl { + clang_full_path = $$system_path($$which($${QMAKE_CXX})) + # Remove the "\bin\clang-cl.exe" part: + clang_dir = $$dirname(clang_full_path) + clang_prefix = $$join(clang_dir,,,"\..") + gn_args += \ + is_clang=true \ + use_ldd=true \ + clang_use_chrome_plugins=false \ + clang_base_path=\"$$system_path($$clean_path($$clang_prefix))\" +} else { + gn_args += is_clang=false use_lld=false +} + +qtConfig(webengine-developer-build) { + gn_args += \ + is_win_fastlink=true + + # Incremental linking doesn't work in release developer builds due to usage of /OPT:ICF + # by Chromium. + CONFIG(debug, debug|release) { + gn_args += \ + use_incremental_linking=true + } else { + gn_args += \ + use_incremental_linking=false + } +} else { + gn_args += \ + is_win_fastlink=false \ + use_incremental_linking=false +} + +defineTest(usingMSVC32BitCrossCompiler) { + CL_DIR = + for(dir, QMAKE_PATH_ENV) { + exists($$dir/cl.exe) { + CL_DIR = $$dir + break() + } + } + isEmpty(CL_DIR): { + warning(Cannot determine location of cl.exe.) + return(false) + } + CL_DIR = $$system_path($$CL_DIR) + CL_DIR = $$split(CL_DIR, \\) + CL_PLATFORM = $$last(CL_DIR) + equals(CL_PLATFORM, amd64_x86): return(true) + return(false) +} + +msvc:contains(QT_ARCH, "i386"):!usingMSVC32BitCrossCompiler() { + # The 32 bit MSVC linker runs out of memory if we do not remove all debug information. + force_debug_info: gn_args -= symbol_level=1 + gn_args *= symbol_level=0 +} + +msvc { + equals(MSVC_VER, 15.0) { + MSVS_VERSION = 2017 + } else: equals(MSVC_VER, 16.0) { + MSVS_VERSION = 2019 + } else { + error("Visual Studio compiler version \"$$MSVC_VER\" is not supported by Qt WebEngine") + } + + gn_args += visual_studio_version=$$MSVS_VERSION + + SDK_PATH = $$(WINDOWSSDKDIR) + VS_PATH= $$(VSINSTALLDIR) + gn_args += visual_studio_path=\"$$clean_path($$VS_PATH)\" + gn_args += windows_sdk_path=\"$$clean_path($$SDK_PATH)\" + + GN_TARGET_CPU = $$gnArch($$QT_ARCH) + gn_args += target_cpu=\"$$GN_TARGET_CPU\" +} else { + error("Qt WebEngine for Windows can only be built with a Microsoft Visual Studio C++ compatible compiler") +} diff --git a/src/core/config/common.pri b/src/core/config/common.pri deleted file mode 100644 index 1a54f1559..000000000 --- a/src/core/config/common.pri +++ /dev/null @@ -1,139 +0,0 @@ -# Shared configuration for all our supported platforms -include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri) -include($$QTWEBENGINE_OUT_ROOT/src/core/qtwebenginecore-config.pri) -QT_FOR_CONFIG += buildtools-private webenginecore webenginecore-private - -gn_args += \ - use_qt=true \ - closure_compile=false \ - is_component_build=false \ - is_shared=true \ - enable_message_center=false \ - enable_mus=false \ - enable_nacl=false \ - enable_remoting=false \ - enable_reporting=false \ - enable_resource_whitelist_generation=false \ - enable_swiftshader=false \ - enable_web_auth=false \ - enable_web_speech=false \ - enable_widevine=true \ - has_native_accessibility=false \ - enable_debugallocation=false \ - use_allocator_shim=false \ - use_allocator=\"none\" \ - use_custom_libcxx=false \ - v8_use_external_startup_data=false \ - toolkit_views=false \ - treat_warnings_as_errors=false \ - safe_browsing_mode=0 \ - optimize_webui=false - -greaterThan(QMAKE_JUMBO_MERGE_LIMIT,0) { - gn_args += \ - use_jumbo_build=true \ - jumbo_file_merge_limit=$$QMAKE_JUMBO_MERGE_LIMIT -} - -!greaterThan(QMAKE_JUMBO_MERGE_LIMIT,8) { - gn_args += jumbo_build_excluded="[\"browser\"]" -} - -qtConfig(webengine-printing-and-pdf) { - gn_args += enable_basic_printing=true enable_print_preview=true - gn_args += enable_pdf=true -} else { - gn_args += enable_basic_printing=false enable_print_preview=false - gn_args += enable_pdf=false -} - -qtConfig(webengine-pepper-plugins) { - gn_args += enable_plugins=true -} else { - gn_args += enable_plugins=false -} - -qtConfig(webengine-spellchecker) { - gn_args += enable_spellcheck=true -} else { - gn_args += enable_spellcheck=false -} - -qtConfig(webengine-webrtc) { - gn_args += enable_webrtc=true -} else { - gn_args += enable_webrtc=false audio_processing_in_audio_service_supported=false -} - -qtConfig(webengine-proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" - -qtConfig(webengine-extensions) { - gn_args += enable_extensions=true -} else { - gn_args += enable_extensions=false -} - -precompile_header { - gn_args += enable_precompiled_headers=true -} else { - gn_args += enable_precompiled_headers=false -} - -CONFIG(release, debug|release):!qtConfig(webengine-developer-build) { - gn_args += is_official_build=true -} else { - gn_args += is_official_build=false - !qtConfig(webengine-developer-build): gn_args += is_unsafe_developer_build=false -} - -CONFIG(release, debug|release) { - gn_args += is_debug=false - force_debug_info { - # Level 1 is not enough to generate all Chromium debug symbols on Windows - msvc: gn_args += symbol_level=2 - else: gn_args += symbol_level=1 - } else { - gn_args += symbol_level=0 - } -} - -CONFIG(debug, debug|release) { - gn_args += is_debug=true - gn_args += use_debug_fission=false - # MSVC requires iterator debug to always match and Qt leaves it default on. - msvc: gn_args += enable_iterator_debugging=true - - # We also can not have optimized V8 binaries for MSVC as iterator debugging - # would mismatch. - msvc|v8base_debug: gn_args += v8_optimized_debug=false -} - -!webcore_debug: gn_args += blink_symbol_level=0 -!v8base_debug: gn_args += remove_v8base_debug_symbols=true - -# Compiling with -Os makes a huge difference in binary size -optimize_size: gn_args += optimize_for_size=true - -# We don't want to apply sanitizer options to the build tools (GN, dict convert, etc). -!host_build { - sanitize_address: gn_args += is_asan=true - sanitize_thread: gn_args += is_tsan=true - sanitize_memory: gn_args += is_msan=true - sanitize_undefined: gn_args += is_ubsan=true is_ubsan_vptr=true -} - -qtConfig(webengine-v8-snapshot):qtConfig(webengine-v8-snapshot-support) { - gn_args += v8_use_snapshot=true -} else { - gn_args += v8_use_snapshot=false -} - -qtConfig(webengine-kerberos) { - gn_args += use_kerberos=true -} else { - gn_args += use_kerberos=false -} - -ccache { - gn_args += cc_wrapper=\"ccache\" -} diff --git a/src/core/config/functions.pri b/src/core/config/functions.pri deleted file mode 100644 index 8c11faa16..000000000 --- a/src/core/config/functions.pri +++ /dev/null @@ -1,8 +0,0 @@ -defineReplace(qtwebengine_extractCFlag) { - CFLAGS = $$QMAKE_CC $$QMAKE_CFLAGS - OPTION = $$find(CFLAGS, $$1) - OPTION = $$split(OPTION, =) - PARAM = $$member(OPTION, 1) - !isEmpty(PARAM): return ($$PARAM) - return ($$OPTION) -} diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri deleted file mode 100644 index 998aedc40..000000000 --- a/src/core/config/linux.pri +++ /dev/null @@ -1,203 +0,0 @@ -include(common.pri) -include(functions.pri) - -defineReplace(extractCFlag) { - return($$qtwebengine_extractCFlag($$1)) -} - -QT_FOR_CONFIG += gui-private webenginecore-private - -gn_args += \ - use_cups=false \ - use_gio=false \ - use_gnome_keyring=false \ - linux_use_bundled_binutils=false \ - use_udev=true \ - use_bundled_fontconfig=false \ - use_sysroot=false \ - enable_session_service=false \ - is_cfi=false \ - strip_absolute_paths_from_debug_symbols=false \ - toolkit_views=false \ - use_ozone=true \ - ozone_auto_platforms=false \ - ozone_platform_headless=false \ - ozone_platform_external=true \ - ozone_platform=\"qt\" \ - ozone_extra_path=\"$$QTWEBENGINE_ROOT/src/core/ozone/ozone_extra.gni\" - -qtConfig(webengine-embedded-build) { - gn_args += is_desktop_linux=false -} - -use_gold_linker: gn_args += use_gold=true -else: gn_args += use_gold=false - -use_lld_linker: gn_args += use_lld=true -else: gn_args += use_lld=false - -clang { - clang_full_path = $$which($${QMAKE_CXX}) - # Remove the "/bin/clang++" part. - clang_prefix = $$section(clang_full_path, /, 0, -3) - gn_args += \ - is_clang=true \ - clang_use_chrome_plugins=false \ - clang_use_default_sample_profile=false \ - clang_base_path=\"$${clang_prefix}\" - - linux-clang-libc++: gn_args += use_libcxx=true -} else { - gn_args += \ - is_clang=false -} - -cross_compile:!host_build { - TOOLCHAIN_SYSROOT = $$[QT_SYSROOT] - !isEmpty(TOOLCHAIN_SYSROOT): gn_args += target_sysroot=\"$${TOOLCHAIN_SYSROOT}\" -} - -contains(QT_ARCH, "arm") { - # Extract ARM specific compiler options that we have to pass to gn, - # but let gn figure out a default if an option is not present. - MTUNE = $$extractCFlag("-mtune=.*") - !isEmpty(MTUNE): gn_args += arm_tune=\"$$MTUNE\" - - MFLOAT = $$extractCFlag("-mfloat-abi=.*") - !isEmpty(MFLOAT): gn_args += arm_float_abi=\"$$MFLOAT\" - - MARCH = $$extractCFlag("-march=.*") - !isEmpty(MARCH): gn_args += arm_arch=\"$$MARCH\" - - MARMV = $$replace(MARCH, "armv",) - !isEmpty(MARMV) { - MARMV = $$split(MARMV,) - MARMV = $$member(MARMV, 0) - lessThan(MARMV, 6): error("$$MARCH architecture is not supported") - gn_args += arm_version=$$MARMV - } - - # TODO: use neon detection from qtbase - !lessThan(MARMV, 8) { - gn_args += arm_use_neon=true - } else { - MFPU = $$extractCFlag("-mfpu=.*") - !isEmpty(MFPU):contains(MFPU, ".*neon.*") { - gn_args += arm_use_neon=true - } else { - gn_args += arm_use_neon=false - # If the toolchain does not explicitly specify to use NEON instructions - # we use arm_neon_optional for ARMv7 - equals(MARMV, 7): gn_args += arm_optionally_use_neon=true - } - } - - qtConfig(webengine-arm-thumb) { - gn_args += arm_use_thumb=true # this adds -mthumb - } else { - gn_args += arm_use_thumb=false - !qtConfig(webengine-system-ffmpeg) { - # Fixme QTBUG-71772 - gn_args += media_use_ffmpeg=false - gn_args += use_webaudio_ffmpeg=false - } - } -} - -contains(QT_ARCH, "mips") { - MARCH = $$extractCFlag("-march=.*") - !isEmpty(MARCH) { - equals(MARCH, "mips32r6"): gn_args += mips_arch_variant=\"r6\" - else: equals(MARCH, "mips32r2"): gn_args += mips_arch_variant=\"r2\" - else: equals(MARCH, "mips32"): gn_args += mips_arch_variant=\"r1\" - } else { - contains(QMAKE_CFLAGS, "mips32r6"): gn_args += mips_arch_variant=\"r6\" - else: contains(QMAKE_CFLAGS, "mips32r2"): gn_args += mips_arch_variant=\"r2\" - else: contains(QMAKE_CFLAGS, "mips32"): gn_args += mips_arch_variant=\"r1\" - } - - contains(QMAKE_CFLAGS, "-mmsa"): gn_args += mips_use_msa=true - - contains(QMAKE_CFLAGS, "-mdsp2"): gn_args += mips_dsp_rev=2 - else: contains(QMAKE_CFLAGS, "-mdsp"): gn_args += mips_dsp_rev=1 -} - -host_build { - gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\" - GN_HOST_CPU = $$gnArch($$QT_ARCH) - gn_args += host_cpu=\"$$GN_HOST_CPU\" - # Don't bother trying to use system libraries in this case - gn_args += use_glib=false -} else { - gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:target\" - gn_args += host_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\" - GN_TARGET_CPU = $$gnArch($$QT_ARCH) - cross_compile { - gn_args += v8_snapshot_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:v8_snapshot\" - # FIXME: we should set host_cpu in case host-toolchain doesn't match os arch, - # but currently we don't it available at this point - gn_args += target_cpu=\"$$GN_TARGET_CPU\" - } else { - gn_args += host_cpu=\"$$GN_TARGET_CPU\" - } - !contains(QT_CONFIG, no-pkg-config) { - # Strip '>2 /dev/null' from $$pkgConfigExecutable() - PKGCONFIG = $$first($$list($$pkgConfigExecutable())) - gn_args += pkg_config=\"$$PKGCONFIG\" - PKG_CONFIG_HOST = $$(GN_PKG_CONFIG_HOST) - pkgConfigLibDir = $$(PKG_CONFIG_LIBDIR) - pkgConfigSysrootDir = $$(PKG_CONFIG_SYSROOT_DIR) - isEmpty(PKG_CONFIG_HOST): cross_compile { - !isEmpty(pkgConfigLibDir)|!isEmpty(pkgConfigSysrootDir) { - PKG_CONFIG_HOST = $$pkgConfigHostExecutable() - } - } - isEmpty(PKG_CONFIG_HOST): PKG_CONFIG_HOST = $$QMAKE_PKG_CONFIG_HOST - gn_args += host_pkg_config=\"$$PKG_CONFIG_HOST\" - } - - qtConfig(webengine-system-zlib) { - qtConfig(webengine-system-minizip): gn_args += use_system_zlib=true use_system_minizip=true - qtConfig(webengine-printing-and-pdf): gn_args += pdfium_use_system_zlib=true - } - qtConfig(webengine-system-png) { - gn_args += use_system_libpng=true - qtConfig(webengine-printing-and-pdf): gn_args += pdfium_use_system_libpng=true - } - qtConfig(webengine-system-jpeg): gn_args += use_system_libjpeg=true - qtConfig(webengine-system-freetype): gn_args += use_system_freetype=true - qtConfig(webengine-system-harfbuzz): gn_args += use_system_harfbuzz=true - !qtConfig(webengine-system-glib): gn_args += use_glib=false - qtConfig(webengine-pulseaudio) { - gn_args += use_pulseaudio=true - } else { - gn_args += use_pulseaudio=false - } - qtConfig(webengine-alsa) { - gn_args += use_alsa=true - } else { - gn_args += use_alsa=false - } - !packagesExist(libpci): gn_args += use_libpci=false - - qtConfig(webengine-ozone-x11) { - gn_args += ozone_platform_x11=true - packagesExist(xscrnsaver): gn_args += use_xscrnsaver=true - } - - qtConfig(webengine-system-libevent): gn_args += use_system_libevent=true - qtConfig(webengine-system-libwebp): gn_args += use_system_libwebp=true - qtConfig(webengine-system-libxml2): gn_args += use_system_libxml=true use_system_libxslt=true - qtConfig(webengine-system-opus): gn_args += use_system_opus=true - qtConfig(webengine-system-snappy): gn_args += use_system_snappy=true - qtConfig(webengine-system-libvpx): gn_args += use_system_libvpx=true - qtConfig(webengine-system-icu): gn_args += use_system_icu=true icu_use_data_file=false - qtConfig(webengine-system-ffmpeg): gn_args += use_system_ffmpeg=true - qtConfig(webengine-system-re2): gn_args += use_system_re2=true - qtConfig(webengine-system-lcms2): gn_args += use_system_lcms2=true - - # FIXME: - #qtConfig(webengine-system-protobuf): gn_args += use_system_protobuf=true - #qtConfig(webengine-system-jsoncpp): gn_args += use_system_jsoncpp=true - #qtConfig(webengine-system-libsrtp: gn_args += use_system_libsrtp=true -} diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri deleted file mode 100644 index 3f2fe9c0a..000000000 --- a/src/core/config/mac_osx.pri +++ /dev/null @@ -1,39 +0,0 @@ -include(common.pri) -load(functions) - -# Reuse the cached sdk version value from mac/sdk.prf if available -# otherwise query for it. -QMAKE_MAC_SDK_VERSION = $$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.SDKVersion) -isEmpty(QMAKE_MAC_SDK_VERSION) { - QMAKE_MAC_SDK_VERSION = $$system("/usr/bin/xcodebuild -sdk $${QMAKE_MAC_SDK} -version SDKVersion 2>/dev/null") - isEmpty(QMAKE_MAC_SDK_VERSION): error("Could not resolve SDK version for \'$${QMAKE_MAC_SDK}\'") -} - -QMAKE_CLANG_DIR = "/usr" -QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX) -!isEmpty(QMAKE_CLANG_PATH) { - clang_dir = $$clean_path("$$dirname(QMAKE_CLANG_PATH)/../") - exists($$clang_dir): QMAKE_CLANG_DIR = $$clang_dir -} - -QMAKE_CLANG_PATH = "$${QMAKE_CLANG_DIR}/bin/clang++" -message("Using clang++ from $${QMAKE_CLANG_PATH}") -system("$${QMAKE_CLANG_PATH} --version") - - -gn_args += \ - is_clang=true \ - use_sysroot=false \ - use_system_xcode=true \ - clang_base_path=\"$${QMAKE_CLANG_DIR}\" \ - clang_use_chrome_plugins=false \ - mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \ - mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \ - use_external_popup_menu=false - -qtConfig(webengine-spellchecker) { - qtConfig(webengine-native-spellchecker): gn_args += use_browser_spellchecker=true - else: gn_args += use_browser_spellchecker=false -} else { - gn_args += use_browser_spellchecker=false -} diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri deleted file mode 100644 index dfa40e9dc..000000000 --- a/src/core/config/windows.pri +++ /dev/null @@ -1,89 +0,0 @@ -include(common.pri) - -gn_args += \ - use_sysroot=false \ - enable_session_service=false \ - ninja_use_custom_environment_files=false \ - is_multi_dll_chrome=false \ - win_linker_timing=true \ - com_init_check_hook_disabled=true - -clang_cl { - clang_full_path = $$system_path($$which($${QMAKE_CXX})) - # Remove the "\bin\clang-cl.exe" part: - clang_dir = $$dirname(clang_full_path) - clang_prefix = $$join(clang_dir,,,"\..") - gn_args += \ - is_clang=true \ - use_ldd=true \ - clang_use_chrome_plugins=false \ - clang_base_path=\"$$system_path($$clean_path($$clang_prefix))\" -} else { - gn_args += is_clang=false use_lld=false -} - -qtConfig(webengine-developer-build) { - gn_args += \ - is_win_fastlink=true - - # Incremental linking doesn't work in release developer builds due to usage of /OPT:ICF - # by Chromium. - CONFIG(debug, debug|release) { - gn_args += \ - use_incremental_linking=true - } else { - gn_args += \ - use_incremental_linking=false - } -} else { - gn_args += \ - is_win_fastlink=false \ - use_incremental_linking=false -} - -defineTest(usingMSVC32BitCrossCompiler) { - CL_DIR = - for(dir, QMAKE_PATH_ENV) { - exists($$dir/cl.exe) { - CL_DIR = $$dir - break() - } - } - isEmpty(CL_DIR): { - warning(Cannot determine location of cl.exe.) - return(false) - } - CL_DIR = $$system_path($$CL_DIR) - CL_DIR = $$split(CL_DIR, \\) - CL_PLATFORM = $$last(CL_DIR) - equals(CL_PLATFORM, amd64_x86): return(true) - return(false) -} - -msvc:contains(QT_ARCH, "i386"):!usingMSVC32BitCrossCompiler() { - # The 32 bit MSVC linker runs out of memory if we do not remove all debug information. - force_debug_info: gn_args -= symbol_level=1 - gn_args *= symbol_level=0 -} - -msvc { - equals(MSVC_VER, 15.0) { - MSVS_VERSION = 2017 - } else: equals(MSVC_VER, 16.0) { - MSVS_VERSION = 2019 - } else { - error("Visual Studio compiler version \"$$MSVC_VER\" is not supported by Qt WebEngine") - } - - gn_args += visual_studio_version=$$MSVS_VERSION - - SDK_PATH = $$(WINDOWSSDKDIR) - VS_PATH= $$(VSINSTALLDIR) - gn_args += visual_studio_path=\"$$clean_path($$VS_PATH)\" - gn_args += windows_sdk_path=\"$$clean_path($$SDK_PATH)\" - - GN_TARGET_CPU = $$gnArch($$QT_ARCH) - gn_args += target_cpu=\"$$GN_TARGET_CPU\" -} else { - error("Qt WebEngine for Windows can only be built with a Microsoft Visual Studio C++ compatible compiler") -} -- cgit v1.2.1 From 5e8ead1792617b9bfaf9ec2992870b348c2bb321 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Sun, 8 Sep 2019 11:25:23 +0200 Subject: Lower requirement for glibc to 2.17 This was not correctly merged from 5.13 due to the check moving to another file. Task-number: QTBUG-77171 Change-Id: I4388ea9a58509c93574d7953eebb09a62b5ffd63 Reviewed-by: Michal Klocek --- src/buildtools/configure.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/buildtools/configure.json b/src/buildtools/configure.json index 0060acac4..3fc342992 100644 --- a/src/buildtools/configure.json +++ b/src/buildtools/configure.json @@ -288,13 +288,13 @@ "type": "detectGn" }, "webengine-glibc": { - "label": "glibc > 2.26", + "label": "glibc > 2.16", "type": "compile", "test": { "include": "features.h", "tail": [ - "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 27", - "#error glibc versions below 2.27 are not supported", + "#if __GLIBC__ < 2 || __GLIBC_MINOR__ < 17", + "#error glibc versions below 2.17 are not supported", "#endif" ] } -- cgit v1.2.1 From d4022e03ccaeb92e41075f276e4011bd49627165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Br=C3=BCning?= Date: Mon, 9 Sep 2019 11:03:16 +0200 Subject: Blacklist several Qt WebEngine quick dialog tests on macOS 10.13 These tests are causing frequent failures on macOS 10.13 in the CI, but are not reproducible / debuggable when not running as part of CI. Task-number: QTBUG-76549 Change-Id: I1b105748c9fad8a6104beeccb10632518893d06b Reviewed-by: Liang Qi --- tests/auto/quick/dialogs/BLACKLIST | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/auto/quick/dialogs/BLACKLIST b/tests/auto/quick/dialogs/BLACKLIST index 6d7e2a2fc..10b7391a0 100644 --- a/tests/auto/quick/dialogs/BLACKLIST +++ b/tests/auto/quick/dialogs/BLACKLIST @@ -1,2 +1,8 @@ [contextMenuRequested] osx-10.13 +[javaScriptDialogRequested] +osx-10.13 +[colorDialogRequested] +osx-10.13 +[fileDialogRequested] +osx-10.13 -- cgit v1.2.1 From 8daefcfd8e1bf41ae4d06c7a79a526b81a78dc58 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Wed, 3 Jul 2019 15:01:35 +0200 Subject: Remove usages of deprecated APIs - Replaced the following deprecated APIs: QWebEngineProfile::setRequestInterceptor -> QWebEngineProfile::setUrlRequestInterceptor QWebEngineSettings::globalSettings -> WebEngineSettings::defaultSettings QLayout::setMargin -> QLayout::setContentsMargins QWheelEvent::{x, y} -> QWheelEvent::position QWheelEvent::{globalX, globalY} -> QWheelEvent::globalPosition QSysInfo::windowsVersion -> QOperatingSystemVersion::current Qt::InputMethodQuery::ImMicroFocus -> Qt::InputMethodQuery::ImCursorRectangle QDesktopWidget::screenGeometry -> QGuiApplication::primaryScreen::geometry QTime -> QElapsedTimer - Fixed the tests to compile when deprecated APIs are disabled. - Replaced the doc references to deprecated APIs with the new ones. Made the docs for deprecated APIs compile conditionally, based on deprecation version. Task-number: QTBUG-76491 Change-Id: I5c6b7c628957deb9163f0bd2b6bc31bde1c7daec Reviewed-by: Allan Sandfeld Jensen --- .../simplebrowser/browserwindow.cpp | 2 +- .../simplebrowser/downloadwidget.cpp | 3 ++- .../simplebrowser/downloadwidget.h | 4 ++-- .../simplebrowser/webpopupwindow.cpp | 2 +- src/core/web_event_factory.cpp | 14 ++++++++++++ src/process/support_win.cpp | 3 ++- src/webenginewidgets/api/qwebengineprofile.cpp | 2 +- .../doc/src/qwebenginepage_lgpl.qdoc | 2 +- .../doc/src/qwebenginesettings_lgpl.qdoc | 2 ++ .../doc/src/qwebengineview_lgpl.qdoc | 2 +- .../qwebengineprofile/tst_qwebengineprofile.cpp | 2 +- .../qwebenginesettings/tst_qwebenginesettings.cpp | 2 +- .../widgets/qwebengineview/tst_qwebengineview.cpp | 25 +++++++++++++++++----- tests/manual/widgets/webgl/main.cpp | 6 +++--- 14 files changed, 52 insertions(+), 19 deletions(-) diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp index 2bb9045b0..7b167ded7 100644 --- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp +++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp @@ -100,7 +100,7 @@ BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool QWidget *centralWidget = new QWidget(this); QVBoxLayout *layout = new QVBoxLayout; layout->setSpacing(0); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); if (!forDevTools) { addToolBarBreak(); diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp index 835a901c6..ddddc5e5d 100644 --- a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp +++ b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp @@ -57,8 +57,9 @@ DownloadWidget::DownloadWidget(QWebEngineDownloadItem *download, QWidget *parent) : QFrame(parent) , m_download(download) - , m_timeAdded(QTime::currentTime()) + , m_timeAdded() { + m_timeAdded.start(); setupUi(this); m_dstName->setText(m_download->downloadFileName()); m_srcUrl->setText(m_download->url().toDisplayString()); diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.h b/examples/webenginewidgets/simplebrowser/downloadwidget.h index c08b298bc..c20676aa6 100644 --- a/examples/webenginewidgets/simplebrowser/downloadwidget.h +++ b/examples/webenginewidgets/simplebrowser/downloadwidget.h @@ -54,7 +54,7 @@ #include "ui_downloadwidget.h" #include -#include +#include QT_BEGIN_NAMESPACE class QWebEngineDownloadItem; @@ -80,7 +80,7 @@ private: QString withUnit(qreal bytes); QWebEngineDownloadItem *m_download; - QTime m_timeAdded; + QElapsedTimer m_timeAdded; }; #endif // DOWNLOADWIDGET_H diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp index 19e3b0124..566723e1f 100644 --- a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp +++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp @@ -66,7 +66,7 @@ WebPopupWindow::WebPopupWindow(QWebEngineProfile *profile) setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); QVBoxLayout *layout = new QVBoxLayout; - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); layout->addWidget(m_urlLineEdit); layout->addWidget(m_view); diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 1b0723cb5..7f5306e67 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -1490,8 +1490,15 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev) webEvent.SetType(webEventTypeForEvent(ev)); webEvent.SetModifiers(modifiersForEvent(ev)); webEvent.SetTimeStamp(base::TimeTicks::Now()); +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) webEvent.SetPositionInWidget(ev->x(), ev->y()); webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); +#else + webEvent.SetPositionInWidget(static_cast(ev->position().x()), + static_cast(ev->position().y())); + webEvent.SetPositionInScreen(static_cast(ev->globalPosition().x()), + static_cast(ev->globalPosition().y())); +#endif webEvent.wheel_ticks_x = static_cast(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; webEvent.wheel_ticks_y = static_cast(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; @@ -1520,8 +1527,15 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent, #endif webEvent.SetTimeStamp(base::TimeTicks::Now()); +#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) webEvent.SetPositionInWidget(ev->x(), ev->y()); webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); +#else + webEvent.SetPositionInWidget(static_cast(ev->position().x()), + static_cast(ev->position().y())); + webEvent.SetPositionInScreen(static_cast(ev->globalPosition().x()), + static_cast(ev->globalPosition().y())); +#endif webEvent.wheel_ticks_x += static_cast(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; webEvent.wheel_ticks_y += static_cast(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; diff --git a/src/process/support_win.cpp b/src/process/support_win.cpp index 21481ce08..3d0ef37bf 100644 --- a/src/process/support_win.cpp +++ b/src/process/support_win.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include +#include #include #include #include @@ -80,7 +81,7 @@ public: ShcoreDLL() : getProcessDpiAwareness(0), setProcessDpiAwareness(0) { - if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8_1) + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1) return; library.setFileName(QStringLiteral("SHCore")); if (!library.load()) diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index 6e2db533e..4a77eb8cf 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -101,7 +101,7 @@ using QtWebEngineCore::ProfileAdapter; web pages not specifically created with another profile belong to. Implementing the QWebEngineUrlRequestInterceptor interface and registering the interceptor on a - profile by setRequestInterceptor() enables intercepting, blocking, and modifying URL + profile by setUrlRequestInterceptor() enables intercepting, blocking, and modifying URL requests (QWebEngineUrlRequestInfo) before they reach the networking stack of Chromium. A QWebEngineUrlSchemeHandler can be registered for a profile by installUrlSchemeHandler() diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index 5536c0058..699d7f181 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -510,7 +510,7 @@ \fn QWebEngineSettings *QWebEnginePage::settings() const Returns a pointer to the page's settings object. - \sa QWebEngineSettings::globalSettings() + \sa QWebEngineSettings::defaultSettings() */ /*! diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc index ce75a4203..0706598ef 100644 --- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc @@ -22,12 +22,14 @@ // by its LGPL license. Documentation written from scratch for new methods should be // placed inline in the code as usual. +#if QT_DEPRECATED_SINCE(5, 5) /*! \fn static QWebEngineSettings *QWebEngineSettings::globalSettings() \obsolete Use defaultSettings() instead. */ +#endif /*! \class QWebEngineSettings diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc index 1b7812dff..3f1b6e509 100644 --- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc @@ -393,5 +393,5 @@ \snippet qtwebengine_qwebengineview_snippet.cpp 6 - \sa QWebEngineSettings::globalSettings() + \sa QWebEngineSettings::defaultSettings() */ diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 0fc494a36..25afa5849 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -526,7 +526,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders() QWebEngineProfile profile; profile.installUrlSchemeHandler("myscheme", &handler); - profile.setRequestInterceptor(&interceptor); + profile.setUrlRequestInterceptor(&interceptor); QWebEnginePage page(&profile); QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool))); diff --git a/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp index 0704cf383..b4061b984 100644 --- a/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp +++ b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp @@ -177,7 +177,7 @@ void tst_QWebEngineSettings::setInAcceptNavigationRequest() { NavigationRequestOverride page; QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool))); - QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false); + QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false); QVERIFY(!page.settings()->testAttribute(QWebEngineSettings::JavascriptEnabled)); page.load(QUrl("about:blank")); diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index fa179f2f8..827ac2757 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -237,30 +237,45 @@ void tst_QWebEngineView::renderHints() QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); QVERIFY(webView.renderHints() & QPainter::TextAntialiasing); QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform); +#if QT_DEPRECATED_SINCE(5, 14) QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing)); +#endif + QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); webView.setRenderHint(QPainter::Antialiasing, true); QVERIFY(webView.renderHints() & QPainter::Antialiasing); QVERIFY(webView.renderHints() & QPainter::TextAntialiasing); QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform); +#if QT_DEPRECATED_SINCE(5, 14) QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing)); +#endif + QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); webView.setRenderHint(QPainter::Antialiasing, false); QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); QVERIFY(webView.renderHints() & QPainter::TextAntialiasing); QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform); +#if QT_DEPRECATED_SINCE(5, 14) QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing)); +#endif + QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); webView.setRenderHint(QPainter::SmoothPixmapTransform, true); QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); QVERIFY(webView.renderHints() & QPainter::TextAntialiasing); QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform); +#if QT_DEPRECATED_SINCE(5, 14) QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing)); +#endif + QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); webView.setRenderHint(QPainter::SmoothPixmapTransform, false); QVERIFY(webView.renderHints() & QPainter::TextAntialiasing); QVERIFY(!(webView.renderHints() & QPainter::SmoothPixmapTransform)); +#if QT_DEPRECATED_SINCE(5, 14) QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing)); +#endif + QVERIFY(!(webView.renderHints() & QPainter::Antialiasing)); #endif } @@ -480,14 +495,14 @@ void tst_QWebEngineView::microFocusCoordinates() evaluateJavaScriptSync(webView.page(), "document.getElementById('input1').focus()"); QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("input1")); - QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus).isValid()); - QVariant initialMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus); + QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle).isValid()); + QVariant initialMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle); evaluateJavaScriptSync(webView.page(), "window.scrollBy(0, 50)"); QTRY_VERIFY(scrollSpy.count() > 0); - QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus).isValid()); - QVariant currentMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus); + QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle).isValid()); + QVariant currentMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle); QCOMPARE(initialMicroFocus.toRect().translated(QPoint(0,-50)), currentMicroFocus.toRect()); } @@ -2989,7 +3004,7 @@ void tst_QWebEngineView::mouseLeave() QVBoxLayout *layout = new QVBoxLayout; layout->setAlignment(Qt::AlignTop); layout->setSpacing(0); - layout->setMargin(0); + layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(label); layout->addWidget(view); containerWidget->setLayout(layout); diff --git a/tests/manual/widgets/webgl/main.cpp b/tests/manual/widgets/webgl/main.cpp index 364eda8b9..c18a15bac 100644 --- a/tests/manual/widgets/webgl/main.cpp +++ b/tests/manual/widgets/webgl/main.cpp @@ -30,9 +30,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -104,7 +104,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) QSize MainWindow::sizeHint() const { - const QRect desktopRect = QApplication::desktop()->screenGeometry(); + const QRect desktopRect = QGuiApplication::primaryScreen()->geometry(); const QSize size = desktopRect.size() * qreal(0.9); return size; } @@ -172,7 +172,7 @@ int main(int argc, char *argv[]) MainWindow w; // Move middle-ish. - const QRect desktopRect = QApplication::desktop()->screenGeometry(); + const QRect desktopRect = QGuiApplication::primaryScreen()->geometry(); const QSize pos = desktopRect.size() * qreal(0.1); w.move(pos.width(), pos.height()); -- cgit v1.2.1