diff options
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsintegration.cpp | 2 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsscreen.cpp | 68 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsscreen.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.cpp | 39 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowswindow.h | 10 |
5 files changed, 85 insertions, 37 deletions
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index fc2ba454df..754d7a0288 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -395,6 +395,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co return true; case MultipleWindows: return true; + case ForeignWindows: + return true; default: return QPlatformIntegration::hasCapability(cap); } diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index f616972aa0..530ebc38b7 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -98,35 +98,39 @@ BOOL QT_WIN_CALLBACK monitorEnumCallback(HMONITOR hMonitor, HDC, LPRECT, LPARAM WindowsScreenDataList *result = reinterpret_cast<WindowsScreenDataList *>(p); QWindowsScreenData data; data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1)); + data.name = QString::fromWCharArray(info.szDevice); + if (data.name == QLatin1String("WinDisc")) { + data.flags |= QWindowsScreenData::LockScreen; + } else { #ifdef Q_OS_WINCE - //Windows CE, just supports one Display and expects to get only DISPLAY, - //instead of DISPLAY0 and so on, which are passed by info.szDevice - HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); + //Windows CE, just supports one Display and expects to get only DISPLAY, + //instead of DISPLAY0 and so on, which are passed by info.szDevice + HDC hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); #else - HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL); + HDC hdc = CreateDC(info.szDevice, NULL, NULL, NULL); #endif - if (hdc) { - data.dpi = deviceDPI(hdc); - 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)); - const int refreshRate = GetDeviceCaps(hdc, VREFRESH); - if (refreshRate > 1) // 0,1 means heardware default. - data.refreshRateHz = refreshRate; - DeleteDC(hdc); - } else { - qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.", - __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)), - data.dpi.first); - } + if (hdc) { + data.dpi = deviceDPI(hdc); + 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)); + const int refreshRate = GetDeviceCaps(hdc, VREFRESH); + if (refreshRate > 1) // 0,1 means hardware default. + data.refreshRateHz = refreshRate; + DeleteDC(hdc); + } else { + qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.", + __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)), + data.dpi.first); + } // CreateDC() failed + } // not lock screen data.geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1)); data.availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1)); data.orientation = data.geometry.height() > data.geometry.width() ? Qt::PortraitOrientation : Qt::LandscapeOrientation; // EnumDisplayMonitors (as opposed to EnumDisplayDevices) enumerates only // virtual desktop screens. - data.name = QString::fromWCharArray(info.szDevice); - data.flags = QWindowsScreenData::VirtualDesktop; + data.flags |= QWindowsScreenData::VirtualDesktop; if (info.dwFlags & MONITORINFOF_PRIMARY) { data.flags |= QWindowsScreenData::PrimaryScreen; // QPlatformIntegration::screenAdded() documentation specifies that first @@ -162,6 +166,8 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) nospace << " primary"; if (d.flags & QWindowsScreenData::VirtualDesktop) nospace << " virtual desktop"; + if (d.flags & QWindowsScreenData::LockScreen) + nospace << " lock screen"; return dbg; } @@ -392,7 +398,8 @@ static inline int indexOfMonitor(const QList<QWindowsScreenData> &screenData, bool QWindowsScreenManager::handleScreenChanges() { // Look for changed monitors, add new ones - const WindowsScreenDataList newDataList = monitorData(); + WindowsScreenDataList newDataList = monitorData(); + const bool lockScreen = newDataList.size() == 1 && (newDataList.front().flags & QWindowsScreenData::LockScreen); foreach (const QWindowsScreenData &newData, newDataList) { const int existingIndex = indexOfMonitor(m_screens, newData.name); if (existingIndex != -1) { @@ -405,14 +412,17 @@ bool QWindowsScreenManager::handleScreenChanges() qDebug() << "New Monitor: " << newData; } // exists } // for new screens. - // Remove deleted ones. - for (int i = m_screens.size() - 1; i >= 0; --i) { - if (indexOfMonitor(newDataList, m_screens.at(i)->data().name) == -1) { - if (QWindowsContext::verboseWindows) - qDebug() << "Removing Monitor: " << m_screens.at(i) ->data(); - delete m_screens.takeAt(i); - } // not found - } // for existing screens + // Remove deleted ones but keep main monitors if we get only the + // 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) { + if (QWindowsContext::verboseWindows) + qDebug() << "Removing Monitor: " << m_screens.at(i) ->data(); + delete m_screens.takeAt(i); + } // not found + } // for existing screens + } // not lock screen return true; } diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index 216973125b..930814a17d 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -59,7 +59,8 @@ struct QWindowsScreenData enum Flags { PrimaryScreen = 0x1, - VirtualDesktop = 0x2 + VirtualDesktop = 0x2, + LockScreen = 0x4 // Temporary screen existing during user change, etc. }; QWindowsScreenData(); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index b3b07cc8dd..f3faccbc14 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -549,6 +549,18 @@ QWindowsWindow::WindowData qDebug().nospace() << "Created desktop window " << w << result.hwnd; return result; } + if ((flags & Qt::WindowType_Mask) == Qt::ForeignWindow) { + result.hwnd = reinterpret_cast<HWND>(w->winId()); + Q_ASSERT(result.hwnd); + const LONG_PTR style = GetWindowLongPtr(result.hwnd, GWL_STYLE); + const LONG_PTR exStyle = GetWindowLongPtr(result.hwnd, GWL_EXSTYLE); + result.geometry = frameGeometry(result.hwnd, !GetParent(result.hwnd)); + result.frame = QWindowsGeometryHint::frame(style, exStyle); + result.embedded = false; + if (QWindowsContext::verboseWindows) + qDebug() << "Foreign window: " << w << result.hwnd << result.geometry << result.frame; + return result; + } const HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0); @@ -962,7 +974,7 @@ void QWindowsWindow::destroyWindow() } } #endif // !Q_OS_WINCE - if (m_data.hwnd != GetDesktopWindow()) + if (m_data.hwnd != GetDesktopWindow() && window()->type() != Qt::ForeignWindow) DestroyWindow(m_data.hwnd); context->removeWindow(m_data.hwnd); m_data.hwnd = 0; @@ -1483,14 +1495,27 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) handleHidden(); QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now. break; - case Qt::WindowNoState: + case Qt::WindowNoState: { // QTBUG-17548: We send expose events when receiving WM_Paint, but for - // layered windows, we won't receive any WM_Paint. - if (GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) { - fireExpose(QRegion(0, 0, window()->width(), window()->height())); - if (!QWindowsContext::instance()->asyncExpose()) - QWindowSystemInterface::flushWindowSystemEvents(); + // layered windows and transient children, we won't receive any WM_Paint. + QWindow *w = window(); + bool exposeEventsSent = false; + if (isLayered()) { + fireExpose(QRegion(0, 0, w->width(), w->height())); + exposeEventsSent = true; } + foreach (QWindow *child, QGuiApplication::allWindows()) { + if (child != w && child->isVisible() && child->transientParent() == w) { + QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(child); + if (platformWindow->isLayered()) { + platformWindow->fireExpose(QRegion(0, 0, child->width(), child->height())); + exposeEventsSent = true; + } + } + } + if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose()) + QWindowSystemInterface::flushWindowSystemEvents(); + } break; default: break; diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index d365ac4d97..f055864482 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -230,6 +230,7 @@ public: static inline void setUserDataOf(HWND hwnd, void *ud); static bool setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal opacity); + bool isLayered() const; HDC getDC(); void releaseDC(); @@ -376,6 +377,15 @@ inline void QWindowsWindow::destroyIcon() } } +inline bool QWindowsWindow::isLayered() const +{ +#ifndef Q_OS_WINCE + return GetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE) & WS_EX_LAYERED; +#else + return false; +#endif +} + QT_END_NAMESPACE Q_DECLARE_METATYPE(QMargins) |