summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2019-06-17 17:47:30 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2019-09-19 17:40:56 +0200
commitecc83677006dc7dffcd2417b1e3cff88b0615756 (patch)
treeedc31425327ff88169efdba57504ae24ab5596f1
parente0cad1aab53119a0e47467f2236f019ce8d6da2a (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.cpp4
-rw-r--r--src/gui/kernel/qscreen.cpp19
-rw-r--r--src/gui/kernel/qscreen.h1
-rw-r--r--src/widgets/widgets/qmenubar.cpp13
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());