diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm index b4a16ab912..3525fddfd1 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.mm +++ b/src/plugins/platforms/cocoa/qcocoadrag.mm @@ -40,9 +40,6 @@ #include "qcocoadrag.h" #include "qmacclipboard.h" #include "qcocoahelpers.h" -#ifndef QT_NO_WIDGETS -#include -#endif #include QT_BEGIN_NAMESPACE @@ -189,19 +186,17 @@ QPixmap QCocoaDrag::dragPixmap(QDrag *drag, QPoint &hotSpot) const const int height = fm.height(); if (width > 0 && height > 0) { qreal dpr = 1.0; - if (const QWindow *sourceWindow = qobject_cast(drag->source())) { - dpr = sourceWindow->devicePixelRatio(); - } -#ifndef QT_NO_WIDGETS - else if (const QWidget *sourceWidget = qobject_cast(drag->source())) { - if (const QWindow *sourceWindow = sourceWidget->window()->windowHandle()) - dpr = sourceWindow->devicePixelRatio(); - } -#endif - else { - if (const QWindow *focusWindow = qApp->focusWindow()) - dpr = focusWindow->devicePixelRatio(); + QWindow *window = qobject_cast(drag->source()); + if (!window && drag->source()->metaObject()->indexOfMethod("_q_closestWindowHandle()") != -1) { + QMetaObject::invokeMethod(drag->source(), "_q_closestWindowHandle", + Q_RETURN_ARG(QWindow *, window)); } + if (!window) + window = qApp->focusWindow(); + + if (window) + dpr = window->devicePixelRatio(); + pm = QPixmap(width * dpr, height * dpr); pm.setDevicePixelRatio(dpr); QPainter p(&pm); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 19945473da..79c8aba8cf 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1112,6 +1112,17 @@ QWindow *QWidgetPrivate::windowHandle(WindowHandleMode mode) const return nullptr; } +/*! + \internal + + Used by clients outside of widgets to get a handle to the + closest QWindow without having to link to widgets. +*/ +QWindow *QWidgetPrivate::_q_closestWindowHandle() const +{ + return windowHandle(QWidgetPrivate::WindowHandleMode::Closest); +} + QScreen *QWidgetPrivate::associatedScreen() const { if (auto window = windowHandle(WindowHandleMode::Closest)) diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 9ea4301428..68a9b7ca9b 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -742,6 +742,7 @@ private: private: Q_DISABLE_COPY(QWidget) Q_PRIVATE_SLOT(d_func(), void _q_showIfNotHidden()) + Q_PRIVATE_SLOT(d_func(), QWindow *_q_closestWindowHandle()) QWidgetData *data; }; diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 3c29b48973..a3eac8d9ec 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -270,6 +270,7 @@ public: TopLevel }; QWindow *windowHandle(WindowHandleMode mode = WindowHandleMode::Direct) const; + QWindow *_q_closestWindowHandle() const; // Private slot in QWidget QScreen *associatedScreen() const;