Add QScreen::virtualSiblingAt() and use it in QMenubarPrivate::popupAction
QGuiApplication::screenAt() is documented "If the point maps to more than one set of virtual siblings, the first match is returned." But in many cases it's possible to start from a known screen and consider only its siblings, as when deciding where to open a QMenu from a QMenuBar: the QMenuBar is already shown on some screen(s), so the QMenu must be shown on a sibling from that set. This function should be useful in other such cases too, hence it might as well be public API. Task-number: QTBUG-76162 Change-Id: I83c74b40eb53f56fb285a6074a3dc2c0ea9c570b Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
e0cad1aab5
commit
ecc8367700
@ -1040,7 +1040,9 @@ QList<QScreen *> QGuiApplication::screens()
|
||||
|
||||
The \a point is in relation to the virtualGeometry() of each set of virtual
|
||||
siblings. If the point maps to more than one set of virtual siblings the first
|
||||
match is returned.
|
||||
match is returned. If you wish to search only the virtual desktop siblings
|
||||
of a known screen (for example siblings of the screen of your application
|
||||
window \c QWidget::windowHandle()->screen()), use QScreen::virtualSiblingAt().
|
||||
|
||||
\since 5.10
|
||||
*/
|
||||
|
@ -699,6 +699,25 @@ void QScreenPrivate::updatePrimaryOrientation()
|
||||
primaryOrientation = geometry.width() >= geometry.height() ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the screen at \a point within the set of \l QScreen::virtualSiblings(),
|
||||
or \c nullptr if outside of any screen.
|
||||
|
||||
The \a point is in relation to the virtualGeometry() of each set of virtual
|
||||
siblings.
|
||||
|
||||
\since 5.15
|
||||
*/
|
||||
QScreen *QScreen::virtualSiblingAt(const QPoint &point)
|
||||
{
|
||||
const auto &siblings = virtualSiblings();
|
||||
for (QScreen *sibling : siblings) {
|
||||
if (sibling->geometry().contains(point))
|
||||
return sibling;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates and returns a pixmap constructed by grabbing the contents
|
||||
of the given \a window restricted by QRect(\a x, \a y, \a width,
|
||||
|
@ -125,6 +125,7 @@ public:
|
||||
QRect availableGeometry() const;
|
||||
|
||||
QList<QScreen *> virtualSiblings() const;
|
||||
QScreen *virtualSiblingAt(const QPoint &point);
|
||||
|
||||
QSize virtualSize() const;
|
||||
QRect virtualGeometry() const;
|
||||
|
@ -324,15 +324,10 @@ void QMenuBarPrivate::popupAction(QAction *action, bool activateFirst)
|
||||
QPoint pos(q->mapToGlobal(QPoint(adjustedActionRect.left(), adjustedActionRect.bottom() + 1)));
|
||||
QSize popup_size = activeMenu->sizeHint();
|
||||
//we put the popup menu on the screen containing the bottom-center of the action rect
|
||||
QScreen *popupScreen = q->window()->windowHandle()->screen();
|
||||
QPoint bottomMiddlePos = pos + QPoint(adjustedActionRect.width() / 2, 0);
|
||||
const auto &siblings = popupScreen->virtualSiblings();
|
||||
for (QScreen *sibling : siblings) {
|
||||
if (sibling->geometry().contains(bottomMiddlePos)) {
|
||||
popupScreen = sibling;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QScreen *menubarScreen = q->window()->windowHandle()->screen();
|
||||
QScreen *popupScreen = menubarScreen->virtualSiblingAt(pos + QPoint(adjustedActionRect.width() / 2, 0));
|
||||
if (!popupScreen)
|
||||
popupScreen = menubarScreen;
|
||||
QRect screenRect = popupScreen->geometry();
|
||||
pos = QPoint(qMax(pos.x(), screenRect.x()), qMax(pos.y(), screenRect.y()));
|
||||
const bool fitUp = (pos.y() - popup_size.height() >= screenRect.top());
|
||||
|
Loading…
Reference in New Issue
Block a user