diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsscreen.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsscreen.cpp | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index a6e2aabaf0..bcdb8a2352 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -68,6 +68,21 @@ static inline QDpi deviceDPI(HDC hdc) return QDpi(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY)); } +#ifndef Q_OS_WINCE + +static inline QDpi monitorDPI(HMONITOR hMonitor) +{ + if (QWindowsContext::shcoredll.isValid()) { + UINT dpiX; + UINT dpiY; + if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, 0, &dpiX, &dpiY))) + return QDpi(dpiX, dpiY); + } + return QDpi(0, 0); +} + +#endif // !Q_OS_WINCE + static inline QSizeF deviceSizeMM(const QSize &pixels, const QDpi &dpi) { const qreal inchToMM = 25.4; @@ -110,7 +125,12 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL); #endif if (hdc) { +#ifndef Q_OS_WINCE + const QDpi dpi = monitorDPI(hMonitor); + data.dpi = dpi.first ? dpi : deviceDPI(hdc); +#else data.dpi = deviceDPI(hdc); +#endif data.depth = GetDeviceCaps(hdc, BITSPIXEL); data.format = data.depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32; data.physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE)); @@ -387,6 +407,30 @@ static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData, return -1; } +void QWindowsScreenManager::removeScreen(int index) +{ + qCDebug(lcQpaWindows) << "Removing Monitor:" << m_screens.at(index)->data(); + QScreen *screen = m_screens.at(index)->screen(); + QScreen *primaryScreen = QGuiApplication::primaryScreen(); + // QTBUG-38650: When a screen is disconnected, Windows will automatically + // move the Window to another screen. This will trigger a geometry change + // event, but unfortunately after the screen destruction signal. To prevent + // QtGui from automatically hiding the QWindow, pretend all Windows move to + // the primary screen first (which is likely the correct, final screen). + if (screen != primaryScreen) { + unsigned movedWindowCount = 0; + foreach (QWindow *w, QGuiApplication::topLevelWindows()) { + if (w->screen() == screen && w->handle() && w->type() != Qt::Desktop) { + QWindowSystemInterface::handleWindowScreenChanged(w, primaryScreen); + ++movedWindowCount; + } + } + if (movedWindowCount) + QWindowSystemInterface::flushWindowSystemEvents(); + } + delete m_screens.takeAt(index); +} + /*! \brief Synchronizes the screen list, adds new screens, removes deleted ones and propagates resolution changes to QWindowSystemInterface. @@ -412,10 +456,8 @@ bool QWindowsScreenManager::handleScreenChanges() // temporary lock screen to avoid window recreation (QTBUG-33062). if (!lockScreen) { for (int i = m_screens.size() - 1; i >= 0; --i) { - if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) { - qCDebug(lcQpaWindows) << "Removing Monitor: " << m_screens.at(i) ->data(); - delete m_screens.takeAt(i); - } // not found + if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) + removeScreen(i); } // for existing screens } // not lock screen return true; |