diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-07-24 10:30:54 +0200 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-07-24 15:23:10 +0200 |
commit | 54b84e14589b3e51f2f2e7980e2af2559601efe2 (patch) | |
tree | eafef9f5b854cd90f6fa8e1ae5ab9e161a424aa3 /src/core | |
parent | 27332664b2745d7d322b8afbc1a41dc0fbfc763a (diff) | |
parent | a2a19a6965601ced75e3e48b2bf618ba2bdbd29e (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
Diffstat (limited to 'src/core')
32 files changed, 342 insertions, 173 deletions
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; } |