summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-09-18 14:45:04 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-09-18 14:45:13 +0200
commit66f69a2052573af086fc5e0286e6af5ccaa80d97 (patch)
tree25056d484013efbbbb3eb1a78ad6a6449b671578 /src
parentb74e93a9b07243da4f3d2784cde49916de455364 (diff)
parentd74fd9b0d9bf5ab80e6c104fec5a92a9b3b9372d (diff)
downloadqtwebengine-66f69a2052573af086fc5e0286e6af5ccaa80d97.tar.gz
Merge branch '5.12' into dev
Change-Id: Icf2b740cb1eb2810beab98ff705e0bb59625f55e
Diffstat (limited to 'src')
m---------src/3rdparty0
-rw-r--r--src/core/api/qwebengineurlrequestjob.cpp26
-rw-r--r--src/core/api/qwebengineurlscheme.cpp48
-rw-r--r--src/core/api/qwebengineurlscheme.h27
-rw-r--r--src/core/compositor.cpp170
-rw-r--r--src/core/compositor.h120
-rw-r--r--src/core/config/linux.pri1
-rw-r--r--src/core/config/windows.pri4
-rw-r--r--src/core/configure.json11
-rw-r--r--src/core/core_chromium.pri2
-rw-r--r--src/core/core_common.pri3
-rw-r--r--src/core/delegated_frame_node.cpp26
-rw-r--r--src/core/devtools_frontend_qt.cpp11
-rw-r--r--src/core/doc/src/qtwebenginecore-module.qdoc2
-rw-r--r--src/core/download_manager_delegate_qt.cpp3
-rw-r--r--src/core/media_capture_devices_dispatcher.cpp11
-rw-r--r--src/core/net/url_request_custom_job_proxy.cpp2
-rw-r--r--src/core/render_widget_host_view_qt.cpp177
-rw-r--r--src/core/render_widget_host_view_qt.h30
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h4
-rw-r--r--src/core/user_script.h1
-rw-r--r--src/core/web_contents_adapter.cpp59
-rw-r--r--src/core/web_contents_adapter.h5
-rw-r--r--src/core/web_contents_delegate_qt.cpp6
-rw-r--r--src/core/web_contents_delegate_qt.h2
-rw-r--r--src/core/web_engine_context.cpp10
-rw-r--r--src/core/web_event_factory.cpp224
-rw-r--r--src/core/web_event_factory.h4
-rw-r--r--src/tools/qwebengine_convert_dict/main.cpp40
-rw-r--r--src/webengine/api/qquickwebengineaction.cpp2
-rw-r--r--src/webengine/api/qquickwebengineprofile.cpp6
-rw-r--r--src/webengine/api/qquickwebengineprofile.h1
-rw-r--r--src/webengine/api/qquickwebengineprofile_p.h2
-rw-r--r--src/webengine/api/qquickwebenginescript.cpp3
-rw-r--r--src/webengine/api/qquickwebenginesettings_p.h2
-rw-r--r--src/webengine/api/qquickwebengineview.cpp197
-rw-r--r--src/webengine/api/qquickwebengineview_p.h4
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h11
-rw-r--r--src/webengine/doc/src/qtwebengine-module.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-platform-notes.qdoc2
-rw-r--r--src/webengine/doc/src/qtwebengine-qmlmodule.qdoc4
-rw-r--r--src/webengine/doc/src/webengineview_lgpl.qdoc2
-rw-r--r--src/webengine/plugin/plugin.pro2
-rw-r--r--src/webengine/plugin/plugins.qmltypes28
-rw-r--r--src/webenginewidgets/api/qwebengineclientcertificateselection.cpp (renamed from src/webenginewidgets/api/qwebengineclientcertselection.cpp)22
-rw-r--r--src/webenginewidgets/api/qwebengineclientcertificateselection.h (renamed from src/webenginewidgets/api/qwebengineclientcertselection.h)16
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp21
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h6
-rw-r--r--src/webenginewidgets/api/qwebengineprofile.cpp2
-rw-r--r--src/webenginewidgets/api/qwebenginescript.cpp2
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp17
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h2
-rw-r--r--src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc2
-rw-r--r--src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc6
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp22
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h7
-rw-r--r--src/webenginewidgets/webenginewidgets.pro4
57 files changed, 950 insertions, 476 deletions
diff --git a/src/3rdparty b/src/3rdparty
-Subproject d4ae420c54b0e8b4660b5c41ec0c38049115f9a
+Subproject 79e2dad9ede84883b66feb83a7334febf20f274
diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp
index c028a1167..c3541598b 100644
--- a/src/core/api/qwebengineurlrequestjob.cpp
+++ b/src/core/api/qwebengineurlrequestjob.cpp
@@ -115,9 +115,24 @@ QByteArray QWebEngineUrlRequestJob::requestMethod() const
/*!
\since 5.11
- Returns the origin URL of the content that initiated the request. If the
- request was not initiated by web content the function will return an
- empty QUrl.
+ Returns the serialized origin of the content that initiated the request.
+
+ Generally, the origin consists of a scheme, hostname, and port. For example,
+ \c "http://localhost:8080" would be a valid origin. The port is omitted if
+ it is the scheme's default port (80 for \c http, 443 for \c https). The
+ hostname is omitted for non-network schemes such as \c file and \c qrc.
+
+ However, there is also the special value \c "null" representing a unique
+ origin. It is, for example, the origin of a sandboxed iframe. The purpose of
+ this special origin is to be always different from all other origins in the
+ same-origin check. In other words, content with a unique origin should never
+ have privileged access to any other content.
+
+ Finally, if the request was not initiated by web content, the function will
+ return an empty QUrl. This happens, for example, when you call \l
+ QWebEnginePage::setUrl().
+
+ This value can be used for implementing secure cross-origin checks.
*/
QUrl QWebEngineUrlRequestJob::initiator() const
{
@@ -136,9 +151,10 @@ QUrl QWebEngineUrlRequestJob::initiator() const
The device should remain available at least as long as the job exists.
When calling this method with a newly constructed device, one solution is to
- make the device delete itself when closed, like this:
+ make the device as a child of the job or delete itself when job is deleted,
+ like this:
\code
- connect(device, &QIODevice::aboutToClose, device, &QObject::deleteLater);
+ connect(job, &QObject::destroyed, device, &QObject::deleteLater);
\endcode
*/
void QWebEngineUrlRequestJob::reply(const QByteArray &contentType, QIODevice *device)
diff --git a/src/core/api/qwebengineurlscheme.cpp b/src/core/api/qwebengineurlscheme.cpp
index 24bcae195..f36f3335b 100644
--- a/src/core/api/qwebengineurlscheme.cpp
+++ b/src/core/api/qwebengineurlscheme.cpp
@@ -43,16 +43,16 @@
QT_BEGIN_NAMESPACE
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::PathSyntax, url::SCHEME_WITHOUT_AUTHORITY)
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::HostSyntax, url::SCHEME_WITH_HOST)
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::HostAndPortSyntax, url::SCHEME_WITH_HOST_AND_PORT)
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::HostPortAndUserInformationSyntax,
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::Path, url::SCHEME_WITHOUT_AUTHORITY)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::Host, url::SCHEME_WITH_HOST)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::HostAndPort, url::SCHEME_WITH_HOST_AND_PORT)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Syntax::HostPortAndUserInformation,
url::SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION)
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::PortUnspecified, url::PORT_UNSPECIFIED);
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::PortUnspecified, url::PORT_UNSPECIFIED)
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Secure, url::CustomScheme::Secure)
-ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::Local, url::CustomScheme::Local)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::SecureScheme, url::CustomScheme::Secure)
+ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::LocalScheme, url::CustomScheme::Local)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::LocalAccessAllowed, url::CustomScheme::LocalAccessAllowed)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::NoAccessAllowed, url::CustomScheme::NoAccessAllowed)
ASSERT_ENUMS_MATCH(QWebEngineUrlScheme::ServiceWorkersAllowed, url::CustomScheme::ServiceWorkersAllowed)
@@ -91,10 +91,10 @@ public:
int main(int argc, char **argv)
{
QWebEngineUrlScheme scheme("myscheme");
- scheme.setSyntax(QWebEngineUrlScheme::HostAndPortSyntax);
+ scheme.setSyntax(QWebEngineUrlScheme::Syntax::HostAndPort);
scheme.setDefaultPort(2345);
- scheme.setFlags(QWebEngineUrlScheme::Secure);
- QWebEngineUrlScheme::addScheme(scheme);
+ scheme.setFlags(QWebEngineUrlScheme::SecureScheme);
+ QWebEngineUrlScheme::registerScheme(scheme);
...
}
\endcode
@@ -113,25 +113,25 @@ public:
To apply the same-origin policy to a custom URL scheme, WebEngine must be able
to compute the origin (host and port combination) of a URL. The \c {Host...}
options indicate that the URL scheme conforms to the standard URL syntax (like
- \c http) and automatically enable the same-origin policy. The \c {PathSyntax}
+ \c http) and automatically enable the same-origin policy. The \c {Path}
option indicates that the URL scheme uses a non-standard syntax and that the
same-origin policy cannot be applied.
- \value HostPortAndUserInformationSyntax
+ \value HostPortAndUserInformation
The authority component of a URL of this type has all of the standard
elements: host, port, user name, and password. A URL without a port will use
the \l defaultPort (which \e must not be \l PortUnspecified).
- \value HostAndPortSyntax
+ \value HostAndPort
The authority component of a URL of this type has only the host and port
elements. A URL without a port will use the \l defaultPort (which \e must not
be \l PortUnspecified).
- \value HostSyntax
+ \value Host
The authority component of a URL of this type has only the host part and no
port. The \l defaultPort \e must be set to \l PortUnspecified.
- \value PathSyntax
+ \value Path
A URL of this type has no authority component at all. Everything after scheme
name and separator character (:) will be preserved as is without validation
or canonicalization. All URLs of such a scheme will be considered as having
@@ -152,7 +152,7 @@ public:
This enum type specifies security options that should apply to a URL scheme.
- \value Secure
+ \value SecureScheme
Indicates that the URL scheme is
\l{https://www.w3.org/TR/powerful-features/#is-origin-trustworthy}{potentially
trustworthy}. This flag should only be applied to URL schemes which ensure
@@ -161,7 +161,7 @@ public:
(authenticated and encrypted) and \c qrc (local resources only), whereas \c
http is an example of an insecure scheme.
- \value Local
+ \value LocalScheme
Indicates that the URL scheme provides access to local resources. The purpose
of this flag is to prevent network content from accessing local resources.
Only schemes with the \c LocalAccessAllowed flag may load resources from a
@@ -237,7 +237,7 @@ QWebEngineUrlScheme::~QWebEngineUrlScheme() = default;
/*!
Returns \c true if this and \a that object are equal.
*/
-bool QWebEngineUrlScheme::operator==(const QWebEngineUrlScheme &that)
+bool QWebEngineUrlScheme::operator==(const QWebEngineUrlScheme &that) const
{
return (d == that.d)
|| (d->name == that.d->name
@@ -247,7 +247,7 @@ bool QWebEngineUrlScheme::operator==(const QWebEngineUrlScheme &that)
}
/*!
- \fn bool QWebEngineUrlScheme::operator!=(const QWebEngineUrlScheme &that)
+ \fn bool QWebEngineUrlScheme::operator!=(const QWebEngineUrlScheme &that) const
Returns \c true if this and \a that object are not equal.
*/
@@ -279,7 +279,7 @@ void QWebEngineUrlScheme::setName(const QByteArray &newValue)
/*!
Returns the syntax type of this URL scheme.
- The default value is \c PathSyntax.
+ The default value is \c Path.
\sa Syntax, setSyntax()
*/
@@ -351,9 +351,9 @@ void QWebEngineUrlScheme::setFlags(Flags newValue)
\warning This function must be called early at application startup, before
creating any WebEngine classes. Late calls will be ignored.
- \sa findScheme()
+ \sa schemeByName()
*/
-void QWebEngineUrlScheme::addScheme(const QWebEngineUrlScheme &scheme)
+void QWebEngineUrlScheme::registerScheme(const QWebEngineUrlScheme &scheme)
{
url::CustomScheme::AddScheme(*scheme.d);
}
@@ -362,9 +362,9 @@ void QWebEngineUrlScheme::addScheme(const QWebEngineUrlScheme &scheme)
Returns the web engine URL scheme with the given \a name or the
default-constructed scheme.
- \sa addScheme()
+ \sa registerScheme()
*/
-QWebEngineUrlScheme QWebEngineUrlScheme::findScheme(const QByteArray &name)
+QWebEngineUrlScheme QWebEngineUrlScheme::schemeByName(const QByteArray &name)
{
base::StringPiece namePiece{name.data(), static_cast<size_t>(name.size())};
if (const url::CustomScheme *cs = url::CustomScheme::FindScheme(namePiece))
diff --git a/src/core/api/qwebengineurlscheme.h b/src/core/api/qwebengineurlscheme.h
index ee5bf3c3c..88a8f5065 100644
--- a/src/core/api/qwebengineurlscheme.h
+++ b/src/core/api/qwebengineurlscheme.h
@@ -43,6 +43,7 @@
#include <QtWebEngineCore/qtwebenginecoreglobal.h>
#include <QtCore/qbytearray.h>
+#include <QtCore/qobjectdefs.h>
#include <QtCore/qshareddata.h>
QT_BEGIN_NAMESPACE
@@ -50,12 +51,13 @@ QT_BEGIN_NAMESPACE
class QWebEngineUrlSchemePrivate;
class QWEBENGINECORE_EXPORT QWebEngineUrlScheme {
+ Q_GADGET
public:
- enum Syntax {
- HostPortAndUserInformationSyntax,
- HostAndPortSyntax,
- HostSyntax,
- PathSyntax,
+ enum class Syntax {
+ HostPortAndUserInformation,
+ HostAndPort,
+ Host,
+ Path,
};
enum SpecialPort {
@@ -63,8 +65,8 @@ public:
};
enum Flag {
- Secure = 0x1,
- Local = 0x2,
+ SecureScheme = 0x1,
+ LocalScheme = 0x2,
LocalAccessAllowed = 0x4,
NoAccessAllowed = 0x8,
ServiceWorkersAllowed = 0x10,
@@ -72,9 +74,10 @@ public:
ContentSecurityPolicyIgnored = 0x40,
};
Q_DECLARE_FLAGS(Flags, Flag)
+ Q_FLAG(Flags)
QWebEngineUrlScheme();
- QWebEngineUrlScheme(const QByteArray &name);
+ explicit QWebEngineUrlScheme(const QByteArray &name);
QWebEngineUrlScheme(const QWebEngineUrlScheme &that);
QWebEngineUrlScheme &operator=(const QWebEngineUrlScheme &that);
@@ -84,8 +87,8 @@ public:
~QWebEngineUrlScheme();
- bool operator==(const QWebEngineUrlScheme &that);
- bool operator!=(const QWebEngineUrlScheme &that) { return !(*this == that); }
+ bool operator==(const QWebEngineUrlScheme &that) const;
+ bool operator!=(const QWebEngineUrlScheme &that) const { return !(*this == that); }
QByteArray name() const;
void setName(const QByteArray &newValue);
@@ -99,8 +102,8 @@ public:
Flags flags() const;
void setFlags(Flags newValue);
- static void addScheme(const QWebEngineUrlScheme &scheme);
- static QWebEngineUrlScheme findScheme(const QByteArray &name);
+ static void registerScheme(const QWebEngineUrlScheme &scheme);
+ static QWebEngineUrlScheme schemeByName(const QByteArray &name);
private:
QWebEngineUrlScheme(QWebEngineUrlSchemePrivate *d);
diff --git a/src/core/compositor.cpp b/src/core/compositor.cpp
new file mode 100644
index 000000000..20d956ab4
--- /dev/null
+++ b/src/core/compositor.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** 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 "compositor.h"
+
+#include "delegated_frame_node.h"
+
+#include <components/viz/common/resources/returned_resource.h>
+#include <content/public/browser/browser_thread.h>
+#include <services/viz/public/interfaces/compositing/compositor_frame_sink.mojom.h>
+
+namespace QtWebEngineCore {
+
+Compositor::Compositor()
+ : m_chromiumCompositorData(new ChromiumCompositorData)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ base::SingleThreadTaskRunner *taskRunner =
+ content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI).get();
+ m_beginFrameSource =
+ std::make_unique<viz::DelayBasedBeginFrameSource>(
+ std::make_unique<viz::DelayBasedTimeSource>(taskRunner),
+ viz::BeginFrameSource::kNotRestartableId);
+}
+
+Compositor::~Compositor()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+}
+
+void Compositor::setViewDelegate(RenderWidgetHostViewQtDelegate *viewDelegate)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ m_viewDelegate = viewDelegate;
+}
+
+void Compositor::setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (m_frameSinkClient == frameSinkClient)
+ return;
+
+ // Accumulated resources belong to the old RendererCompositorFrameSink and
+ // should not be returned.
+ //
+ // TODO(juvaldma): Can there be a pending frame from the old client?
+ m_resourcesToRelease.clear();
+ m_frameSinkClient = frameSinkClient;
+}
+
+void Compositor::setNeedsBeginFrames(bool needsBeginFrames)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ if (m_needsBeginFrames == needsBeginFrames)
+ return;
+
+ if (needsBeginFrames)
+ m_beginFrameSource->AddObserver(this);
+ else
+ m_beginFrameSource->RemoveObserver(this);
+
+ m_needsBeginFrames = needsBeginFrames;
+}
+
+void Compositor::submitFrame(viz::CompositorFrame frame)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ DCHECK(!m_havePendingFrame);
+
+ m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor;
+ m_chromiumCompositorData->previousFrameData = std::move(m_chromiumCompositorData->frameData);
+ m_chromiumCompositorData->frameData = std::move(frame);
+ m_havePendingFrame = true;
+
+ // Tell viewDelegate to call updatePaintNode() soon.
+ m_viewDelegate->update();
+}
+
+QSGNode *Compositor::updatePaintNode(QSGNode *oldNode)
+{
+ // DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ //
+ // This might be called from a Qt Quick render thread, but the UI thread
+ // will still be blocked for the duration of this call.
+
+ DelegatedFrameNode *frameNode = static_cast<DelegatedFrameNode *>(oldNode);
+ if (!frameNode)
+ frameNode = new DelegatedFrameNode;
+
+ frameNode->commit(m_chromiumCompositorData.data(), &m_resourcesToRelease, m_viewDelegate);
+
+ if (m_havePendingFrame) {
+ m_havePendingFrame = false;
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE,
+ base::BindOnce(&Compositor::notifyFrameCommitted, m_weakPtrFactory.GetWeakPtr()));
+ }
+
+ return frameNode;
+}
+
+void Compositor::notifyFrameCommitted()
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ m_beginFrameSource->DidFinishFrame(this);
+ if (m_frameSinkClient)
+ m_frameSinkClient->DidReceiveCompositorFrameAck(m_resourcesToRelease);
+ m_resourcesToRelease.clear();
+}
+
+bool Compositor::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+
+ m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval);
+ if (m_frameSinkClient)
+ m_frameSinkClient->OnBeginFrame(args);
+
+ return true;
+}
+
+void Compositor::OnBeginFrameSourcePausedChanged(bool)
+{
+ // Ignored for now. If the begin frame source is paused, the renderer
+ // doesn't need to be informed about it and will just not receive more
+ // begin frames.
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/compositor.h b/src/core/compositor.h
new file mode 100644
index 000000000..4456c648b
--- /dev/null
+++ b/src/core/compositor.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** 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 COMPOSITOR_H
+#define COMPOSITOR_H
+
+#include <base/memory/weak_ptr.h>
+#include <components/viz/common/frame_sinks/begin_frame_source.h>
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+class QSGNode;
+QT_END_NAMESPACE
+
+namespace viz {
+class CompositorFrame;
+struct ReturnedResource;
+namespace mojom {
+class CompositorFrameSinkClient;
+} // namespace mojom
+} // namespace viz
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQtDelegate;
+class ChromiumCompositorData;
+
+// Receives viz::CompositorFrames from child compositors and provides QSGNodes
+// to the Qt Quick renderer.
+//
+// The life cycle of a frame:
+//
+// Step 1. A new CompositorFrame is received from child compositors and handed
+// off to submitFrame(). The new frame will start off in a pending state.
+//
+// Step 2. Once the new frame is ready to be rendered, Compositor will call
+// update() on the delegate.
+//
+// Step 3. Once the delegate is ready to render, updatePaintNode() should be
+// called to receive the scene graph for the new frame. This call will commit
+// the pending frame. Until the next frame is ready, all subsequent calls to
+// updatePaintNode() will keep using this same committed frame.
+//
+// Step 4. The Compositor will return unneeded resources back to the child
+// compositors. Go to step 1.
+class Compositor final : private viz::BeginFrameObserverBase
+{
+public:
+ explicit Compositor();
+ ~Compositor() override;
+
+ void setViewDelegate(RenderWidgetHostViewQtDelegate *viewDelegate);
+ void setFrameSinkClient(viz::mojom::CompositorFrameSinkClient *frameSinkClient);
+ void setNeedsBeginFrames(bool needsBeginFrames);
+
+ void submitFrame(viz::CompositorFrame frame);
+
+ QSGNode *updatePaintNode(QSGNode *oldNode);
+
+private:
+ void notifyFrameCommitted();
+
+ // viz::BeginFrameObserverBase
+ bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs &args) override;
+ void OnBeginFrameSourcePausedChanged(bool paused) override;
+
+ std::vector<viz::ReturnedResource> m_resourcesToRelease;
+ QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
+ RenderWidgetHostViewQtDelegate *m_viewDelegate = nullptr;
+ std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource;
+ viz::mojom::CompositorFrameSinkClient *m_frameSinkClient = nullptr;
+ bool m_havePendingFrame = false;
+ bool m_needsBeginFrames = false;
+
+ base::WeakPtrFactory<Compositor> m_weakPtrFactory{this};
+
+ DISALLOW_COPY_AND_ASSIGN(Compositor);
+};
+
+} // namespace QtWebEngineCore
+
+#endif // !COMPOSITOR_H
diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri
index f06679a3b..f0755f9cb 100644
--- a/src/core/config/linux.pri
+++ b/src/core/config/linux.pri
@@ -60,6 +60,7 @@ contains(QT_ARCH, "arm") {
!isEmpty(MFLOAT): gn_args += arm_float_abi=\"$$MFLOAT\"
MARCH = $$extractCFlag("-march=.*")
+ !isEmpty(MARCH): gn_args += arm_arch=\"$$MARCH\"
MARMV = $$replace(MARCH, "armv",)
!isEmpty(MARMV) {
diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri
index b3e4cf77d..5aa511da3 100644
--- a/src/core/config/windows.pri
+++ b/src/core/config/windows.pri
@@ -57,7 +57,7 @@ msvc {
equals(MSVC_VER, 15.0) {
MSVS_VERSION = 2017
} else {
- fatal("Visual Studio compiler version \"$$MSVC_VER\" is not supported by Qt WebEngine")
+ error("Visual Studio compiler version \"$$MSVC_VER\" is not supported by Qt WebEngine")
}
gn_args += visual_studio_version=$$MSVS_VERSION
@@ -71,5 +71,5 @@ msvc {
gn_args += target_cpu=\"$$GN_TARGET_CPU\"
} else {
- fatal("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler")
+ error("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler")
}
diff --git a/src/core/configure.json b/src/core/configure.json
index aaebcc4a8..e546cf899 100644
--- a/src/core/configure.json
+++ b/src/core/configure.json
@@ -250,11 +250,6 @@
"test": "snappy",
"type": "compile"
},
- "webengine-srtp": {
- "label": "srtp",
- "test": "srtp",
- "type": "compile"
- },
"webengine-winversion": {
"label": "winversion",
"test": "winversion",
@@ -474,11 +469,6 @@
"condition": "config.unix && tests.webengine-snappy",
"output": [ "privateFeature" ]
},
- "webengine-system-libsrtp" : {
- "label": "libsrtp",
- "condition": "config.unix && tests.webengine-srtp",
- "output": [ "privateFeature" ]
- },
"webengine-winversion" : {
"label": "winversion",
"condition": "config.win32 && tests.webengine-winversion",
@@ -751,7 +741,6 @@
"webengine-system-ffmpeg",
"webengine-system-libvpx",
"webengine-system-snappy",
- "webengine-system-libsrtp",
"webengine-system-glib",
"webengine-system-zlib",
"webengine-system-minizip",
diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri
index a3f9f5c80..92ab80c6c 100644
--- a/src/core/core_chromium.pri
+++ b/src/core/core_chromium.pri
@@ -53,6 +53,7 @@ SOURCES = \
common/qt_ipc_logging.cpp \
common/qt_messages.cpp \
common/user_script_data.cpp \
+ compositor.cpp \
content_client_qt.cpp \
content_browser_client_qt.cpp \
content_main_delegate_qt.cpp \
@@ -139,6 +140,7 @@ HEADERS = \
color_chooser_controller.h \
common/qt_messages.h \
common/user_script_data.h \
+ compositor.h \
content_client_qt.h \
content_browser_client_qt.h \
content_main_delegate_qt.h \
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
index 0c3e69e15..ce0eecce2 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -7,3 +7,6 @@ QT_PRIVATE += quick-private gui-private core-private webenginecoreheaders-privat
qtConfig(webengine-geolocation): QT += positioning
qtConfig(webengine-webchannel): QT += webchannel
+
+# LTO does not work for Chromium at the moment, so disable it completely for core.
+CONFIG -= ltcg
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 736ff1ab7..a3afc2002 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -154,7 +154,6 @@ public:
ResourceHolder(const viz::TransferableResource &resource);
QSharedPointer<QSGTexture> initTexture(bool quadIsAllOpaque, RenderWidgetHostViewQtDelegate *apiDelegate = 0);
QSGTexture *texture() const { return m_texture.data(); }
- viz::TransferableResource &transferableResource() { return m_resource; }
viz::ReturnedResource returnResource();
void incImportCount() { ++m_importCount; }
bool needsToFetch() const { return !m_resource.is_software && m_texture && !m_texture.data()->textureId(); }
@@ -185,11 +184,10 @@ public:
virtual void setupRenderPassNode(QSGTexture *, const QRect &, QSGNode *) = 0;
virtual void setupTextureContentNode(QSGTexture *, const QRect &, const QRectF &,
- QSGTexture::Filtering,
QSGTextureNode::TextureCoordinatesTransformMode,
QSGNode *) = 0;
virtual void setupTiledContentNode(QSGTexture *, const QRect &, const QRectF &,
- QSGTexture::Filtering, QSGNode *) = 0;
+ QSGNode *) = 0;
virtual void setupSolidColorNode(const QRect &, const QColor &, QSGNode *) = 0;
#ifndef QT_NO_OPENGL
@@ -228,7 +226,6 @@ public:
}
void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect,
- QSGTexture::Filtering filtering,
QSGTextureNode::TextureCoordinatesTransformMode texCoordTransForm,
QSGNode *) override
{
@@ -245,11 +242,11 @@ public:
textureNode->setRect(rect);
if (textureNode->sourceRect() != sourceRect)
textureNode->setSourceRect(sourceRect);
- if (textureNode->filtering() != filtering)
- textureNode->setFiltering(filtering);
+ if (textureNode->filtering() != texture->filtering())
+ textureNode->setFiltering(texture->filtering());
}
void setupTiledContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect,
- QSGTexture::Filtering filtering, QSGNode *) override
+ QSGNode *) override
{
Q_ASSERT(m_nodeIterator != m_sceneGraphNodes->end());
QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++);
@@ -262,8 +259,8 @@ public:
textureNode->setRect(rect);
if (textureNode->sourceRect() != sourceRect)
textureNode->setSourceRect(sourceRect);
- if (textureNode->filtering() != filtering)
- textureNode->setFiltering(filtering);
+ if (textureNode->filtering() != texture->filtering())
+ textureNode->setFiltering(texture->filtering());
}
void setupSolidColorNode(const QRect &rect, const QColor &color, QSGNode *) override
{
@@ -332,7 +329,6 @@ public:
}
void setupTextureContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect,
- QSGTexture::Filtering filtering,
QSGTextureNode::TextureCoordinatesTransformMode texCoordTransForm,
QSGNode *layerChain) override
{
@@ -341,20 +337,19 @@ public:
textureNode->setRect(rect);
textureNode->setSourceRect(sourceRect);
textureNode->setTexture(texture);
- textureNode->setFiltering(filtering);
+ textureNode->setFiltering(texture->filtering());
layerChain->appendChildNode(textureNode);
m_sceneGraphNodes->append(textureNode);
}
void setupTiledContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect,
- QSGTexture::Filtering filtering,
QSGNode *layerChain) override
{
QSGTextureNode *textureNode = m_apiDelegate->createTextureNode();
textureNode->setRect(rect);
textureNode->setSourceRect(sourceRect);
- textureNode->setFiltering(filtering);
+ textureNode->setFiltering(texture->filtering());
textureNode->setTexture(texture);
layerChain->appendChildNode(textureNode);
@@ -674,6 +669,7 @@ QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, R
Q_UNREACHABLE();
#endif
}
+ texture->setFiltering(m_resource.filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest);
m_texture = texture;
}
// All quads using a resource should request the same blending state.
@@ -1128,8 +1124,6 @@ void DelegatedFrameNode::handleQuad(
nodeHandler->setupTextureContentNode(
texture, toQt(quad->rect), toQt(uv_rect),
- resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear
- : QSGTexture::Nearest,
tquad->y_flipped ? QSGTextureNode::MirrorVertically : QSGTextureNode::NoTransform,
currentLayerChain);
break;
@@ -1173,8 +1167,6 @@ void DelegatedFrameNode::handleQuad(
nodeHandler->setupTiledContentNode(
initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate),
toQt(quad->rect), toQt(tquad->tex_coord_rect),
- resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear
- : QSGTexture::Nearest,
currentLayerChain);
break;
#ifndef QT_NO_OPENGL
diff --git a/src/core/devtools_frontend_qt.cpp b/src/core/devtools_frontend_qt.cpp
index 154b275b5..bd9e0ebe7 100644
--- a/src/core/devtools_frontend_qt.cpp
+++ b/src/core/devtools_frontend_qt.cpp
@@ -446,7 +446,16 @@ void DevToolsFrontendQt::HandleMessageFromDevToolsFrontend(const std::string &me
WindowOpenDisposition::NEW_FOREGROUND_TAB,
ui::PAGE_TRANSITION_LINK,
false);
- m_frontendDelegate->OpenURLFromTab(nullptr, openParams);
+ // OpenURL will (via WebContentsDelegateQt::OpenURLFromTab) call
+ // application code, which may decide to close this devtools view (see
+ // quicknanobrowser for example).
+ //
+ // Chromium always calls SendMessageAck through a callback bound to a
+ // WeakPtr, we do the same here, except without the callback.
+ base::WeakPtr<DevToolsFrontendQt> weakThis = m_weakFactory.GetWeakPtr();
+ web_contents()->OpenURL(openParams);
+ if (!weakThis)
+ return;
} else if (method == "bringToFront") {
Activate();
} else {
diff --git a/src/core/doc/src/qtwebenginecore-module.qdoc b/src/core/doc/src/qtwebenginecore-module.qdoc
index 2ed0a4c06..65e0766de 100644
--- a/src/core/doc/src/qtwebenginecore-module.qdoc
+++ b/src/core/doc/src/qtwebenginecore-module.qdoc
@@ -43,9 +43,11 @@
indirectly included through the \l{Qt WebEngine QML Types}{Qt WebEngine} or
\l{Qt WebEngine Widgets C++ Classes}{Qt WebEngine Widgets} modules.
+ \if !defined(qtforpython)
To link against the module, add this line to your qmake project file:
\snippet qtwebenginecore_build_snippet.qdoc 0
However, \c webenginecore is implied by adding \c webengine or \c webenginewidgets.
+ \endif
*/
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp
index 4ed77688e..9fe233577 100644
--- a/src/core/download_manager_delegate_qt.cpp
+++ b/src/core/download_manager_delegate_qt.cpp
@@ -43,6 +43,7 @@
#include "content/public/browser/download_manager.h"
#include "content/public/browser/save_page_type.h"
#include "content/public/browser/web_contents.h"
+#include "net/base/net_string_util.h"
#include "net/http/http_content_disposition.h"
#include <QDir>
@@ -136,7 +137,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem*
}
if (suggestedFilename.isEmpty())
- suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), std::string()).filename());
+ suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), net::kCharsetLatin1).filename());
if (suggestedFilename.isEmpty())
suggestedFilename = toQt(item->GetTargetFilePath().AsUTF8Unsafe());
diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp
index 5298e29cf..b6e59f3bb 100644
--- a/src/core/media_capture_devices_dispatcher.cpp
+++ b/src/core/media_capture_devices_dispatcher.cpp
@@ -114,7 +114,16 @@ void getDevicesForDesktopCapture(
content::DesktopMediaID getDefaultScreenId()
{
-#if QT_CONFIG(webengine_webrtc)
+ // While this function is executing another thread may also want to create a
+ // DesktopCapturer [1]. Unfortunately, creating a DesktopCapturer is not
+ // thread safe on X11 due to the use of webrtc::XErrorTrap. It's safe to
+ // disable this code on X11 since we don't actually need to create a
+ // DesktopCapturer to get the screen id anyway
+ // (ScreenCapturerLinux::GetSourceList always returns 0 as the id).
+ //
+ // [1]: webrtc::InProcessVideoCaptureDeviceLauncher::DoStartDesktopCaptureOnDeviceThread
+
+#if QT_CONFIG(webengine_webrtc) && !defined(USE_X11)
// Source id patterns are different across platforms.
// On Linux, the hardcoded value "0" is used.
// On Windows, the screens are enumerated consecutively in increasing order from 0.
diff --git a/src/core/net/url_request_custom_job_proxy.cpp b/src/core/net/url_request_custom_job_proxy.cpp
index 5280318ad..b5f10388c 100644
--- a/src/core/net/url_request_custom_job_proxy.cpp
+++ b/src/core/net/url_request_custom_job_proxy.cpp
@@ -159,7 +159,7 @@ void URLRequestCustomJobProxy::initialize(GURL url, std::string method, base::Op
QUrl initiatorOrigin;
if (initiator.has_value())
- initiatorOrigin = toQt(initiator.value().GetURL());
+ initiatorOrigin = QUrl::fromEncoded(QByteArray::fromStdString(initiator.value().Serialize()));
QWebEngineUrlSchemeHandler *schemeHandler = nullptr;
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 3e5d9bc4b..a3c5b06d1 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -43,7 +43,7 @@
#include "browser_accessibility_manager_qt.h"
#include "browser_accessibility_qt.h"
#include "chromium_overrides.h"
-#include "delegated_frame_node.h"
+#include "compositor.h"
#include "qtwebenginecoreglobal_p.h"
#include "render_widget_host_view_qt_delegate.h"
#include "type_conversion.h"
@@ -321,21 +321,15 @@ bool isAccessibilityEnabled() {
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget)
: content::RenderWidgetHostViewBase::RenderWidgetHostViewBase(widget)
- , m_host(content::RenderWidgetHostImpl::From(widget))
, m_gestureProvider(QtGestureProviderConfig(), this)
, m_sendMotionActionDown(false)
, m_touchMotionStarted(false)
- , m_chromiumCompositorData(new ChromiumCompositorData)
- , m_needsDelegatedFrameAck(false)
+ , m_compositor(new Compositor)
, m_loadVisuallyCommittedState(NotCommitted)
, m_adapterClient(0)
- , m_rendererCompositorFrameSink(0)
, m_imeInProgress(false)
, m_receivedEmptyImeEvent(false)
, m_initPending(false)
- , m_beginFrameSource(nullptr)
- , m_needsBeginFrames(false)
- , m_addedFrameObserver(false)
, m_backgroundColor(SK_ColorWHITE)
, m_imState(0)
, m_anchorPositionWithinSelection(-1)
@@ -344,11 +338,7 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
, m_emptyPreviousSelection(true)
, m_wheelAckPending(false)
{
- auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
- m_beginFrameSource.reset(new viz::DelayBasedBeginFrameSource(
- std::make_unique<viz::DelayBasedTimeSource>(task_runner), 0));
-
- m_host->SetView(this);
+ host()->SetView(this);
#ifndef QT_NO_ACCESSIBILITY
if (isAccessibilityEnabled()) {
QAccessible::installActivationObserver(this);
@@ -378,6 +368,7 @@ RenderWidgetHostViewQt::~RenderWidgetHostViewQt()
void RenderWidgetHostViewQt::setDelegate(RenderWidgetHostViewQtDelegate* delegate)
{
m_delegate.reset(delegate);
+ m_compositor->setViewDelegate(delegate);
}
void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterClient)
@@ -477,7 +468,7 @@ void RenderWidgetHostViewQt::Focus()
{
if (!IsPopup())
m_delegate->setKeyboardFocus();
- m_host->Focus();
+ host()->Focus();
}
bool RenderWidgetHostViewQt::HasFocus() const
@@ -528,8 +519,8 @@ void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color)
// Set the background of the compositor if necessary
m_delegate->setClearColor(toQt(color));
// Set the background of the blink::FrameView
- m_host->SetBackgroundOpaque(SkColorGetA(color) == SK_AlphaOPAQUE);
- m_host->Send(new RenderViewObserverQt_SetBackgroundColor(m_host->GetRoutingID(), color));
+ host()->SetBackgroundOpaque(SkColorGetA(color) == SK_AlphaOPAQUE);
+ host()->Send(new RenderViewObserverQt_SetBackgroundColor(host()->GetRoutingID(), color));
}
// Return value indicates whether the mouse is locked successfully or not.
@@ -547,7 +538,7 @@ void RenderWidgetHostViewQt::UnlockMouse()
mouse_locked_ = false;
m_delegate->unlockMouse();
qApp->restoreOverrideCursor();
- m_host->LostMouseLock();
+ host()->LostMouseLock();
}
void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor)
@@ -752,10 +743,7 @@ void RenderWidgetHostViewQt::DisplayTooltipText(const base::string16 &tooltip_te
void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(viz::mojom::CompositorFrameSinkClient *frameSink)
{
- // Accumulated resources belong to the old RendererCompositorFrameSink and
- // should not be returned.
- m_resourcesToRelease.clear();
- m_rendererCompositorFrameSink = frameSink;
+ m_compositor->setFrameSinkClient(frameSink);
}
void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &local_surface_id, viz::CompositorFrame frame, viz::mojom::HitTestRegionListPtr)
@@ -770,11 +758,6 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo
// FIXME: update frame_size and device_scale_factor?
// FIXME: showPrimarySurface()?
}
- Q_ASSERT(!m_needsDelegatedFrameAck);
- m_needsDelegatedFrameAck = true;
- m_chromiumCompositorData->previousFrameData = std::move(m_chromiumCompositorData->frameData);
- m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor;
- m_chromiumCompositorData->frameData = std::move(frame);
// Force to process swap messages
uint32_t frame_token = frame.metadata.frame_token;
@@ -784,9 +767,9 @@ void RenderWidgetHostViewQt::SubmitCompositorFrame(const viz::LocalSurfaceId &lo
// Support experimental.viewport.devicePixelRatio, see GetScreenInfo implementation below.
float dpiScale = this->dpiScale();
if (dpiScale != 0 && dpiScale != 1)
- m_chromiumCompositorData->frameDevicePixelRatio /= dpiScale;
+ frame.metadata.device_scale_factor /= dpiScale;
- m_delegate->update();
+ m_compositor->submitFrame(std::move(frame));
if (m_loadVisuallyCommittedState == NotCommitted) {
m_loadVisuallyCommittedState = DidFirstCompositorFrameSwap;
@@ -973,60 +956,46 @@ void RenderWidgetHostViewQt::selectionChanged()
void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture)
{
- m_host->ForwardGestureEvent(ui::CreateWebGestureEventFromGestureEventData(gesture));
+ host()->ForwardGestureEvent(ui::CreateWebGestureEventFromGestureEventData(gesture));
}
QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode)
{
- DelegatedFrameNode *frameNode = static_cast<DelegatedFrameNode *>(oldNode);
- if (!frameNode)
- frameNode = new DelegatedFrameNode;
-
- frameNode->commit(m_chromiumCompositorData.data(), &m_resourcesToRelease, m_delegate.get());
-
- // This is possibly called from the Qt render thread, post the ack back to the UI
- // to tell the child compositors to release resources and trigger a new frame.
- if (m_needsDelegatedFrameAck) {
- m_needsDelegatedFrameAck = false;
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(&RenderWidgetHostViewQt::sendDelegatedFrameAck, AsWeakPtr()));
- }
-
- return frameNode;
+ return m_compositor->updatePaintNode(oldNode);
}
void RenderWidgetHostViewQt::notifyResize()
{
- m_host->WasResized();
- m_host->SendScreenRects();
+ host()->WasResized();
+ host()->SendScreenRects();
}
void RenderWidgetHostViewQt::notifyShown()
{
- m_host->WasShown(ui::LatencyInfo());
+ host()->WasShown(ui::LatencyInfo());
}
void RenderWidgetHostViewQt::notifyHidden()
{
- m_host->WasHidden();
+ host()->WasHidden();
}
void RenderWidgetHostViewQt::windowBoundsChanged()
{
- m_host->SendScreenRects();
+ host()->SendScreenRects();
if (m_delegate->window())
- m_host->NotifyScreenInfoChanged();
+ host()->NotifyScreenInfoChanged();
}
void RenderWidgetHostViewQt::windowChanged()
{
if (m_delegate->window())
- m_host->NotifyScreenInfoChanged();
+ host()->NotifyScreenInfoChanged();
}
bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
{
- Q_ASSERT(m_host->GetView());
+ Q_ASSERT(host()->GetView());
switch (event->type()) {
case QEvent::ShortcutOverride: {
@@ -1073,7 +1042,11 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
case QEvent::MouseMove:
// Skip second MouseMove event when a window is being adopted, so that Chromium
// can properly handle further move events.
- if (m_adapterClient->isBeingAdopted())
+ // Also make sure the adapter client exists to prevent a null pointer dereference,
+ // because it's possible for a QWebEnginePagePrivate (adapter) instance to be destroyed,
+ // and then the OS (observed on Windows) might still send mouse move events to a still
+ // existing popup RWHVQDW instance.
+ if (m_adapterClient && m_adapterClient->isBeingAdopted())
return false;
handleMouseEvent(static_cast<QMouseEvent*>(event));
break;
@@ -1091,12 +1064,14 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
case QEvent::TouchCancel:
handleTouchEvent(static_cast<QTouchEvent*>(event));
break;
+#if QT_CONFIG(tabletevent)
case QEvent::TabletPress:
Focus(); // Fall through.
case QEvent::TabletRelease:
case QEvent::TabletMove:
handleTabletEvent(static_cast<QTabletEvent*>(event));
break;
+#endif
#ifndef QT_NO_GESTURES
case QEvent::NativeGesture:
handleGestureEvent(static_cast<QNativeGestureEvent *>(event));
@@ -1117,7 +1092,7 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event)
break;
case QEvent::HoverLeave:
case QEvent::Leave:
- m_host->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(event));
+ host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(event));
break;
default:
return false;
@@ -1172,21 +1147,21 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query)
}
}
+void RenderWidgetHostViewQt::closePopup()
+{
+ // We notify the popup to be closed by telling it that it lost focus. WebKit does the rest
+ // (hiding the widget and automatic memory cleanup via
+ // RenderWidget::CloseWidgetSoon() -> RenderWidgetHostImpl::ShutdownAndDestroyWidget(true).
+ host()->SetActive(false);
+ host()->Blur();
+}
+
void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) {
Q_UNUSED(touch);
const bool eventConsumed = ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED;
m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed, /*fixme: ?? */false);
}
-void RenderWidgetHostViewQt::sendDelegatedFrameAck()
-{
- m_beginFrameSource->DidFinishFrame(this);
- std::vector<viz::ReturnedResource> resources;
- m_resourcesToRelease.swap(resources);
- if (m_rendererCompositorFrameSink)
- m_rendererCompositorFrameSink->DidReceiveCompositorFrameAck(resources);
-}
-
void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent)
{
auto result = m_gestureProvider.OnTouchEvent(motionEvent);
@@ -1196,7 +1171,7 @@ void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEve
blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent,
result.moved_beyond_slop_region,
false /*hovering, FIXME ?*/);
- m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
+ host()->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent));
}
QList<QTouchEvent::TouchPoint> RenderWidgetHostViewQt::mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints)
@@ -1249,11 +1224,11 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
// We're getting the composition result in a key event.
if (ev->key() != 0) {
// The key event is not a result of an IME composition. Cancel IME.
- m_host->ImeCancelComposition();
+ host()->ImeCancelComposition();
m_receivedEmptyImeEvent = false;
} else {
if (ev->type() == QEvent::KeyRelease) {
- m_host->ImeCommitText(toString16(ev->text()),
+ host()->ImeCommitText(toString16(ev->text()),
std::vector<ui::ImeTextSpan>(),
gfx::Range::InvalidRange(),
0);
@@ -1271,13 +1246,13 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
content::EditCommands commands;
commands.emplace_back(m_editCommand, "");
m_editCommand.clear();
- m_host->ForwardKeyboardEventWithCommands(webEvent, latency, &commands, nullptr);
+ host()->ForwardKeyboardEventWithCommands(webEvent, latency, &commands, nullptr);
return;
}
bool keyDownTextInsertion = webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && webEvent.text[0];
webEvent.skip_in_browser = keyDownTextInsertion;
- m_host->ForwardKeyboardEvent(webEvent);
+ host()->ForwardKeyboardEvent(webEvent);
if (keyDownTextInsertion) {
// Blink won't consume the RawKeyDown, but rather the Char event in this case.
@@ -1285,7 +1260,7 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev)
// The same os_event will be set on both NativeWebKeyboardEvents.
webEvent.skip_in_browser = false;
webEvent.SetType(blink::WebInputEvent::kChar);
- m_host->ForwardKeyboardEvent(webEvent);
+ host()->ForwardKeyboardEvent(webEvent);
}
}
@@ -1294,7 +1269,7 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
// Reset input manager state
m_imState = 0;
- if (!m_host)
+ if (!host())
return;
QString commitString = ev->commitString();
@@ -1408,7 +1383,7 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
m_receivedEmptyImeEvent = false;
if (m_imeInProgress) {
m_imeInProgress = false;
- m_host->ImeCancelComposition();
+ host()->ImeCancelComposition();
}
}
@@ -1419,7 +1394,7 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
// Finish compostion: insert or erase text.
if (!commitString.isEmpty() || replacementLength > 0) {
- m_host->ImeCommitText(toString16(commitString),
+ host()->ImeCommitText(toString16(commitString),
underlines,
replacementRange,
0);
@@ -1430,7 +1405,7 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev)
// Be aware of that, we might get a commit string and a pre-edit string in a single event and
// this means a new composition.
if (!preeditString.isEmpty()) {
- m_host->ImeSetComposition(toString16(preeditString),
+ host()->ImeSetComposition(toString16(preeditString),
underlines,
replacementRange,
selectionRange.start(),
@@ -1467,7 +1442,7 @@ void RenderWidgetHostViewQt::handleWheelEvent(QWheelEvent *ev)
if (!m_wheelAckPending) {
Q_ASSERT(m_pendingWheelEvents.isEmpty());
m_wheelAckPending = true;
- m_host->ForwardWheelEvent(WebEventFactory::toWebWheelEvent(ev, dpiScale()));
+ host()->ForwardWheelEvent(WebEventFactory::toWebWheelEvent(ev, dpiScale()));
return;
}
if (!m_pendingWheelEvents.isEmpty()) {
@@ -1483,7 +1458,7 @@ void RenderWidgetHostViewQt::WheelEventAck(const blink::WebMouseWheelEvent &/*ev
m_wheelAckPending = false;
if (!m_pendingWheelEvents.isEmpty()) {
m_wheelAckPending = true;
- m_host->ForwardWheelEvent(m_pendingWheelEvents.takeFirst());
+ host()->ForwardWheelEvent(m_pendingWheelEvents.takeFirst());
}
// TODO: We could forward unhandled wheelevents to our parent.
}
@@ -1500,7 +1475,7 @@ void RenderWidgetHostViewQt::handleGestureEvent(QNativeGestureEvent *ev)
const Qt::NativeGestureType type = ev->gestureType();
// These are the only supported gestures by Chromium so far.
if (type == Qt::ZoomNativeGesture || type == Qt::SmartZoomNativeGesture) {
- m_host->ForwardGestureEvent(WebEventFactory::toWebGestureEvent(
+ host()->ForwardGestureEvent(WebEventFactory::toWebGestureEvent(
ev,
static_cast<double>(dpiScale())));
}
@@ -1617,10 +1592,12 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
}
}
+#if QT_CONFIG(tabletevent)
void RenderWidgetHostViewQt::handleTabletEvent(QTabletEvent *event)
{
handlePointerEvent<QTabletEvent>(event);
}
+#endif
template<class T>
void RenderWidgetHostViewQt::handlePointerEvent(T *event)
@@ -1668,20 +1645,20 @@ void RenderWidgetHostViewQt::handlePointerEvent(T *event)
#endif
}
- m_host->ForwardMouseEvent(webEvent);
+ host()->ForwardMouseEvent(webEvent);
}
void RenderWidgetHostViewQt::handleHoverEvent(QHoverEvent *ev)
{
- m_host->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(ev, dpiScale()));
+ host()->ForwardMouseEvent(WebEventFactory::toWebMouseEvent(ev, dpiScale()));
}
void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
{
if (ev->gotFocus()) {
- m_host->GotFocus();
- m_host->SetActive(true);
- content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(m_host);
+ host()->GotFocus();
+ host()->SetActive(true);
+ content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(host());
Q_ASSERT(viewHost);
if (ev->reason() == Qt::TabFocusReason)
viewHost->SetInitialFocus(false);
@@ -1689,50 +1666,20 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
viewHost->SetInitialFocus(true);
ev->accept();
} else if (ev->lostFocus()) {
- m_host->SetActive(false);
- m_host->Blur();
+ host()->SetActive(false);
+ host()->Blur();
ev->accept();
}
}
void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames)
{
- m_needsBeginFrames = needs_begin_frames;
- updateNeedsBeginFramesInternal();
-}
-
-void RenderWidgetHostViewQt::updateNeedsBeginFramesInternal()
-{
- Q_ASSERT(m_beginFrameSource);
-
- if (m_addedFrameObserver == m_needsBeginFrames)
- return;
-
- if (m_needsBeginFrames)
- m_beginFrameSource->AddObserver(this);
- else
- m_beginFrameSource->RemoveObserver(this);
- m_addedFrameObserver = m_needsBeginFrames;
-}
-
-bool RenderWidgetHostViewQt::OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args)
-{
- m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval);
- if (m_rendererCompositorFrameSink)
- m_rendererCompositorFrameSink->OnBeginFrame(args);
- return true;
-}
-
-void RenderWidgetHostViewQt::OnBeginFrameSourcePausedChanged(bool paused)
-{
- // Ignored for now. If the begin frame source is paused, the renderer
- // doesn't need to be informed about it and will just not receive more
- // begin frames.
+ m_compositor->setNeedsBeginFrames(needs_begin_frames);
}
content::RenderFrameHost *RenderWidgetHostViewQt::getFocusedFrameHost()
{
- content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(m_host);
+ content::RenderViewHostImpl *viewHost = content::RenderViewHostImpl::From(host());
if (!viewHost)
return nullptr;
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 0779136f0..909b3bd84 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -58,16 +58,7 @@
#include <QtGui/qaccessible.h>
#include <QtGui/QTouchEvent>
-#include "delegated_frame_node.h"
-
QT_BEGIN_NAMESPACE
-class QEvent;
-class QFocusEvent;
-class QHoverEvent;
-class QKeyEvent;
-class QMouseEvent;
-class QVariant;
-class QWheelEvent;
class QAccessibleInterface;
QT_END_NAMESPACE
@@ -78,6 +69,8 @@ class RenderWidgetHostImpl;
namespace QtWebEngineCore {
+class Compositor;
+
struct MultipleMouseClickHelper
{
QPoint lastPressPosition;
@@ -99,7 +92,6 @@ class RenderWidgetHostViewQt
, public ui::GestureProviderClient
, public RenderWidgetHostViewQtDelegateClient
, public base::SupportsWeakPtr<RenderWidgetHostViewQt>
- , public viz::BeginFrameObserverBase
#ifndef QT_NO_ACCESSIBILITY
, public QAccessible::ActivationObserver
#endif // QT_NO_ACCESSIBILITY
@@ -173,21 +165,20 @@ public:
void windowChanged() override;
bool forwardEvent(QEvent *) override;
QVariant inputMethodQuery(Qt::InputMethodQuery query) override;
+ void closePopup() override;
// Overridden from content::TextInputManager::Observer
void OnUpdateTextInputStateCalled(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view, bool did_update_state) override;
void OnSelectionBoundsChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
void OnTextSelectionChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view) override;
- // cc::BeginFrameObserverBase implementation.
- bool OnBeginFrameDerivedImpl(const viz::BeginFrameArgs& args) override;
- void OnBeginFrameSourcePausedChanged(bool paused) override;
-
void handleMouseEvent(QMouseEvent*);
void handleKeyEvent(QKeyEvent*);
void handleWheelEvent(QWheelEvent*);
void handleTouchEvent(QTouchEvent*);
+#if QT_CONFIG(tabletevent)
void handleTabletEvent(QTabletEvent *ev);
+#endif
#ifndef QT_NO_GESTURES
void handleGestureEvent(QNativeGestureEvent *);
#endif
@@ -217,7 +208,6 @@ public:
gfx::Vector2dF lastScrollOffset() const { return m_lastScrollOffset; }
private:
- void sendDelegatedFrameAck();
void processMotionEvent(const ui::MotionEvent &motionEvent);
void clearPreviousTouchMotionState();
QList<QTouchEvent::TouchPoint> mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints);
@@ -230,7 +220,6 @@ private:
content::RenderFrameHost *getFocusedFrameHost();
ui::TextInputType getTextInputType() const;
- content::RenderWidgetHostImpl *m_host;
ui::FilteredGestureProvider m_gestureProvider;
base::TimeDelta m_eventsToNowDelta;
bool m_sendMotionActionDown;
@@ -239,15 +228,12 @@ private:
QList<QTouchEvent::TouchPoint> m_previousTouchPoints;
std::unique_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
- QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData;
- std::vector<viz::ReturnedResource> m_resourcesToRelease;
- bool m_needsDelegatedFrameAck;
+ std::unique_ptr<Compositor> m_compositor;
LoadVisuallyCommittedState m_loadVisuallyCommittedState;
QMetaObject::Connection m_adapterClientDestroyedConnection;
WebContentsAdapterClient *m_adapterClient;
MultipleMouseClickHelper m_clickHelper;
- viz::mojom::CompositorFrameSinkClient *m_rendererCompositorFrameSink;
bool m_imeInProgress;
bool m_receivedEmptyImeEvent;
@@ -255,10 +241,6 @@ private:
bool m_initPending;
- std::unique_ptr<viz::SyntheticBeginFrameSource> m_beginFrameSource;
- bool m_needsBeginFrames;
- bool m_addedFrameObserver;
-
gfx::Vector2dF m_lastScrollOffset;
gfx::SizeF m_lastContentsSize;
SkColor m_backgroundColor;
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 55dd1923a..72f54dcb6 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -57,15 +57,12 @@
#include <QtGui/qwindowdefs.h>
QT_BEGIN_NAMESPACE
-class QCursor;
class QEvent;
-class QPainter;
class QSGLayer;
class QSGNode;
class QSGRectangleNode;
class QSGTexture;
class QVariant;
-class QWindow;
class QInputMethodEvent;
class QSGInternalImageNode;
@@ -89,6 +86,7 @@ public:
virtual void windowChanged() = 0;
virtual bool forwardEvent(QEvent *) = 0;
virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) = 0;
+ virtual void closePopup() = 0;
};
class QWEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegate {
diff --git a/src/core/user_script.h b/src/core/user_script.h
index 7743521f2..5ad53fdc1 100644
--- a/src/core/user_script.h
+++ b/src/core/user_script.h
@@ -53,7 +53,6 @@
#include "qtwebenginecoreglobal_p.h"
-#include <QtCore/QAtomicInt>
#include <QtCore/QScopedPointer>
#include <QtCore/QSharedData>
#include <QtCore/QString>
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 84b97412b..2e3f3785a 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -638,18 +638,19 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
}
}
- auto navigate = [this, loadParams = std::move(params)]() {
- webContents()->GetController().LoadURLWithParams(loadParams);
+ auto navigate = [](WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams &params) {
+ adapter->webContents()->GetController().LoadURLWithParams(params);
// Follow chrome::Navigate and invalidate the URL immediately.
- m_webContentsDelegate->NavigationStateChanged(webContents(), content::INVALIDATE_TYPE_URL);
- focusIfNecessary();
+ adapter->m_webContentsDelegate->NavigationStateChanged(adapter->webContents(), content::INVALIDATE_TYPE_URL);
+ adapter->focusIfNecessary();
};
if (resizeNeeded) {
// Schedule navigation on the event loop.
- QTimer::singleShot(0, std::move(navigate));
+ content::BrowserThread::PostTask(
+ content::BrowserThread::UI, FROM_HERE, base::BindOnce(navigate, this, std::move(params)));
} else {
- navigate();
+ navigate(this, params);
}
}
@@ -1265,11 +1266,11 @@ void WebContentsAdapter::dpiScaleChanged()
impl->NotifyScreenInfoChanged();
}
-void WebContentsAdapter::backgroundColorChanged()
+void WebContentsAdapter::setBackgroundColor(const QColor &color)
{
CHECK_INITIALIZED();
if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView())
- rwhv->SetBackgroundColor(toSk(m_adapterClient->backgroundColor()));
+ rwhv->SetBackgroundColor(toSk(color));
}
content::WebContents *WebContentsAdapter::webContents() const
@@ -1450,23 +1451,6 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
}
}
-void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPointF &screenPos)
-{
- CHECK_INITIALIZED();
-
- if (!m_currentDropData) {
- // The drag originated outside the WebEngineView.
- m_currentDropData.reset(new content::DropData);
- fillDropDataFromMimeData(m_currentDropData.get(), e->mimeData());
- }
-
- content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
- rvh->GetWidget()->FilterDropData(m_currentDropData.get());
- rvh->GetWidget()->DragTargetDragEnter(*m_currentDropData, toGfx(e->posF()), toGfx(screenPos),
- toWeb(e->possibleActions()),
- flagsFromModifiers(e->keyboardModifiers()));
-}
-
Qt::DropAction toQt(blink::WebDragOperation op)
{
if (op & blink::kWebDragOperationCopy)
@@ -1504,6 +1488,23 @@ static int toWeb(Qt::KeyboardModifiers modifiers)
return result;
}
+void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPointF &screenPos)
+{
+ CHECK_INITIALIZED();
+
+ if (!m_currentDropData) {
+ // The drag originated outside the WebEngineView.
+ m_currentDropData.reset(new content::DropData);
+ fillDropDataFromMimeData(m_currentDropData.get(), e->mimeData());
+ }
+
+ content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
+ rvh->GetWidget()->FilterDropData(m_currentDropData.get());
+ rvh->GetWidget()->DragTargetDragEnter(*m_currentDropData, toGfx(e->posF()), toGfx(screenPos),
+ toWeb(e->possibleActions()),
+ toWeb(e->mouseButtons()) | toWeb(e->keyboardModifiers()));
+}
+
Qt::DropAction WebContentsAdapter::updateDragPosition(QDragMoveEvent *e, const QPointF &screenPos)
{
CHECK_INITIALIZED(Qt::DropAction());
@@ -1545,14 +1546,16 @@ void WebContentsAdapter::updateDragAction(int action)
m_currentDropAction = static_cast<blink::WebDragOperation>(action);
}
-void WebContentsAdapter::endDragging(const QPointF &clientPos, const QPointF &screenPos)
+void WebContentsAdapter::endDragging(QDropEvent *e, const QPointF &screenPos)
{
CHECK_INITIALIZED();
content::RenderViewHost *rvh = m_webContents->GetRenderViewHost();
rvh->GetWidget()->FilterDropData(m_currentDropData.get());
- m_lastDragClientPos = clientPos;
+ m_lastDragClientPos = e->posF();
m_lastDragScreenPos = screenPos;
- rvh->GetWidget()->DragTargetDrop(*m_currentDropData, toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos), 0);
+ rvh->GetWidget()->DragTargetDrop(*m_currentDropData, toGfx(m_lastDragClientPos), toGfx(m_lastDragScreenPos),
+ toWeb(e->mouseButtons()) | toWeb(e->keyboardModifiers()));
+
m_currentDropData.reset();
}
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index bd2ca4b23..fcdac94b8 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -73,6 +73,7 @@ QT_BEGIN_NAMESPACE
class QAccessibleInterface;
class QDragEnterEvent;
class QDragMoveEvent;
+class QDropEvent;
class QMimeData;
class QPageLayout;
class QString;
@@ -186,7 +187,7 @@ public:
void grantMouseLockPermission(bool granted);
void dpiScaleChanged();
- void backgroundColorChanged();
+ void setBackgroundColor(const QColor &color);
QAccessibleInterface *browserAccessible();
ProfileQt* profile();
ProfileAdapter* profileAdapter();
@@ -205,7 +206,7 @@ public:
void enterDrag(QDragEnterEvent *e, const QPointF &screenPos);
Qt::DropAction updateDragPosition(QDragMoveEvent *e, const QPointF &screenPos);
void updateDragAction(int action);
- void endDragging(const QPointF &clientPos, const QPointF &screenPos);
+ void endDragging(QDropEvent *e, const QPointF &screenPos);
void leaveDrag();
#endif // QT_CONFIG(draganddrop)
void printToPDF(const QPageLayout&, const QString&);
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 7f1604162..36703c225 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -376,7 +376,11 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame
if (!m_faviconManager->hasCandidate())
m_viewClient->iconChanged(QUrl());
- EmitLoadFinished(true, toQt(validated_url));
+ content::NavigationEntry *entry = web_contents()->GetController().GetActiveEntry();
+ int http_statuscode = 0;
+ if (entry)
+ http_statuscode = entry->GetHttpStatusCode();
+ EmitLoadFinished(true /* success */ , toQt(validated_url), false /* isErrorPage */, http_statuscode);
}
void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates)
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 674e75fcd..a2bef7cc7 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -56,10 +56,8 @@ QT_FORWARD_DECLARE_CLASS(CertificateErrorController)
QT_FORWARD_DECLARE_CLASS(ClientCertSelectController)
namespace content {
- class BrowserContext;
class ColorChooser;
class SiteInstance;
- class RenderViewHost;
class JavaScriptDialogManager;
class WebContents;
struct WebPreferences;
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index a7301e02d..410e13837 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -170,7 +170,7 @@ bool usingSoftwareDynamicGL()
{
if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
return true;
-#if defined(Q_OS_WIN)
+#if defined(Q_OS_WIN) && !defined(QT_NO_OPENGL)
HMODULE handle = static_cast<HMODULE>(QOpenGLContext::openGLModuleHandle());
wchar_t path[MAX_PATH];
DWORD size = GetModuleFileName(handle, path, MAX_PATH);
@@ -329,10 +329,10 @@ WebEngineContext::WebEngineContext()
#endif
QWebEngineUrlScheme qrcScheme(QByteArrayLiteral("qrc"));
- qrcScheme.setFlags(QWebEngineUrlScheme::Secure
+ qrcScheme.setFlags(QWebEngineUrlScheme::SecureScheme
| QWebEngineUrlScheme::LocalAccessAllowed
| QWebEngineUrlScheme::ViewSourceAllowed);
- QWebEngineUrlScheme::addScheme(qrcScheme);
+ QWebEngineUrlScheme::registerScheme(qrcScheme);
// Allow us to inject javascript like any webview toolkit.
content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
@@ -516,8 +516,10 @@ WebEngineContext::WebEngineContext()
parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
#ifdef Q_OS_WIN
- if (enableWebGLSoftwareRendering)
+ 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 b8e8b1689..6358f6830 100644
--- a/src/core/web_event_factory.cpp
+++ b/src/core/web_event_factory.cpp
@@ -69,6 +69,9 @@
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
+
+#include <QtGui/private/qtgui-config_p.h>
#include <QCoreApplication>
#include <QElapsedTimer>
@@ -76,16 +79,141 @@
#include <QKeyEvent>
#include <QMouseEvent>
#include <QStyleHints>
+#if QT_CONFIG(tabletevent)
#include <QTabletEvent>
+#endif
#include <QWheelEvent>
using namespace blink;
-static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad)
+enum class KeyboardDriver { Unknown, Windows, Cocoa, Xkb, Evdev };
+
+static KeyboardDriver keyboardDriverImpl()
+{
+ QString platformName = QGuiApplication::platformName();
+
+ if (platformName == QLatin1Literal("windows"))
+ return KeyboardDriver::Windows;
+
+ if (platformName == QLatin1Literal("cocoa"))
+ return KeyboardDriver::Cocoa;
+
+ if (platformName == QLatin1Literal("xcb") || platformName == QLatin1Literal("wayland"))
+ return KeyboardDriver::Xkb;
+
+#if QT_CONFIG(libinput) && QT_CONFIG(xkbcommon_evdev)
+ // Based on QEglFSIntegration::createInputHandlers and QLibInputKeyboard::processKey.
+ if (platformName == QLatin1Literal("eglfs") && !qEnvironmentVariableIntValue("QT_QPA_EGLFS_NO_LIBINPUT"))
+ return KeyboardDriver::Xkb;
+#endif
+
+#if QT_CONFIG(evdev)
+ // Based on QEglFSIntegration::createInputHandlers.
+ if (platformName == QLatin1Literal("eglfs"))
+ return KeyboardDriver::Evdev;
+#endif
+
+ return KeyboardDriver::Unknown;
+}
+
+static KeyboardDriver keyboardDriver()
+{
+ static KeyboardDriver cached = keyboardDriverImpl();
+ return cached;
+}
+
+// Qt swaps the Control and Meta keys on macOS (unless the attribute
+// AA_MacDontSwapCtrlAndMeta is set). To preserve compatibility with Chromium we
+// want to unswap them when forwarding events. The following two functions,
+// qtKeyForKeyEvent and qtModifiersForEvent, should be used for accessing the
+// key() and modifiers() properties to ensure that the unswapping is done
+// consistently.
+static int qtKeyForKeyEvent(const QKeyEvent *ev)
+{
+ int key = ev->key();
+ if (keyboardDriver() == KeyboardDriver::Cocoa && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
+ if (key == Qt::Key_Control)
+ return Qt::Key_Meta;
+ if (key == Qt::Key_Meta)
+ return Qt::Key_Control;
+ }
+ return key;
+}
+
+// See above
+static Qt::KeyboardModifiers qtModifiersForEvent(const QInputEvent *ev)
+{
+ Qt::KeyboardModifiers modifiers = ev->modifiers();
+ if (keyboardDriver() == KeyboardDriver::Cocoa && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
+ bool controlModifier = modifiers.testFlag(Qt::ControlModifier);
+ bool metaModifier = modifiers.testFlag(Qt::MetaModifier);
+ modifiers.setFlag(Qt::ControlModifier, metaModifier);
+ modifiers.setFlag(Qt::MetaModifier, controlModifier);
+ }
+ return modifiers;
+}
+
+// QKeyEvent::text() has some limits that we need to work around.
+//
+// On Linux, the Control modifier transformation is applied [1]. For example,
+// pressing Ctrl+@ generates the text "\u0000". We would like "@" instead.
+//
+// [1]: https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
+//
+// On macOS, if the Control modifier is used, then no text is generated at all.
+// We need some text.
+//
+// The workaround is to use QKeyEvent::key() instead, when needed. Contrary to
+// the documentation, QKeyEvent::key() is not at all limited to the values
+// listed in the Qt::Key enum: it can actually contain any Unicode codepoint.
+// The only drawback is that letters are always upper cased.
+static QString qtTextForKeyEvent(const QKeyEvent *ev, int qtKey, Qt::KeyboardModifiers qtModifiers)
+{
+ QString text = ev->text();
+
+ 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;
+}
+
+// The 'native key code' in Chromium refers to
+//
+// - On Windows: the Windows OEM scancode.
+// - On macOS: the NSEvent's keyCode.
+// - On Linux: The XKB keycode.
+static quint32 nativeKeyCodeForKeyEvent(const QKeyEvent *ev)
+{
+ // Ifdefs here should match <ui/events/keycodes/dom/keycode_converter.cc>,
+ // since that is where the native key code is eventually used.
+ //
+ // Note that Xkb key codes are only supported under Linux (no BSDs,
+ // Cygwin/X, etc). Also evdev key codes are *not* supported for the same
+ // reason.
+#if defined(Q_OS_WINDOWS)
+ return keyboardDriver() == KeyboardDriver::Windows ? ev->nativeScanCode() : 0;
+#elif defined(Q_OS_MACOS)
+ return keyboardDriver() == KeyboardDriver::Cocoa ? ev->nativeVirtualKey() : 0;
+#elif defined(Q_OS_LINUX)
+ return keyboardDriver() == KeyboardDriver::Xkb ? ev->nativeScanCode() : 0;
+#else
+ return 0; // 0 means unknown, KeyboardEvent.code will be empty string.
+#endif
+}
+
+static int windowsKeyCodeForQtKey(int qtKey, bool isKeypad)
{
// Determine wheter the event comes from the keypad
if (isKeypad) {
- switch (keycode) {
+ switch (qtKey) {
case Qt::Key_0:
return VK_NUMPAD0; // (60) Numeric keypad 0 key
case Qt::Key_1:
@@ -152,7 +280,7 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad)
}
} else {
- switch (keycode) {
+ switch (qtKey) {
case Qt::Key_Backspace:
return VK_BACK; // (08) BACKSPACE key
case Qt::Key_Backtab:
@@ -645,12 +773,10 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad)
* - ui::DomKey::VIDEO_MODE_NEXT
* - ui::DomKey::WINK
*/
-static ui::DomKey getDomKeyFromQKeyEvent(QKeyEvent *ev)
+static ui::DomKey domKeyForQtKey(int qtKey)
{
- if (!ev->text().isEmpty())
- return ui::DomKey::FromCharacter(ev->text().toUcs4().first());
-
- switch (ev->key()) {
+ Q_ASSERT(qtKey >= Qt::Key_Escape);
+ switch (qtKey) {
case Qt::Key_Backspace:
return ui::DomKey::BACKSPACE;
case Qt::Key_Tab:
@@ -1083,17 +1209,10 @@ static inline WebInputEvent::Modifiers modifierForKeyCode(int key)
return WebInputEvent::kShiftKey;
case Qt::Key_Alt:
return WebInputEvent::kAltKey;
-#if defined(Q_OS_OSX)
- case Qt::Key_Control:
- return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::kMetaKey : WebInputEvent::kControlKey;
- case Qt::Key_Meta:
- return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::kControlKey : WebInputEvent::kMetaKey;
-#else
case Qt::Key_Control:
return WebInputEvent::kControlKey;
case Qt::Key_Meta:
return WebInputEvent::kMetaKey;
-#endif
default:
return static_cast<WebInputEvent::Modifiers>(0);
}
@@ -1102,22 +1221,11 @@ static inline WebInputEvent::Modifiers modifierForKeyCode(int key)
static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* event)
{
unsigned result = 0;
- Qt::KeyboardModifiers modifiers = event->modifiers();
-#if defined(Q_OS_OSX)
- if (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) {
- if (modifiers & Qt::ControlModifier)
- result |= WebInputEvent::kMetaKey;
- if (modifiers & Qt::MetaModifier)
- result |= WebInputEvent::kControlKey;
- } else
-#endif
- {
- if (modifiers & Qt::ControlModifier)
- result |= WebInputEvent::kControlKey;
- if (modifiers & Qt::MetaModifier)
- result |= WebInputEvent::kMetaKey;
- }
-
+ Qt::KeyboardModifiers modifiers = qtModifiersForEvent(event);
+ if (modifiers & Qt::ControlModifier)
+ result |= WebInputEvent::kControlKey;
+ if (modifiers & Qt::MetaModifier)
+ result |= WebInputEvent::kMetaKey;
if (modifiers & Qt::ShiftModifier)
result |= WebInputEvent::kShiftKey;
if (modifiers & Qt::AltModifier)
@@ -1139,7 +1247,7 @@ static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* even
const QKeyEvent *keyEvent = static_cast<const QKeyEvent*>(event);
if (keyEvent->isAutoRepeat())
result |= WebInputEvent::kIsAutoRepeat;
- result |= modifierForKeyCode(keyEvent->key());
+ result |= modifierForKeyCode(qtKeyForKeyEvent(keyEvent));
}
default:
break;
@@ -1186,6 +1294,7 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event)
}
}
+#if QT_CONFIG(tabletevent)
static WebPointerProperties::PointerType pointerTypeForTabletEvent(const QTabletEvent *ev)
{
switch (ev->pointerType()) {
@@ -1199,6 +1308,7 @@ static WebPointerProperties::PointerType pointerTypeForTabletEvent(const QTablet
return WebPointerProperties::PointerType::kMouse;
}
}
+#endif
WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale)
{
@@ -1230,6 +1340,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale)
return webKitEvent;
}
+#if QT_CONFIG(tabletevent)
WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev, double dpiScale)
{
WebMouseEvent webKitEvent(webEventTypeForEvent(ev),
@@ -1248,6 +1359,7 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QTabletEvent *ev, double dpiScale
webKitEvent.pointer_type = pointerTypeForTabletEvent(ev);
return webKitEvent;
}
+#endif
WebMouseEvent WebEventFactory::toWebMouseEvent(QEvent *ev)
{
@@ -1374,19 +1486,36 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e
webKitEvent.SetModifiers(modifiersForEvent(ev));
webKitEvent.SetType(webEventTypeForEvent(ev));
- webKitEvent.native_key_code = ev->nativeVirtualKey();
- webKitEvent.windows_key_code = windowsKeyCodeForKeyEvent(ev->key(), ev->modifiers() & Qt::KeypadModifier);
- webKitEvent.dom_key = getDomKeyFromQKeyEvent(ev);
-
- ui::DomCode domCode = ui::DomCode::NONE;
- int scanCode = ev->nativeScanCode();
- if (scanCode)
- domCode = ui::KeycodeConverter::NativeKeycodeToDomCode(scanCode);
- webKitEvent.dom_code = static_cast<int>(domCode);
-
- const ushort* text = ev->text().utf16();
- memcpy(&webKitEvent.text, text, std::min(sizeof(webKitEvent.text), size_t(ev->text().length() * 2)));
- memcpy(&webKitEvent.unmodified_text, text, std::min(sizeof(webKitEvent.unmodified_text), size_t(ev->text().length() * 2)));
+ int qtKey = qtKeyForKeyEvent(ev);
+ Qt::KeyboardModifiers qtModifiers = qtModifiersForEvent(ev);
+ QString qtText = qtTextForKeyEvent(ev, qtKey, qtModifiers);
+
+ webKitEvent.native_key_code = nativeKeyCodeForKeyEvent(ev);
+ webKitEvent.windows_key_code = windowsKeyCodeForQtKey(qtKey, qtModifiers & Qt::KeypadModifier);
+
+ if (qtKey >= Qt::Key_Escape)
+ webKitEvent.dom_key = domKeyForQtKey(qtKey);
+ else if (!qtText.isEmpty())
+ webKitEvent.dom_key = ui::DomKey::FromCharacter(qtText.toUcs4().first());
+
+ // The dom_code field should contain the USB keycode of the *physical* key
+ // that was pressed. Physical meaning independent of layout and modifiers.
+ //
+ // Since this information is not available from QKeyEvent in portable form,
+ // we try to compute it from the native key code. If there's no native key
+ // code available either, then we assume a US layout and convert it from
+ // windows_key_code. The result will be incorrect on non-US layouts.
+ if (webKitEvent.native_key_code)
+ webKitEvent.dom_code = static_cast<int>(
+ ui::KeycodeConverter::NativeKeycodeToDomCode(webKitEvent.native_key_code));
+ else
+ webKitEvent.dom_code = static_cast<int>(
+ ui::UsLayoutKeyboardCodeToDomCode(static_cast<ui::KeyboardCode>(webKitEvent.windows_key_code)));
+
+ const ushort* text = qtText.utf16();
+ size_t textSize = std::min(sizeof(webKitEvent.text), size_t(qtText.length() * 2));
+ memcpy(&webKitEvent.text, text, textSize);
+ memcpy(&webKitEvent.unmodified_text, text, textSize);
if (webKitEvent.windows_key_code == VK_RETURN) {
// This is the same behavior as GTK:
@@ -1465,10 +1594,7 @@ bool WebEventFactory::getEditCommand(QKeyEvent *event, std::string *editCommand)
}
#ifdef Q_OS_MACOS
- Qt::KeyboardModifier cmdKey = qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta) ?
- Qt::MetaModifier :
- Qt::ControlModifier;
- if ((event->modifiers() & ~Qt::ShiftModifier) == cmdKey) {
+ if ((qtModifiersForEvent(event) & ~Qt::ShiftModifier) == Qt::MetaModifier) {
if (event->key() == Qt::Key_Backspace) {
*editCommand = "DeleteToBeginningOfLine";
return true;
diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h
index dc29970a7..4b22de7d7 100644
--- a/src/core/web_event_factory.h
+++ b/src/core/web_event_factory.h
@@ -54,7 +54,9 @@ class QEvent;
class QHoverEvent;
class QKeyEvent;
class QMouseEvent;
+#ifndef QT_NO_TABLETEVENT
class QTabletEvent;
+#endif
class QWheelEvent;
#ifndef QT_NO_GESTURES
class QNativeGestureEvent;
@@ -66,7 +68,9 @@ class WebEventFactory {
public:
static blink::WebMouseEvent toWebMouseEvent(QMouseEvent*, double dpiScale);
static blink::WebMouseEvent toWebMouseEvent(QHoverEvent*, double dpiScale);
+#ifndef QT_NO_TABLETEVENT
static blink::WebMouseEvent toWebMouseEvent(QTabletEvent*, double dpiScale);
+#endif
static blink::WebMouseEvent toWebMouseEvent(QEvent *);
#ifndef QT_NO_GESTURES
static blink::WebGestureEvent toWebGestureEvent(QNativeGestureEvent *, double dpiScale);
diff --git a/src/tools/qwebengine_convert_dict/main.cpp b/src/tools/qwebengine_convert_dict/main.cpp
index 3a1a1ff64..2a82e5945 100644
--- a/src/tools/qwebengine_convert_dict/main.cpp
+++ b/src/tools/qwebengine_convert_dict/main.cpp
@@ -17,6 +17,7 @@
******************************************************************************/
#include <base/at_exit.h>
+#include <base/containers/span.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/i18n/icu_util.h>
@@ -61,6 +62,20 @@ inline QString toQt(const std::string &string)
return QString::fromStdString(string);
}
+template<class T>
+QTextStream &operator<<(QTextStream &out, base::span<T> span)
+{
+ out << '[';
+ QString prefix;
+ for (const auto &element : span) {
+ out << prefix;
+ out << element;
+ prefix = QStringLiteral(",");
+ }
+ out << ']';
+ return out;
+}
+
// Compares the given word list with the serialized trie to make sure they
// are the same.
inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
@@ -86,22 +101,23 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
}
if (org_words[i].first != buf) {
- out << "Word doesn't match, word #" << buf << endl;
+ out << "Word does not match!\n"
+ << " Index: " << i << "\n"
+ << " Expected: " << QString::fromStdString(org_words[i].first) << "\n"
+ << " Actual: " << QString::fromUtf8(buf) << endl;
return false;
}
- if (affix_matches != static_cast<int>(org_words[i].second.size())) {
- out << "Different number of affix indices, word #" << buf << endl;
- return false;
- }
+ base::span<const int> expectedAffixes(org_words[i].second);
+ base::span<const int> actualAffixes(affix_ids, affix_matches);
- // Check the individual affix indices.
- for (size_t affix_index = 0; affix_index < org_words[i].second.size();
- affix_index++) {
- if (affix_ids[affix_index] != org_words[i].second[affix_index]) {
- out << "Index doesn't match, word #" << buf << endl;
- return false;
- }
+ if (expectedAffixes != actualAffixes) {
+ out << "Affixes do not match!\n"
+ << " Index: " << i << "\n"
+ << " Word: " << QString::fromUtf8(buf) << "\n"
+ << " Expected: " << expectedAffixes << "\n"
+ << " Actual: " << actualAffixes << endl;
+ return false;
}
}
diff --git a/src/webengine/api/qquickwebengineaction.cpp b/src/webengine/api/qquickwebengineaction.cpp
index ce2fe6357..a0be20b54 100644
--- a/src/webengine/api/qquickwebengineaction.cpp
+++ b/src/webengine/api/qquickwebengineaction.cpp
@@ -134,7 +134,7 @@ QString QQuickWebEngineAction::text() const
/*!
\qmlproperty string WebEngineAction::iconText
- This property holds the action's descriptive icon text
+ This property holds the action's descriptive icon text.
*/
QString QQuickWebEngineAction::iconText() const
{
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index da84af8d0..f536695ef 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -173,7 +173,7 @@ QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
m_ongoingDownloads.clear();
- if (q_ptr != QQuickWebEngineProfile::defaultProfile())
+ if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter())
delete m_profileAdapter;
}
@@ -341,8 +341,6 @@ QQuickWebEngineProfile::QQuickWebEngineProfile(QObject *parent)
: QObject(parent),
d_ptr(new QQuickWebEngineProfilePrivate(new QtWebEngineCore::ProfileAdapter()))
{
- // Sets up the global WebEngineContext
- QQuickWebEngineProfile::defaultProfile();
d_ptr->q_ptr = this;
}
@@ -838,7 +836,7 @@ static bool checkInternalScheme(const QByteArray &scheme)
Registers a handler \a handler for custom URL scheme \a scheme in the profile.
It is recommended to first register the scheme with \l
- QWebEngineUrlScheme::addScheme at application startup.
+ QWebEngineUrlScheme::registerScheme at application startup.
*/
void QQuickWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
diff --git a/src/webengine/api/qquickwebengineprofile.h b/src/webengine/api/qquickwebengineprofile.h
index 4f1053924..9fc4f9eca 100644
--- a/src/webengine/api/qquickwebengineprofile.h
+++ b/src/webengine/api/qquickwebengineprofile.h
@@ -168,6 +168,7 @@ private:
friend class QQuickWebEngineViewPrivate;
friend class QQuickWebEngineDownloadItem;
friend class QQuickWebEngineDownloadItemPrivate;
+ friend class QQuickWebEngineView;
QScopedPointer<QQuickWebEngineProfilePrivate> d_ptr;
};
diff --git a/src/webengine/api/qquickwebengineprofile_p.h b/src/webengine/api/qquickwebengineprofile_p.h
index 9ed8b89de..d31ded0ec 100644
--- a/src/webengine/api/qquickwebengineprofile_p.h
+++ b/src/webengine/api/qquickwebengineprofile_p.h
@@ -90,7 +90,7 @@ public:
static void userScripts_clear(QQmlListProperty<QQuickWebEngineScript> *p);
private:
- friend class QQuickWebEngineViewPrivate;
+ friend class QQuickWebEngineView;
QQuickWebEngineProfile *q_ptr;
QScopedPointer<QQuickWebEngineSettings> m_settings;
QPointer<QtWebEngineCore::ProfileAdapter> m_profileAdapter;
diff --git a/src/webengine/api/qquickwebenginescript.cpp b/src/webengine/api/qquickwebenginescript.cpp
index acc5cedb7..ab7aee4cb 100644
--- a/src/webengine/api/qquickwebenginescript.cpp
+++ b/src/webengine/api/qquickwebenginescript.cpp
@@ -86,7 +86,8 @@ QT_BEGIN_NAMESPACE
/*!
\enum QQuickWebEngineScript::ScriptWorldId
- The world ID defining which isolated world the script is executed in.
+ The world ID defining which isolated world the script is executed in. Besides these predefined
+ IDs custom IDs can be used, but must be integers between \c 0 and \c 256.
\value MainWorld
The world used by the page's web contents. It can be useful in order to expose custom
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index 179416b54..6e1aaca39 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -204,7 +204,7 @@ private:
Q_DISABLE_COPY(QQuickWebEngineSettings)
friend class QQuickWebEngineProfilePrivate;
friend class QQuickWebEngineViewPrivate;
-
+ friend class QQuickWebEngineView;
void setParentSettings(QQuickWebEngineSettings *parentSettings);
QScopedPointer<QtWebEngineCore::WebEngineSettings> d_ptr;
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 02666d363..6bf23ea7b 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -107,11 +107,12 @@ static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *obje
}
#endif // QT_NO_ACCESSIBILITY
+static QLatin1String defaultMimeType("text/html;charset=UTF-8");
+
QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
- : m_profile(QQuickWebEngineProfile::defaultProfile())
+ : m_profile(nullptr)
, adapter(QSharedPointer<WebContentsAdapter>::create())
, m_history(new QQuickWebEngineHistory(this))
- , m_settings(new QQuickWebEngineSettings(m_profile->settings()))
#if QT_CONFIG(webengine_testsupport)
, m_testSupport(0)
#endif
@@ -127,11 +128,12 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
, m_isBeingAdopted(false)
, m_dpiScale(1.0)
, m_backgroundColor(Qt::white)
- , m_defaultZoomFactor(1.0)
+ , m_zoomFactor(1.0)
, m_ui2Enabled(false)
+ , m_profileInitialized(false)
{
- m_profile->d_ptr->addWebContentsAdapterClient(this);
memset(actions, 0, sizeof(actions));
+
QString platform = qApp->platformName().toLower();
if (platform == QLatin1Literal("eglfs"))
m_ui2Enabled = true;
@@ -159,12 +161,31 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
{
+ Q_ASSERT(m_profileInitialized);
m_profile->d_ptr->removeWebContentsAdapterClient(this);
adapter->stopFinding();
if (faviconProvider)
faviconProvider->detach(q_ptr);
}
+void QQuickWebEngineViewPrivate::initializeProfile()
+{
+ if (!m_profileInitialized) {
+ Q_ASSERT(!adapter->isInitialized());
+ m_profileInitialized = true;
+ if (!m_profile)
+ m_profile = QQuickWebEngineProfile::defaultProfile();
+ m_profile->d_ptr->addWebContentsAdapterClient(this);
+ m_settings.reset(new QQuickWebEngineSettings(m_profile->settings()));
+ adapter->setClient(this);
+ }
+}
+
+bool QQuickWebEngineViewPrivate::profileInitialized() const
+{
+ return m_profileInitialized;
+}
+
void QQuickWebEngineViewPrivate::destroy()
{
// the profile for this web contens is about to be
@@ -327,7 +348,6 @@ void QQuickWebEngineViewPrivate::urlChanged(const QUrl &url)
{
Q_Q(QQuickWebEngineView);
Q_UNUSED(url);
- explicitUrl = QUrl();
Q_EMIT q->urlChanged();
}
@@ -452,9 +472,8 @@ void QQuickWebEngineViewPrivate::loadFinished(bool success, const QUrl &url, boo
return;
}
if (success) {
- explicitUrl = QUrl();
- QTimer::singleShot(0, q, [q, url]() {
- QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus);
+ QTimer::singleShot(0, q, [q, url, errorDescription, errorCode]() {
+ QQuickWebEngineLoadRequest loadRequest(url, QQuickWebEngineView::LoadSucceededStatus, errorDescription, errorCode);
emit q->loadingChanged(&loadRequest);
});
return;
@@ -753,8 +772,6 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
{
Q_D(QQuickWebEngineView);
d->q_ptr = this;
- d->adapter->setClient(d);
-
this->setActiveFocusOnTab(true);
this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsDrops);
}
@@ -765,9 +782,12 @@ QQuickWebEngineView::~QQuickWebEngineView()
void QQuickWebEngineViewPrivate::ensureContentsAdapter()
{
+ initializeProfile();
if (!adapter->isInitialized()) {
- if (explicitUrl.isValid())
- adapter->load(explicitUrl);
+ if (!m_html.isEmpty())
+ adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url);
+ else if (m_url.isValid())
+ adapter->load(m_url);
else
adapter->loadDefault();
}
@@ -777,14 +797,21 @@ void QQuickWebEngineViewPrivate::initializationFinished()
{
Q_Q(QQuickWebEngineView);
- if (m_backgroundColor != Qt::white)
- adapter->backgroundColorChanged();
+ Q_ASSERT(m_profileInitialized);
+ if (m_backgroundColor != Qt::white) {
+ adapter->setBackgroundColor(m_backgroundColor);
+ emit q->backgroundColorChanged();
+ }
+
+ if (!qFuzzyCompare(adapter->currentZoomFactor(), m_zoomFactor)) {
+ adapter->setZoomFactor(m_zoomFactor);
+ emit q->zoomFactorChanged(m_zoomFactor);
+ }
+
#if QT_CONFIG(webengine_webchannel)
if (m_webChannel)
adapter->setWebChannel(m_webChannel, m_webChannelWorld);
#endif
- if (!qFuzzyCompare(adapter->currentZoomFactor(), m_defaultZoomFactor))
- q->setZoomFactor(m_defaultZoomFactor);
if (devToolsView && devToolsView->d_ptr->adapter)
adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
@@ -855,20 +882,25 @@ void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction act
QUrl QQuickWebEngineView::url() const
{
Q_D(const QQuickWebEngineView);
- return d->explicitUrl.isValid() ? d->explicitUrl : d->adapter->activeUrl();
+ if (d->adapter->isInitialized())
+ return d->adapter->activeUrl();
+ else
+ return d->m_url;
}
void QQuickWebEngineView::setUrl(const QUrl& url)
{
+ Q_D(QQuickWebEngineView);
if (url.isEmpty())
return;
- Q_D(QQuickWebEngineView);
- d->explicitUrl = url;
- if (d->adapter->isInitialized())
+ if (d->adapter->isInitialized()) {
d->adapter->load(url);
- if (!qmlEngine(this) || isComponentComplete())
- d->ensureContentsAdapter();
+ return;
+ }
+
+ d->m_url = url;
+ d->m_html.clear();
}
QUrl QQuickWebEngineView::icon() const
@@ -880,11 +912,12 @@ QUrl QQuickWebEngineView::icon() const
void QQuickWebEngineView::loadHtml(const QString &html, const QUrl &baseUrl)
{
Q_D(QQuickWebEngineView);
- d->explicitUrl = QUrl();
- if (!qmlEngine(this) || isComponentComplete())
- d->ensureContentsAdapter();
- if (d->adapter->isInitialized())
- d->adapter->setContent(html.toUtf8(), QStringLiteral("text/html;charset=UTF-8"), baseUrl);
+ d->m_url = baseUrl;
+ d->m_html = html;
+ if (d->adapter->isInitialized()) {
+ d->adapter->setContent(html.toUtf8(), defaultMimeType, baseUrl);
+ return;
+ }
}
void QQuickWebEngineView::goBack()
@@ -920,31 +953,48 @@ void QQuickWebEngineView::stop()
void QQuickWebEngineView::setZoomFactor(qreal arg)
{
Q_D(QQuickWebEngineView);
- d->m_defaultZoomFactor = arg;
-
- qreal oldFactor = d->adapter->currentZoomFactor();
- d->adapter->setZoomFactor(arg);
- if (qFuzzyCompare(oldFactor, d->adapter->currentZoomFactor()))
- return;
-
- emit zoomFactorChanged(arg);
+ if (d->adapter->isInitialized() && !qFuzzyCompare(d->m_zoomFactor, d->adapter->currentZoomFactor())) {
+ d->adapter->setZoomFactor(arg);
+ emit zoomFactorChanged(arg);
+ } else {
+ d->m_zoomFactor = arg;
+ }
}
-QQuickWebEngineProfile *QQuickWebEngineView::profile() const
+QQuickWebEngineProfile *QQuickWebEngineView::profile()
{
- Q_D(const QQuickWebEngineView);
+ Q_D(QQuickWebEngineView);
+ d->initializeProfile();
return d->m_profile;
}
void QQuickWebEngineView::setProfile(QQuickWebEngineProfile *profile)
{
Q_D(QQuickWebEngineView);
- d->setProfile(profile);
+
+ if (d->m_profile == profile)
+ return;
+
+ if (!d->profileInitialized()) {
+ d->m_profile = profile;
+ return;
+ }
+
+ if (d->m_profile)
+ d->m_profile->d_ptr->removeWebContentsAdapterClient(d);
+
+ d->m_profile = profile;
+ d->m_profile->d_ptr->addWebContentsAdapterClient(d);
+ d->m_settings->setParentSettings(profile->settings());
+
+ d->updateAdapter();
+ Q_EMIT profileChanged();
}
-QQuickWebEngineSettings *QQuickWebEngineView::settings() const
+QQuickWebEngineSettings *QQuickWebEngineView::settings()
{
- Q_D(const QQuickWebEngineView);
+ Q_D(QQuickWebEngineView);
+ d->initializeProfile();
return d->m_settings.data();
}
@@ -958,32 +1008,22 @@ QQmlListProperty<QQuickWebEngineScript> QQuickWebEngineView::userScripts()
d->userScripts_clear);
}
-void QQuickWebEngineViewPrivate::setProfile(QQuickWebEngineProfile *profile)
+void QQuickWebEngineViewPrivate::updateAdapter()
{
- Q_Q(QQuickWebEngineView);
-
- if (profile == m_profile)
- return;
- m_profile->d_ptr->removeWebContentsAdapterClient(this);
- m_profile = profile;
- m_profile->d_ptr->addWebContentsAdapterClient(this);
- Q_EMIT q->profileChanged();
- m_settings->setParentSettings(profile->settings());
-
- if (adapter->profile() != profileAdapter()->profile()) {
- // When the profile changes we need to create a new WebContentAdapter and reload the active URL.
- bool wasInitialized = adapter->isInitialized();
- QUrl activeUrl = adapter->activeUrl();
- adapter = QSharedPointer<WebContentsAdapter>::create();
- adapter->setClient(this);
- if (wasInitialized) {
- if (explicitUrl.isValid())
- adapter->load(explicitUrl);
- else if (activeUrl.isValid())
- adapter->load(activeUrl);
- else
- adapter->loadDefault();
- }
+ // When the profile changes we need to create a new WebContentAdapter and reload the active URL.
+ bool wasInitialized = adapter->isInitialized();
+ QUrl activeUrl = adapter->activeUrl();
+ adapter = QSharedPointer<WebContentsAdapter>::create();
+ adapter->setClient(this);
+ if (wasInitialized) {
+ if (!m_html.isEmpty())
+ adapter->setContent(m_html.toUtf8(), defaultMimeType, m_url);
+ else if (m_url.isValid())
+ adapter->load(m_url);
+ else if (activeUrl.isValid())
+ adapter->load(activeUrl);
+ else
+ adapter->loadDefault();
}
}
@@ -1148,7 +1188,7 @@ qreal QQuickWebEngineView::zoomFactor() const
{
Q_D(const QQuickWebEngineView);
if (!d->adapter->isInitialized())
- return d->m_defaultZoomFactor;
+ return d->m_zoomFactor;
return d->adapter->currentZoomFactor();
}
@@ -1164,8 +1204,10 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color)
if (color == d->m_backgroundColor)
return;
d->m_backgroundColor = color;
- d->adapter->backgroundColorChanged();
- emit backgroundColorChanged();
+ if (d->adapter->isInitialized()) {
+ d->adapter->setBackgroundColor(color);
+ emit backgroundColorChanged();
+ }
}
/*!
@@ -1281,9 +1323,7 @@ QQmlWebChannel *QQuickWebEngineView::webChannel()
Q_D(QQuickWebEngineView);
if (!d->m_webChannel) {
d->m_webChannel = new QQmlWebChannel(this);
- d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld);
}
-
return d->m_webChannel;
#endif
qWarning("WebEngine compiled without webchannel support");
@@ -1297,7 +1337,8 @@ void QQuickWebEngineView::setWebChannel(QQmlWebChannel *webChannel)
if (d->m_webChannel == webChannel)
return;
d->m_webChannel = webChannel;
- d->adapter->setWebChannel(webChannel, d->m_webChannelWorld);
+ if (d->profileInitialized())
+ d->adapter->setWebChannel(webChannel, d->m_webChannelWorld);
Q_EMIT webChannelChanged();
#else
Q_UNUSED(webChannel)
@@ -1318,7 +1359,8 @@ void QQuickWebEngineView::setWebChannelWorld(uint webChannelWorld)
if (d->m_webChannelWorld == webChannelWorld)
return;
d->m_webChannelWorld = webChannelWorld;
- d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld);
+ if (d->profileInitialized())
+ d->adapter->setWebChannel(d->m_webChannel, d->m_webChannelWorld);
Q_EMIT webChannelWorldChanged(webChannelWorld);
#else
Q_UNUSED(webChannelWorld)
@@ -1353,6 +1395,7 @@ QQuickWebEngineView *QQuickWebEngineView::devToolsView() const
return d->devToolsView;
}
+
void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView)
{
Q_D(QQuickWebEngineView);
@@ -1365,7 +1408,7 @@ void QQuickWebEngineView::setDevToolsView(QQuickWebEngineView *devToolsView)
d->devToolsView = devToolsView;
if (devToolsView)
devToolsView->setInspectedView(this);
- if (d->adapter->isInitialized()) {
+ if (d->profileInitialized() && d->adapter->isInitialized()) {
if (devToolsView)
d->adapter->openDevToolsFrontend(devToolsView->d_ptr->adapter);
else
@@ -1452,7 +1495,8 @@ void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRect
void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickWebEngineView);
- if (d && d->adapter->isInitialized() && (change == ItemSceneChange || change == ItemVisibleHasChanged)) {
+ if (d && d->profileInitialized() && d->adapter->isInitialized()
+ && (change == ItemSceneChange || change == ItemVisibleHasChanged)) {
if (window() && isVisible())
d->adapter->wasShown();
else
@@ -1497,7 +1541,7 @@ void QQuickWebEngineView::dropEvent(QDropEvent *e)
{
Q_D(QQuickWebEngineView);
e->accept();
- d->adapter->endDragging(e->pos(), mapToScreen(this, e->pos()));
+ d->adapter->endDragging(e, mapToScreen(this, e->pos()));
}
#endif // QT_CONFIG(draganddrop)
@@ -1929,7 +1973,8 @@ void QQuickWebEngineViewPrivate::userScripts_clear(QQmlListProperty<QQuickWebEng
void QQuickWebEngineView::componentComplete()
{
QQuickItem::componentComplete();
-
+ Q_D(QQuickWebEngineView);
+ d->initializeProfile();
#ifndef QT_NO_ACCESSIBILITY
// Enable accessibility via a dynamic QQmlProperty, instead of using private API call
// QQuickAccessibleAttached::qmlAttachedProperties(this). The qmlContext is required, otherwise
diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index f60fdcddf..ae92b6df0 100644
--- a/src/webengine/api/qquickwebengineview_p.h
+++ b/src/webengine/api/qquickwebengineview_p.h
@@ -461,11 +461,11 @@ public:
// QmlParserStatus
void componentComplete() override;
- QQuickWebEngineProfile *profile() const;
+ QQuickWebEngineProfile *profile();
void setProfile(QQuickWebEngineProfile *);
QQmlListProperty<QQuickWebEngineScript> userScripts();
- QQuickWebEngineSettings *settings() const;
+ QQuickWebEngineSettings *settings();
QQmlWebChannel *webChannel();
void setWebChannel(QQmlWebChannel *);
QQuickWebEngineHistory *navigationHistory() const;
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index b030b2a29..ee38ece6b 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -90,7 +90,7 @@ public:
QQuickWebEngineViewPrivate();
~QQuickWebEngineViewPrivate();
void destroy();
-
+ void initializeProfile();
QtWebEngineCore::UIDelegatesManager *ui();
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
@@ -160,6 +160,7 @@ public:
void updateAction(QQuickWebEngineView::WebAction) const;
void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
void setProfile(QQuickWebEngineProfile *profile);
+ void updateAdapter();
void ensureContentsAdapter();
void setFullScreenMode(bool);
@@ -178,7 +179,8 @@ public:
#endif
QQmlComponent *contextMenuExtraItems;
QtWebEngineCore::WebEngineContextMenuData m_contextMenuData;
- QUrl explicitUrl;
+ QUrl m_url;
+ QString m_html;
QUrl iconUrl;
QQuickWebEngineFaviconProvider *faviconProvider;
int loadProgress;
@@ -196,13 +198,16 @@ public:
bool m_isBeingAdopted;
mutable QQuickWebEngineAction *actions[QQuickWebEngineView::WebActionCount];
+ bool profileInitialized() const;
+
private:
QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
QList<QQuickWebEngineScript *> m_userScripts;
qreal m_dpiScale;
QColor m_backgroundColor;
- qreal m_defaultZoomFactor;
+ qreal m_zoomFactor;
bool m_ui2Enabled;
+ bool m_profileInitialized;
};
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/webengine/doc/src/qtwebengine-module.qdoc b/src/webengine/doc/src/qtwebengine-module.qdoc
index 97657f6a9..2d4d1b8da 100644
--- a/src/webengine/doc/src/qtwebengine-module.qdoc
+++ b/src/webengine/doc/src/qtwebengine-module.qdoc
@@ -38,7 +38,9 @@
\snippet qtwebengine_build_snippet.qdoc 1
+ \if !defined(qtforpython)
To link against the module, add the following to your qmake project file:
\snippet qtwebengine_build_snippet.qdoc 0
+ \endif
*/
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 403cdf330..6c8703fe4 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -73,7 +73,7 @@
\section2 Linux
- On Linux, Clang or GCC version 4.7 or later is required.
+ On Linux, Clang or GCC version 5 or later is required.
Supported configurations are \c linux-g++ and \c{linux-clang}.
Qt WebEngine requires \c pkg-config to detect most of its dependencies. The
diff --git a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
index 1c6cb53c7..17c29a126 100644
--- a/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
+++ b/src/webengine/doc/src/qtwebengine-qmlmodule.qdoc
@@ -26,7 +26,7 @@
****************************************************************************/
/*!
- \qmlmodule QtWebEngine 1.7
+ \qmlmodule QtWebEngine 1.8
\title Qt WebEngine QML Types
\brief Provides QML types for rendering web content within a QML application
\ingroup qtwebengine-modules
@@ -36,7 +36,7 @@
your .qml file:
\badcode
- import QtWebEngine 1.7
+ import QtWebEngine 1.8
\endcode
To link against the module, add the following QT variable to your qmake .pro
diff --git a/src/webengine/doc/src/webengineview_lgpl.qdoc b/src/webengine/doc/src/webengineview_lgpl.qdoc
index cc826a0d9..87094c266 100644
--- a/src/webengine/doc/src/webengineview_lgpl.qdoc
+++ b/src/webengine/doc/src/webengineview_lgpl.qdoc
@@ -365,7 +365,7 @@
\since QtWebEngine 1.3
JavaScript world that the web channel instance used by this view is
- installed in.
+ installed in. The world must be a number between \c 0 and \c 256.
*/
/*!
diff --git a/src/webengine/plugin/plugin.pro b/src/webengine/plugin/plugin.pro
index 0bbe83c26..b6652fa26 100644
--- a/src/webengine/plugin/plugin.pro
+++ b/src/webengine/plugin/plugin.pro
@@ -1,7 +1,7 @@
CXX_MODULE = qml
TARGET = qtwebengineplugin
TARGETPATH = QtWebEngine
-IMPORT_VERSION = 1.7
+IMPORT_VERSION = 1.8
QT += webengine qml quick
QT_PRIVATE += core-private webenginecore-private webengine-private
diff --git a/src/webengine/plugin/plugins.qmltypes b/src/webengine/plugin/plugins.qmltypes
index 44c85bd8e..a17bcfbab 100644
--- a/src/webengine/plugin/plugins.qmltypes
+++ b/src/webengine/plugin/plugins.qmltypes
@@ -20,14 +20,6 @@ Module {
Signal { name: "toggled" }
Signal { name: "triggered" }
Signal {
- name: "textChanged"
- Parameter { name: "text"; type: "string" }
- }
- Signal {
- name: "iconTextChanged"
- Parameter { name: "iconText"; type: "string" }
- }
- Signal {
name: "enabledChanged"
Parameter { name: "enabled"; type: "bool" }
}
@@ -180,10 +172,11 @@ Module {
"QtWebEngine/WebEngineDownloadItem 1.4",
"QtWebEngine/WebEngineDownloadItem 1.5",
"QtWebEngine/WebEngineDownloadItem 1.6",
- "QtWebEngine/WebEngineDownloadItem 1.7"
+ "QtWebEngine/WebEngineDownloadItem 1.7",
+ "QtWebEngine/WebEngineDownloadItem 1.8"
]
isCreatable: false
- exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6]
+ exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7]
Enum {
name: "DownloadState"
values: {
@@ -259,6 +252,13 @@ Module {
Property { name: "isFinished"; revision: 5; type: "bool"; isReadonly: true }
Property { name: "isPaused"; revision: 5; type: "bool"; isReadonly: true }
Property { name: "isSavePageDownload"; revision: 6; type: "bool"; isReadonly: true }
+ Property {
+ name: "view"
+ revision: 7
+ type: "QQuickWebEngineView"
+ isReadonly: true
+ isPointer: true
+ }
Signal { name: "savePageFormatChanged"; revision: 2 }
Signal { name: "mimeTypeChanged"; revision: 1 }
Signal { name: "typeChanged"; revision: 3 }
@@ -579,10 +579,11 @@ Module {
"QtWebEngine/WebEngineSettings 1.4",
"QtWebEngine/WebEngineSettings 1.5",
"QtWebEngine/WebEngineSettings 1.6",
- "QtWebEngine/WebEngineSettings 1.7"
+ "QtWebEngine/WebEngineSettings 1.7",
+ "QtWebEngine/WebEngineSettings 1.8"
]
isCreatable: false
- exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6]
+ exportMetaObjectRevisions: [0, 1, 2, 3, 4, 5, 6, 7]
Enum {
name: "UnknownUrlSchemePolicy"
values: {
@@ -620,6 +621,7 @@ Module {
Property { name: "playbackRequiresUserGesture"; revision: 6; type: "bool" }
Property { name: "webRTCPublicInterfacesOnly"; revision: 6; type: "bool" }
Property { name: "javascriptCanPaste"; revision: 6; type: "bool" }
+ Property { name: "dnsPrefetchEnabled"; revision: 7; type: "bool" }
Signal { name: "fullScreenSupportEnabledChanged"; revision: 1 }
Signal { name: "screenCaptureEnabledChanged"; revision: 2 }
Signal { name: "webGLEnabledChanged"; revision: 2 }
@@ -636,6 +638,7 @@ Module {
Signal { name: "playbackRequiresUserGestureChanged"; revision: 6 }
Signal { name: "webRTCPublicInterfacesOnlyChanged"; revision: 6 }
Signal { name: "javascriptCanPasteChanged"; revision: 6 }
+ Signal { name: "dnsPrefetchEnabledChanged"; revision: 7 }
}
Component {
name: "QQuickWebEngineSingleton"
@@ -1132,6 +1135,7 @@ Module {
revision: 7
Parameter { name: "request"; type: "QWebEngineRegisterProtocolHandlerRequest" }
}
+ Signal { name: "printRequested"; revision: 8 }
Method {
name: "runJavaScript"
Parameter { type: "string" }
diff --git a/src/webenginewidgets/api/qwebengineclientcertselection.cpp b/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp
index de1e101f6..8b5f49d6b 100644
--- a/src/webenginewidgets/api/qwebengineclientcertselection.cpp
+++ b/src/webenginewidgets/api/qwebengineclientcertificateselection.cpp
@@ -37,7 +37,7 @@
**
****************************************************************************/
-#include "qwebengineclientcertselection.h"
+#include "qwebengineclientcertificateselection.h"
#if QT_CONFIG(ssl)
@@ -46,12 +46,12 @@
QT_BEGIN_NAMESPACE
/*!
- \class QWebEngineClientCertSelection
+ \class QWebEngineClientCertificateSelection
\brief The QWebEngineClientCertSelection class wraps a client certificate selection.
\since 5.12
\inmodule QtWebEngineWidgets
- Provides access to the certicates to choose from, and a method for selecting one.
+ Provides access to the certificates to choose from, and a method for selecting one.
The selection is asynchronous. If no certificate is selected and no copy of the
object is kept alive, loading will continue without a certificate.
@@ -59,21 +59,21 @@ QT_BEGIN_NAMESPACE
/*! \internal
*/
-QWebEngineClientCertSelection::QWebEngineClientCertSelection(QSharedPointer<ClientCertSelectController> selectController)
+QWebEngineClientCertificateSelection::QWebEngineClientCertificateSelection(QSharedPointer<ClientCertSelectController> selectController)
: d_ptr(selectController)
{}
-QWebEngineClientCertSelection::QWebEngineClientCertSelection(const QWebEngineClientCertSelection &other)
+QWebEngineClientCertificateSelection::QWebEngineClientCertificateSelection(const QWebEngineClientCertificateSelection &other)
: d_ptr(other.d_ptr)
{}
-QWebEngineClientCertSelection &QWebEngineClientCertSelection::operator=(const QWebEngineClientCertSelection &other)
+QWebEngineClientCertificateSelection &QWebEngineClientCertificateSelection::operator=(const QWebEngineClientCertificateSelection &other)
{
d_ptr = other.d_ptr;
return *this;
}
-QWebEngineClientCertSelection::~QWebEngineClientCertSelection()
+QWebEngineClientCertificateSelection::~QWebEngineClientCertificateSelection()
{
}
@@ -82,7 +82,7 @@ QWebEngineClientCertSelection::~QWebEngineClientCertSelection()
\sa select()
*/
-QVector<QSslCertificate> QWebEngineClientCertSelection::certificates() const
+QVector<QSslCertificate> QWebEngineClientCertificateSelection::certificates() const
{
return d_ptr->certificates();
}
@@ -93,7 +93,7 @@ QVector<QSslCertificate> QWebEngineClientCertSelection::certificates() const
\sa certificates(), selectNone()
*/
-void QWebEngineClientCertSelection::select(const QSslCertificate &certificate)
+void QWebEngineClientCertificateSelection::select(const QSslCertificate &certificate)
{
d_ptr->select(certificate);
}
@@ -105,7 +105,7 @@ void QWebEngineClientCertSelection::select(const QSslCertificate &certificate)
\sa select()
*/
-void QWebEngineClientCertSelection::selectNone()
+void QWebEngineClientCertificateSelection::selectNone()
{
d_ptr->selectNone();
}
@@ -113,7 +113,7 @@ void QWebEngineClientCertSelection::selectNone()
/*!
Returns the host and port of the server requesting the client certificate.
*/
-QUrl QWebEngineClientCertSelection::host() const
+QUrl QWebEngineClientCertificateSelection::host() const
{
return d_ptr->hostAndPort();
}
diff --git a/src/webenginewidgets/api/qwebengineclientcertselection.h b/src/webenginewidgets/api/qwebengineclientcertificateselection.h
index 84de56a67..15b8a47c6 100644
--- a/src/webenginewidgets/api/qwebengineclientcertselection.h
+++ b/src/webenginewidgets/api/qwebengineclientcertificateselection.h
@@ -45,19 +45,19 @@
#if QT_CONFIG(ssl)
-#include <QtCore/QScopedPointer>
-#include <QtCore/QVector>
-#include <QtNetwork/QSslCertificate>
+#include <QtCore/qscopedpointer.h>
+#include <QtCore/qvector.h>
+#include <QtNetwork/qsslcertificate.h>
QT_BEGIN_NAMESPACE
class ClientCertSelectController;
-class QWEBENGINEWIDGETS_EXPORT QWebEngineClientCertSelection {
+class QWEBENGINEWIDGETS_EXPORT QWebEngineClientCertificateSelection {
public:
- QWebEngineClientCertSelection(const QWebEngineClientCertSelection &);
- ~QWebEngineClientCertSelection();
+ QWebEngineClientCertificateSelection(const QWebEngineClientCertificateSelection &);
+ ~QWebEngineClientCertificateSelection();
- QWebEngineClientCertSelection &operator=(const QWebEngineClientCertSelection &);
+ QWebEngineClientCertificateSelection &operator=(const QWebEngineClientCertificateSelection &);
QUrl host() const;
@@ -68,7 +68,7 @@ public:
private:
friend class QWebEnginePagePrivate;
- QWebEngineClientCertSelection(QSharedPointer<ClientCertSelectController>);
+ QWebEngineClientCertificateSelection(QSharedPointer<ClientCertSelectController>);
QSharedPointer<ClientCertSelectController> d_ptr;
};
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 6a4554b57..3d8f9389a 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -281,7 +281,7 @@ RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostVie
void QWebEnginePagePrivate::initializationFinished()
{
if (m_backgroundColor != Qt::white)
- adapter->backgroundColorChanged();
+ adapter->setBackgroundColor(m_backgroundColor);
#if QT_CONFIG(webengine_webchannel)
if (webChannel)
adapter->setWebChannel(webChannel, webChannelWorldId);
@@ -902,7 +902,7 @@ QWebEnginePage::~QWebEnginePage()
Q_D(QWebEnginePage);
setDevToolsPage(nullptr);
d->adapter->stopFinding();
- QWebEngineViewPrivate::bind(d->view, 0);
+ QWebEngineViewPrivate::bind(nullptr, this, true);
}
QWebEngineHistory *QWebEnginePage::history() const
@@ -1007,7 +1007,7 @@ void QWebEnginePage::setBackgroundColor(const QColor &color)
if (d->m_backgroundColor == color)
return;
d->m_backgroundColor = color;
- d->adapter->backgroundColorChanged();
+ d->adapter->setBackgroundColor(color);
}
/*!
@@ -1679,7 +1679,7 @@ void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSele
{
#if QT_CONFIG(ssl)
Q_Q(QWebEnginePage);
- QWebEngineClientCertSelection certSelection(controller);
+ QWebEngineClientCertificateSelection certSelection(controller);
Q_EMIT q->selectClientCertificate(certSelection);
#else
@@ -1689,19 +1689,19 @@ void QWebEnginePagePrivate::selectClientCert(const QSharedPointer<ClientCertSele
#if QT_CONFIG(ssl)
/*!
- \fn void QWebEnginePage::selectClientCertificate(QWebEngineClientCertSelection clientCertSelection)
+ \fn void QWebEnginePage::selectClientCertificate(QWebEngineClientCertificateSelection clientCertificateSelection)
\since 5.12
This signal is emitted when a web site requests an SSL client certificate, and one or more were
found in system's client certificate store.
Handling the signal is asynchronous, and loading will be waiting until a certificate is selected,
- or the last copy of \a clientCertSelection is destroyed.
+ or the last copy of \a clientCertificateSelection is destroyed.
- If the signal is not handled, \a clientCertSelection is automatically destroyed, and loading
+ If the signal is not handled, \a clientCertificateSelection is automatically destroyed, and loading
will continue without a client certificate.
- \sa QWebEngineClientCertSelection
+ \sa QWebEngineClientCertificateSelection
*/
#endif
@@ -2365,6 +2365,11 @@ void QWebEnginePage::printToPdf(const QWebEngineCallback<const QByteArray&> &res
It is the users responsibility to ensure the \a printer remains valid until \a resultCallback
has been called.
+ \note The rendering of the current content into a temporary PDF document is asynchronous and does
+ not block the main thread. However, the subsequent rendering of PDF into \a printer runs on the
+ main thread and will therefore block the event loop. Moreover, printing runs on the browser
+ process, which is by default not sandboxed.
+
The \a resultCallback must take a boolean as parameter. If printing was successful, this
boolean will have the value \c true, otherwise, its value will be \c false.
\since 5.8
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index b8bf61700..6dd2da21c 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -41,7 +41,7 @@
#define QWEBENGINEPAGE_H
#include <QtWebEngineWidgets/qtwebenginewidgetsglobal.h>
-#include <QtWebEngineWidgets/qwebengineclientcertselection.h>
+#include <QtWebEngineWidgets/qwebengineclientcertificateselection.h>
#include <QtWebEngineWidgets/qwebenginedownloaditem.h>
#include <QtWebEngineCore/qwebenginecallback.h>
#include <QtWebEngineCore/qwebenginehttprequest.h>
@@ -60,7 +60,7 @@ class QPrinter;
class QContextMenuBuilder;
class QWebChannel;
class QWebEngineCertificateError;
-class QWebEngineClientCertSelection;
+class QWebEngineClientCertificateSelection;
class QWebEngineContextMenuData;
class QWebEngineFullScreenRequest;
class QWebEngineHistory;
@@ -323,7 +323,7 @@ Q_SIGNALS:
void quotaRequested(QWebEngineQuotaRequest quotaRequest);
void registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request);
#if QT_CONFIG(ssl)
- void selectClientCertificate(QWebEngineClientCertSelection clientCertSelection);
+ void selectClientCertificate(QWebEngineClientCertificateSelection clientCertSelection);
#endif
void authenticationRequired(const QUrl &requestUrl, QAuthenticator *authenticator);
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index b66a1aa53..b2fe49da3 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -682,7 +682,7 @@ static bool checkInternalScheme(const QByteArray &scheme)
Registers a handler \a handler for custom URL scheme \a scheme in the profile.
It is recommended to first register the scheme with \l
- QWebEngineUrlScheme::addScheme at application startup.
+ QWebEngineUrlScheme::registerScheme at application startup.
*/
void QWebEngineProfile::installUrlSchemeHandler(const QByteArray &scheme, QWebEngineUrlSchemeHandler *handler)
{
diff --git a/src/webenginewidgets/api/qwebenginescript.cpp b/src/webenginewidgets/api/qwebenginescript.cpp
index d5247cde1..d1e996b3a 100644
--- a/src/webenginewidgets/api/qwebenginescript.cpp
+++ b/src/webenginewidgets/api/qwebenginescript.cpp
@@ -224,6 +224,8 @@ quint32 QWebEngineScript::worldId() const
/*!
Sets the world ID of the isolated world to \a id when running this script.
+
+ Must be between \c 0 and \c 256.
*/
void QWebEngineScript::setWorldId(quint32 id)
{
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 369c6b02b..aa51e5b0e 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -55,7 +55,7 @@
QT_BEGIN_NAMESPACE
-void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
+void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page, bool pageBeingDeleted)
{
if (view && page == view->d_func()->page)
return;
@@ -64,20 +64,22 @@ void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
// Un-bind page from its current view.
if (QWebEngineView *oldView = page->d_func()->view) {
page->disconnect(oldView);
- oldView->d_func()->page = 0;
+ oldView->d_func()->page = nullptr;
}
page->d_func()->view = view;
- page->d_func()->adapter->reattachRWHV();
+ if (!pageBeingDeleted)
+ page->d_func()->adapter->reattachRWHV();
}
if (view) {
// Un-bind view from its current page.
if (QWebEnginePage *oldPage = view->d_func()->page) {
oldPage->disconnect(view);
- oldPage->d_func()->view = 0;
- oldPage->d_func()->adapter->reattachRWHV();
+ oldPage->d_func()->view = nullptr;
if (oldPage->parent() == view)
delete oldPage;
+ else
+ oldPage->d_func()->adapter->reattachRWHV();
}
view->d_func()->page = page;
}
@@ -147,8 +149,7 @@ QWebEngineView::QWebEngineView(QWidget *parent)
QWebEngineView::~QWebEngineView()
{
- Q_D(QWebEngineView);
- QWebEngineViewPrivate::bind(0, d->page);
+ QWebEngineViewPrivate::bind(this, nullptr);
}
QWebEnginePage* QWebEngineView::page() const
@@ -423,7 +424,7 @@ void QWebEngineView::dropEvent(QDropEvent *e)
if (!d->m_dragEntered)
return;
e->accept();
- d->page->d_ptr->adapter->endDragging(e->pos(), mapToGlobal(e->pos()));
+ d->page->d_ptr->adapter->endDragging(e, mapToGlobal(e->pos()));
d->m_dragEntered = false;
}
#endif // QT_CONFIG(draganddrop)
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index 7f0cdac45..bfb44bec5 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -65,7 +65,7 @@ public:
Q_DECLARE_PUBLIC(QWebEngineView)
QWebEngineView *q_ptr;
- static void bind(QWebEngineView *view, QWebEnginePage *page);
+ static void bind(QWebEngineView *view, QWebEnginePage *page, bool pageBeingDeleted = false);
QWebEngineViewPrivate();
diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
index e4f259882..35fed802c 100644
--- a/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
+++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-module.qdoc
@@ -41,7 +41,9 @@
\snippet qtwebenginewidgets_build_snippet.qdoc 1
+ \if !defined(qtforpython)
To link against the module, add the following to your qmake project file:
\snippet qtwebenginewidgets_build_snippet.qdoc 0
+ \endif
*/
diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
index 3013903c8..f91b71ea1 100644
--- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
+++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc
@@ -718,9 +718,9 @@
\since 5.7
Runs the JavaScript code contained in \a scriptSource in the world specified by \a worldId.
- The world ID values are the same as provided by QWebEngineScript::ScriptWorldId. Using the
- \e runJavaScript() versions without the world ID is the same as running the script in the
- \c MainWorld.
+ The world ID values are the same as provided by QWebEngineScript::ScriptWorldId, and between \c 0
+ and \c 256. Using the \e runJavaScript() versions without the world ID is the same as running the
+ script in the \c MainWorld.
When the script has been executed, \a resultCallback is called with the result of the last
executed statement. \c resultCallback can be any of a function pointer, a functor or a lambda,
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 9497ba0fa..d7bcd0ae3 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -218,20 +218,24 @@ void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect)
// to be destroyed.
setAttribute(Qt::WA_ShowWithoutActivating);
setFocusPolicy(Qt::NoFocus);
-
-#ifdef Q_OS_MACOS
- // macOS doesn't like Qt::ToolTip when QWebEngineView is inside a modal dialog, specifically by
- // not forwarding click events to the popup. So we use Qt::Tool which behaves the same way, but
- // works on macOS too.
- setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
-#else
- setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
-#endif
+ setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
setGeometry(screenRect);
show();
}
+void RenderWidgetHostViewQtDelegateWidget::closeEvent(QCloseEvent *event)
+{
+ Q_UNUSED(event);
+
+ // If a close event was received from the window manager (e.g. when moving the parent window,
+ // clicking outside the popup area)
+ // make sure to notify the Chromium WebUI popup and its underlying
+ // RenderWidgetHostViewQtDelegate instance to be closed.
+ if (m_isPopup)
+ m_client->closePopup();
+}
+
QRectF RenderWidgetHostViewQtDelegateWidget::screenRect() const
{
return QRectF(x(), y(), width(), height());
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 79958132c..42b454bc5 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -48,6 +48,12 @@
namespace QtWebEngineCore {
+// Useful information keyboard and mouse QEvent propagation.
+// A RenderWidgetHostViewQtDelegateWidget instance initialized as a popup will receive
+// no keyboard focus (so all keyboard QEvents will be sent to the parent RWHVQD instance),
+// but will still receive mouse input (all mouse QEvent moves and clicks will be given to the popup
+// RWHVQD instance, and the mouse interaction area covers the surface of the whole parent
+// QWebEngineView, and not only the smaller surface that an HTML select popup would occupy).
class RenderWidgetHostViewQtDelegateWidget : public QQuickWidget, public RenderWidgetHostViewQtDelegate {
Q_OBJECT
public:
@@ -83,6 +89,7 @@ protected:
void resizeEvent(QResizeEvent *resizeEvent) override;
void showEvent(QShowEvent *) override;
void hideEvent(QHideEvent *) override;
+ void closeEvent(QCloseEvent *event) override;
QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index 1e24f35e9..e61575d3a 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -14,7 +14,7 @@ INCLUDEPATH += $$PWD api ../core ../core/api ../webengine/api
SOURCES = \
api/qtwebenginewidgetsglobal.cpp \
api/qwebenginecertificateerror.cpp \
- api/qwebengineclientcertselection.cpp \
+ api/qwebengineclientcertificateselection.cpp \
api/qwebenginecontextmenudata.cpp \
api/qwebenginedownloaditem.cpp \
api/qwebenginefullscreenrequest.cpp \
@@ -30,7 +30,7 @@ SOURCES = \
HEADERS = \
api/qtwebenginewidgetsglobal.h \
api/qwebenginecertificateerror.h \
- api/qwebengineclientcertselection.h \
+ api/qwebengineclientcertificateselection.h \
api/qwebenginecontextmenudata.h \
api/qwebenginedownloaditem.h \
api/qwebenginedownloaditem_p.h \