From 7e2fded55e67727043c3dd0a1a5b3883655101c4 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 6 Jul 2020 17:22:12 +0200 Subject: [PATCH] Remove usage of QDesktopWidget(Private) from most places in QtWidgets Call QGuiApplication and QScreen APIs directly to get geometries, and make use of QScreen::grabWindow grabbing the screen it's called on when called with WId == 0. This assumes that QGuiApplication::screen and QWidget::screen never return nullptr, which is already assumed in other places. In QSplashScreen, simplify the code to operate on the screen of the QSplashScreen itself. Remove the case that handles a QDesktopWidget parent - QSplashScreen doesn't have a constructor that takes a QWidget* parent anymore. In the QEffect implementation, we can rely on the widget pointer not being nullptr (it's tested in the free functions client code uses). Includes a few drive-by changes to coding style and logic in qtooltip.cpp, where the tip label placement now prefers the screen of the widget the label is created for, and uses the position only as a fallback. What remains is the special handling of QDesktopWidget and the Qt::Desktop type in QWidget and QApplication. Change-Id: I30b67bab8ae82ddfcc7bbbec3c10f6e935b74f06 Reviewed-by: Shawn Rutledge Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- src/widgets/dialogs/qcolordialog.cpp | 11 ++-- src/widgets/dialogs/qdialog.cpp | 25 ++++---- src/widgets/dialogs/qmessagebox.cpp | 3 +- src/widgets/dialogs/qwizard.cpp | 1 - src/widgets/kernel/qtooltip.cpp | 41 +++++-------- src/widgets/kernel/qwhatsthis.cpp | 45 +++++++-------- src/widgets/util/qcompleter.cpp | 2 +- src/widgets/util/qscroller.cpp | 1 - src/widgets/util/qsystemtrayicon.cpp | 18 +++--- src/widgets/widgets/qcombobox.cpp | 1 - src/widgets/widgets/qdatetimeedit.cpp | 34 ++++++----- src/widgets/widgets/qdockarealayout.cpp | 22 +++---- src/widgets/widgets/qeffects.cpp | 16 +++-- src/widgets/widgets/qfontcombobox.cpp | 1 - src/widgets/widgets/qmdiarea.cpp | 1 - src/widgets/widgets/qmenu.cpp | 24 +++----- src/widgets/widgets/qmenu_p.h | 3 +- src/widgets/widgets/qmenubar.cpp | 1 - src/widgets/widgets/qpushbutton.cpp | 1 - src/widgets/widgets/qsizegrip.cpp | 1 - src/widgets/widgets/qsplashscreen.cpp | 61 ++++---------------- src/widgets/widgets/qtabwidget.cpp | 1 - src/widgets/widgets/qtoolbutton.cpp | 3 +- src/widgets/widgets/qwidgetresizehandler.cpp | 2 +- 24 files changed, 129 insertions(+), 190 deletions(-) diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 8e5895f48b8..30c81f8c0e9 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -40,7 +40,6 @@ #include "qcolordialog.h" #include "qapplication.h" -#include #include "qdrawutil.h" #include "qevent.h" #include "qimage.h" @@ -1564,9 +1563,11 @@ bool QColorDialogPrivate::selectColor(const QColor &col) QColor QColorDialogPrivate::grabScreenColor(const QPoint &p) { - const QWidget *desktop = QApplication::desktop(); - const QPixmap pixmap = QGuiApplication::primaryScreen()->grabWindow(desktop->winId(), p.x(), p.y(), 1, 1); - QImage i = pixmap.toImage(); + QScreen *screen = QGuiApplication::screenAt(p); + if (!screen) + screen = QGuiApplication::primaryScreen(); + const QPixmap pixmap = screen->grabWindow(0, p.x(), p.y(), 1, 1); + const QImage i = pixmap.toImage(); return i.pixel(0, 0); } @@ -1758,7 +1759,7 @@ void QColorDialogPrivate::initWidgets() } else { // better color picker size for small displays #if defined(QT_SMALL_COLORDIALOG) - QSize screenSize = QDesktopWidgetPrivate::availableGeometry(QCursor::pos()).size(); + QSize screenSize = QGuiApplication::screenAt(QCursor::pos())->availableGeometry().size(); pWidth = pHeight = qMin(screenSize.width(), screenSize.height()); pHeight -= 20; if(screenSize.height() > screenSize.width()) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 0f0e213e71d..52976611aaa 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -49,7 +49,6 @@ #endif #include "qevent.h" -#include #include "qapplication.h" #include "qlayout.h" #if QT_CONFIG(sizegrip) @@ -872,23 +871,23 @@ void QDialog::showEvent(QShowEvent *event) /*! \internal */ void QDialog::adjustPosition(QWidget* w) { - if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) if (theme->themeHint(QPlatformTheme::WindowAutoPlacement).toBool()) return; QPoint p(0, 0); - int extraw = 0, extrah = 0, scrn = 0; + int extraw = 0, extrah = 0; if (w) w = w->window(); QRect desk; - if (w) { - scrn = QDesktopWidgetPrivate::screenNumber(w); - } else if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1) { - scrn = QDesktopWidgetPrivate::screenNumber(QCursor::pos()); - } else { - scrn = QDesktopWidgetPrivate::screenNumber(this); - } - desk = QDesktopWidgetPrivate::availableGeometry(scrn); + QScreen *scrn = nullptr; + if (w) + scrn = w->screen(); + else if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1) + scrn = QGuiApplication::screenAt(QCursor::pos()); + else + scrn = screen(); + if (scrn) + desk = scrn->availableGeometry(); QWidgetList list = QApplication::topLevelWidgets(); for (int i = 0; (extraw == 0 || extrah == 0) && i < list.size(); ++i) { @@ -942,9 +941,9 @@ void QDialog::adjustPosition(QWidget* w) // QTBUG-52735: Manually set the correct target screen since scaling in a // subsequent call to QWindow::resize() may otherwise use the wrong factor // if the screen changed notification is still in an event queue. - if (scrn >= 0) { + if (scrn) { if (QWindow *window = windowHandle()) - window->setScreen(QGuiApplication::screens().at(scrn)); + window->setScreen(scrn); } move(p); diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index e0edc2f7555..22d86b301ad 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -64,7 +64,6 @@ #include #include #include "private/qabstractbutton_p.h" -#include #ifdef Q_OS_WIN # include @@ -363,7 +362,7 @@ void QMessageBoxPrivate::updateSize() if (!q->isVisible()) return; - QSize screenSize = QDesktopWidgetPrivate::availableGeometry(QCursor::pos()).size(); + const QSize screenSize = QGuiApplication::screenAt(QCursor::pos())->availableGeometry().size(); int hardLimit = qMin(screenSize.width() - 480, 1000); // can never get bigger than this // on small screens allows the messagebox be the same size as the screen if (screenSize.width() <= 1024) diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp index 0860f9defe5..2548a668ced 100644 --- a/src/widgets/dialogs/qwizard.cpp +++ b/src/widgets/dialogs/qwizard.cpp @@ -47,7 +47,6 @@ #include "qapplication.h" #include "qboxlayout.h" #include "qlayoutitem.h" -#include #include "qevent.h" #include "qframe.h" #include "qlabel.h" diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp index af5fbadf22f..a57ede6059e 100644 --- a/src/widgets/kernel/qtooltip.cpp +++ b/src/widgets/kernel/qtooltip.cpp @@ -40,7 +40,6 @@ #include #include -#include #include #include #include @@ -167,11 +166,11 @@ private: QTipLabel *QTipLabel::instance = nullptr; QTipLabel::QTipLabel(const QString &text, const QPoint &pos, QWidget *w, int msecDisplayTime) + : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget) #ifndef QT_NO_STYLE_STYLESHEET - : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), styleSheetParent(nullptr), widget(nullptr) -#else - : QLabel(w, Qt::ToolTip | Qt::BypassGraphicsProxyWidget), widget(0) + , styleSheetParent(nullptr) #endif + , widget(nullptr) { delete instance; instance = this; @@ -225,15 +224,10 @@ void QTipLabel::updateSize(const QPoint &pos) ++extra.rheight(); setWordWrap(Qt::mightBeRichText(text())); QSize sh = sizeHint(); - QScreen *screen = windowHandle() ? windowHandle()->screen() : QGuiApplication::screenAt(pos); - if (!screen) - screen = QGuiApplication::primaryScreen(); - if (screen) { - const qreal screenWidth = screen->geometry().width(); - if (!wordWrap() && sh.width() > screenWidth) { - setWordWrap(true); - sh = sizeHint(); - } + const QScreen *screen = getTipScreen(pos, this); + if (!wordWrap() && sh.width() > screen->geometry().width()) { + setWordWrap(true); + sh = sizeHint(); } resize(sh + extra); } @@ -367,10 +361,7 @@ bool QTipLabel::eventFilter(QObject *o, QEvent *e) QScreen *QTipLabel::getTipScreen(const QPoint &pos, QWidget *w) { - int screenNo = QGuiApplication::primaryScreen()->virtualSiblings().size() > 1 - ? QDesktopWidgetPrivate::screenNumber(pos) - : QDesktopWidgetPrivate::screenNumber(w); - return QDesktopWidgetPrivate::screen(screenNo); + return w ? w->screen() : QGuiApplication::primaryScreen()->virtualSiblingAt(pos); } void QTipLabel::placeTip(const QPoint &pos, QWidget *w) @@ -463,12 +454,11 @@ bool QTipLabel::tipChanged(const QPoint &pos, const QString &text, QObject *o) void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime) { - if (QTipLabel::instance && QTipLabel::instance->isVisible()){ // a tip does already exist + if (QTipLabel::instance && QTipLabel::instance->isVisible()) { // a tip does already exist if (text.isEmpty()){ // empty text means hide current tip QTipLabel::instance->hideTip(); return; - } - else if (!QTipLabel::instance->fadingOut){ + } else if (!QTipLabel::instance->fadingOut) { // If the tip has changed, reuse the one // that is showing (removes flickering) QPoint localPos = pos; @@ -483,24 +473,23 @@ 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* { + if (!text.isEmpty()) { // no tip can be reused, create new tip: + QWidget *tipLabelParent = [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 - QScreen *screen = QTipLabel::getTipScreen(pos, w); - return QApplication::desktop(screen); + Q_UNUSED(w); + return nullptr; #else - Q_UNUSED(pos); return w; #endif }(); new QTipLabel(text, pos, tipLabelParent, msecDisplayTime); // sets QTipLabel::instance to itself + QWidgetPrivate::get(QTipLabel::instance)->setScreen(QTipLabel::getTipScreen(pos, w)); QTipLabel::instance->setTipRect(w, rect); QTipLabel::instance->placeTip(pos, w); QTipLabel::instance->setObjectName(QLatin1String("qtooltip_label")); - #if QT_CONFIG(effects) if (QApplication::isEffectEnabled(Qt::UI_FadeTooltip)) qFadeEffect(QTipLabel::instance); diff --git a/src/widgets/kernel/qwhatsthis.cpp b/src/widgets/kernel/qwhatsthis.cpp index c5a9989837e..7ca50f9dab9 100644 --- a/src/widgets/kernel/qwhatsthis.cpp +++ b/src/widgets/kernel/qwhatsthis.cpp @@ -41,7 +41,7 @@ #include "qpointer.h" #include "qapplication.h" #include -#include +#include "qwidget.h" #include "qevent.h" #include "qpixmap.h" #include "qscreen.h" @@ -235,8 +235,7 @@ QWhatsThat::~QWhatsThat() void QWhatsThat::showEvent(QShowEvent *) { - background = QGuiApplication::primaryScreen()->grabWindow(QApplication::desktop()->internalWinId(), - x(), y(), width(), height()); + background = QGuiApplication::primaryScreen()->grabWindow(0, x(), y(), width(), height()); } void QWhatsThat::mousePressEvent(QMouseEvent* e) @@ -579,16 +578,16 @@ void QWhatsThisPrivate::say(QWidget * widget, const QString &text, int x, int y) QWhatsThat *whatsThat = new QWhatsThat(text, nullptr, widget); // okay, now to find a suitable location - int scr = (widget ? - QDesktopWidgetPrivate::screenNumber(widget) : - QDesktopWidgetPrivate::screenNumber(QPoint(x,y)) - ); - QRect screen = QDesktopWidgetPrivate::screenGeometry(scr); + QScreen *screen = widget ? widget->screen() + : QGuiApplication::screenAt(QPoint(x, y)); + if (!screen) + screen = QGuiApplication::primaryScreen(); + QRect screenRect = screen->geometry(); int w = whatsThat->width(); int h = whatsThat->height(); - int sx = screen.x(); - int sy = screen.y(); + int sx = screenRect.x(); + int sy = screenRect.y(); // first try locating the widget immediately above/below, // with nice alignment if possible. @@ -601,13 +600,13 @@ void QWhatsThisPrivate::say(QWidget * widget, const QString &text, int x, int y) else x = x - w/2; - // squeeze it in if that would result in part of what's this - // being only partially visible - if (x + w + shadowWidth > sx+screen.width()) - x = (widget? (qMin(screen.width(), - pos.x() + widget->width()) - ) : screen.width()) + // squeeze it in if that would result in part of what's this + // being only partially visible + if (x + w + shadowWidth > sx+screenRect.width()) { + x = (widget ? qMin(screenRect.width(), pos.x() + widget->width()) + : screenRect.width()) - w; + } if (x < sx) x = sx; @@ -615,18 +614,18 @@ void QWhatsThisPrivate::say(QWidget * widget, const QString &text, int x, int y) if (widget && h > widget->height() + 16) { y = pos.y() + widget->height() + 2; // below, two pixels spacing // what's this is above or below, wherever there's most space - if (y + h + 10 > sy+screen.height()) + if (y + h + 10 > sy + screenRect.height()) y = pos.y() + 2 - shadowWidth - h; // above, overlap } y = y + 2; - // squeeze it in if that would result in part of what's this - // being only partially visible - if (y + h + shadowWidth > sy+screen.height()) - y = (widget ? (qMin(screen.height(), - pos.y() + widget->height()) - ) : screen.height()) + // squeeze it in if that would result in part of what's this + // being only partially visible + if (y + h + shadowWidth > sy + screenRect.height()) { + y = (widget ? qMin(screenRect.height(), pos.y() + widget->height()) + : screenRect.height()) - h; + } if (y < sy) y = sy; diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 30838899541..cdd06f47907 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -158,7 +158,7 @@ #include "QtWidgets/qapplication.h" #include "QtGui/qevent.h" #include -#include +#include #if QT_CONFIG(lineedit) #include "QtWidgets/qlineedit.h" #endif diff --git a/src/widgets/util/qscroller.cpp b/src/widgets/util/qscroller.cpp index 003f27de567..b94d8f4b81b 100644 --- a/src/widgets/util/qscroller.cpp +++ b/src/widgets/util/qscroller.cpp @@ -57,7 +57,6 @@ #include #include #endif -#include #include #include #include diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp index 9e49b1ec57a..556427387f9 100644 --- a/src/widgets/util/qsystemtrayicon.cpp +++ b/src/widgets/util/qsystemtrayicon.cpp @@ -60,7 +60,6 @@ #include "qstyle.h" #include "qgridlayout.h" #include "qapplication.h" -#include #include "qbitmap.h" #include @@ -599,12 +598,15 @@ void QBalloonTip::resizeEvent(QResizeEvent *ev) void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow) { this->showArrow = showArrow; - QRect scr = QDesktopWidgetPrivate::screenGeometry(pos); + QScreen *screen = QGuiApplication::screenAt(pos); + if (!screen) + screen = QGuiApplication::primaryScreen(); + QRect screenRect = screen->geometry(); QSize sh = sizeHint(); const int border = 1; const int ah = 18, ao = 18, aw = 18, rc = 7; - bool arrowAtTop = (pos.y() + sh.height() + ah < scr.height()); - bool arrowAtLeft = (pos.x() + sh.width() - ao < scr.width()); + bool arrowAtTop = (pos.y() + sh.height() + ah < screenRect.height()); + bool arrowAtLeft = (pos.x() + sh.width() - ao < screenRect.width()); setContentsMargins(border + 3, border + (arrowAtTop ? ah : 0) + 2, border + 3, border + (arrowAtTop ? 0 : ah) + 2); updateGeometry(); sh = sizeHint(); @@ -630,14 +632,14 @@ void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow) path.lineTo(ml + ao, mt - ah); path.lineTo(ml + ao + aw, mt); } - move(qMax(pos.x() - ao, scr.left() + 2), pos.y()); + move(qMax(pos.x() - ao, screenRect.left() + 2), pos.y()); } else if (arrowAtTop && !arrowAtLeft) { if (showArrow) { path.lineTo(mr - ao - aw, mt); path.lineTo(mr - ao, mt - ah); path.lineTo(mr - ao, mt); } - move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2), pos.y()); + move(qMin(pos.x() - sh.width() + ao, screenRect.right() - sh.width() - 2), pos.y()); } path.lineTo(mr - rc, mt); path.arcTo(QRect(mr - rc*2, mt, rc*2, rc*2), 90, -90); @@ -649,7 +651,7 @@ void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow) path.lineTo(mr - ao, mb + ah); path.lineTo(mr - ao - aw, mb); } - move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2), + move(qMin(pos.x() - sh.width() + ao, screenRect.right() - sh.width() - 2), pos.y() - sh.height()); } else if (!arrowAtTop && arrowAtLeft) { if (showArrow) { @@ -657,7 +659,7 @@ void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow) path.lineTo(ao, mb + ah); path.lineTo(ao, mb); } - move(qMax(pos.x() - ao, scr.x() + 2), pos.y() - sh.height()); + move(qMax(pos.x() - ao, screenRect.x() + 2), pos.y() - sh.height()); } path.lineTo(ml + rc, mb); path.arcTo(QRect(ml, mb - rc*2, rc*2, rc*2), -90, -90); diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 042e702987a..c42d9512487 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #include #if QT_CONFIG(tableview) #include diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 01f22b2dd6f..d8256760350 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -2598,28 +2597,31 @@ void QDateTimeEditPrivate::positionCalendarPopup() pos = q->mapToGlobal(pos); pos2 = q->mapToGlobal(pos2); QSize size = monthCalendar->sizeHint(); - QRect screen = QDesktopWidgetPrivate::availableGeometry(pos); + QScreen *screen = QGuiApplication::screenAt(pos); + if (!screen) + screen = QGuiApplication::primaryScreen(); + const QRect screenRect = screen->availableGeometry(); //handle popup falling "off screen" if (q->layoutDirection() == Qt::RightToLeft) { pos.setX(pos.x()-size.width()); pos2.setX(pos2.x()-size.width()); - if (pos.x() < screen.left()) - pos.setX(qMax(pos.x(), screen.left())); - else if (pos.x()+size.width() > screen.right()) - pos.setX(qMax(pos.x()-size.width(), screen.right()-size.width())); + if (pos.x() < screenRect.left()) + pos.setX(qMax(pos.x(), screenRect.left())); + else if (pos.x()+size.width() > screenRect.right()) + pos.setX(qMax(pos.x()-size.width(), screenRect.right()-size.width())); } else { - if (pos.x()+size.width() > screen.right()) - pos.setX(screen.right()-size.width()); - pos.setX(qMax(pos.x(), screen.left())); + if (pos.x()+size.width() > screenRect.right()) + pos.setX(screenRect.right()-size.width()); + pos.setX(qMax(pos.x(), screenRect.left())); } - if (pos.y() + size.height() > screen.bottom()) + if (pos.y() + size.height() > screenRect.bottom()) pos.setY(pos2.y() - size.height()); - else if (pos.y() < screen.top()) - pos.setY(screen.top()); - if (pos.y() < screen.top()) - pos.setY(screen.top()); - if (pos.y()+size.height() > screen.bottom()) - pos.setY(screen.bottom()-size.height()); + else if (pos.y() < screenRect.top()) + pos.setY(screenRect.top()); + if (pos.y() < screenRect.top()) + pos.setY(screenRect.top()); + if (pos.y()+size.height() > screenRect.bottom()) + pos.setY(screenRect.bottom()-size.height()); monthCalendar->move(pos); } diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index 022ee645cb8..26543415050 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -44,7 +44,6 @@ #include "QtWidgets/qtabbar.h" #endif #include "QtWidgets/qstyle.h" -#include #include "QtWidgets/qapplication.h" #include "QtCore/qvariant.h" #include "qdockarealayout_p.h" @@ -3019,19 +3018,20 @@ QSize QDockAreaLayout::minimumSize() const */ QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget) { - QRect desktop; + QScreen *screen; if (QGuiApplication::primaryScreen()->virtualSiblings().size() > 1) - desktop = QDesktopWidgetPrivate::screenGeometry(rect.topLeft()); + screen = QGuiApplication::screenAt(rect.topLeft()); else - desktop = QWidgetPrivate::screenGeometry(widget); + screen = widget->screen(); - if (desktop.isValid()) { - rect.setWidth(qMin(rect.width(), desktop.width())); - rect.setHeight(qMin(rect.height(), desktop.height())); - rect.moveLeft(qMax(rect.left(), desktop.left())); - rect.moveTop(qMax(rect.top(), desktop.top())); - rect.moveRight(qMin(rect.right(), desktop.right())); - rect.moveBottom(qMin(rect.bottom(), desktop.bottom())); + const QRect screenRect = screen->geometry(); + if (screenRect.isValid()) { + rect.setWidth(qMin(rect.width(), screenRect.width())); + rect.setHeight(qMin(rect.height(), screenRect.height())); + rect.moveLeft(qMax(rect.left(), screenRect.left())); + rect.moveTop(qMax(rect.top(), screenRect.top())); + rect.moveRight(qMin(rect.right(), screenRect.right())); + rect.moveBottom(qMin(rect.bottom(), screenRect.bottom())); } return rect; diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp index cdfad40760c..0090f9b0b9e 100644 --- a/src/widgets/widgets/qeffects.cpp +++ b/src/widgets/widgets/qeffects.cpp @@ -38,7 +38,9 @@ ****************************************************************************/ #include "qapplication.h" +#include "qdebug.h" #include "qeffects_p.h" +#include "qelapsedtimer.h" #include "qevent.h" #include "qimage.h" #include "qpainter.h" @@ -46,10 +48,10 @@ #include "qpixmap.h" #include "qpointer.h" #include "qtimer.h" -#include "qelapsedtimer.h" -#include "qdebug.h" +#include "qwidget.h" +#include "private/qwidget_p.h" +#include "qwindow.h" -#include QT_BEGIN_NAMESPACE @@ -98,8 +100,9 @@ static QAlphaWidget* q_blend = nullptr; Constructs a QAlphaWidget. */ QAlphaWidget::QAlphaWidget(QWidget* w, Qt::WindowFlags f) - : QWidget(QApplication::desktop(w ? w->screen() : nullptr), f) + : QWidget(nullptr, f) { + QWidgetPrivate::get(this)->setScreen(w->screen()); #ifndef Q_OS_WIN setEnabled(false); #endif @@ -161,7 +164,7 @@ void QAlphaWidget::run(int time) resize(widget->size().width(), widget->size().height()); frontImage = widget->grab().toImage(); - backImage = QGuiApplication::primaryScreen()->grabWindow(QApplication::desktop()->winId(), + backImage = QGuiApplication::primaryScreen()->grabWindow(0, widget->geometry().x(), widget->geometry().y(), widget->geometry().width(), widget->geometry().height()).toImage(); @@ -379,8 +382,9 @@ static QRollEffect* q_roll = nullptr; Construct a QRollEffect widget. */ QRollEffect::QRollEffect(QWidget* w, Qt::WindowFlags f, DirFlags orient) - : QWidget(QApplication::desktop(w ? w->screen() : nullptr), f), orientation(orient) + : QWidget(nullptr, f), orientation(orient) { + QWidgetPrivate::get(this)->setScreen(w->screen()); #ifndef Q_OS_WIN setEnabled(false); #endif diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index a4ac34b51a7..5f90853ec51 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -46,7 +46,6 @@ #include #include #include -#include #include QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp index f2613bf5dd7..c1913a3d09f 100644 --- a/src/widgets/widgets/qmdiarea.cpp +++ b/src/widgets/widgets/qmdiarea.cpp @@ -165,7 +165,6 @@ #include #include #include -#include #include #include #if QT_CONFIG(menu) diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 96945fe7563..5edc4809495 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -81,7 +81,6 @@ #include #include #include -#include #include QT_BEGIN_NAMESPACE @@ -108,7 +107,7 @@ class QTornOffMenu : public QMenu Q_Q(QTornOffMenu); QSize size = menuSize; const QPoint p = (!initialized) ? causedMenu->pos() : q->pos(); - QRect screen = popupGeometry(QDesktopWidgetPrivate::screenNumber(p)); + const QRect screen = popupGeometry(QGuiApplication::screenAt(p)); const int desktopFrame = q->style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, nullptr, q); const int titleBarHeight = q->style()->pixelMetric(QStyle::PM_TitleBarHeight, nullptr, q); if (scroll && (size.height() > screen.height() - titleBarHeight || size.width() > screen.width())) { @@ -319,19 +318,14 @@ inline bool QMenuPrivate::useFullScreenForPopup() const return !tornoff && QStylePrivate::useFullScreenForPopup(); } -QRect QMenuPrivate::popupGeometry() const +QRect QMenuPrivate::popupGeometry(QScreen *screen) const { Q_Q(const QMenu); - return useFullScreenForPopup() - ? QWidgetPrivate::screenGeometry(q) - : QWidgetPrivate::availableScreenGeometry(q); -} - -QRect QMenuPrivate::popupGeometry(int screen) const -{ - return useFullScreenForPopup() - ? QDesktopWidgetPrivate::screenGeometry(screen) - : QDesktopWidgetPrivate::availableGeometry(screen); + if (useFullScreenForPopup()) + return screen ? screen->geometry() + : QWidgetPrivate::screenGeometry(q); + return screen ? screen->availableGeometry() + : QWidgetPrivate::availableScreenGeometry(q); } QList> QMenuPrivate::calcCausedStack() const @@ -2427,7 +2421,7 @@ void QMenuPrivate::popup(const QPoint &p, QAction *atAction, PositionFunction po screen = popupGeometry(); else #endif - screen = popupGeometry(QDesktopWidgetPrivate::screenNumber(p)); + screen = popupGeometry(QGuiApplication::screenAt(p)); updateActionRects(screen); QPoint pos; @@ -3668,7 +3662,7 @@ void QMenu::internalDelayedPopup() screen = d->popupGeometry(); else #endif - screen = d->popupGeometry(QDesktopWidgetPrivate::screenNumber(pos())); + screen = d->popupGeometry(QGuiApplication::screenAt(pos())); int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, nullptr, this); const QRect actionRect(d->actionRect(d->currentAction)); diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 4814fcaad99..ffe956d007a 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -352,8 +352,7 @@ public: mutable QHash widgetItems; void updateActionRects() const; void updateActionRects(const QRect &screen) const; - QRect popupGeometry() const; - QRect popupGeometry(int screen) const; + QRect popupGeometry(QScreen *screen = nullptr) const; bool useFullScreenForPopup() const; int getLastVisibleAction() const; void popup(const QPoint &p, QAction *atAction, PositionFunction positionFunction = {}); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 10c44e4203c..5fd84f7f3bf 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -63,7 +63,6 @@ #include #include "private/qguiapplication_p.h" #include "qpa/qplatformintegration.h" -#include #include "qmenu_p.h" #include "qmenubar_p.h" diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp index 8657eb4174d..4faa8c7f675 100644 --- a/src/widgets/widgets/qpushbutton.cpp +++ b/src/widgets/widgets/qpushbutton.cpp @@ -39,7 +39,6 @@ #include "qapplication.h" #include "qbitmap.h" -#include #if QT_CONFIG(dialog) #include #endif diff --git a/src/widgets/widgets/qsizegrip.cpp b/src/widgets/widgets/qsizegrip.cpp index 02d9b4f3f1d..946839c3738 100644 --- a/src/widgets/widgets/qsizegrip.cpp +++ b/src/widgets/widgets/qsizegrip.cpp @@ -50,7 +50,6 @@ #include "qdebug.h" #include -#include #include QT_BEGIN_NAMESPACE diff --git a/src/widgets/widgets/qsplashscreen.cpp b/src/widgets/widgets/qsplashscreen.cpp index 1f1c71dcb80..2c2d1922be9 100644 --- a/src/widgets/widgets/qsplashscreen.cpp +++ b/src/widgets/widgets/qsplashscreen.cpp @@ -40,7 +40,6 @@ #include "qsplashscreen.h" #include "qapplication.h" -#include #include "qpainter.h" #include "qpixmap.h" #include "qtextdocument.h" @@ -69,10 +68,6 @@ public: int currAlign; inline QSplashScreenPrivate(); - - void setPixmap(const QPixmap &p, const QScreen *screen = nullptr); - - static const QScreen *screenFor(const QWidget *w); }; /*! @@ -153,7 +148,9 @@ QSplashScreen::QSplashScreen(const QPixmap &pixmap, Qt::WindowFlags f) QSplashScreen::QSplashScreen(QScreen *screen, const QPixmap &pixmap, Qt::WindowFlags f) : QWidget(*(new QSplashScreenPrivate()), nullptr, Qt::SplashScreen | Qt::FramelessWindowHint | f) { - d_func()->setPixmap(pixmap, screen); + Q_D(QSplashScreen); + d->setScreen(screen); + setPixmap(pixmap); } /*! @@ -283,52 +280,16 @@ void QSplashScreen::finish(QWidget *mainWin) */ void QSplashScreen::setPixmap(const QPixmap &pixmap) { - d_func()->setPixmap(pixmap, QSplashScreenPrivate::screenFor(this)); -} + Q_D(QSplashScreen); + d->pixmap = pixmap; + setAttribute(Qt::WA_TranslucentBackground, pixmap.hasAlpha()); -// In setPixmap(), resize and try to position on a screen according to: -// 1) If the screen for the given widget is available, use that -// 2) If a QDesktopScreenWidget is found in the parent hierarchy, use that (see docs on -// QSplashScreen(QWidget *, QPixmap). -// 3) If a widget with associated QWindow is found, use that -// 4) When nothing can be found, try to center it over the cursor + const QRect r(QPoint(), pixmap.size() / pixmap.devicePixelRatio()); + resize(r.size()); -const QScreen *QSplashScreenPrivate::screenFor(const QWidget *w) -{ - if (w && w->screen()) - return w->screen(); - - for (const QWidget *p = w; p !=nullptr ; p = p->parentWidget()) { - if (auto dsw = qobject_cast(p)) - return dsw->screen(); - if (QWindow *window = p->windowHandle()) - return window->screen(); - } - -#if QT_CONFIG(cursor) - // Note: We could rely on QPlatformWindow::initialGeometry() to center it - // over the cursor, but not all platforms (namely Android) use that. - if (QGuiApplication::screens().size() > 1) { - if (auto screenAtCursor = QGuiApplication::screenAt(QCursor::pos())) - return screenAtCursor; - } -#endif // cursor - return QGuiApplication::primaryScreen(); -} - -void QSplashScreenPrivate::setPixmap(const QPixmap &p, const QScreen *screen) -{ - Q_Q(QSplashScreen); - - pixmap = p; - q->setAttribute(Qt::WA_TranslucentBackground, pixmap.hasAlpha()); - - QRect r(QPoint(), pixmap.size() / pixmap.devicePixelRatio()); - q->resize(r.size()); - if (screen) - q->move(screen->geometry().center() - r.center()); - if (q->isVisible()) - q->repaint(); + move(screen()->geometry().center() - r.center()); + if (isVisible()) + repaint(); } /*! diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index e054156995f..710d5a42a7b 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -44,7 +44,6 @@ #include "private/qtabbar_p.h" #include "qapplication.h" #include "qbitmap.h" -#include #include "qevent.h" #include "qlayout.h" #include "qstackedwidget.h" diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index 0b090d2bac7..5a394cfda88 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -40,7 +40,6 @@ #include "qtoolbutton.h" #include -#include #include #include #include @@ -728,7 +727,7 @@ static QPoint positionMenu(const QToolButton *q, bool horizontal, { QPoint p; const QRect rect = q->rect(); // Find screen via point in case of QGraphicsProxyWidget. - QRect screen = QDesktopWidgetPrivate::availableGeometry(q->mapToGlobal(rect.center())); + const QRect screen = QWidgetPrivate::availableScreenGeometry(q); if (horizontal) { if (q->isRightToLeft()) { if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.bottom()) { diff --git a/src/widgets/widgets/qwidgetresizehandler.cpp b/src/widgets/widgets/qwidgetresizehandler.cpp index 4f6541f509b..0cf9457a578 100644 --- a/src/widgets/widgets/qwidgetresizehandler.cpp +++ b/src/widgets/widgets/qwidgetresizehandler.cpp @@ -41,7 +41,7 @@ #include "qframe.h" #include "qapplication.h" -#include +#include "private/qwidget_p.h" #include "qcursor.h" #if QT_CONFIG(sizegrip) #include "qsizegrip.h"