From ea1395e48205dd45f2485a40e8a3f23273cc4ad3 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 7 May 2019 10:58:20 +0200 Subject: Place popups in correct locations for transformed webengine views MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Transform between global coordinates have the relative position to the window transforms and coordinates where they are not. Note, the content of the popup is not transformed yet. Task-number: QTBUG-73244 Change-Id: I74b75771e8b60b409ab82c6238308b2497c435ef Reviewed-by: Jüri Valdmann --- src/webengine/api/qquickwebengineview.cpp | 1 + .../render_widget_host_view_qt_delegate_quick.cpp | 8 ++++- ...er_widget_host_view_qt_delegate_quickwindow.cpp | 42 +++++++++++++++++++--- ...nder_widget_host_view_qt_delegate_quickwindow.h | 7 ++-- 4 files changed, 50 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index 9826ebfe2..976e6ed04 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -219,6 +219,7 @@ RenderWidgetHostViewQtDelegate *QQuickWebEngineViewPrivate::CreateRenderWidgetHo RenderWidgetHostViewQtDelegateQuick *quickDelegate = new RenderWidgetHostViewQtDelegateQuick(client, /*isPopup = */ true); if (hasWindowCapability) { RenderWidgetHostViewQtDelegateQuickWindow *wrapperWindow = new RenderWidgetHostViewQtDelegateQuickWindow(quickDelegate); + wrapperWindow->setVirtualParent(q); quickDelegate->setParentItem(wrapperWindow->contentItem()); return wrapperWindow; } diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp index 4d3a71a79..b636448b3 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp @@ -101,7 +101,13 @@ void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r) QRectF RenderWidgetHostViewQtDelegateQuick::viewGeometry() const { - return QRectF(mapToGlobal(QPointF(0, 0)), size()); + // 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 RenderWidgetHostViewQtDelegateQuick::windowGeometry() const diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp index 91ef84960..c085aacd7 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp @@ -44,8 +44,9 @@ namespace QtWebEngineCore { -RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegate *realDelegate) +RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate) : m_realDelegate(realDelegate) + , m_virtualParent(nullptr) { setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus); } @@ -54,17 +55,43 @@ RenderWidgetHostViewQtDelegateQuickWindow::~RenderWidgetHostViewQtDelegateQuickW { } +void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *virtualParent) +{ + Q_ASSERT(virtualParent); + m_virtualParent = virtualParent; +} + +static inline QRectF mapRectToGlobal(const QQuickItem *item, const QRectF &rect) +{ + const QPointF p1 = item->mapToGlobal(rect.topLeft()); + const QPointF p2 = item->mapToGlobal(rect.bottomRight()); + return QRectF(p1, p2).normalized(); +} + +static inline QRectF mapRectFromGlobal(const QQuickItem *item, const QRectF &rect) +{ + const QPointF p1 = item->mapFromGlobal(rect.topLeft()); + const QPointF p2 = item->mapFromGlobal(rect.bottomRight()); + return QRectF(p1, p2).normalized(); +} + void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &screenRect) { - m_realDelegate->initAsPopup(QRect(QPoint(0, 0), screenRect.size())); - setGeometry(screenRect); + QRectF popupRect(screenRect); + popupRect = mapRectFromGlobal(m_virtualParent, popupRect); + popupRect = m_virtualParent->mapRectToScene(popupRect); + popupRect = mapRectToGlobal(m_virtualParent, popupRect); + + m_realDelegate->initAsPopup(QRect(QPoint(0, 0), popupRect.size().toSize())); + popupRect.setSize(screenRect.size()); + setGeometry(popupRect.toAlignedRect()); raise(); show(); } QRectF RenderWidgetHostViewQtDelegateQuickWindow::viewGeometry() const { - return m_realDelegate->viewGeometry(); + return geometry(); } QRect RenderWidgetHostViewQtDelegateQuickWindow::windowGeometry() const @@ -138,7 +165,12 @@ void RenderWidgetHostViewQtDelegateQuickWindow::resize(int width, int height) void RenderWidgetHostViewQtDelegateQuickWindow::move(const QPoint &screenPos) { - QQuickWindow::setPosition(screenPos); + QRectF popupRect(screenPos, size()); + popupRect = mapRectFromGlobal(m_virtualParent, popupRect); + popupRect = m_virtualParent->mapRectToScene(popupRect); + popupRect = mapRectToGlobal(m_virtualParent, popupRect); + + QQuickWindow::setPosition(popupRect.topLeft().toPoint()); } } // namespace QtWebEngineCore diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h index 35a30d976..ab583bd63 100644 --- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h +++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h @@ -52,7 +52,7 @@ namespace QtWebEngineCore { class RenderWidgetHostViewQtDelegateQuickWindow : public QQuickWindow , public RenderWidgetHostViewQtDelegate { public: - RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegate *realDelegate); + RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegateQuick *realDelegate); ~RenderWidgetHostViewQtDelegateQuickWindow(); void initAsPopup(const QRect&) override; @@ -80,8 +80,11 @@ public: void setClearColor(const QColor &) override { } bool copySurface(const QRect &, const QSize &, QImage &) override { return false; } + void setVirtualParent(QQuickItem *virtualParent); + private: - QScopedPointer m_realDelegate; + QScopedPointer m_realDelegate; + QQuickItem *m_virtualParent; }; } // namespace QtWebEngineCore -- cgit v1.2.3