*** a/qtbase/src/gui/kernel/qguiapplication.cpp --- b/qtbase/src/gui/kernel/qguiapplication.cpp *************** void QGuiApplicationPrivate::processMous *** 1883,1889 **** if (!e->synthetic()) { if (const QScreen *screen = window->screen()) if (QPlatformCursor *cursor = screen->handle()->cursor()) { ! const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, screen); const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen); QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint, button, buttons, e->modifiers, e->source); --- 1883,1890 ---- if (!e->synthetic()) { if (const QScreen *screen = window->screen()) if (QPlatformCursor *cursor = screen->handle()->cursor()) { ! // HiRes :localPoint is OS pos in client space -> should be scaled using window scale factor. ! const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, window); const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen); QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint, button, buttons, e->modifiers, e->source); *** a/qtbase/src/gui/kernel/qhighdpiscaling.cpp --- b/qtbase/src/gui/kernel/qhighdpiscaling.cpp *************** *** 42,47 **** --- 42,48 ---- #include "qscreen.h" #include "qplatformintegration.h" #include "private/qscreen_p.h" + #include #include *************** void QHighDpiScaling::setScreenFactor(QS *** 353,372 **** QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen) { ! if (!platformScreen) ! return pos; ! const qreal scaleFactor = factor(platformScreen); ! const QPoint topLeft = platformScreen->geometry().topLeft(); ! return (pos - topLeft) * scaleFactor + topLeft; } QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen) { ! if (!platformScreen) ! return pos; ! const qreal scaleFactor = factor(platformScreen); ! const QPoint topLeft = platformScreen->geometry().topLeft(); ! return (pos - topLeft) / scaleFactor + topLeft; } qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) --- 354,369 ---- QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen) { ! // HiRes Patch : glvlevch : Do not do any math here (just a code copy paste). ! // Instead rely on general formula for conversions which does not depend on screen. ! return QHighDpi::toNative(pos, 0, QPoint(0,0)); } QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen) { ! // HiRes Patch : glvlevch : Do not do any math here (just a code copy paste). ! // Instead rely on general formula for conversions which does not depend on screen. ! return QHighDpi::fromNative(pos, 0, QPoint(0,0)); } qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) *************** QDpi QHighDpiScaling::logicalDpi() *** 389,394 **** --- 386,409 ---- return m_logicalDpi; } + // HiRes Patch : glvlevch : for now we have only one global space for Qt and OS. + QDpiScreenInfo QHighDpiScaling::dpiScreenInfo(const QPoint &pos) + { + QDpiScreenInfo screenSettings; + screenSettings.first = QPoint(0,0); + screenSettings.second = 1.0; + + if (QGuiApplication::primaryScreen()) // Just for screen initialization case. + { + const QPlatformScreen *nativeScreen = QGuiApplication::primaryScreen()->handle(); + nativeScreen = nativeScreen->screenForPosition(pos); + screenSettings.second = QHighDpiScaling::factor(nativeScreen); + screenSettings.first = QHighDpiScaling::origin(nativeScreen); + } + + return screenSettings; + } + qreal QHighDpiScaling::factor(const QScreen *screen) { // Fast path for when scaling in Qt is not used at all. *************** qreal QHighDpiScaling::factor(const QWin *** 421,427 **** QPoint QHighDpiScaling::origin(const QScreen *screen) { ! return screen->geometry().topLeft(); } QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen) --- 436,446 ---- QPoint QHighDpiScaling::origin(const QScreen *screen) { ! // HiRes Patch : glvlevch : Origins of QScreen and QPlatformScreen must the same. ! // While Qt initializes QScreen geometry - it sets the same origings for QScreen as ! // for QPlatforScreen. BUT we have to point to this here anyway. ! // Note : this change is not necessy but good to have. ! return origin(screen->handle()); } QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen) *** a/qtbase/src/gui/kernel/qhighdpiscaling_p.h --- b/qtbase/src/gui/kernel/qhighdpiscaling_p.h *************** Q_DECLARE_LOGGING_CATEGORY(lcScaling); *** 68,73 **** --- 68,74 ---- class QScreen; class QPlatformScreen; typedef QPair QDpi; + typedef QPair QDpiScreenInfo; #ifndef QT_NO_HIGHDPISCALING class Q_GUI_EXPORT QHighDpiScaling { *************** public: *** 86,91 **** --- 87,95 ---- static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen); static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen); static QDpi logicalDpi(); + + // HiRes Patch : glvlevch : Helper. Qt global space is the same as OS global space. + static QDpiScreenInfo dpiScreenInfo(const QPoint &pos); private: static qreal screenSubfactor(const QPlatformScreen *screen); *************** private: *** 99,137 **** static QDpi m_logicalDpi; }; // Coordinate system conversion functions: ! // QHighDpi::fromNativePixels : from physical(screen/backing) to logical pixels ! // QHighDpi::toNativePixels : from logical to physical pixels namespace QHighDpi { inline QPointF fromNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) { ! return (pos - origin) / scaleFactor + origin; } inline QPointF toNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) { ! return (pos - origin) * scaleFactor + origin; } inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) { ! return (pos - origin) / scaleFactor + origin; } inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) { ! return (pos - origin) * scaleFactor + origin; } inline QPoint fromNative(const QPoint &pos, qreal scaleFactor) { ! return pos / scaleFactor; } inline QPoint toNative(const QPoint &pos, qreal scaleFactor) { return pos * scaleFactor; } --- 103,240 ---- static QDpi m_logicalDpi; }; + //-------------------------------------------------------------------------------------------------- // Coordinate system conversion functions: ! // ! // 1. OS native global space is a Qt global space (NO SCALING) for SCREEN ONLY ! // ! // - Do not need to convert OS global to Qt global (but we using fromNative/toNative for marking) ! // - Can do math e.g. fromNative(V+U) = fromNative(V) + fromNative(U) ! // - Can do math e.g. toNative(V+U) = toNative(V) + toNative(U) ! // - Such math support +/-consts to Qt global position and map them back to OS global. ! // - Can find OS pos for any Qt pos (and vice versa) and define exactly one screen for it. ! // - Can place TOP-LEVEL windows using Qt global pos ! // !- TOP-LEVEL window topLeft corner is a Qt/OS global position. ! // - fromNative/toNative with (QPointF, qreal, QPointF)/(QPoint, QScreen) are used. ! // ! // 2. OS native window space is SCALED Qt native window space. For Windows with parent and screens. ! // ! // - size of screen and window in Qt space is scaled OS size. ! // ! // 3. TOP-LEVEL windows and QScreen ! // ! // - The pos of window and screen offset in Qt global space is the same as OS global space. ! // - The size of window and screen in Qt global space is the scaled OS size. ! // ! // 4. NON TOP-LEVEL windows ! // ! // - The pos and size are scaled according to screen scale factor from its parent. ! // ! // 5. QWidgets wich are not represented by native OS handle leave in Qt scaled space. ! // ! ! /* ! ! >>> OS Global <-> Global QT : does NOTHING!!! ! inline QPointF fromNative (const QPointF &pos, qreal scaleFactor, const QPointF &origin) ! inline QPointF toNative (const QPointF &pos, qreal scaleFactor, const QPointF &origin) ! inline QPoint fromNative (const QPoint &pos, qreal scaleFactor, const QPoint &origin) ! inline QPoint toNative (const QPoint &pos, qreal scaleFactor, const QPoint &origin) ! inline QPoint fromNativePixels (const QPoint &pixelPoint, const QScreen *screen) ! inline QPoint toNativePixels (const QPoint &pointPoint, const QScreen *screen) ! inline QPointF fromNativePixels (const QPointF &pixelPoint, const QScreen *screen) ! inline QPointF toNativePixels (const QPointF &pointPoint, const QScreen *screen) ! ! >>> Window/Screen OS <-> Window/Screen QT : f(v) = v/k f(v) = v*k ! inline QPoint fromNative (const QPoint &pos, qreal scaleFactor) ! inline QPoint toNative (const QPoint &pos, qreal scaleFactor) ! inline QSize fromNative (const QSize &size, qreal scaleFactor) ! inline QSize toNative (const QSize &size, qreal scaleFactor) ! inline QSizeF fromNative (const QSizeF &size, qreal scaleFactor) ! inline QSizeF toNative (const QSizeF &size, qreal scaleFactor) ! T fromNativePixels(const T &pixelValue, const QWindow *window) ! T fromNativePixels(const T &pixelValue, const QScreen *screen) ! T toNativePixels (const T &pointValue, const QWindow *window) ! T toNativePixels (const T &pointValue, const QScreen *screen) ! QVector fromNativePixels(const QVector &pixelValues, const QWindow *window) ! QVector toNativePixels (const QVector &pointValues, const QWindow *window) ! ! >>> OS Global <-> Global QT : TopLeft==TopLeft Size=Size*k Size=Size/k ! inline QRect fromNative (const QRect &rect, qreal scaleFactor, const QPoint &origin) ! inline QRect toNative (const QRect &rect, qreal scaleFactor, const QPoint &origin) ! inline QRect fromNative (const QRect &rect, const QScreen *screen, const QPoint &screenOrigin) ! inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen) ! inline QRect fromNativePixels (const QRect &pixelRect, const QPlatformScreen *platformScreen) ! inline QRect toNativePixels (const QRect &pointRect, const QPlatformScreen *platformScreen) ! inline QRect fromNativePixels (const QRect &pixelRect, const QScreen *screen) ! inline QRect toNativePixels (const QRect &pointRect, const QScreen *screen) ! inline QRectF toNativePixels (const QRectF &pointRect, const QScreen *screen) ! inline QRectF fromNativePixels (const QRectF &pixelRect, const QScreen *screen) ! ! >>> OS Window <-> Window QT : f(v) = v/k f(v) = v*k ! inline QPoint fromNativeLocalPosition (const QPoint &pos, const QWindow *window) ! inline QPoint toNativeLocalPosition (const QPoint &pos, const QWindow *window) ! inline QPointF fromNativeLocalPosition (const QPointF &pos, const QWindow *window) ! inline QPointF toNativeLocalPosition (const QPointF &pos, const QWindow *window) ! inline QSize fromNativePixels (const QSize &pixelSize, const QWindow *window) ! inline QSize toNativePixels (const QSize &pointSize, const QWindow *window) ! inline QSizeF fromNativePixels (const QSizeF &pixelSize, const QWindow *window) ! inline QSizeF toNativePixels (const QSizeF &pointSize, const QWindow *window) ! inline QMargins fromNativePixels (const QMargins &pixelMargins, const QWindow *window) ! inline QMargins toNativePixels (const QMargins &pointMargins, const QWindow *window) ! inline QRegion fromNativeLocalRegion (const QRegion &pixelRegion, const QWindow *window) ! inline QRegion fromNativeLocalExposedRegion (const QRegion &pixelRegion, const QWindow *window) ! inline QRegion toNativeLocalRegion (const QRegion &pointRegion, const QWindow *window) ! ! >>> TOP LEVEL WINDOW -> TopLeft==TopLeft Size=Size*k Size=Size/k ! >>> WINDOW in WINDOW -> f(v) = v/k f(v) = v*k ! inline QRect fromNativePixels (const QRect &pixelRect, const QWindow *window) ! inline QRect toNativePixels (const QRect &pointRect, const QWindow *window) ! inline QRectF fromNativePixels (const QRectF &pixelRect, const QWindow *window) ! inline QRectF toNativePixels (const QRectF &pointRect, const QWindow *window) ! inline QPoint fromNativePixels (const QPoint &pixelPoint, const QWindow *window) ! inline QPoint toNativePixels (const QPoint &pointPoint, const QWindow *window) ! inline QPointF fromNativePixels (const QPointF &pixelPoint, const QWindow *window) ! inline QPointF toNativePixels (const QPointF &pointPoint, const QWindow *window) ! ! */ ! //-------------------------------------------------------------------------------------------------- namespace QHighDpi { inline QPointF fromNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) { ! // HiRes Patch : glvlevch : Make Qt global space be the same as OS one. ! return pos; } inline QPointF toNative(const QPointF &pos, qreal scaleFactor, const QPointF &origin) { ! // HiRes Patch : glvlevch : Make Qt global space be the same as OS one. ! return pos; } inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) { ! // HiRes Patch : glvlevch : Make Qt global space be the same as OS one. ! return pos; } inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) { ! // HiRes Patch : glvlevch : Make Qt global space be the same as OS one. ! return pos; } inline QPoint fromNative(const QPoint &pos, qreal scaleFactor) { ! // HiRes Patch : glvlevch : For windows only. ! return pos / scaleFactor; } inline QPoint toNative(const QPoint &pos, qreal scaleFactor) { + // HiRes Patch : glvlevch : For windows only. return pos * scaleFactor; } *************** inline QRegion fromNativeLocalRegion(con *** 384,391 **** QRegion pointRegion; const auto rects = pixelRegion.rects(); for (const QRect &rect : rects) { ! pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor), ! fromNative(rect.size(), scaleFactor)); } return pointRegion; } --- 487,494 ---- QRegion pointRegion; const auto rects = pixelRegion.rects(); for (const QRect &rect : rects) { ! pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor), ! fromNative(rect.size(), scaleFactor)); } return pointRegion; } *************** inline QRegion toNativeLocalRegion(const *** 417,424 **** QRegion pixelRegon; const auto rects = pointRegion.rects(); for (const QRect &rect : rects) { ! pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor), ! toNative(rect.size(), scaleFactor)); } return pixelRegon; } --- 520,527 ---- QRegion pixelRegon; const auto rects = pointRegion.rects(); for (const QRect &rect : rects) { ! pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor), ! toNative(rect.size(), scaleFactor)); } return pixelRegon; } *** a/qtbase/src/gui/kernel/qplatformscreen.cpp --- b/qtbase/src/gui/kernel/qplatformscreen.cpp *************** QWindow *QPlatformScreen::topLevelAt(con *** 108,123 **** Returns this screen if no suitable screen is found at the position. */ const QPlatformScreen *QPlatformScreen::screenForPosition(const QPoint &point) const { if (!geometry().contains(point)) { const auto screens = virtualSiblings(); for (const QPlatformScreen *screen : screens) { if (screen->geometry().contains(point)) return screen; } } ! return this; } --- 108,188 ---- Returns this screen if no suitable screen is found at the position. */ + static int sLocation(int a, int b, int p) + { + if (a < b) + return (p < b ? a : b); + + return (p < a ? b : a); + } + const QPlatformScreen *QPlatformScreen::screenForPosition(const QPoint &point) const { + const QPlatformScreen* retScreen = this; + if (!geometry().contains(point)) { const auto screens = virtualSiblings(); for (const QPlatformScreen *screen : screens) { if (screen->geometry().contains(point)) return screen; } + + // Go through all screens to define one which holds input point. + for (const QPlatformScreen *screen : screens) + { + // Do not need to define screen for the last one. + if (retScreen == screen) + continue; + + // HiRes : quite complicated. + // We have to define DIRECTLY ONE screen for each point from OS global space. + + // The starting point to defiene screen is its topLeft point. + // + // 1. There is ONE screen - whole XoY space belong to it. + // 2. TWO SCREENS + // - INIT: point belong to screen from previous iteration or from initialization. + // - TODO: all we need is to define - does point belong to the other screen? + // - if no - continu + // - else took the other screen for next iteration. + // + // + // + // Screen A AREA + // + // **********************-------------------------------------------------------- + // * * + // * * Screen A AREA + // * * + // Screen A AREA * Screen A * + // * ***************************------------------------------ + // * * * + // * * * Screen B AREA + // ********************** * + // | * * + // | Screen A AREA * Screen B * + // | * * + // | * * + // | * * + // | *************************** + // | | + // | | + // | | Screen B AREA + // | | + + QPoint posCur = retScreen->geometry().topLeft(); + QPoint posPot = screen->geometry().topLeft(); + + if ((posCur.x() != posPot.x() && sLocation(posCur.x(), posPot.x(), point.x()) == posPot.x()) || + (posCur.y() != posPot.y() && sLocation(posCur.y(), posPot.y(), point.y()) == posPot.y()) ) + { + retScreen = screen; + } + + } } ! ! return retScreen; } *************** void QPlatformScreen::resizeMaximizedWin *** 336,343 **** const QRect oldGeometry = screen()->geometry(); const QRect oldAvailableGeometry = screen()->availableGeometry(); const QRect newGeometry = deviceIndependentGeometry(); ! const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft()); ! // make sure maximized and fullscreen windows are updated for (int i = 0; i < windows.size(); ++i) { QWindow *w = windows.at(i); --- 401,408 ---- const QRect oldGeometry = screen()->geometry(); const QRect oldAvailableGeometry = screen()->availableGeometry(); const QRect newGeometry = deviceIndependentGeometry(); ! const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft()); ! // make sure maximized and fullscreen windows are updated for (int i = 0; i < windows.size(); ++i) { QWindow *w = windows.at(i); *************** QRect QPlatformScreen::mapBetween(Qt::Sc *** 440,448 **** QRect QPlatformScreen::deviceIndependentGeometry() const { - qreal scaleFactor = QHighDpiScaling::factor(this); QRect nativeGeometry = geometry(); ! return QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor)); } /*! --- 505,514 ---- QRect QPlatformScreen::deviceIndependentGeometry() const { QRect nativeGeometry = geometry(); ! // HiRes : just the same but using functin form QHighDpi ! // Left topLeft as it was and scale size. ! return QHighDpi::fromNativePixels(nativeGeometry, this); } /*! *** a/qtbase/src/gui/kernel/qplatformwindow.cpp --- b/qtbase/src/gui/kernel/qplatformwindow.cpp *************** QString QPlatformWindow::formatWindowTit *** 486,510 **** \since 5.4 \sa QWindowSystemInterface::handleWindowScreenChanged() */ ! QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const { ! QPlatformScreen *currentScreen = screen(); ! QPlatformScreen *fallback = currentScreen; // QRect::center can return a value outside the rectangle if it's empty. // Apply mapToGlobal() in case it is a foreign/embedded window. QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center(); if (window()->type() == Qt::ForeignWindow) center = mapToGlobal(center - newGeometry.topLeft()); ! if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) { ! const auto screens = currentScreen->virtualSiblings(); ! for (QPlatformScreen *screen : screens) { ! const QRect screenGeometry = screen->geometry(); ! if (screenGeometry.contains(center)) ! return screen; ! if (screenGeometry.intersects(newGeometry)) ! fallback = screen; ! } } return fallback; } --- 486,504 ---- \since 5.4 \sa QWindowSystemInterface::handleWindowScreenChanged() */ ! const QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const { ! const QPlatformScreen *currentScreen = screen(); ! const QPlatformScreen *fallback = currentScreen; // QRect::center can return a value outside the rectangle if it's empty. // Apply mapToGlobal() in case it is a foreign/embedded window. QPoint center = newGeometry.isEmpty() ? newGeometry.topLeft() : newGeometry.center(); if (window()->type() == Qt::ForeignWindow) center = mapToGlobal(center - newGeometry.topLeft()); ! // HiRes : do not do any math here - use QPlatforScreen::screenForPosition instead. ! if (!parent() && currentScreen) { ! fallback = currentScreen->screenForPosition(center); } return fallback; } *************** QRect QPlatformWindow::initialGeometry(c *** 596,602 **** const QScreen *screen = effectiveScreen(w); if (!screen) return initialGeometry; ! QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); if (rect.width() == 0) { const int minWidth = w->minimumWidth(); rect.setWidth(minWidth > 0 ? minWidth : defaultWidth); --- 590,600 ---- const QScreen *screen = effectiveScreen(w); if (!screen) return initialGeometry; ! // HiRes : initial geometry of toplevel window (this is one) holds ! // topLeft corner in OS global space to be able to define destination screen for it. ! // After screen was defined we can scale initial size according to screen scale. ! // that is why we have to use translation with screen instead of window. ! QRect rect(QHighDpi::fromNativePixels(initialGeometry, screen)); if (rect.width() == 0) { const int minWidth = w->minimumWidth(); rect.setWidth(minWidth > 0 ? minWidth : defaultWidth); *** a/qtbase/src/gui/kernel/qplatformwindow.h --- b/qtbase/src/gui/kernel/qplatformwindow.h *************** public: *** 150,156 **** protected: static QString formatWindowTitle(const QString &title, const QString &separator); ! QPlatformScreen *screenForGeometry(const QRect &newGeometry) const; static QSize constrainWindowSize(const QSize &size); QScopedPointer d_ptr; --- 150,156 ---- protected: static QString formatWindowTitle(const QString &title, const QString &separator); ! const QPlatformScreen *screenForGeometry(const QRect &newGeometry) const; static QSize constrainWindowSize(const QSize &size); QScopedPointer d_ptr; *** a/qtbase/src/gui/kernel/qscreen.cpp --- b/qtbase/src/gui/kernel/qscreen.cpp *************** QList QScreen::virtualSibling *** 374,379 **** --- 374,392 ---- } /*! + Find the sibling screen corresponding to \a globalPos. + + Returns this screen if no suitable screen is found at the position. + */ + const QScreen *QScreen::screenForPosition(const QPoint &point) const + { + QPoint nativePoint = QHighDpi::toNative(point, 0.0, QPoint(0,0)); + const QPlatformScreen* nativeScreen = handle(); + nativeScreen = nativeScreen->screenForPosition(nativePoint); + return nativeScreen->screen(); + } + + /*! \property QScreen::virtualSize \brief the pixel size of the virtual desktop to which this screen belongs *** a/qtbase/src/gui/kernel/qscreen.h --- b/qtbase/src/gui/kernel/qscreen.h *************** public: *** 117,122 **** --- 117,123 ---- QRect availableGeometry() const; QList virtualSiblings() const; + const QScreen *screenForPosition(const QPoint &point) const; QSize virtualSize() const; QRect virtualGeometry() const; *** a/qtbase/src/gui/kernel/qscreen_p.h --- b/qtbase/src/gui/kernel/qscreen_p.h *************** public: *** 73,79 **** void updateHighDpi() { geometry = platformScreen->deviceIndependentGeometry(); ! availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft()); } void updatePrimaryOrientation(); --- 73,81 ---- void updateHighDpi() { geometry = platformScreen->deviceIndependentGeometry(); ! // HiRes : never map screen origin - it must be in OS global space. ! // Screen width and height should be scale if need. ! availableGeometry = QHighDpi::fromNativePixels(platformScreen->availableGeometry(), platformScreen); } void updatePrimaryOrientation(); *** a/qtbase/src/gui/kernel/qsimpledrag.cpp --- b/qtbase/src/gui/kernel/qsimpledrag.cpp *************** void QBasicDrag::disableEventFilter() *** 117,123 **** static inline QPoint getNativeMousePos(QEvent *e, QObject *o) { ! return QHighDpi::toNativePixels(static_cast(e)->globalPos(), qobject_cast(o)); } bool QBasicDrag::eventFilter(QObject *o, QEvent *e) --- 117,124 ---- static inline QPoint getNativeMousePos(QEvent *e, QObject *o) { ! // HiRes : we use OS global for Qt global - nothing to convert ( QHighDpi::toNative(QPoint global,qreal,QPoint) returns global ) ! return QHighDpi::toNative(static_cast(e)->globalPos(), 0.0, QPoint(0,0)); } bool QBasicDrag::eventFilter(QObject *o, QEvent *e) *** a/qtbase/src/gui/kernel/qwindow.cpp --- b/qtbase/src/gui/kernel/qwindow.cpp *************** void QWindow::setGeometry(const QRect &r *** 1475,1487 **** d->positionPolicy = QWindowPrivate::WindowFrameExclusive; if (d->platformWindow) { ! 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; --- 1475,1483 ---- d->positionPolicy = QWindowPrivate::WindowFrameExclusive; if (d->platformWindow) { ! // HiRes : do not define destination screen for QWindow here. ! // This will be done in QWindowsBaseWindow right before MoveWindow API call. ! d->platformWindow->setGeometry(QHighDpi::toNativePixels(rect, this)); } else { d->geometry = rect; *************** void QWindow::setGeometry(const QRect &r *** 1502,1508 **** 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(); --- 1498,1504 ---- chicken and egg problem here: we cannot convert to native coordinates before we know which screen we are on. */ ! const QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) { Q_Q(QWindow); QScreen *currentScreen = q->screen(); *************** QPoint QWindow::mapToGlobal(const QPoint *** 2344,2353 **** { Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow ! && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { ! return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } return pos + d->globalPosition(); } --- 2340,2353 ---- { Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. + // HiRes : IF QHighDpiScaling::isActive() then all math around platformWindow geometry goes through QHighDpi + // thus we have to relay on QHighDpi here as well. BUT for platformWindow ONLY!!! if (d->platformWindow ! && (QHighDpiScaling::isActive() || type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { ! return QHighDpi::fromNative( d->platformWindow->mapToGlobal( QHighDpi::toNativeLocalPosition(pos, this) ), 0.0, QPoint(0,0) ); } + // HiRes : For non OS represented windows we use just a regular mapping. + // QHighDpi mapping will be done for its parent with platformWindow return pos + d->globalPosition(); } *************** QPoint QWindow::mapFromGlobal(const QPoi *** 2364,2373 **** { Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. if (d->platformWindow ! && (type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { ! return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } return pos - d->globalPosition(); } --- 2364,2377 ---- { Q_D(const QWindow); // QTBUG-43252, prefer platform implementation for foreign windows. + // HiRes : IF QHighDpiScaling::isActive() then all math around platformWindow geometry goes through QHighDpi + // thus we have to relay on QHighDpi here as well. BUT for platformWindow ONLY!!! if (d->platformWindow ! && (QHighDpiScaling::isActive() || type() == Qt::ForeignWindow || d->platformWindow->isEmbedded())) { ! return QHighDpi::fromNativeLocalPosition( d->platformWindow->mapFromGlobal( QHighDpi::toNative(pos, 0.0, QPoint(0,0)) ), this ); } + // HiRes : For non OS represented windows we use just a regular mapping. + // QHighDpi mapping will be done for its parent with platformWindow return pos - d->globalPosition(); } *** a/qtbase/src/gui/kernel/qwindow_p.h --- b/qtbase/src/gui/kernel/qwindow_p.h *************** public: *** 143,149 **** void connectToScreen(QScreen *topLevelScreen); void disconnectFromScreen(); void emitScreenChangedRecursion(QScreen *newScreen); ! QScreen *screenForGeometry(const QRect &rect); virtual void clearFocusObject(); virtual QRectF closestAcceptableGeometry(const QRectF &rect) const; --- 143,149 ---- void connectToScreen(QScreen *topLevelScreen); void disconnectFromScreen(); void emitScreenChangedRecursion(QScreen *newScreen); ! const QScreen *screenForGeometry(const QRect &rect); virtual void clearFocusObject(); virtual QRectF closestAcceptableGeometry(const QRectF &rect) const; *** a/qtbase/src/gui/kernel/qwindowsysteminterface.cpp --- b/qtbase/src/gui/kernel/qwindowsysteminterface.cpp *************** void QWindowSystemInterface::handleMouse *** 177,184 **** void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { QWindowSystemInterfacePrivate::MouseEvent * e = ! new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } --- 177,185 ---- void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { + // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) QWindowSystemInterfacePrivate::MouseEvent * e = ! new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNative(global, 0.0, QPoint(0,0)), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } *************** void QWindowSystemInterface::handleFrame *** 192,201 **** void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { QWindowSystemInterfacePrivate::MouseEvent * e = new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QWindowSystemInterfacePrivate::FrameStrutMouse, ! QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } --- 193,203 ---- void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods, Qt::MouseEventSource source) { + // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) QWindowSystemInterfacePrivate::MouseEvent * e = new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QWindowSystemInterfacePrivate::FrameStrutMouse, ! QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNative(global, 0.0, QPoint(0,0)), b, mods, source); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } *************** void QWindowSystemInterface::handleWheel *** 335,341 **** // Simple case: vertical deltas only: if (angleDelta.y() != 0 && angleDelta.x() == 0) { ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; --- 337,344 ---- // Simple case: vertical deltas only: if (angleDelta.y() != 0 && angleDelta.x() == 0) { ! // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNative(global, 0.0, QPoint(0,0)), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; *************** void QWindowSystemInterface::handleWheel *** 343,349 **** // Simple case: horizontal deltas only: if (angleDelta.y() == 0 && angleDelta.x() != 0) { ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; } --- 346,353 ---- // Simple case: horizontal deltas only: if (angleDelta.y() == 0 && angleDelta.x() != 0) { ! // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNative(global, 0.0, QPoint(0,0)), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); return; } *************** void QWindowSystemInterface::handleWheel *** 351,362 **** // Both horizontal and vertical deltas: Send two wheel events. // The first event contains the Qt 5 pixel and angle delta as points, // and in addition the Qt 4 compatibility vertical angle delta. ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); // The second event contains null pixel and angle points and the // Qt 4 compatibility horizontal angle delta. ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } --- 355,368 ---- // Both horizontal and vertical deltas: Send two wheel events. // The first event contains the Qt 5 pixel and angle delta as points, // and in addition the Qt 4 compatibility vertical angle delta. ! // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNative(global, 0.0, QPoint(0,0)), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); // The second event contains null pixel and angle points and the // Qt 4 compatibility horizontal angle delta. ! // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) ! e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNative(global, 0.0, QPoint(0,0)), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source, invertedScrolling); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); } *************** QList *** 474,480 **** p.setState(point->state); const QPointF screenPos = point->area.center(); ! p.setScreenPos(QHighDpi::fromNativePixels(screenPos, window)); p.setScreenRect(QHighDpi::fromNativePixels(point->area, window)); // The local pos and rect are not set, they will be calculated --- 480,487 ---- p.setState(point->state); const QPointF screenPos = point->area.center(); ! // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) ! p.setScreenPos(QHighDpi::fromNative(screenPos, 0.0, QPoint(0,0))); p.setScreenRect(QHighDpi::fromNativePixels(point->area, window)); // The local pos and rect are not set, they will be calculated *************** void QWindowSystemInterface::handleTable *** 731,738 **** { QWindowSystemInterfacePrivate::TabletEvent *e = new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp, ! QHighDpi::fromNativeLocalPosition(local, w), ! QHighDpi::fromNativePixels(global, w), device, pointerType, buttons, pressure, xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); --- 738,745 ---- { QWindowSystemInterfacePrivate::TabletEvent *e = new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp, ! QHighDpi::fromNativeLocalPosition(local, w), ! QHighDpi::fromNative(global, 0.0, QPoint(0,0)), // HiRes : OS global are the same as Qt global -> does nothing (QHighDpi::fromNative(global, 0.0, QPoint(0,0)) returns global) device, pointerType, buttons, pressure, xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers); QWindowSystemInterfacePrivate::handleWindowSystemEvent(e); *************** Q_GUI_EXPORT void qt_handleMouseEvent(QW *** 868,874 **** QWindowSystemInterface::setSynchronousWindowSystemEvents(true); const qreal factor = QHighDpiScaling::factor(w); QWindowSystemInterface::handleMouseEvent(w, timestamp, local * factor, ! global * factor, b, mods); QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } --- 875,881 ---- QWindowSystemInterface::setSynchronousWindowSystemEvents(true); const qreal factor = QHighDpiScaling::factor(w); QWindowSystemInterface::handleMouseEvent(w, timestamp, local * factor, ! global, b, mods); // HiRes : OS global are the same as Qt global QWindowSystemInterface::setSynchronousWindowSystemEvents(wasSynchronous); } *** a/qtbase/src/plugins/platforms/windows/qwindowsintegration.cpp --- b/qtbase/src/plugins/platforms/windows/qwindowsintegration.cpp *************** QPlatformWindow *QWindowsIntegration::cr *** 305,310 **** --- 305,319 ---- { if (window->type() == Qt::Desktop) { QWindowsDesktopWindow *result = new QWindowsDesktopWindow(window); + + // HiRes : The initialization case. + const QRect obtainedGeometry = result->geometry(); + QScreen *screen = Q_NULLPTR; + if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry)) + screen = pScreen->screen(); + if (screen && screen != window->screen()) + window->setScreen(screen); + qCDebug(lcQpaWindows) << "Desktop window:" << window << showbase << hex << result->winId() << noshowbase << dec << result->geometry(); return result; *************** QPlatformWindow *QWindowsIntegration::cr *** 356,362 **** && requested.geometry != obtained.geometry) { QWindowSystemInterface::handleGeometryChange(window, obtained.geometry); } ! QPlatformScreen *screen = result->screenForGeometry(obtained.geometry); if (screen && result->screen() != screen) QWindowSystemInterface::handleWindowScreenChanged(window, screen->screen()); } --- 365,371 ---- && requested.geometry != obtained.geometry) { QWindowSystemInterface::handleGeometryChange(window, obtained.geometry); } ! const QPlatformScreen *screen = result->screenForGeometry(obtained.geometry); if (screen && result->screen() != screen) QWindowSystemInterface::handleWindowScreenChanged(window, screen->screen()); } *** a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp --- b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp *************** void QWindowsWindow::handleGeometryChang *** 1593,1603 **** && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) { fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); } ! if (previousGeometry.topLeft() != m_data.geometry.topLeft()) { ! QPlatformScreen *newScreen = screenForGeometry(m_data.geometry); ! if (newScreen != screen()) ! QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); ! } if (testFlag(SynchronousGeometryChangeEvent)) QWindowSystemInterface::flushWindowSystemEvents(); --- 1593,1604 ---- && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) { fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true); } ! ! // HiRes : There is no possibility here to define that screen for window was changed. ! // There is only one place which could defined screen changed - QWindowsBaseWindow::setGeometry_sys function. ! // It calls API MoveWindow function and has knowladge about previous and destination geometry. ! // This is needed to define previous and destination screen before and after geometry change. ! if (testFlag(SynchronousGeometryChangeEvent)) QWindowSystemInterface::flushWindowSystemEvents(); *************** void QWindowsWindow::handleGeometryChang *** 1607,1613 **** void QWindowsBaseWindow::setGeometry_sys(const QRect &rect) const { const QMargins margins = frameMargins(); ! const QRect frameGeometry = rect + margins; qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window() << "\n from " << geometry_sys() << " frame: " --- 1608,1614 ---- void QWindowsBaseWindow::setGeometry_sys(const QRect &rect) const { const QMargins margins = frameMargins(); ! QRect frameGeometry = rect + margins; // HiRes : coudl be changed if screen will be changed. qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << window() << "\n from " << geometry_sys() << " frame: " *************** void QWindowsBaseWindow::setGeometry_sys *** 1631,1638 **** --- 1632,1674 ---- } else #endif // !Q_OS_WINCE { + //---------------------------------------------------------------------------------------- + // HiRes : this is the place where we can define destination screen for new geometry and + // should we update destination geometry if we will change screen. + bool changeScreen = false; + // The new frame geometry defined, let's define destination screen for it: + const QPlatformScreen *newScreen = isTopLevel() ? screenForGeometry(frameGeometry) : NULL; + if (isTopLevel() && newScreen != screen()) + { + // Now define scaled window geometry for new screen: + QRect rectInNewScreen = QHighDpi::toNativePixels( QHighDpi::fromNativePixels( frameGeometry, screen() ), newScreen ); + + // If window screen will be changed then new screen scale factor will be applied to window geometry. + // In this case, the destination screen of window can be changed again! + // Thus, we have defien destination screen for new geomrty as well: + const QPlatformScreen *newRectScreen = screenForGeometry(rectInNewScreen); + + // So, if destination screen for new geometry is the same destination screen for window geometry scaled + // after sceen change - then we really have to change screen for window! + if ( newRectScreen == newScreen ) + { + changeScreen = true; + // In addtion we have to set window geometry in new screen to place it correctly. + frameGeometry = rectInNewScreen; + } + } + //---------------------------------------------------------------------------------------- + result = MoveWindow(hwnd, frameGeometry.x(), frameGeometry.y(), frameGeometry.width(), frameGeometry.height(), true); + + //---------------------------------------------------------------------------------------- + // Code from QWindowsWindow::handleGeometryChange() function : handle window screen change. + if (isTopLevel() && changeScreen) { + QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); + } + //---------------------------------------------------------------------------------------- + } qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << window() << "\n resulting " << result << geometry_sys(); *************** bool QWindowsWindow::handleNonClientHitT *** 2240,2246 **** if (!fixedWidth && !fixedHeight) return false; const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w)); ! const QSize size = w->size(); if (fixedHeight) { if (localPos.y() >= size.height()) { *result = HTBORDER; // Unspecified border, no resize cursor. --- 2276,2282 ---- if (!fixedWidth && !fixedHeight) return false; const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w)); ! const QSize size = w->size(); if (fixedHeight) { if (localPos.y() >= size.height()) { *result = HTBORDER; // Unspecified border, no resize cursor. *** a/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp --- b/qtbase/src/plugins/platforms/xcb/qxcbwindow.cpp *************** void QXcbWindow::setGeometry(const QRect *** 634,641 **** propagateSizeHints(); ! QXcbScreen *currentScreen = xcbScreen(); ! QXcbScreen *newScreen = parent() ? parentScreen() : static_cast(screenForGeometry(rect)); if (!newScreen) newScreen = xcbScreen(); --- 634,641 ---- propagateSizeHints(); ! const QXcbScreen *currentScreen = xcbScreen(); ! const QXcbScreen *newScreen = parent() ? parentScreen() : static_cast(screenForGeometry(rect)); if (!newScreen) newScreen = xcbScreen(); *************** void QXcbWindow::handleConfigureNotifyEv *** 2079,2085 **** } const QRect actualGeometry = QRect(pos, QSize(event->width, event->height)); ! QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(actualGeometry); if (!newScreen) return; --- 2079,2085 ---- } const QRect actualGeometry = QRect(pos, QSize(event->width, event->height)); ! const QPlatformScreen *newScreen = parent() ? parent()->screen() : screenForGeometry(actualGeometry); if (!newScreen) return; *** a/qtbase/src/widgets/kernel/qdesktopwidget.cpp --- b/qtbase/src/widgets/kernel/qdesktopwidget.cpp *************** *** 43,48 **** --- 43,49 ---- #include "qscreen.h" #include "qwidget_p.h" #include "qwindow.h" + #include QT_BEGIN_NAMESPACE *************** int QDesktopWidget::screenNumber(const Q *** 250,256 **** const QList primaryScreens = screens.first()->virtualSiblings(); // Find the screen index on the primary virtual desktop first foreach (QScreen *screen, primaryScreens) { ! if (screen->geometry().contains(p)) return screens.indexOf(screen); } // If the screen index is not found on primary virtual desktop, find --- 251,257 ---- const QList primaryScreens = screens.first()->virtualSiblings(); // Find the screen index on the primary virtual desktop first foreach (QScreen *screen, primaryScreens) { ! if (QHighDpi::toNativePixels(screen->geometry(), screen).contains(p)) // p is in global space, map screen rect to global space as well return screens.indexOf(screen); } // If the screen index is not found on primary virtual desktop, find *************** int QDesktopWidget::screenNumber(const Q *** 259,268 **** // only when there is more than one virtual desktop. if (screens.count() != primaryScreens.count()) { for (int i = 1; i < screens.size(); ++i) { ! if (screens[i]->geometry().contains(p)) return i; } } } return primaryScreen(); //even better would be closest screen } --- 260,280 ---- // only when there is more than one virtual desktop. if (screens.count() != primaryScreens.count()) { for (int i = 1; i < screens.size(); ++i) { ! if (QHighDpi::toNativePixels(screens[i]->geometry(), screens[i]).contains(p)) // p is in global space, map screen rect to global space as well return i; } } + + // HiRes : Screen definition by pos must be done by QScreen::screenForPosition() function only! + // Note: the real definition of screen by pos done in QPlatformScreen::screenForPosition() which + // is used by QScreen::screenForPosition(). + const QScreen* pDestScreen = QGuiApplication::primaryScreen(); + pDestScreen = pDestScreen->screenForPosition(p); + foreach(QScreen *screen, screens) + { + if (pDestScreen->geometry() == screen->geometry()) + return screens.indexOf(screen); + } } return primaryScreen(); //even better would be closest screen } *** a/qtbase/src/widgets/kernel/qtooltip.cpp --- b/qtbase/src/widgets/kernel/qtooltip.cpp *************** *** 54,59 **** --- 54,60 ---- #include #include #include + #include #ifndef QT_NO_TOOLTIP #ifdef Q_DEAD_CODE_FROM_QT4_MAC *************** void QTipLabel::placeTip(const QPoint &p *** 401,406 **** --- 402,414 ---- #endif QPoint p = pos; + + // HiRes : we have to do all math in scaled to selected screen local space. + // and then map them into global space for moving tooltip window + QDpiScreenInfo screenInfo = QHighDpiScaling::dpiScreenInfo(p); + screen.translate( -screenInfo.first ); // scaled to screen with {0,0} origin + p = (p - screenInfo.first) / screenInfo.second; // map to screen space + p += QPoint(2, #ifdef Q_DEAD_CODE_FROM_QT4_WIN 21 *************** void QTipLabel::placeTip(const QPoint &p *** 420,425 **** --- 428,437 ---- p.setX(screen.x()); if (p.y() + this->height() > screen.y() + screen.height()) p.setY(screen.y() + screen.height() - this->height()); + + // HiRes : map p from scaled screen space to OS/Qt global space + p = p * screenInfo.second + screenInfo.first; + this->move(p); } *** a/qtbase/src/widgets/widgets/qmenu.cpp --- b/qtbase/src/widgets/widgets/qmenu.cpp *************** *** 72,77 **** --- 72,78 ---- #include #include #include + #include QT_BEGIN_NAMESPACE *************** void QMenu::popup(const QPoint &p, QActi *** 2183,2188 **** --- 2184,2206 ---- else #endif screen = d->popupGeometry(QApplication::desktop()->screenNumber(p)); + + //---------------------------------------------------------------------------------------- + // HiRes support + // This function fits menu into selected screen. + // To do this, Qt defines screen rect and looks for correct position for menu. + // To make math rigth - we have to deel with screen space. + // It must be (0,0) with screen 'poins' width and height. + // When we done with location - we just map this space back to OS global one. + + // Get screen info. + QDpiScreenInfo screenInfo = QHighDpiScaling::dpiScreenInfo(pos); + + // Map screen rect and input pos into screen space. + screen.translate( -screenInfo.first ); + pos = (pos - screenInfo.first) / screenInfo.second; + //---------------------------------------------------------------------------------------- + const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this); bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen); *************** void QMenu::popup(const QPoint &p, QActi *** 2295,2302 **** QMenu *caused = qobject_cast(d_func()->causedPopup.widget); if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) { QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction)); ! const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft()); ! parentActionRect.moveTopLeft(actionTopLeft); if (isRightToLeft()) { if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset) && (pos.x() < parentActionRect.right())) --- 2313,2324 ---- QMenu *caused = qobject_cast(d_func()->causedPopup.widget); if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) { QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction)); ! //---------------------------------------------------------------------------------------- ! // Here we can not work in OS global space! ! // Instead we have to map pos into screen space. ! const QPoint actionTopLeft = (caused->mapToGlobal(parentActionRect.topLeft()) - screenInfo.first) / screenInfo.second; ! //---------------------------------------------------------------------------------------- ! parentActionRect.moveTopLeft(actionTopLeft); if (isRightToLeft()) { if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset) && (pos.x() < parentActionRect.right())) *************** void QMenu::popup(const QPoint &p, QActi *** 2319,2325 **** --- 2341,2353 ---- } } } + + //---------------------------------------------------------------------------------------- + // Map menu pos from screen space back to OS global spcae. + pos = pos * screenInfo.second + screenInfo.first; + //---------------------------------------------------------------------------------------- setGeometry(QRect(pos, size)); + #ifndef QT_NO_EFFECTS int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll; int vGuess = QEffects::DownScroll; *** a/qtbase/src/widgets/widgets/qtoolbutton.cpp --- b/qtbase/src/widgets/widgets/qtoolbutton.cpp *************** *** 58,63 **** --- 58,64 ---- #include #include #include + #include QT_BEGIN_NAMESPACE *************** void QToolButtonPrivate::popupTimerDone( *** 748,753 **** --- 749,764 ---- QPoint p; const QRect rect = q->rect(); // Find screen via point in case of QGraphicsProxyWidget. QRect screen = QApplication::desktop()->availableGeometry(q->mapToGlobal(rect.center())); + + //------------------------------------------------------------------------------------------------------ + // HiRes : All calculations here done in global space (OS or Qt which are the same). + // Thus, we need to define screen rect in OS global space. + // To do this, we have to define QScreen or QPlatformScreen and apply QHighDpi::toNative(QRect,QScreen) to + // current selected screen's available geometry. + QDpiScreenInfo screenInfo = QHighDpiScaling::dpiScreenInfo( screen.topLeft() ); + screen = QRect( screen.topLeft(), screen.size() * screenInfo.second ); // The same as QHighDpi::toNative(QRect,QScreen) does. + //------------------------------------------------------------------------------------------------------ + QSize sh = ((QToolButton*)(QMenu*)actualMenu)->receivers(SIGNAL(aboutToShow()))? QSize() : actualMenu->sizeHint(); if (horizontal) { if (q->isRightToLeft()) {