From ad8a48e8f1b336099eab2a00c1c1e59abad8e717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Sun, 10 Sep 2017 14:58:49 +0200 Subject: Add QGuiApplication::screenAt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ChangeLog][QtGui] It's now possible to retrieve the screen at a given point via QGuiApplication::screenAt(). Change-Id: Ic09514ec731d8cce5d453833e98fcd118a70600e Reviewed-by: Gatis Paeglis Reviewed-by: Błażej Szczygieł --- src/gui/kernel/qguiapplication.cpp | 63 ++++++++++++++++++----------------- src/gui/kernel/qguiapplication.h | 2 ++ src/widgets/kernel/qdesktopwidget.cpp | 22 ++---------- 3 files changed, 36 insertions(+), 51 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index a29ddbe44e..63539c0103 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -987,6 +987,34 @@ QList QGuiApplication::screens() return QGuiApplicationPrivate::screen_list; } +/*! + Returns the screen at \a point, or \c nullptr if outside of any screen. + + 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. + + \since 5.10 +*/ +QScreen *QGuiApplication::screenAt(const QPoint &point) +{ + QVarLengthArray visitedScreens; + for (const QScreen *screen : QGuiApplication::screens()) { + if (visitedScreens.contains(screen)) + continue; + + // The virtual siblings include the screen itself, so iterate directly + for (QScreen *sibling : screen->virtualSiblings()) { + if (sibling->geometry().contains(point)) + return sibling; + + visitedScreens.append(sibling); + } + } + + return nullptr; +} + /*! \fn void QGuiApplication::screenAdded(QScreen *screen) @@ -1050,38 +1078,11 @@ qreal QGuiApplication::devicePixelRatio() const */ QWindow *QGuiApplication::topLevelAt(const QPoint &pos) { - const QList screens = QGuiApplication::screens(); - if (!screens.isEmpty()) { - const QList primaryScreens = screens.first()->virtualSiblings(); - QScreen *windowScreen = Q_NULLPTR; - - // Find the window on the primary virtual desktop first - for (QScreen *screen : primaryScreens) { - if (screen->geometry().contains(pos)) { - windowScreen = screen; - break; - } - } - - // If the window is not found on primary virtual desktop, find it on all screens - // except the first which was for sure in the previous loop. Some other screens - // may repeat. Find only when there is more than one virtual desktop. - if (!windowScreen && screens.count() != primaryScreens.count()) { - for (int i = 1; i < screens.size(); ++i) { - QScreen *screen = screens.at(i); - if (screen->geometry().contains(pos)) { - windowScreen = screen; - break; - } - } - } - - if (windowScreen) { - const QPoint devicePosition = QHighDpi::toNativePixels(pos, windowScreen); - return windowScreen->handle()->topLevelAt(devicePosition); - } + if (QScreen *windowScreen = screenAt(pos)) { + const QPoint devicePosition = QHighDpi::toNativePixels(pos, windowScreen); + return windowScreen->handle()->topLevelAt(devicePosition); } - return Q_NULLPTR; + return nullptr; } /*! diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 6721970222..e130553b9d 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -110,6 +110,8 @@ public: static QScreen *primaryScreen(); static QList screens(); + static QScreen *screenAt(const QPoint &point); + qreal devicePixelRatio() const; #ifndef QT_NO_CURSOR diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index 6077ac38db..1b9cf88efe 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -352,26 +352,8 @@ int QDesktopWidget::screenNumber(const QPoint &p) const int QDesktopWidgetPrivate::screenNumber(const QPoint &p) { - const QList screens = QGuiApplication::screens(); - if (!screens.isEmpty()) { - const QList primaryScreens = screens.first()->virtualSiblings(); - // Find the screen index on the primary virtual desktop first - foreach (QScreen *screen, primaryScreens) { - if (screen->geometry().contains(p)) - return screens.indexOf(screen); - } - // If the screen index is not found on primary virtual desktop, find - // the screen index on all screens except the first which was for - // sure in the previous loop. Some other screens may repeat. Find - // only when there is more than one virtual desktop. - if (screens.count() != primaryScreens.count()) { - for (int i = 1; i < screens.size(); ++i) { - if (screens[i]->geometry().contains(p)) - return i; - } - } - } - return primaryScreen(); //even better would be closest screen + QScreen *screen = QGuiApplication::screenAt(p); + return screen ? QGuiApplication::screens().indexOf(screen) : primaryScreen(); } void QDesktopWidget::resizeEvent(QResizeEvent *) -- cgit v1.2.3