Add QGuiApplication::screenAt()

[ChangeLog][QtGui] It's now possible to retrieve the screen
at a given point via QGuiApplication::screenAt().

Change-Id: Ic09514ec731d8cce5d453833e98fcd118a70600e
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
This commit is contained in:
Tor Arne Vestbø 2017-09-10 14:58:49 +02:00
parent 037652d7a2
commit ad8a48e8f1
3 changed files with 36 additions and 51 deletions

View File

@ -987,6 +987,34 @@ QList<QScreen *> 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<const QScreen *, 8> 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<QScreen *> screens = QGuiApplication::screens();
if (!screens.isEmpty()) {
const QList<QScreen *> 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;
}
/*!

View File

@ -110,6 +110,8 @@ public:
static QScreen *primaryScreen();
static QList<QScreen *> screens();
static QScreen *screenAt(const QPoint &point);
qreal devicePixelRatio() const;
#ifndef QT_NO_CURSOR

View File

@ -352,26 +352,8 @@ int QDesktopWidget::screenNumber(const QPoint &p) const
int QDesktopWidgetPrivate::screenNumber(const QPoint &p)
{
const QList<QScreen *> screens = QGuiApplication::screens();
if (!screens.isEmpty()) {
const QList<QScreen *> 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 *)