summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/webengine/quicknanobrowser/BrowserWindow.qml7
-rw-r--r--examples/webenginewidgets/maps/maps.pro2
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.cpp4
-rw-r--r--examples/webenginewidgets/simplebrowser/webpage.h2
-rw-r--r--mkspecs/features/functions.prf9
m---------src/3rdparty0
-rw-r--r--src/core/accessibility_tree_formatter_qt.cpp19
-rw-r--r--src/core/api/qtwebenginecoreglobal.cpp27
-rw-r--r--src/core/api/qwebenginecookiestore.cpp3
-rw-r--r--src/core/browser_accessibility_qt.h3
-rw-r--r--src/core/browser_main_parts_qt.cpp231
-rw-r--r--src/core/browser_main_parts_qt.h80
-rw-r--r--src/core/client_cert_select_controller.cpp4
-rw-r--r--src/core/client_cert_select_controller.h6
-rw-r--r--src/core/config/common.pri3
-rw-r--r--src/core/config/linux.pri2
-rw-r--r--src/core/configure.json15
-rw-r--r--src/core/content_browser_client_qt.cpp194
-rw-r--r--src/core/content_browser_client_qt.h1
-rw-r--r--src/core/content_main_delegate_qt.cpp6
-rw-r--r--src/core/content_main_delegate_qt.h4
-rw-r--r--src/core/content_utility_client_qt.cpp60
-rw-r--r--src/core/content_utility_client_qt.h56
-rw-r--r--src/core/core_chromium.pri4
-rw-r--r--src/core/login_delegate_qt.cpp1
-rw-r--r--src/core/net/proxy_config_service_qt.cpp7
-rw-r--r--src/core/ozone/gl_ozone_glx_qt.cpp19
-rw-r--r--src/core/profile_io_data_qt.cpp9
-rw-r--r--src/core/profile_io_data_qt.h2
-rw-r--r--src/core/qtwebengine.gni1
-rw-r--r--src/core/render_widget_host_view_qt.cpp88
-rw-r--r--src/core/render_widget_host_view_qt.h2
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h1
-rw-r--r--src/core/type_conversion.cpp1
-rw-r--r--src/core/web_contents_adapter.cpp13
-rw-r--r--src/core/web_contents_adapter.h2
-rw-r--r--src/core/web_contents_adapter_client.h2
-rw-r--r--src/core/web_contents_delegate_qt.cpp31
-rw-r--r--src/core/web_contents_delegate_qt.h2
-rw-r--r--src/core/web_contents_view_qt.cpp2
-rw-r--r--src/core/web_engine_context.cpp12
-rw-r--r--src/core/web_event_factory.cpp30
-rw-r--r--src/webengine/api/qquickwebengineview.cpp81
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h10
-rw-r--r--src/webengine/doc/qtwebengine.qdocconf1
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp16
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.h11
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp7
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quickwindow.h1
-rw-r--r--src/webengine/ui_delegates_manager.cpp5
-rw-r--r--src/webenginewidgets/api/qwebengineclientcertificateselection.cpp4
-rw-r--r--src/webenginewidgets/api/qwebengineclientcertificateselection.h4
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp97
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h2
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h11
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp102
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h11
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp59
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h12
-rw-r--r--tests/auto/quick/qquickwebenginedefaultsurfaceformat/BLACKLIST4
-rw-r--r--tests/auto/widgets/proxypac/proxy.pac7
-rw-r--r--tests/auto/widgets/proxypac/proxypac.pro28
-rw-r--r--tests/auto/widgets/proxypac/proxyserver.cpp84
-rw-r--r--tests/auto/widgets/proxypac/proxyserver.h62
-rw-r--r--tests/auto/widgets/proxypac/tst_proxypac.cpp73
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp17
-rw-r--r--tests/auto/widgets/widgets.pro3
67 files changed, 1178 insertions, 501 deletions
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index 7b8767b8d..8d62482da 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -367,7 +367,10 @@ ApplicationWindow {
return tab;
}
- anchors.fill: parent
+ anchors.top: parent.top
+ anchors.bottom: devToolsView.top
+ anchors.left: parent.left
+ anchors.right: parent.right
Component.onCompleted: createEmptyTab(defaultProfile)
Component {
@@ -500,7 +503,7 @@ ApplicationWindow {
WebEngineView {
id: devToolsView
visible: devToolsEnabled.checked
- height: 400
+ height: visible ? 400 : 0
inspectedView: visible && tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null
anchors.left: parent.left
anchors.right: parent.right
diff --git a/examples/webenginewidgets/maps/maps.pro b/examples/webenginewidgets/maps/maps.pro
index b1cb3b28b..fead8fe0b 100644
--- a/examples/webenginewidgets/maps/maps.pro
+++ b/examples/webenginewidgets/maps/maps.pro
@@ -12,6 +12,6 @@ target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/maps
INSTALLS += target
!qtConfig(webengine-geolocation) {
- error('Qt WebEngine compiled without geolocaton support, this example will not work.')
+ error('Qt WebEngine compiled without geolocation support, this example will not work.')
}
diff --git a/examples/webenginewidgets/simplebrowser/webpage.cpp b/examples/webenginewidgets/simplebrowser/webpage.cpp
index ab9dce4b8..e44410284 100644
--- a/examples/webenginewidgets/simplebrowser/webpage.cpp
+++ b/examples/webenginewidgets/simplebrowser/webpage.cpp
@@ -66,7 +66,7 @@ WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
connect(this, &QWebEnginePage::featurePermissionRequested, this, &WebPage::handleFeaturePermissionRequested);
connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, &WebPage::handleProxyAuthenticationRequired);
connect(this, &QWebEnginePage::registerProtocolHandlerRequested, this, &WebPage::handleRegisterProtocolHandlerRequested);
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
connect(this, &QWebEnginePage::selectClientCertificate, this, &WebPage::handleSelectClientCertificate);
#endif
}
@@ -197,7 +197,7 @@ void WebPage::handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolH
}
//! [registerProtocolHandlerRequested]
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
void WebPage::handleSelectClientCertificate(QWebEngineClientCertificateSelection selection)
{
// Just select one.
diff --git a/examples/webenginewidgets/simplebrowser/webpage.h b/examples/webenginewidgets/simplebrowser/webpage.h
index 0b351ab31..908295894 100644
--- a/examples/webenginewidgets/simplebrowser/webpage.h
+++ b/examples/webenginewidgets/simplebrowser/webpage.h
@@ -69,7 +69,7 @@ private slots:
void handleFeaturePermissionRequested(const QUrl &securityOrigin, Feature feature);
void handleProxyAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth, const QString &proxyHost);
void handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request);
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
void handleSelectClientCertificate(QWebEngineClientCertificateSelection clientCertSelection);
#endif
};
diff --git a/mkspecs/features/functions.prf b/mkspecs/features/functions.prf
index a26f1258d..c9bd65b03 100644
--- a/mkspecs/features/functions.prf
+++ b/mkspecs/features/functions.prf
@@ -127,3 +127,12 @@ defineReplace(pkgConfigHostExecutable) {
export(QMAKE_DISTCLEAN)
return($$system_quote($$system_path($$wrapper_name)))
}
+
+defineTest(hasX11Dependencies) {
+ for(package, $$list("libdrm xcomposite xcursor xi xrandr xtst")) {
+ !qtConfig(webengine-system-$$package) {
+ return(false)
+ }
+ }
+ return(true)
+}
diff --git a/src/3rdparty b/src/3rdparty
-Subproject 156c2b70ceef9a4464a5a241c9f816dea4fd316
+Subproject d521ec6dd1ed0114b9c6d32b047fb024420a6cd
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.
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 116f49c3c..3bc0be196 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -166,6 +166,9 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
adapter->stopFinding();
if (faviconProvider)
faviconProvider->detach(q_ptr);
+ // q_ptr->d_ptr might be null due to destroy()
+ if (q_ptr->d_ptr)
+ bindViewAndWidget(q_ptr, nullptr);
}
void QQuickWebEngineViewPrivate::initializeProfile()
@@ -188,10 +191,11 @@ bool QQuickWebEngineViewPrivate::profileInitialized() const
void QQuickWebEngineViewPrivate::destroy()
{
- // the profile for this web contens is about to be
- // garbage collected, delete WebContent first and
- // let the QQuickWebEngineView be collected later by gc.
- delete q_ptr->d_ptr.take();
+ // The profile for this web contents is about to be
+ // garbage collected, delete WebContents first and
+ // let the QQuickWebEngineView be collected later by gc.
+ bindViewAndWidget(q_ptr, nullptr);
+ delete q_ptr->d_ptr.take();
}
UIDelegatesManager *QQuickWebEngineViewPrivate::ui()
@@ -669,6 +673,12 @@ void QQuickWebEngineViewPrivate::printRequested()
});
}
+void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWidgetBase)
+{
+ Q_Q(QQuickWebEngineView);
+ bindViewAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateQuick *>(newWidgetBase));
+}
+
WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
{
return m_settings->d_ptr.data();
@@ -846,6 +856,52 @@ void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen)
}
}
+void QQuickWebEngineViewPrivate::bindViewAndWidget(QQuickWebEngineView *view,
+ RenderWidgetHostViewQtDelegateQuick *widget)
+{
+ auto oldWidget = view ? view->d_func()->widget : nullptr;
+ auto oldView = widget ? widget->m_view : nullptr;
+
+ // Change pointers first.
+
+ if (widget && oldView != view) {
+ if (oldView)
+ oldView->d_func()->widget = nullptr;
+ widget->m_view = view;
+ }
+
+ if (view && oldWidget != widget) {
+ if (oldWidget)
+ oldWidget->m_view = nullptr;
+ view->d_func()->widget = widget;
+ }
+
+ // Then notify.
+
+ if (widget && oldView != view && oldView)
+ oldView->d_func()->widgetChanged(widget, nullptr);
+
+ if (view && oldWidget != widget)
+ view->d_func()->widgetChanged(oldWidget, widget);
+}
+
+void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegateQuick *oldWidget,
+ RenderWidgetHostViewQtDelegateQuick *newWidget)
+{
+ Q_Q(QQuickWebEngineView);
+
+ if (oldWidget)
+ oldWidget->setParentItem(nullptr);
+
+ if (newWidget) {
+ newWidget->setParentItem(q);
+ newWidget->setSize(q->boundingRect().size());
+ // Focus on creation if the view accepts it
+ if (q->activeFocusOnPress())
+ newWidget->setFocus(true);
+ }
+}
+
void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction action) const
{
QQuickWebEngineAction *a = actions[action];
@@ -878,6 +934,15 @@ void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction act
a->d_ptr->setEnabled(enabled);
}
+void QQuickWebEngineViewPrivate::updateNavigationActions()
+{
+ updateAction(QQuickWebEngineView::Back);
+ updateAction(QQuickWebEngineView::Forward);
+ updateAction(QQuickWebEngineView::Stop);
+ updateAction(QQuickWebEngineView::Reload);
+ updateAction(QQuickWebEngineView::ReloadAndBypassCache);
+ updateAction(QQuickWebEngineView::ViewSource);
+}
QUrl QQuickWebEngineView::url() const
{
@@ -1485,11 +1550,9 @@ void QQuickWebEngineView::fullScreenCancelled()
void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickItem::geometryChanged(newGeometry, oldGeometry);
- const QList<QQuickItem *> children = childItems();
- for (QQuickItem *child : children) {
- if (qobject_cast<RenderWidgetHostViewQtDelegateQuick *>(child))
- child->setSize(newGeometry.size());
- }
+ Q_D(QQuickWebEngineView);
+ if (d->widget)
+ d->widget->setSize(newGeometry.size());
}
void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value)
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index ee38ece6b..cbba9b568 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -63,8 +63,9 @@
#include <QtGui/qaccessibleobject.h>
namespace QtWebEngineCore {
-class WebContentsAdapter;
+class RenderWidgetHostViewQtDelegateQuick;
class UIDelegatesManager;
+class WebContentsAdapter;
}
QT_BEGIN_NAMESPACE
@@ -145,6 +146,7 @@ public:
void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override;
void updateScrollPosition(const QPointF &position) override;
void updateContentsSize(const QSizeF &size) override;
+ void updateNavigationActions() override;
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
const QPixmap &pixmap, const QPoint &offset) override;
bool supportsDragging() const override;
@@ -156,6 +158,7 @@ public:
QtWebEngineCore::ProfileAdapter *profileAdapter() override;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
void printRequested() override;
+ void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidgetBase) override;
void updateAction(QQuickWebEngineView::WebAction) const;
void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
@@ -164,6 +167,10 @@ public:
void ensureContentsAdapter();
void setFullScreenMode(bool);
+ static void bindViewAndWidget(QQuickWebEngineView *view, QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget);
+ void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *oldWidget,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *newWidget);
+
// QQmlListPropertyHelpers
static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script);
static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p);
@@ -197,6 +204,7 @@ public:
uint m_webChannelWorld;
bool m_isBeingAdopted;
mutable QQuickWebEngineAction *actions[QQuickWebEngineView::WebActionCount];
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget = nullptr;
bool profileInitialized() const;
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index dc162bf56..b1e3a2ded 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -54,7 +54,6 @@ depends += qtcore \
qtqml \
qtquick \
qtquickcontrols \
- qtquickcontrols2 \
qtdoc \
qtwebchannel \
qtwebview \
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index baece82f3..d23e64774 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -55,7 +55,6 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
: m_client(client)
, m_isPopup(isPopup)
, m_isPasswordInput(false)
- , m_initialized(false)
{
setFlag(ItemHasContents);
setAcceptedMouseButtons(Qt::AllButtons);
@@ -85,16 +84,9 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
}
-void RenderWidgetHostViewQtDelegateQuick::initAsChild(WebContentsAdapterClient* container)
+RenderWidgetHostViewQtDelegateQuick::~RenderWidgetHostViewQtDelegateQuick()
{
- QQuickWebEngineView *view = static_cast<QQuickWebEngineViewPrivate *>(container)->q_func();
- setParentItem(view);
- setSize(view->boundingRect().size());
- // Focus on creation if the view accepts it
- if (view->activeFocusOnPress())
- setFocus(true);
- m_initialized = true;
-
+ QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, this);
}
void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
@@ -106,7 +98,6 @@ void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
setWidth(rect.width());
setHeight(rect.height());
setVisible(true);
- m_initialized = true;
}
QRectF RenderWidgetHostViewQtDelegateQuick::screenRect() const
@@ -361,8 +352,7 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
}
- if (m_initialized)
- m_client->windowChanged();
+ m_client->windowChanged();
} else if (change == QQuickItem::ItemVisibleHasChanged) {
if (!m_isPopup && !value.boolValue)
onHide();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index 74cddf476..6b855c824 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -44,6 +44,11 @@
#include <QQuickItem>
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineView;
+class QQuickWebEngineViewPrivate;
+QT_END_NAMESPACE
+
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateQuick : public QQuickItem, public RenderWidgetHostViewQtDelegate
@@ -51,8 +56,8 @@ class RenderWidgetHostViewQtDelegateQuick : public QQuickItem, public RenderWidg
Q_OBJECT
public:
RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup);
+ ~RenderWidgetHostViewQtDelegateQuick();
- void initAsChild(WebContentsAdapterClient* container) override;
void initAsPopup(const QRect&) override;
QRectF screenRect() const override;
QRectF contentsRect() const override;
@@ -102,12 +107,14 @@ private slots:
void onHide();
private:
+ friend QQuickWebEngineViewPrivate;
+
RenderWidgetHostViewQtDelegateClient *m_client;
QList<QMetaObject::Connection> m_windowConnections;
bool m_isPopup;
bool m_isPasswordInput;
- bool m_initialized;
QPoint m_lastGlobalPos;
+ QQuickWebEngineView *m_view = nullptr;
};
} // namespace QtWebEngineCore
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
index dd37ff6fa..d3c88148e 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -54,13 +54,6 @@ RenderWidgetHostViewQtDelegateQuickWindow::~RenderWidgetHostViewQtDelegateQuickW
{
}
-void RenderWidgetHostViewQtDelegateQuickWindow::initAsChild(WebContentsAdapterClient *container)
-{
- Q_UNUSED(container);
- // We should only use this wrapper class for webUI popups.
- Q_UNREACHABLE();
-}
-
void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &screenRect)
{
m_realDelegate->initAsPopup(QRect(QPoint(0, 0), screenRect.size()));
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index 6a1be8b7f..df241bf3a 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -55,7 +55,6 @@ public:
RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegate *realDelegate);
~RenderWidgetHostViewQtDelegateQuickWindow();
- void initAsChild(WebContentsAdapterClient* container) override;
void initAsPopup(const QRect&) override;
QRectF screenRect() const override;
QRectF contentsRect() const override;
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index 252bdc9b6..7e49bc77d 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -508,12 +508,7 @@ public:
if (pos.isNull() || !item->contains(pos))
return;
const QPoint oldPos = QCursor::pos();
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
const QPoint globalPos = item->mapToGlobal(QPointF(pos)).toPoint();
-#else
- const QPoint posInWindow = item->mapToItem(item->window()->contentItem(), QPointF(pos)).toPoint();
- const QPoint globalPos = item->window()->mapToGlobal(posInWindow);
-#endif
if (oldPos == globalPos)
return;
m_oldCursorPos = oldPos;
diff --git a/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp b/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp
index 8d3c8d223..9eca01bbe 100644
--- a/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp
+++ b/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp
@@ -39,7 +39,7 @@
#include "qwebengineclientcertificateselection.h"
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
#include "client_cert_select_controller.h"
@@ -124,4 +124,4 @@ QUrl QWebEngineClientCertificateSelection::host() const
QT_END_NAMESPACE
-#endif // QT_CONFIG(ssl)
+#endif // !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
diff --git a/src/webenginewidgets/api/qwebengineclientcertificateselection.h b/src/webenginewidgets/api/qwebengineclientcertificateselection.h
index 15b8a47c6..d451d09ae 100644
--- a/src/webenginewidgets/api/qwebengineclientcertificateselection.h
+++ b/src/webenginewidgets/api/qwebengineclientcertificateselection.h
@@ -43,7 +43,7 @@
#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
#include <QtNetwork/qtnetwork-config.h>
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
#include <QtCore/qscopedpointer.h>
#include <QtCore/qvector.h>
@@ -75,6 +75,6 @@ private:
QT_END_NAMESPACE
-#endif // QT_CONFIG(ssl)
+#endif // !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
#endif // QWEBENGINECLIENTCERTSELECTION_H
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 1f9b2f72a..6a70203be 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -276,8 +276,6 @@ RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostVie
// The new delegate will not be deleted by the parent view though, because we unset the parent
// when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is
// dismissed.
- // If the delegate is not for a popup, but for a newly created QWebEngineView, the parent is 0
- // just like before.
return new RenderWidgetHostViewQtDelegateWidget(client, this->view);
}
@@ -371,12 +369,6 @@ void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isError
isLoading = true;
QTimer::singleShot(0, q, &QWebEnginePage::loadStarted);
- updateNavigationActions();
-}
-
-void QWebEnginePagePrivate::loadCommitted()
-{
- updateNavigationActions();
}
void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription)
@@ -404,7 +396,6 @@ void QWebEnginePagePrivate::loadFinished(bool success, const QUrl &url, bool isE
emit q->loadFinished(success);
});
}
- updateNavigationActions();
}
void QWebEnginePagePrivate::didPrintPageToPdf(const QString &filePath, bool success)
@@ -688,6 +679,8 @@ void QWebEnginePagePrivate::recreateFromSerializedHistory(QDataStream &input)
adapter = std::move(newWebContents);
adapter->setClient(this);
adapter->loadDefault();
+ if (view && view->isVisible())
+ wasShown();
}
}
@@ -728,12 +721,87 @@ const QObject *QWebEnginePagePrivate::holdingQObject() const
return q;
}
+void QWebEnginePagePrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWidgetBase)
+{
+ Q_Q(QWebEnginePage);
+ bindPageAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateWidget *>(newWidgetBase));
+}
+
void QWebEnginePagePrivate::ensureInitialized() const
{
if (!adapter->isInitialized())
adapter->loadDefault();
}
+void QWebEnginePagePrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView *view)
+{
+ auto oldView = page ? page->d_func()->view : nullptr;
+ auto oldPage = view ? view->d_func()->page : nullptr;
+
+ // Change pointers first.
+
+ if (page && oldView != view) {
+ if (oldView)
+ oldView->d_func()->page = nullptr;
+ page->d_func()->view = view;
+ }
+
+ if (view && oldPage != page) {
+ if (oldPage)
+ oldPage->d_func()->view = nullptr;
+ view->d_func()->page = page;
+ }
+
+ // Then notify.
+
+ auto widget = page ? page->d_func()->widget : nullptr;
+ auto oldWidget = oldPage ? oldPage->d_func()->widget : nullptr;
+
+ if (page && oldView != view && oldView) {
+ oldView->d_func()->pageChanged(page, nullptr);
+ if (widget)
+ oldView->d_func()->widgetChanged(widget, nullptr);
+ }
+
+ if (view && oldPage != page) {
+ view->d_func()->pageChanged(oldPage, page);
+ if (oldWidget != widget)
+ view->d_func()->widgetChanged(oldWidget, widget);
+ }
+}
+
+void QWebEnginePagePrivate::bindPageAndWidget(QWebEnginePage *page, RenderWidgetHostViewQtDelegateWidget *widget)
+{
+ auto oldPage = widget ? widget->m_page : nullptr;
+ auto oldWidget = page ? page->d_func()->widget : nullptr;
+
+ // Change pointers first.
+
+ if (widget && oldPage != page) {
+ if (oldPage)
+ oldPage->d_func()->widget = nullptr;
+ widget->m_page = page;
+ }
+
+ if (page && oldWidget != widget) {
+ if (oldWidget)
+ oldWidget->m_page = nullptr;
+ page->d_func()->widget = widget;
+ }
+
+ // Then notify.
+
+ if (widget && oldPage != page && oldPage) {
+ if (auto oldView = oldPage->d_func()->view)
+ oldView->d_func()->widgetChanged(widget, nullptr);
+ }
+
+ if (page && oldWidget != widget) {
+ if (auto view = page->d_func()->view)
+ view->d_func()->widgetChanged(oldWidget, widget);
+ }
+}
+
QWebEnginePage::QWebEnginePage(QObject* parent)
: QObject(parent)
, d_ptr(new QWebEnginePagePrivate())
@@ -905,7 +973,8 @@ QWebEnginePage::~QWebEnginePage()
Q_D(QWebEnginePage);
setDevToolsPage(nullptr);
d->adapter->stopFinding();
- QWebEngineViewPrivate::removePageFromView(this);
+ QWebEnginePagePrivate::bindPageAndView(this, nullptr);
+ QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
}
QWebEngineHistory *QWebEnginePage::history() const
@@ -1074,9 +1143,9 @@ bool QWebEnginePage::recentlyAudible() const
return d->adapter->isInitialized() && d->adapter->recentlyAudible();
}
-void QWebEnginePage::setView(QWidget *view)
+void QWebEnginePage::setView(QWidget *newViewBase)
{
- QWebEngineViewPrivate::bind(qobject_cast<QWebEngineView*>(view), this);
+ QWebEnginePagePrivate::bindPageAndView(this, qobject_cast<QWebEngineView *>(newViewBase));
}
QWidget *QWebEnginePage::view() const
@@ -1680,7 +1749,7 @@ void QWebEnginePagePrivate::allowCertificateError(const QSharedPointer<Certifica
void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSelectController> &controller)
{
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
Q_Q(QWebEnginePage);
QWebEngineClientCertificateSelection certSelection(controller);
@@ -1690,7 +1759,7 @@ void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSele
#endif
}
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
/*!
\fn void QWebEnginePage::selectClientCertificate(QWebEngineClientCertificateSelection clientCertificateSelection)
\since 5.12
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index a6bad4f26..4fd195074 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -325,7 +325,7 @@ Q_SIGNALS:
void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);
void quotaRequested(QWebEngineQuotaRequest quotaRequest);
void registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request);
-#if QT_CONFIG(ssl)
+#if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
void selectClientCertificate(QWebEngineClientCertificateSelection clientCertSelection);
#endif
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 6d214adca..7b4e52f79 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -65,6 +65,7 @@
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegate;
+class RenderWidgetHostViewQtDelegateWidget;
class WebContentsAdapter;
}
@@ -100,7 +101,7 @@ public:
qreal dpiScale() const override;
QColor backgroundColor() const override;
void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) override;
- void loadCommitted() override;
+ void loadCommitted() override { }
void loadVisuallyCommitted() override { }
void loadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()) override;
void focusContainer() override;
@@ -141,6 +142,7 @@ public:
void requestGeometryChange(const QRect &geometry, const QRect &frameGeometry) override;
void updateScrollPosition(const QPointF &position) override;
void updateContentsSize(const QSizeF &size) override;
+ void updateNavigationActions() override;
void startDragging(const content::DropData &dropData, Qt::DropActions allowedActions,
const QPixmap &pixmap, const QPoint &offset) override;
bool supportsDragging() const override;
@@ -150,12 +152,12 @@ public:
const QObject *holdingQObject() const override;
ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; }
void interceptRequest(QWebEngineUrlRequestInfo &) override;
+ void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidget) override;
QtWebEngineCore::ProfileAdapter *profileAdapter() override;
QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
void updateAction(QWebEnginePage::WebAction) const;
- void updateNavigationActions();
void _q_webActionTriggered(bool checked);
void wasShown();
@@ -167,6 +169,10 @@ public:
void setFullScreenMode(bool);
void ensureInitialized() const;
+ static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view);
+ static void bindPageAndWidget(QWebEnginePage *page,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget);
+
QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter;
QWebEngineHistory *history;
QWebEngineProfile *profile;
@@ -189,6 +195,7 @@ public:
qreal defaultZoomFactor;
QTimer wasShownTimer;
QWebEngineUrlRequestInterceptor *requestInterceptor;
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget = nullptr;
mutable QtWebEngineCore::CallbackDirectory m_callbacks;
mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index e6f9fcb49..576baad17 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -41,6 +41,7 @@
#include "qwebengineview_p.h"
#include "qwebenginepage_p.h"
+#include "render_widget_host_view_qt_delegate_widget.h"
#include "web_contents_adapter.h"
#if QT_CONFIG(action)
@@ -55,89 +56,61 @@
QT_BEGIN_NAMESPACE
-void QWebEngineViewPrivate::notify(QWebEngineView *view, QWebEnginePage *oldPage, QWebEnginePage *newPage)
+void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage)
{
- Q_ASSERT(view);
+ Q_Q(QWebEngineView);
+
+ if (oldPage) {
+ oldPage->disconnect(q);
+ }
+
+ if (newPage) {
+ QObject::connect(newPage, &QWebEnginePage::titleChanged, q, &QWebEngineView::titleChanged);
+ QObject::connect(newPage, &QWebEnginePage::urlChanged, q, &QWebEngineView::urlChanged);
+ QObject::connect(newPage, &QWebEnginePage::iconUrlChanged, q, &QWebEngineView::iconUrlChanged);
+ QObject::connect(newPage, &QWebEnginePage::iconChanged, q, &QWebEngineView::iconChanged);
+ QObject::connect(newPage, &QWebEnginePage::loadStarted, q, &QWebEngineView::loadStarted);
+ QObject::connect(newPage, &QWebEnginePage::loadProgress, q, &QWebEngineView::loadProgress);
+ QObject::connect(newPage, &QWebEnginePage::loadFinished, q, &QWebEngineView::loadFinished);
+ QObject::connect(newPage, &QWebEnginePage::selectionChanged, q, &QWebEngineView::selectionChanged);
+ QObject::connect(newPage, &QWebEnginePage::renderProcessTerminated, q, &QWebEngineView::renderProcessTerminated);
+ }
auto oldUrl = oldPage ? oldPage->url() : QUrl();
auto newUrl = newPage ? newPage->url() : QUrl();
if (oldUrl != newUrl)
- Q_EMIT view->urlChanged(newUrl);
+ Q_EMIT q->urlChanged(newUrl);
auto oldTitle = oldPage ? oldPage->title() : QString();
auto newTitle = newPage ? newPage->title() : QString();
if (oldTitle != newTitle)
- Q_EMIT view->titleChanged(newTitle);
+ Q_EMIT q->titleChanged(newTitle);
auto oldIcon = oldPage ? oldPage->iconUrl() : QUrl();
auto newIcon = newPage ? newPage->iconUrl() : QUrl();
if (oldIcon != newIcon) {
- Q_EMIT view->iconUrlChanged(newIcon);
- Q_EMIT view->iconChanged(newPage ? newPage->icon() : QIcon());
+ Q_EMIT q->iconUrlChanged(newIcon);
+ Q_EMIT q->iconChanged(newPage ? newPage->icon() : QIcon());
}
if ((oldPage && oldPage->hasSelection()) || (newPage && newPage->hasSelection()))
- Q_EMIT view->selectionChanged();
-}
-
-QWebEnginePage* QWebEngineViewPrivate::removeViewFromPage(QWebEngineView *view)
-{
- Q_ASSERT(view);
- QWebEnginePage *oldPage = view->d_func()->page;
-
- if (oldPage) {
- oldPage->disconnect(view);
- oldPage->d_func()->view = nullptr;
- if (oldPage->parent() != view)
- oldPage->d_func()->adapter->reattachRWHV();
- }
- return oldPage;
-}
-
-void QWebEngineViewPrivate::removePageFromView(QWebEnginePage *page)
-{
- Q_ASSERT(page);
- if (QWebEngineView *oldView = page->d_func()->view) {
- page->disconnect(oldView);
- page->d_func()->view = nullptr;
- oldView->d_func()->page = nullptr;
- notify(oldView, page, nullptr);
- }
+ Q_EMIT q->selectionChanged();
}
-void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
+void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget)
{
- if (view && page == view->d_func()->page)
- return;
-
- if (page) {
- // Un-bind page from its current view.
- removePageFromView(page);
- page->d_func()->view = view;
- page->d_func()->adapter->reattachRWHV();
- }
-
- if (view) {
- // Un-bind view from its current page.
- QWebEnginePage *oldPage = removeViewFromPage(view);
-
- view->d_func()->page = page;
- notify(view, oldPage, page);
+ Q_Q(QWebEngineView);
- if (oldPage && oldPage->parent() == view)
- delete oldPage;
+ if (oldWidget) {
+ q->layout()->removeWidget(oldWidget);
+ oldWidget->hide();
}
- if (view && page) {
- QObject::connect(page, &QWebEnginePage::titleChanged, view, &QWebEngineView::titleChanged);
- QObject::connect(page, &QWebEnginePage::urlChanged, view, &QWebEngineView::urlChanged);
- QObject::connect(page, &QWebEnginePage::iconUrlChanged, view, &QWebEngineView::iconUrlChanged);
- QObject::connect(page, &QWebEnginePage::iconChanged, view, &QWebEngineView::iconChanged);
- QObject::connect(page, &QWebEnginePage::loadStarted, view, &QWebEngineView::loadStarted);
- QObject::connect(page, &QWebEnginePage::loadProgress, view, &QWebEngineView::loadProgress);
- QObject::connect(page, &QWebEnginePage::loadFinished, view, &QWebEngineView::loadFinished);
- QObject::connect(page, &QWebEnginePage::selectionChanged, view, &QWebEngineView::selectionChanged);
- QObject::connect(page, &QWebEnginePage::renderProcessTerminated, view, &QWebEngineView::renderProcessTerminated);
+ if (newWidget) {
+ q->layout()->addWidget(newWidget);
+ q->setFocusProxy(newWidget);
+ newWidget->show();
}
}
@@ -193,7 +166,8 @@ QWebEngineView::QWebEngineView(QWidget *parent)
QWebEngineView::~QWebEngineView()
{
- QWebEngineViewPrivate::removeViewFromPage(this);
+ blockSignals(true);
+ QWebEnginePagePrivate::bindPageAndView(nullptr, this);
}
QWebEnginePage* QWebEngineView::page() const
@@ -206,9 +180,9 @@ QWebEnginePage* QWebEngineView::page() const
return d->page;
}
-void QWebEngineView::setPage(QWebEnginePage* page)
+void QWebEngineView::setPage(QWebEnginePage *newPage)
{
- QWebEngineViewPrivate::bind(this, page);
+ QWebEnginePagePrivate::bindPageAndView(newPage, this);
}
void QWebEngineView::load(const QUrl& url)
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index 1845bfb60..28fb883aa 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -55,6 +55,10 @@
#include <QtWidgets/qaccessiblewidget.h>
+namespace QtWebEngineCore {
+class RenderWidgetHostViewQtDelegateWidget;
+}
+
QT_BEGIN_NAMESPACE
class QWebEngineView;
@@ -65,10 +69,9 @@ public:
Q_DECLARE_PUBLIC(QWebEngineView)
QWebEngineView *q_ptr;
- static void notify(QWebEngineView *view, QWebEnginePage *oldPage, QWebEnginePage *newPage);
- static QWebEnginePage* removeViewFromPage(QWebEngineView *view);
- static void removePageFromView(QWebEnginePage *page);
- static void bind(QWebEngineView *view, QWebEnginePage *page);
+ void pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage);
+ void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget);
QWebEngineViewPrivate();
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index 13c65f1ec..7bbd85091 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -165,15 +165,28 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_AlwaysShowToolTips);
- if (parent) {
- // Unset the popup parent if the parent is being destroyed, thus making sure a double
- // delete does not happen.
- // Also in case the delegate is destroyed before its parent (when a popup is simply
- // dismissed), this connection will automatically be removed by ~QObject(), preventing
- // a use-after-free.
+ setContent(QUrl(), nullptr, m_rootItem.data());
+
+ connectRemoveParentBeforeParentDelete();
+}
+
+RenderWidgetHostViewQtDelegateWidget::~RenderWidgetHostViewQtDelegateWidget()
+{
+ QWebEnginePagePrivate::bindPageAndWidget(nullptr, this);
+}
+
+void RenderWidgetHostViewQtDelegateWidget::connectRemoveParentBeforeParentDelete()
+{
+ if (QWidget *parent = parentWidget())
connect(parent, &QObject::destroyed,
this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
- }
+}
+
+void RenderWidgetHostViewQtDelegateWidget::disconnectRemoveParentBeforeParentDelete()
+{
+ if (QWidget *parent = parentWidget())
+ disconnect(parent, &QObject::destroyed,
+ this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
}
void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
@@ -188,29 +201,9 @@ void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
close();
}
-void RenderWidgetHostViewQtDelegateWidget::initAsChild(WebContentsAdapterClient* container)
-{
- setContent(QUrl(), nullptr, m_rootItem.data());
-
- QWebEnginePagePrivate *pagePrivate = static_cast<QWebEnginePagePrivate *>(container);
- if (pagePrivate->view) {
- if (parentWidget())
- disconnect(parentWidget(), &QObject::destroyed,
- this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
- pagePrivate->view->layout()->addWidget(this);
- if (QWidget *focusProxy = pagePrivate->view->focusProxy())
- if (focusProxy != this)
- pagePrivate->view->layout()->removeWidget(focusProxy);
- pagePrivate->view->setFocusProxy(this);
- show();
- } else
- setParent(0);
-}
-
void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect)
{
m_isPopup = true;
- setContent(QUrl(), nullptr, m_rootItem.data());
// The keyboard events are supposed to go to the parent RenderHostView
// so the WebUI popups should never have focus. Besides, if the parent view
@@ -422,6 +415,18 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
{
bool handled = false;
+ // Track parent to make sure we don't get deleted.
+ switch (event->type()) {
+ case QEvent::ParentAboutToChange:
+ disconnectRemoveParentBeforeParentDelete();
+ break;
+ case QEvent::ParentChange:
+ connectRemoveParentBeforeParentDelete();
+ break;
+ default:
+ break;
+ }
+
// Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is
// disabled.
if (!isEnabled()) {
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 4dc47dfdd..74c9e3413 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -46,6 +46,11 @@
#include <QQuickItem>
#include <QQuickWidget>
+QT_BEGIN_NAMESPACE
+class QWebEnginePage;
+class QWebEnginePagePrivate;
+QT_END_NAMESPACE
+
namespace QtWebEngineCore {
// Useful information keyboard and mouse QEvent propagation.
@@ -58,8 +63,8 @@ class RenderWidgetHostViewQtDelegateWidget : public QQuickWidget, public RenderW
Q_OBJECT
public:
RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent = 0);
+ ~RenderWidgetHostViewQtDelegateWidget();
- void initAsChild(WebContentsAdapterClient* container) override;
void initAsPopup(const QRect&) override;
QRectF screenRect() const override;
QRectF contentsRect() const override;
@@ -95,9 +100,13 @@ protected:
private slots:
void onWindowPosChanged();
+ void connectRemoveParentBeforeParentDelete();
+ void disconnectRemoveParentBeforeParentDelete();
void removeParentBeforeParentDelete();
private:
+ friend QWebEnginePagePrivate;
+
RenderWidgetHostViewQtDelegateClient *m_client;
QScopedPointer<QQuickItem> m_rootItem;
bool m_isPopup;
@@ -105,6 +114,7 @@ private:
QColor m_clearColor;
QPoint m_lastGlobalPos;
QList<QMetaObject::Connection> m_windowConnections;
+ QWebEnginePage *m_page = nullptr;
};
} // namespace QtWebEngineCore
diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/BLACKLIST b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/BLACKLIST
new file mode 100644
index 000000000..a48edeeab
--- /dev/null
+++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/BLACKLIST
@@ -0,0 +1,4 @@
+[javascriptClipboard:default]
+opensuse-leap
+[javascriptClipboard:canPaste]
+opensuse-leap
diff --git a/tests/auto/widgets/proxypac/proxy.pac b/tests/auto/widgets/proxypac/proxy.pac
new file mode 100644
index 000000000..1d29847b9
--- /dev/null
+++ b/tests/auto/widgets/proxypac/proxy.pac
@@ -0,0 +1,7 @@
+function FindProxyForURL(url, host)
+{
+ if (shExpMatch(host, "*.proxy1.com")) return "PROXY localhost:5551";
+ if (shExpMatch(host, "*.proxy2.com")) return "PROXY localhost:5552";
+ return "PROXY proxy.url:8080";
+}
+
diff --git a/tests/auto/widgets/proxypac/proxypac.pro b/tests/auto/widgets/proxypac/proxypac.pro
new file mode 100644
index 000000000..00ae90977
--- /dev/null
+++ b/tests/auto/widgets/proxypac/proxypac.pro
@@ -0,0 +1,28 @@
+include(../tests.pri)
+QT += webengine
+HEADERS += proxyserver.h
+SOURCES += proxyserver.cpp
+
+# QTBUG-71229
+xgd_desktop.name=XDG_CURRENT_DESKTOP
+xgd_desktop.value=KDE
+QT_TOOL_ENV += xgd_desktop
+
+kde_home.name=KDEHOME
+kde_home.value=$$OUT_PWD
+QT_TOOL_ENV += kde_home
+
+PROXY_CONFIG= \
+ "[Proxy Settings]" \
+ "Proxy Config Script=$$PWD/proxy.pac" \
+ "ProxyType=2"
+
+mkpath($$OUT_PWD/share/config)
+KDE_FILE = $$OUT_PWD/share/config/kioslaverc
+
+!build_pass {
+ write_file($$KDE_FILE, PROXY_CONFIG)
+}
+
+QMAKE_DISTCLEAN += $$KDE_FILE
+
diff --git a/tests/auto/widgets/proxypac/proxyserver.cpp b/tests/auto/widgets/proxypac/proxyserver.cpp
new file mode 100644
index 000000000..4d38c87c9
--- /dev/null
+++ b/tests/auto/widgets/proxypac/proxyserver.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "proxyserver.h"
+#include <QDataStream>
+#include <QTcpSocket>
+#include <QDebug>
+
+ProxyServer::ProxyServer(QObject *parent) : QObject(parent),
+ m_port(5555)
+{
+ connect(&m_server, &QTcpServer::newConnection, this, &ProxyServer::handleNewConnection);
+}
+
+void ProxyServer::setPort(int port)
+{
+ m_port = port;
+}
+
+bool ProxyServer::isListening()
+{
+ return m_server.isListening();
+}
+
+void ProxyServer::run()
+{
+ if (!m_server.listen(QHostAddress::LocalHost, m_port))
+ qFatal("Could not start the test server");
+}
+
+void ProxyServer::handleNewConnection()
+{
+ // do one connection at the time
+ Q_ASSERT(m_data.isEmpty());
+ QTcpSocket *socket = m_server.nextPendingConnection();
+ Q_ASSERT(socket);
+ connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater);
+ connect(socket, &QAbstractSocket::readyRead, this, &ProxyServer::handleReadReady);
+}
+
+void ProxyServer::handleReadReady()
+{
+ QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
+ Q_ASSERT(socket);
+
+ m_data.append(socket->readAll());
+
+ //simply wait for whole request
+ if (!m_data.endsWith("\r\n\r\n"))
+ return;
+
+ // add fake proxy authetication
+ socket->write("HTTP/1.1 407 Proxy Auth Required\nProxy-Authenticate: "
+ "Basic realm=\"Proxy requires authentication\"\r\n\r\n");
+
+ m_data.clear();
+ socket->disconnectFromHost();
+ emit requestReceived();
+}
diff --git a/tests/auto/widgets/proxypac/proxyserver.h b/tests/auto/widgets/proxypac/proxyserver.h
new file mode 100644
index 000000000..ea68286a2
--- /dev/null
+++ b/tests/auto/widgets/proxypac/proxyserver.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROXY_SERVER_H
+#define PROXY_SERVER_H
+
+#include <QObject>
+#include <QTcpServer>
+
+class ProxyServer : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit ProxyServer(QObject *parent = nullptr);
+
+ void setPort(int port);
+ bool isListening();
+
+signals:
+ void requestReceived();
+
+public slots:
+ void run();
+
+private slots:
+ void handleNewConnection();
+ void handleReadReady();
+
+private:
+ int m_port;
+ QByteArray m_data;
+ QTcpServer m_server;
+
+};
+
+#endif // PROXY_SERVER_H
diff --git a/tests/auto/widgets/proxypac/tst_proxypac.cpp b/tests/auto/widgets/proxypac/tst_proxypac.cpp
new file mode 100644
index 000000000..f9340341b
--- /dev/null
+++ b/tests/auto/widgets/proxypac/tst_proxypac.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtwebengineglobal.h"
+#include "proxyserver.h"
+#include <QTest>
+#include <QSignalSpy>
+#include <QWebEngineProfile>
+#include <QWebEnginePage>
+#include <QNetworkProxy>
+
+
+class tst_ProxyPac : public QObject {
+ Q_OBJECT
+public:
+ tst_ProxyPac(){}
+
+private slots:
+ void proxypac();
+};
+
+void tst_ProxyPac::proxypac()
+{
+ ProxyServer proxyServer1;
+ proxyServer1.setPort(5551);
+ proxyServer1.run();
+ QSignalSpy proxySpy1(&proxyServer1, &ProxyServer::requestReceived);
+
+ ProxyServer proxyServer2;
+ proxyServer2.setPort(5552);
+ proxyServer2.run();
+ QSignalSpy proxySpy2(&proxyServer2, &ProxyServer::requestReceived);
+
+ QTRY_VERIFY2(proxyServer1.isListening(), "Could not setup proxy server 1");
+ QTRY_VERIFY2(proxyServer2.isListening(), "Could not setup proxy server 2");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ page.load(QUrl("http://test.proxy1.com"));
+ QTRY_COMPARE(proxySpy1.count() >= 1, true);
+ QVERIFY(proxySpy2.count() == 0);
+ page.load(QUrl("http://test.proxy2.com"));
+ QTRY_COMPARE(proxySpy2.count() >= 1 , true);
+}
+
+#include "tst_proxypac.moc"
+QTEST_MAIN(tst_ProxyPac)
+
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index 6ce4623d6..0fe0ec6cf 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -35,6 +35,7 @@ class tst_QWebEngineScript: public QObject {
private Q_SLOTS:
void domEditing();
void loadEvents();
+ void scriptWorld_data();
void scriptWorld();
void scriptModifications();
#if QT_CONFIG(webengine_webchannel)
@@ -185,8 +186,18 @@ void tst_QWebEngineScript::loadEvents()
QCOMPARE(profile.pages.back().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
}
+void tst_QWebEngineScript::scriptWorld_data()
+{
+ QTest::addColumn<int>("worldId");
+
+ QTest::newRow("ApplicationWorld") << static_cast<int>(QWebEngineScript::ApplicationWorld);
+ QTest::newRow("UserWorld") << static_cast<int>(QWebEngineScript::UserWorld);
+ QTest::newRow("150") << 150;
+}
+
void tst_QWebEngineScript::scriptWorld()
{
+ QFETCH(int, worldId);
QWebEnginePage page;
QWebEngineScript script;
script.setInjectionPoint(QWebEngineScript::DocumentCreation);
@@ -197,14 +208,14 @@ void tst_QWebEngineScript::scriptWorld()
QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;"), QVariant::fromValue(true));
- QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) == \"undefined\"", QWebEngineScript::ApplicationWorld), QVariant::fromValue(true));
- script.setWorldId(QWebEngineScript::ApplicationWorld);
+ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) == \"undefined\"", worldId), QVariant::fromValue(true));
+ script.setWorldId(worldId);
page.scripts().clear();
page.scripts().insert(script);
page.load(QUrl("about:blank"));
QVERIFY(spyFinished.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) == \"undefined\""), QVariant::fromValue(true));
- QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;", QWebEngineScript::ApplicationWorld), QVariant::fromValue(true));
+ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;", worldId), QVariant::fromValue(true));
}
void tst_QWebEngineScript::scriptModifications()
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 05a4bfa59..eec8bb389 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -27,6 +27,9 @@ qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printing
}
+# QTBUG-71229
+linux:!boot2qt: SUBDIRS += proxypac
+
qtConfig(webengine-spellchecker):!cross_compile {
!qtConfig(webengine-native-spellchecker) {
SUBDIRS += spellchecking