summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-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.cpp442
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.h161
-rw-r--r--src/core/web_contents_delegate_qt.cpp4
8 files changed, 627 insertions, 53 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/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
new file mode 100644
index 000000000..75ed57271
--- /dev/null
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -0,0 +1,442 @@
+/****************************************************************************
+**
+** 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 "render_widget_host_view_qt_delegate_item.h"
+
+#include "render_widget_host_view_qt_delegate_client.h"
+
+#include <QGuiApplication>
+#include <QMouseEvent>
+#include <QSGImageNode>
+#include <QWindow>
+
+namespace QtWebEngineCore {
+
+RenderWidgetHostViewQtDelegateItem::RenderWidgetHostViewQtDelegateItem(RenderWidgetHostViewQtDelegateClient *client, bool isPopup)
+ : m_client(client)
+ , m_isPopup(isPopup)
+{
+ setFlag(ItemHasContents);
+ setAcceptedMouseButtons(Qt::AllButtons);
+ setAcceptHoverEvents(true);
+ setAcceptTouchEvents(true);
+ if (!isPopup) {
+ setFocus(true);
+ setActiveFocusOnTab(true);
+ }
+ bind(client->compositorId());
+}
+
+RenderWidgetHostViewQtDelegateItem::~RenderWidgetHostViewQtDelegateItem()
+{
+ if (m_widgetDelegate) {
+ m_widgetDelegate->Unbind();
+ m_widgetDelegate->Destroy();
+ }
+}
+
+void RenderWidgetHostViewQtDelegateItem::initAsPopup(const QRect &screenRect)
+{
+ Q_ASSERT(m_isPopup);
+ setSize(screenRect.size());
+ if (m_widgetDelegate)
+ m_widgetDelegate->InitAsPopup(screenRect);
+}
+
+QRectF RenderWidgetHostViewQtDelegateItem::viewGeometry() const
+{
+ // Transform the entire rect to find the correct top left corner.
+ const QPointF p1 = mapToGlobal(mapFromScene(QPointF(0, 0)));
+ const QPointF p2 = mapToGlobal(mapFromScene(QPointF(width(), height())));
+ QRectF geometry = QRectF(p1, p2).normalized();
+ // But keep the size untransformed to behave like other QQuickItems.
+ geometry.setSize(size());
+ return geometry;
+}
+
+QRect RenderWidgetHostViewQtDelegateItem::windowGeometry() const
+{
+ if (!Window())
+ return QRect();
+ return Window()->frameGeometry();
+}
+
+void RenderWidgetHostViewQtDelegateItem::setKeyboardFocus()
+{
+ setFocus(true);
+}
+
+bool RenderWidgetHostViewQtDelegateItem::hasKeyboardFocus()
+{
+ return hasActiveFocus();
+}
+
+void RenderWidgetHostViewQtDelegateItem::lockMouse()
+{
+ grabMouse();
+}
+
+void RenderWidgetHostViewQtDelegateItem::unlockMouse()
+{
+ ungrabMouse();
+}
+
+void RenderWidgetHostViewQtDelegateItem::show()
+{
+ if (isVisible())
+ m_client->notifyShown();
+ else
+ setVisible(true);
+}
+
+void RenderWidgetHostViewQtDelegateItem::hide()
+{
+ if (isVisible())
+ setVisible(false);
+ else
+ m_client->notifyHidden();
+}
+
+bool RenderWidgetHostViewQtDelegateItem::isVisible() const
+{
+ return QQuickItem::isVisible();
+}
+
+QWindow *RenderWidgetHostViewQtDelegateItem::Window() const
+{
+ if (m_widgetDelegate) {
+ if (auto *window = m_widgetDelegate->Window())
+ return window;
+ }
+ return QQuickItem::window();
+}
+
+void RenderWidgetHostViewQtDelegateItem::readyToSwap()
+{
+ // Call update() on UI thread.
+ QMetaObject::invokeMethod(this, &QQuickItem::update, Qt::QueuedConnection);
+}
+
+void RenderWidgetHostViewQtDelegateItem::updateCursor(const QCursor &cursor)
+{
+ setCursor(cursor);
+}
+
+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 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);
+}
+
+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);
+
+#if QT_CONFIG(gestures)
+ if (event->type() == QEvent::NativeGesture)
+ return m_client->forwardEvent(event);
+#endif
+
+ return QQuickItem::event(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::focusInEvent(QFocusEvent *event)
+{
+#if QT_CONFIG(accessibility)
+ 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 RenderWidgetHostViewQtDelegateItem::focusOutEvent(QFocusEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::mousePressEvent(QMouseEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate) {
+ if (m_widgetDelegate->ActiveFocusOnPress()) {
+ forceActiveFocus();
+ } else {
+ event->ignore();
+ return;
+ }
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::mouseMoveEvent(QMouseEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress()) {
+ event->ignore();
+ return;
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::mouseReleaseEvent(QMouseEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress()) {
+ event->ignore();
+ return;
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::keyPressEvent(QKeyEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::keyReleaseEvent(QKeyEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::wheelEvent(QWheelEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::touchEvent(QTouchEvent *event)
+{
+ if (!m_isPopup && m_widgetDelegate) {
+ if (event->type() == QEvent::TouchBegin && m_widgetDelegate->ActiveFocusOnPress())
+ forceActiveFocus();
+
+ if (!m_widgetDelegate->ActiveFocusOnPress()) {
+ event->ignore();
+ return;
+ }
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::hoverMoveEvent(QHoverEvent *event)
+{
+ if ((!m_isPopup && m_widgetDelegate && !m_widgetDelegate->ActiveFocusOnPress())
+ || event->position() == event->oldPosF()) {
+ event->ignore();
+ return;
+ }
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::hoverLeaveEvent(QHoverEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+QVariant RenderWidgetHostViewQtDelegateItem::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+ return m_client->inputMethodQuery(query);
+}
+
+void RenderWidgetHostViewQtDelegateItem::inputMethodEvent(QInputMethodEvent *event)
+{
+ m_client->forwardEvent(event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
+{
+ QQuickItem::geometryChange(newGeometry, oldGeometry);
+ m_client->visualPropertiesChanged();
+}
+
+void RenderWidgetHostViewQtDelegateItem::itemChange(ItemChange change, const ItemChangeData &value)
+{
+ 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, &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)
+ m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
+ }
+ m_client->visualPropertiesChanged();
+ } else if (change == QQuickItem::ItemVisibleHasChanged) {
+ if (value.boolValue) {
+ m_client->notifyShown();
+ } else {
+ m_client->notifyHidden();
+ if (!m_isPopup)
+ onHide();
+ }
+ }
+}
+
+QSGNode *RenderWidgetHostViewQtDelegateItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ 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));
+#if QT_CONFIG(opengl)
+ } else if (comp->type() == Compositor::Type::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);
+#endif
+ } else {
+ Q_UNREACHABLE();
+ }
+
+ return node;
+}
+
+void RenderWidgetHostViewQtDelegateItem::onBeforeRendering()
+{
+ auto comp = compositor();
+ if (!comp || comp->type() != Compositor::Type::OpenGL)
+ return;
+ comp->waitForTexture();
+}
+
+void RenderWidgetHostViewQtDelegateItem::onWindowPosChanged()
+{
+ m_client->visualPropertiesChanged();
+}
+
+void RenderWidgetHostViewQtDelegateItem::onHide()
+{
+ QFocusEvent event(QEvent::FocusOut, Qt::OtherFocusReason);
+ m_client->forwardEvent(&event);
+}
+
+void RenderWidgetHostViewQtDelegateItem::adapterClientChanged(WebContentsAdapterClient *client)
+{
+ m_adapterClient = client;
+ if (m_widgetDelegate)
+ m_widgetDelegate->Bind(client);
+}
+
+void RenderWidgetHostViewQtDelegateItem::unhandledWheelEvent(QWheelEvent *ev)
+{
+ if (QWindow *w = Window()) {
+ if (QWindow *p = w->parent())
+ qApp->sendEvent(p, ev);
+ }
+}
+
+} // namespace QtWebEngineCore
diff --git a/src/core/render_widget_host_view_qt_delegate_item.h b/src/core/render_widget_host_view_qt_delegate_item.h
new file mode 100644
index 000000000..515f2b28c
--- /dev/null
+++ b/src/core/render_widget_host_view_qt_delegate_item.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** 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 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 <QtQuick/QQuickItem>
+
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineView;
+class QQuickWebEngineViewPrivate;
+class QWebEnginePage;
+class QWebEngineViewPrivate;
+QT_END_NAMESPACE
+
+namespace QtWebEngineCore {
+
+class RenderWidgetHostViewQtDelegateClient;
+class WebContentsAdapterClient;
+class WebEngineQuickWidget;
+
+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:
+ RenderWidgetHostViewQtDelegateItem(RenderWidgetHostViewQtDelegateClient *client, bool isPopup);
+ ~RenderWidgetHostViewQtDelegateItem();
+
+ 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;
+
+ void readyToSwap() override;
+
+ void setWidgetDelegate(WidgetDelegate *delegate);
+
+protected:
+ bool event(QEvent *event) override;
+ void focusInEvent(QFocusEvent *event) override;
+ void focusOutEvent(QFocusEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void keyReleaseEvent(QKeyEvent *event) override;
+ void wheelEvent(QWheelEvent *event) override;
+ void touchEvent(QTouchEvent *event) override;
+ void hoverMoveEvent(QHoverEvent *event) override;
+ void hoverLeaveEvent(QHoverEvent *event) override;
+ QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
+ void inputMethodEvent(QInputMethodEvent *event) override;
+ void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
+ 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;
+ 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;
+};
+
+} // namespace QtWebEngineCore
+
+#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);
}