summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@qt.io>2025-10-20 10:10:56 +0200
committerMichal Klocek <michal.klocek@qt.io>2025-12-01 17:11:29 +0100
commit452e0aaed82ee01833455ef4616fb59a9fc7fc2b (patch)
tree413bb8733db0815aea4839e6f22b983beb080c2a
parent68322bd57bd790d609e85599d3c524c9650e31c2 (diff)
Make html comoboxes great again (2/2)
This patch is band-aid patch to handle QQuickWebEngineView transformations like scaling and rotation. Before this patch we used mapToGlobal to get viewGeometry however if the item is transformed by rotation and scaling the mapToGlobal will return something not expected by Chromium. Imagine: --------- ------- | aaaaa | | aaaa| | bbbbb | => rotates 90 => | bbbb| | ccccc | | cccc| --------- | | ------- So Chromium still 'thinks' that content is displayed horizontally and just window geometry changed. Moreover, mapToGlobal for rect QRectF(tl,rb) when this is rotated by 90 degree will return QRectF(tr,bl).nomralized() in global coordinates. This is not correct geometry. As band-aid solution for transform case, go with fixed view geometry of QRect(0,0,widith(),hight()) This will allow to Chromium get untransformed popup position, which we later transform in delegate. Fix and simplify transformation calculations in QQuickWindow delegate using just global screen coordinates. Note having fixed view geometry will have side effect like accessibility mappings broken or screen edge detection not working (if dropdown comobox can not be displayed due to screen border it is simply moved over the combobox filed) Therefore, this is just band-aid solution, which covers anyway rare use case of doing the QQuickWebview transformation within the scene. Tested with openbox, weston, mutter-wayland, mutter-xwayland. Pick-to: 6.10 Change-Id: I3c2d662ccd093793da6b5e192d79c9e22e451789 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.cpp25
-rw-r--r--src/core/render_widget_host_view_qt_delegate_item.h1
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp39
-rw-r--r--src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h1
4 files changed, 28 insertions, 38 deletions
diff --git a/src/core/render_widget_host_view_qt_delegate_item.cpp b/src/core/render_widget_host_view_qt_delegate_item.cpp
index 4886351ba..aaf8bb263 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.cpp
+++ b/src/core/render_widget_host_view_qt_delegate_item.cpp
@@ -55,19 +55,30 @@ void RenderWidgetHostViewQtDelegateItem::initAsPopup(const QRect &screenRect)
{
Q_ASSERT(m_isPopup);
setSize(screenRect.size());
+ m_popupRect = screenRect;
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(QPointF(0, 0));
- const QPointF p2 = mapToGlobal(QPointF(width(), height()));
- QRectF geometry = QRectF(p1, p2).normalized();
- // But keep the size untransformed to behave like other QQuickItems.
- geometry.setSize(size());
- return geometry;
+ const QTransform transform = itemTransform(nullptr, nullptr);
+
+ const bool isTransformed = transform.type() > QTransform::TxTranslate;
+
+ if (!isTransformed) {
+ // find the correct top left corner
+ const QPointF tl = mapToGlobal(QPointF(0, 0));
+ return QRectF(tl, size());
+ } else if (!m_isPopup) {
+ // keep it simply untransformed, as we transform only delegate as there no way
+ // to return screen rect which would makes sense in that case
+ // this is just band-aid workaround to support rotation and scaling
+ return QRectF(QPointF(0, 0), size());
+ } else {
+ // this is transformed and popup, keep chromium unaware of transformations
+ return m_popupRect;
+ }
}
QRect RenderWidgetHostViewQtDelegateItem::windowGeometry() const
diff --git a/src/core/render_widget_host_view_qt_delegate_item.h b/src/core/render_widget_host_view_qt_delegate_item.h
index a4246b8ff..6775e4063 100644
--- a/src/core/render_widget_host_view_qt_delegate_item.h
+++ b/src/core/render_widget_host_view_qt_delegate_item.h
@@ -115,6 +115,7 @@ private:
RenderWidgetHostViewQtDelegateClient *m_client;
bool m_isPopup;
+ QRectF m_popupRect;
QColor m_clearColor;
Qt::InputMethodHints m_inputMethodHints = {};
QList<QMetaObject::Connection> m_windowConnections;
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 9e546089b..3ad88ca39 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -27,19 +27,6 @@ static inline struct ItemTransform getTransformValuesFromItemTree(QQuickItem *it
return returnValue;
}
-static inline QPointF transformPoint(const QPointF &point, const QTransform &transform,
- const QPointF &offset, const QQuickItem *parent)
-{
- // make scene vector
- QPointF a = point - offset;
- // apply local transformation
- a = transform.map(a);
- // make screen coordinates
- a = parent->mapFromScene(a);
- a = parent->mapToGlobal(a);
- return a;
-}
-
RenderWidgetHostViewQtDelegateQuickWindow::RenderWidgetHostViewQtDelegateQuickWindow(
RenderWidgetHostViewQtDelegateItem *realDelegate, QWindow *parent)
: QQuickWindow(), m_realDelegate(realDelegate), m_virtualParent(nullptr), m_transformed(false)
@@ -64,37 +51,29 @@ void RenderWidgetHostViewQtDelegateQuickWindow::setVirtualParent(QQuickItem *vir
}
// rect is visual geometry in form of global screen coordinates
-// chromium knows nothing about local transformation
+// if menu is transformed screen rect is simply given in screen
+// coordinates where parent geometry is simply QRect(0,0,size())
void RenderWidgetHostViewQtDelegateQuickWindow::InitAsPopup(const QRect &rect)
{
// To decide if there is a scale or rotation, we check it from the transfrom
// to also cover the case where the scale is higher up in the item tree.
QTransform transform = m_virtualParent->itemTransform(nullptr, nullptr);
- m_transformed = transform.isRotating() || transform.isScaling();
+ m_transformed = transform.type() > QTransform::TxTranslate;
if (m_transformed) {
// code below tries to cover the case where webengine view is rotated or scaled,
// the code assumes the rotation is in the form of 90, 180, 270 degrees
// to archive that we keep chromium unaware of transformation and we transform
// just the window content.
- m_rect = rect;
- // get parent window (scene) offset
- QPointF offset = m_virtualParent->mapFromScene(QPoint(0, 0));
- offset = m_virtualParent->mapToGlobal(offset);
- // get local transform
- QPointF tl = transformPoint(rect.topLeft(), transform, offset, m_virtualParent);
- QPointF br = transformPoint(rect.bottomRight(), transform, offset, m_virtualParent);
- QRectF popupRect(tl, br);
- popupRect = popupRect.normalized();
- // include offset from parent window
- popupRect.moveTo(popupRect.topLeft() - offset);
- setGeometry(popupRect.adjusted(0, 0, 1, 1).toRect());
- // add offset since screenRect and transformed popupRect one are different and
- // we want to rotate in center.
+ QRectF popupRect = transform.mapRect(rect);
+ // adjust for scene offset
+ const QPointF offset =
+ m_virtualParent->mapToGlobal(m_virtualParent->mapFromScene(QPoint(0, 0)));
+ popupRect.translate(offset);
+ setGeometry(popupRect.normalized().toRect());
m_realDelegate->setX(-rect.width() / 2.0 + geometry().width() / 2.0);
m_realDelegate->setY(-rect.height() / 2.0 + geometry().height() / 2.0);
m_realDelegate->setTransformOrigin(QQuickItem::Center);
-
// We need to read the values for scale and rotation from the item tree as it is not
// sufficient to only use the virtual parent item and its parent for the case that the
// scale or rotation is applied higher up the item tree.
diff --git a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h
index c39d2f24a..dff1b81a0 100644
--- a/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h
+++ b/src/webenginequick/render_widget_host_view_qt_delegate_quickwindow_p.h
@@ -49,7 +49,6 @@ public:
private:
QPointer<RenderWidgetHostViewQtDelegateItem> m_realDelegate;
QQuickItem *m_virtualParent;
- QRect m_rect;
bool m_transformed;
};