diff --git a/README.md b/README.md index bcadc2c0..8463813d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -This is Qt 6.7.2 **qtbase module** backport that runs on Windows 7/8. The repository contains patched source files from the qtbase module. +This is Qt 6.7.3 **qtbase module** backport that runs on Windows 7/8. The repository contains patched source files from the qtbase module. Approach is based on this [forum thread](https://forum.qt.io/topic/133002/qt-creator-6-0-1-and-qt-6-2-2-running-on-windows-7/60) but better: many improvements amongst important fallbacks to default Qt 6 behaviour when running on newer Windows. - After replacing qtbase source files with the patched ones from this repository, you can compile Qt yourself using compiler and build options you need. -- You can use our [compile_win.pl](https://github.com/crystalidea/qt-build-tools/tree/master/6.7.2) build script (uses Visual C++ 2022 with OpenSSL 3.0.13 statically linked) +- You can use our [compile_win.pl](https://github.com/crystalidea/qt-build-tools/tree/master/6.7.3) build script (uses Visual C++ 2022 with OpenSSL 3.0.13 statically linked) - You can download our [prebuild Qt dlls](https://github.com/crystalidea/qt6windows7/releases) which also have Qt Designer binary for demonstration -**Qt 6.7.2 designer running on Windows 7**: +**Qt 6.7.3 designer running on Windows 7**: ![image](https://github.com/crystalidea/qt6windows7/assets/2600624/41f4291a-082a-41e8-a09d-c3b9e7f36e9e) diff --git a/designer.png b/designer.png new file mode 100644 index 00000000..95cf5664 Binary files /dev/null and b/designer.png differ diff --git a/qtbase/src/gui/rhi/qrhid3d11.cpp b/qtbase/src/gui/rhi/qrhid3d11.cpp index 7d2a99ed..4f015668 100644 --- a/qtbase/src/gui/rhi/qrhid3d11.cpp +++ b/qtbase/src/gui/rhi/qrhid3d11.cpp @@ -2872,7 +2872,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD) break; case QD3D11CommandBuffer::Command::Draw: if (cmd.args.draw.ps) { - if (cmd.args.draw.instanceCount == 1) + if (cmd.args.draw.instanceCount == 1 && cmd.args.draw.firstInstance == 0) context->Draw(cmd.args.draw.vertexCount, cmd.args.draw.firstVertex); else context->DrawInstanced(cmd.args.draw.vertexCount, cmd.args.draw.instanceCount, @@ -2883,7 +2883,7 @@ void QRhiD3D11::executeCommandBuffer(QD3D11CommandBuffer *cbD) break; case QD3D11CommandBuffer::Command::DrawIndexed: if (cmd.args.drawIndexed.ps) { - if (cmd.args.drawIndexed.instanceCount == 1) + if (cmd.args.drawIndexed.instanceCount == 1 && cmd.args.drawIndexed.firstInstance == 0) context->DrawIndexed(cmd.args.drawIndexed.indexCount, cmd.args.drawIndexed.firstIndex, cmd.args.drawIndexed.vertexOffset); else diff --git a/qtbase/src/plugins/platforms/windows/qwindowsdrag.cpp b/qtbase/src/plugins/platforms/windows/qwindowsdrag.cpp index 072906c5..b4439b46 100644 --- a/qtbase/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/qtbase/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -256,8 +256,9 @@ void QWindowsOleDropSource::createCursors() if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) platformScreen = primaryScreen->handle(); } - Q_ASSERT(platformScreen); - QPlatformCursor *platformCursor = platformScreen->cursor(); + QPlatformCursor *platformCursor = nullptr; + if (platformScreen) + platformCursor = platformScreen->cursor(); if (GetSystemMetrics (SM_REMOTESESSION) != 0) { /* Workaround for RDP issues with large cursors. @@ -274,7 +275,7 @@ void QWindowsOleDropSource::createCursors() hotSpotScaleFactor = QHighDpiScaling::factor(platformScreen); pixmapScaleFactor = hotSpotScaleFactor / pixmap.devicePixelRatio(); } - QPixmap scaledPixmap = qFuzzyCompare(pixmapScaleFactor, 1.0) + QPixmap scaledPixmap = (!hasPixmap || qFuzzyCompare(pixmapScaleFactor, 1.0)) ? pixmap : pixmap.scaled((QSizeF(pixmap.size()) * pixmapScaleFactor).toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation); diff --git a/qtbase/src/plugins/platforms/windows/qwindowsscreen.cpp b/qtbase/src/plugins/platforms/windows/qwindowsscreen.cpp index 23486b24..3552e21d 100644 --- a/qtbase/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/qtbase/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -142,6 +142,18 @@ struct DiRegKeyHandleTraits using DiRegKeyHandle = QUniqueHandle; +struct DevInfoHandleTraits +{ + using Type = HDEVINFO; + static Type invalidValue() + { + return reinterpret_cast(INVALID_HANDLE_VALUE); + } + static bool close(Type handle) { return SetupDiDestroyDeviceInfoList(handle) == TRUE; } +}; + +using DevInfoHandle = QUniqueHandle; + } static void setMonitorDataFromSetupApi(QWindowsScreenData &data, @@ -191,13 +203,16 @@ static void setMonitorDataFromSetupApi(QWindowsScreenData &data, constexpr GUID GUID_DEVINTERFACE_MONITOR = { 0xe6f07b5f, 0xee97, 0x4a90, { 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7 } }; - const HDEVINFO devInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_MONITOR, nullptr, nullptr, - DIGCF_DEVICEINTERFACE); + const DevInfoHandle devInfo{ SetupDiGetClassDevs( + &GUID_DEVINTERFACE_MONITOR, nullptr, nullptr, DIGCF_DEVICEINTERFACE) }; + + if (!devInfo.isValid()) + continue; SP_DEVICE_INTERFACE_DATA deviceInterfaceData{}; deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); - if (!SetupDiOpenDeviceInterfaceW(devInfo, deviceName.monitorDevicePath, DIODI_NO_ADD, + if (!SetupDiOpenDeviceInterfaceW(devInfo.get(), deviceName.monitorDevicePath, DIODI_NO_ADD, &deviceInterfaceData)) { qCWarning(lcQpaScreen) << u"Unable to open monitor interface to %1:"_s.arg(data.deviceName) @@ -206,7 +221,7 @@ static void setMonitorDataFromSetupApi(QWindowsScreenData &data, } DWORD requiredSize{ 0 }; - if (SetupDiGetDeviceInterfaceDetailW(devInfo, &deviceInterfaceData, nullptr, 0, + if (SetupDiGetDeviceInterfaceDetailW(devInfo.get(), &deviceInterfaceData, nullptr, 0, &requiredSize, nullptr) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { continue; @@ -217,7 +232,7 @@ static void setMonitorDataFromSetupApi(QWindowsScreenData &data, devicePath->cbSize = sizeof(std::remove_pointer_t); SP_DEVINFO_DATA deviceInfoData{}; deviceInfoData.cbSize = sizeof(deviceInfoData); - if (!SetupDiGetDeviceInterfaceDetailW(devInfo, &deviceInterfaceData, devicePath, + if (!SetupDiGetDeviceInterfaceDetailW(devInfo.get(), &deviceInterfaceData, devicePath, requiredSize, nullptr, &deviceInfoData)) { qCDebug(lcQpaScreen) << u"Unable to get monitor metadata for %1:"_s.arg(data.deviceName) << QSystemError::windowsString(); @@ -225,7 +240,7 @@ static void setMonitorDataFromSetupApi(QWindowsScreenData &data, } const DiRegKeyHandle edidRegistryKey{ SetupDiOpenDevRegKey( - devInfo, &deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ) }; + devInfo.get(), &deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ) }; if (!edidRegistryKey.isValid()) continue; diff --git a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp index 59e5ace4..b4cd8a8e 100644 --- a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp @@ -35,6 +35,7 @@ #include #include +#include #include @@ -2176,11 +2177,8 @@ void QWindowsWindow::setGeometry(const QRect &rectIn) const QMargins margins = frameMargins(); rect.moveTopLeft(rect.topLeft() + QPoint(margins.left(), margins.top())); } - if (m_windowState & Qt::WindowMinimized) m_data.geometry = rect; // Otherwise set by handleGeometryChange() triggered by event. - else - setWindowState(Qt::WindowNoState);// Update window state to WindowNoState unless minimized if (m_data.hwnd) { // A ResizeEvent with resulting geometry will be sent. If we cannot @@ -2490,6 +2488,12 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt, return result; } +inline bool QWindowsBaseWindow::hasMaximumSize() const +{ + const auto maximumSize = window()->maximumSize(); + return maximumSize.width() != QWINDOWSIZE_MAX || maximumSize.height() != QWINDOWSIZE_MAX; +} + void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state) { qCDebug(lcQpaWindow) << __FUNCTION__ << this << window() @@ -2506,6 +2510,21 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state) GetWindowPlacement(m_data.hwnd, &windowPlacement); const RECT geometry = RECTfromQRect(m_data.restoreGeometry); windowPlacement.rcNormalPosition = geometry; + + // A bug in windows 10 grows + // - ptMaxPosition.x by the task bar's width, if it's on the left + // - ptMaxPosition.y by the task bar's height, if it's on the top + // each time GetWindowPlacement() is called. + // The offset of the screen's left edge (as per frameMargins_sys().left()) is ignored. + // => Check for windows 10 and correct. + static const auto windows11 = QOperatingSystemVersion::Windows11_21H2; + static const bool isWindows10 = QOperatingSystemVersion::current() < windows11; + if (isWindows10 && hasMaximumSize()) { + const QMargins margins = frameMargins_sys(); + const QPoint topLeft = window()->screen()->geometry().topLeft(); + windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() }; + } + // Even if the window is hidden, windowPlacement's showCmd is not SW_HIDE, so change it // manually to avoid unhiding a hidden window with the subsequent call to // SetWindowPlacement().