diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-06-17 17:47:30 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2019-09-19 17:40:56 +0200 |
commit | ecc83677006dc7dffcd2417b1e3cff88b0615756 (patch) | |
tree | edc31425327ff88169efdba57504ae24ab5596f1 | |
parent | e0cad1aab53119a0e47467f2236f019ce8d6da2a (diff) |
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>
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 4 | ||||
-rw-r--r-- | src/gui/kernel/qscreen.cpp | 19 | ||||
-rw-r--r-- | src/gui/kernel/qscreen.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar.cpp | 13 |
4 files changed, 27 insertions, 10 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a3ef3b2314..c21bc90d39 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -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 */ diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp index 7adf3db1b8..80de561297 100644 --- a/src/gui/kernel/qscreen.cpp +++ b/src/gui/kernel/qscreen.cpp @@ -700,6 +700,25 @@ void QScreenPrivate::updatePrimaryOrientation() } /*! + 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, \a height). diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h index 14392d3036..88925ab731 100644 --- a/src/gui/kernel/qscreen.h +++ b/src/gui/kernel/qscreen.h @@ -125,6 +125,7 @@ public: QRect availableGeometry() const; QList<QScreen *> virtualSiblings() const; + QScreen *virtualSiblingAt(const QPoint &point); QSize virtualSize() const; QRect virtualGeometry() const; diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 3d31a3b73a..69b1c5896f 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -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()); |