diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index a6af19b030..f59a6f759e 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -473,27 +473,22 @@ public: // These helper functions return the (available) geometry for the screen // the widget is on, and takes care if this one is embedded in a QGraphicsView. - static QRect graphicsViewParentRect(const QWidget *widget) + static QWidget *parentGraphicsView(const QWidget *widget) { - QRect rect; #if QT_CONFIG(graphicsview) QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget); //It's embedded if it has an ancestor if (ancestorProxy) { if (!bypassGraphicsProxyWidget(widget) && ancestorProxy->scene() != nullptr) { - // One view, let be smart and return the viewport rect then the popup is aligned - if (ancestorProxy->scene()->views().size() == 1) { - QGraphicsView *view = ancestorProxy->scene()->views().at(0); - rect = view->mapToScene(view->viewport()->rect()).boundingRect().toRect(); - } else { - rect = ancestorProxy->scene()->sceneRect().toRect(); + if (!ancestorProxy->scene()->views().empty()) { + return ancestorProxy->scene()->views().at(0); } } } #else Q_UNUSED(widget); #endif - return rect; + return nullptr; } static QRect screenGeometry(const QWidget *widget) @@ -506,11 +501,10 @@ public: return availableScreenGeometry(widget, QPoint(), false); } - static QRect screenGeometry(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true) + static QScreen *screen(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true) { - QRect rect = graphicsViewParentRect(widget); - if (!rect.isNull()) - return rect; + while (QWidget *view = parentGraphicsView(widget)) + widget = view; QScreen *screen = nullptr; if (hasPosition) @@ -518,22 +512,17 @@ public: if (!screen) screen = widget->screen(); - return screen->geometry(); + return screen; + } + + static QRect screenGeometry(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true) + { + return screen(widget, globalPosition, hasPosition)->geometry(); } static QRect availableScreenGeometry(const QWidget *widget, const QPoint &globalPosition, bool hasPosition = true) { - QRect rect = graphicsViewParentRect(widget); - if (!rect.isNull()) - return rect; - - QScreen *screen = nullptr; - if (hasPosition) - screen = widget->screen()->virtualSiblingAt(globalPosition); - if (!screen) - screen = widget->screen(); - - return screen->availableGeometry(); + return screen(widget, globalPosition, hasPosition)->availableGeometry(); } inline void setRedirected(QPaintDevice *replacement, const QPoint &offset) diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp index cacc0f22d1..97650979e0 100644 --- a/src/widgets/widgets/qpushbutton.cpp +++ b/src/widgets/widgets/qpushbutton.cpp @@ -643,7 +643,7 @@ QPoint QPushButtonPrivate::adjustedMenuPosition() QPoint globalPos = q->mapToGlobal(rect.topLeft()); int x = globalPos.x(); int y = globalPos.y(); - const QRect availableGeometry = QWidgetPrivate::availableScreenGeometry(q); + const QRect availableGeometry = QWidgetPrivate::availableScreenGeometry(q, q->mapToGlobal(rect.center())); if (horizontal) { if (globalPos.y() + rect.height() + menuSize.height() <= availableGeometry.bottom()) { y += rect.height(); diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index f4e1610fee..c3a400d3d3 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -724,7 +724,7 @@ static QPoint positionMenu(const QToolButton *q, bool horizontal, { QPoint p; const QRect rect = q->rect(); // Find screen via point in case of QGraphicsProxyWidget. - const QRect screen = QWidgetPrivate::availableScreenGeometry(q); + const QRect screen = QWidgetPrivate::availableScreenGeometry(q, q->mapToGlobal(rect.center())); if (horizontal) { if (q->isRightToLeft()) { if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.bottom()) {