Fix QWidget::mapTo/FromGlobal() when embedded in QGraphicsView.

Map the positions via QGraphicsScene and the first QGraphicsView
(as is done in existing code). Fall back to the previous code
path when no QGraphicsView exists, which is hit in the tests.

Change-Id: I0754765d05cded6bc1b64045f2513fef8afde337
Task-number: QTBUG-41135
Reviewed-by: Frederik Gladhorn <frederik.gladhorn@theqtcompany.com>
This commit is contained in:
Friedemann Kleint 2014-10-21 12:24:52 +02:00
parent f3699510d4
commit ed0245e145
2 changed files with 50 additions and 0 deletions

View File

@ -12250,6 +12250,17 @@ QPaintEngine *QWidget::paintEngine() const
*/
QPoint QWidget::mapToGlobal(const QPoint &pos) const
{
#ifndef QT_NO_GRAPHICSVIEW
Q_D(const QWidget);
if (d->extra && d->extra->proxyWidget) {
const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views();
if (!views.isEmpty()) {
const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos);
const QPoint viewPortPos = views.first()->mapFromScene(scenePos);
return views.first()->viewport()->mapToGlobal(viewPortPos);
}
}
#endif // !QT_NO_GRAPHICSVIEW
int x = pos.x(), y = pos.y();
const QWidget *w = this;
while (w) {
@ -12274,6 +12285,17 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const
*/
QPoint QWidget::mapFromGlobal(const QPoint &pos) const
{
#ifndef QT_NO_GRAPHICSVIEW
Q_D(const QWidget);
if (d->extra && d->extra->proxyWidget) {
const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views();
if (!views.isEmpty()) {
const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos);
const QPointF scenePos = views.first()->mapToScene(viewPortPos);
return d->extra->proxyWidget->mapFromScene(scenePos).toPoint();
}
}
#endif // !QT_NO_GRAPHICSVIEW
int x = pos.x(), y = pos.y();
const QWidget *w = this;
while (w) {

View File

@ -174,6 +174,7 @@ private slots:
void clickFocus();
void windowFrameMargins();
void QTBUG_6986_sendMouseEventToAlienWidget();
void mapToGlobal();
};
// Subclass that exposes the protected functions.
@ -3659,5 +3660,32 @@ void tst_QGraphicsProxyWidget::QTBUG_6986_sendMouseEventToAlienWidget()
QTRY_COMPARE(scene.hoverButton->hoverLeaveReceived, true);
}
void tst_QGraphicsProxyWidget::mapToGlobal() // QTBUG-41135
{
const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
const QSize size = availableGeometry.size() / 5;
QGraphicsScene scene;
QGraphicsView view(&scene);
view.setWindowTitle(QTest::currentTestFunction());
view.resize(size);
view.move(availableGeometry.bottomRight() - QPoint(size.width(), size.height()) - QPoint(100, 100));
QWidget *embeddedWidget = new QWidget;
embeddedWidget->setFixedSize(size / 2);
scene.addWidget(embeddedWidget);
QApplication::setActiveWindow(&view);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
const QPoint embeddedCenter = embeddedWidget->geometry().center();
const QPoint embeddedCenterGlobal = embeddedWidget->mapToGlobal(embeddedCenter);
QCOMPARE(embeddedWidget->mapFromGlobal(embeddedCenterGlobal), embeddedCenter);
// This should be equivalent to the view center give or take rounding
// errors due to odd window margins
const QPoint viewCenter = view.geometry().center();
QVERIFY2((viewCenter - embeddedCenterGlobal).manhattanLength() <= 2,
qPrintable(QStringLiteral("%1, %2 != %3, %4")
.arg(viewCenter.x()).arg(viewCenter.y())
.arg(embeddedCenterGlobal.x()).arg(embeddedCenterGlobal.y())));
}
QTEST_MAIN(tst_QGraphicsProxyWidget)
#include "tst_qgraphicsproxywidget.moc"