summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael BrĂ¼ning <michael.bruning@qt.io>2020-07-24 10:30:54 +0200
committerMichael BrĂ¼ning <michael.bruning@qt.io>2020-07-24 15:23:10 +0200
commit54b84e14589b3e51f2f2e7980e2af2559601efe2 (patch)
treeeafef9f5b854cd90f6fa8e1ae5ab9e161a424aa3
parent27332664b2745d7d322b8afbc1a41dc0fbfc763a (diff)
parenta2a19a6965601ced75e3e48b2bf618ba2bdbd29e (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts: src/core/compositor/delegated_frame_node.cpp src/core/core_chromium.pri src/core/render_widget_host_view_qt.cpp Change-Id: I9387151e9647c87fc387095e7b6d8d66560cdf71
m---------src/3rdparty0
-rw-r--r--src/buildtools/config/linking.pri75
-rw-r--r--src/buildtools/config/mac_osx.pri1
-rw-r--r--src/buildtools/config/support.pri19
-rw-r--r--src/buildtools/configure.json12
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp48
-rw-r--r--src/core/api/qwebenginecookiestore.cpp9
-rw-r--r--src/core/clipboard_qt.cpp9
-rw-r--r--src/core/compositor/compositor_resource_fence.cpp9
-rw-r--r--src/core/config/linux.pri2
-rw-r--r--src/core/configure.json25
-rw-r--r--src/core/content_client_qt.cpp2
-rw-r--r--src/core/content_main_delegate_qt.cpp9
-rw-r--r--src/core/core_chromium.pri5
-rw-r--r--src/core/core_module.pro57
-rw-r--r--src/core/devtools_frontend_qt.cpp3
-rw-r--r--src/core/devtools_manager_delegate_qt.cpp2
-rw-r--r--src/core/macos_context_type_helper.h42
-rw-r--r--src/core/macos_context_type_helper.mm49
-rw-r--r--src/core/net/cookie_monster_delegate_qt.cpp46
-rw-r--r--src/core/net/cookie_monster_delegate_qt.h4
-rw-r--r--src/core/net/plugin_response_interceptor_url_loader_throttle.cpp2
-rw-r--r--src/core/net/proxying_restricted_cookie_manager_qt.cpp41
-rw-r--r--src/core/net/system_network_context_manager.cpp18
-rw-r--r--src/core/net/system_network_context_manager.h21
-rw-r--r--src/core/permission_manager_qt.cpp10
-rw-r--r--src/core/pref_service_adapter.cpp2
-rw-r--r--src/core/profile_adapter.cpp30
-rw-r--r--src/core/profile_io_data_qt.cpp8
-rw-r--r--src/core/profile_io_data_qt.h2
-rw-r--r--src/core/render_view_context_menu_qt.cpp2
-rw-r--r--src/core/render_widget_host_view_qt_delegate_client.cpp5
-rw-r--r--src/core/web_contents_delegate_qt.cpp9
-rw-r--r--src/core/web_contents_delegate_qt.h1
-rw-r--r--src/core/web_engine_context.cpp10
-rw-r--r--src/core/web_engine_library_info.cpp8
-rw-r--r--src/core/web_event_factory.cpp25
-rw-r--r--src/pdf/config/ios.pri1
-rw-r--r--src/pdf/pdf.pro6
-rw-r--r--src/pdf/pdfcore.pro43
-rw-r--r--src/pdf/pdfcore_prl_generator.pro27
-rw-r--r--src/pdf/quick/quick.pro2
-rw-r--r--src/pdfwidgets/pdfwidgets.pro1
-rw-r--r--src/plugins/imageformats/pdf/pdf.pro6
-rw-r--r--src/tools/qwebengine_convert_dict/main.cpp2
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc9
-rw-r--r--tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro1
-rw-r--r--tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp72
-rw-r--r--tests/auto/shared/httpreqrep.cpp2
-rw-r--r--tests/auto/widgets/proxypac/tst_proxypac.cpp2
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp29
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp5
52 files changed, 601 insertions, 229 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 15a42873b9a4bda657e7a435f25241a05b8bd1c
+Subproject d61a4348c475ab6867334ef3ab4b5709cae15bb
diff --git a/src/buildtools/config/linking.pri b/src/buildtools/config/linking.pri
new file mode 100644
index 000000000..0ee18f3a5
--- /dev/null
+++ b/src/buildtools/config/linking.pri
@@ -0,0 +1,75 @@
+include($$QTWEBENGINE_OUT_ROOT/src/buildtools/qtbuildtools-config.pri)
+QT_FOR_CONFIG += buildtools-private
+
+linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
+
+!include($$linking_pri) {
+ error("Could not find the linking information that gn should have generated.")
+}
+
+# Do not precompile any headers. We are only interested in the linker step.
+PRECOMPILED_HEADER =
+
+isEmpty(NINJA_OBJECTS): error("Missing object files from linking pri.")
+isEmpty(NINJA_LFLAGS): error("Missing linker flags from linking pri")
+isEmpty(NINJA_ARCHIVES): error("Missing archive files from linking pri")
+isEmpty(NINJA_LIBS): error("Missing library files from linking pri")
+NINJA_OBJECTS = $$eval($$list($$NINJA_OBJECTS))
+# Do manual response file linking for macOS and Linux
+
+RSP_OBJECT_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}_o.rsp
+for(object, NINJA_OBJECTS): RSP_O_CONTENT += $$object
+write_file($$RSP_OBJECT_FILE, RSP_O_CONTENT)
+RSP_ARCHIVE_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}_a.rsp
+for(archive, NINJA_ARCHIVES): RSP_A_CONTENT += $$archive
+write_file($$RSP_ARCHIVE_FILE, RSP_A_CONTENT)
+
+if(macos|ios) {
+ QMAKE_LFLAGS += -Wl,-filelist,$$shell_quote($${RSP_OBJECT_FILE})
+ !static {
+ QMAKE_LFLAGS += @$${RSP_ARCHIVE_FILE}
+ } else {
+ LIBS_PRIVATE += $${NINJA_ARCHIVES}
+ }
+}
+
+linux {
+ QMAKE_LFLAGS += @$${RSP_OBJECT_FILE}
+ !static {
+ QMAKE_LFLAGS += -Wl,--start-group @$${RSP_ARCHIVE_FILE} -Wl,--end-group
+ } else {
+ LIBS_PRIVATE += -Wl,--start-group @$${NINJA_ARCHIVES} -Wl,--end-group
+ }
+}
+
+win32 {
+ QMAKE_LFLAGS += @$${RSP_OBJECT_FILE}
+ !static {
+ QMAKE_LFLAGS += @$${RSP_ARCHIVE_FILE}
+ } else {
+ LIBS_PRIVATE += $${NINJA_ARCHIVES}
+ }
+}
+
+LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS
+# GN's LFLAGS doesn't always work across all the Linux configurations we support.
+# The Windows and macOS ones from GN does provide a few useful flags however
+
+unix:qtConfig(webengine-noexecstack): \
+ QMAKE_LFLAGS += -Wl,-z,noexecstack
+linux {
+ # add chromium flags
+ for(flag, NINJA_LFLAGS) {
+ # filter out some flags
+ !contains(flag, .*noexecstack$): \
+ !contains(flag, .*as-needed$): \
+ !contains(flag, ^-B.*): \
+ !contains(flag, ^-fuse-ld.*): \
+ QMAKE_LFLAGS += $$flag
+ }
+} else {
+ QMAKE_LFLAGS += $$NINJA_LFLAGS
+}
+
+POST_TARGETDEPS += $$eval($$NINJA_TARGETDEPS)
+
diff --git a/src/buildtools/config/mac_osx.pri b/src/buildtools/config/mac_osx.pri
index b53f91706..a93460784 100644
--- a/src/buildtools/config/mac_osx.pri
+++ b/src/buildtools/config/mac_osx.pri
@@ -34,5 +34,6 @@ gn_args += \
mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \
mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION_MAJOR_MINOR}\" \
use_external_popup_menu=false \
+ init_stack_vars=false \
angle_enable_vulkan=false
diff --git a/src/buildtools/config/support.pri b/src/buildtools/config/support.pri
index 80f291500..e192f8777 100644
--- a/src/buildtools/config/support.pri
+++ b/src/buildtools/config/support.pri
@@ -5,7 +5,10 @@ defineTest(qtwebengine_skipBuild) {
# this should match webengine-core-support
defineReplace(qtwebengine_checkWebEngineCoreError) {
- !qtwebengine_checkForBuildSupport(QtWebEngine):return(false)
+ !linux:!win32:!macos {
+ qtwebengine_skipBuild("QtWebEngine can be built only on Linux, Windows or macOS.")
+ return(false)
+ }
static {
qtwebengine_skipBuild("Static builds of QtWebEngine are not supported.")
return(false)
@@ -35,7 +38,10 @@ defineReplace(qtwebengine_checkWebEngineCoreError) {
# this shuold match webengine-qtpdf-support
defineReplace(qtwebengine_checkPdfError) {
- !qtwebengine_checkForBuildSupport(QtPdf):return(false)
+ !linux:!win32:!macos:!ios {
+ qtwebengine_skipBuild("QtPdf can be built only on Linux, Windows, macOS or iOS.")
+ return(false)
+ }
!qtwebengine_checkForGui(QtPdf):return(false)
!qtwebengine_checkForSubmodule(QtPdf):return(false)
!qtwebengine_checkForWhiteSpace(QtPdf):return(false)
@@ -52,15 +58,6 @@ defineReplace(qtwebengine_checkPdfError) {
return(true)
}
-defineTest(qtwebengine_checkForBuildSupport) {
- module = $$1
- !linux:!win32:!macos {
- qtwebengine_skipBuild("$${module} can be build only on Linux, Windows or macOS.")
- return(false)
- }
- return(true)
-}
-
defineTest(qtwebengine_checkForGui) {
module = $$1
!qtHaveModule(gui) {
diff --git a/src/buildtools/configure.json b/src/buildtools/configure.json
index 772159add..2da87a11c 100644
--- a/src/buildtools/configure.json
+++ b/src/buildtools/configure.json
@@ -353,6 +353,11 @@
"webengine-sanitizer": {
"label" : "sanitizer support",
"type": "isSanitizerSupported"
+ },
+ "webengine-noexecstack" : {
+ "label": "linker supports -z noexecstack",
+ "type": "linkerSupportsFlag",
+ "flag": "-z,noexecstack"
}
},
"features": {
@@ -384,7 +389,7 @@
},
"webengine-qtpdf-support": {
"label": "Support Qt Pdf",
- "condition": "(config.linux || config.win32 || config.macos)
+ "condition": "(config.linux || config.win32 || config.macos || config.ios)
&& module.gui
&& features.webengine-submodule
&& features.webengine-nowhitespace
@@ -675,6 +680,11 @@
"autoDetect": "config.sanitizer && tests.webengine-sanitizer",
"condition": "config.sanitizer",
"output": [ "privateFeature" ]
+ },
+ "webengine-noexecstack": {
+ "label": "linker supports -z noexecstack",
+ "condition": "config.unix && tests.webengine-noexecstack",
+ "output": [ "privateFeature" ]
}
},
"report": [
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp
index ce4362741..3c9387a10 100644
--- a/src/core/api/qtwebenginecoreglobal.cpp
+++ b/src/core/api/qtwebenginecoreglobal.cpp
@@ -45,6 +45,8 @@
#ifdef Q_OS_MACOS
#include <sys/types.h>
#include <sys/sysctl.h>
+#include <QOffscreenSurface>
+#include "macos_context_type_helper.h"
#endif
#endif
#include <QThread>
@@ -127,6 +129,52 @@ Q_WEBENGINECORE_PRIVATE_EXPORT void initialize()
shareContext = new QOpenGLContext;
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
// format.setOption(QSurfaceFormat::ResetNotification);
+
+#ifdef Q_OS_MACOS
+ if (format == QSurfaceFormat()) {
+ QOpenGLContext testContext;
+
+ // Chromium turns off OpenGL for CoreProfiles with versions < 4.1
+ // The newest Mac that only supports 3.3 was released in Mid 2011,
+ // so it should be safe to request 4.1, but we still double check it
+ // works in order not to set an invalid default surface format.
+ format.setVersion(4, 1);
+ format.setProfile(QSurfaceFormat::CoreProfile);
+
+ testContext.setFormat(format);
+ if (testContext.create()) {
+ QOffscreenSurface surface;
+ surface.setFormat(format);
+ surface.create();
+
+ if (testContext.makeCurrent(&surface)) {
+ // The Cocoa QPA integration allows sharing between OpenGL 3.2 and 4.1 contexts,
+ // which means even though we requested a 4.1 context, if we only get a 3.2 context,
+ // it will still work an Chromium will not black list it.
+ if (testContext.format().version() >= qMakePair(3, 2) &&
+ testContext.format().profile() == QSurfaceFormat::CoreProfile &&
+ !isCurrentContextSoftware()) {
+ QSurfaceFormat::setDefaultFormat(format);
+ } else {
+ qWarning("The available OpenGL surface format was either not version 3.2 or higher or not a Core Profile.\n"
+ "Chromium on macOS will fall back to software rendering in this case.\n"
+ "Hardware acceleration and features such as WebGL will not be available.");
+ format = QSurfaceFormat::defaultFormat();
+ }
+ testContext.doneCurrent();
+ }
+ surface.destroy();
+ }
+ } else {
+ // The user explicitly requested a specific surface format that does not fit Chromium's requirements. Warn them about this.
+ if (format.version() < qMakePair(3,2) || format.profile() != QSurfaceFormat::CoreProfile) {
+ qWarning("An OpenGL surfcace format was requested that is either not version 3.2 or higher or a not Core Profile.\n"
+ "Chromium on macOS will fall back to software rendering in this case.\n"
+ "Hardware acceleration and features such as WebGL will not be available.");
+ }
+ }
+#endif
+
shareContext->setFormat(format);
shareContext->create();
qAddPostRoutine(deleteShareContext);
diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp
index 40594b9c0..a09a74bf6 100644
--- a/src/core/api/qwebenginecookiestore.cpp
+++ b/src/core/api/qwebenginecookiestore.cpp
@@ -89,6 +89,9 @@ void QWebEngineCookieStorePrivate::processPendingUserCookies()
delegate->deleteSessionCookies(CallbackDirectory::DeleteSessionCookiesCallbackId);
}
+ if (bool(filterCallback))
+ delegate->setHasFilter(true);
+
if (m_pendingUserCookies.isEmpty())
return;
@@ -362,7 +365,10 @@ void QWebEngineCookieStore::deleteAllCookies()
*/
void QWebEngineCookieStore::setCookieFilter(const std::function<bool(const FilterRequest &)> &filterCallback)
{
+ bool changed = bool(d_ptr->filterCallback) != bool(filterCallback);
d_ptr->filterCallback = filterCallback;
+ if (changed && d_ptr->delegate)
+ d_ptr->delegate->setHasFilter(bool(d_ptr->filterCallback));
}
/*!
@@ -371,7 +377,10 @@ void QWebEngineCookieStore::setCookieFilter(const std::function<bool(const Filte
*/
void QWebEngineCookieStore::setCookieFilter(std::function<bool(const FilterRequest &)> &&filterCallback)
{
+ bool changed = bool(d_ptr->filterCallback) != bool(filterCallback);
d_ptr->filterCallback = std::move(filterCallback);
+ if (changed && d_ptr->delegate)
+ d_ptr->delegate->setHasFilter(bool(d_ptr->filterCallback));
}
/*!
diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp
index ef7a05299..c3b25ff63 100644
--- a/src/core/clipboard_qt.cpp
+++ b/src/core/clipboard_qt.cpp
@@ -143,7 +143,14 @@ void ClipboardQt::WriteText(const char *text_data, size_t text_len)
void ClipboardQt::WriteHTML(const char *markup_data, size_t markup_len, const char *url_data, size_t url_len)
{
- getUncommittedData()->setHtml(QString::fromUtf8(markup_data, markup_len));
+ QString markup_string = QString::fromUtf8(markup_data, markup_len);
+#if defined (Q_OS_MACOS)
+ // We need to prepend the charset on macOS to prevent garbled Unicode characters
+ // when pasting to certain applications (e.g. Notes, TextEdit)
+ // Mirrors the behavior in ui/base/clipboard/clipboard_mac.mm in Chromium.
+ markup_string.prepend(QLatin1String("<meta charset='utf-8'>"));
+#endif
+ getUncommittedData()->setHtml(markup_string);
}
void ClipboardQt::WriteRTF(const char *rtf_data, size_t data_len)
diff --git a/src/core/compositor/compositor_resource_fence.cpp b/src/core/compositor/compositor_resource_fence.cpp
index 4179395d6..e7bf2fea7 100644
--- a/src/core/compositor/compositor_resource_fence.cpp
+++ b/src/core/compositor/compositor_resource_fence.cpp
@@ -38,15 +38,22 @@
****************************************************************************/
#include "compositor_resource_fence.h"
-
+#include "ozone/gl_surface_qt.h"
#include "ui/gl/gl_context.h"
+#include <QtGui/private/qtguiglobal_p.h>
#include <QtGui/qopenglcontext.h>
#ifndef GL_TIMEOUT_IGNORED
#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
#endif
+
+#if QT_CONFIG(egl)
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#endif
+
namespace QtWebEngineCore {
void CompositorResourceFence::wait()
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index e98524002..26d0dcf7d 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -29,6 +29,8 @@ qtConfig(webengine-embedded-build) {
qtConfig(webengine-webrtc): gn_args += rtc_use_x11=true
}
+ qtConfig(webengine-webrtc): qtConfig(webengine-webrtc-pipewire): gn_args += rtc_use_pipewire=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
diff --git a/src/core/configure.json b/src/core/configure.json
index 1a2162723..4cd6174fc 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -25,6 +25,7 @@
"webengine-native-spellchecker": "boolean",
"webengine-extensions": "boolean",
"webengine-webrtc": "boolean",
+ "webengine-webrtc-pipewire": "boolean",
"webengine-geolocation": "boolean",
"webengine-webchannel": "boolean",
"webengine-kerberos": "boolean",
@@ -67,6 +68,12 @@
"sources": [
{ "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" }
]
+ },
+ "webengine-gio": {
+ "label": "gio",
+ "sources": [
+ { "type": "pkgConfig", "args": "gio-2.0" }
+ ]
}
},
"tests" : {
@@ -85,11 +92,6 @@
"label": "embedded build",
"type": "detectEmbedded"
},
- "webengine-noexecstack" : {
- "label": "linker supports -z noexecstack",
- "type": "linkerSupportsFlag",
- "flag": "-z,noexecstack"
- },
"webengine-nodejs": {
"label": "node.js",
"type": "detectNodeJS"
@@ -183,6 +185,13 @@
"autoDetect": "!features.webengine-embedded-build",
"output": [ "privateFeature" ]
},
+ "webengine-webrtc-pipewire": {
+ "label": "PipeWire over GIO",
+ "purpose": "Provides PipeWire support in WebRTC using GIO.",
+ "condition": "features.webengine-webrtc && libs.webengine-gio",
+ "autoDetect": "false",
+ "output": [ "privateFeature" ]
+ },
"webengine-ozone" : {
"label": "Support qpa-xcb",
"condition": "features.webengine-ozone-x11",
@@ -204,11 +213,6 @@
{ "type": "privateConfig", "name": "webcore_debug" }
]
},
- "webengine-noexecstack": {
- "label": "linker supports -z noexecstack",
- "condition": "config.unix && tests.webengine-noexecstack",
- "output": [ "privateFeature" ]
- },
"webengine-nodejs": {
"label": "Node.js",
"condition": "tests.webengine-nodejs",
@@ -252,6 +256,7 @@
"webengine-spellchecker",
"webengine-native-spellchecker",
"webengine-webrtc",
+ "webengine-webrtc-pipewire",
"webengine-geolocation",
"webengine-webchannel",
"webengine-kerberos",
diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp
index 083e10f2a..647d45819 100644
--- a/src/core/content_client_qt.cpp
+++ b/src/core/content_client_qt.cpp
@@ -199,7 +199,7 @@ void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins)
{
QStringList pluginPaths;
#if defined(Q_OS_WIN)
- QString winDir = QDir::fromNativeSeparators(qgetenv("WINDIR"));
+ QString winDir = QDir::fromNativeSeparators(qEnvironmentVariable("WINDIR"));
if (winDir.isEmpty())
winDir = QString::fromLatin1("C:/Windows");
QDir pluginDir(winDir + "/System32/Macromed/Flash");
diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp
index f93a3c0ea..30bac71af 100644
--- a/src/core/content_main_delegate_qt.cpp
+++ b/src/core/content_main_delegate_qt.cpp
@@ -69,6 +69,7 @@
#endif
#if defined(OS_LINUX)
+#include "media/audio/audio_manager.h"
#include "ui/base/ui_base_switches.h"
#endif
@@ -220,6 +221,14 @@ void ContentMainDelegateQt::PreSandboxStartup()
media::InitializeVideoToolbox();
}
#endif
+
+ if (parsedCommandLine->HasSwitch(service_manager::switches::kApplicationName)) {
+ const std::string appName = parsedCommandLine->GetSwitchValueASCII(service_manager::switches::kApplicationName);
+ QCoreApplication::setApplicationName(QString::fromStdString(appName));
+#if defined(OS_LINUX)
+ media::AudioManager::SetGlobalAppName(appName);
+#endif
+ }
}
content::ContentBrowserClient *ContentMainDelegateQt::CreateContentBrowserClient()
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index 14a65a39c..60cc104cf 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -297,6 +297,11 @@ contains(QT_CONFIG, opengl) {
HEADERS += \
compositor/compositor_resource_fence.h \
compositor/display_gl_output_surface.h
+
+ macos {
+ HEADERS+=macos_context_type_helper.h
+ SOURCES+=macos_context_type_helper.mm
+ }
}
qtConfig(webengine-geolocation) {
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index 5007012ac..3b439e818 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -1,62 +1,10 @@
MODULE = webenginecore
include(core_common.pri)
-# Needed to set a CFBundleIdentifier
-QMAKE_INFO_PLIST = Info_mac.plist
-
-linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
-
-!include($$linking_pri) {
- error("Could not find the linking information that gn should have generated.")
-}
+include($${QTWEBENGINE_ROOT}/src/buildtools/config/linking.pri)
api_library_name = qtwebenginecoreapi$$qtPlatformTargetSuffix()
api_library_path = $$OUT_PWD/api/$$getConfigDir()
-
-# Do not precompile any headers. We are only interested in the linker step.
-PRECOMPILED_HEADER =
-
-isEmpty(NINJA_OBJECTS): error("Missing object files from QtWebEngineCore linking pri.")
-isEmpty(NINJA_LFLAGS): error("Missing linker flags from QtWebEngineCore linking pri")
-isEmpty(NINJA_ARCHIVES): error("Missing archive files from QtWebEngineCore linking pri")
-isEmpty(NINJA_LIBS): error("Missing library files from QtWebEngineCore linking pri")
-NINJA_OBJECTS = $$eval($$list($$NINJA_OBJECTS))
-# Do manual response file linking for macOS and Linux
-
-RSP_OBJECT_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}_o.rsp
-for(object, NINJA_OBJECTS): RSP_O_CONTENT += $$object
-write_file($$RSP_OBJECT_FILE, RSP_O_CONTENT)
-RSP_ARCHIVE_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}_a.rsp
-for(archive, NINJA_ARCHIVES): RSP_A_CONTENT += $$archive
-write_file($$RSP_ARCHIVE_FILE, RSP_A_CONTENT)
-
-macos:LIBS_PRIVATE += -Wl,-filelist,$$shell_quote($${RSP_OBJECT_FILE}) @$${RSP_ARCHIVE_FILE}
-linux:QMAKE_LFLAGS += @$${RSP_OBJECT_FILE} -Wl,--start-group @$${RSP_ARCHIVE_FILE} -Wl,--end-group
-win32:QMAKE_LFLAGS += @$${RSP_OBJECT_FILE} @$${RSP_ARCHIVE_FILE}
-
-LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS
-# GN's LFLAGS doesn't always work across all the Linux configurations we support.
-# The Windows and macOS ones from GN does provide a few useful flags however
-
-unix:qtConfig(webengine-noexecstack): \
- QMAKE_LFLAGS += -Wl,-z,noexecstack
-linux {
- # add chromium flags
- for(flag, NINJA_LFLAGS) {
- # filter out some flags
- !contains(flag, .*noexecstack$): \
- !contains(flag, .*as-needed$): \
- !contains(flag, ^-B.*): \
- !contains(flag, ^-fuse-ld.*): \
- QMAKE_LFLAGS += $$flag
- }
-} else {
- QMAKE_LFLAGS += $$NINJA_LFLAGS
-}
-
-POST_TARGETDEPS += $$NINJA_TARGETDEPS
-
-
LIBS_PRIVATE += -L$$api_library_path
CONFIG *= no_smart_library_merge
osx {
@@ -86,6 +34,9 @@ win32 {
POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a
}
+# Needed to set a CFBundleIdentifier
+QMAKE_INFO_PLIST = Info_mac.plist
+
# Using -Wl,-Bsymbolic-functions seems to confuse the dynamic linker
# and doesn't let Chromium get access to libc symbols through dlsym.
CONFIG -= bsymbolic_functions
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index 52d7dc669..8070d1c98 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -339,7 +339,8 @@ void DevToolsFrontendQt::RemovePreference(const std::string &name)
void DevToolsFrontendQt::ClearPreferences()
{
- if (web_contents()->GetBrowserContext()->IsOffTheRecord())
+ ProfileQt *profile = static_cast<ProfileQt *>(web_contents()->GetBrowserContext());
+ if (profile->IsOffTheRecord() || profile->profileAdapter()->storageName().isEmpty())
m_prefStore = scoped_refptr<PersistentPrefStore>(new InMemoryPrefStore());
else
CreateJsonPreferences(true);
diff --git a/src/core/devtools_manager_delegate_qt.cpp b/src/core/devtools_manager_delegate_qt.cpp
index ecd2a7d40..8c4037879 100644
--- a/src/core/devtools_manager_delegate_qt.cpp
+++ b/src/core/devtools_manager_delegate_qt.cpp
@@ -114,7 +114,7 @@ DevToolsServerQt::~DevToolsServerQt()
void DevToolsServerQt::parseAddressAndPort()
{
- const QString inspectorEnv = QString::fromUtf8(qgetenv("QTWEBENGINE_REMOTE_DEBUGGING"));
+ const QString inspectorEnv = qEnvironmentVariable("QTWEBENGINE_REMOTE_DEBUGGING");
const base::CommandLine &commandLine = *base::CommandLine::ForCurrentProcess();
QString portStr;
diff --git a/src/core/macos_context_type_helper.h b/src/core/macos_context_type_helper.h
new file mode 100644
index 000000000..d234a2bff
--- /dev/null
+++ b/src/core/macos_context_type_helper.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 MACOS_CONTEXT_TYPE_HELPER_H_
+#define MACOS_CONTEXT_TYPE_HELPER_H_
+bool isCurrentContextSoftware();
+#endif // MACOS_CONTEXT_TYPE_HELPER_H_
diff --git a/src/core/macos_context_type_helper.mm b/src/core/macos_context_type_helper.mm
new file mode 100644
index 000000000..c814d2849
--- /dev/null
+++ b/src/core/macos_context_type_helper.mm
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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$
+**
+****************************************************************************/
+#import <Foundation/Foundation.h>
+#import <AppKit/AppKit.h>
+
+#include "macos_context_type_helper.h"
+
+bool isCurrentContextSoftware()
+{
+ int rendererID = 0;
+ [NSOpenGLContext.currentContext getValues:&rendererID forParameter:NSOpenGLContextParameterCurrentRendererID];
+ return (rendererID & kCGLRendererIDMatchingMask) == kCGLRendererGenericFloatID;
+}
diff --git a/src/core/net/cookie_monster_delegate_qt.cpp b/src/core/net/cookie_monster_delegate_qt.cpp
index d3157f760..263973684 100644
--- a/src/core/net/cookie_monster_delegate_qt.cpp
+++ b/src/core/net/cookie_monster_delegate_qt.cpp
@@ -72,6 +72,25 @@ private:
DISALLOW_COPY_AND_ASSIGN(CookieChangeListener);
};
+class CookieAccessFilter : public network::mojom::CookieRemoteAccessFilter
+{
+public:
+ CookieAccessFilter(CookieMonsterDelegateQt *delegate) : m_delegate(delegate) { }
+ ~CookieAccessFilter() override = default;
+
+ void AllowedAccess(const GURL& url, const GURL& site_for_cookies, AllowedAccessCallback callback) override
+ {
+ bool allow = m_delegate->canGetCookies(toQt(site_for_cookies), toQt(url));
+ std::move(callback).Run(allow);
+ }
+
+private:
+ CookieMonsterDelegateQt *m_delegate;
+
+ DISALLOW_COPY_AND_ASSIGN(CookieAccessFilter);
+};
+
+
static GURL sourceUrlForCookie(const QNetworkCookie &cookie)
{
QString urlFragment = QStringLiteral("%1%2").arg(cookie.domain()).arg(cookie.path());
@@ -81,7 +100,10 @@ static GURL sourceUrlForCookie(const QNetworkCookie &cookie)
CookieMonsterDelegateQt::CookieMonsterDelegateQt()
: m_client(nullptr)
, m_listener(new CookieChangeListener(this))
+ , m_filter(new CookieAccessFilter(this))
, m_receiver(m_listener.get())
+ , m_filterReceiver(m_filter.get())
+ , m_hasFilter(false)
{
}
@@ -123,9 +145,12 @@ void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie
callback = base::BindOnce(&CookieMonsterDelegateQt::SetCookieCallbackOnUIThread, this, callbackId);
net::CanonicalCookie::CookieInclusionStatus inclusion;
auto canonCookie = net::CanonicalCookie::Create(gurl, cookie_line, base::Time::Now(), base::nullopt, &inclusion);
+ if (!inclusion.IsInclude()) {
+ LOG(WARNING) << "QWebEngineCookieStore::setCookie() - Tried to set invalid cookie";
+ return;
+ }
net::CookieOptions options;
- if (!inclusion.HasExclusionReason(net::CanonicalCookie::CookieInclusionStatus::EXCLUDE_HTTP_ONLY))
- options.set_include_httponly();
+ options.set_include_httponly();
m_mojoCookieManager->SetCanonicalCookie(*canonCookie.get(), gurl.scheme(), options, std::move(callback));
}
@@ -176,14 +201,31 @@ void CookieMonsterDelegateQt::setMojoCookieManager(network::mojom::CookieManager
m_mojoCookieManager.Bind(std::move(cookie_manager_info));
m_mojoCookieManager->AddGlobalChangeListener(m_receiver.BindNewPipeAndPassRemote());
+ if (m_hasFilter)
+ m_mojoCookieManager->SetRemoteFilter(m_filterReceiver.BindNewPipeAndPassRemote());
if (m_client)
m_client->d_func()->processPendingUserCookies();
}
+void CookieMonsterDelegateQt::setHasFilter(bool hasFilter)
+{
+ m_hasFilter = hasFilter;
+ if (!m_mojoCookieManager.is_bound())
+ return;
+ if (m_hasFilter) {
+ if (!m_filterReceiver.is_bound())
+ m_mojoCookieManager->SetRemoteFilter(m_filterReceiver.BindNewPipeAndPassRemote());
+ } else {
+ if (m_filterReceiver.is_bound())
+ m_filterReceiver.reset();
+ }
+}
+
void CookieMonsterDelegateQt::unsetMojoCookieManager()
{
m_receiver.reset();
+ m_filterReceiver.reset();
m_mojoCookieManager.reset();
}
diff --git a/src/core/net/cookie_monster_delegate_qt.h b/src/core/net/cookie_monster_delegate_qt.h
index c55bcff94..a8432e125 100644
--- a/src/core/net/cookie_monster_delegate_qt.h
+++ b/src/core/net/cookie_monster_delegate_qt.h
@@ -85,7 +85,10 @@ class Q_WEBENGINECORE_PRIVATE_EXPORT CookieMonsterDelegateQt : public base::RefC
network::mojom::CookieManagerPtr m_mojoCookieManager;
std::unique_ptr<network::mojom::CookieChangeListener> m_listener;
+ std::unique_ptr<network::mojom::CookieRemoteAccessFilter> m_filter;
mojo::Receiver<network::mojom::CookieChangeListener> m_receiver;
+ mojo::Receiver<network::mojom::CookieRemoteAccessFilter> m_filterReceiver;
+ bool m_hasFilter;
public:
CookieMonsterDelegateQt();
~CookieMonsterDelegateQt();
@@ -101,6 +104,7 @@ public:
void setClient(QWebEngineCookieStore *client);
void setMojoCookieManager(network::mojom::CookieManagerPtrInfo cookie_manager_info);
void unsetMojoCookieManager();
+ void setHasFilter(bool b);
bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url) const;
bool canGetCookies(const QUrl &firstPartyUrl, const QUrl &url) const;
diff --git a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
index d854a556c..4fdb8c3d0 100644
--- a/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
+++ b/src/core/net/plugin_response_interceptor_url_loader_throttle.cpp
@@ -125,6 +125,8 @@ void PluginResponseInterceptorURLLoaderThrottle::WillProcessResponse(const GURL
if (extension_id.empty())
return;
+ *defer = true;
+
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
base::BindOnce(&onPdfStreamIntercepted,
response_url,
diff --git a/src/core/net/proxying_restricted_cookie_manager_qt.cpp b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
index 7ee6c2a15..331b55e62 100644
--- a/src/core/net/proxying_restricted_cookie_manager_qt.cpp
+++ b/src/core/net/proxying_restricted_cookie_manager_qt.cpp
@@ -58,34 +58,6 @@
namespace QtWebEngineCore {
-class ProxyingRestrictedCookieManagerListenerQt : public network::mojom::CookieChangeListener {
-public:
- ProxyingRestrictedCookieManagerListenerQt(const GURL &url,
- const GURL &site_for_cookies,
- const url::Origin &top_frame_origin,
- base::WeakPtr<ProxyingRestrictedCookieManagerQt> restricted_cookie_manager,
- mojo::PendingRemote<network::mojom::CookieChangeListener> client_listener)
- : url_(url)
- , site_for_cookies_(site_for_cookies)
- , top_frame_origin_(top_frame_origin)
- , restricted_cookie_manager_(restricted_cookie_manager)
- , client_listener_(std::move(client_listener))
- {}
-
- void OnCookieChange(const net::CookieChangeInfo &change) override
- {
- if (restricted_cookie_manager_ && restricted_cookie_manager_->allowCookies(url_, site_for_cookies_))
- client_listener_->OnCookieChange(change);
- }
-
-private:
- const GURL url_;
- const GURL site_for_cookies_;
- const url::Origin top_frame_origin_;
- base::WeakPtr<ProxyingRestrictedCookieManagerQt> restricted_cookie_manager_;
- mojo::Remote<network::mojom::CookieChangeListener> client_listener_;
-};
-
// static
void ProxyingRestrictedCookieManagerQt::CreateAndBind(ProfileIODataQt *profileIoData,
mojo::PendingRemote<network::mojom::RestrictedCookieManager> underlying_rcm,
@@ -179,18 +151,7 @@ void ProxyingRestrictedCookieManagerQt::AddChangeListener(const GURL &url,
AddChangeListenerCallback callback)
{
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- mojo::PendingRemote<network::mojom::CookieChangeListener> proxy_listener_remote;
- auto proxy_listener =
- std::make_unique<ProxyingRestrictedCookieManagerListenerQt>(
- url, site_for_cookies, top_frame_origin,
- weak_factory_.GetWeakPtr(),
- std::move(listener));
-
- mojo::MakeSelfOwnedReceiver(std::move(proxy_listener),
- proxy_listener_remote.InitWithNewPipeAndPassReceiver());
-
- underlying_restricted_cookie_manager_->AddChangeListener(url, site_for_cookies, top_frame_origin, std::move(proxy_listener_remote), std::move(callback));
+ underlying_restricted_cookie_manager_->AddChangeListener(url, site_for_cookies, top_frame_origin, std::move(listener), std::move(callback));
}
void ProxyingRestrictedCookieManagerQt::SetCookieFromString(const GURL &url,
diff --git a/src/core/net/system_network_context_manager.cpp b/src/core/net/system_network_context_manager.cpp
index 29cc82abf..611b5eafa 100644
--- a/src/core/net/system_network_context_manager.cpp
+++ b/src/core/net/system_network_context_manager.cpp
@@ -61,6 +61,7 @@
#include "chrome/common/chrome_switches.h"
#include "components/certificate_transparency/ct_known_logs.h"
#include "components/network_session_configurator/common/network_features.h"
+#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/cors_exempt_headers.h"
@@ -199,19 +200,6 @@ scoped_refptr<network::SharedURLLoaderFactory> SystemNetworkContextManager::GetS
return shared_url_loader_factory_;
}
-void SystemNetworkContextManager::SetUp(
- network::mojom::NetworkContextRequest *network_context_request,
- network::mojom::NetworkContextParamsPtr *network_context_params, bool *stub_resolver_enabled,
- base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> *dns_over_https_servers,
- network::mojom::HttpAuthStaticParamsPtr *http_auth_static_params,
- network::mojom::HttpAuthDynamicParamsPtr *http_auth_dynamic_params, bool *is_quic_allowed)
-{
- *is_quic_allowed = false;
- *http_auth_static_params = CreateHttpAuthStaticParams();
- *http_auth_dynamic_params = CreateHttpAuthDynamicParams();
- // GetStubResolverConfig(local_state_, stub_resolver_enabled, dns_over_https_servers);
-}
-
// static
SystemNetworkContextManager *SystemNetworkContextManager::CreateInstance()
{
@@ -245,8 +233,10 @@ SystemNetworkContextManager::~SystemNetworkContextManager()
void SystemNetworkContextManager::OnNetworkServiceCreated(network::mojom::NetworkService *network_service)
{
+ bool is_quic_force_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableQuic);
// Disable QUIC globally
- network_service->DisableQuic();
+ if (!is_quic_force_enabled)
+ network_service->DisableQuic();
network_service->SetUpHttpAuth(CreateHttpAuthStaticParams());
network_service->ConfigureHttpAuthPrefs(CreateHttpAuthDynamicParams());
diff --git a/src/core/net/system_network_context_manager.h b/src/core/net/system_network_context_manager.h
index 5094008f2..0dd503ce1 100644
--- a/src/core/net/system_network_context_manager.h
+++ b/src/core/net/system_network_context_manager.h
@@ -105,27 +105,6 @@ public:
// Destroys the global SystemNetworkContextManager instance.
static void DeleteInstance();
- // If the network service is disabled, |network_context_request| will be for
- // the NetworkContext used by the SystemNetworkContextManager and
- // |network_context_params| as needed to set up a system NetworkContext.
- // Otherwise, this method can still be used to help set up the IOThread's
- // in-process URLRequestContext.
- //
- // Must be called before the system NetworkContext is first used.
- //
- // |stub_resolver_enabled|, |dns_over_https_servers|,
- // |http_auth_static_params|, |http_auth_dynamic_params|, and
- // |is_quic_allowed| are used to pass initial NetworkService state to the
- // caller, so the NetworkService can be configured appropriately. Using
- // NetworkService's Mojo interface to set those options would lead to races
- // with other UI->IO thread network-related tasks, since Mojo doesn't preserve
- // execution order relative to PostTasks.
- void SetUp(network::mojom::NetworkContextRequest *network_context_request,
- network::mojom::NetworkContextParamsPtr *network_context_params, bool *stub_resolver_enabled,
- base::Optional<std::vector<network::mojom::DnsOverHttpsServerPtr>> *dns_over_https_servers,
- network::mojom::HttpAuthStaticParamsPtr *http_auth_static_params,
- network::mojom::HttpAuthDynamicParamsPtr *http_auth_dynamic_params, bool *is_quic_allowed);
-
// Returns the System NetworkContext. May only be called after SetUp(). Does
// any initialization of the NetworkService that may be needed when first
// called.
diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp
index 862a1c262..ece74b123 100644
--- a/src/core/permission_manager_qt.cpp
+++ b/src/core/permission_manager_qt.cpp
@@ -200,6 +200,11 @@ int PermissionManagerQt::RequestPermission(content::PermissionType permission,
bool /*user_gesture*/,
base::OnceCallback<void(blink::mojom::PermissionStatus)> callback)
{
+ if (requesting_origin.is_empty()) {
+ std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
+ return content::PermissionController::kNoPendingOperation;
+ }
+
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
content::WebContents::FromRenderFrameHost(frameHost)->GetDelegate());
Q_ASSERT(contentsDelegate);
@@ -231,6 +236,11 @@ int PermissionManagerQt::RequestPermissions(const std::vector<content::Permissio
bool /*user_gesture*/,
base::OnceCallback<void(const std::vector<blink::mojom::PermissionStatus>&)> callback)
{
+ if (requesting_origin.is_empty()) {
+ std::move(callback).Run(std::vector<blink::mojom::PermissionStatus>(permissions.size(), blink::mojom::PermissionStatus::DENIED));
+ return content::PermissionController::kNoPendingOperation;
+ }
+
WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(
content::WebContents::FromRenderFrameHost(frameHost)->GetDelegate());
Q_ASSERT(contentsDelegate);
diff --git a/src/core/pref_service_adapter.cpp b/src/core/pref_service_adapter.cpp
index 4ded70d07..65dfb73ee 100644
--- a/src/core/pref_service_adapter.cpp
+++ b/src/core/pref_service_adapter.cpp
@@ -85,7 +85,7 @@ void PrefServiceAdapter::setup(const ProfileAdapter &profileAdapter)
WebEngineContext::commandLine()));
QString userPrefStorePath = profileAdapter.dataPath();
- if (userPrefStorePath.isEmpty() || profileAdapter.isOffTheRecord()) {
+ if (profileAdapter.isOffTheRecord() || profileAdapter.storageName().isEmpty()) {
factory.set_user_prefs(new InMemoryPrefStore);
} else {
userPrefStorePath += QDir::separator();
diff --git a/src/core/profile_adapter.cpp b/src/core/profile_adapter.cpp
index 4557ad7a4..c436c8277 100644
--- a/src/core/profile_adapter.cpp
+++ b/src/core/profile_adapter.cpp
@@ -245,13 +245,17 @@ QObject* ProfileAdapter::globalQObjectRoot()
QString ProfileAdapter::dataPath() const
{
- if (m_offTheRecord)
- return QString();
if (!m_dataPath.isEmpty())
return m_dataPath;
- if (!m_name.isNull())
- return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation), m_name);
- return QString();
+ // And off-the-record or memory-only profile should not write to disk
+ // but Chromium often creates temporary directories anyway, so given them
+ // a location to do so.
+ QString name = m_name;
+ if (m_offTheRecord)
+ name = QStringLiteral("OffTheRecord");
+ else if (m_name.isEmpty())
+ name = QStringLiteral("UnknownProfile");
+ return buildLocationFromStandardPath(QStandardPaths::writableLocation(QStandardPaths::DataLocation), name);
}
void ProfileAdapter::setDataPath(const QString &path)
@@ -259,13 +263,11 @@ void ProfileAdapter::setDataPath(const QString &path)
if (m_dataPath == path)
return;
m_dataPath = path;
- if (!m_offTheRecord) {
- m_profile->setupPrefService();
- if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
- m_profile->m_profileIOData->resetNetworkContext();
- if (m_visitedLinksManager)
- resetVisitedLinksManager();
- }
+ m_profile->setupPrefService();
+ if (!m_profile->m_profileIOData->isClearHttpCacheInProgress())
+ m_profile->m_profileIOData->resetNetworkContext();
+ if (!m_offTheRecord && m_visitedLinksManager)
+ resetVisitedLinksManager();
}
void ProfileAdapter::setDownloadPath(const QString &path)
@@ -353,7 +355,7 @@ void ProfileAdapter::setHttpCacheType(ProfileAdapter::HttpCacheType newhttpCache
ProfileAdapter::PersistentCookiesPolicy ProfileAdapter::persistentCookiesPolicy() const
{
- if (isOffTheRecord() || dataPath().isEmpty())
+ if (isOffTheRecord() || m_name.isEmpty())
return NoPersistentCookies;
return m_persistentCookiesPolicy;
}
@@ -372,7 +374,7 @@ ProfileAdapter::VisitedLinksPolicy ProfileAdapter::visitedLinksPolicy() const
{
if (isOffTheRecord() || m_visitedLinksPolicy == DoNotTrackVisitedLinks)
return DoNotTrackVisitedLinks;
- if (dataPath().isEmpty())
+ if (m_name.isEmpty())
return TrackVisitedLinksInMemory;
return m_visitedLinksPolicy;
}
diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp
index ecebbdaa7..02912e35e 100644
--- a/src/core/profile_io_data_qt.cpp
+++ b/src/core/profile_io_data_qt.cpp
@@ -179,6 +179,8 @@ void ProfileIODataQt::setFullConfiguration()
m_httpCacheMaxSize = m_profileAdapter->httpCacheMaxSize();
m_useForGlobalCertificateVerification = m_profileAdapter->isUsedForGlobalCertificateVerification();
m_dataPath = m_profileAdapter->dataPath();
+ m_storageName = m_profileAdapter->storageName();
+ m_inMemoryOnly = m_profileAdapter->isOffTheRecord() || m_storageName.isEmpty();
}
void ProfileIODataQt::resetNetworkContext()
@@ -221,7 +223,7 @@ network::mojom::NetworkContextParamsPtr ProfileIODataQt::CreateNetworkContextPar
network::mojom::NetworkContextParamsPtr network_context_params =
SystemNetworkContextManager::GetInstance()->CreateDefaultNetworkContextParams();
- network_context_params->context_name = m_profile->profileAdapter()->storageName().toStdString();
+ network_context_params->context_name = m_storageName.toStdString();
network_context_params->user_agent = m_httpUserAgent.toStdString();
network_context_params->accept_language = m_httpAcceptLanguage.toStdString();
@@ -234,7 +236,7 @@ network::mojom::NetworkContextParamsPtr ProfileIODataQt::CreateNetworkContextPar
if (m_httpCacheType == ProfileAdapter::DiskHttpCache && !m_httpCachePath.isEmpty())
network_context_params->http_cache_path = toFilePath(m_httpCachePath);
- if (m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies && !m_dataPath.isEmpty()) {
+ if (m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies && !m_inMemoryOnly) {
base::FilePath cookie_path = toFilePath(m_dataPath);
cookie_path = cookie_path.AppendASCII("Cookies");
network_context_params->cookie_path = cookie_path;
@@ -242,7 +244,7 @@ network::mojom::NetworkContextParamsPtr ProfileIODataQt::CreateNetworkContextPar
network_context_params->restore_old_session_cookies = m_persistentCookiesPolicy == ProfileAdapter::ForcePersistentCookies;
network_context_params->persist_session_cookies = m_persistentCookiesPolicy != ProfileAdapter::NoPersistentCookies;
}
- if (!m_dataPath.isEmpty()) {
+ if (!m_inMemoryOnly) {
network_context_params->http_server_properties_path = toFilePath(m_dataPath).AppendASCII("Network Persistent State");
network_context_params->transport_security_persister_path = toFilePath(m_dataPath);
}
diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h
index b0567dead..00d2c392c 100644
--- a/src/core/profile_io_data_qt.h
+++ b/src/core/profile_io_data_qt.h
@@ -133,6 +133,8 @@ private:
QString m_httpUserAgent;
ProfileAdapter::HttpCacheType m_httpCacheType;
QString m_httpCachePath;
+ QString m_storageName;
+ bool m_inMemoryOnly;
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QMutex m_mutex{QMutex::Recursive};
using QRecursiveMutex = QMutex;
diff --git a/src/core/render_view_context_menu_qt.cpp b/src/core/render_view_context_menu_qt.cpp
index 4e182973c..8fdae498c 100644
--- a/src/core/render_view_context_menu_qt.cpp
+++ b/src/core/render_view_context_menu_qt.cpp
@@ -98,6 +98,8 @@ namespace QtWebEngineCore {
appendCopyItem();
else
appendPageItems();
+ } else {
+ appendPageItems();
}
if (m_contextData.linkUrl().isValid() || !m_contextData.unfilteredLinkUrl().isEmpty() || !m_contextData.linkUrl().isEmpty())
diff --git a/src/core/render_widget_host_view_qt_delegate_client.cpp b/src/core/render_widget_host_view_qt_delegate_client.cpp
index bee4bc4c2..25344a1c4 100644
--- a/src/core/render_widget_host_view_qt_delegate_client.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_client.cpp
@@ -427,7 +427,7 @@ void RenderWidgetHostViewQtDelegateClient::handlePointerEvent(T *event)
if ((webEvent.GetType() == blink::WebInputEvent::kMouseDown
|| webEvent.GetType() == blink::WebInputEvent::kMouseUp)
&& webEvent.button == blink::WebMouseEvent::Button::kNoButton) {
- // Blink can only handle the 3 main mouse-buttons and may assert when processing mouse-down
+ // Blink can only handle the 5 main mouse-buttons and may assert when processing mouse-down
// for no button.
LOG(INFO) << "Unhandled mouse button";
return;
@@ -448,6 +448,9 @@ void RenderWidgetHostViewQtDelegateClient::handlePointerEvent(T *event)
m_clickHelper.lastPressPosition = QPointF(event->pos()).toPoint();
}
+ if (webEvent.GetType() == blink::WebInputEvent::kMouseUp)
+ webEvent.click_count = m_clickHelper.clickCounter;
+
webEvent.movement_x = event->globalX() - m_previousMousePosition.x();
webEvent.movement_y = event->globalY() - m_previousMousePosition.y();
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 77dd4593f..03916baa0 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -807,6 +807,15 @@ void WebContentsDelegateQt::ContentsZoomChange(bool zoom_in)
adapter->setZoomFactor(adapter->currentZoomFactor() - 0.1f);
}
+bool WebContentsDelegateQt::ShouldNavigateOnBackForwardMouseButtons()
+{
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ return false;
+#else
+ return true;
+#endif
+}
+
FaviconManager *WebContentsDelegateQt::faviconManager()
{
return m_faviconManager.data();
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 861310e9b..6d15daf47 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -168,6 +168,7 @@ public:
void OnVisibilityChanged(content::Visibility visibility) override;
void DidFirstVisuallyNonEmptyPaint() override;
void ActivateContents(content::WebContents* contents) override;
+ bool ShouldNavigateOnBackForwardMouseButtons() override;
void didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription);
void overrideWebPreferences(content::WebContents *, content::WebPreferences*);
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 5b0e9d0c1..bfb34c484 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -173,9 +173,9 @@ bool usingDefaultSGBackend()
}
if (device.isEmpty())
- device = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND"));
+ device = qEnvironmentVariable("QT_QUICK_BACKEND");
if (device.isEmpty())
- device = QString::fromLocal8Bit(qgetenv("QMLSCENE_DEVICE"));
+ device = qEnvironmentVariable("QMLSCENE_DEVICE");
return device.isEmpty();
}
@@ -326,7 +326,7 @@ void WebEngineContext::addProfileAdapter(ProfileAdapter *profileAdapter)
{
Q_ASSERT(!m_profileAdapters.contains(profileAdapter));
const QString path = profileAdapter->dataPath();
- if (!path.isEmpty()) {
+ if (!profileAdapter->isOffTheRecord() && !profileAdapter->storageName().isEmpty()) {
for (auto profileAdapter : m_profileAdapters) {
if (profileAdapter->dataPath() == path) {
// QTBUG-66068
@@ -579,6 +579,8 @@ WebEngineContext::WebEngineContext()
setupProxyPac(parsedCommandLine);
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
+ parsedCommandLine->AppendSwitchASCII(service_manager::switches::kApplicationName, QCoreApplication::applicationName().toStdString());
+
// Enable sandboxing on OS X and Linux (Desktop / Embedded) by default.
bool disable_sandbox = qEnvironmentVariableIsSet(kDisableSandboxEnv);
if (!disable_sandbox) {
@@ -854,7 +856,7 @@ base::CommandLine* WebEngineContext::commandLine() {
QStringList appArgs = QCoreApplication::arguments();
if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
- appArgs.append(parseEnvCommandLine(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv))));
+ appArgs.append(parseEnvCommandLine(qEnvironmentVariable(kChromiumFlagsEnv)));
}
#ifdef Q_OS_WIN
appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp
index 1c8316430..9c99e7e22 100644
--- a/src/core/web_engine_library_info.cpp
+++ b/src/core/web_engine_library_info.cpp
@@ -153,10 +153,10 @@ QString subProcessPath()
#endif
QStringList candidatePaths;
- const QByteArray fromEnv = qgetenv("QTWEBENGINEPROCESS_PATH");
+ const QString fromEnv = qEnvironmentVariable("QTWEBENGINEPROCESS_PATH");
if (!fromEnv.isEmpty()) {
// Only search in QTWEBENGINEPROCESS_PATH if set
- candidatePaths << QString::fromLocal8Bit(fromEnv);
+ candidatePaths << fromEnv;
} else {
#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
candidatePaths << getPath(frameworkBundle())
@@ -218,10 +218,10 @@ QString dictionariesPath()
if (!initialized) {
initialized = true;
- const QByteArray fromEnv = qgetenv("QTWEBENGINE_DICTIONARIES_PATH");
+ const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_DICTIONARIES_PATH");
if (!fromEnv.isEmpty()) {
// Only search in QTWEBENGINE_DICTIONARIES_PATH if set
- candidatePaths << QString::fromLocal8Bit(fromEnv);
+ candidatePaths << fromEnv;
} else {
// First try to find dictionaries near the application.
#ifdef OS_MACOSX
diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp
index 5d5086d34..1f005233d 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -205,7 +205,14 @@ static quint32 nativeKeyCodeForKeyEvent(const QKeyEvent *ev)
// Cygwin/X, etc). Also evdev key codes are *not* supported for the same
// reason.
#if defined(Q_OS_WINDOWS)
- return keyboardDriver() == KeyboardDriver::Windows ? ev->nativeScanCode() : 0;
+ if (keyboardDriver() == KeyboardDriver::Windows) {
+ // see GetScanCodeFromLParam in events_win_utils.cc:
+ quint32 scancode = ev->nativeScanCode() & 0xff;
+ if (ev->nativeScanCode() & 0x100)
+ scancode |= 0xe000;
+ return scancode;
+ }
+ return 0;
#elif defined(Q_OS_MACOS)
return keyboardDriver() == KeyboardDriver::Cocoa ? ev->nativeVirtualKey() : 0;
#elif defined(Q_OS_LINUX)
@@ -1229,6 +1236,10 @@ static WebMouseEvent::Button mouseButtonForEvent(T *event)
return WebMouseEvent::Button::kRight;
else if (event->button() == Qt::MiddleButton)
return WebMouseEvent::Button::kMiddle;
+ else if (event->button() == Qt::BackButton)
+ return WebMouseEvent::Button::kBack;
+ else if (event->button() == Qt::ForwardButton)
+ return WebMouseEvent::Button::kForward;
if (event->type() != QEvent::MouseMove && event->type() != QEvent::TabletMove)
return WebMouseEvent::Button::kNoButton;
@@ -1241,6 +1252,10 @@ static WebMouseEvent::Button mouseButtonForEvent(T *event)
return WebMouseEvent::Button::kRight;
else if (event->buttons() & Qt::MiddleButton)
return WebMouseEvent::Button::kMiddle;
+ else if (event->buttons() & Qt::BackButton)
+ return WebMouseEvent::Button::kBack;
+ else if (event->buttons() & Qt::ForwardButton)
+ return WebMouseEvent::Button::kForward;
return WebMouseEvent::Button::kNoButton;
}
@@ -1255,6 +1270,10 @@ static unsigned mouseButtonsModifiersForEvent(const T* event)
ret |= WebInputEvent::kRightButtonDown;
if (event->buttons() & Qt::MiddleButton)
ret |= WebInputEvent::kMiddleButtonDown;
+ if (event->buttons() & Qt::BackButton)
+ ret |= WebInputEvent::kBackButtonDown;
+ if (event->buttons() & Qt::ForwardButton)
+ ret |= WebInputEvent::kForwardButtonDown;
return ret;
}
@@ -1348,6 +1367,10 @@ static inline Qt::MouseButtons mouseButtonsForModifier(unsigned int modifier)
buttons |= Qt::RightButton;
if (modifier & WebInputEvent::kMiddleButtonDown)
buttons |= Qt::MiddleButton;
+ if (modifier & WebInputEvent::kBackButtonDown)
+ buttons |= Qt::BackButton;
+ if (modifier & WebInputEvent::kForwardButtonDown)
+ buttons |= Qt::ForwardButton;
return buttons;
}
diff --git a/src/pdf/config/ios.pri b/src/pdf/config/ios.pri
index 5dc7faf9d..1dcbeffde 100644
--- a/src/pdf/config/ios.pri
+++ b/src/pdf/config/ios.pri
@@ -26,7 +26,6 @@ use_allocator_shim=false \
use_allocator=\"none\" \
use_custom_libcxx=false \
v8_use_external_startup_data=false \
-v8_use_snapshot=false \
toolkit_views=false \
treat_warnings_as_errors=false \
safe_browsing_mode=0 \
diff --git a/src/pdf/pdf.pro b/src/pdf/pdf.pro
index fcdfafab5..9f98c32b0 100644
--- a/src/pdf/pdf.pro
+++ b/src/pdf/pdf.pro
@@ -4,9 +4,10 @@ TEMPLATE = subdirs
pdfcore.file = pdfcore.pro
pdfcore_generator.file = pdfcore_generator.pro
gn_run.file = gn_run.pro
-
+pdfcore_prl_generator.file = pdfcore_prl_generator.pro
gn_run.depends = pdfcore_generator
-pdfcore.depends = gn_run
+pdfcore_prl_generator.depends = gn_run
+pdfcore.depends = pdfcore_prl_generator
quick.depends = pdfcore
!qtConfig(webengine-qtpdf-support):qtConfig(build-qtpdf)::!build_pass {
@@ -23,6 +24,7 @@ quick.depends = pdfcore
SUBDIRS += \
pdfcore_generator \
gn_run \
+ pdfcore_prl_generator \
pdfcore \
quick
}
diff --git a/src/pdf/pdfcore.pro b/src/pdf/pdfcore.pro
index c87722b7e..2dfe39dc0 100644
--- a/src/pdf/pdfcore.pro
+++ b/src/pdf/pdfcore.pro
@@ -17,33 +17,6 @@ INCLUDEPATH += $$QTWEBENGINE_ROOT/src/pdf \
DEFINES += QT_BUILD_PDF_LIB
win32: DEFINES += NOMINMAX
-linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
-!include($$linking_pri) {
- error("Could not find the linking information that gn should have generated.")
-}
-
-isEmpty(NINJA_OBJECTS): error("Missing object files from QtPdf linking pri.")
-isEmpty(NINJA_LFLAGS): error("Missing linker flags from QtPdf linking pri")
-isEmpty(NINJA_LIBS): error("Missing library files from QtPdf linking pri")
-
-NINJA_OBJECTS = $$eval($$list($$NINJA_OBJECTS))
-RSP_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}.rsp
-for(object, NINJA_OBJECTS): RSP_CONTENT += $$object
-write_file($$RSP_FILE, RSP_CONTENT)
-
-macos:LIBS_PRIVATE += -Wl,-filelist,$$shell_quote($$RSP_FILE)
-linux:LIBS_PRIVATE += @$$RSP_FILE
-
-# QTBUG-58710 add main rsp file on windows
-win32:QMAKE_LFLAGS += @$$RSP_FILE
-
-!isEmpty(NINJA_ARCHIVES) {
- linux: LIBS_PRIVATE += -Wl,--start-group $$NINJA_ARCHIVES -Wl,--end-group
- else: LIBS_PRIVATE += $$NINJA_ARCHIVES
-}
-
-LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS
-
QMAKE_DOCS = $$PWD/doc/qtpdf.qdocconf
gcc {
@@ -54,7 +27,21 @@ msvc {
QMAKE_CXXFLAGS_WARN_ON += -wd"4100"
}
-ios: OBJECTS += $$NINJA_OBJECTS
+include($${QTWEBENGINE_ROOT}/src/buildtools/config/linking.pri)
+
+# install static dependencies and handle prl files for static builds
+
+static:!isEmpty(NINJA_ARCHIVES) {
+ static_dep_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}_static_dep.pri
+ !include($${static_dep_pri}) {
+ error("Could not find the prl information.")
+ }
+ ninja_archives = $$eval($$list($$NINJA_ARCHIVES))
+ ninja_archs_install.files = $${ninja_archives}
+ ninja_archs_install.path = $$[QT_INSTALL_LIBS]/static_chrome
+ ninja_archs_install.CONFIG = no_check_exist
+ INSTALLS += ninja_archs_install
+}
SOURCES += \
qpdfbookmarkmodel.cpp \
diff --git a/src/pdf/pdfcore_prl_generator.pro b/src/pdf/pdfcore_prl_generator.pro
new file mode 100644
index 000000000..39fdaed40
--- /dev/null
+++ b/src/pdf/pdfcore_prl_generator.pro
@@ -0,0 +1,27 @@
+
+qtConfig(debug_and_release): CONFIG += debug_and_release
+
+TARGET = QtPdf
+TEMPLATE = aux
+
+build_pass|!debug_and_relase {
+ linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
+ !include($$linking_pri) {
+ error("Could not find the linking information that gn should have generated.")
+ }
+
+ !isEmpty(NINJA_ARCHIVES) {
+ prl_file = $$OUT_PWD/$$getConfigDir()/$${TARGET}_static_dep.pri
+ ninja_archives = $$eval($$list($$NINJA_ARCHIVES))
+ qqt_libdir = \$\$\$\$[QT_INSTALL_LIBS]
+ for(ninja_arch, ninja_archives) {
+ ninja_arch_name = $$basename(ninja_arch)
+ ninja_arch_dirname = $$dirname(ninja_arch)
+ prl_content += "ninja_arch_prl_replace_$${ninja_arch_name}.match = $${ninja_arch_dirname}"
+ prl_content += "ninja_arch_prl_replace_$${ninja_arch_name}.replace = $${qqt_libdir}/static_chrome"
+ prl_content += "ninja_arch_prl_replace_$${ninja_arch_name}.CONFIG = path"
+ prl_content += "QMAKE_PRL_INSTALL_REPLACE += ninja_arch_prl_replace_$${ninja_arch_name}"
+ }
+ write_file($${prl_file}, prl_content)
+ }
+}
diff --git a/src/pdf/quick/quick.pro b/src/pdf/quick/quick.pro
index bd6bc8827..47c559091 100644
--- a/src/pdf/quick/quick.pro
+++ b/src/pdf/quick/quick.pro
@@ -36,5 +36,5 @@ HEADERS += \
qquicktableviewextra_p.h \
QT += pdf pdf-private gui core qml quick quick-private
-
+include($${OUT_PWD}/../$$getConfigDir()/QtPdf_static_dep.pri)
load(qml_plugin)
diff --git a/src/pdfwidgets/pdfwidgets.pro b/src/pdfwidgets/pdfwidgets.pro
index cf221be03..17772b886 100644
--- a/src/pdfwidgets/pdfwidgets.pro
+++ b/src/pdfwidgets/pdfwidgets.pro
@@ -9,4 +9,5 @@ HEADERS += \
qpdfview_p.h \
qtpdfwidgetsglobal.h
+include($${OUT_PWD}/../pdf/$$getConfigDir()/QtPdf_static_dep.pri)
load(qt_module)
diff --git a/src/plugins/imageformats/pdf/pdf.pro b/src/plugins/imageformats/pdf/pdf.pro
index b820ae7d5..1a11b8ef2 100644
--- a/src/plugins/imageformats/pdf/pdf.pro
+++ b/src/plugins/imageformats/pdf/pdf.pro
@@ -1,11 +1,13 @@
TARGET = qpdf
-
PLUGIN_TYPE = imageformats
PLUGIN_EXTENDS = pdf
PLUGIN_CLASS_NAME = QPdfPlugin
-load(qt_plugin)
HEADERS += qpdfiohandler_p.h
SOURCES += main.cpp \
qpdfiohandler.cpp
QT += pdf
+
+include($${OUT_PWD}/../../../pdf/$$getConfigDir()/QtPdf_static_dep.pri)
+
+load(qt_plugin)
diff --git a/src/tools/qwebengine_convert_dict/main.cpp b/src/tools/qwebengine_convert_dict/main.cpp
index 5c95f6d69..37b6e0171 100644
--- a/src/tools/qwebengine_convert_dict/main.cpp
+++ b/src/tools/qwebengine_convert_dict/main.cpp
@@ -159,7 +159,7 @@ int main(int argc, char *argv[])
// Try to look up the path to the ICU data directory via an environment variable
// (e.g. for the case when the tool is ran during build phase, and regular installed
// ICU data file is not available).
- QString icuPossibleEnvDataDir = QString::fromLatin1(qgetenv("QT_WEBENGINE_ICU_DATA_DIR"));
+ const QString icuPossibleEnvDataDir = qEnvironmentVariable("QT_WEBENGINE_ICU_DATA_DIR");
if (!icuPossibleEnvDataDir.isEmpty() && QFileInfo::exists(icuPossibleEnvDataDir)) {
icuDataDir = icuPossibleEnvDataDir;
icuDataDirFound = true;
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 9d5c41713..789d9794e 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -376,11 +376,6 @@
to the main frame or a child frame. If the function returns \c true, the navigation request is
accepted and \c url is loaded. The default implementation accepts all navigation requests.
- This function is called for absolute URLs that are prefixed with \c {http://} or \c {https://}
- and for unrecognized schemes, such as \c {mailto:}, which will be handled by QDesktopServices
- if accepted. To have this function called also upon receiving navigation requests to local URLs,
- prefix the URLs with \c {http://}.
-
Navigation requests can be delegated to the Qt application instead of having the HTML handler
engine process them by overloading this function. This is necessary when an HTML document is
used as part of the user interface, and not to display external data, for example, when
@@ -391,6 +386,10 @@
signal that returns \c false is to be expected even after delegating the
request.
+ \note When using setHtml or setContent with relative links, make
+ sure to specify a base url, otherwise the links will be considered
+ invalid and no navigation requests will be emitted.
+
The \l{QWebEngineUrlRequestInterceptor} class offers further options for intercepting and
manipulating requests.
*/
diff --git a/tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro b/tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro
index e99c7f493..9c239f1a7 100644
--- a/tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro
+++ b/tests/auto/core/qwebenginecookiestore/qwebenginecookiestore.pro
@@ -1 +1,2 @@
include(../tests.pri)
+include(../../shared/http.pri)
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
index 2c41aa9b1..638b2e028 100644
--- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
+++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp
@@ -33,6 +33,9 @@
#include <QtWebEngineWidgets/qwebenginepage.h>
#include <QtWebEngineWidgets/qwebengineprofile.h>
+#include "httpserver.h"
+#include "httpreqrep.h"
+
class tst_QWebEngineCookieStore : public QObject
{
Q_OBJECT
@@ -56,6 +59,7 @@ private Q_SLOTS:
void cookieSignals();
void batchCookieTasks();
void basicFilter();
+ void basicFilterOverHTTP();
void html5featureFilter();
private:
@@ -239,6 +243,74 @@ void tst_QWebEngineCookieStore::basicFilter()
QCOMPARE(cookieAddedSpy.count(), 2);
}
+void tst_QWebEngineCookieStore::basicFilterOverHTTP()
+{
+ QWebEnginePage page(m_profile);
+ QWebEngineCookieStore *client = m_profile->cookieStore();
+
+ QAtomicInt accessTested = 0;
+ client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return true; });
+
+ HttpServer httpServer;
+
+ if (!httpServer.start())
+ QSKIP("Failed to start http server");
+
+ QByteArray cookieRequestHeader;
+ connect(&httpServer, &HttpServer::newRequest, [&cookieRequestHeader](HttpReqRep *rr) {
+ if (rr->requestPath().size() <= 1) {
+ cookieRequestHeader = rr->requestHeader(QByteArrayLiteral("Cookie"));
+ rr->setResponseStatus(200);
+ if (cookieRequestHeader.isEmpty())
+ rr->setResponseHeader(QByteArrayLiteral("Set-Cookie"), QByteArrayLiteral("Test=test"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy cookieAddedSpy(client, SIGNAL(cookieAdded(const QNetworkCookie &)));
+ QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &)));
+
+ page.load(httpServer.url());
+
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000);
+ QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
+ QTRY_COMPARE(cookieAddedSpy.count(), 1);
+ QTRY_COMPARE(accessTested.loadAcquire(), 3);
+ QVERIFY(cookieRequestHeader.isEmpty());
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
+ QVERIFY(!cookieRequestHeader.isEmpty());
+ QTRY_COMPARE(cookieAddedSpy.count(), 1);
+ QTRY_COMPARE(accessTested.loadAcquire(), 5);
+
+ client->deleteAllCookies();
+ QTRY_COMPARE(cookieRemovedSpy.count(), 1);
+
+ client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return false; });
+ page.triggerAction(QWebEnginePage::ReloadAndBypassCache);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
+ QVERIFY(cookieRequestHeader.isEmpty());
+ // Test cookies are NOT added:
+ QTest::qWait(100);
+ QCOMPARE(cookieAddedSpy.count(), 1);
+ QTRY_COMPARE(accessTested.loadAcquire(), 8);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QVERIFY(loadSpy.takeFirst().takeFirst().toBool());
+ QVERIFY(cookieRequestHeader.isEmpty());
+ QCOMPARE(cookieAddedSpy.count(), 1);
+
+ (void) httpServer.stop();
+}
+
void tst_QWebEngineCookieStore::html5featureFilter()
{
QWebEnginePage page(m_profile);
diff --git a/tests/auto/shared/httpreqrep.cpp b/tests/auto/shared/httpreqrep.cpp
index 15a86631c..b1b6a0a04 100644
--- a/tests/auto/shared/httpreqrep.cpp
+++ b/tests/auto/shared/httpreqrep.cpp
@@ -67,7 +67,7 @@ void HttpReqRep::close()
QByteArray HttpReqRep::requestHeader(const QByteArray &key) const
{
- auto it = m_requestHeaders.find(key);
+ auto it = m_requestHeaders.find(key.toLower());
if (it != m_requestHeaders.end())
return it->second;
return {};
diff --git a/tests/auto/widgets/proxypac/tst_proxypac.cpp b/tests/auto/widgets/proxypac/tst_proxypac.cpp
index 934e23fde..dabbfb4e5 100644
--- a/tests/auto/widgets/proxypac/tst_proxypac.cpp
+++ b/tests/auto/widgets/proxypac/tst_proxypac.cpp
@@ -46,7 +46,7 @@ private slots:
void tst_ProxyPac::proxypac()
{
- const QString fromEnv = QString::fromLocal8Bit(qgetenv("QTWEBENGINE_CHROMIUM_FLAGS"));
+ const QString fromEnv = qEnvironmentVariable("QTWEBENGINE_CHROMIUM_FLAGS");
if (!fromEnv.contains("--proxy-pac-url"))
qFatal("--proxy-pac-url argument is not passed.");
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 9768747ca..550548418 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -92,6 +92,7 @@ private Q_SLOTS:
void comboBoxPopupPositionAfterChildMove();
void acceptNavigationRequest();
void acceptNavigationRequestNavigationType();
+ void acceptNavigationRequestRelativeToNothing();
void geolocationRequestJS_data();
void geolocationRequestJS();
void loadFinished();
@@ -601,6 +602,34 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
}
}
+// Relative url without base url.
+//
+// See also: QTBUG-48435
+void tst_QWebEnginePage::acceptNavigationRequestRelativeToNothing()
+{
+ TestPage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
+ /* baseUrl: */ QUrl());
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
+ page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
+ /* baseUrl: */ QString("qrc:/"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 3, 20000);
+ page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 4, 20000);
+
+ // The two setHtml and the second click are counted, while the
+ // first click is ignored due to the empty base url.
+ QCOMPARE(page.navigations.count(), 3);
+ QCOMPARE(page.navigations[0].type, QWebEnginePage::NavigationTypeTyped);
+ QCOMPARE(page.navigations[1].type, QWebEnginePage::NavigationTypeTyped);
+ QCOMPARE(page.navigations[2].type, QWebEnginePage::NavigationTypeLinkClicked);
+ QCOMPARE(page.navigations[2].url, QUrl(QString("qrc:/S0")));
+}
+
void tst_QWebEnginePage::popupFormSubmission()
{
TestPage page;
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 908b38202..fad94259c 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -136,12 +136,13 @@ void tst_QWebEngineProfile::privateProfile()
QCOMPARE(otrProfile.httpCacheType(), QWebEngineProfile::MemoryHttpCache);
QCOMPARE(otrProfile.persistentCookiesPolicy(), QWebEngineProfile::NoPersistentCookies);
QCOMPARE(otrProfile.cachePath(), QString());
- QCOMPARE(otrProfile.persistentStoragePath(), QString());
+ QCOMPARE(otrProfile.persistentStoragePath(), QStandardPaths::writableLocation(QStandardPaths::DataLocation)
+ + QStringLiteral("/QtWebEngine/OffTheRecord"));
// TBD: setters do not really work
otrProfile.setCachePath(QStringLiteral("/home/foo/bar"));
QCOMPARE(otrProfile.cachePath(), QString());
otrProfile.setPersistentStoragePath(QStringLiteral("/home/foo/bar"));
- QCOMPARE(otrProfile.persistentStoragePath(), QString());
+ QCOMPARE(otrProfile.persistentStoragePath(), QStringLiteral("/home/foo/bar"));
otrProfile.setHttpCacheType(QWebEngineProfile::DiskHttpCache);
QCOMPARE(otrProfile.httpCacheType(), QWebEngineProfile::MemoryHttpCache);
otrProfile.setPersistentCookiesPolicy(QWebEngineProfile::ForcePersistentCookies);