diff options
Diffstat (limited to 'src/core')
36 files changed, 607 insertions, 336 deletions
diff --git a/src/core/accessibility_tree_formatter_qt.cpp b/src/core/accessibility_tree_formatter_qt.cpp index 6d3129275..8b15c5dee 100644 --- a/src/core/accessibility_tree_formatter_qt.cpp +++ b/src/core/accessibility_tree_formatter_qt.cpp @@ -52,6 +52,7 @@ namespace content { +#ifndef QT_NO_ACCESSIBILITY class AccessibilityTreeFormatterQt : public AccessibilityTreeFormatterBrowser { public: explicit AccessibilityTreeFormatterQt(); @@ -66,12 +67,6 @@ private: base::string16 ProcessTreeForOutput(const base::DictionaryValue &node, base::DictionaryValue * = nullptr) override; }; -// static -AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create() -{ - return new AccessibilityTreeFormatterQt(); -} - AccessibilityTreeFormatterQt::AccessibilityTreeFormatterQt() { } @@ -203,4 +198,16 @@ const std::string AccessibilityTreeFormatterQt::GetDenyString() return "@QT-DENY:"; } +#endif // QT_NO_ACCESSIBILITY + +// static +AccessibilityTreeFormatter* AccessibilityTreeFormatter::Create() +{ +#ifndef QT_NO_ACCESSIBILITY + return new AccessibilityTreeFormatterQt(); +#else + return nullptr; +#endif } + +} // namespace content diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp index d3cf72477..a415ade92 100644 --- a/src/core/api/qtwebenginecoreglobal.cpp +++ b/src/core/api/qtwebenginecoreglobal.cpp @@ -42,6 +42,10 @@ #include <QGuiApplication> #ifndef QT_NO_OPENGL # include <QOpenGLContext> +#ifdef Q_OS_MACOS +#include <sys/types.h> +#include <sys/sysctl.h> +#endif #endif #include <QThread> @@ -52,6 +56,23 @@ Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); QT_END_NAMESPACE #endif +#ifndef QT_NO_OPENGL +#ifdef Q_OS_MACOS +static bool needsOfflineRendererWorkaround() { + size_t hwmodelsize = 0; + + if (sysctlbyname("hw.model", nullptr, &hwmodelsize, nullptr, 0) == -1) + return false; + + char hwmodel[hwmodelsize]; + if (sysctlbyname("hw.model", &hwmodel, &hwmodelsize, nullptr, 0) == -1) + return false; + + return QString::fromLatin1(hwmodel) == QLatin1String("MacPro6,1"); +} +#endif +#endif + namespace QtWebEngineCore { #ifndef QT_NO_OPENGL static QOpenGLContext *shareContext; @@ -74,7 +95,10 @@ QWEBENGINECORE_PRIVATE_EXPORT void initialize() #ifdef Q_OS_WIN32 qputenv("QT_D3DCREATE_MULTITHREADED", "1"); #endif - +#ifdef Q_OS_MACOS + if (needsOfflineRendererWorkaround()) + qputenv("QT_MAC_PRO_WEBENGINE_WORKAROUND", "1"); +#endif // No need to override the shared context if QApplication already set one (e.g with Qt::AA_ShareOpenGLContexts). if (qt_gl_global_share_context()) return; @@ -107,3 +131,4 @@ QWEBENGINECORE_PRIVATE_EXPORT void initialize() #endif // QT_NO_OPENGL } } // namespace QtWebEngineCore + diff --git a/src/core/api/qwebenginecookiestore.cpp b/src/core/api/qwebenginecookiestore.cpp index abb39f074..035c98342 100644 --- a/src/core/api/qwebenginecookiestore.cpp +++ b/src/core/api/qwebenginecookiestore.cpp @@ -195,7 +195,8 @@ bool QWebEngineCookieStorePrivate::canAccessCookies(const QUrl &firstPartyUrl, c if (!filterCallback) return true; - bool thirdParty = + // Empty first-party URL indicates a first-party request (see net/base/static_cookie_policy.cc) + bool thirdParty = !firstPartyUrl.isEmpty() && !net::registry_controlled_domains::SameDomainOrHost(toGurl(url), toGurl(firstPartyUrl), net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h index edb1f1ed7..345ee9862 100644 --- a/src/core/browser_accessibility_qt.h +++ b/src/core/browser_accessibility_qt.h @@ -41,9 +41,10 @@ #define BROWSER_ACCESSIBILITY_QT_H #include <QtGui/qaccessible.h> -#ifndef QT_NO_ACCESSIBILITY #include "content/browser/accessibility/browser_accessibility.h" +#ifndef QT_NO_ACCESSIBILITY + namespace content { class BrowserAccessibilityQt diff --git a/src/core/browser_main_parts_qt.cpp b/src/core/browser_main_parts_qt.cpp new file mode 100644 index 000000000..38e048470 --- /dev/null +++ b/src/core/browser_main_parts_qt.cpp @@ -0,0 +1,231 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "browser_main_parts_qt.h" + +#include "base/message_loop/message_loop.h" +#include "base/process/process.h" +#include "base/threading/thread_restrictions.h" +#include "content/public/browser/browser_main_parts.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/service_manager_connection.h" +#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h" +#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" +#include "services/service_manager/public/cpp/connector.h" +#include "services/service_manager/public/cpp/service.h" +#include "ui/display/screen.h" + +#include "service/service_qt.h" +#include "web_engine_context.h" + +#include <QCoreApplication> +#include <QEvent> +#include <QEventLoop> +#include <QObject> +#include <QTimerEvent> + +#if defined(Q_OS_WIN) +#include "ui/display/win/screen_win.h" +#else +#include "desktop_screen_qt.h" +#endif + + +namespace QtWebEngineCore { + +namespace { + +// Return a timeout suitable for the glib loop, -1 to block forever, +// 0 to return right away, or a timeout in milliseconds from now. +int GetTimeIntervalMilliseconds(const base::TimeTicks &from) +{ + if (from.is_null()) + return -1; + + // Be careful here. TimeDelta has a precision of microseconds, but we want a + // value in milliseconds. If there are 5.5ms left, should the delay be 5 or + // 6? It should be 6 to avoid executing delayed work too early. + int delay = static_cast<int>(std::ceil((from - base::TimeTicks::Now()).InMillisecondsF())); + + // If this value is negative, then we need to run delayed work soon. + return delay < 0 ? 0 : delay; +} + +class MessagePumpForUIQt : public QObject, + public base::MessagePump +{ +public: + MessagePumpForUIQt() + : m_delegate(nullptr) + , m_explicitLoop(nullptr) + , m_timerId(0) + { + } + + void Run(Delegate *delegate) override + { + if (!m_delegate) + m_delegate = delegate; + else + Q_ASSERT(delegate == m_delegate); + // This is used only when MessagePumpForUIQt is used outside of the GUI thread. + QEventLoop loop; + m_explicitLoop = &loop; + loop.exec(); + m_explicitLoop = nullptr; + } + + void Quit() override + { + Q_ASSERT(m_explicitLoop); + m_explicitLoop->quit(); + } + + void ScheduleWork() override + { + if (!m_delegate) + m_delegate = base::MessageLoopForUI::current(); + QCoreApplication::postEvent(this, new QTimerEvent(0)); + m_timerScheduledTime = base::TimeTicks::Now(); + } + + void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override + { + if (!m_delegate) + m_delegate = base::MessageLoopForUI::current(); + if (delayed_work_time.is_null()) { + killTimer(m_timerId); + m_timerId = 0; + m_timerScheduledTime = base::TimeTicks(); + } else if (!m_timerId || delayed_work_time < m_timerScheduledTime) { + killTimer(m_timerId); + m_timerId = startTimer(GetTimeIntervalMilliseconds(delayed_work_time)); + m_timerScheduledTime = delayed_work_time; + } + } + +protected: + void timerEvent(QTimerEvent *ev) override + { + Q_ASSERT(!ev->timerId() || m_timerId == ev->timerId()); + killTimer(m_timerId); + m_timerId = 0; + m_timerScheduledTime = base::TimeTicks(); + + handleScheduledWork(); + } + +private: + void handleScheduledWork() + { + bool more_work_is_plausible = m_delegate->DoWork(); + + base::TimeTicks delayed_work_time; + more_work_is_plausible |= m_delegate->DoDelayedWork(&delayed_work_time); + + if (more_work_is_plausible) + return ScheduleWork(); + + more_work_is_plausible |= m_delegate->DoIdleWork(); + if (more_work_is_plausible) + return ScheduleWork(); + + ScheduleDelayedWork(delayed_work_time); + } + + Delegate *m_delegate; + QEventLoop *m_explicitLoop; + int m_timerId; + base::TimeTicks m_timerScheduledTime; +}; + +} // anonymous namespace + +std::unique_ptr<base::MessagePump> messagePumpFactory() +{ + return base::WrapUnique(new MessagePumpForUIQt); +} + +BrowserMainPartsQt::BrowserMainPartsQt() : content::BrowserMainParts() +{ } + +BrowserMainPartsQt::~BrowserMainPartsQt() = default; + + +int BrowserMainPartsQt::PreEarlyInitialization() +{ + base::MessageLoop::InitMessagePumpForUIFactory(messagePumpFactory); + return 0; +} + +void BrowserMainPartsQt::PreMainMessageLoopStart() +{ +} + +void BrowserMainPartsQt::PostMainMessageLoopRun() +{ + // The BrowserContext's destructor uses the MessageLoop so it should be deleted + // right before the RenderProcessHostImpl's destructor destroys it. + WebEngineContext::current()->destroyBrowserContext(); +} + +int BrowserMainPartsQt::PreCreateThreads() +{ + base::ThreadRestrictions::SetIOAllowed(true); + // Like ChromeBrowserMainExtraPartsViews::PreCreateThreads does. +#if defined(Q_OS_WIN) + display::Screen::SetScreenInstance(new display::win::ScreenWin); +#else + display::Screen::SetScreenInstance(new DesktopScreenQt); +#endif + return 0; +} + +void BrowserMainPartsQt::ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection) +{ + ServiceQt::GetInstance()->InitConnector(); + connection->GetConnector()->StartService(service_manager::Identity("qtwebengine")); + if (resource_coordinator::IsResourceCoordinatorEnabled()) { + m_processResourceCoordinator = std::make_unique<resource_coordinator::ProcessResourceCoordinator>(connection->GetConnector()); + m_processResourceCoordinator->SetLaunchTime(base::Time::Now()); + m_processResourceCoordinator->SetPID(base::Process::Current().Pid()); + } +} + +} // namespace QtWebEngineCore diff --git a/src/core/browser_main_parts_qt.h b/src/core/browser_main_parts_qt.h new file mode 100644 index 000000000..04ca9483d --- /dev/null +++ b/src/core/browser_main_parts_qt.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE: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 BROWSER_MAIN_PARTS_QT_H +#define BROWSER_MAIN_PARTS_QT_H + +#include "content/public/browser/browser_main_parts.h" + +namespace base { +class MessagePump; +} + +namespace content { +class ServiceManagerConnection; +} + +namespace resource_coordinator { +class ProcessResourceCoordinator; +} + +namespace QtWebEngineCore { + +std::unique_ptr<base::MessagePump> messagePumpFactory(); + +class BrowserMainPartsQt : public content::BrowserMainParts +{ +public: + BrowserMainPartsQt(); + ~BrowserMainPartsQt(); + + int PreEarlyInitialization() override; + void PreMainMessageLoopStart() override; + void PostMainMessageLoopRun() override; + int PreCreateThreads() override; + void ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection) override; + +private: + DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt); + std::unique_ptr<resource_coordinator::ProcessResourceCoordinator> m_processResourceCoordinator; +}; + +} // namespace QtWebEngineCore + +#endif // BROWSER_MAIN_PARTS_QT_H diff --git a/src/core/client_cert_select_controller.cpp b/src/core/client_cert_select_controller.cpp index 1362322f7..7d08d57c1 100644 --- a/src/core/client_cert_select_controller.cpp +++ b/src/core/client_cert_select_controller.cpp @@ -71,7 +71,7 @@ ClientCertSelectController::~ClientCertSelectController() m_delegate->ContinueWithCertificate(nullptr, nullptr); } -#if QT_CONFIG(ssl) +#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) void ClientCertSelectController::selectNone() { @@ -118,6 +118,6 @@ QVector<QSslCertificate> ClientCertSelectController::certificates() const return out; } -#endif // QT_CONFIG(ssl) +#endif // !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) QT_END_NAMESPACE diff --git a/src/core/client_cert_select_controller.h b/src/core/client_cert_select_controller.h index 4a245c74c..46324ee90 100644 --- a/src/core/client_cert_select_controller.h +++ b/src/core/client_cert_select_controller.h @@ -55,7 +55,7 @@ #include <QtNetwork/qtnetwork-config.h> #include <QtCore/QUrl> -#if QT_CONFIG(ssl) +#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) #include <QtCore/QVector> #include <QtNetwork/QSslCertificate> #endif @@ -80,12 +80,12 @@ public: ~ClientCertSelectController(); QUrl hostAndPort() const { return m_hostAndPort; } -#if QT_CONFIG(ssl) +#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) void selectNone(); void select(const QSslCertificate &certificate); QVector<QSslCertificate> certificates() const; -#endif // QT_CONFIG(ssl) +#endif private: QUrl m_hostAndPort; diff --git a/src/core/config/common.pri b/src/core/config/common.pri index bb318f1f0..6b79a1f99 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -23,8 +23,7 @@ gn_args += \ !win32: gn_args += \ use_jumbo_build=true \ - jumbo_file_merge_limit=8 \ - jumbo_build_excluded="[\"browser\",\"renderer\"]" + jumbo_file_merge_limit=8 qtConfig(webengine-printing-and-pdf) { gn_args += enable_basic_printing=true enable_print_preview=true diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index 7f634472d..eb8bb7bb0 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -24,7 +24,7 @@ qtConfig(webengine-embedded-build) { !use_gold_linker: gn_args += use_gold=false } -qtConfig(webengine-system-x11) { +qtConfig(webengine-system-x11): hasX11Dependencies() { gn_args += ozone_platform_x11=true } diff --git a/src/core/configure.json b/src/core/configure.json index a72e6ca55..3aba2d55a 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -213,8 +213,21 @@ }, "webengine-freetype": { "label": "freetype >= 2.4.2", + "test": { + "head": [ + "#include <ft2build.h>", + "#include FT_FREETYPE_H", + "#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20402)", + "# error This version of freetype is too old.", + "#endif" + ], + "main": [ + "FT_Face ft_face = 0;", + "FT_Reference_Face(ft_face);" + ] + }, "sources": [ - { "type": "pkgConfig", "args": "freetype2 >= 2.4.2" } + { "type": "pkgConfig", "args": "freetype2" } ] }, "webengine-x11" : { diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 9f1b35ec9..beec6dd26 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -41,15 +41,13 @@ #include "base/json/json_reader.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/threading/thread_restrictions.h" +#include "base/strings/utf_string_conversions.h" #if QT_CONFIG(webengine_spellchecker) #include "chrome/browser/spellchecker/spell_check_host_chrome_impl.h" #endif #include "components/network_hints/browser/network_hints_message_filter.h" #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/common/url_schemes.h" -#include "content/public/browser/browser_main_parts.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" @@ -72,30 +70,27 @@ #include "mojo/public/cpp/bindings/binding_set.h" #include "printing/buildflags/buildflags.h" #include "net/ssl/client_cert_identity.h" -#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h" -#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" +#include "services/proxy_resolver/proxy_resolver_service.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/sandbox/switches.h" #include "third_party/blink/public/platform/modules/insecure_input/insecure_input_service.mojom.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_switches.h" -#include "ui/display/screen.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_share_group.h" #include "ui/gl/gpu_timing.h" #include "url/url_util_qt.h" -#include "service/service_qt.h" #include "qtwebengine/grit/qt_webengine_resources.h" #include "profile_adapter.h" +#include "browser_main_parts_qt.h" #include "browser_message_filter_qt.h" #include "certificate_error_controller.h" #include "certificate_error_controller_p.h" #include "client_cert_select_controller.h" -#include "desktop_screen_qt.h" #include "devtools_manager_delegate_qt.h" #include "login_delegate_qt.h" #include "media_capture_devices_dispatcher.h" @@ -107,15 +102,12 @@ #include "profile_qt.h" #include "quota_permission_context_qt.h" #include "renderer_host/user_resource_controller_host.h" +#include "service/service_qt.h" #include "type_conversion.h" #include "web_contents_delegate_qt.h" #include "web_engine_context.h" #include "web_engine_library_info.h" -#if defined(Q_OS_WIN) -#include "ui/display/win/screen_win.h" -#endif - #if defined(Q_OS_LINUX) #include "global_descriptors_qt.h" #include "ui/base/resource/resource_bundle.h" @@ -156,176 +148,6 @@ QT_END_NAMESPACE namespace QtWebEngineCore { -namespace { - -// Return a timeout suitable for the glib loop, -1 to block forever, -// 0 to return right away, or a timeout in milliseconds from now. -int GetTimeIntervalMilliseconds(const base::TimeTicks& from) { - if (from.is_null()) - return -1; - - // Be careful here. TimeDelta has a precision of microseconds, but we want a - // value in milliseconds. If there are 5.5ms left, should the delay be 5 or - // 6? It should be 6 to avoid executing delayed work too early. - int delay = static_cast<int>( - ceil((from - base::TimeTicks::Now()).InMillisecondsF())); - - // If this value is negative, then we need to run delayed work soon. - return delay < 0 ? 0 : delay; -} - -class MessagePumpForUIQt : public QObject, - public base::MessagePump -{ -public: - MessagePumpForUIQt() - : m_delegate(nullptr) - , m_explicitLoop(0) - , m_timerId(0) - { - } - - void Run(Delegate *delegate) override - { - if (!m_delegate) - m_delegate = delegate; - else - Q_ASSERT(delegate == m_delegate); - // This is used only when MessagePumpForUIQt is used outside of the GUI thread. - QEventLoop loop; - m_explicitLoop = &loop; - loop.exec(); - m_explicitLoop = 0; - } - - void Quit() override - { - Q_ASSERT(m_explicitLoop); - m_explicitLoop->quit(); - } - - void ScheduleWork() override - { - if (!m_delegate) - m_delegate = base::MessageLoopForUI::current(); - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - } - - void ScheduleDelayedWork(const base::TimeTicks &delayed_work_time) override - { - if (!m_delegate) - m_delegate = base::MessageLoopForUI::current(); - if (delayed_work_time.is_null()) { - killTimer(m_timerId); - m_timerId = 0; - m_timerScheduledTime = base::TimeTicks(); - } else if (!m_timerId || delayed_work_time < m_timerScheduledTime) { - killTimer(m_timerId); - m_timerId = startTimer(GetTimeIntervalMilliseconds(delayed_work_time)); - m_timerScheduledTime = delayed_work_time; - } - } - -protected: - void customEvent(QEvent *ev) override - { - if (handleScheduledWork()) - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - } - - void timerEvent(QTimerEvent *ev) override - { - Q_ASSERT(m_timerId == ev->timerId()); - killTimer(m_timerId); - m_timerId = 0; - m_timerScheduledTime = base::TimeTicks(); - - base::TimeTicks next_delayed_work_time; - m_delegate->DoDelayedWork(&next_delayed_work_time); - ScheduleDelayedWork(next_delayed_work_time); - } - -private: - bool handleScheduledWork() { - bool more_work_is_plausible = m_delegate->DoWork(); - - base::TimeTicks delayed_work_time; - more_work_is_plausible |= m_delegate->DoDelayedWork(&delayed_work_time); - - if (more_work_is_plausible) - return true; - - more_work_is_plausible |= m_delegate->DoIdleWork(); - if (!more_work_is_plausible) - ScheduleDelayedWork(delayed_work_time); - - return more_work_is_plausible; - } - - Delegate *m_delegate; - QEventLoop *m_explicitLoop; - int m_timerId; - base::TimeTicks m_timerScheduledTime; -}; - -std::unique_ptr<base::MessagePump> messagePumpFactory() -{ - return base::WrapUnique(new MessagePumpForUIQt); -} - -} // anonymous namespace - -class BrowserMainPartsQt : public content::BrowserMainParts -{ -public: - BrowserMainPartsQt() - : content::BrowserMainParts() - { } - - int PreEarlyInitialization() override - { - base::MessageLoop::InitMessagePumpForUIFactory(messagePumpFactory); - return 0; - } - - void PreMainMessageLoopStart() override - { - } - - void PostMainMessageLoopRun() override - { - // The BrowserContext's destructor uses the MessageLoop so it should be deleted - // right before the RenderProcessHostImpl's destructor destroys it. - WebEngineContext::current()->destroyBrowserContext(); - } - - int PreCreateThreads() override - { - base::ThreadRestrictions::SetIOAllowed(true); - // Like ChromeBrowserMainExtraPartsViews::PreCreateThreads does. -#if defined(Q_OS_WIN) - display::Screen::SetScreenInstance(new display::win::ScreenWin); -#else - display::Screen::SetScreenInstance(new DesktopScreenQt); -#endif - return 0; - } - void ServiceManagerConnectionStarted(content::ServiceManagerConnection *connection) override - { - ServiceQt::GetInstance()->InitConnector(); - connection->GetConnector()->StartService(service_manager::Identity("qtwebengine")); - if (resource_coordinator::IsResourceCoordinatorEnabled()) { - m_processResourceCoordinator = std::make_unique<resource_coordinator::ProcessResourceCoordinator>(connection->GetConnector()); - m_processResourceCoordinator->SetLaunchTime(base::Time::Now()); - m_processResourceCoordinator->SetPID(base::Process::Current().Pid()); - } - } - -private: - DISALLOW_COPY_AND_ASSIGN(BrowserMainPartsQt); - std::unique_ptr<resource_coordinator::ProcessResourceCoordinator> m_processResourceCoordinator; -}; - class QtShareGLContext : public gl::GLContext { public: QtShareGLContext(QOpenGLContext *qtContext) @@ -700,6 +522,12 @@ void ContentBrowserClientQt::RegisterInProcessServices(StaticServiceMap* service services->insert(std::make_pair("qtwebengine", info)); } +void ContentBrowserClientQt::RegisterOutOfProcessServices(content::ContentBrowserClient::OutOfProcessServiceMap *services) +{ + (*services)[proxy_resolver::mojom::kProxyResolverServiceName] = + base::BindRepeating(&base::ASCIIToUTF16, "V8 Proxy Resolver"); +} + std::unique_ptr<base::Value> ContentBrowserClientQt::GetServiceManifestOverlay(base::StringPiece name) { ui::ResourceBundle &rb = ui::ResourceBundle::GetSharedInstance(); @@ -708,6 +536,8 @@ std::unique_ptr<base::Value> ContentBrowserClientQt::GetServiceManifestOverlay(b id = IDR_QTWEBENGINE_CONTENT_PACKAGED_SERVICES_MANIFEST_OVERLAY; else if (name == content::mojom::kRendererServiceName) id = IDR_QTWEBENGINE_CONTENT_RENDERER_MANIFEST_OVERLAY; + else if (name == content::mojom::kBrowserServiceName) + id = IDR_QTWEBENGINE_CONTENT_BROWSER_MANIFEST_OVERLAY; if (id == -1) return nullptr; diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 4d25ddf6a..b2761b311 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -118,6 +118,7 @@ public: const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) override; void RegisterInProcessServices(StaticServiceMap* services, content::ServiceManagerConnection* connection) override; + void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; std::vector<ServiceManifestInfo> GetExtraServiceManifests() override; std::unique_ptr<base::Value> GetServiceManifestOverlay(base::StringPiece name) override; bool CanCreateWindow( diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index d9ddf3f49..2811d5545 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -186,6 +186,12 @@ content::ContentRendererClient *ContentMainDelegateQt::CreateContentRendererClie return new ContentRendererClientQt; } +content::ContentUtilityClient *ContentMainDelegateQt::CreateContentUtilityClient() +{ + m_utilityClient.reset(new ContentUtilityClientQt); + return m_utilityClient.get(); +} + // see icu_util.cc #define ICU_UTIL_DATA_FILE 0 #define ICU_UTIL_DATA_SHARED 1 diff --git a/src/core/content_main_delegate_qt.h b/src/core/content_main_delegate_qt.h index 407687c81..c06afb0fb 100644 --- a/src/core/content_main_delegate_qt.h +++ b/src/core/content_main_delegate_qt.h @@ -43,6 +43,7 @@ #include "content/public/app/content_main_delegate.h" #include "content_browser_client_qt.h" +#include "content_utility_client_qt.h" namespace QtWebEngineCore { @@ -56,11 +57,12 @@ public: content::ContentBrowserClient* CreateContentBrowserClient() override; content::ContentRendererClient* CreateContentRendererClient() override; - + content::ContentUtilityClient* CreateContentUtilityClient() override; bool BasicStartupComplete(int* /*exit_code*/) override; private: std::unique_ptr<ContentBrowserClientQt> m_browserClient; + std::unique_ptr<ContentUtilityClientQt> m_utilityClient; }; } // namespace QtWebEngineCore diff --git a/src/core/content_utility_client_qt.cpp b/src/core/content_utility_client_qt.cpp new file mode 100644 index 000000000..9e86826fe --- /dev/null +++ b/src/core/content_utility_client_qt.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "content_utility_client_qt.h" + +#include "content/public/utility/utility_thread.h" +#include "services/proxy_resolver/proxy_resolver_service.h" + +ContentUtilityClientQt::ContentUtilityClientQt() { +} + +ContentUtilityClientQt::~ContentUtilityClientQt() = default; + + +void ContentUtilityClientQt::RegisterServices( + ContentUtilityClient::StaticServiceMap* services) { + service_manager::EmbeddedServiceInfo proxy_resolver_info; + proxy_resolver_info.task_runner = + content::ChildThread::Get()->GetIOTaskRunner(); + proxy_resolver_info.factory = + base::Bind(&proxy_resolver::ProxyResolverService::CreateService); + services->emplace(proxy_resolver::mojom::kProxyResolverServiceName, + proxy_resolver_info); +} diff --git a/src/core/content_utility_client_qt.h b/src/core/content_utility_client_qt.h new file mode 100644 index 000000000..df1eb5557 --- /dev/null +++ b/src/core/content_utility_client_qt.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE: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 CONTENT_UTILITY_CLIENT_QT_H +#define CONTENT_UTILITY_CLIENT_QT_H +#include "content/public/utility/content_utility_client.h" + +class MashServiceFactory; +class UtilityMessageHandler; + +class ContentUtilityClientQt : public content::ContentUtilityClient { + public: + ContentUtilityClientQt(); + ~ContentUtilityClientQt() override; + + // content::ContentUtilityClient: + void RegisterServices(StaticServiceMap* services) override; +}; + +#endif diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index c060185ba..f8f99e5fc 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -43,6 +43,7 @@ SOURCES = \ browser_accessibility_manager_qt.cpp \ browser_accessibility_qt.cpp \ browsing_data_remover_delegate_qt.cpp \ + browser_main_parts_qt.cpp \ browser_message_filter_qt.cpp \ certificate_error_controller.cpp \ chromium_gpu_helper.cpp \ @@ -59,6 +60,7 @@ SOURCES = \ content_client_qt.cpp \ content_browser_client_qt.cpp \ content_main_delegate_qt.cpp \ + content_utility_client_qt.cpp \ delegated_frame_node.cpp \ desktop_screen_qt.cpp \ devtools_frontend_qt.cpp \ @@ -130,6 +132,7 @@ HEADERS = \ browser_accessibility_manager_qt.h \ browser_accessibility_qt.h \ browsing_data_remover_delegate_qt.h \ + browser_main_parts_qt.h \ browser_message_filter_qt.h \ certificate_error_controller_p.h \ certificate_error_controller.h \ @@ -147,6 +150,7 @@ HEADERS = \ content_client_qt.h \ content_browser_client_qt.h \ content_main_delegate_qt.h \ + content_utility_client_qt.h \ delegated_frame_node.h \ desktop_screen_qt.h \ devtools_frontend_qt.h \ diff --git a/src/core/login_delegate_qt.cpp b/src/core/login_delegate_qt.cpp index 2dbc27cf2..9659b354a 100644 --- a/src/core/login_delegate_qt.cpp +++ b/src/core/login_delegate_qt.cpp @@ -84,6 +84,7 @@ LoginDelegateQt::~LoginDelegateQt() void LoginDelegateQt::OnRequestCancelled() { destroy(); + // TODO: this should close native dialog, since page can be navigated somewhere else } QUrl LoginDelegateQt::url() const diff --git a/src/core/net/proxy_config_service_qt.cpp b/src/core/net/proxy_config_service_qt.cpp index c5316d54e..13b969281 100644 --- a/src/core/net/proxy_config_service_qt.cpp +++ b/src/core/net/proxy_config_service_qt.cpp @@ -93,9 +93,7 @@ void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *obs net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfigWithAnnotation *config) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) m_usesSystemConfiguration = QNetworkProxyFactory::usesSystemConfiguration(); -#endif if (m_usesSystemConfiguration) { // Use Chromium's base service to retrieve system settings net::ProxyConfigWithAnnotation systemConfig; @@ -149,7 +147,6 @@ void ProxyConfigServiceQt::OnLazyPoll() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); -#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) // We need to update if // - setUseSystemConfiguration() was called in between // - user changed application proxy @@ -160,10 +157,6 @@ void ProxyConfigServiceQt::OnLazyPoll() if (m_baseService.get()) m_baseService->OnLazyPoll(); } -#else - if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()) - Update(); -#endif } // Called when the base service changed diff --git a/src/core/ozone/gl_ozone_glx_qt.cpp b/src/core/ozone/gl_ozone_glx_qt.cpp index 9a0fea7c7..2e7a28a0e 100644 --- a/src/core/ozone/gl_ozone_glx_qt.cpp +++ b/src/core/ozone/gl_ozone_glx_qt.cpp @@ -41,7 +41,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - +#include <QGuiApplication> #include "gl_ozone_glx_qt.h" #include "gl_surface_glx_qt.h" #include "ui/gl/gl_context_glx.h" @@ -49,6 +49,13 @@ #include "ui/gl/gl_glx_api_implementation.h" #include <dlfcn.h> +#ifndef QT_NO_OPENGL +#include <QOpenGLContext> +QT_BEGIN_NAMESPACE +Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context(); +QT_END_NAMESPACE +#endif + namespace ui { bool GLOzoneGLXQt::InitializeGLOneOffPlatform() { @@ -72,6 +79,16 @@ bool GLOzoneGLXQt::InitializeStaticGLBindings( reinterpret_cast<gl::GLGetProcAddressProc>( base::GetFunctionPointerFromNativeLibrary(library, "glXGetProcAddress")); + +#ifndef QT_NO_OPENGL + if (!get_proc_address) { + // glx handle not loaded, fallback to qpa + if (QOpenGLContext *context = qt_gl_global_share_context()) { + get_proc_address = reinterpret_cast<gl::GLGetProcAddressProc>( + context->getProcAddress("glXGetProcAddress")); + } + } +#endif if (!get_proc_address) { LOG(ERROR) << "glxGetProcAddress not found."; base::UnloadNativeLibrary(library); diff --git a/src/core/profile_io_data_qt.cpp b/src/core/profile_io_data_qt.cpp index ee59f3d96..4519bd8fb 100644 --- a/src/core/profile_io_data_qt.cpp +++ b/src/core/profile_io_data_qt.cpp @@ -327,10 +327,11 @@ void ProfileIODataQt::generateStorage() if (!m_dhcpPacFileFetcherFactory) m_dhcpPacFileFetcherFactory.reset(new net::DhcpPacFileFetcherFactory); + proxy_resolver::mojom::ProxyResolverFactoryPtr proxyResolver(std::move(m_proxyResolverFactoryInterface)); m_storage->set_proxy_resolution_service(network::CreateProxyResolutionServiceUsingMojoFactory( - std::move(m_proxyResolverFactory), + std::move(proxyResolver), std::unique_ptr<net::ProxyConfigService>(proxyConfigService), - net::PacFileFetcherImpl::Create(m_urlRequestContext.get()), + net::PacFileFetcherImpl::CreateWithFileUrlSupport(m_urlRequestContext.get()), m_dhcpPacFileFetcherFactory->Create(m_urlRequestContext.get()), host_resolver.get(), nullptr /* NetLog */, @@ -642,8 +643,8 @@ void ProfileIODataQt::updateStorageSettings() new ProxyConfigServiceQt( net::ProxyResolutionService::CreateSystemProxyConfigService( content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO))); - m_proxyResolverFactory = ChromeMojoProxyResolverFactory::CreateWithStrongBinding(); - + //pass interface to io thread + m_proxyResolverFactoryInterface = ChromeMojoProxyResolverFactory::CreateWithStrongBinding().PassInterface(); if (m_initialized) content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&ProfileIODataQt::generateAllStorage, m_weakPtr)); diff --git a/src/core/profile_io_data_qt.h b/src/core/profile_io_data_qt.h index 949497c71..b7706f190 100644 --- a/src/core/profile_io_data_qt.h +++ b/src/core/profile_io_data_qt.h @@ -120,7 +120,7 @@ private: scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate; content::URLRequestInterceptorScopedVector m_requestInterceptors; content::ProtocolHandlerMap m_protocolHandlers; - proxy_resolver::mojom::ProxyResolverFactoryPtr m_proxyResolverFactory; + mojo::InterfacePtrInfo<proxy_resolver::mojom::ProxyResolverFactory> m_proxyResolverFactoryInterface; net::URLRequestJobFactoryImpl *m_baseJobFactory = nullptr; QAtomicPointer<net::ProxyConfigService> m_proxyConfigService; QPointer<ProfileAdapter> m_profileAdapter; // never dereferenced in IO thread and it is passed by qpointer diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni index ba2f6e936..14da1e6cf 100644 --- a/src/core/qtwebengine.gni +++ b/src/core/qtwebengine.gni @@ -31,6 +31,7 @@ deps = [ "//content/public/renderer", "//media:media_buildflags", "//net:net_with_v8", + "//services/proxy_resolver:lib", "//skia", "//third_party/blink/public:blink", "//third_party/mesa:mesa_headers", diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index f96bbff30..792ed1d88 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -90,9 +90,7 @@ #include <QVariant> #include <QWheelEvent> #include <QWindow> -#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) #include <QtGui/private/qinputcontrol_p.h> -#endif #include <QtGui/qaccessible.h> namespace QtWebEngineCore { @@ -178,55 +176,7 @@ static inline bool compareTouchPoints(const QTouchEvent::TouchPoint &lhs, const static inline bool isCommonTextEditShortcut(const QKeyEvent *ke) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) return QInputControl::isCommonTextEditShortcut(ke); -#else - if (ke->modifiers() == Qt::NoModifier - || ke->modifiers() == Qt::ShiftModifier - || ke->modifiers() == Qt::KeypadModifier) { - if (ke->key() < Qt::Key_Escape) { - return true; - } else { - switch (ke->key()) { - case Qt::Key_Return: - case Qt::Key_Enter: - case Qt::Key_Delete: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Backspace: - case Qt::Key_Left: - case Qt::Key_Right: - case Qt::Key_Up: - case Qt::Key_Down: - case Qt::Key_Tab: - return true; - default: - break; - } - } - } else if (ke->matches(QKeySequence::Copy) - || ke->matches(QKeySequence::Paste) - || ke->matches(QKeySequence::Cut) - || ke->matches(QKeySequence::Redo) - || ke->matches(QKeySequence::Undo) - || ke->matches(QKeySequence::MoveToNextWord) - || ke->matches(QKeySequence::MoveToPreviousWord) - || ke->matches(QKeySequence::MoveToStartOfDocument) - || ke->matches(QKeySequence::MoveToEndOfDocument) - || ke->matches(QKeySequence::SelectNextWord) - || ke->matches(QKeySequence::SelectPreviousWord) - || ke->matches(QKeySequence::SelectStartOfLine) - || ke->matches(QKeySequence::SelectEndOfLine) - || ke->matches(QKeySequence::SelectStartOfBlock) - || ke->matches(QKeySequence::SelectEndOfBlock) - || ke->matches(QKeySequence::SelectStartOfDocument) - || ke->matches(QKeySequence::SelectEndOfDocument) - || ke->matches(QKeySequence::SelectAll) - ) { - return true; - } - return false; -#endif } static uint32_t s_eventId = 0; @@ -315,7 +265,6 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget , m_adapterClient(0) , m_imeInProgress(false) , m_receivedEmptyImeEvent(false) - , m_initPending(false) , m_imState(0) , m_anchorPositionWithinSelection(-1) , m_cursorPositionWithinSelection(-1) @@ -368,18 +317,10 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC m_adapterClientDestroyedConnection = QObject::connect(adapterClient->holdingQObject(), &QObject::destroyed, [this] { m_adapterClient = nullptr; }); - if (m_initPending) - InitAsChild(0); } void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView) { - if (!m_adapterClient) { - m_initPending = true; - return; - } - m_initPending = false; - m_delegate->initAsChild(m_adapterClient); } void RenderWidgetHostViewQt::InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect& rect) @@ -750,6 +691,11 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo m_adapterClient->updateScrollPosition(toQt(m_lastScrollOffset)); if (contentsSizeChanged) m_adapterClient->updateContentsSize(toQt(m_lastContentsSize)); + + if (m_pendingResize && host()) { + if (host()->SynchronizeVisualProperties()) + m_pendingResize = false; + } } void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo *results) const @@ -950,10 +896,6 @@ void RenderWidgetHostViewQt::OnDidUpdateVisualPropertiesComplete(const cc::Rende QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode) { - if (m_pendingResize && host()) { - if (host()->SynchronizeVisualProperties()) - m_pendingResize = false; - } return m_compositor->updatePaintNode(oldNode, m_delegate.get()); } @@ -977,13 +919,13 @@ void RenderWidgetHostViewQt::notifyHidden() void RenderWidgetHostViewQt::windowBoundsChanged() { host()->SendScreenRects(); - if (m_delegate->window()) + if (m_delegate && m_delegate->window()) host()->NotifyScreenInfoChanged(); } void RenderWidgetHostViewQt::windowChanged() { - if (m_delegate->window()) + if (m_delegate && m_delegate->window()) host()->NotifyScreenInfoChanged(); } @@ -1031,7 +973,8 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) return false; } case QEvent::MouseButtonPress: - Focus(); // Fall through. + Focus(); + Q_FALLTHROUGH(); case QEvent::MouseButtonRelease: case QEvent::MouseMove: // Skip second MouseMove event when a window is being adopted, so that Chromium @@ -1052,7 +995,8 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) handleWheelEvent(static_cast<QWheelEvent*>(event)); break; case QEvent::TouchBegin: - Focus(); // Fall through. + Focus(); + Q_FALLTHROUGH(); case QEvent::TouchUpdate: case QEvent::TouchEnd: case QEvent::TouchCancel: @@ -1060,7 +1004,8 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) break; #if QT_CONFIG(tabletevent) case QEvent::TabletPress: - Focus(); // Fall through. + Focus(); + Q_FALLTHROUGH(); case QEvent::TabletRelease: case QEvent::TabletMove: handleTabletEvent(static_cast<QTabletEvent*>(event)); @@ -1292,13 +1237,12 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev) end = qMax(0, start + end); } - QTextCharFormat format = qvariant_cast<QTextFormat>(attribute.value).toCharFormat(); + underlines.push_back(ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, start, end, ui::ImeTextSpan::Thickness::kThin, SK_ColorTRANSPARENT)); - QColor underlineColor(0, 0, 0, 0); + QTextCharFormat format = qvariant_cast<QTextFormat>(attribute.value).toCharFormat(); if (format.underlineStyle() != QTextCharFormat::NoUnderline) - underlineColor = format.underlineColor(); + underlines.back().underline_color = toSk(format.underlineColor()); - underlines.push_back(ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, start, end, ui::ImeTextSpan::Thickness::kThin, toSk(underlineColor), SK_ColorTRANSPARENT)); break; } case QInputMethodEvent::Cursor: diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index ad7fc9f13..6a1134ac0 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -246,8 +246,6 @@ private: bool m_receivedEmptyImeEvent; QPoint m_previousMousePosition; - bool m_initPending; - gfx::Vector2dF m_lastScrollOffset; gfx::SizeF m_lastContentsSize; viz::LocalSurfaceId m_localSurfaceId; diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index 8936ce63e..991c26ea8 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -91,7 +91,6 @@ public: class QWEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegate { public: virtual ~RenderWidgetHostViewQtDelegate() { } - virtual void initAsChild(WebContentsAdapterClient*) = 0; virtual void initAsPopup(const QRect&) = 0; virtual QRectF screenRect() const = 0; virtual QRectF contentsRect() const = 0; diff --git a/src/core/type_conversion.cpp b/src/core/type_conversion.cpp index 2a9746660..4aff2cff6 100644 --- a/src/core/type_conversion.cpp +++ b/src/core/type_conversion.cpp @@ -52,6 +52,7 @@ QImage toQImage(const SkBitmap &bitmap) switch (bitmap.colorType()) { case kUnknown_SkColorType: case kRGBA_F16_SkColorType: + case kRGBA_F32_SkColorType: qWarning("Unknown or unsupported skia image format"); break; case kAlpha_8_SkColorType: diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 762d9f53a..21540f5da 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -516,14 +516,9 @@ void WebContentsAdapter::initialize(content::SiteInstance *site) if (!rvh->IsRenderViewLive()) static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, base::UnguessableToken::Create(), content::FrameReplicationState()); - m_adapterClient->initializationFinished(); -} + m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh); -void WebContentsAdapter::reattachRWHV() -{ - CHECK_INITIALIZED(); - if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView()) - rwhv->InitAsChild(0); + m_adapterClient->initializationFinished(); } bool WebContentsAdapter::canGoBack() const @@ -1431,11 +1426,7 @@ bool WebContentsAdapter::handleDropDataFileContents(const content::DropData &dro const auto maybeFilename = dropData.GetSafeFilenameForImageFileContents(); const QString fileName = maybeFilename ? toQt(maybeFilename->AsUTF16Unsafe()) : QString(); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) const QString &filePath = m_dndTmpDir->filePath(fileName); -#else - const QString &filePath = m_dndTmpDir->path() + QLatin1Char('/') + fileName; -#endif QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { qWarning("Cannot write temporary file %s.", qUtf8Printable(filePath)); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 8e02a852b..e8e5359be 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -109,8 +109,6 @@ public: void load(const QWebEngineHttpRequest &request); void setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl); - void reattachRWHV(); - bool canGoBack() const; bool canGoForward() const; void stop(); diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index f1a15ddfd..b4f7d3f95 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -466,6 +466,7 @@ public: virtual void selectClientCert(const QSharedPointer<ClientCertSelectController> &selectController) = 0; virtual void updateScrollPosition(const QPointF &position) = 0; virtual void updateContentsSize(const QSizeF &size) = 0; + virtual void updateNavigationActions() = 0; virtual void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions, const QPixmap &pixmap, const QPoint &offset) = 0; virtual bool supportsDragging() const = 0; @@ -474,6 +475,7 @@ public: virtual void setToolTip(const QString& toolTipText) = 0; virtual ClientType clientType() = 0; virtual void printRequested() = 0; + virtual void widgetChanged(RenderWidgetHostViewQtDelegate *newWidget) = 0; virtual void interceptRequest(QWebEngineUrlRequestInfo &) { } virtual ProfileAdapter *profileAdapter() = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 569b939d8..4bde93fd3 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -258,11 +258,20 @@ void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_ m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID()); } +void WebContentsDelegateQt::RenderViewHostChanged(content::RenderViewHost *, content::RenderViewHost *newHost) +{ + if (newHost && newHost->GetWidget() && newHost->GetWidget()->GetView()) { + auto rwhv = static_cast<RenderWidgetHostViewQt *>(newHost->GetWidget()->GetView()); + m_viewClient->widgetChanged(rwhv->delegate()); + } +} + void WebContentsDelegateQt::EmitLoadStarted(const QUrl &url, bool isErrorPage) { if (m_lastLoadProgress >= 0 && m_lastLoadProgress < 100) // already running return; m_viewClient->loadStarted(url, isErrorPage); + m_viewClient->updateNavigationActions(); m_viewClient->loadProgressChanged(0); m_lastLoadProgress = 0; } @@ -287,6 +296,16 @@ void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool m_lastLoadProgress = -1; m_viewClient->loadProgressChanged(100); m_viewClient->loadFinished(success, url, isErrorPage, errorCode, errorDescription); + m_viewClient->updateNavigationActions(); +} + +void WebContentsDelegateQt::EmitLoadCommitted() +{ + // Make sure that we don't set the findNext WebFindOptions on a new frame. + m_lastSearchedString = QString(); + + m_viewClient->loadCommitted(); + m_viewClient->updateNavigationActions(); } void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navigation_handle) @@ -302,11 +321,7 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig profileAdapter->visitedLinksManager()->addUrl(url); } - // Make sure that we don't set the findNext WebFindOptions on a new frame. - m_lastSearchedString = QString(); - - // This is currently used for canGoBack/Forward values, which is flattened across frames. For other purposes we might have to pass is_main_frame. - m_viewClient->loadCommitted(); + EmitLoadCommitted(); } // Success is reported by DidFinishLoad, but DidFailLoad is now dead code and needs to be handled below if (navigation_handle->GetNetErrorCode() == net::OK) @@ -325,10 +340,8 @@ void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navig EmitLoadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true); // If it is already committed we will not see another DidFinishNavigation call or a DidFinishLoad call. - if (navigation_handle->HasCommitted()) { - m_lastSearchedString = QString(); - m_viewClient->loadCommitted(); - } + if (navigation_handle->HasCommitted()) + EmitLoadCommitted(); } } diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 124250a40..9c0f8f484 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -130,6 +130,7 @@ public: // WebContentsObserver overrides void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override; + void RenderViewHostChanged(content::RenderViewHost *old_host, content::RenderViewHost *new_host) override; void DidStartNavigation(content::NavigationHandle *navigation_handle) override; void DidFinishNavigation(content::NavigationHandle *navigation_handle) override; void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description) override; @@ -159,6 +160,7 @@ private: QWeakPointer<WebContentsAdapter> createWindow(std::unique_ptr<content::WebContents> new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); void EmitLoadStarted(const QUrl &url, bool isErrorPage = false); void EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()); + void EmitLoadCommitted(); WebContentsAdapterClient *m_viewClient; QString m_lastSearchedString; diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index 7910688d3..3c4465ae3 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -78,8 +78,6 @@ content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForWidget(conten view->setDelegate(m_factoryClient->CreateRenderWidgetHostViewQtDelegate(view)); if (m_client) view->setAdapterClient(m_client); - // Tell the RWHV delegate to attach itself to the native view container. - view->InitAsChild(0); return view; } diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 7e91b3bdb..db74978d3 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -144,10 +144,8 @@ bool usingQtQuick2DRenderer() } } -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) if (device.isEmpty()) device = QQuickWindow::sceneGraphBackend(); -#endif if (device.isEmpty()) device = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND")); if (device.isEmpty()) @@ -364,10 +362,8 @@ WebEngineContext::WebEngineContext() appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' ')); } -#ifdef Q_OS_WIN bool enableWebGLSoftwareRendering = appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering")); -#endif bool useEmbeddedSwitches = false; #if defined(QTWEBENGINE_EMBEDDED_SWITCHES) @@ -462,12 +458,10 @@ WebEngineContext::WebEngineContext() bool tryGL = !usingANGLE() && (!usingSoftwareDynamicGL() -#ifdef Q_OS_WIN - // If user requested WebGL support on Windows, instead of using Skia rendering to - // bitmaps, use software rendering via opengl32sw.dll. This might be less + // If user requested WebGL support instead of using Skia rendering to + // bitmaps, use software rendering via software OpenGL. This might be less // performant, but at least provides WebGL support. || enableWebGLSoftwareRendering -#endif ) && !usingQtQuick2DRenderer(); @@ -534,12 +528,10 @@ WebEngineContext::WebEngineContext() if (glType) { parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType); parsedCommandLine->AppendSwitch(switches::kInProcessGPU); -#ifdef Q_OS_WIN if (enableWebGLSoftwareRendering) { parsedCommandLine->AppendSwitch(switches::kDisableGpuRasterization); parsedCommandLine->AppendSwitch(switches::kIgnoreGpuBlacklist); } -#endif } else { parsedCommandLine->AppendSwitch(switches::kDisableGpu); } diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 479fc38f8..a45f7048b 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -174,14 +174,6 @@ static QString qtTextForKeyEvent(const QKeyEvent *ev, int qtKey, Qt::KeyboardMod if ((qtModifiers & Qt::ControlModifier) && keyboardDriver() == KeyboardDriver::Xkb) text.clear(); - if (!text.isEmpty() || qtKey >= Qt::Key_Escape) - return text; - - QChar ch(qtKey); - if (!(qtModifiers & Qt::ShiftModifier)) // No way to check for caps lock - ch = ch.toLower(); - - text.append(ch); return text; } @@ -1413,11 +1405,7 @@ static void setBlinkWheelEventDelta(blink::WebMouseWheelEvent &webEvent) // a pixel delta based on ticks and scroll per line. static const float cDefaultQtScrollStep = 20.f; -#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) static const int wheelScrollLines = QGuiApplication::styleHints()->wheelScrollLines(); -#else - static const int wheelScrollLines = 3; -#endif webEvent.delta_x = webEvent.wheel_ticks_x * wheelScrollLines * cDefaultQtScrollStep; webEvent.delta_y = webEvent.wheel_ticks_y * wheelScrollLines * cDefaultQtScrollStep; } @@ -1426,7 +1414,9 @@ blink::WebMouseWheelEvent::Phase toBlinkPhase(QWheelEvent *ev) { switch (ev->phase()) { case Qt::NoScrollPhase: +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) case Qt::ScrollMomentum: +#endif return blink::WebMouseWheelEvent::kPhaseNone; case Qt::ScrollBegin: return ev->angleDelta().isNull() ? blink::WebMouseWheelEvent::kPhaseMayBegin : blink::WebMouseWheelEvent::kPhaseBegan; @@ -1451,7 +1441,11 @@ blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, doub webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; webEvent.phase = toBlinkPhase(ev); - webEvent.has_precise_scrolling_deltas = true; +#if defined(Q_OS_DARWIN) + // has_precise_scrolling_deltas is a macOS term meaning it is a system scroll gesture, see qnsview_mouse.mm + webEvent.has_precise_scrolling_deltas = (ev->source() == Qt::MouseEventSynthesizedBySystem); +#endif + setBlinkWheelEventDelta(webEvent); return webEvent; @@ -1465,6 +1459,10 @@ bool WebEventFactory::coalesceWebWheelEvent(blink::WebMouseWheelEvent &webEvent, return false; if (toBlinkPhase(ev) != webEvent.phase) return false; +#if defined(Q_OS_DARWIN) + if (webEvent.has_precise_scrolling_deltas != (ev->source() == Qt::MouseEventSynthesizedBySystem)) + return false; +#endif webEvent.SetTimeStamp(currentTimeForEvent(ev)); webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale); @@ -1495,6 +1493,12 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e webKitEvent.dom_key = domKeyForQtKey(qtKey); else if (!qtText.isEmpty()) webKitEvent.dom_key = ui::DomKey::FromCharacter(qtText.toUcs4().first()); + else { + QChar ch(qtKey); + if (!(qtModifiers & Qt::ShiftModifier)) // No way to check for caps lock + ch = ch.toLower(); + webKitEvent.dom_key = ui::DomKey::FromCharacter(ch.unicode()); + } // The dom_code field should contain the USB keycode of the *physical* key // that was pressed. Physical meaning independent of layout and modifiers. |