diff options
Diffstat (limited to 'src/gui/kernel/qwindow.cpp')
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 154 |
1 files changed, 118 insertions, 36 deletions
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 871437efb1..e262f3f8a4 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -47,6 +47,7 @@ #ifndef QT_NO_ACCESSIBILITY # include "qaccessible.h" #endif +#include "qhighdpiscaling_p.h" #include <private/qevent_p.h> @@ -388,25 +389,31 @@ void QWindowPrivate::setTopLevelScreen(QScreen *newScreen, bool recreate) void QWindowPrivate::create(bool recursive) { Q_Q(QWindow); + if (platformWindow) + return; + + platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q); + Q_ASSERT(platformWindow); + if (!platformWindow) { - platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q); - QObjectList childObjects = q->children(); - for (int i = 0; i < childObjects.size(); i ++) { - QObject *object = childObjects.at(i); - if (object->isWindowType()) { - QWindow *window = static_cast<QWindow *>(object); - if (recursive) - window->d_func()->create(true); - if (window->d_func()->platformWindow) - window->d_func()->platformWindow->setParent(platformWindow); - } - } + qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags(); + return; + } - if (platformWindow) { - QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); - QGuiApplication::sendEvent(q, &e); + QObjectList childObjects = q->children(); + for (int i = 0; i < childObjects.size(); i ++) { + QObject *object = childObjects.at(i); + if (object->isWindowType()) { + QWindow *window = static_cast<QWindow *>(object); + if (recursive) + window->d_func()->create(true); + if (window->d_func()->platformWindow) + window->d_func()->platformWindow->setParent(platformWindow); } } + + QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated); + QGuiApplication::sendEvent(q, &e); } void QWindowPrivate::clearFocusObject() @@ -587,8 +594,7 @@ QWindow *QWindow::parent() const Setting \a parent to be 0 will make the window become a top level window. If \a parent is a window created by fromWinId(), then the current window - will be embedded inside \a parent, if the platform supports it. Window - embedding is currently supported only by the X11 platform plugin. + will be embedded inside \a parent, if the platform supports it. */ void QWindow::setParent(QWindow *parent) { @@ -1085,13 +1091,13 @@ qreal QWindow::devicePixelRatio() const { Q_D(const QWindow); - // If there is no platform window, do the second best thing and - // return the app global devicePixelRatio. This is the highest - // devicePixelRatio found on the system screens, and will be - // correct for single-display systems (a very common case). + // If there is no platform window use the app global devicePixelRatio, + // which is the the highest devicePixelRatio found on the system + // screens, and will be correct for single-display systems (a very common case). if (!d->platformWindow) return qApp->devicePixelRatio(); - return d->platformWindow->devicePixelRatio(); + + return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this); } /*! @@ -1437,7 +1443,13 @@ void QWindow::setGeometry(const QRect &rect) d->positionPolicy = QWindowPrivate::WindowFrameExclusive; if (d->platformWindow) { - d->platformWindow->setGeometry(rect); + QRect nativeRect; + QScreen *newScreen = d->screenForGeometry(rect); + if (newScreen && isTopLevel()) + nativeRect = QHighDpi::toNativePixels(rect, newScreen); + else + nativeRect = QHighDpi::toNativePixels(rect, this); + d->platformWindow->setGeometry(nativeRect); } else { d->geometry = rect; @@ -1452,6 +1464,30 @@ void QWindow::setGeometry(const QRect &rect) } } +/* + This is equivalent to QPlatformWindow::screenForGeometry, but in platform + independent coordinates. The duplication is unfortunate, but there is a + chicken and egg problem here: we cannot convert to native coordinates + before we know which screen we are on. +*/ +QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) +{ + Q_Q(QWindow); + QScreen *currentScreen = q->screen(); + QScreen *fallback = currentScreen; + QPoint center = newGeometry.center(); + if (!q->parent() && currentScreen && !currentScreen->geometry().contains(center)) { + Q_FOREACH (QScreen* screen, currentScreen->virtualSiblings()) { + if (screen->geometry().contains(center)) + return screen; + if (screen->geometry().intersects(newGeometry)) + fallback = screen; + } + } + return fallback; +} + + /*! Returns the geometry of the window, excluding its window frame. @@ -1461,7 +1497,7 @@ QRect QWindow::geometry() const { Q_D(const QWindow); if (d->platformWindow) - return d->platformWindow->geometry(); + return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this); return d->geometry; } @@ -1474,7 +1510,7 @@ QMargins QWindow::frameMargins() const { Q_D(const QWindow); if (d->platformWindow) - return d->platformWindow->frameMargins(); + return QHighDpi::fromNativePixels(d->platformWindow->frameMargins(), this); return QMargins(); } @@ -1488,7 +1524,7 @@ QRect QWindow::frameGeometry() const Q_D(const QWindow); if (d->platformWindow) { QMargins m = frameMargins(); - return d->platformWindow->geometry().adjusted(-m.left(), -m.top(), m.right(), m.bottom()); + return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this).adjusted(-m.left(), -m.top(), m.right(), m.bottom()); } return d->geometry; } @@ -1505,7 +1541,7 @@ QPoint QWindow::framePosition() const Q_D(const QWindow); if (d->platformWindow) { QMargins margins = frameMargins(); - return d->platformWindow->geometry().topLeft() - QPoint(margins.left(), margins.top()); + return QHighDpi::fromNativePixels(d->platformWindow->geometry().topLeft(), this) - QPoint(margins.left(), margins.top()); } return d->geometry.topLeft(); } @@ -1521,7 +1557,7 @@ void QWindow::setFramePosition(const QPoint &point) d->positionPolicy = QWindowPrivate::WindowFrameInclusive; d->positionAutomatic = false; if (d->platformWindow) { - d->platformWindow->setGeometry(QRect(point, size())); + d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(point, size()), this)); } else { d->geometry.moveTopLeft(point); } @@ -1581,7 +1617,7 @@ void QWindow::resize(const QSize &newSize) { Q_D(QWindow); if (d->platformWindow) { - d->platformWindow->setGeometry(QRect(position(), newSize)); + d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(position(), newSize), this)); } else { const QSize oldSize = d->geometry.size(); d->geometry.setSize(newSize); @@ -2261,10 +2297,10 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow - && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { + && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { return d->platformWindow->mapToGlobal(pos); } - return pos + d_func()->globalPosition(); + return pos + d->globalPosition(); } @@ -2281,10 +2317,10 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow - && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded(0))) { + && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { return d->platformWindow->mapFromGlobal(pos); } - return pos - d_func()->globalPosition(); + return pos - d->globalPosition(); } @@ -2346,9 +2382,16 @@ QWindow *QWindowPrivate::topLevelWindow() const Given the handle \a id to a native window, this method creates a QWindow object which can be used to represent the window when invoking methods like setParent() and setTransientParent(). - This can be used, on platforms which support it, to embed a window inside a - container or to make a window stick on top of a window created by another - process. + + This can be used, on platforms which support it, to embed a QWindow inside a + native window, or to embed a native window inside a QWindow. + + If foreign windows are not supported, this function returns 0. + + \note The resulting QWindow should not be used to manipulate the underlying + native window (besides re-parenting), or to observe state changes of the + native window. Any support for these kind of operations is incidental, highly + platform dependent and untested. \sa setParent() \sa setTransientParent() @@ -2477,6 +2520,45 @@ void QWindowPrivate::applyCursor() } #endif // QT_NO_CURSOR +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug debug, const QWindow *window) +{ + QDebugStateSaver saver(debug); + debug.nospace(); + if (window) { + debug << window->metaObject()->className() << '(' << (const void *)window; + if (!window->objectName().isEmpty()) + debug << ", name=" << window->objectName(); + if (debug.verbosity() > 2) { + const QRect geometry = window->geometry(); + if (window->isVisible()) + debug << ", visible"; + if (window->isExposed()) + debug << ", exposed"; + debug << ", state=" << window->windowState() + << ", type=" << window->type() << ", flags=" << window->flags() + << ", surface type=" << window->surfaceType(); + if (window->isTopLevel()) + debug << ", toplevel"; + debug << ", " << geometry.width() << 'x' << geometry.height() + << forcesign << geometry.x() << geometry.y() << noforcesign; + const QMargins margins = window->frameMargins(); + if (!margins.isNull()) + debug << ", margins=" << margins; + debug << ", devicePixelRatio=" << window->devicePixelRatio(); + if (const QPlatformWindow *platformWindow = window->handle()) + debug << ", winId=0x" << hex << platformWindow->winId() << dec; + if (const QScreen *screen = window->screen()) + debug << ", on " << screen->name(); + } + debug << ')'; + } else { + debug << "QWindow(0x0)"; + } + return debug; +} +#endif // !QT_NO_DEBUG_STREAM + QT_END_NAMESPACE #include "moc_qwindow.cpp" |