summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-05-09 12:04:12 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-06-09 18:58:54 +0200
commit5d1ef38f9f6815807596d0606cf7ed06b7930aac (patch)
tree441c2b27eb9d169d58cb94a30ac424ebb6b42b65
parent3f5b5213d42376470274f0e3aaa51731f0d2552a (diff)
Create a RWHV delegate in core
This is adapting the Quick code for shared use with widgets, and allows us to use it from QWebEnginePage. Pick-to: 6.4 Fixes: QTBUG-96377 Change-Id: I3f09c1a949eff86d80fbe6c513dc66e3f9f2f611 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/api/qwebenginepage.cpp58
-rw-r--r--src/core/api/qwebenginepage_p.h10
-rw-r--r--src/core/render_widget_host_view_qt.cpp2
-rw-r--r--src/core/render_widget_host_view_qt_delegate.h2
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.cpp (renamed from src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp)293
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.h (renamed from src/webenginequick/render_widget_host_view_qt_delegate_quick.h)100
-rw-r--r--src/core/web_contents_delegate_qt.cpp4
-rw-r--r--src/webenginequick/CMakeLists.txt2
-rw-r--r--src/webenginequick/api/qquickwebengineview.cpp146
-rw-r--r--src/webenginequick/api/qquickwebengineview_p.h5
-rw-r--r--src/webenginequick/api/qquickwebengineview_p_p.h30
-rw-r--r--src/webenginequick/qquickwebengine_accessible.cpp186
-rw-r--r--src/webenginequick/qquickwebengine_accessible.h96
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp64
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h38
-rw-r--r--src/webenginewidgets/CMakeLists.txt2
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp371
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h30
-rw-r--r--src/webenginewidgets/qwebengine_accessible.cpp142
-rw-r--r--src/webenginewidgets/qwebengine_accessible.h88
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp542
-rw-r--r--src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h138
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp4
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp5
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp20
-rw-r--r--tests/auto/widgets/spellchecking/tst_spellchecking.cpp3
27 files changed, 1201 insertions, 1181 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e9951d187..18078ba5a 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -160,6 +160,7 @@ foreach(arch ${archs})
render_widget_host_view_qt.cpp render_widget_host_view_qt.h
render_widget_host_view_qt_delegate.h
render_widget_host_view_qt_delegate_client.cpp render_widget_host_view_qt_delegate_client.h
+ render_widget_host_view_qt_delegate_item.cpp render_widget_host_view_qt_delegate_item.h
renderer/content_renderer_client_qt.cpp renderer/content_renderer_client_qt.h
renderer/content_settings_observer_qt.cpp renderer/content_settings_observer_qt.h
renderer/render_configuration.cpp renderer/render_configuration.h
diff --git a/src/core/api/qwebenginepage.cpp b/src/core/api/qwebenginepage.cpp
index 0b3cba785..a893d5a80 100644
--- a/src/core/api/qwebenginepage.cpp
+++ b/src/core/api/qwebenginepage.cpp
@@ -67,6 +67,7 @@
#include "render_view_context_menu_qt.h"
#include "render_widget_host_view_qt_delegate.h"
#include "render_widget_host_view_qt_delegate_client.h"
+#include "render_widget_host_view_qt_delegate_item.h"
#include "web_contents_adapter.h"
#include <QAction>
@@ -84,51 +85,6 @@ QT_BEGIN_NAMESPACE
using namespace QtWebEngineCore;
-// add temporary dummy code to cover the case when page is loading and there is no view
-class DummyDelegate : public QObject, public QtWebEngineCore::RenderWidgetHostViewQtDelegate
-{
-public:
- DummyDelegate(RenderWidgetHostViewQtDelegateClient *client) : m_delegateClient(client) {};
- ~DummyDelegate() = default;
- void initAsPopup(const QRect &) override { Q_UNREACHABLE(); }
- QRectF viewGeometry() const override { return QRectF(m_pos, m_size); }
- void setKeyboardFocus() override { }
- bool hasKeyboardFocus() override { return false; }
- void lockMouse() override { Q_UNREACHABLE(); }
- void unlockMouse() override { Q_UNREACHABLE(); }
- void show() override { m_delegateClient->notifyShown(); }
- void hide() override { m_delegateClient->notifyHidden(); }
- bool isVisible() const override { Q_UNREACHABLE(); }
- QWindow *window() const override { return nullptr; }
- void updateCursor(const QCursor &cursor) override
- {
- Q_UNUSED(cursor);
- /*setCursor(cursor);*/
- }
- void resize(int width, int height) override
- {
- m_size = QSize(width, height);
- m_delegateClient->visualPropertiesChanged();
- }
- void move(const QPoint &) override { Q_UNREACHABLE(); }
- void inputMethodStateChanged(bool, bool) override { }
- void setInputMethodHints(Qt::InputMethodHints) override { }
- void setClearColor(const QColor &) override { }
- void adapterClientChanged(WebContentsAdapterClient *) override { }
- bool copySurface(const QRect &, const QSize &, QImage &)
- {
- Q_UNREACHABLE();
- return false;
- }
- QRect windowGeometry() const override { return QRect(m_pos, m_size); }
- bool forwardEvent(QEvent *ev) { return m_delegateClient->forwardEvent(ev); }
-
-private:
- RenderWidgetHostViewQtDelegateClient *m_delegateClient;
- QPoint m_pos;
- QSize m_size;
-};
-
static QWebEnginePage::WebWindowType toWindowType(WebContentsAdapterClient::WindowOpenDisposition disposition)
{
switch (disposition) {
@@ -202,6 +158,14 @@ QWebEnginePagePrivate::~QWebEnginePagePrivate()
RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
+ item = view
+ ? (QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *)view->CreateRenderWidgetHostViewQtDelegate(client)
+ : new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, false);
+ return item;
+}
+
+RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client)
+{
// Set the QWebEngineView as the parent for a popup delegate, so that the new popup window
// responds properly to clicks in case the QWebEngineView is inside a modal QDialog. Setting the
// parent essentially notifies the OS that the popup window is part of the modal session, and
@@ -209,7 +173,9 @@ RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostVie
// The new delegate will not be deleted by the parent view though, because we unset the parent
// when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is
// dismissed.
- return view ? view->CreateRenderWidgetHostViewQtDelegate(client) : new DummyDelegate(client);
+ return view
+ ? view->CreateRenderWidgetHostViewQtDelegateForPopup(client)
+ : new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, true);
}
void QWebEnginePagePrivate::initializationFinished()
diff --git a/src/core/api/qwebenginepage_p.h b/src/core/api/qwebenginepage_p.h
index 785930127..2b76795b5 100644
--- a/src/core/api/qwebenginepage_p.h
+++ b/src/core/api/qwebenginepage_p.h
@@ -62,11 +62,12 @@
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegate;
-class RenderWidgetHostViewQtDelegateWidget;
class RenderWidgetHostViewQtDelegateClient;
+class RenderWidgetHostViewQtDelegateItem;
class TouchHandleDrawableDelegate;
class TouchSelectionMenuController;
class WebContentsAdapter;
+class WidgetDelegate;
}
QT_BEGIN_NAMESPACE
@@ -94,6 +95,8 @@ public:
virtual void setToolTip(const QString &toolTipText) = 0;
virtual QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate(
QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) = 0;
+ virtual QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegateForPopup(
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) = 0;
virtual QWebEngineContextMenuRequest *lastContextMenuRequest() const = 0;
virtual QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) = 0;
virtual bool isEnabled() const = 0;
@@ -118,7 +121,7 @@ public:
~QWebEnginePagePrivate();
QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
- QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override { return CreateRenderWidgetHostViewQtDelegate(client); }
+ QtWebEngineCore::RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
void initializationFinished() override;
void lifecycleStateChanged(LifecycleState state) override;
void recommendedStateChanged(LifecycleState state) override;
@@ -227,7 +230,8 @@ public:
bool defaultAudioMuted;
qreal defaultZoomFactor;
QTimer wasShownTimer;
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget = nullptr;
+ QtWebEngineCore::WidgetDelegate *widget = nullptr;
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *item = nullptr;
#if QT_CONFIG(webengine_printing_and_pdf)
QPrinter *currentPrinter = nullptr;
#endif
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 572468bc8..d15381d66 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -894,7 +894,7 @@ bool RenderWidgetHostViewQt::isPopup() const
bool RenderWidgetHostViewQt::updateScreenInfo()
{
display::ScreenInfo oldScreenInfo = m_screenInfo;
- QScreen *screen = m_delegate->window() ? m_delegate->window()->screen() : nullptr;
+ QScreen *screen = m_delegate->Window() ? m_delegate->Window()->screen() : nullptr;
m_screenInfo = screenInfoFromQScreen(screen);
return (m_screenInfo != oldScreenInfo);
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 1df1322c7..66a9d7161 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -78,7 +78,7 @@ public:
virtual void show() = 0;
virtual void hide() = 0;
virtual bool isVisible() const = 0;
- virtual QWindow* window() const = 0;
+ virtual QWindow *Window() const = 0;
virtual void updateCursor(const QCursor &) = 0;
virtual void resize(int width, int height) = 0;
virtual void move(const QPoint &) = 0;
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 93311d992..75ed57271 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,22 +37,18 @@
**
****************************************************************************/
-#include "render_widget_host_view_qt_delegate_quick.h"
+#include "render_widget_host_view_qt_delegate_item.h"
#include "render_widget_host_view_qt_delegate_client.h"
-#include "qquickwebengineview_p.h"
-#include "qquickwebengineview_p_p.h"
-
-#include <QtCore/qvariant.h>
-#include <QtGui/qguiapplication.h>
-#include <QtGui/qwindow.h>
-#include <QtQuick/qquickwindow.h>
-#include <QtQuick/qsgimagenode.h>
+#include <QGuiApplication>
+#include <QMouseEvent>
+#include <QSGImageNode>
+#include <QWindow>
namespace QtWebEngineCore {
-RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
+RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
: m_client(client)
, m_isPopup(isPopup)
{
@@ -67,22 +63,23 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
bind(client->compositorId());
}
-RenderWidgetHostViewQtDelegateQuick::~RenderWidgetHostViewQtDelegateQuick()
+RenderWidgetHostViewQtDelegateItem::~RenderWidgetHostViewQtDelegateItem()
{
- QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, this);
+ if (m_widgetDelegate) {
+ m_widgetDelegate->Unbind();
+ m_widgetDelegate->Destroy();
+ }
}
-void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &screenRect)
+void RenderWidgetHostViewQtDelegateItem::initAsPopup(const QRect &screenRect)
{
- //note this is called when there is no windowing system
- //otherwsie see RenderWidgetHostViewQtDelegateQuickWindow
- Q_ASSERT(m_isPopup && parentItem());
- setPosition(screenRect.topLeft());
+ Q_ASSERT(m_isPopup);
setSize(screenRect.size());
- setVisible(true);
+ if (m_widgetDelegate)
+ m_widgetDelegate->InitAsPopup(screenRect);
}
-QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const
+QRectF RenderWidgetHostViewQtDelegateItem::viewGeometry() const
{
// Transform the entire rect to find the correct top left corner.
const QPointF p1 = mapToGlobal(mapFromScene(QPointF(0, 0)));
@@ -93,89 +90,138 @@ QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const
return geometry;
}
-QRect RenderWidgetHostViewQtDelegateQuick::windowGeometry() const
+QRect RenderWidgetHostViewQtDelegateItem::windowGeometry() const
{
- if (!window())
+ if (!Window())
return QRect();
- return window()->frameGeometry();
+ return Window()->frameGeometry();
}
-void RenderWidgetHostViewQtDelegateQuick::setKeyboardFocus()
+void RenderWidgetHostViewQtDelegateItem::setKeyboardFocus()
{
setFocus(true);
}
-bool RenderWidgetHostViewQtDelegateQuick::hasKeyboardFocus()
+bool RenderWidgetHostViewQtDelegateItem::hasKeyboardFocus()
{
return hasActiveFocus();
}
-void RenderWidgetHostViewQtDelegateQuick::lockMouse()
+void RenderWidgetHostViewQtDelegateItem::lockMouse()
{
grabMouse();
}
-void RenderWidgetHostViewQtDelegateQuick::unlockMouse()
+void RenderWidgetHostViewQtDelegateItem::unlockMouse()
{
ungrabMouse();
}
-void RenderWidgetHostViewQtDelegateQuick::show()
+void RenderWidgetHostViewQtDelegateItem::show()
{
- setVisible(true);
- m_client->notifyShown();
+ if (isVisible())
+ m_client->notifyShown();
+ else
+ setVisible(true);
}
-void RenderWidgetHostViewQtDelegateQuick::hide()
+void RenderWidgetHostViewQtDelegateItem::hide()
{
- setVisible(false);
- m_client->notifyHidden();
+ if (isVisible())
+ setVisible(false);
+ else
+ m_client->notifyHidden();
}
-bool RenderWidgetHostViewQtDelegateQuick::isVisible() const
+bool RenderWidgetHostViewQtDelegateItem::isVisible() const
{
return QQuickItem::isVisible();
}
-QWindow* RenderWidgetHostViewQtDelegateQuick::window() const
+QWindow *RenderWidgetHostViewQtDelegateItem::Window() const
{
+ if (m_widgetDelegate) {
+ if (auto *window = m_widgetDelegate->Window())
+ return window;
+ }
return QQuickItem::window();
}
-void RenderWidgetHostViewQtDelegateQuick::readyToSwap()
+void RenderWidgetHostViewQtDelegateItem::readyToSwap()
{
// Call update() on UI thread.
QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
}
-void RenderWidgetHostViewQtDelegateQuick::updateCursor(const QCursor &cursor)
+void RenderWidgetHostViewQtDelegateItem::updateCursor(const QCursor &cursor)
{
setCursor(cursor);
}
-void RenderWidgetHostViewQtDelegateQuick::resize(int width, int height)
+void RenderWidgetHostViewQtDelegateItem::resize(int width, int height)
{
setSize(QSizeF(width, height));
+ if (m_widgetDelegate)
+ m_widgetDelegate->Resize(width, height);
+}
+
+void RenderWidgetHostViewQtDelegateItem::move(const QPoint &point)
+{
+ if (m_widgetDelegate && m_isPopup)
+ m_widgetDelegate->MoveWindow(point);
}
-void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVisible, bool passwordInput)
+void RenderWidgetHostViewQtDelegateItem::inputMethodStateChanged(bool editorVisible, bool passwordInput)
{
setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);
if (parentItem())
parentItem()->setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible && !passwordInput);
+ if (m_widgetDelegate)
+ m_widgetDelegate->SetInputMethodEnabled(editorVisible && !passwordInput);
+
qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
if (qApp->inputMethod()->isVisible() != editorVisible)
qApp->inputMethod()->setVisible(editorVisible);
}
-bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event)
+void RenderWidgetHostViewQtDelegateItem::setWidgetDelegate(WidgetDelegate *delegate)
+{
+ Q_ASSERT(!m_widgetDelegate || !delegate);
+ m_widgetDelegate = delegate;
+ if (m_widgetDelegate) {
+ if (m_inputMethodHints)
+ m_widgetDelegate->SetInputMethodHints(m_inputMethodHints);
+ if (m_clearColor.isValid())
+ m_widgetDelegate->SetClearColor(m_clearColor);
+ if (flags().testFlag(QQuickItem::ItemAcceptsInputMethod))
+ m_widgetDelegate->SetInputMethodEnabled(true);
+ if (m_adapterClient)
+ m_widgetDelegate->Bind(m_adapterClient);
+ }
+}
+
+void RenderWidgetHostViewQtDelegateItem::setInputMethodHints(Qt::InputMethodHints hints)
+{
+ m_inputMethodHints = hints;
+ if (m_widgetDelegate)
+ m_widgetDelegate->SetInputMethodHints(hints);
+}
+
+void RenderWidgetHostViewQtDelegateItem::setClearColor(const QColor &color)
+{
+ m_clearColor = color;
+ if (m_widgetDelegate)
+ m_widgetDelegate->SetClearColor(color);
+}
+
+bool RenderWidgetHostViewQtDelegateItem::event(QEvent *event)
{
if (event->type() == QEvent::ShortcutOverride)
return m_client->forwardEvent(event);
-#ifndef QT_NO_GESTURES
+#if QT_CONFIG(gestures)
if (event->type() == QEvent::NativeGesture)
return m_client->forwardEvent(event);
#endif
@@ -183,78 +229,78 @@ bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event)
return QQuickItem::event(event);
}
-void RenderWidgetHostViewQtDelegateQuick::focusInEvent(QFocusEvent *event)
+void RenderWidgetHostViewQtDelegateItem::focusInEvent(QFocusEvent *event)
{
#if QT_CONFIG(accessibility)
- if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(this)->focusChild()) {
- QAccessibleEvent focusEvent(iface, QAccessible::Focus);
- QAccessible::updateAccessibility(&focusEvent);
+ if (QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(this)) {
+ if (auto *focusChild = iface->focusChild()) {
+ QAccessibleEvent focusEvent(focusChild, QAccessible::Focus);
+ QAccessible::updateAccessibility(&focusEvent);
+ }
}
#endif // QT_CONFIG(accessibility)
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event)
+void RenderWidgetHostViewQtDelegateItem::focusOutEvent(QFocusEvent *event)
{
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event)
+void RenderWidgetHostViewQtDelegateItem::mousePressEvent(QMouseEvent *event)
{
- QQuickItem *parent = parentItem();
- if (!m_isPopup && (parent && parent->property("activeFocusOnPress").toBool()))
- forceActiveFocus();
- if (!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
- event->ignore();
- return;
+ if (!m_isPopup && m_widgetDelegate) {
+ if (m_widgetDelegate->ActiveFocusOnPress()) {
+ forceActiveFocus();
+ } else {
+ event->ignore();
+ return;
+ }
}
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::mouseMoveEvent(QMouseEvent *event)
+void RenderWidgetHostViewQtDelegateItem::mouseMoveEvent(QMouseEvent *event)
{
- QQuickItem *parent = parentItem();
- if (parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ if (!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress()) {
event->ignore();
return;
}
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::mouseReleaseEvent(QMouseEvent *event)
+void RenderWidgetHostViewQtDelegateItem::mouseReleaseEvent(QMouseEvent *event)
{
- QQuickItem *parent = parentItem();
- if (!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ if (!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress()) {
event->ignore();
return;
}
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::keyPressEvent(QKeyEvent *event)
+void RenderWidgetHostViewQtDelegateItem::keyPressEvent(QKeyEvent *event)
{
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::keyReleaseEvent(QKeyEvent *event)
+void RenderWidgetHostViewQtDelegateItem::keyReleaseEvent(QKeyEvent *event)
{
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event)
+void RenderWidgetHostViewQtDelegateItem::wheelEvent(QWheelEvent *event)
{
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event)
+void RenderWidgetHostViewQtDelegateItem::touchEvent(QTouchEvent *event)
{
- QQuickItem *parent = parentItem();
- if (!m_isPopup && parent) {
- if (event->type() == QEvent::TouchBegin && parent->property("activeFocusOnPress").toBool())
+ if (!m_isPopup && m_widgetDelegate) {
+ if (event->type() == QEvent::TouchBegin && m_widgetDelegate->ActiveFocusOnPress())
forceActiveFocus();
- if (!parent->property("activeFocusOnPress").toBool() && !parent->hasActiveFocus()) {
+ if (!m_widgetDelegate->ActiveFocusOnPress()) {
event->ignore();
return;
}
@@ -262,11 +308,9 @@ void RenderWidgetHostViewQtDelegateQuick::touchEvent(QTouchEvent *event)
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::hoverMoveEvent(QHoverEvent *event)
+void RenderWidgetHostViewQtDelegateItem::hoverMoveEvent(QHoverEvent *event)
{
- QQuickItem *parent = parentItem();
- if ((!m_isPopup && parent && !parent->property("activeFocusOnPress").toBool()
- && !parent->hasActiveFocus())
+ if ((!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress())
|| event->position() == event->oldPosF()) {
event->ignore();
return;
@@ -274,28 +318,28 @@ void RenderWidgetHostViewQtDelegateQuick::hoverMoveEvent(QHoverEvent *event)
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::hoverLeaveEvent(QHoverEvent *event)
+void RenderWidgetHostViewQtDelegateItem::hoverLeaveEvent(QHoverEvent *event)
{
m_client->forwardEvent(event);
}
-QVariant RenderWidgetHostViewQtDelegateQuick::inputMethodQuery(Qt::InputMethodQuery query) const
+QVariant RenderWidgetHostViewQtDelegateItem::inputMethodQuery(Qt::InputMethodQuery query) const
{
return m_client->inputMethodQuery(query);
}
-void RenderWidgetHostViewQtDelegateQuick::inputMethodEvent(QInputMethodEvent *event)
+void RenderWidgetHostViewQtDelegateItem::inputMethodEvent(QInputMethodEvent *event)
{
m_client->forwardEvent(event);
}
-void RenderWidgetHostViewQtDelegateQuick::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
+void RenderWidgetHostViewQtDelegateItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickItem::geometryChange(newGeometry, oldGeometry);
m_client->visualPropertiesChanged();
}
-void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const ItemChangeData &value)
+void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const ItemChangeData &value)
{
QQuickItem::itemChange(change, value);
if (change == QQuickItem::ItemSceneChange) {
@@ -303,8 +347,8 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
disconnect(c);
m_windowConnections.clear();
if (value.window) {
- m_windowConnections.append(connect(value.window, SIGNAL(beforeRendering()),
- SLOT(onBeforeRendering()), Qt::DirectConnection));
+ m_windowConnections.append(connect(value.window, &QQuickWindow::beforeRendering,
+ this, &RenderWidgetHostViewQtDelegateItem::onBeforeRendering, Qt::DirectConnection));
m_windowConnections.append(connect(value.window, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
m_windowConnections.append(connect(value.window, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
if (!m_isPopup)
@@ -312,12 +356,17 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
}
m_client->visualPropertiesChanged();
} else if (change == QQuickItem::ItemVisibleHasChanged) {
- if (!m_isPopup && !value.boolValue)
- onHide();
+ if (value.boolValue) {
+ m_client->notifyShown();
+ } else {
+ m_client->notifyHidden();
+ if (!m_isPopup)
+ onHide();
+ }
}
}
-QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
auto comp = compositor();
if (!comp)
@@ -340,16 +389,14 @@ QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode,
if (comp->type() == Compositor::Type::Software) {
QImage image = comp->image();
node->setTexture(win->createTextureFromImage(image));
+#if QT_CONFIG(opengl)
} else if (comp->type() == Compositor::Type::OpenGL) {
QQuickWindow::CreateTextureOptions texOpts;
-#if QT_CONFIG(opengl)
if (comp->hasAlphaChannel())
texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
int texId = comp->textureId();
node->setTexture(QNativeInterface::QSGOpenGLTexture::fromNative(texId, win, texSize, texOpts));
node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
-#else
- Q_UNREACHABLE();
#endif
} else {
Q_UNREACHABLE();
@@ -358,7 +405,7 @@ QSGNode *RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode *oldNode,
return node;
}
-void RenderWidgetHostViewQtDelegateQuick::onBeforeRendering()
+void RenderWidgetHostViewQtDelegateItem::onBeforeRendering()
{
auto comp = compositor();
if (!comp || comp->type() != Compositor::Type::OpenGL)
@@ -366,84 +413,30 @@ void RenderWidgetHostViewQtDelegateQuick::onBeforeRendering()
comp->waitForTexture();
}
-void RenderWidgetHostViewQtDelegateQuick::onWindowPosChanged()
+void RenderWidgetHostViewQtDelegateItem::onWindowPosChanged()
{
m_client->visualPropertiesChanged();
}
-void RenderWidgetHostViewQtDelegateQuick::onHide()
+void RenderWidgetHostViewQtDelegateItem::onHide()
{
QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
m_client->forwardEvent(&event);
}
-void RenderWidgetHostViewQtDelegateQuick::adapterClientChanged(WebContentsAdapterClient *client)
-{
- QQuickWebEngineViewPrivate::bindViewAndWidget(
- static_cast<QQuickWebEngineViewPrivate *>(client)->q_func(), this);
-}
-
-#if QT_CONFIG(accessibility)
-RenderWidgetHostViewQtDelegateQuickAccessible::RenderWidgetHostViewQtDelegateQuickAccessible(RenderWidgetHostViewQtDelegateQuick *o, QQuickWebEngineView *view)
- : QAccessibleObject(o)
- , m_view(view)
-{
-}
-
-bool RenderWidgetHostViewQtDelegateQuickAccessible::isValid() const
-{
- if (!viewAccessible() || !viewAccessible()->isValid())
- return false;
-
- return QAccessibleObject::isValid();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::parent() const
-{
- return viewAccessible()->parent();
-}
-
-QString RenderWidgetHostViewQtDelegateQuickAccessible::text(QAccessible::Text) const
-{
- return QString();
-}
-
-QAccessible::Role RenderWidgetHostViewQtDelegateQuickAccessible::role() const
-{
- return QAccessible::Client;
-}
-
-QAccessible::State RenderWidgetHostViewQtDelegateQuickAccessible::state() const
-{
- return viewAccessible()->state();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::focusChild() const
-{
- return viewAccessible()->focusChild();
-}
-
-int RenderWidgetHostViewQtDelegateQuickAccessible::childCount() const
-{
- return viewAccessible()->childCount();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::child(int index) const
-{
- return viewAccessible()->child(index);
-}
-
-int RenderWidgetHostViewQtDelegateQuickAccessible::indexOfChild(const QAccessibleInterface *c) const
+void RenderWidgetHostViewQtDelegateItem::adapterClientChanged(WebContentsAdapterClient *client)
{
- return viewAccessible()->indexOfChild(c);
+ m_adapterClient = client;
+ if (m_widgetDelegate)
+ m_widgetDelegate->Bind(client);
}
-QQuickWebEngineViewAccessible *RenderWidgetHostViewQtDelegateQuickAccessible::viewAccessible() const
+void RenderWidgetHostViewQtDelegateItem::unhandledWheelEvent(QWheelEvent *ev)
{
- return static_cast<QQuickWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
+ if (QWindow *w = Window()) {
+ if (QWindow *p = w->parent())
+ qApp->sendEvent(p, ev);
+ }
}
-#endif // QT_CONFIG(accessibility)
} // namespace QtWebEngineCore
-
-#include "moc_render_widget_host_view_qt_delegate_quick.cpp"
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quick.h b/src/core/render_widget_host_view_qt_delegate_item.h
index 1580e0614..515f2b28c 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quick.h
+++ b/src/core/render_widget_host_view_qt_delegate_item.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
@@ -37,33 +37,59 @@
**
****************************************************************************/
-#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
-#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H
+#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_ITEM_H
+#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_ITEM_H
#include "compositor/compositor.h"
#include "render_widget_host_view_qt_delegate.h"
-#include <QtGui/qaccessibleobject.h>
-#include <QtQuick/qquickitem.h>
+#include <QtQuick/QQuickItem>
QT_BEGIN_NAMESPACE
class QQuickWebEngineView;
-class QQuickWebEngineViewAccessible;
class QQuickWebEngineViewPrivate;
+class QWebEnginePage;
+class QWebEngineViewPrivate;
QT_END_NAMESPACE
namespace QtWebEngineCore {
class RenderWidgetHostViewQtDelegateClient;
+class WebContentsAdapterClient;
+class WebEngineQuickWidget;
-class RenderWidgetHostViewQtDelegateQuick : public QQuickItem,
- public RenderWidgetHostViewQtDelegate,
- public Compositor::Observer
+class WidgetDelegate
+{
+public:
+ virtual ~WidgetDelegate() = default;
+ virtual void InitAsPopup(const QRect &screenRect) = 0;
+ virtual void SetInputMethodEnabled(bool) { }
+ virtual void SetInputMethodHints(Qt::InputMethodHints) { }
+ virtual void SetClearColor(const QColor &) { }
+ virtual bool ActiveFocusOnPress() = 0;
+ virtual void MoveWindow(const QPoint & ) { }
+ virtual void Bind(WebContentsAdapterClient *) = 0;
+ virtual void Unbind() = 0;
+ virtual void Destroy() = 0;
+ virtual void Resize(int, int) { }
+ virtual QWindow *Window() { return nullptr; }
+};
+
+// Useful information keyboard and mouse QEvent propagation.
+// A RenderWidgetHostViewQtDelegateItem 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 Q_WEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegateItem
+ : public QQuickItem
+ , public RenderWidgetHostViewQtDelegate
+ , public Compositor::Observer
{
Q_OBJECT
public:
- RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup);
- ~RenderWidgetHostViewQtDelegateQuick();
+ RenderWidgetHostViewQtDelegateItem(RenderWidgetHostViewQtDelegateClient *client, bool isPopup);
+ ~RenderWidgetHostViewQtDelegateItem();
void initAsPopup(const QRect&) override;
QRectF viewGeometry() const override;
@@ -75,16 +101,18 @@ public:
void show() override;
void hide() override;
bool isVisible() const override;
- QWindow* window() const override;
+ QWindow *Window() const override;
void updateCursor(const QCursor &) override;
void resize(int width, int height) override;
- void move(const QPoint&) override { }
- void inputMethodStateChanged(bool editorVisible, bool isPasswordInput) override;
- void setInputMethodHints(Qt::InputMethodHints) override { }
- // The QtQuick view doesn't have a backbuffer of its own and doesn't need this
- void setClearColor(const QColor &) override { }
+ void move(const QPoint &screenPos) override;
+ void inputMethodStateChanged(bool editorVisible, bool passwordInput) override;
+ void setInputMethodHints(Qt::InputMethodHints) override;
+ void setClearColor(const QColor &color) override;
+ void unhandledWheelEvent(QWheelEvent *ev) override;
+
void readyToSwap() override;
- void adapterClientChanged(WebContentsAdapterClient *client) override;
+
+ void setWidgetDelegate(WidgetDelegate *delegate);
protected:
bool event(QEvent *event) override;
@@ -105,43 +133,29 @@ protected:
void itemChange(ItemChange change, const ItemChangeData &value) override;
QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
+ void adapterClientChanged(WebContentsAdapterClient *client) override;
+
private Q_SLOTS:
void onBeforeRendering();
void onWindowPosChanged();
void onHide();
private:
+ friend QWebEngineViewPrivate;
friend QQuickWebEngineViewPrivate;
+ friend WebEngineQuickWidget;
RenderWidgetHostViewQtDelegateClient *m_client;
- QList<QMetaObject::Connection> m_windowConnections;
bool m_isPopup;
+ QColor m_clearColor;
+ Qt::InputMethodHints m_inputMethodHints = {};
+ QList<QMetaObject::Connection> m_windowConnections;
+ WebContentsAdapterClient *m_adapterClient = nullptr;
+ QWebEnginePage *m_page = nullptr;
QQuickWebEngineView *m_view = nullptr;
+ WidgetDelegate *m_widgetDelegate = nullptr;
};
-#if QT_CONFIG(accessibility)
-class RenderWidgetHostViewQtDelegateQuickAccessible : public QAccessibleObject
-{
-public:
- RenderWidgetHostViewQtDelegateQuickAccessible(RenderWidgetHostViewQtDelegateQuick *o, QQuickWebEngineView *view);
-
- bool isValid() const override;
- QAccessibleInterface *parent() const override;
- QString text(QAccessible::Text t) const override;
- QAccessible::Role role() const override;
- QAccessible::State state() const override;
-
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface *) const override;
-
-private:
- QQuickWebEngineViewAccessible *viewAccessible() const;
- QQuickWebEngineView *m_view;
-};
-#endif // QT_CONFIG(accessibility)
-
} // namespace QtWebEngineCore
-#endif
+#endif // RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_ITEM_H
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 292043f78..bbd15a35d 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -629,8 +629,8 @@ void WebContentsDelegateQt::SetContentsBounds(content::WebContents *source, cons
QRect frameGeometry(toQt(bounds));
QRect geometry;
if (RenderWidgetHostViewQt *rwhv = static_cast<RenderWidgetHostViewQt*>(web_contents()->GetRenderWidgetHostView())) {
- if (rwhv->delegate() && rwhv->delegate()->window())
- geometry = frameGeometry.marginsRemoved(rwhv->delegate()->window()->frameMargins());
+ if (rwhv->delegate() && rwhv->delegate()->Window())
+ geometry = frameGeometry.marginsRemoved(rwhv->delegate()->Window()->frameMargins());
}
m_viewClient->requestGeometryChange(geometry, frameGeometry);
}
diff --git a/src/webenginequick/CMakeLists.txt b/src/webenginequick/CMakeLists.txt
index 3800f8386..ebe1ddf54 100644
--- a/src/webenginequick/CMakeLists.txt
+++ b/src/webenginequick/CMakeLists.txt
@@ -34,7 +34,7 @@ qt_internal_add_qml_module(WebEngineQuick
api/qquickwebengineforeigntypes_p.h
api/qtwebenginequickglobal.cpp api/qtwebenginequickglobal.h
api/qtwebenginequickglobal_p.h
- render_widget_host_view_qt_delegate_quick.cpp render_widget_host_view_qt_delegate_quick.h
+ qquickwebengine_accessible.cpp qquickwebengine_accessible.h
render_widget_host_view_qt_delegate_quickwindow.cpp render_widget_host_view_qt_delegate_quickwindow.h
ui_delegates_manager.cpp ui_delegates_manager.h
DEFINES
diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp
index 7eb5a8677..24c059d39 100644
--- a/src/webenginequick/api/qquickwebengineview.cpp
+++ b/src/webenginequick/api/qquickwebengineview.cpp
@@ -59,7 +59,8 @@
#include "file_picker_controller.h"
#include "find_text_helper.h"
#include "javascript_dialog_controller.h"
-#include "render_widget_host_view_qt_delegate_quick.h"
+#include "qquickwebengine_accessible.h"
+#include "render_widget_host_view_qt_delegate_item.h"
#include "render_widget_host_view_qt_delegate_quickwindow.h"
#include "touch_selection_menu_controller.h"
#include "ui_delegates_manager.h"
@@ -139,14 +140,61 @@ Q_STATIC_ASSERT(static_cast<int>(QQuickWebEngineView::LoadSucceededStatus) == st
QT_WARNING_POP
#endif
-#ifndef QT_NO_ACCESSIBILITY
+class WebEngineQuickWidgetDelegate : public QtWebEngineCore::WidgetDelegate
+{
+public:
+ WebEngineQuickWidgetDelegate(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *item, QQuickWebEngineView *parent)
+ : m_contentItem(item)
+ , m_parentView(parent)
+ {
+ }
+
+ ~WebEngineQuickWidgetDelegate() override
+ {
+ if (m_contentItem)
+ m_contentItem->setWidgetDelegate(nullptr);
+ }
+
+ void InitAsPopup(const QRect &screenRect) override
+ {
+ Q_UNUSED(screenRect);
+ Q_UNREACHABLE();
+ }
+
+ void Bind(WebContentsAdapterClient *client) override
+ {
+ QQuickWebEngineViewPrivate::bindViewAndWidget(
+ static_cast<QQuickWebEngineViewPrivate *>(client)->q_func(), m_contentItem);
+ }
+
+ void Unbind() override
+ {
+ QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, m_contentItem);
+ }
+
+ void Destroy() override
+ {
+ delete this;
+ }
+
+ bool ActiveFocusOnPress() override
+ {
+ return m_parentView->property("activeFocusOnPress").toBool() || m_parentView->hasActiveFocus();
+ }
+
+private:
+ QPointer<RenderWidgetHostViewQtDelegateItem> m_contentItem; // deleted by core
+ QPointer<QQuickWebEngineView> m_parentView;
+};
+
+#if QT_CONFIG(accessibility)
static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object)
{
if (QQuickWebEngineView *v = qobject_cast<QQuickWebEngineView*>(object))
return new QQuickWebEngineViewAccessible(v);
- return 0;
+ return nullptr;
}
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
static QLatin1String defaultMimeType("text/html;charset=UTF-8");
@@ -174,9 +222,9 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
{
memset(actions, 0, sizeof(actions));
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
QAccessible::installFactory(&webAccessibleFactory);
-#endif // QT_NO_ACCESSIBILITY
+#endif // QT_CONFIG(accessibility)
}
QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate()
@@ -234,22 +282,26 @@ UIDelegatesManager *QQuickWebEngineViewPrivate::ui()
RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client)
{
- return new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ false);
+ Q_Q(QQuickWebEngineView);
+ auto *item = new RenderWidgetHostViewQtDelegateItem(client, /*isPopup = */ false);
+ item->setWidgetDelegate(new WebEngineQuickWidgetDelegate(item, q));
+ return item;
}
RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client)
{
Q_Q(QQuickWebEngineView);
const bool hasWindowCapability = QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::MultipleWindows);
- RenderWidgetHostViewQtDelegateQuick *quickDelegate = new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ true);
+ RenderWidgetHostViewQtDelegateItem *quickDelegate = new RenderWidgetHostViewQtDelegateItem(client, /*isPopup = */ true);
if (hasWindowCapability) {
RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow =
new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate, q->window());
+ quickDelegate->setWidgetDelegate(wrapperWindow);
wrapperWindow->setVirtualParent(q);
- quickDelegate->setParentItem(wrapperWindow->contentItem());
- return wrapperWindow;
+ return quickDelegate;
}
quickDelegate->setParentItem(q);
+ quickDelegate->setWidgetDelegate(new WebEngineQuickWidgetDelegate(quickDelegate, q));
quickDelegate->show();
return quickDelegate;
}
@@ -715,74 +767,6 @@ void QQuickWebEngineViewPrivate::visibleChanged(bool visible)
Q_UNUSED(visible);
}
-#ifndef QT_NO_ACCESSIBILITY
-QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o)
- : QAccessibleObject(o)
-{}
-
-bool QQuickWebEngineViewAccessible::isValid() const
-{
- if (!QAccessibleObject::isValid())
- return false;
-
- if (!engineView() || !engineView()->d_func())
- return false;
-
- return true;
-}
-
-QAccessibleInterface *QQuickWebEngineViewAccessible::parent() const
-{
- QQuickItem *parent = engineView()->parentItem();
- QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parent);
- if (!iface)
- return QAccessible::queryAccessibleInterface(engineView()->window());
- return iface;
-}
-
-QAccessibleInterface *QQuickWebEngineViewAccessible::focusChild() const
-{
- if (child(0) && child(0)->focusChild())
- return child(0)->focusChild();
- return const_cast<QQuickWebEngineViewAccessible *>(this);
-}
-
-int QQuickWebEngineViewAccessible::childCount() const
-{
- return child(0) ? 1 : 0;
-}
-
-QAccessibleInterface *QQuickWebEngineViewAccessible::child(int index) const
-{
- if (index == 0 && isValid())
- return engineView()->d_func()->adapter->browserAccessible();
- return nullptr;
-}
-
-int QQuickWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
-{
- if (child(0) && c == child(0))
- return 0;
- return -1;
-}
-
-QString QQuickWebEngineViewAccessible::text(QAccessible::Text) const
-{
- return QString();
-}
-
-QAccessible::Role QQuickWebEngineViewAccessible::role() const
-{
- return QAccessible::Client;
-}
-
-QAccessible::State QQuickWebEngineViewAccessible::state() const
-{
- QAccessible::State s;
- return s;
-}
-#endif // QT_NO_ACCESSIBILITY
-
class WebContentsAdapterOwner : public QObject
{
public:
@@ -912,7 +896,7 @@ void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen)
}
void QQuickWebEngineViewPrivate::bindViewAndWidget(QQuickWebEngineView *view,
- RenderWidgetHostViewQtDelegateQuick *widget)
+ RenderWidgetHostViewQtDelegateItem *widget)
{
auto oldWidget = view ? view->d_func()->widget : nullptr;
auto oldView = widget ? widget->m_view : nullptr;
@@ -940,8 +924,8 @@ void QQuickWebEngineViewPrivate::bindViewAndWidget(QQuickWebEngineView *view,
view->d_func()->widgetChanged(oldWidget, widget);
}
-void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegateQuick *oldWidget,
- RenderWidgetHostViewQtDelegateQuick *newWidget)
+void QQuickWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *oldWidget,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *newWidget)
{
Q_Q(QQuickWebEngineView);
diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h
index fb736085b..46b92b9c6 100644
--- a/src/webenginequick/api/qquickwebengineview_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p.h
@@ -57,10 +57,6 @@
#include <QtQml/qqmlregistration.h>
#include <QtQuick/qquickitem.h>
-namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegateQuick;
-}
-
QT_BEGIN_NAMESPACE
class QQmlWebChannel;
@@ -589,7 +585,6 @@ private:
Q_DECLARE_PRIVATE(QQuickWebEngineView)
QScopedPointer<QQuickWebEngineViewPrivate> d_ptr;
- friend class QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick;
friend class QQuickContextMenuBuilder;
friend class FaviconImageResponse;
friend class FaviconImageResponseRunnable;
diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h
index 2096f79c6..fe9f78322 100644
--- a/src/webenginequick/api/qquickwebengineview_p_p.h
+++ b/src/webenginequick/api/qquickwebengineview_p_p.h
@@ -66,7 +66,7 @@
#include <QtGui/qaccessibleobject.h>
namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegateQuick;
+class RenderWidgetHostViewQtDelegateItem;
class TouchSelectionMenuController;
class UIDelegatesManager;
class WebContentsAdapter;
@@ -174,9 +174,9 @@ public:
void ensureContentsAdapter();
void setFullScreenMode(bool);
- static void bindViewAndWidget(QQuickWebEngineView *view, QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget);
- void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *oldWidget,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *newWidget);
+ static void bindViewAndWidget(QQuickWebEngineView *view, QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *widget);
+ void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *oldWidget,
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *newWidget);
QQuickWebEngineProfile *m_profile;
QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter;
@@ -200,7 +200,7 @@ public:
bool m_defaultAudioMuted;
bool m_isBeingAdopted;
mutable QQuickWebEngineAction *actions[QQuickWebEngineView::WebActionCount];
- QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget = nullptr;
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateItem *widget = nullptr;
bool profileInitialized() const;
QQuickWebEngineScriptCollection *getUserScripts();
@@ -216,26 +216,6 @@ private:
QQmlComponent *m_touchHandleDelegate;
};
-#ifndef QT_NO_ACCESSIBILITY
-class QQuickWebEngineViewAccessible : public QAccessibleObject
-{
-public:
- QQuickWebEngineViewAccessible(QQuickWebEngineView *o);
- bool isValid() const override;
- QAccessibleInterface *parent() const override;
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface*) const override;
- QString text(QAccessible::Text) const override;
- QAccessible::Role role() const override;
- QAccessible::State state() const override;
-
-private:
- QQuickWebEngineView *engineView() const { return static_cast<QQuickWebEngineView*>(object()); }
-};
-#endif // QT_NO_ACCESSIBILITY
-
class QQuickContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt
{
public:
diff --git a/src/webenginequick/qquickwebengine_accessible.cpp b/src/webenginequick/qquickwebengine_accessible.cpp
new file mode 100644
index 000000000..8d9f2bd63
--- /dev/null
+++ b/src/webenginequick/qquickwebengine_accessible.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 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 "qquickwebengine_accessible.h"
+
+#include <QQuickItem>
+#include <QQuickWindow>
+
+#include "api/qquickwebengineview_p.h"
+#include "api/qquickwebengineview_p_p.h"
+#include "web_contents_adapter.h"
+
+
+#if QT_CONFIG(accessibility)
+QT_BEGIN_NAMESPACE
+QQuickWebEngineViewAccessible::QQuickWebEngineViewAccessible(QQuickWebEngineView *o)
+ : QAccessibleObject(o)
+{}
+
+bool QQuickWebEngineViewAccessible::isValid() const
+{
+ if (!QAccessibleObject::isValid())
+ return false;
+
+ if (!engineView() || !engineView()->d_func())
+ return false;
+
+ return true;
+}
+
+QAccessibleInterface *QQuickWebEngineViewAccessible::parent() const
+{
+ QQuickItem *parent = engineView()->parentItem();
+ QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parent);
+ if (!iface)
+ return QAccessible::queryAccessibleInterface(engineView()->window());
+ return iface;
+}
+
+QAccessibleInterface *QQuickWebEngineViewAccessible::focusChild() const
+{
+ if (child(0) && child(0)->focusChild())
+ return child(0)->focusChild();
+ return const_cast<QQuickWebEngineViewAccessible *>(this);
+}
+
+int QQuickWebEngineViewAccessible::childCount() const
+{
+ return child(0) ? 1 : 0;
+}
+
+QAccessibleInterface *QQuickWebEngineViewAccessible::child(int index) const
+{
+ if (index == 0 && isValid())
+ return engineView()->d_func()->adapter->browserAccessible();
+ return nullptr;
+}
+
+int QQuickWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ if (child(0) && c == child(0))
+ return 0;
+ return -1;
+}
+
+QString QQuickWebEngineViewAccessible::text(QAccessible::Text) const
+{
+ return QString();
+}
+
+QAccessible::Role QQuickWebEngineViewAccessible::role() const
+{
+ return QAccessible::Client;
+}
+
+QAccessible::State QQuickWebEngineViewAccessible::state() const
+{
+ QAccessible::State s;
+ return s;
+}
+
+QQuickWebEngineView *QQuickWebEngineViewAccessible::engineView() const
+{
+ return static_cast<QQuickWebEngineView*>(object());
+}
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+RenderWidgetHostViewQtDelegateQuickAccessible::RenderWidgetHostViewQtDelegateQuickAccessible(QObject *o, QQuickWebEngineView *view)
+ : QAccessibleObject(o)
+ , m_view(view)
+{
+}
+
+bool RenderWidgetHostViewQtDelegateQuickAccessible::isValid() const
+{
+ if (!viewAccessible() || !viewAccessible()->isValid())
+ return false;
+
+ return QAccessibleObject::isValid();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::parent() const
+{
+ return viewAccessible()->parent();
+}
+
+QString RenderWidgetHostViewQtDelegateQuickAccessible::text(QAccessible::Text) const
+{
+ return QString();
+}
+
+QAccessible::Role RenderWidgetHostViewQtDelegateQuickAccessible::role() const
+{
+ return QAccessible::Client;
+}
+
+QAccessible::State RenderWidgetHostViewQtDelegateQuickAccessible::state() const
+{
+ return viewAccessible()->state();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::focusChild() const
+{
+ return viewAccessible()->focusChild();
+}
+
+int RenderWidgetHostViewQtDelegateQuickAccessible::childCount() const
+{
+ return viewAccessible()->childCount();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateQuickAccessible::child(int index) const
+{
+ return viewAccessible()->child(index);
+}
+
+int RenderWidgetHostViewQtDelegateQuickAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ return viewAccessible()->indexOfChild(c);
+}
+
+QQuickWebEngineViewAccessible *RenderWidgetHostViewQtDelegateQuickAccessible::viewAccessible() const
+{
+ return static_cast<QQuickWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
+}
+} // namespace QtWebEngineCore
+#endif // QT_CONFIG(accessibility)
diff --git a/src/webenginequick/qquickwebengine_accessible.h b/src/webenginequick/qquickwebengine_accessible.h
new file mode 100644
index 000000000..0005ed9cc
--- /dev/null
+++ b/src/webenginequick/qquickwebengine_accessible.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 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 QQUICKWEBENGINE_ACCESSIBLE_H
+#define QQUICKWEBENGINE_ACCESSIBLE_H
+
+#include <QtCore/qpointer.h>
+#include <QtGui/qaccessibleobject.h>
+
+#if QT_CONFIG(accessibility)
+
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineView;
+
+class QQuickWebEngineViewAccessible : public QAccessibleObject
+{
+public:
+ QQuickWebEngineViewAccessible(QQuickWebEngineView *o);
+ bool isValid() const override;
+ QAccessibleInterface *parent() const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *) const override;
+ QString text(QAccessible::Text) const override;
+ QAccessible::Role role() const override;
+ QAccessible::State state() const override;
+
+private:
+ QQuickWebEngineView *engineView() const;
+};
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+class RenderWidgetHostViewQtDelegateQuickAccessible : public QAccessibleObject
+{
+public:
+ RenderWidgetHostViewQtDelegateQuickAccessible(QObject *o, QQuickWebEngineView *view);
+
+ bool isValid() const override;
+ QAccessibleInterface *parent() const override;
+ QString text(QAccessible::Text t) const override;
+ QAccessible::Role role() const override;
+ QAccessible::State state() const override;
+
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *) const override;
+
+private:
+ QQuickWebEngineViewAccessible *viewAccessible() const;
+ QPointer<QQuickWebEngineView> m_view;
+};
+} // namespace QtWebEngineCore
+
+#endif // QT_CONFIG(accessibility)
+
+#endif // QQUICKWEBENGINE_ACCESSIBLE_H
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
index 7cae38b2e..911d10c8a 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -37,10 +37,9 @@
**
****************************************************************************/
-#include "render_widget_host_view_qt_delegate_quick.h"
#include "render_widget_host_view_qt_delegate_quickwindow.h"
-#include <QtQuick/qquickitem.h>
+#include "api/qquickwebengineview_p_p.h"
namespace QtWebEngineCore {
@@ -68,14 +67,19 @@ static inline QPointF transformPoint(const QPointF &point, const QTransform &tra
}
RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(
- RenderWidgetHostViewQtDelegateQuick *realDelegate, QWindow *parent)
+ RenderWidgetHostViewQtDelegateItem *realDelegate, QWindow *parent)
: QQuickWindow(parent), m_realDelegate(realDelegate), m_virtualParent(nullptr), m_rotated(false)
{
setFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+ realDelegate->setParentItem(contentItem());
}
RenderWidgetHostViewQtDelegateQuickWindow::~RenderWidgetHostViewQtDelegateQuickWindow()
{
+ if (m_realDelegate) {
+ m_realDelegate->setWidgetDelegate(nullptr);
+ m_realDelegate->setParentItem(nullptr);
+ }
}
void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *virtualParent)
@@ -86,9 +90,9 @@ void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *vir
// rect is window geometry in form of parent window offset + offset in scene coordinates
// chromium knows nothing about local transformation
-void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &rect)
+void RenderWidgetHostViewQtDelegateQuickWindow::InitAsPopup(const QRect &rect)
{
- m_rotated = m_virtualParent->parentItem()->rotation() > 0;
+ m_rotated = m_virtualParent->rotation() > 0 || m_virtualParent->parentItem()->rotation() > 0;
if (m_rotated) {
// code below tries to cover the case where webengine view is rotated,
// the code assumes the rotation is in the form of 90, 180, 270 degrees
@@ -104,7 +108,6 @@ void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &rect)
QPointF br = transformPoint(rect.bottomRight(), transform, offset, m_virtualParent);
QRectF popupRect(tl, br);
popupRect = popupRect.normalized();
- m_realDelegate->setSize(rect.size());
// include offset from parent window
popupRect.moveTo(popupRect.topLeft() - offset);
setGeometry(popupRect.adjusted(0, 0, 1, 1).toRect());
@@ -115,64 +118,51 @@ void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &rect)
m_realDelegate->setTransformOrigin(QQuickItem::Center);
m_realDelegate->setRotation(m_virtualParent->parentItem()->rotation());
} else {
- m_realDelegate->setSize(rect.size());
QRect geometry(rect);
geometry.moveTo(rect.topLeft() - getOffset(m_virtualParent));
setGeometry(geometry);
}
+ m_realDelegate->show();
raise();
show();
}
-QRectF RenderWidgetHostViewQtDelegateQuickWindow::viewGeometry() const
-{
- return m_rotated ? m_rect : geometry();
-}
-
-QRect RenderWidgetHostViewQtDelegateQuickWindow::windowGeometry() const
+void RenderWidgetHostViewQtDelegateQuickWindow::Resize(int width, int height)
{
- return m_rotated ? m_rect : frameGeometry();
-}
-
-void RenderWidgetHostViewQtDelegateQuickWindow::show()
-{
- QQuickWindow::show();
- m_realDelegate->show();
+ if (!m_rotated)
+ QQuickWindow::resize(width, height);
}
-void RenderWidgetHostViewQtDelegateQuickWindow::hide()
+void RenderWidgetHostViewQtDelegateQuickWindow::MoveWindow(const QPoint &screenPos)
{
- QQuickWindow::hide();
- m_realDelegate->hide();
+ if (!m_rotated)
+ QQuickWindow::setPosition(screenPos - getOffset(m_virtualParent));
}
-bool RenderWidgetHostViewQtDelegateQuickWindow::isVisible() const
+void RenderWidgetHostViewQtDelegateQuickWindow::SetClearColor(const QColor &color)
{
- return QQuickWindow::isVisible();
+ QQuickWindow::setColor(color);
}
-QWindow *RenderWidgetHostViewQtDelegateQuickWindow::window() const
+bool RenderWidgetHostViewQtDelegateQuickWindow::ActiveFocusOnPress()
{
- return const_cast<RenderWidgetHostViewQtDelegateQuickWindow*>(this);
+ return false;
}
-void RenderWidgetHostViewQtDelegateQuickWindow::updateCursor(const QCursor &cursor)
+void RenderWidgetHostViewQtDelegateQuickWindow::Bind(QtWebEngineCore::WebContentsAdapterClient *client)
{
- setCursor(cursor);
+ QQuickWebEngineViewPrivate::bindViewAndWidget(
+ static_cast<QQuickWebEngineViewPrivate *>(client)->q_func(), m_realDelegate.data());
}
-void RenderWidgetHostViewQtDelegateQuickWindow::resize(int width, int height)
+void RenderWidgetHostViewQtDelegateQuickWindow::Unbind()
{
- if (!m_rotated) {
- QQuickWindow::resize(width, height);
- m_realDelegate->resize(width, height);
- }
+ QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, m_realDelegate.data());
}
-void RenderWidgetHostViewQtDelegateQuickWindow::move(const QPoint &screenPos)
+void RenderWidgetHostViewQtDelegateQuickWindow::Destroy()
{
- if (!m_rotated)
- QQuickWindow::setPosition(screenPos - getOffset(m_virtualParent));
+ deleteLater();
}
} // namespace QtWebEngineCore
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h
index f7dfd1a05..1b94698ff 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.h
@@ -41,43 +41,33 @@
#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICKWINDOW_H
#include "render_widget_host_view_qt_delegate.h"
+#include "render_widget_host_view_qt_delegate_item.h"
-#include <QtCore/qscopedpointer.h>
+#include <QtCore/qpointer.h>
#include <QtQuick/qquickwindow.h>
namespace QtWebEngineCore {
-class RenderWidgetHostViewQtDelegateQuick;
-
-class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public RenderWidgetHostViewQtDelegate {
+class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public WidgetDelegate {
public:
- RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate,
+ RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateItem *realDelegate,
QWindow *parent);
~RenderWidgetHostViewQtDelegateQuickWindow();
- void initAsPopup(const QRect&) override;
- QRectF viewGeometry() const override;
- QRect windowGeometry() const override;
- void setKeyboardFocus() override {}
- bool hasKeyboardFocus() override { return false; }
- void lockMouse() override {}
- void unlockMouse() override {}
- void show() override;
- void hide() override;
- bool isVisible() const override;
- QWindow* window() const override;
- void updateCursor(const QCursor &) override;
- void resize(int width, int height) override;
- void move(const QPoint &screenPos) override;
- void inputMethodStateChanged(bool, bool) override {}
- void setInputMethodHints(Qt::InputMethodHints) override { }
- void setClearColor(const QColor &) override { }
- void adapterClientChanged(WebContentsAdapterClient *) override { }
+ void InitAsPopup(const QRect &screenRect) override;
+ void SetClearColor(const QColor &) override;
+ bool ActiveFocusOnPress() override;
+ void MoveWindow(const QPoint &) override;
+ void Bind(WebContentsAdapterClient *) override;
+ void Unbind() override;
+ void Destroy() override;
+ void Resize(int width, int height) override;
+
void setVirtualParent(QQuickItem *virtualParent);
private:
- QScopedPointer<RenderWidgetHostViewQtDelegateQuick> m_realDelegate;
+ QPointer<RenderWidgetHostViewQtDelegateItem> m_realDelegate;
QQuickItem *m_virtualParent;
QRect m_rect;
bool m_rotated;
diff --git a/src/webenginewidgets/CMakeLists.txt b/src/webenginewidgets/CMakeLists.txt
index 6a25e7297..1aa4ae1e2 100644
--- a/src/webenginewidgets/CMakeLists.txt
+++ b/src/webenginewidgets/CMakeLists.txt
@@ -8,7 +8,7 @@ qt_internal_add_module(WebEngineWidgets
api/qtwebenginewidgetsglobal.h
api/qwebenginenotificationpresenter.cpp api/qwebenginenotificationpresenter_p.h
api/qwebengineview.cpp api/qwebengineview.h api/qwebengineview_p.h
- render_widget_host_view_qt_delegate_widget.cpp render_widget_host_view_qt_delegate_widget.h
+ qwebengine_accessible.cpp qwebengine_accessible.h
DEFINES
QT_BUILD_WEBENGINEWIDGETS_LIB
INCLUDE_DIRECTORIES
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index 8016b2d57..b3bba7d9e 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -40,7 +40,9 @@
#include "qwebenginenotificationpresenter_p.h"
#include "qwebengineview.h"
#include "qwebengineview_p.h"
-#include "render_widget_host_view_qt_delegate_widget.h"
+#include "render_widget_host_view_qt_delegate_client.h"
+#include "render_widget_host_view_qt_delegate_item.h"
+#include "qwebengine_accessible.h"
#include <QtWebEngineCore/private/qwebenginepage_p.h>
#include <QtWebEngineCore/qwebenginecontextmenurequest.h>
@@ -57,6 +59,7 @@
#include <QIcon>
#include <QStyle>
#include <QGuiApplication>
+#include <QQuickWidget>
#if QT_CONFIG(action)
#include <QAction>
@@ -91,6 +94,286 @@
#include <QThread>
#endif
+namespace QtWebEngineCore {
+class WebEngineQuickWidget : public QQuickWidget, public WidgetDelegate
+{
+public:
+ WebEngineQuickWidget(RenderWidgetHostViewQtDelegateItem *widget, QWidget *parent)
+ : QQuickWidget(parent)
+ , m_contentItem(widget)
+ {
+ setFocusPolicy(Qt::StrongFocus);
+ setMouseTracking(true);
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ setAttribute(Qt::WA_AlwaysShowToolTips);
+
+ QQuickItem *root = new QQuickItem(); // Indirection so we don't delete m_contentItem
+ setContent(QUrl(), nullptr, root);
+ root->setFlags(QQuickItem::ItemHasContents);
+ root->setFocus(true);
+ root->setVisible(true);
+ m_contentItem->setParentItem(root);
+
+ connectRemoveParentBeforeParentDelete();
+ }
+ ~WebEngineQuickWidget() override
+ {
+ if (m_contentItem) {
+ m_contentItem->setWidgetDelegate(nullptr);
+ m_contentItem->setParentItem(nullptr);
+ }
+ }
+
+ void InitAsPopup(const QRect &screenRect) override
+ {
+ setAttribute(Qt::WA_ShowWithoutActivating);
+ setFocusPolicy(Qt::NoFocus);
+ setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+
+ setGeometry(screenRect);
+ raise();
+ m_contentItem->show();
+ show();
+ }
+
+ void Bind(WebContentsAdapterClient *client) override
+ {
+ if (m_pageDestroyedConnection)
+ QObject::disconnect(m_pageDestroyedConnection);
+ QWebEnginePage *page = static_cast<QWebEnginePagePrivate *>(client)->q_func();
+ QWebEngineViewPrivate::bindPageAndWidget(page, this);
+ m_pageDestroyedConnection = QObject::connect(page, &QWebEnginePage::_q_aboutToDelete, this, &WebEngineQuickWidget::Unbind);
+ }
+
+ void Unbind() override
+ {
+ if (m_pageDestroyedConnection)
+ QObject::disconnect(m_pageDestroyedConnection);
+ QWebEngineViewPrivate::bindPageAndWidget(nullptr, this);
+ }
+
+ void Destroy() override
+ {
+ deleteLater();
+ }
+
+ bool ActiveFocusOnPress() override
+ {
+ return true;
+ }
+
+ void SetInputMethodEnabled(bool enabled) override
+ {
+ QQuickWidget::setAttribute(Qt::WA_InputMethodEnabled, enabled);
+ }
+ void SetInputMethodHints(Qt::InputMethodHints hints) override
+ {
+ QQuickWidget::setInputMethodHints(hints);
+ }
+ void SetClearColor(const QColor &color) override
+ {
+ QQuickWidget::setClearColor(color);
+ // QQuickWidget is usually blended by punching holes into widgets
+ // above it to simulate the visual stacking order. If we want it to be
+ // transparent we have to throw away the proper stacking order and always
+ // blend the complete normal widgets backing store under it.
+ bool isTranslucent = color.alpha() < 255;
+ setAttribute(Qt::WA_AlwaysStackOnTop, isTranslucent);
+ setAttribute(Qt::WA_OpaquePaintEvent, !isTranslucent);
+ update();
+ }
+ void MoveWindow(const QPoint &screenPos) override
+ {
+ QQuickWidget::move(screenPos);
+ }
+ void Resize(int width, int height) override
+ {
+ QQuickWidget::resize(width, height);
+ }
+ QWindow *Window() override
+ {
+ if (const QWidget *root = QQuickWidget::window())
+ return root->windowHandle();
+ return nullptr;
+ }
+
+protected:
+ void closeEvent(QCloseEvent *event) override
+ {
+ QQuickWidget::closeEvent(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_contentItem && m_contentItem->m_isPopup)
+ m_contentItem->m_client->closePopup();
+ }
+ void showEvent(QShowEvent *event) override
+ {
+ QQuickWidget::showEvent(event);
+ // We don't have a way to catch a top-level window change with QWidget
+ // but a widget will most likely be shown again if it changes, so do
+ // the reconnection at this point.
+ for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
+ disconnect(c);
+ m_windowConnections.clear();
+ if (QWindow *w = Window()) {
+ m_windowConnections.append(connect(w, SIGNAL(xChanged(int)), m_contentItem, SLOT(onWindowPosChanged())));
+ m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), m_contentItem, SLOT(onWindowPosChanged())));
+ }
+ }
+ void resizeEvent(QResizeEvent *event) override
+ {
+ QQuickWidget::resizeEvent(event);
+ if (m_contentItem) { // FIXME: Not sure why we need to set m_contentItem size manually
+ m_contentItem->setSize(event->size());
+ m_contentItem->onWindowPosChanged();
+ }
+ }
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
+ {
+ if (m_contentItem)
+ return m_contentItem->inputMethodQuery(query);
+ return QVariant();
+ }
+ bool event(QEvent *event) override;
+
+ void connectRemoveParentBeforeParentDelete();
+ void removeParentBeforeParentDelete();
+
+private:
+ friend QWebEngineViewPrivate;
+ QPointer<RenderWidgetHostViewQtDelegateItem> m_contentItem; // deleted by core
+ QMetaObject::Connection m_parentDestroyedConnection;
+ QMetaObject::Connection m_pageDestroyedConnection;
+ QList<QMetaObject::Connection> m_windowConnections;
+};
+
+void WebEngineQuickWidget::connectRemoveParentBeforeParentDelete()
+{
+ disconnect(m_parentDestroyedConnection);
+
+ if (QWidget *parent = parentWidget()) {
+ m_parentDestroyedConnection = connect(parent, &QObject::destroyed,
+ this,
+ &WebEngineQuickWidget::removeParentBeforeParentDelete);
+ } else {
+ m_parentDestroyedConnection = QMetaObject::Connection();
+ }
+}
+
+void WebEngineQuickWidget::removeParentBeforeParentDelete()
+{
+ // Unset the parent, because parent is being destroyed, but the owner of this
+ // WebEngineQuickWidget is actually a RenderWidgetHostViewQt instance.
+ setParent(nullptr);
+
+ // If this widget represents a popup window, make sure to close it, so that if the popup was the
+ // last visible top level window, the application event loop can quit if it deems it necessarry.
+ if (m_contentItem && m_contentItem->m_isPopup)
+ close();
+}
+
+bool WebEngineQuickWidget::event(QEvent *event)
+{
+ bool handled = false;
+
+ // Track parent to make sure we don't get deleted.
+ if (event->type() == QEvent::ParentChange)
+ connectRemoveParentBeforeParentDelete();
+
+ if (!m_contentItem)
+ return QQuickWidget::event(event);
+
+ // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is
+ // disabled.
+ if (!isEnabled()) {
+ switch (event->type()) {
+ case QEvent::TabletPress:
+ case QEvent::TabletRelease:
+ case QEvent::TabletMove:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ case QEvent::TouchCancel:
+ case QEvent::ContextMenu:
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+#ifndef QT_NO_WHEELEVENT
+ case QEvent::Wheel:
+#endif
+ return false;
+ default:
+ break;
+ }
+ }
+
+ switch (event->type()) {
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ // We forward focus events later, once they have made it to the content item.
+ return QQuickWidget::event(event);
+ case QEvent::DragEnter:
+ case QEvent::DragLeave:
+ case QEvent::DragMove:
+ case QEvent::Drop:
+ case QEvent::HoverEnter:
+ case QEvent::HoverLeave:
+ case QEvent::HoverMove:
+ // Let the parent handle these events.
+ return false;
+ default:
+ break;
+ }
+
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::MouseMove:
+ // Don't forward mouse events synthesized by the system, which are caused by genuine touch
+ // events. Chromium would then process for e.g. a mouse click handler twice, once due to the
+ // system synthesized mouse event, and another time due to a touch-to-gesture-to-mouse
+ // transformation done by Chromium.
+ // Only allow them for popup type, since QWidgetWindow will ignore them for Qt::Popup flag,
+ // which is expected to get input through synthesized mouse events (either by system or Qt)
+ if (!m_contentItem->m_isPopup &&
+ static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem) {
+ Q_ASSERT(!windowFlags().testFlag(Qt::Popup));
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (event->type() == QEvent::MouseButtonDblClick) {
+ // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event.
+ // QtQuick is different by sending both the Press and DblClick events for the second press
+ // where we can simply ignore the DblClick event.
+ QMouseEvent *dblClick = static_cast<QMouseEvent *>(event);
+ QMouseEvent press(QEvent::MouseButtonPress, dblClick->position(), dblClick->scenePosition(),
+ dblClick->globalPosition(), dblClick->button(), dblClick->buttons(),
+ dblClick->modifiers(), dblClick->source());
+ press.setTimestamp(dblClick->timestamp());
+ handled = m_contentItem->m_client->forwardEvent(&press);
+ } else
+ handled = m_contentItem->m_client->forwardEvent(event);
+
+ if (!handled)
+ return QQuickWidget::event(event);
+ event->accept();
+ return true;
+}
+
+} // namespace QtWebEngineCore
+
QT_BEGIN_NAMESPACE
void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage)
@@ -144,8 +427,8 @@ void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage
Q_EMIT q->selectionChanged();
}
-void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget)
+void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::WebEngineQuickWidget *oldWidget,
+ QtWebEngineCore::WebEngineQuickWidget *newWidget)
{
Q_Q(QWebEngineView);
@@ -162,8 +445,6 @@ void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQ
if (newWidget) {
Q_ASSERT(!QtWebEngineCore::closingDown());
#if QT_CONFIG(accessibility)
- // An earlier QAccessible::queryAccessibleInterface() call may have already registered a default
- // QAccessibleInterface for newWidget: remove it first to avoid assert in QAccessibleCache::insert().
QAccessible::deleteAccessibleInterface(QAccessible::uniqueId(QAccessible::queryAccessibleInterface(newWidget)));
QAccessible::registerAccessibleInterface(new QtWebEngineCore::RenderWidgetHostViewQtDelegateWidgetAccessible(newWidget, q));
#endif
@@ -403,20 +684,24 @@ void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView
// Then notify.
- auto widget = page ? page->d_func()->widget : nullptr;
- auto oldWidget = (oldPage && oldPage->d_func()) ? oldPage->d_func()->widget : nullptr;
+ auto widget = page ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(page->d_func()->widget) : nullptr;
+ auto oldWidget = (oldPage && oldPage->d_func()) ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(oldPage->d_func()->widget) : nullptr;
+ // New page/widget moving away from oldView
if (page && oldView != view && oldView) {
oldView->d_func()->pageChanged(page, nullptr);
if (widget)
oldView->d_func()->widgetChanged(widget, nullptr);
}
+ // New page/widget moving into new view
if (view && oldPage != page) {
if (oldPage && oldPage->d_func())
view->d_func()->pageChanged(oldPage, page);
else
view->d_func()->pageChanged(nullptr, page);
+ if (!widget && page && page->d_func()->item)
+ widget = new QtWebEngineCore::WebEngineQuickWidget(page->d_func()->item, nullptr);
if (oldWidget != widget)
view->d_func()->widgetChanged(oldWidget, widget);
}
@@ -425,23 +710,27 @@ void QWebEngineViewPrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView
}
void QWebEngineViewPrivate::bindPageAndWidget(
- QWebEnginePage *page, QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget)
+ QWebEnginePage *page, QtWebEngineCore::WebEngineQuickWidget *widget)
{
- auto oldPage = widget ? widget->m_page : nullptr;
- auto oldWidget = page ? page->d_func()->widget : nullptr;
+ auto oldPage = (widget && widget->m_contentItem) ? widget->m_contentItem->m_page : nullptr;
+ auto oldWidget = page ? static_cast<QtWebEngineCore::WebEngineQuickWidget *>(page->d_func()->widget) : nullptr;
// Change pointers first.
if (widget && oldPage != page) {
- if (oldPage && oldPage->d_func())
+ if (oldPage && oldPage->d_func()) {
oldPage->d_func()->widget = nullptr;
- widget->m_page = page;
+ oldPage->d_func()->item = nullptr;
+ }
+ if (widget->m_contentItem)
+ widget->m_contentItem->m_page = page;
}
if (page && oldWidget != widget) {
- if (oldWidget)
- oldWidget->m_page = nullptr;
+ if (oldWidget && oldWidget->m_contentItem)
+ oldWidget->m_contentItem->m_page = nullptr;
page->d_func()->widget = widget;
+ page->d_func()->item = widget->m_contentItem;
}
// Then notify.
@@ -585,8 +874,21 @@ QtWebEngineCore::RenderWidgetHostViewQtDelegate *
QWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegate(
QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client)
{
+ auto *item = new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, false);
+ auto *widget = new QtWebEngineCore::WebEngineQuickWidget(item, nullptr);
+ item->setWidgetDelegate(widget);
+ return item;
+}
+
+QtWebEngineCore::RenderWidgetHostViewQtDelegate *
+QWebEngineViewPrivate::CreateRenderWidgetHostViewQtDelegateForPopup(
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client)
+{
Q_Q(QWebEngineView);
- return new QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget(client, q);
+ auto *item = new QtWebEngineCore::RenderWidgetHostViewQtDelegateItem(client, true);
+ auto *widget = new QtWebEngineCore::WebEngineQuickWidget(item, q);
+ item->setWidgetDelegate(widget);
+ return item;
}
QWebEngineContextMenuRequest *QWebEngineViewPrivate::lastContextMenuRequest() const
@@ -1115,45 +1417,6 @@ void QWebEngineView::print(QPrinter *printer)
#endif
}
-#ifndef QT_NO_ACCESSIBILITY
-bool QWebEngineViewAccessible::isValid() const
-{
- if (!QAccessibleWidget::isValid())
- return false;
-
- if (!view() || !view()->d_func() || !view()->d_func()->page || !view()->d_func()->page->d_func())
- return false;
-
- return true;
-}
-
-QAccessibleInterface *QWebEngineViewAccessible::focusChild() const
-{
- if (child(0) && child(0)->focusChild())
- return child(0)->focusChild();
- return const_cast<QWebEngineViewAccessible *>(this);
-}
-
-int QWebEngineViewAccessible::childCount() const
-{
- return child(0) ? 1 : 0;
-}
-
-QAccessibleInterface *QWebEngineViewAccessible::child(int index) const
-{
- if (index == 0 && isValid())
- return view()->page()->d_func()->adapter->browserAccessible();
- return nullptr;
-}
-
-int QWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
-{
- if (child(0) && c == child(0))
- return 0;
- return -1;
-}
-#endif // QT_NO_ACCESSIBILITY
-
#if QT_CONFIG(action)
QContextMenuBuilder::QContextMenuBuilder(QWebEngineContextMenuRequest *request,
QWebEngineView *view, QMenu *menu)
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index b5d38a6c1..e3c9468ce 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -52,14 +52,14 @@
//
#include <QtWebEngineCore/private/qwebenginepage_p.h> // PageView
-#include <QtWidgets/qaccessiblewidget.h>
#include "render_view_context_menu_qt.h"
namespace QtWebEngineCore {
class QWebEngineContextMenuRequest;
-class RenderWidgetHostViewQtDelegateWidget;
+class WebEngineQuickWidget;
class RenderWidgetHostViewQtDelegate;
+class RenderWidgetHostViewQtDelegateClient;
}
QT_BEGIN_NAMESPACE
@@ -75,8 +75,8 @@ public:
QWebEngineView *q_ptr;
void pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage);
- void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget);
+ void widgetChanged(QtWebEngineCore::WebEngineQuickWidget *oldWidget,
+ QtWebEngineCore::WebEngineQuickWidget *newWidget);
void contextMenuRequested(QWebEngineContextMenuRequest *request) override;
QStringList chooseFiles(QWebEnginePage::FileSelectionMode mode, const QStringList &oldFiles,
@@ -91,6 +91,8 @@ public:
void setToolTip(const QString &toolTipText) override;
QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegate(
QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
+ QtWebEngineCore::RenderWidgetHostViewQtDelegate *CreateRenderWidgetHostViewQtDelegateForPopup(
+ QtWebEngineCore::RenderWidgetHostViewQtDelegateClient *client) override;
QWebEngineContextMenuRequest *lastContextMenuRequest() const override;
QWebEnginePage *createPageForWindow(QWebEnginePage::WebWindowType type) override;
QObject *accessibilityParentObject() override;
@@ -102,7 +104,7 @@ public:
virtual ~QWebEngineViewPrivate();
static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view);
static void bindPageAndWidget(QWebEnginePage *page,
- QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget);
+ QtWebEngineCore::WebEngineQuickWidget *widget);
QIcon webActionIcon(QWebEnginePage::WebAction action);
void unhandledKeyEvent(QKeyEvent *event) override;
void focusContainer() override;
@@ -117,24 +119,6 @@ public:
QWebEngineContextMenuRequest *m_contextRequest;
};
-#ifndef QT_NO_ACCESSIBILITY
-class QWebEngineViewAccessible : public QAccessibleWidget
-{
-public:
- QWebEngineViewAccessible(QWebEngineView *o) : QAccessibleWidget(o)
- {}
-
- bool isValid() const override;
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface *child) const override;
-
-private:
- QWebEngineView *view() const { return static_cast<QWebEngineView *>(object()); }
-};
-#endif // QT_NO_ACCESSIBILITY
-
class QContextMenuBuilder : public QtWebEngineCore::RenderViewContextMenuQt
{
public:
diff --git a/src/webenginewidgets/qwebengine_accessible.cpp b/src/webenginewidgets/qwebengine_accessible.cpp
new file mode 100644
index 000000000..a1b4bc889
--- /dev/null
+++ b/src/webenginewidgets/qwebengine_accessible.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 "qwebengine_accessible.h"
+
+#include "qwebengineview.h"
+#include "qwebengineview_p.h"
+
+#include "web_contents_adapter.h"
+
+#if QT_CONFIG(accessibility)
+
+QT_BEGIN_NAMESPACE
+
+QWebEngineViewAccessible::QWebEngineViewAccessible(QWebEngineView *o) : QAccessibleWidget(o)
+{
+}
+
+bool QWebEngineViewAccessible::isValid() const
+{
+ if (!QAccessibleWidget::isValid())
+ return false;
+
+ if (!view() || !view()->d_func() || !view()->d_func()->page || !view()->d_func()->page->d_func())
+ return false;
+
+ return true;
+}
+
+QAccessibleInterface *QWebEngineViewAccessible::focusChild() const
+{
+ if (child(0) && child(0)->focusChild())
+ return child(0)->focusChild();
+ return const_cast<QWebEngineViewAccessible *>(this);
+}
+
+int QWebEngineViewAccessible::childCount() const
+{
+ return child(0) ? 1 : 0;
+}
+
+QAccessibleInterface *QWebEngineViewAccessible::child(int index) const
+{
+ if (index == 0 && isValid())
+ return view()->page()->d_func()->adapter->browserAccessible();
+ return nullptr;
+}
+
+int QWebEngineViewAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ if (child(0) && c == child(0))
+ return 0;
+ return -1;
+}
+
+QWebEngineView *QWebEngineViewAccessible::view() const
+{
+ return static_cast<QWebEngineView *>(object());
+}
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+RenderWidgetHostViewQtDelegateWidgetAccessible::RenderWidgetHostViewQtDelegateWidgetAccessible(QWidget *o, QWebEngineView *view)
+ : QAccessibleWidget(o)
+ , m_view(view)
+{
+}
+
+bool RenderWidgetHostViewQtDelegateWidgetAccessible::isValid() const
+{
+ if (!viewAccessible() || !viewAccessible()->isValid())
+ return false;
+
+ return QAccessibleWidget::isValid();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::focusChild() const
+{
+ return viewAccessible()->focusChild();
+}
+
+int RenderWidgetHostViewQtDelegateWidgetAccessible::childCount() const
+{
+ return viewAccessible()->childCount();
+}
+
+QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::child(int index) const
+{
+ return viewAccessible()->child(index);
+}
+
+int RenderWidgetHostViewQtDelegateWidgetAccessible::indexOfChild(const QAccessibleInterface *c) const
+{
+ return viewAccessible()->indexOfChild(c);
+}
+
+QWebEngineViewAccessible *RenderWidgetHostViewQtDelegateWidgetAccessible::viewAccessible() const
+{
+ return static_cast<QWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
+}
+
+} // namespace QtWebEngineCore
+
+#endif // QT_CONFIG(accessibility)
diff --git a/src/webenginewidgets/qwebengine_accessible.h b/src/webenginewidgets/qwebengine_accessible.h
new file mode 100644
index 000000000..d0781635d
--- /dev/null
+++ b/src/webenginewidgets/qwebengine_accessible.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 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 QWEBENGINE_ACCESSIBLE_H
+#define QWEBENGINE_ACCESSIBLE_H
+
+#include <QAccessibleWidget>
+#include <QPointer>
+
+#if QT_CONFIG(accessibility)
+
+QT_BEGIN_NAMESPACE
+class QWebEngineView;
+
+class QWebEngineViewAccessible : public QAccessibleWidget
+{
+public:
+ QWebEngineViewAccessible(QWebEngineView *o);
+
+ bool isValid() const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *child) const override;
+
+private:
+ QWebEngineView *view() const;
+};
+
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQtDelegateWidgetAccessible : public QAccessibleWidget
+{
+public:
+ RenderWidgetHostViewQtDelegateWidgetAccessible(QWidget *o, QWebEngineView *view);
+
+ bool isValid() const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ QAccessibleInterface *child(int index) const override;
+ int indexOfChild(const QAccessibleInterface *child) const override;
+
+private:
+ QWebEngineViewAccessible *viewAccessible() const;
+ QPointer<QWebEngineView> m_view;
+};
+} // namespace QtWebEngineCore
+#endif // QT_CONFIG(accessibility)
+
+#endif // QWEBENGINE_ACCESSIBLE_H
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
deleted file mode 100644
index 1dd19fd67..000000000
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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 "render_widget_host_view_qt_delegate_widget.h"
-
-#include "render_widget_host_view_qt_delegate_client.h"
-
-#include <QtWebEngineCore/private/qwebenginepage_p.h>
-#include "qwebengineview.h"
-#include "qwebengineview_p.h"
-
-#include <QGuiApplication>
-#include <QMouseEvent>
-#include <QResizeEvent>
-#include <QSGImageNode>
-#include <QWindow>
-
-namespace QtWebEngineCore {
-
-class RenderWidgetHostViewQuickItem : public QQuickItem, public Compositor::Observer
-{
-public:
- RenderWidgetHostViewQuickItem(RenderWidgetHostViewQtDelegateClient *client) : m_client(client)
- {
- setFlag(ItemHasContents, true);
- // Mark that this item should receive focus when the parent QQuickWidget receives focus.
- setFocus(true);
-
- bind(client->compositorId());
- }
-
-protected:
- bool event(QEvent *event) override
- {
- if (event->type() == QEvent::ShortcutOverride)
- return m_client->forwardEvent(event);
-
- return QQuickItem::event(event);
- }
- void focusInEvent(QFocusEvent *event) override
- {
- m_client->forwardEvent(event);
- }
- void focusOutEvent(QFocusEvent *event) override
- {
- m_client->forwardEvent(event);
- }
- void inputMethodEvent(QInputMethodEvent *event) override
- {
- m_client->forwardEvent(event);
- }
- void itemChange(ItemChange change, const ItemChangeData &value) override
- {
- QQuickItem::itemChange(change, value);
- if (change == QQuickItem::ItemSceneChange) {
- for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
- disconnect(c);
- m_windowConnections.clear();
- if (value.window) {
- m_windowConnections.append(connect(
- value.window, &QQuickWindow::beforeRendering, this,
- &RenderWidgetHostViewQuickItem::onBeforeRendering, Qt::DirectConnection));
- }
- }
- }
- QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) override
- {
- auto comp = compositor();
- if (!comp)
- return nullptr;
-
- QQuickWindow *win = QQuickItem::window();
-
- // Delete old node before swapFrame to decrement refcount of
- // QImage in software mode.
- delete oldNode;
- QSGImageNode *node = win->createImageNode();
- node->setOwnsTexture(true);
-
- comp->swapFrame();
-
- QSize texSize = comp->size();
- QSizeF texSizeInDips = QSizeF(texSize) / comp->devicePixelRatio();
- node->setRect(QRectF(QPointF(0, 0), texSizeInDips));
-
- if (comp->type() == Compositor::Type::Software) {
- QImage image = comp->image();
- node->setTexture(win->createTextureFromImage(image));
- } else if (comp->type() == Compositor::Type::OpenGL) {
-#if QT_CONFIG(opengl)
- QQuickWindow::CreateTextureOptions texOpts;
- if (comp->hasAlphaChannel())
- texOpts.setFlag(QQuickWindow::TextureHasAlphaChannel);
- int texId = comp->textureId();
- node->setTexture(QNativeInterface::QSGOpenGLTexture::fromNative(texId, win, texSize, texOpts));
- node->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
-#else
- Q_UNREACHABLE();
-
-#endif
- } else {
- Q_UNREACHABLE();
- }
-
- return node;
- }
- void onBeforeRendering()
- {
- auto comp = compositor();
- if (!comp || comp->type() != Compositor::Type::OpenGL)
- return;
- comp->waitForTexture();
- }
- QVariant inputMethodQuery(Qt::InputMethodQuery query) const override
- {
- return m_client->inputMethodQuery(query);
- }
- void readyToSwap() override
- {
- // Call update() on UI thread.
- QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
- }
-
-private:
- RenderWidgetHostViewQtDelegateClient *m_client;
- QList<QMetaObject::Connection> m_windowConnections;
-};
-
-RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent)
- : QQuickWidget(parent)
- , m_client(client)
- , m_rootItem(new RenderWidgetHostViewQuickItem(client))
- , m_isPopup(false)
-{
- setFocusPolicy(Qt::StrongFocus);
- setMouseTracking(true);
- setAttribute(Qt::WA_AcceptTouchEvents);
- setAttribute(Qt::WA_OpaquePaintEvent);
- setAttribute(Qt::WA_AlwaysShowToolTips);
-
- setContent(QUrl(), nullptr, m_rootItem.data());
-
- connectRemoveParentBeforeParentDelete();
-}
-
-RenderWidgetHostViewQtDelegateWidget::~RenderWidgetHostViewQtDelegateWidget()
-{
- QWebEngineViewPrivate::bindPageAndWidget(nullptr, this);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::connectRemoveParentBeforeParentDelete()
-{
- disconnect(m_parentDestroyedConnection);
-
- if (QWidget *parent = parentWidget()) {
- m_parentDestroyedConnection = connect(parent, &QObject::destroyed,
- this,
- &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
- } else {
- m_parentDestroyedConnection = QMetaObject::Connection();
- }
-}
-
-void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
-{
- // Unset the parent, because parent is being destroyed, but the owner of this
- // RenderWidgetHostViewQtDelegateWidget is actually a RenderWidgetHostViewQt instance.
- setParent(nullptr);
-
- // If this widget represents a popup window, make sure to close it, so that if the popup was the
- // last visible top level window, the application event loop can quit if it deems it necessarry.
- if (m_isPopup)
- close();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect)
-{
- m_isPopup = true;
-
- // The keyboard events are supposed to go to the parent RenderHostView
- // so the WebUI popups should never have focus. Besides, if the parent view
- // loses focus, WebKit will cause its associated popups (including this one)
- // to be destroyed.
- setAttribute(Qt::WA_ShowWithoutActivating);
- setFocusPolicy(Qt::NoFocus);
- 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::viewGeometry() const
-{
- return QRectF(mapToGlobal(pos()), size());
-}
-
-QRect RenderWidgetHostViewQtDelegateWidget::windowGeometry() const
-{
- if (!window())
- return QRect();
- return window()->frameGeometry();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus()
-{
- // The root item always has focus within the root focus scope:
- Q_ASSERT(m_rootItem->hasFocus());
-
- setFocus();
-}
-
-bool RenderWidgetHostViewQtDelegateWidget::hasKeyboardFocus()
-{
- // The root item always has focus within the root focus scope:
- Q_ASSERT(m_rootItem->hasFocus());
-
- return hasFocus();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::lockMouse()
-{
- grabMouse();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::unlockMouse()
-{
- releaseMouse();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::show()
-{
- m_rootItem->setVisible(true);
- // Check if we're attached to a QWebEngineView, we don't
- // want to show anything else than popups as top-level.
- if (parent() || m_isPopup) {
- QQuickWidget::show();
- }
-}
-
-void RenderWidgetHostViewQtDelegateWidget::hide()
-{
- m_rootItem->setVisible(false);
- QQuickWidget::hide();
-}
-
-bool RenderWidgetHostViewQtDelegateWidget::isVisible() const
-{
- return QQuickWidget::isVisible() && m_rootItem->isVisible();
-}
-
-QWindow* RenderWidgetHostViewQtDelegateWidget::window() const
-{
- const QWidget* root = QQuickWidget::window();
- return root ? root->windowHandle() : 0;
-}
-
-void RenderWidgetHostViewQtDelegateWidget::updateCursor(const QCursor &cursor)
-{
- QQuickWidget::setCursor(cursor);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::resize(int width, int height)
-{
- QQuickWidget::resize(width, height);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::move(const QPoint &screenPos)
-{
- Q_ASSERT(m_isPopup);
- QQuickWidget::move(screenPos);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVisible, bool passwordInput)
-{
- QQuickWidget::setAttribute(Qt::WA_InputMethodEnabled, editorVisible && !passwordInput);
- qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
- if (qApp->inputMethod()->isVisible() != editorVisible)
- qApp->inputMethod()->setVisible(editorVisible);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::setInputMethodHints(Qt::InputMethodHints hints)
-{
- QQuickWidget::setInputMethodHints(hints);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color)
-{
- QQuickWidget::setClearColor(color);
- // QQuickWidget is usually blended by punching holes into widgets
- // above it to simulate the visual stacking order. If we want it to be
- // transparent we have to throw away the proper stacking order and always
- // blend the complete normal widgets backing store under it.
- bool isTranslucent = color.alpha() < 255;
- setAttribute(Qt::WA_AlwaysStackOnTop, isTranslucent);
- setAttribute(Qt::WA_OpaquePaintEvent, !isTranslucent);
- update();
-}
-
-QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQuery query) const
-{
- return m_client->inputMethodQuery(query);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent)
-{
- QQuickWidget::resizeEvent(resizeEvent);
- m_client->visualPropertiesChanged();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::showEvent(QShowEvent *event)
-{
- QQuickWidget::showEvent(event);
- // We don't have a way to catch a top-level window change with QWidget
- // but a widget will most likely be shown again if it changes, so do
- // the reconnection at this point.
- for (const QMetaObject::Connection &c : qAsConst(m_windowConnections))
- disconnect(c);
- m_windowConnections.clear();
- if (QWindow *w = window()) {
- m_windowConnections.append(connect(w, SIGNAL(xChanged(int)), SLOT(onWindowPosChanged())));
- m_windowConnections.append(connect(w, SIGNAL(yChanged(int)), SLOT(onWindowPosChanged())));
- }
- m_client->visualPropertiesChanged();
- m_client->notifyShown();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::hideEvent(QHideEvent *event)
-{
- QQuickWidget::hideEvent(event);
- m_client->notifyHidden();
-}
-
-bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
-{
- bool handled = false;
-
- // Track parent to make sure we don't get deleted.
- switch (event->type()) {
- case QEvent::ParentChange:
- connectRemoveParentBeforeParentDelete();
- break;
- default:
- break;
- }
-
- // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is
- // disabled.
- if (!isEnabled()) {
- switch (event->type()) {
- case QEvent::TabletPress:
- case QEvent::TabletRelease:
- case QEvent::TabletMove:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- case QEvent::TouchBegin:
- case QEvent::TouchUpdate:
- case QEvent::TouchEnd:
- case QEvent::TouchCancel:
- case QEvent::ContextMenu:
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
-#ifndef QT_NO_WHEELEVENT
- case QEvent::Wheel:
-#endif
- return false;
- default:
- break;
- }
- }
-
- switch (event->type()) {
- case QEvent::FocusIn:
- case QEvent::FocusOut:
- // We forward focus events later, once they have made it to the m_rootItem.
- return QQuickWidget::event(event);
- case QEvent::DragEnter:
- case QEvent::DragLeave:
- case QEvent::DragMove:
- case QEvent::Drop:
- case QEvent::HoverEnter:
- case QEvent::HoverLeave:
- case QEvent::HoverMove:
- // Let the parent handle these events.
- return false;
- default:
- break;
- }
-
- switch (event->type()) {
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseMove:
- // Don't forward mouse events synthesized by the system, which are caused by genuine touch
- // events. Chromium would then process for e.g. a mouse click handler twice, once due to the
- // system synthesized mouse event, and another time due to a touch-to-gesture-to-mouse
- // transformation done by Chromium.
- // Only allow them for popup type, since QWidgetWindow will ignore them for Qt::Popup flag,
- // which is expected to get input through synthesized mouse events (either by system or Qt)
- if (!m_isPopup && static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedBySystem) {
- Q_ASSERT(!windowFlags().testFlag(Qt::Popup));
- return true;
- }
- break;
- default:
- break;
- }
-
- if (event->type() == QEvent::MouseButtonDblClick) {
- // QWidget keeps the Qt4 behavior where the DblClick event would replace the Press event.
- // QtQuick is different by sending both the Press and DblClick events for the second press
- // where we can simply ignore the DblClick event.
- QMouseEvent *dblClick = static_cast<QMouseEvent *>(event);
- QMouseEvent press(QEvent::MouseButtonPress, dblClick->position(), dblClick->scenePosition(),
- dblClick->globalPosition(), dblClick->button(), dblClick->buttons(),
- dblClick->modifiers(), dblClick->source());
- press.setTimestamp(dblClick->timestamp());
- handled = m_client->forwardEvent(&press);
- } else
- handled = m_client->forwardEvent(event);
-
- if (!handled)
- return QQuickWidget::event(event);
- event->accept();
- return true;
-}
-
-void RenderWidgetHostViewQtDelegateWidget::unhandledWheelEvent(QWheelEvent *ev)
-{
- if (QWidget *p = parentWidget())
- qApp->sendEvent(p, ev);
-}
-
-void RenderWidgetHostViewQtDelegateWidget::onWindowPosChanged()
-{
- m_client->visualPropertiesChanged();
-}
-
-void RenderWidgetHostViewQtDelegateWidget::adapterClientChanged(WebContentsAdapterClient *client)
-{
- if (m_pageDestroyedConnection)
- disconnect(m_pageDestroyedConnection);
- QWebEnginePage *page = static_cast<QWebEnginePagePrivate *>(client)->q_func();
- QWebEngineViewPrivate::bindPageAndWidget(page, this);
- m_pageDestroyedConnection = connect(page, &QWebEnginePage::_q_aboutToDelete, this,
- [this]() { QWebEngineViewPrivate::bindPageAndWidget(nullptr, this); });
-}
-
-#if QT_CONFIG(accessibility)
-RenderWidgetHostViewQtDelegateWidgetAccessible::RenderWidgetHostViewQtDelegateWidgetAccessible(RenderWidgetHostViewQtDelegateWidget *o, QWebEngineView *view)
- : QAccessibleWidget(o)
- , m_view(view)
-{
-}
-
-bool RenderWidgetHostViewQtDelegateWidgetAccessible::isValid() const
-{
- if (!viewAccessible() || !viewAccessible()->isValid())
- return false;
-
- return QAccessibleWidget::isValid();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::focusChild() const
-{
- return viewAccessible()->focusChild();
-}
-
-int RenderWidgetHostViewQtDelegateWidgetAccessible::childCount() const
-{
- return viewAccessible()->childCount();
-}
-
-QAccessibleInterface *RenderWidgetHostViewQtDelegateWidgetAccessible::child(int index) const
-{
- return viewAccessible()->child(index);
-}
-
-int RenderWidgetHostViewQtDelegateWidgetAccessible::indexOfChild(const QAccessibleInterface *c) const
-{
- return viewAccessible()->indexOfChild(c);
-}
-
-QWebEngineViewAccessible *RenderWidgetHostViewQtDelegateWidgetAccessible::viewAccessible() const
-{
- return static_cast<QWebEngineViewAccessible *>(QAccessible::queryAccessibleInterface(m_view));
-}
-#endif // QT_CONFIG(accessibility)
-
-} // namespace QtWebEngineCore
-
-#include "moc_render_widget_host_view_qt_delegate_widget.cpp"
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
deleted file mode 100644
index 1adebd3b5..000000000
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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 RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H
-#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H
-
-#include "render_widget_host_view_qt_delegate.h"
-#include "web_contents_adapter_client.h"
-
-#include <QAccessibleWidget>
-#include <QQuickItem>
-#include <QQuickWidget>
-
-QT_BEGIN_NAMESPACE
-class QWebEnginePage;
-class QWebEngineView;
-class QWebEngineViewAccessible;
-class QWebEngineViewPrivate;
-QT_END_NAMESPACE
-
-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:
- RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent = nullptr);
- ~RenderWidgetHostViewQtDelegateWidget();
-
- void initAsPopup(const QRect&) override;
- QRectF viewGeometry() const override;
- QRect windowGeometry() const override;
- void setKeyboardFocus() override;
- bool hasKeyboardFocus() override;
- void lockMouse() override;
- void unlockMouse() override;
- void show() override;
- void hide() override;
- bool isVisible() const override;
- QWindow* window() const override;
- void updateCursor(const QCursor &) override;
- void resize(int width, int height) override;
- void move(const QPoint &screenPos) override;
- void inputMethodStateChanged(bool editorVisible, bool passwordInput) override;
- void setInputMethodHints(Qt::InputMethodHints) override;
- void setClearColor(const QColor &color) override;
- void unhandledWheelEvent(QWheelEvent *ev) override;
-
-protected:
- bool event(QEvent *event) override;
- 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;
- void adapterClientChanged(WebContentsAdapterClient *client) override;
-
-private Q_SLOTS:
- void onWindowPosChanged();
- void connectRemoveParentBeforeParentDelete();
- void removeParentBeforeParentDelete();
-
-private:
- friend QWebEngineViewPrivate;
-
- RenderWidgetHostViewQtDelegateClient *m_client;
- QScopedPointer<QQuickItem> m_rootItem;
- bool m_isPopup;
- QColor m_clearColor;
- QList<QMetaObject::Connection> m_windowConnections;
- QWebEnginePage *m_page = nullptr;
- QMetaObject::Connection m_parentDestroyedConnection;
- QMetaObject::Connection m_pageDestroyedConnection;
-};
-
-#if QT_CONFIG(accessibility)
-class RenderWidgetHostViewQtDelegateWidgetAccessible : public QAccessibleWidget
-{
-public:
- RenderWidgetHostViewQtDelegateWidgetAccessible(RenderWidgetHostViewQtDelegateWidget *o, QWebEngineView *view);
-
- bool isValid() const override;
- QAccessibleInterface *focusChild() const override;
- int childCount() const override;
- QAccessibleInterface *child(int index) const override;
- int indexOfChild(const QAccessibleInterface *child) const override;
-
-private:
- QWebEngineViewAccessible *viewAccessible() const;
- QWebEngineView *m_view;
-};
-#endif // QT_CONFIG(accessibility)
-
-} // namespace QtWebEngineCore
-
-#endif
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 10aeede25..c747e6b8f 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -463,7 +463,6 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
void tst_QQuickWebEngineView::inputMethod()
{
m_window->show();
- QTRY_VERIFY(qApp->focusObject());
QQuickItem *input;
QQuickWebEngineView *view = webEngineView();
@@ -471,18 +470,21 @@ void tst_QQuickWebEngineView::inputMethod()
view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
+ QTRY_VERIFY(qobject_cast<QQuickItem *>(qApp->focusObject()));
input = qobject_cast<QQuickItem *>(qApp->focusObject());
QVERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
runJavaScript("document.getElementById('inputField').focus();");
QTRY_COMPARE(activeElementId(view), QStringLiteral("inputField"));
+ QTRY_VERIFY(qobject_cast<QQuickItem *>(qApp->focusObject()));
input = qobject_cast<QQuickItem *>(qApp->focusObject());
QTRY_VERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
runJavaScript("document.getElementById('inputField').blur();");
QTRY_VERIFY(activeElementId(view).isEmpty());
+ QTRY_VERIFY(qobject_cast<QQuickItem *>(qApp->focusObject()));
input = qobject_cast<QQuickItem *>(qApp->focusObject());
QTRY_VERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 57f6b24a8..63d39dd59 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1441,15 +1441,18 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
return viewWidth;
};
+ QCOMPARE(jsViewWidth(), originalViewWidth);
+
// Resize the "spacer" widget, and implicitly change the global position of the QWebEngineView.
const int offset = 50;
spacer.setMinimumWidth(spacer.size().width() + offset);
+
QTRY_COMPARE(jsViewWidth(), originalViewWidth - offset);
makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo")));
QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
QTRY_VERIFY(!popup->position().isNull());
- QCOMPARE(popupPos + QPoint(50, 0), popup->position());
+ QCOMPARE(popupPos + QPoint(offset, 0), popup->position());
}
#ifdef Q_OS_MAC
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 921b0c52f..883720490 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -106,6 +106,7 @@ private Q_SLOTS:
void changePage();
void reusePage_data();
void reusePage();
+ void setLoadedPage();
void microFocusCoordinates();
void focusInputTypes();
void unhandledKeyEventPropagation();
@@ -399,7 +400,7 @@ void tst_QWebEngineView::reusePage()
view1->show();
QVERIFY(QTest::qWaitForWindowExposed(view1));
delete view1;
- QVERIFY(page != 0); // deleting view must not have deleted the page, since it's not a child of view
+ QVERIFY(page != nullptr); // deleting view must not have deleted the page, since it's not a child of view
QWebEngineView *view2 = new QWebEngineView;
view2->setPage(page.data());
@@ -412,6 +413,23 @@ void tst_QWebEngineView::reusePage()
QDir::setCurrent(QApplication::applicationDirPath());
}
+void tst_QWebEngineView::setLoadedPage()
+{
+ // MEMO load page first to make sure that just simple attach to view would draw its content
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ page.setHtml(QString("<html><body bgcolor=\"%1\"></body></html>").arg(QColor(Qt::yellow).name()));
+ QTRY_VERIFY(loadSpy.count() == 1 && loadSpy.first().first().toBool());
+
+ QWebEngineView view;
+ view.resize(480, 320);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ view.setPage(&page);
+ QTRY_COMPARE(view.grab().toImage().pixelColor(QPoint(view.width() / 2, view.height() / 2)), Qt::yellow);
+}
+
// Class used in crashTests
class WebViewCrashTest : public QObject {
Q_OBJECT
diff --git a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
index 7263904ce..738010ac8 100644
--- a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
+++ b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
@@ -170,6 +170,7 @@ void tst_Spellchecking::spellcheck()
QVariantList list = evaluateJavaScriptSync(m_view->page(), "findWordPosition('I lowe Qt ....','lowe');").toList();
QRect rect(list[0].value<int>(),list[1].value<int>(),list[2].value<int>(),list[3].value<int>());
+ QTRY_VERIFY(m_view->focusWidget());
//type text, spellchecker needs time
QTest::mouseMove(m_view->focusWidget(), QPoint(20,20));
QTest::mousePress(m_view->focusWidget(), Qt::LeftButton, {}, QPoint(20,20));
@@ -182,7 +183,7 @@ void tst_Spellchecking::spellcheck()
// make sure text is there
QString result = evaluateJavaScriptSync(m_view->page(), "text();").toString();
- QVERIFY(result == text);
+ QCOMPARE(result, text);
bool gotMisspelledWord = false; // clumsy QTRY_VERIFY still execs expr after first success
QString detail;