diff options
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/kernel.pri | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 22 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget.cpp | 182 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget.h | 72 | ||||
-rw-r--r-- | src/widgets/kernel/qdesktopwidget_p.h | 100 | ||||
-rw-r--r-- | src/widgets/kernel/qtooltip.cpp | 32 | ||||
-rw-r--r-- | src/widgets/kernel/qwhatsthis.cpp | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 45 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 36 |
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) |