diff options
29 files changed, 349 insertions, 175 deletions
diff --git a/.qmake.conf b/.qmake.conf index b311aa946..04aa122a8 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -5,4 +5,4 @@ QTWEBENGINE_OUT_ROOT = $$shadowed($$PWD) load(qt_build_config) CONFIG += warning_clean -MODULE_VERSION = 5.15.11 +MODULE_VERSION = 5.15.17 diff --git a/CHROMIUM_VERSION b/CHROMIUM_VERSION index b7e9d2de9..cfc4c49b3 100644 --- a/CHROMIUM_VERSION +++ b/CHROMIUM_VERSION @@ -1,2 +1,2 @@ Based on Chromium version: 87.0.4280.144 -Patched with security patches up to Chromium version: 98.0.4758.102 +Patched with security patches up to Chromium version: 123.0.6312.58 diff --git a/config_help.txt b/config_help.txt index 48236c18a..d50892121 100644 --- a/config_help.txt +++ b/config_help.txt @@ -15,6 +15,7 @@ WebEngine options: (Linux only) -webengine-pepper-plugins ...... Enable use of Pepper Flash and Widevine plugins [auto] + -webengine-python-version ...... Use specific python version for building [python2/python3] -webengine-printing-and-pdf .... Enable use of printing and output to PDF [auto] -webengine-proprietary-codecs .. Enable support for proprietary codecs [no] diff --git a/configure.pri b/configure.pri index e072961f0..cb53c93b0 100644 --- a/configure.pri +++ b/configure.pri @@ -12,12 +12,9 @@ defineTest(isPythonVersionSupported) { python_version ~= s/[()]//g python_version = $$split(python_version, ',') python_major_version = $$first(python_version) - greaterThan(python_major_version, 2) { - qtLog("Python version 3 is not supported by Chromium.") - return(false) - } python_minor_version = $$member(python_version, 1) python_patch_version = $$member(python_version, 2) + greaterThan(python_major_version, 2): greaterThan(python_minor_version, 7): return(true) greaterThan(python_major_version, 1): greaterThan(python_minor_version, 6): greaterThan(python_patch_version, 4): return(true) qtLog("Unsupported python version: $${python_major_version}.$${python_minor_version}.$${python_patch_version}.") return(false) @@ -53,21 +50,37 @@ defineTest(qtConfReport_jumboBuild) { } defineTest(qtConfTest_detectPython2) { - python = $$qtConfFindInPath("python2$$EXE_SUFFIX") - isEmpty(python) { - qtLog("'python2$$EXE_SUFFIX' not found in PATH. Checking for 'python$$EXE_SUFFIX'.") - python = $$qtConfFindInPath("python$$EXE_SUFFIX") + pythonOverride = $$eval(config.input.python_override) + !isEmpty(pythonOverride) { + python = $$qtConfFindInPath("$$pythonOverride$$EXE_SUFFIX") + isEmpty(python) { + qtLog("User selected '$$pythonOverride$$EXE_SUFFIX' was not found in PATH. Giving up.") + return(false) + } } + + win32 { + # the default name of the python 2 executable on windows is just + # python, so try that first + isEmpty(python):python = $$qtConfFindInPath("python$$EXE_SUFFIX") + isEmpty(python):python = $$qtConfFindInPath("python2$$EXE_SUFFIX") + isEmpty(python):python = $$qtConfFindInPath("python3$$EXE_SUFFIX") + } else { + isEmpty(python):python = $$qtConfFindInPath("python2$$EXE_SUFFIX") + isEmpty(python):python = $$qtConfFindInPath("python3$$EXE_SUFFIX") + isEmpty(python):python = $$qtConfFindInPath("python$$EXE_SUFFIX") + } + isEmpty(python) { - qtLog("'python$$EXE_SUFFIX' not found in PATH. Giving up.") + qtLog("Python not found in PATH. Giving up.") return(false) } !isPythonVersionSupported($$python) { - qtLog("A suitable Python 2 executable could not be located.") + qtLog("A suitable Python executable could not be located.") return(false) } - # Make tests.python2.location available in configure.json. + # Make tests.python.location available in configure.json. $${1}.location = $$clean_path($$python) export($${1}.location) $${1}.cache += location @@ -460,6 +473,10 @@ defineTest(qtwebengine_isMacOsPlatformSupported) { qtwebengine_platformError("requires a macOS SDK version of 10.13 or newer. Current version is $${WEBENGINE_OSX_SDK_PRODUCT_VERSION}.") return(false) } + CONFIG(debug, debug|release):isUniversal(){ + qtwebengine_platformError("Universal builds can not be done with debug configuration due to large binary size.") + return(false) + } return(true) } diff --git a/src/3rdparty b/src/3rdparty -Subproject be349eaf62e77955791d7bf29f893f1e8a37daf +Subproject fdfef5b37af3bed8402d7c7e20a5487f2602b0a diff --git a/src/buildtools/config/support.pri b/src/buildtools/config/support.pri index e7f869a15..a9df3d243 100644 --- a/src/buildtools/config/support.pri +++ b/src/buildtools/config/support.pri @@ -21,7 +21,7 @@ defineReplace(qtwebengine_checkWebEngineCoreError) { !qtwebengine_checkForGperf(QtWebEngine):return(false) !qtwebengine_checkForBison(QtWebEngine):return(false) !qtwebengine_checkForFlex(QtWebEngine):return(false) - !qtwebengine_checkForPython2(QtWebEngine):return(false) + !qtwebengine_checkForPython(QtWebEngine):return(false) !qtwebengine_checkForNodejs(QtWebEngine):return(false) !qtwebengine_checkForSanitizer(QtWebEngine):return(false) linux:!qtwebengine_checkForPkgCfg(QtWebEngine):return(false) @@ -51,7 +51,7 @@ defineReplace(qtwebengine_checkPdfError) { !qtwebengine_checkForGperf(QtPdf):return(false) !qtwebengine_checkForBison(QtPdf):return(false) !qtwebengine_checkForFlex(QtPdf):return(false) - !qtwebengine_checkForPython2(QtPdf):return(false) + !qtwebengine_checkForPython(QtPdf):return(false) !qtwebengine_checkForSanitizer(QtPdf):return(false) linux:!qtwebengine_checkForPkgCfg(QtPdf):return(false) linux:!qtwebengine_checkForHostPkgCfg(QtPdf):return(false) @@ -143,10 +143,10 @@ defineTest(qtwebengine_checkForFlex) { return(true) } -defineTest(qtwebengine_checkForPython2) { +defineTest(qtwebengine_checkForPython) { module = $$1 - !qtConfig(webengine-python2) { - qtwebengine_skipBuild("Python version 2 (2.7.5 or later) is required to build $${module}.") + !qtConfig(webengine-python) { + qtwebengine_skipBuild("Python version 2 (2.7.5 or later) or Python version 3 (3.6 or later) is required to build $${module}.") return(false) } return(true) diff --git a/src/buildtools/configure.json b/src/buildtools/configure.json index 88d1790c1..5e5d9d725 100644 --- a/src/buildtools/configure.json +++ b/src/buildtools/configure.json @@ -10,7 +10,8 @@ "options": { "build-qtwebengine-core": "boolean", "build-qtpdf": "boolean", - "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"} + "webengine-jumbo-build": { "type": "optionalString", "name": "merge_limit"}, + "webengine-python-version": { "type": "optionalString", "name": "python_override", "values": ["python2", "python3"] } } }, "libraries": { @@ -212,6 +213,27 @@ { "type": "pkgConfig", "args": "libavcodec libavformat libavutil" } ] }, + "webengine-ffmpeg-support": { + "label": "compatible ffmpeg", + "type": "compile", + "test": { + "head": [ + "#include <libavformat/version.h>", + "extern \"C\" {", + "#include <libavformat/avformat.h>", + "}" + ], + "main": [ + "#if LIBAVFORMAT_VERSION_MAJOR >= 59", + "AVStream stream;", + "auto first_dts = av_stream_get_first_dts(&stream);", + "#endif" + ] + }, + "sources": [ + { "type": "pkgConfig", "args": "libavformat" } + ] + }, "webengine-opus": { "label": "opus", "sources": [ @@ -295,7 +317,7 @@ "label": "system ninja", "type": "detectNinja" }, - "webengine-python2": { + "webengine-python": { "label": "python2", "type": "detectPython2", "log": "location" @@ -374,7 +396,7 @@ && features.webengine-gperf && features.webengine-bison && features.webengine-flex - && features.webengine-python2 + && features.webengine-python && features.webengine-nodejs && (!config.sanitizer || features.webengine-sanitizer) && (!config.linux || features.pkg-config) @@ -400,7 +422,7 @@ && features.webengine-gperf && features.webengine-bison && features.webengine-flex - && features.webengine-python2 + && features.webengine-python && (!config.sanitizer || features.webengine-sanitizer) && (!config.linux || features.pkg-config) && (!config.linux || features.webengine-host-pkg-config) @@ -423,12 +445,12 @@ "autoDetect": "features.private_tests", "output": [ "privateFeature" ] }, - "webengine-python2": { + "webengine-python": { "label": "python2", - "condition": "tests.webengine-python2", + "condition": "tests.webengine-python", "output": [ "privateFeature", - { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python2.location" } + { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.webengine-python.location" } ] }, "webengine-gperf": { @@ -758,6 +780,11 @@ "type": "warning", "condition": "config.ios && config.simulator && config.device && features.build-qtpdf", "message": "Building fat libray with device and simulator architectures will disable NEON." + }, + { + "type": "fatal", + "condition": "features.webengine-system-ffmpeg && !libs.webengine-ffmpeg-support", + "message": "Unmodified ffmpeg >= 5.0 is not supported. Please configure with -qt-webengine-ffmpeg." } ], "summary": [ diff --git a/src/core/accessibility_activation_observer.cpp b/src/core/accessibility_activation_observer.cpp index 833190844..b9d73cb68 100644 --- a/src/core/accessibility_activation_observer.cpp +++ b/src/core/accessibility_activation_observer.cpp @@ -48,12 +48,13 @@ namespace QtWebEngineCore { namespace { bool isAccessibilityEnabled() { - // On Linux accessibility is disabled by default due to performance issues, - // and can be re-enabled by setting the QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment - // variable. For details, see QTBUG-59922. + // On Linux accessibility can be disabled due to performance issues by setting the + // QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment variable to 0. For details, + // see QTBUG-59922. #ifdef Q_OS_LINUX static bool accessibility_enabled - = qEnvironmentVariableIsSet("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY"); + = qEnvironmentVariable("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY", QLatin1String("1")) + == QLatin1String("1"); #else const bool accessibility_enabled = true; #endif diff --git a/src/core/browsing_data_remover_delegate_qt.h b/src/core/browsing_data_remover_delegate_qt.h index a10409f39..5adfbbe7e 100644 --- a/src/core/browsing_data_remover_delegate_qt.h +++ b/src/core/browsing_data_remover_delegate_qt.h @@ -40,6 +40,8 @@ #ifndef BROWSING_DATA_REMOVER_DELEGATE_QT_H #define BROWSING_DATA_REMOVER_DELEGATE_QT_H +#include <cstdint> + #include "content/public/browser/browsing_data_remover_delegate.h" namespace QtWebEngineCore { diff --git a/src/core/compositor/content_gpu_client_qt.cpp b/src/core/compositor/content_gpu_client_qt.cpp index f934979a0..2c0f78548 100644 --- a/src/core/compositor/content_gpu_client_qt.cpp +++ b/src/core/compositor/content_gpu_client_qt.cpp @@ -38,22 +38,151 @@ ****************************************************************************/ #include "content_gpu_client_qt.h" - #include "web_engine_context.h" +#include "ui/gl/gl_share_group.h" +#include "ui/gl/gl_context.h" +#include "ui/gl/gl_implementation.h" +#include "ui/gl/gpu_timing.h" + +#if QT_CONFIG(opengl) +#include <QOpenGLContext> +#include <QOpenGLExtraFunctions> +#endif + +#include <QGuiApplication> +#include <qpa/qplatformnativeinterface.h> + +#if QT_CONFIG(opengl) +QT_BEGIN_NAMESPACE +Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); +QT_END_NAMESPACE +#endif namespace QtWebEngineCore { -ContentGpuClientQt::ContentGpuClientQt() +class QtShareGLContext : public gl::GLContext { -} +public: + QtShareGLContext(QOpenGLContext *qtContext) : gl::GLContext(0), m_handle(0) + { + QString platform = qApp->platformName().toLower(); + QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface(); + if (platform == QLatin1String("xcb") || platform == QLatin1String("offscreen")) { + if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2) + m_handle = + pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); + else + m_handle = + pni->nativeResourceForContext(QByteArrayLiteral("glxcontext"), qtContext); + } else if (platform == QLatin1String("cocoa")) + m_handle = pni->nativeResourceForContext(QByteArrayLiteral("cglcontextobj"), qtContext); + else if (platform == QLatin1String("qnx")) + m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); + else if (platform == QLatin1String("eglfs") || platform == QLatin1String("wayland") + || platform == QLatin1String("wayland-egl")) + m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); + else if (platform == QLatin1String("windows")) { + if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2) + m_handle = + pni->nativeResourceForContext(QByteArrayLiteral("eglContext"), qtContext); + else + m_handle = pni->nativeResourceForContext(QByteArrayLiteral("renderingcontext"), + qtContext); + } else { + qFatal("%s platform not yet supported", platform.toLatin1().constData()); + // Add missing platforms once they work. + Q_UNREACHABLE(); + } + } + + void *GetHandle() override { return m_handle; } + unsigned int CheckStickyGraphicsResetStatusImpl() override + { +#if QT_CONFIG(opengl) + if (QOpenGLContext *context = qt_gl_global_share_context()) { + if (context->format().testOption(QSurfaceFormat::ResetNotification)) + return context->extraFunctions()->glGetGraphicsResetStatus(); + } +#endif + return 0 /*GL_NO_ERROR*/; + } + + // We don't care about the rest, this context shouldn't be used except for its handle. + bool Initialize(gl::GLSurface *, const gl::GLContextAttribs &) override + { + Q_UNREACHABLE(); + return false; + } + bool MakeCurrentImpl(gl::GLSurface *) override + { + Q_UNREACHABLE(); + return false; + } + void ReleaseCurrent(gl::GLSurface *) override + { + Q_UNREACHABLE(); + } + bool IsCurrent(gl::GLSurface *) override + { + Q_UNREACHABLE(); + return false; + } + scoped_refptr<gl::GPUTimingClient> CreateGPUTimingClient() override + { + return nullptr; + } + const gfx::ExtensionSet &GetExtensions() override + { + static const gfx::ExtensionSet s_emptySet; + return s_emptySet; + } + void ResetExtensions() override { } + +private: + void *m_handle; +}; -ContentGpuClientQt::~ContentGpuClientQt() +class ShareGroupQtQuick : public gl::GLShareGroup { +public: + gl::GLContext *GetContext() override { return m_shareContextQtQuick.get(); } + void AboutToAddFirstContext() override; + +private: + scoped_refptr<QtShareGLContext> m_shareContextQtQuick; +}; + +void ShareGroupQtQuick::AboutToAddFirstContext() +{ +#if QT_CONFIG(opengl) + // This currently has to be setup by ::main in all applications using QQuickWebEngineView + // with de legated rendering. + QOpenGLContext *shareContext = qt_gl_global_share_context(); + if (!shareContext) { + qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure " + "to" + "call QtWebEngine::initialize() in your main() function before QCoreApplication " + "is " + "created."); + } + m_shareContextQtQuick = new QtShareGLContext(shareContext); +#endif } +ContentGpuClientQt::ContentGpuClientQt() { } + +ContentGpuClientQt::~ContentGpuClientQt() { } + gpu::SyncPointManager *ContentGpuClientQt::GetSyncPointManager() { return WebEngineContext::syncPointManager(); } +gl::GLShareGroup *ContentGpuClientQt::GetInProcessGpuShareGroup() +{ + if (!m_shareGroupQtQuick.get()) + m_shareGroupQtQuick = new ShareGroupQtQuick; + return m_shareGroupQtQuick.get(); +} + } // namespace diff --git a/src/core/compositor/content_gpu_client_qt.h b/src/core/compositor/content_gpu_client_qt.h index d7ad43881..5288c65bd 100644 --- a/src/core/compositor/content_gpu_client_qt.h +++ b/src/core/compositor/content_gpu_client_qt.h @@ -43,6 +43,8 @@ namespace QtWebEngineCore { +class ShareGroupQtQuick; + class ContentGpuClientQt : public content::ContentGpuClient { public: explicit ContentGpuClientQt(); @@ -50,6 +52,10 @@ public: // content::ContentGpuClient implementation. gpu::SyncPointManager *GetSyncPointManager() override; + gl::GLShareGroup *GetInProcessGpuShareGroup() override; + +private: + scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick; }; } diff --git a/src/core/config/common.pri b/src/core/config/common.pri index d9d64e76b..fc46d55ce 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -46,3 +46,4 @@ qtConfig(webengine-kerberos) { } !qtConfig(webengine-nodejs10): gn_args += use_rollup=false +gn_args += enable_ipc_logging=false diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index f3eccb921..e15bd05f3 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -80,7 +80,6 @@ #include "ui/base/ui_base_switches.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" -#include "ui/gl/gl_share_group.h" #include "ui/gl/gpu_timing.h" #include "url/url_util_qt.h" @@ -118,11 +117,6 @@ #include "api/qwebenginecookiestore.h" #include "api/qwebenginecookiestore_p.h" -#if QT_CONFIG(opengl) -#include <QOpenGLContext> -#include <QOpenGLExtraFunctions> -#endif - #if QT_CONFIG(webengine_geolocation) #include "base/memory/ptr_util.h" #include "location_provider_qt.h" @@ -179,11 +173,6 @@ #include <QGuiApplication> #include <QStandardPaths> -#include <qpa/qplatformnativeinterface.h> - -QT_BEGIN_NAMESPACE -Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); -QT_END_NAMESPACE // Implement IsHandledProtocol as declared in //url/url_util_qt.h. namespace url { @@ -231,93 +220,6 @@ void MaybeAddThrottle( throttles->push_back(std::move(maybe_throttle)); } -class QtShareGLContext : public gl::GLContext { -public: - QtShareGLContext(QOpenGLContext *qtContext) - : gl::GLContext(0) - , m_handle(0) - { - QString platform = qApp->platformName().toLower(); - QPlatformNativeInterface *pni = QGuiApplication::platformNativeInterface(); - if (platform == QLatin1String("xcb") || platform == QLatin1String("offscreen")) { - if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2) - m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); - else - m_handle = pni->nativeResourceForContext(QByteArrayLiteral("glxcontext"), qtContext); - } else if (platform == QLatin1String("cocoa")) - m_handle = pni->nativeResourceForContext(QByteArrayLiteral("cglcontextobj"), qtContext); - else if (platform == QLatin1String("qnx")) - m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); - else if (platform == QLatin1String("eglfs") || platform == QLatin1String("wayland") - || platform == QLatin1String("wayland-egl")) - m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglcontext"), qtContext); - else if (platform == QLatin1String("windows")) { - if (gl::GetGLImplementation() == gl::kGLImplementationEGLGLES2) - m_handle = pni->nativeResourceForContext(QByteArrayLiteral("eglContext"), qtContext); - else - m_handle = pni->nativeResourceForContext(QByteArrayLiteral("renderingcontext"), qtContext); - } else { - qFatal("%s platform not yet supported", platform.toLatin1().constData()); - // Add missing platforms once they work. - Q_UNREACHABLE(); - } - } - - void* GetHandle() override { return m_handle; } - unsigned int CheckStickyGraphicsResetStatusImpl() override - { -#if QT_CONFIG(opengl) - if (QOpenGLContext *context = qt_gl_global_share_context()) { - if (context->format().testOption(QSurfaceFormat::ResetNotification)) - return context->extraFunctions()->glGetGraphicsResetStatus(); - } -#endif - return 0 /*GL_NO_ERROR*/; - } - - // We don't care about the rest, this context shouldn't be used except for its handle. - bool Initialize(gl::GLSurface *, const gl::GLContextAttribs &) override { Q_UNREACHABLE(); return false; } - bool MakeCurrentImpl(gl::GLSurface *) override { Q_UNREACHABLE(); return false; } - void ReleaseCurrent(gl::GLSurface *) override { Q_UNREACHABLE(); } - bool IsCurrent(gl::GLSurface *) override { Q_UNREACHABLE(); return false; } - scoped_refptr<gl::GPUTimingClient> CreateGPUTimingClient() override - { - return nullptr; - } - const gfx::ExtensionSet& GetExtensions() override - { - static const gfx::ExtensionSet s_emptySet; - return s_emptySet; - } - void ResetExtensions() override - { - } - -private: - void *m_handle; -}; - -class ShareGroupQtQuick : public gl::GLShareGroup { -public: - gl::GLContext* GetContext() override { return m_shareContextQtQuick.get(); } - void AboutToAddFirstContext() override; - -private: - scoped_refptr<QtShareGLContext> m_shareContextQtQuick; -}; - -void ShareGroupQtQuick::AboutToAddFirstContext() -{ -#if QT_CONFIG(opengl) - // This currently has to be setup by ::main in all applications using QQuickWebEngineView with delegated rendering. - QOpenGLContext *shareContext = qt_gl_global_share_context(); - if (!shareContext) { - qFatal("QWebEngine: OpenGL resource sharing is not set up in QtQuick. Please make sure to call QtWebEngine::initialize() in your main() function before QCoreApplication is created."); - } - m_shareContextQtQuick = new QtShareGLContext(shareContext); -#endif -} - ContentBrowserClientQt::ContentBrowserClientQt() { } @@ -364,13 +266,6 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost renderer_configuration->SetInitialConfiguration(is_incognito_process); } -gl::GLShareGroup *ContentBrowserClientQt::GetInProcessGpuShareGroup() -{ - if (!m_shareGroupQtQuick.get()) - m_shareGroupQtQuick = new ShareGroupQtQuick; - return m_shareGroupQtQuick.get(); -} - content::MediaObserver *ContentBrowserClientQt::GetMediaObserver() { return MediaCaptureDevicesDispatcher::GetInstance(); @@ -868,6 +763,15 @@ static void LaunchURL(const GURL& url, protocolHandlerRegistry->IsHandledProtocol(url.scheme())) return; +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (guest_view::GuestViewBase::IsGuest(webContents)) { + // Use parent / top level contents delegate for launching URLs from guest views. + webContents = guest_view::GuestViewBase::GetTopLevelWebContents(webContents); + if (!webContents) + return; + } +#endif //BUILDFLAG(ENABLE_EXTENSIONS) + WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate()); contentsDelegate->launchExternalURL(toQt(url), page_transition, is_main_frame, has_user_gesture); } diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 7c8aa3ac9..06e2e9a20 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -60,14 +60,8 @@ struct MainFunctionParams; struct Referrer; } -namespace gl { -class GLShareGroup; -} - namespace QtWebEngineCore { -class ShareGroupQtQuick; - class ContentBrowserClientQt : public content::ContentBrowserClient { public: @@ -75,7 +69,6 @@ public: ~ContentBrowserClientQt(); std::unique_ptr<content::BrowserMainParts> CreateBrowserMainParts(const content::MainFunctionParams&) override; void RenderProcessWillLaunch(content::RenderProcessHost *host) override; - gl::GLShareGroup* GetInProcessGpuShareGroup() override; content::MediaObserver* GetMediaObserver() override; scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() override; void OverrideWebkitPrefs(content::RenderViewHost *render_view_host, @@ -266,9 +259,6 @@ public: std::string GetUserAgent() override { return getUserAgent(); } std::string GetProduct() override; - -private: - scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick; }; } // namespace QtWebEngineCore diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index f1ad1e677..b694d1759 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -295,7 +295,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content ++m_currentId, toQt(web_contents->GetURL()), download::DownloadItem::IN_PROGRESS, - 0, /* totalBytes */ + -1, /* totalBytes */ 0, /* receivedBytes */ QStringLiteral("application/x-mimearchive"), suggestedFilePath, diff --git a/src/core/net/client_cert_store_data.cpp b/src/core/net/client_cert_store_data.cpp index 314e64145..a96e247b2 100644 --- a/src/core/net/client_cert_store_data.cpp +++ b/src/core/net/client_cert_store_data.cpp @@ -104,8 +104,8 @@ public: std::vector<uint16_t> GetAlgorithmPreferences() override { - return { SSL_SIGN_RSA_PKCS1_SHA1, SSL_SIGN_RSA_PKCS1_SHA512 - , SSL_SIGN_RSA_PKCS1_SHA384, SSL_SIGN_RSA_PKCS1_SHA256 }; + return net::SSLPrivateKey::DefaultAlgorithmPreferences(EVP_PKEY_id(m_key), + /* supports pss */ true); } std::string GetProviderName() override { return "qtwebengine"; diff --git a/src/core/net/proxying_url_loader_factory_qt.cpp b/src/core/net/proxying_url_loader_factory_qt.cpp index a9b774086..a016cbc72 100644 --- a/src/core/net/proxying_url_loader_factory_qt.cpp +++ b/src/core/net/proxying_url_loader_factory_qt.cpp @@ -66,6 +66,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +namespace { + network::mojom::URLResponseHeadPtr createResponse(const network::ResourceRequest &request) { + const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity); + network::mojom::URLResponseHeadPtr response = network::mojom::URLResponseHead::New(); + response->response_type = network::cors::CalculateResponseType( + request.mode, disable_web_security || ( + request.request_initiator && request.request_initiator->IsSameOriginWith(url::Origin::Create(request.url)))); + + return response; + } +} + namespace QtWebEngineCore { ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, blink::mojom::ResourceType::kMainFrame) @@ -211,11 +223,7 @@ InterceptedRequest::InterceptedRequest(ProfileAdapter *profile_adapter, , weak_factory_(this) { const bool disable_web_security = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableWebSecurity); - current_response_ = network::mojom::URLResponseHead::New(); - current_response_->response_type = network::cors::CalculateResponseType( - request_.mode, - disable_web_security || ( - request_.request_initiator && request_.request_initiator->IsSameOriginWith(url::Origin::Create(request_.url)))); + current_response_ = createResponse(request_); // If there is a client error, clean up the request. target_client_.set_disconnect_handler( base::BindOnce(&InterceptedRequest::OnURLLoaderClientError, base::Unretained(this))); @@ -381,9 +389,6 @@ void InterceptedRequest::ContinueAfterIntercept() first_party_url_policy, request_.referrer_policy, request_.referrer.spec(), net::HTTP_TEMPORARY_REDIRECT, toGurl(info.url), base::nullopt, false /*insecure_scheme_was_upgraded*/); - - // FIXME: Should probably create a new header. - current_response_->encoded_data_length = 0; request_.method = redirectInfo.new_method; request_.url = redirectInfo.new_url; request_.site_for_cookies = redirectInfo.new_site_for_cookies; @@ -391,6 +396,11 @@ void InterceptedRequest::ContinueAfterIntercept() request_.referrer_policy = redirectInfo.new_referrer_policy; if (request_.method == net::HttpRequestHeaders::kGetMethod) request_.request_body = nullptr; + // In case of multiple sequential rediredts, current_response_ has previously been moved to target_client_ + // so we create a new one using the redirect url. + if (!current_response_) + current_response_ = createResponse(request_); + current_response_->encoded_data_length = 0; target_client_->OnReceiveRedirect(redirectInfo, std::move(current_response_)); return; } diff --git a/src/core/ozone/gl_context_qt.cpp b/src/core/ozone/gl_context_qt.cpp index 9a24f6bf4..0e7213a3a 100644 --- a/src/core/ozone/gl_context_qt.cpp +++ b/src/core/ozone/gl_context_qt.cpp @@ -51,8 +51,10 @@ #endif QT_BEGIN_NAMESPACE - +#if QT_CONFIG(opengl) Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); +#endif + GLContextHelper* GLContextHelper::contextHelper = 0; namespace { diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index eb459fbdc..184f78c3b 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -637,6 +637,7 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing); +#if QT_CONFIG(opengl) #if defined(Q_OS_WIN) // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create // an OpenGL Core Profile context. If the switch is not set, it would always try to create a @@ -659,7 +660,8 @@ WebEngineContext::WebEngineContext() if (isDesktopGLOrSoftware || isGLES2Context) parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext); -#endif +#endif // defined(Q_OS_WIN) +#endif // QT_CONFIG(opengl) // Do not advertise a feature we have removed at compile time parsedCommandLine->AppendSwitch(switches::kDisableSpeechAPI); diff --git a/src/pdf/qpdfdocument.cpp b/src/pdf/qpdfdocument.cpp index e4ec363ce..c07ec90c4 100644 --- a/src/pdf/qpdfdocument.cpp +++ b/src/pdf/qpdfdocument.cpp @@ -424,6 +424,8 @@ QRectF QPdfDocumentPrivate::getCharBox(FPDF_TEXTPAGE textPage, double pageHeight QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF position) { const QPdfMutexLocker lock; + + TextPosition result; FPDF_PAGE pdfPage = FPDF_LoadPage(doc, page); double pageHeight = FPDF_GetPageHeight(pdfPage); FPDF_TEXTPAGE textPage = FPDFText_LoadPage(pdfPage); @@ -440,10 +442,14 @@ QPdfDocumentPrivate::TextPosition QPdfDocumentPrivate::hitTest(int page, QPointF ++hitIndex; } qCDebug(qLcDoc) << "on page" << page << "@" << position << "got char position" << charPos << "index" << hitIndex; - return { charPos, charBox.height(), hitIndex }; + result = { charPos, charBox.height(), hitIndex }; } } - return {}; + + FPDFText_ClosePage(textPage); + FPDF_ClosePage(pdfPage); + + return result; } /*! @@ -789,6 +795,9 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end) CharacterHitTolerance, CharacterHitTolerance); int endIndex = FPDFText_GetCharIndexAtPos(textPage, end.x(), pageHeight - end.y(), CharacterHitTolerance, CharacterHitTolerance); + + QPdfSelection result; + if (startIndex >= 0 && endIndex != startIndex) { if (startIndex > endIndex) qSwap(startIndex, endIndex); @@ -815,11 +824,15 @@ QPdfSelection QPdfDocument::getSelection(int page, QPointF start, QPointF end) bounds << QPolygonF(rect); } qCDebug(qLcDoc) << page << start << "->" << end << "found" << startIndex << "->" << endIndex << text; - return QPdfSelection(text, bounds, hull, startIndex, endIndex); + result = QPdfSelection(text, bounds, hull, startIndex, endIndex); + } else { + qCDebug(qLcDoc) << page << start << "->" << end << "nothing found"; } - qCDebug(qLcDoc) << page << start << "->" << end << "nothing found"; - return QPdfSelection(); + FPDFText_ClosePage(textPage); + FPDF_ClosePage(pdfPage); + + return result; } /*! @@ -860,6 +873,10 @@ QPdfSelection QPdfDocument::getSelectionAtIndex(int page, int startIndex, int ma hull = QRectF(d->getCharPosition(textPage, pageHeight, startIndex), QSizeF()); qCDebug(qLcDoc) << "on page" << page << "at index" << startIndex << "maxLength" << maxLength << "got" << text.length() << "chars," << rectCount << "rects within" << hull; + + FPDFText_ClosePage(textPage); + FPDF_ClosePage(pdfPage); + return QPdfSelection(text, bounds, hull, startIndex, startIndex + text.length()); } @@ -890,6 +907,10 @@ QPdfSelection QPdfDocument::getAllText(int page) bounds << QPolygonF(rect); } qCDebug(qLcDoc) << "on page" << page << "got" << count << "chars," << rectCount << "rects within" << hull; + + FPDFText_ClosePage(textPage); + FPDF_ClosePage(pdfPage); + return QPdfSelection(text, bounds, hull, 0, count); } diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index e32424eea..9f75beb85 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -126,6 +126,10 @@ \note \QWE cannot be built for the 32-bit mode of \macos (using the \c macx-clang-32 \c mkspec). + \note Universal debug or debug-and-release builds of \QWE on \macos are not supported in Qt 5 + due to memory constraints of the build toolchain. Use the configure options \c -force-debug-info + and \c -separate-debug-info for a build that can be used with a debugger. + \section1 Using Earlier Qt Versions to Build \QWE Building \QWE with earlier Qt versions (down to the last LTS @@ -221,13 +225,11 @@ or VoiceOver on \macos. \endlist - Due to some limitations, the Linux QPA plugin almost always reports that accessibility should - be activated. On big HTML pages, this can cause a significant slowdown in rendering speed. + On some old Linux configurations, accessibility can cause a significant slowdown + on large HTML pages. - Because of that, from Qt 5.9 onwards, \QWE accessibility support is disabled by default - on Linux. - It can be re-enabled by setting the \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment - variable to a non-empty value. + Because of that, \QWE accessibility support can be disabled on Linux, by setting the + \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment variable to 0. \section1 Popups in Fullscreen Applications on Windows Because of a limitation in the Windows compositor, applications that show a fullscreen web diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp index 7366dbf59..d44b9e4e9 100644 --- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp +++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp @@ -465,7 +465,7 @@ QWebEngineDownloadItem::DownloadState QWebEngineDownloadItem::state() const } /*! - Returns the the total amount of data to download in bytes. + Returns the total amount of data to download in bytes. \c -1 means the size is unknown. */ diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index 223d3b114..b25055d79 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -228,6 +228,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) itemPrivate->downloadState = info.accepted ? QWebEngineDownloadItem::DownloadInProgress : QWebEngineDownloadItem::DownloadRequested; itemPrivate->startTime = info.startTime; + itemPrivate->totalBytes = info.totalBytes; itemPrivate->downloadDirectory = QFileInfo(info.path).path(); itemPrivate->downloadFileName = QFileInfo(info.path).fileName(); itemPrivate->suggestedFileName = info.suggestedFileName; diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html new file mode 100644 index 000000000..84bf55036 --- /dev/null +++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content3.html @@ -0,0 +1,6 @@ +<html> +<head><link rel="icon" href="data:,"></head> +<body> +<a>Simple test page without favicon (meaning no separate request from http server)</a> +</body> +</html> diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp index 642e5db7c..32a618de3 100644 --- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp +++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp @@ -79,6 +79,7 @@ private Q_SLOTS: void replaceInterceptor_data(); void replaceInterceptor(); void replaceOnIntercept(); + void multipleRedirects(); }; tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor() @@ -211,6 +212,29 @@ public: } }; +class TestMultipleRedirectsInterceptor : public QWebEngineUrlRequestInterceptor { +public: + QList<RequestInfo> requestInfos; + QMap<QUrl, QUrl> redirectPairs; + int redirectCount = 0; + void interceptRequest(QWebEngineUrlRequestInfo &info) override + { + QVERIFY(QThread::currentThread() == QCoreApplication::instance()->thread()); + qCDebug(lc) << this << "Type:" << info.resourceType() << info.requestMethod() << "Navigation:" << info.navigationType() + << info.requestUrl() << "Initiator:" << info.initiator(); + auto redirectUrl = redirectPairs.constFind(info.requestUrl()); + if (redirectUrl != redirectPairs.constEnd()) { + info.redirect(redirectUrl.value()); + requestInfos.append(info); + redirectCount++; + } + } + + TestMultipleRedirectsInterceptor() + { + } +}; + class ConsolePage : public QWebEnginePage { Q_OBJECT public: @@ -915,5 +939,28 @@ void tst_QWebEngineUrlRequestInterceptor::replaceOnIntercept() QCOMPARE(profileInterceptor.requestInfos.size(), pageInterceptor2.requestInfos.size()); } +void tst_QWebEngineUrlRequestInterceptor::multipleRedirects() +{ + HttpServer server; + server.setResourceDirs({ ":/resources" }); + QVERIFY(server.start()); + + TestMultipleRedirectsInterceptor multiInterceptor; + multiInterceptor.redirectPairs.insert(QUrl(server.url("/content.html")), QUrl(server.url("/content2.html"))); + multiInterceptor.redirectPairs.insert(QUrl(server.url("/content2.html")), QUrl(server.url("/content3.html"))); + + QWebEngineProfile profile; + profile.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); + profile.setUrlRequestInterceptor(&multiInterceptor); + QWebEnginePage page(&profile); + QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); + + page.setUrl(server.url("/content.html")); + + QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000); + QTRY_COMPARE(multiInterceptor.redirectCount, 2); + QTRY_COMPARE(multiInterceptor.requestInfos.size(), 2); +} + QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor) #include "tst_qwebengineurlrequestinterceptor.moc" diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc index 6a34635f7..df9c81a7b 100644 --- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc +++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc @@ -1,6 +1,8 @@ <!DOCTYPE RCC><RCC version="1.0"> <qresource prefix="/"> <file>resources/content.html</file> + <file>resources/content2.html</file> + <file>resources/content3.html</file> <file>resources/favicon.html</file> <file>resources/firstparty.html</file> <file>resources/fontawesome.woff</file> diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp index 9a3e7b52e..74082ab8c 100644 --- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp +++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp @@ -455,7 +455,7 @@ void tst_QWebEngineDownloadItem::downloadLink() ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested); QCOMPARE(item->isFinished(), false); - QCOMPARE(item->totalBytes(), -1); + QCOMPARE(item->totalBytes(), fileContents.size()); QCOMPARE(item->receivedBytes(), 0); QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition)); @@ -568,7 +568,7 @@ void tst_QWebEngineDownloadItem::downloadTwoLinks() ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested); QCOMPARE(item->isFinished(), false); - QCOMPARE(item->totalBytes(), -1); + QCOMPARE(item->totalBytes(), 5); // strlen("fileN") QCOMPARE(item->receivedBytes(), 0); QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat); diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST index 2498ed765..d1425bfd6 100644 --- a/tests/auto/widgets/qwebenginepage/BLACKLIST +++ b/tests/auto/widgets/qwebenginepage/BLACKLIST @@ -4,3 +4,4 @@ osx [mouseMovementProperties] windows macos # Can't move cursor (QTBUG-76312) +sles-15.4 # QTBUG-111297 diff --git a/tests/auto/widgets/touchinput/BLACKLIST b/tests/auto/widgets/touchinput/BLACKLIST new file mode 100644 index 000000000..d9e06df8c --- /dev/null +++ b/tests/auto/widgets/touchinput/BLACKLIST @@ -0,0 +1,2 @@ +[touchTap] +sles-15.4 # QTBUG-106334 |