diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-07 10:58:20 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-05-14 07:58:21 +0000 |
commit | ea1395e48205dd45f2485a40e8a3f23273cc4ad3 (patch) | |
tree | d03c3b5ec616e79c2305580b7c0182d5f8e005c8 | |
parent | cc105d084620d19953e90abf006b75c3c4c498b0 (diff) |
Place popups in correct locations for transformed webengine views
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 <juri.valdmann@qt.io>
4 files changed, 50 insertions, 8 deletions
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<RenderWidgetHostViewQtDelegate> m_realDelegate; + QScopedPointer<RenderWidgetHostViewQtDelegateQuick> m_realDelegate; + QQuickItem *m_virtualParent; }; } // namespace QtWebEngineCore |