QDesktopWidget::screenNumber(QWidget*): check virtual sibling screens

Find the root widget only when more than one virtual desktop exists
and find the screen index using virtual siblings from this root
widget.

Use intersecting rects instead of middle point to obtain the screen.
This can help to get the screen index when the middle point is outside
the screen geometry, but part of the window is still on the screen.

If the widget is completely outside the screen geometry, -1 is
returned.

This commit amends: a6b2a4642f

Change-Id: I80247fc1956a82c487ee6f728d1576bf48b28748
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
bb10
Błażej Szczygieł 2015-12-31 21:47:41 +01:00
parent f3114120f2
commit 1606a0e508
1 changed files with 34 additions and 16 deletions

View File

@ -195,28 +195,46 @@ const QRect QDesktopWidget::screenGeometry(int screenNo) const
int QDesktopWidget::screenNumber(const QWidget *w) const
{
if (!w)
return 0;
return primaryScreen();
// Find the root widget, get a QScreen pointer from it and find
// the screen number.
const QWidget *root = w;
const QWidget *tmp = w;
while ((tmp = tmp->parentWidget()))
root = tmp;
QWindow *winHandle = root->windowHandle();
if (winHandle) {
int screenIdx = QGuiApplication::screens().indexOf(winHandle->screen());
if (screenIdx > -1)
return screenIdx;
const QList<QScreen *> allScreens = QGuiApplication::screens();
QList<QScreen *> screens = allScreens;
if (screens.isEmpty()) // This should never happen
return primaryScreen();
// If there is more than one virtual desktop
if (screens.count() != screens.first()->virtualSiblings().count()) {
// Find the root widget, get a QScreen from it and use the
// virtual siblings for checking the window position.
const QWidget *root = w;
const QWidget *tmp = w;
while ((tmp = tmp->parentWidget()))
root = tmp;
const QWindow *winHandle = root->windowHandle();
if (winHandle) {
const QScreen *winScreen = winHandle->screen();
if (winScreen)
screens = winScreen->virtualSiblings();
}
}
// If the screen number cannot be obtained using QScreen pointer,
// get it from window position using screen geometry.
// Get the screen number from window position using screen geometry
// and proper screens.
QRect frame = w->frameGeometry();
if (!w->isWindow())
frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2;
return screenNumber(midpoint);
QScreen *widgetScreen = Q_NULLPTR;
int largestArea = 0;
foreach (QScreen *screen, screens) {
QRect intersected = screen->geometry().intersected(frame);
int area = intersected.width() * intersected.height();
if (largestArea < area) {
widgetScreen = screen;
largestArea = area;
}
}
return allScreens.indexOf(widgetScreen);
}
int QDesktopWidget::screenNumber(const QPoint &p) const