summaryrefslogtreecommitdiffstats
path: root/src/widgets/kernel
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2020-05-16 20:43:34 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2020-06-08 20:29:49 +0200
commit44fb925f50471ebc23dcccfaa4e9d9873b05d205 (patch)
treee4e212052b66242ff94aa98f6df7b15dbeb945f7 /src/widgets/kernel
parenta061a646429c6e9d695458fc0ecb0021a30e12ee (diff)
Phase 2 of removing QDesktopWidget
Remove QDestopWidget public header, simplify the implementation that maintains a Qt::Desktop type QWidget for each QScreen, and turn QWidget's initial target screen into a QScreen pointer. QApplication::desktop() now takes an optional QScreen pointer, and returns a QWidget pointer, so that applications and widgets can get access to the root widget for a specific screen without having to resort to private APIs. QDesktopWidgetPrivate implementations to look up a screen for an index, widget, or point are now all inline functions that thinly wrap QGuiApplication::screens/screenAt calls. We should consider adding those as convenience APIs to QScreen instead. Note that QWidget::screen is assumed to return a valid pointer; there is code that handles the case that it returns nullptr (but also code that trusts that it never is nullptr), so this needs to be defined, verified with tests, and asserted. We can then simplify the code further. Change-Id: Ifc89be65a0dce265b6729feaf54121c35137cb94 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r--src/widgets/kernel/kernel.pri1
-rw-r--r--src/widgets/kernel/qapplication.cpp22
-rw-r--r--src/widgets/kernel/qapplication.h3
-rw-r--r--src/widgets/kernel/qdesktopwidget.cpp182
-rw-r--r--src/widgets/kernel/qdesktopwidget.h72
-rw-r--r--src/widgets/kernel/qdesktopwidget_p.h100
-rw-r--r--src/widgets/kernel/qtooltip.cpp32
-rw-r--r--src/widgets/kernel/qwhatsthis.cpp1
-rw-r--r--src/widgets/kernel/qwidget.cpp45
-rw-r--r--src/widgets/kernel/qwidget_p.h36
10 files changed, 178 insertions, 316 deletions
diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri
index b9dfdef5ee..462897b886 100644
--- a/src/widgets/kernel/kernel.pri
+++ b/src/widgets/kernel/kernel.pri
@@ -11,7 +11,6 @@ HEADERS += \
kernel/qapplication_p.h \
kernel/qwidgetrepaintmanager_p.h \
kernel/qboxlayout.h \
- kernel/qdesktopwidget.h \
kernel/qgridlayout.h \
kernel/qlayout.h \
kernel/qlayout_p.h \
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 0e96e8bc69..1af94efdf9 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -42,7 +42,7 @@
#include "qapplication.h"
#include "qclipboard.h"
#include "qcursor.h"
-#include "qdesktopwidget.h"
+#include "qdesktopwidget_p.h"
#include "qdir.h"
#include "qevent.h"
#include "qfile.h"
@@ -2521,22 +2521,30 @@ void QApplicationPrivate::sendSyntheticEnterLeave(QWidget *widget)
/*!
\internal
- Returns the desktop widget (also called the root window).
+ Returns the desktop widget (also called the root window) for \a screen.
+
+ If \a screen is nullptr, then the widget that represents the entire virtual
+ desktop is returned, and its geometry will be the union of all screens.
+
+ Use the desktop widget for a specific screen as the parent of a new toplevel
+ widget to position the widget on a specific screen.
The desktop may be composed of multiple screens, so it would be incorrect,
for example, to attempt to \e center some widget in the desktop's geometry.
- QDesktopWidget has various functions for obtaining useful geometries upon
- the desktop, such as QDesktopWidget::screenGeometry() and
- QDesktopWidget::availableGeometry().
+ Use QScreen::geometry() and QScreen::availableGeometry() to get the dimensions
+ of a specific screen instead.
*/
-QDesktopWidget *QApplication::desktop()
+QWidget *QApplication::desktop(QScreen *screen)
{
CHECK_QAPP_INSTANCE(nullptr)
if (!qt_desktopWidget || // not created yet
!(qt_desktopWidget->windowType() == Qt::Desktop)) { // reparented away
qt_desktopWidget = new QDesktopWidget();
}
- return qt_desktopWidget;
+ if (!screen)
+ return qt_desktopWidget;
+ QDesktopWidgetPrivate *dwp = static_cast<QDesktopWidgetPrivate*>(qt_widget_private(qt_desktopWidget));
+ return dwp->widgetForScreen(screen);
}
/*
diff --git a/src/widgets/kernel/qapplication.h b/src/widgets/kernel/qapplication.h
index 1903aa48dc..36a7576c2d 100644
--- a/src/widgets/kernel/qapplication.h
+++ b/src/widgets/kernel/qapplication.h
@@ -51,7 +51,6 @@
QT_BEGIN_NAMESPACE
-class QDesktopWidget;
class QStyle;
class QEventLoop;
class QIcon;
@@ -106,7 +105,7 @@ public:
static QWidgetList allWidgets();
static QWidgetList topLevelWidgets();
- static QDesktopWidget *desktop();
+ static QWidget *desktop(QScreen *screen = nullptr);
static QWidget *activePopupWidget();
static QWidget *activeModalWidget();
diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp
index dd74fbf53e..797980c7c5 100644
--- a/src/widgets/kernel/qdesktopwidget.cpp
+++ b/src/widgets/kernel/qdesktopwidget.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qglobal.h"
-#include "qdesktopwidget.h"
#include "qdesktopwidget_p.h"
#include "qscreen.h"
#include "qwidget_p.h"
@@ -50,109 +49,66 @@
QT_BEGIN_NAMESPACE
QDesktopScreenWidget::QDesktopScreenWidget(QScreen *screen, const QRect &geometry)
- : QWidget(nullptr, Qt::Desktop), m_screen(screen)
+ : QWidget(nullptr, Qt::Desktop)
{
setVisible(false);
if (QWindow *winHandle = windowHandle())
winHandle->setScreen(screen);
- setScreenGeometry(geometry);
-}
-
-void QDesktopScreenWidget::setScreenGeometry(const QRect &geometry)
-{
- m_geometry = geometry;
setGeometry(geometry);
}
-int QDesktopScreenWidget::screenNumber() const
+QScreen *QDesktopScreenWidget::screen() const
{
const QDesktopWidgetPrivate *desktopWidgetP
= static_cast<const QDesktopWidgetPrivate *>(qt_widget_private(QApplication::desktop()));
- return desktopWidgetP->screens.indexOf(const_cast<QDesktopScreenWidget *>(this));
-}
-
-const QRect QDesktopWidgetPrivate::screenGeometry(const QWidget *widget)
-{
- if (Q_UNLIKELY(!widget)) {
- qWarning("QDesktopWidget::screenGeometry(): Attempt "
- "to get the screen geometry of a null widget");
- return QRect();
+ for (auto it : qAsConst(desktopWidgetP->screenWidgets)) {
+ if (it.second == this)
+ return it.first;
}
- QRect rect = QWidgetPrivate::screenGeometry(widget);
- if (rect.isNull())
- return screenGeometry(screenNumber(widget));
- else return rect;
+ return nullptr;
}
-const QRect QDesktopWidgetPrivate::availableGeometry(const QWidget *widget)
+QDesktopWidgetPrivate::~QDesktopWidgetPrivate()
{
- if (Q_UNLIKELY(!widget)) {
- qWarning("QDesktopWidget::availableGeometry(): Attempt "
- "to get the available geometry of a null widget");
- return QRect();
- }
- QRect rect = QWidgetPrivate::screenGeometry(widget);
- if (rect.isNull())
- return availableGeometry(screenNumber(widget));
- else
- return rect;
+ qDeleteAll(screenWidgets.values());
}
-QDesktopScreenWidget *QDesktopWidgetPrivate::widgetForScreen(QScreen *qScreen) const
-{
- foreach (QDesktopScreenWidget *widget, screens) {
- if (widget->assignedScreen() == qScreen)
- return widget;
- }
- return nullptr;
-}
-
-void QDesktopWidgetPrivate::_q_updateScreens()
+void QDesktopWidgetPrivate::updateScreens()
{
Q_Q(QDesktopWidget);
const QList<QScreen *> screenList = QGuiApplication::screens();
- const int targetLength = screenList.length();
// Re-build our screens list. This is the easiest way to later compute which signals to emit.
- // Create new screen widgets as necessary. While iterating, keep the old list in place so
- // that widgetForScreen works.
+ // Create new screen widgets as necessary.
// Furthermore, we note which screens have changed, and compute the overall virtual geometry.
- QList<QDesktopScreenWidget *> newScreens;
- QList<int> changedScreens;
+ QFlatMap<QScreen*, QDesktopScreenWidget*> newScreenWidgets;
QRegion virtualGeometry;
- for (int i = 0; i < targetLength; ++i) {
- QScreen *qScreen = screenList.at(i);
- const QRect screenGeometry = qScreen->geometry();
- QDesktopScreenWidget *screenWidget = widgetForScreen(qScreen);
- if (screenWidget) {
- // an old screen. update geometry and remember the index in the *new* list
- if (screenGeometry != screenWidget->screenGeometry()) {
- screenWidget->setScreenGeometry(screenGeometry);
- changedScreens.push_back(i);
- }
- } else {
+ for (QScreen *screen : screenList) {
+ const QRect screenGeometry = screen->geometry();
+ QDesktopScreenWidget *screenWidget = screenWidgets.value(screen);
+ if (!screenWidget) {
// a new screen, create a widget and connect the signals.
- screenWidget = new QDesktopScreenWidget(qScreen, screenGeometry);
- QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)),
- q, SLOT(_q_updateScreens()), Qt::QueuedConnection);
- QObject::connect(qScreen, SIGNAL(destroyed()),
- q, SLOT(_q_updateScreens()), Qt::QueuedConnection);
+ screenWidget = new QDesktopScreenWidget(screen, screenGeometry);
+ QObjectPrivate::connect(screen, &QScreen::geometryChanged,
+ this, &QDesktopWidgetPrivate::updateScreens, Qt::QueuedConnection);
+ QObjectPrivate::connect(screen, &QObject::destroyed,
+ this, &QDesktopWidgetPrivate::updateScreens, Qt::QueuedConnection);
}
// record all the screens and the overall geometry.
- newScreens.push_back(screenWidget);
+ newScreenWidgets.insert(screen, screenWidget);
virtualGeometry += screenGeometry;
}
// Now we apply the accumulated updates.
- screens.swap(newScreens); // now [newScreens] is the old screen list
- Q_ASSERT(screens.size() == targetLength);
+ qSwap(screenWidgets, newScreenWidgets); // now [newScreenWidgets] is the old screen list
+ Q_ASSERT(screenWidgets.size() == screenList.length());
q->setGeometry(virtualGeometry.boundingRect());
// Delete the QDesktopScreenWidget that are not used any more.
- foreach (QDesktopScreenWidget *screen, newScreens) {
- if (!screens.contains(screen))
- delete screen;
+ for (auto it : qAsConst(newScreenWidgets)) {
+ if (!screenWidgets.contains(it.first))
+ delete it.second;
}
}
@@ -161,90 +117,12 @@ QDesktopWidget::QDesktopWidget()
{
Q_D(QDesktopWidget);
setObjectName(QLatin1String("desktop"));
- d->_q_updateScreens();
- connect(qApp, SIGNAL(screenAdded(QScreen*)), this, SLOT(_q_updateScreens()));
-}
-
-QDesktopWidget::~QDesktopWidget()
-{
+ d->updateScreens();
+ QObjectPrivate::connect(qApp, &QApplication::screenAdded, d, &QDesktopWidgetPrivate::updateScreens);
}
-QWidget *QDesktopWidget::screen(int screen)
-{
- Q_D(QDesktopWidget);
- if (screen < 0 || screen >= d->screens.length())
- return d->screens.at(0);
- return d->screens.at(screen);
-}
-
-const QRect QDesktopWidgetPrivate::availableGeometry(int screenNo)
-{
- const QScreen *screen = QDesktopWidgetPrivate::screen(screenNo);
- return screen ? screen->availableGeometry() : QRect();
-}
-
-const QRect QDesktopWidgetPrivate::screenGeometry(int screenNo)
-{
- const QScreen *screen = QDesktopWidgetPrivate::screen(screenNo);
- return screen ? screen->geometry() : QRect();
-}
-
-int QDesktopWidgetPrivate::screenNumber(const QWidget *w)
-{
- if (!w)
- return 0;
-
- const QList<QScreen *> allScreens = QGuiApplication::screens();
- QList<QScreen *> screens = allScreens;
- if (screens.isEmpty()) // This should never happen
- return 0;
-
- // If there is more than one virtual desktop
- if (screens.count() != screens.constFirst()->virtualSiblings().count()) {
- // Find the root widget, get a QScreen from it and use the
- // virtual siblings for checking the window position.
- if (const QScreen *winScreen = qt_widget_private(const_cast<QWidget *>(w))->associatedScreen())
- screens = winScreen->virtualSiblings();
- }
-
- // 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)));
-
- QScreen *widgetScreen = nullptr;
- int largestArea = 0;
- foreach (QScreen *screen, screens) {
- const QRect deviceIndependentScreenGeometry =
- QHighDpi::fromNativePixels(screen->handle()->geometry(), screen);
- const QRect intersected = deviceIndependentScreenGeometry.intersected(frame);
- int area = intersected.width() * intersected.height();
- if (largestArea < area) {
- widgetScreen = screen;
- largestArea = area;
- }
- }
- return allScreens.indexOf(widgetScreen);
-}
-
-int QDesktopWidgetPrivate::screenNumber(const QPoint &p)
-{
- QScreen *screen = QGuiApplication::screenAt(p);
- return screen ? QGuiApplication::screens().indexOf(screen) : 0;
-}
-
-QScreen *QDesktopWidgetPrivate::screen(int screenNo)
-{
- QList<QScreen *> screens = QGuiApplication::screens();
- if (screenNo == -1)
- screenNo = 0;
- if (screenNo < 0 || screenNo >= screens.size())
- return nullptr;
- return screens.at(screenNo);
-}
+QDesktopWidget::~QDesktopWidget() = default;
QT_END_NAMESPACE
-#include "moc_qdesktopwidget.cpp"
#include "moc_qdesktopwidget_p.cpp"
diff --git a/src/widgets/kernel/qdesktopwidget.h b/src/widgets/kernel/qdesktopwidget.h
deleted file mode 100644
index 265f320b1f..0000000000
--- a/src/widgets/kernel/qdesktopwidget.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDESKTOPWIDGET_H
-#define QDESKTOPWIDGET_H
-
-#include <QtWidgets/qtwidgetsglobal.h>
-#include <QtWidgets/qwidget.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QApplication;
-class QDesktopWidgetPrivate;
-
-class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget
-{
- Q_OBJECT
-public:
- QDesktopWidget();
- ~QDesktopWidget();
-
- QT_DEPRECATED_X("Use QScreen") QWidget *screen(int screen = -1);
-
-private:
- Q_DISABLE_COPY(QDesktopWidget)
- Q_DECLARE_PRIVATE(QDesktopWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_updateScreens())
-
- friend class QApplication;
- friend class QApplicationPrivate;
-};
-
-QT_END_NAMESPACE
-
-#endif // QDESKTOPWIDGET_H
diff --git a/src/widgets/kernel/qdesktopwidget_p.h b/src/widgets/kernel/qdesktopwidget_p.h
index b0ac13808d..d2845af17c 100644
--- a/src/widgets/kernel/qdesktopwidget_p.h
+++ b/src/widgets/kernel/qdesktopwidget_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -52,56 +52,96 @@
#define QDESKTOPWIDGET_P_H
#include <QtWidgets/private/qtwidgetsglobal_p.h>
-#include "QDesktopWidget"
#include "private/qwidget_p.h"
-#include <QtCore/qalgorithms.h>
#include <QtGui/qscreen.h>
+#include <QtCore/private/qflatmap_p.h>
QT_BEGIN_NAMESPACE
-class QDesktopScreenWidget : public QWidget {
+class QDesktopWidgetPrivate;
+
+class Q_WIDGETS_EXPORT QDesktopWidget : public QWidget
+{
Q_OBJECT
public:
- explicit QDesktopScreenWidget(QScreen *screen, const QRect &geometry);
+ QDesktopWidget();
+ ~QDesktopWidget();
- int screenNumber() const;
- void setScreenGeometry(const QRect &geometry);
-
- QScreen *assignedScreen() const { return m_screen.data(); }
- QRect screenGeometry() const { return m_geometry; }
private:
- // The widget updates its screen and geometry automatically. We need to save them separately
- // to detect changes, and trigger the appropriate signals.
- const QPointer<QScreen> m_screen;
- QRect m_geometry;
-};
+ Q_DISABLE_COPY(QDesktopWidget)
+ Q_DECLARE_PRIVATE(QDesktopWidget)
-class QDesktopWidgetPrivate : public QWidgetPrivate {
- Q_DECLARE_PUBLIC(QDesktopWidget)
+ friend class QApplication;
+ friend class QApplicationPrivate;
+};
+class QDesktopScreenWidget : public QWidget {
+ Q_OBJECT
public:
- ~QDesktopWidgetPrivate() { qDeleteAll(screens); }
- void _q_updateScreens();
- QDesktopScreenWidget *widgetForScreen(QScreen *qScreen) const;
+ explicit QDesktopScreenWidget(QScreen *, const QRect &geometry);
- static int screenNumber(const QWidget *widget = nullptr);
- static int screenNumber(const QPoint &);
+ QScreen *screen() const;
+};
- static QScreen *screen(int screenNo = -1);
+class QDesktopWidgetPrivate : public QWidgetPrivate {
+ Q_DECLARE_PUBLIC(QDesktopWidget)
- static const QRect screenGeometry(int screen = -1);
- static const QRect screenGeometry(const QWidget *widget);
- static const QRect screenGeometry(const QPoint &point)
+public:
+ ~QDesktopWidgetPrivate();
+ void updateScreens();
+ QDesktopScreenWidget *widgetForScreen(QScreen *qScreen) const
+ {
+ return screenWidgets.value(qScreen);
+ }
+
+ static inline int screenNumber(const QWidget *widget = nullptr)
+ {
+ if (!widget)
+ return 0;
+ return QGuiApplication::screens().indexOf(widget->screen());
+ }
+
+ static inline int screenNumber(const QPoint &point)
+ {
+ int screenNo = 0;
+ if (QScreen *screen = QGuiApplication::screenAt(point))
+ screenNo = QGuiApplication::screens().indexOf(screen);
+ return screenNo;
+ }
+
+ static inline QScreen *screen(int screenNo = -1)
+ {
+ const QList<QScreen *> screens = QGuiApplication::screens();
+ if (screenNo == -1)
+ screenNo = 0;
+ if (screenNo < 0 || screenNo >= screens.size())
+ return nullptr;
+ return screens.at(screenNo);
+ }
+
+ static inline QRect screenGeometry(int screenNo = -1)
+ {
+ QRect rect;
+ if (const QScreen *s = screen(screenNo))
+ rect = s->geometry();
+ return rect;
+ }
+ static inline QRect screenGeometry(const QPoint &point)
{ return screenGeometry(screenNumber(point)); }
- static const QRect availableGeometry(int screen = -1);
- static const QRect availableGeometry(const QWidget *widget);
- static const QRect availableGeometry(const QPoint &point)
+ static inline QRect availableGeometry(int screenNo = -1)
+ {
+ QRect rect;
+ if (const QScreen *s = screen(screenNo))
+ rect = s->availableGeometry();
+ return rect;
+ }
+ static inline QRect availableGeometry(const QPoint &point)
{ return availableGeometry(screenNumber(point)); }
- QList<QDesktopScreenWidget *> screens;
+ QFlatMap<QScreen*, QDesktopScreenWidget*> screenWidgets;
};
QT_END_NAMESPACE
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index 80a87bb3cd..8aca4db58a 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -40,7 +40,6 @@
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include <qapplication.h>
-#include <qdesktopwidget.h>
#include <private/qdesktopwidget_p.h>
#include <qevent.h>
#include <qpointer.h>
@@ -139,7 +138,7 @@ public:
bool tipChanged(const QPoint &pos, const QString &text, QObject *o);
void placeTip(const QPoint &pos, QWidget *w);
- static int getTipScreen(const QPoint &pos, QWidget *w);
+ static QScreen *getTipScreen(const QPoint &pos, QWidget *w);
protected:
void timerEvent(QTimerEvent *e) override;
void paintEvent(QPaintEvent *e) override;
@@ -366,12 +365,12 @@ bool QTipLabel::eventFilter(QObject *o, QEvent *e)
return false;
}
-int QTipLabel::getTipScreen(const QPoint &pos, QWidget *w)
+QScreen *QTipLabel::getTipScreen(const QPoint &pos, QWidget *w)
{
- if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1)
- return QDesktopWidgetPrivate::screenNumber(pos);
- else
- return QDesktopWidgetPrivate::screenNumber(w);
+ int screenNo = QGuiApplication::primaryScreen()->virtualSiblings().size() > 1
+ ? QDesktopWidgetPrivate::screenNumber(pos)
+ : QDesktopWidgetPrivate::screenNumber(w);
+ return QDesktopWidgetPrivate::screen(screenNo);
}
void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
@@ -396,8 +395,7 @@ void QTipLabel::placeTip(const QPoint &pos, QWidget *w)
#endif //QT_NO_STYLE_STYLESHEET
QPoint p = pos;
- const QScreen *screen = QGuiApplication::screens().value(getTipScreen(pos, w),
- QGuiApplication::primaryScreen());
+ const QScreen *screen = getTipScreen(pos, w);
// a QScreen's handle *should* never be null, so this is a bit paranoid
if (const QPlatformScreen *platformScreen = screen ? screen->handle() : nullptr) {
const QSize cursorSize = QHighDpi::fromNativePixels(platformScreen->cursor()->size(),
@@ -494,16 +492,18 @@ void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, cons
}
if (!text.isEmpty()){ // no tip can be reused, create new tip:
+ QWidget *tipLabelParent = [pos, w]() -> QWidget* {
#ifdef Q_OS_WIN32
- // On windows, we can't use the widget as parent otherwise the window will be
- // raised when the tooltip will be shown
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
- new QTipLabel(text, pos, QApplication::desktop()->screen(QTipLabel::getTipScreen(pos, w)), msecDisplayTime);
-QT_WARNING_POP
+ // On windows, we can't use the widget as parent otherwise the window will be
+ // raised when the tooltip will be shown
+ QScreen *screen = QTipLabel::getTipScreen(pos, w);
+ return QApplication::desktop(screen);
#else
- new QTipLabel(text, pos, w, msecDisplayTime); // sets QTipLabel::instance to itself
+ Q_UNUSED(pos);
+ return w;
#endif
+ }();
+ new QTipLabel(text, pos, tipLabelParent, msecDisplayTime); // sets QTipLabel::instance to itself
QTipLabel::instance->setTipRect(w, rect);
QTipLabel::instance->placeTip(pos, w);
QTipLabel::instance->setObjectName(QLatin1String("qtooltip_label"));
diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp
index fdf90acccc..c5a9989837 100644
--- a/src/widgets/kernel/qwhatsthis.cpp
+++ b/src/widgets/kernel/qwhatsthis.cpp
@@ -41,7 +41,6 @@
#include "qpointer.h"
#include "qapplication.h"
#include <private/qguiapplication_p.h>
-#include "qdesktopwidget.h"
#include <private/qdesktopwidget_p.h>
#include "qevent.h"
#include "qpixmap.h"
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 56e558eca0..c7303dde66 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -990,10 +990,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
if (allWidgets)
allWidgets->insert(q);
- int targetScreen = -1;
+ QScreen *targetScreen = nullptr;
if (parentWidget && parentWidget->windowType() == Qt::Desktop) {
const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(parentWidget);
- targetScreen = sw ? sw->screenNumber() : 0;
+ targetScreen = sw ? sw->screen() : nullptr;
parentWidget = nullptr;
}
@@ -1006,10 +1006,10 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f)
}
#endif
- if (targetScreen >= 0) {
- topData()->initialScreenIndex = targetScreen;
+ if (targetScreen) {
+ topData()->initialScreen = targetScreen;
if (QWindow *window = q->windowHandle())
- window->setScreen(QGuiApplication::screens().value(targetScreen, nullptr));
+ window->setScreen(targetScreen);
}
data.fstrut_dirty = true;
@@ -1293,13 +1293,13 @@ void QWidgetPrivate::create()
else
win->resize(q->size());
if (win->isTopLevel()) {
- int screenNumber = topData()->initialScreenIndex;
- topData()->initialScreenIndex = -1;
- if (screenNumber < 0) {
- screenNumber = q->windowType() != Qt::Desktop
- ? QDesktopWidgetPrivate::screenNumber(q) : 0;
+ QScreen *targetScreen = topData()->initialScreen;
+ topData()->initialScreen = nullptr;
+ if (!targetScreen) {
+ targetScreen = q->windowType() != Qt::Desktop
+ ? q->screen() : nullptr;
}
- win->setScreen(QGuiApplication::screens().value(screenNumber, nullptr));
+ win->setScreen(targetScreen);
}
QSurfaceFormat format = win->requestedFormat();
@@ -1602,7 +1602,7 @@ void QWidgetPrivate::createTLExtra()
x->sizeAdjusted = false;
x->embedded = 0;
x->window = nullptr;
- x->initialScreenIndex = -1;
+ x->initialScreen = nullptr;
#ifdef QWIDGET_EXTRA_DEBUG
static int count = 0;
@@ -2507,8 +2507,8 @@ QScreen *QWidget::screen() const
return associatedScreen;
if (auto topLevel = window()) {
if (auto topData = qt_widget_private(topLevel)->topData()) {
- if (auto initialScreen = QGuiApplicationPrivate::screen_list.value(topData->initialScreenIndex))
- return initialScreen;
+ if (topData->initialScreen)
+ return topData->initialScreen;
}
if (auto screenByPos = QGuiApplication::screenAt(topLevel->geometry().center()))
return screenByPos;
@@ -3472,8 +3472,7 @@ QPoint QWidget::pos() const
issues with windows.
\note Do not use this function to find the width of a screen on
- a \l{QDesktopWidget}{multiple screen desktop}. Read
- \l{QDesktopWidget#Screen Geometry}{this note} for details.
+ a multi-screen desktop. See QScreen for details.
By default, this property contains a value that depends on the user's
platform and screen geometry.
@@ -10487,13 +10486,13 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
Qt::WindowFlags oldFlags = data.window_flags;
bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
- int targetScreen = -1;
+ QScreen *targetScreen = nullptr;
// Handle a request to move the widget to a particular screen
if (newparent && newparent->windowType() == Qt::Desktop) {
// make sure the widget is created on the same screen as the
// programmer specified desktop widget
const QDesktopScreenWidget *sw = qobject_cast<const QDesktopScreenWidget *>(newparent);
- targetScreen = sw ? sw->screenNumber() : 0;
+ targetScreen = sw ? sw->screen() : nullptr;
newparent = nullptr;
}
@@ -10523,9 +10522,9 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
if (!newparent) {
f |= Qt::Window;
- if (targetScreen == -1) {
+ if (!targetScreen) {
if (parent)
- targetScreen = QDesktopWidgetPrivate::screenNumber(q->parentWidget()->window());
+ targetScreen = q->parentWidget()->window()->screen();
}
}
@@ -10568,12 +10567,12 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden);
// move the window to the selected screen
- if (!newparent && targetScreen != -1) {
+ if (!newparent && targetScreen) {
// only if it is already created
if (q->testAttribute(Qt::WA_WState_Created))
- q->windowHandle()->setScreen(QGuiApplication::screens().value(targetScreen, 0));
+ q->windowHandle()->setScreen(targetScreen);
else
- topData()->initialScreenIndex = targetScreen;
+ topData()->initialScreen = targetScreen;
}
}
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index 3e52a6ad2f..08954cc778 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -61,6 +61,7 @@
#include "QtGui/qinputmethod.h"
#include "QtGui/qopengl.h"
#include "QtGui/qsurfaceformat.h"
+#include "QtGui/qscreen.h"
#include "QtWidgets/qsizepolicy.h"
#include "QtWidgets/qstyle.h"
#include "QtWidgets/qapplication.h"
@@ -144,8 +145,7 @@ struct QTLWExtra {
QRect frameStrut;
QRect normalGeometry; // used by showMin/maximized/FullScreen
Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
- // ### TODO replace initialScreenIndex with QScreen *, in case the screens change at runtime
- int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent.
+ QScreen *initialScreen; // Screen when passing a QDesktop[Screen]Widget as parent.
#ifndef QT_NO_OPENGL
std::vector<std::unique_ptr<QPlatformTextureList>> widgetTextures;
@@ -476,13 +476,11 @@ public:
void setModal_sys();
- // This is an helper function that return the available geometry for
- // a widget and takes care is this one is in QGraphicsView.
- // If the widget is not embed in a scene then the geometry available is
- // null, we let QDesktopWidget decide for us.
- static QRect screenGeometry(const QWidget *widget)
+ // These helper functions return the (available) geometry for the screen
+ // the widget is on, and takes care if this one is embedded in a QGraphicsView.
+ static QRect graphicsViewParentRect(const QWidget *widget)
{
- QRect screen;
+ QRect rect;
#if QT_CONFIG(graphicsview)
QGraphicsProxyWidget *ancestorProxy = widget->d_func()->nearestGraphicsProxyWidget(widget);
//It's embedded if it has an ancestor
@@ -491,16 +489,30 @@ public:
// One view, let be smart and return the viewport rect then the popup is aligned
if (ancestorProxy->scene()->views().size() == 1) {
QGraphicsView *view = ancestorProxy->scene()->views().at(0);
- screen = view->mapToScene(view->viewport()->rect()).boundingRect().toRect();
+ rect = view->mapToScene(view->viewport()->rect()).boundingRect().toRect();
} else {
- screen = ancestorProxy->scene()->sceneRect().toRect();
+ rect = ancestorProxy->scene()->sceneRect().toRect();
}
}
}
#else
Q_UNUSED(widget);
#endif
- return screen;
+ return rect;
+ }
+ static QRect screenGeometry(const QWidget *widget)
+ {
+ QRect rect = graphicsViewParentRect(widget);
+ if (rect.isNull())
+ rect = widget->screen()->geometry();
+ return rect;
+ }
+ static QRect availableScreenGeometry(const QWidget *widget)
+ {
+ QRect rect = graphicsViewParentRect(widget);
+ if (rect.isNull())
+ rect = widget->screen()->availableGeometry();
+ return rect;
}
inline void setRedirected(QPaintDevice *replacement, const QPoint &offset)