diff options
| author | Friedemann Kleint <[email protected]> | 2019-04-05 14:19:06 +0200 | 
|---|---|---|
| committer | Friedemann Kleint <[email protected]> | 2019-06-18 10:15:26 +0200 | 
| commit | eed9a8fbd300dafb2802b6c09c018fbda4e13ef1 (patch) | |
| tree | f7dd03d516d76be452336c1c086438ade2544b40 | |
| parent | cd563b3497a608a91794a7a086e5fbf248e77998 (diff) | |
Add accessors for QWindow and QScreen to QWidgetPrivate
Rewrite the existing accessor QWidgetPrivate::windowHandle() to
accept a mode enumeration that has an "Any" convenience.
Based on that, add QWidgetPrivate::associatedScreen(), which is seful
in many places where scaling is performed.
Prototypically simplify the code.
Task-number: QTBUG-62094
Task-number: QTBUG-73231
Change-Id: I516288363d329bce9bc94e4951106f9357bc6cde
Reviewed-by: Tor Arne Vestbø <[email protected]>
 
 
 
| -rw-r--r-- | src/widgets/accessible/qaccessiblemenu.cpp | 13 | ||||
| -rw-r--r-- | src/widgets/dialogs/qmessagebox.cpp | 11 | ||||
| -rw-r--r-- | src/widgets/itemviews/qabstractitemview.cpp | 11 | ||||
| -rw-r--r-- | src/widgets/kernel/qdesktopwidget.cpp | 12 | ||||
| -rw-r--r-- | src/widgets/kernel/qopenglwidget.cpp | 7 | ||||
| -rw-r--r-- | src/widgets/kernel/qwidget.cpp | 31 | ||||
| -rw-r--r-- | src/widgets/kernel/qwidget_p.h | 17 | ||||
| -rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 5 | ||||
| -rw-r--r-- | src/widgets/styles/qwindowsstyle.cpp | 17 | ||||
| -rw-r--r-- | src/widgets/widgets/qcombobox.cpp | 22 | ||||
| -rw-r--r-- | src/widgets/widgets/qdockwidget.cpp | 8 | ||||
| -rw-r--r-- | src/widgets/widgets/qlineedit_p.cpp | 4 | ||||
| -rw-r--r-- | src/widgets/widgets/qmainwindowlayout.cpp | 6 | 
13 files changed, 72 insertions, 92 deletions
diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp index 507584eb021..7f872885202 100644 --- a/src/widgets/accessible/qaccessiblemenu.cpp +++ b/src/widgets/accessible/qaccessiblemenu.cpp @@ -47,6 +47,7 @@  #endif  #include <QtWidgets/QAction>  #include <qstyle.h> +#include <private/qwidget_p.h>  #ifndef QT_NO_ACCESSIBILITY @@ -241,15 +242,9 @@ QObject *QAccessibleMenuItem::object() const  /*! \reimp */  QWindow *QAccessibleMenuItem::window() const  { -    QWindow *result = nullptr; -    if (!m_owner.isNull()) { -        result = m_owner->windowHandle(); -        if (!result) { -            if (const QWidget *nativeParent = m_owner->nativeParentWidget()) -                result = nativeParent->windowHandle(); -        } -    } -    return result; +    return m_owner.isNull() +        ? nullptr +        : qt_widget_private(m_owner.data())->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);  }  QRect QAccessibleMenuItem::rect() const diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index f143e3b5275..9bfea06a54c 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -2662,14 +2662,9 @@ QPixmap QMessageBoxPrivate::standardIcon(QMessageBox::Icon icon, QMessageBox *mb          break;      }      if (!tmpIcon.isNull()) { -        QWindow *window = nullptr; -        if (mb) { -            window = mb->windowHandle(); -            if (!window) { -                if (const QWidget *nativeParent = mb->nativeParentWidget()) -                    window = nativeParent->windowHandle(); -            } -        } +        QWindow *window = mb +            ? qt_widget_private(mb)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest) +            : nullptr;          return tmpIcon.pixmap(window, QSize(iconSize, iconSize));      }      return QPixmap(); diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 95631ffa5fe..1d1c144bb83 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -4461,15 +4461,8 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,      if (paintPairs.isEmpty())          return QPixmap(); -    qreal scale = 1.0f; - -    Q_Q(const QAbstractItemView); -    QWidget *window = q->window(); -    if (window) { -        QWindow *windowHandle = window->windowHandle(); -        if (windowHandle) -            scale = windowHandle->devicePixelRatio(); -    } +    QWindow *window = windowHandle(WindowHandleMode::Closest); +    const qreal scale = window ? window->devicePixelRatio() : qreal(1);      QPixmap pixmap(r->size() * scale);      pixmap.setDevicePixelRatio(scale); diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index d17c7eb36c7..ac0cfcf2f5e 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -321,20 +321,12 @@ int QDesktopWidgetPrivate::screenNumber(const QWidget *w)      if (screens.isEmpty()) // This should never happen          return primaryScreen(); -    const QWindow *winHandle = w->windowHandle(); -    if (!winHandle) { -        if (const QWidget *nativeParent = w->nativeParentWidget()) -            winHandle = nativeParent->windowHandle(); -    } -      // 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 (winHandle) { -            if (const QScreen *winScreen = winHandle->screen()) -                screens = winScreen->virtualSiblings(); -        } +        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 diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index 374ea53726f..ae7729b49b5 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -1333,11 +1333,8 @@ int QOpenGLWidget::metric(QPaintDevice::PaintDeviceMetric metric) const      if (d->inBackingStorePaint)          return QWidget::metric(metric); -    QWidget *tlw = window(); -    QWindow *window = tlw ? tlw->windowHandle() : 0; -    QScreen *screen = tlw && tlw->windowHandle() ? tlw->windowHandle()->screen() : 0; -    if (!screen && QGuiApplication::primaryScreen()) -        screen = QGuiApplication::primaryScreen(); +    auto window = d->windowHandle(QWidgetPrivate::WindowHandleMode::TopLevel); +    QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();      const float dpmx = qt_defaultDpiX() * 100. / 2.54;      const float dpmy = qt_defaultDpiY() * 100. / 2.54; diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 58963d5eec2..be2906a7430 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1252,6 +1252,33 @@ void QWidgetPrivate::createRecursively()      }  } +QWindow *QWidgetPrivate::windowHandle(WindowHandleMode mode) const +{ +    if (mode == WindowHandleMode::Direct || mode == WindowHandleMode::Closest) { +        if (QTLWExtra *x = maybeTopData()) +            return x->window; +    } +    if (mode == WindowHandleMode::Closest) { +        if (auto nativeParent = q_func()->nativeParentWidget()) { +            if (auto window = nativeParent->windowHandle()) +                return window; +        } +    } +    if (mode == WindowHandleMode::TopLevel || mode == WindowHandleMode::Closest) { +        if (auto topLevel = q_func()->topLevelWidget()) { +            if (auto window = topLevel ->windowHandle()) +                return window; +        } +    } +    return nullptr; +} + +QScreen *QWidgetPrivate::associatedScreen() const +{ +    if (auto window = windowHandle(WindowHandleMode::Closest)) +        return window->screen(); +    return nullptr; +}  // ### fixme: Qt 6: Remove parameter window from QWidget::create() @@ -8103,7 +8130,7 @@ void QWidgetPrivate::show_sys()  {      Q_Q(QWidget); -    QWidgetWindow *window = windowHandle(); +    auto window = qobject_cast<QWidgetWindow *>(windowHandle());      if (q->testAttribute(Qt::WA_DontShowOnScreen)) {          invalidateBackingStore(q->rect()); @@ -8242,7 +8269,7 @@ void QWidgetPrivate::hide_sys()  {      Q_Q(QWidget); -    QWidgetWindow *window = windowHandle(); +    auto window = qobject_cast<QWidgetWindow *>(windowHandle());      if (q->testAttribute(Qt::WA_DontShowOnScreen)) {          q->setAttribute(Qt::WA_Mapped, false); diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index c073b8fb038..1f36c192f53 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -342,7 +342,15 @@ public:      QPainter *sharedPainter() const;      void setSharedPainter(QPainter *painter);      QWidgetBackingStore *maybeBackingStore() const; -    QWidgetWindow *windowHandle() const; + +    enum class WindowHandleMode { +        Direct, +        Closest, +        TopLevel +    }; +    QWindow *windowHandle(WindowHandleMode mode = WindowHandleMode::Direct) const; + +    QScreen *associatedScreen() const;      template <typename T>      void repaint(T t); @@ -1014,13 +1022,6 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const      return x ? x->backingStoreTracker.data() : nullptr;  } -inline QWidgetWindow *QWidgetPrivate::windowHandle() const -{ -    if (QTLWExtra *x = maybeTopData()) -        return x->window; -    return nullptr; -} -  QT_END_NAMESPACE  #endif // QWIDGET_P_H diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 70b305326c3..a5d9eee49de 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -592,10 +592,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)                          w->window()->raise();                      } -                    QWindow *win = w->windowHandle(); -                    if (!win) -                        win = w->nativeParentWidget()->windowHandle(); -                    if (win) { +                    if (auto win = qt_widget_private(w)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest)) {                          const QRect globalGeometry = win->isTopLevel()                              ? win->geometry()                              : QRect(win->mapToGlobal(QPoint(0, 0)), win->size()); diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index 7b5da9bfa86..3c0478b84e9 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -380,23 +380,12 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm)      return QWindowsStylePrivate::InvalidMetric;  } -static QWindow *windowOf(const QWidget *w) +static QScreen *screenOf(const QWidget *w)  { -    QWindow *result = nullptr;      if (w) { -        result = w->windowHandle(); -        if (!result) { -            if (const QWidget *np = w->nativeParentWidget()) -                result = np->windowHandle(); -        } +        if (auto screen = qt_widget_private(const_cast<QWidget *>(w))->associatedScreen()) +            return screen;      } -    return result; -} - -static QScreen *screenOf(const QWidget *w) -{ -    if (const QWindow *window = windowOf(w)) -        return window->screen();      return QGuiApplication::primaryScreen();  } diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index a1434203d30..a052f2df79f 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2838,19 +2838,15 @@ void QComboBox::showPopup()      bool startTimer = !container->isVisible();      container->raise();      container->create(); -    QWindow *containerWindow = container->window()->windowHandle(); -    if (containerWindow) { -        QWindow *win = window()->windowHandle(); -        if (win) { -            QScreen *currentScreen = win->screen(); -            if (currentScreen && !currentScreen->virtualSiblings().contains(containerWindow->screen())) { -                containerWindow->setScreen(currentScreen); - -                // This seems to workaround an issue in xcb+multi GPU+multiscreen -                // environment where the window might not always show up when screen -                // is changed. -                container->hide(); -            } +    if (QWindow *containerWindow = qt_widget_private(container)->windowHandle(QWidgetPrivate::WindowHandleMode::TopLevel)) { +        QScreen *currentScreen = d->associatedScreen(); +        if (currentScreen && !currentScreen->virtualSiblings().contains(containerWindow->screen())) { +            containerWindow->setScreen(currentScreen); + +            // This seems to workaround an issue in xcb+multi GPU+multiscreen +            // environment where the window might not always show up when screen +            // is changed. +            container->hide();          }      }      container->show(); diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index f98e0e44db5..b8b6c12bf39 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -1535,10 +1535,10 @@ bool QDockWidget::event(QEvent *event)          d->toggleViewAction->setChecked(true);          QPoint parentTopLeft(0, 0);          if (isWindow()) { -            if (const QWindow *window = windowHandle()) -                parentTopLeft = window->screen()->availableVirtualGeometry().topLeft(); -            else -                parentTopLeft = QGuiApplication::primaryScreen()->availableVirtualGeometry().topLeft(); +            const QScreen *screen = d->associatedScreen(); +            parentTopLeft = screen +                ? screen->availableVirtualGeometry().topLeft() +                : QGuiApplication::primaryScreen()->availableVirtualGeometry().topLeft();          }          emit visibilityChanged(geometry().right() >= parentTopLeft.x() && geometry().bottom() >= parentTopLeft.y());  } diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 21e70db0aca..7d580e50a51 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -355,9 +355,7 @@ QLineEditPrivate *QLineEditIconButton::lineEditPrivate() const  void QLineEditIconButton::paintEvent(QPaintEvent *)  {      QPainter painter(this); -    QWindow *window = nullptr; -    if (const QWidget *nativeParent = nativeParentWidget()) -        window = nativeParent->windowHandle(); +    QWindow *window = qt_widget_private(this)->windowHandle(QWidgetPrivate::WindowHandleMode::Closest);      QIcon::Mode state = QIcon::Disabled;      if (isEnabled())          state = isDown() ? QIcon::Active : QIcon::Normal; diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index f54835f23b5..b8f997b7823 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -2584,9 +2584,9 @@ void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos)              }          }          for (QWidget *w : candidates) { -            QWindow *handle1 = widget->windowHandle(); -            QWindow *handle2 = w->windowHandle(); -            if (handle1 && handle2 && handle1->screen() != handle2->screen()) +            const QScreen *screen1 = qt_widget_private(widget)->associatedScreen(); +            const QScreen *screen2 = qt_widget_private(w)->associatedScreen(); +            if (screen1 && screen2 && screen1 != screen2)                  continue;              if (!w->geometry().contains(mousePos))                  continue;  | 
