11 Commits

Author SHA1 Message Date
1b4cd6f752 Merge d6525e7907 into aabe4f68c7 2024-12-28 10:03:42 +01:00
aabe4f68c7 Merge pull request #29 from wsxarcher/patch-2
Fix mingw cross compilation on linux
2024-12-28 10:03:34 +01:00
263451546b Merge pull request #30 from wsxarcher/patch-3
Fix gcc (mingw) compilation of pointer comparison in switch using ifs
2024-12-28 09:59:23 +01:00
04ec1a740d fix gcc compilation of pointer comparison 2024-12-27 23:53:49 +01:00
5a8a83f569 Fix mingw cross compilation 2024-12-16 02:02:54 +01:00
d6525e7907 Fix build on non-windows 2024-12-15 23:00:30 +01:00
45d7e6576d Update README.md 2024-12-13 15:50:31 +01:00
8c8f9a4e87 Qt 6.8.1 2024-12-13 13:51:13 +01:00
a9966ab3ae Update README.md 2024-11-21 14:34:17 +01:00
4f4f7a7c46 fixed compilation when using non-microsoft compiler 2024-11-19 13:57:04 +01:00
6ba197bce4 Update README.md 2024-11-18 13:56:33 +01:00
11 changed files with 162 additions and 74 deletions

View File

@ -1,21 +1,16 @@
This repository provides a backport of the Qt 6.8.0 qtbase module, tailored for compatibility with Windows 7 and 8. It contains patched source files from the qtbase module, along with some additional required files. To apply the backport, simply copy the contents of the src folder into your qtbase/src directory, replacing the existing files. This repository provides a backport of the Qt 6.8.1 qtbase module, tailored for compatibility with Windows 7 and 8. It contains patched source files from the qtbase module, along with some additional required files. To apply the backport, simply copy the contents of the src folder into your qtbase/src directory, replacing the existing files.
This approach builds upon the methodology discussed in [forum thread](https://forum.qt.io/topic/133002/qt-creator-6-0-1-and-qt-6-2-2-running-on-windows-7/60) but offers significant enhancements, including important fallbacks to the default Qt 6 behavior when running on newer versions of Windows. This approach builds upon the methodology discussed in 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 offers significant enhancements, including important fallbacks to the default Qt 6 behavior when running on newer versions of Windows.
You have two options for compiling Qt: You can compile it yourself using your preferred compiler and build options or can use our [compile_win.pl](https://github.com/crystalidea/qt-build-tools/tree/master/6.8.1) build script, which utilizes Visual C++ 2022 and includes OpenSSL 3.0.13 statically linked. Alternatively, you can download our [prebuild Qt dlls](https://github.com/crystalidea/qt6windows7/releases), which also include the Qt Designer binary for demonstration purposes.
- Compile it yourself using your preferred compiler and build options. **Qt 6.8.1 designer running on Windows 7**:
- Use our [compile_win.pl](https://github.com/crystalidea/qt-build-tools/tree/master/6.8.0) build script, which utilizes Visual C++ 2022 and includes OpenSSL 3.0.13 statically linked.
Alternatively, you can download our [prebuild Qt dlls](https://github.com/crystalidea/qt6windows7/releases), which also include the Qt Designer binary for demonstration purposes.
**Qt 6.8.0 designer running on Windows 7**:
![Qt Designer](designer.png) ![Qt Designer](designer.png)
**Other modules**: **Other modules**:
Many of other modules should also work on Windows 7 without modifications, e.g. Many of other Qt 6 modules are known to work fine on Windows 7 without modifications when compiled with patched qtbase. Verified modules:
- qt5compat - qt5compat
- qtimageformats - qtimageformats
@ -28,7 +23,7 @@ Many of other modules should also work on Windows 7 without modifications, e.g.
### Older versions: ### Older versions:
- [Qt 6.7.3](https://github.com/crystalidea/qt6windows7/releases/tag/v6.7.3) - [Qt 6.8.0](https://github.com/crystalidea/qt6windows7/releases/tag/v6.8.0)
- [Qt 6.7.2](https://github.com/crystalidea/qt6windows7/releases/tag/v6.7.2) - [Qt 6.7.2](https://github.com/crystalidea/qt6windows7/releases/tag/v6.7.2)
- [Qt 6.6.3](https://github.com/crystalidea/qt6windows7/releases/tag/v6.6.3) - [Qt 6.6.3](https://github.com/crystalidea/qt6windows7/releases/tag/v6.6.3)
- [Qt 6.6.2](https://github.com/crystalidea/qt6windows7/releases/tag/v6.6.2) - [Qt 6.6.2](https://github.com/crystalidea/qt6windows7/releases/tag/v6.6.2)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -12,7 +12,7 @@
#include <qt_windows.h> #include <qt_windows.h>
#include <shlobj.h> #include <shlobj.h>
#include <VersionHelpers.h> #include <versionhelpers.h>
#include <intshcut.h> #include <intshcut.h>
#include <qvarlengtharray.h> #include <qvarlengtharray.h>

View File

@ -76,7 +76,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
// avoid recursion. // avoid recursion.
TlsSetValue(qt_current_thread_data_tls_index, threadData); TlsSetValue(qt_current_thread_data_tls_index, threadData);
QT_TRY { QT_TRY {
threadData->thread = new QAdoptedThread(threadData); threadData->thread.storeRelease(new QAdoptedThread(threadData));
} QT_CATCH(...) { } QT_CATCH(...) {
TlsSetValue(qt_current_thread_data_tls_index, 0); TlsSetValue(qt_current_thread_data_tls_index, 0);
threadData->deref(); threadData->deref();
@ -101,7 +101,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
0, 0,
FALSE, FALSE,
DUPLICATE_SAME_ACCESS); DUPLICATE_SAME_ACCESS);
qt_watch_adopted_thread(realHandle, threadData->thread); qt_watch_adopted_thread(realHandle, threadData->thread.loadRelaxed());
} }
} }
return threadData; return threadData;
@ -209,7 +209,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
auto thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread)); auto thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
Q_UNUSED(thread_p); Q_UNUSED(thread_p);
Q_ASSERT(!thread_p->finished); Q_ASSERT(!thread_p->finished);
QThreadPrivate::finish(thread); thread_p->finish();
} }
data->deref(); data->deref();
@ -240,6 +240,8 @@ typedef struct tagTHREADNAME_INFO
typedef HRESULT(WINAPI* SetThreadDescriptionFunc)(HANDLE, PCWSTR); typedef HRESULT(WINAPI* SetThreadDescriptionFunc)(HANDLE, PCWSTR);
#if defined(Q_CC_MSVC)
// Helper function to set the thread name using RaiseException and __try // Helper function to set the thread name using RaiseException and __try
static void setThreadNameUsingException(HANDLE threadId, LPCSTR threadName) { static void setThreadNameUsingException(HANDLE threadId, LPCSTR threadName) {
THREADNAME_INFO info; THREADNAME_INFO info;
@ -256,6 +258,8 @@ static void setThreadNameUsingException(HANDLE threadId, LPCSTR threadName) {
} }
} }
#endif // Q_CC_MSVC
void qt_set_thread_name(HANDLE threadId, const QString &name) void qt_set_thread_name(HANDLE threadId, const QString &name)
{ {
HMODULE hKernel32 = GetModuleHandleW(L"Kernel32.dll"); HMODULE hKernel32 = GetModuleHandleW(L"Kernel32.dll");
@ -278,7 +282,6 @@ void qt_set_thread_name(HANDLE threadId, const QString &name)
} }
} }
/************************************************************************** /**************************************************************************
** QThreadPrivate ** QThreadPrivate
*************************************************************************/ *************************************************************************/
@ -322,7 +325,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
QThread::setTerminationEnabled(true); QThread::setTerminationEnabled(true);
thr->run(); thr->run();
finish(arg); thr->d_func()->finish();
return 0; return 0;
} }
@ -337,10 +340,10 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
In those cases, \a arg will not be the current thread. In those cases, \a arg will not be the current thread.
*/ */
void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept void QThreadPrivate::finish(bool lockAnyway) noexcept
{ {
QThread *thr = reinterpret_cast<QThread *>(arg); QThreadPrivate *d = this;
QThreadPrivate *d = thr->d_func(); QThread *thr = q_func();
QMutexLocker locker(lockAnyway ? &d->mutex : nullptr); QMutexLocker locker(lockAnyway ? &d->mutex : nullptr);
d->isInFinish = true; d->isInFinish = true;
@ -534,7 +537,7 @@ void QThread::terminate()
} }
TerminateThread(d->handle, 0); TerminateThread(d->handle, 0);
QThreadPrivate::finish(this, false); d->finish(false);
} }
bool QThread::wait(QDeadlineTimer deadline) bool QThread::wait(QDeadlineTimer deadline)
@ -548,6 +551,13 @@ bool QThread::wait(QDeadlineTimer deadline)
} }
if (d->finished || !d->running) if (d->finished || !d->running)
return true; return true;
return d->wait(locker, deadline);
}
bool QThreadPrivate::wait(QMutexLocker<QMutex> &locker, QDeadlineTimer deadline)
{
Q_ASSERT(locker.isLocked());
QThreadPrivate *d = this;
++d->waiters; ++d->waiters;
locker.mutex()->unlock(); locker.mutex()->unlock();
@ -572,7 +582,7 @@ bool QThread::wait(QDeadlineTimer deadline)
if (ret && !d->finished) { if (ret && !d->finished) {
// thread was terminated by someone else // thread was terminated by someone else
QThreadPrivate::finish(this, false); d->finish(false);
} }
if (d->finished && !d->waiters) { if (d->finished && !d->waiters) {
@ -592,7 +602,7 @@ void QThread::setTerminationEnabled(bool enabled)
QMutexLocker locker(&d->mutex); QMutexLocker locker(&d->mutex);
d->terminationEnabled = enabled; d->terminationEnabled = enabled;
if (enabled && d->terminatePending) { if (enabled && d->terminatePending) {
QThreadPrivate::finish(thr, false); d->finish(false);
locker.unlock(); // don't leave the mutex locked! locker.unlock(); // don't leave the mutex locked!
_endthreadex(0); _endthreadex(0);
} }

View File

@ -12,7 +12,7 @@
#include <cstdio> #include <cstdio>
#include <VersionHelpers.h> #include <versionhelpers.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -3312,6 +3312,10 @@ bool QD3D11Texture::prepareCreate(QSize *adjustedSize)
if (tex || tex3D || tex1D) if (tex || tex3D || tex1D)
destroy(); destroy();
QRHI_RES_RHI(QRhiD3D11);
if (!rhiD->isTextureFormatSupported(m_format, m_flags))
return false;
const bool isDepth = isDepthTextureFormat(m_format); const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap); const bool isCube = m_flags.testFlag(CubeMap);
const bool is3D = m_flags.testFlag(ThreeDimensional); const bool is3D = m_flags.testFlag(ThreeDimensional);
@ -3322,7 +3326,6 @@ bool QD3D11Texture::prepareCreate(QSize *adjustedSize)
const QSize size = is1D ? QSize(qMax(1, m_pixelSize.width()), 1) const QSize size = is1D ? QSize(qMax(1, m_pixelSize.width()), 1)
: (m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize); : (m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize);
QRHI_RES_RHI(QRhiD3D11);
dxgiFormat = toD3DTextureFormat(m_format, m_flags); dxgiFormat = toD3DTextureFormat(m_format, m_flags);
mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1); mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
sampleDesc = rhiD->effectiveSampleDesc(m_sampleCount); sampleDesc = rhiD->effectiveSampleDesc(m_sampleCount);

View File

@ -4210,6 +4210,10 @@ bool QD3D12Texture::prepareCreate(QSize *adjustedSize)
if (!handle.isNull()) if (!handle.isNull())
destroy(); destroy();
QRHI_RES_RHI(QRhiD3D12);
if (!rhiD->isTextureFormatSupported(m_format, m_flags))
return false;
const bool isDepth = isDepthTextureFormat(m_format); const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap); const bool isCube = m_flags.testFlag(CubeMap);
const bool is3D = m_flags.testFlag(ThreeDimensional); const bool is3D = m_flags.testFlag(ThreeDimensional);
@ -4240,7 +4244,7 @@ bool QD3D12Texture::prepareCreate(QSize *adjustedSize)
else else
srvFormat = toD3DTextureFormat(m_readViewFormat.format, m_readViewFormat.srgb ? sRGB : Flags()); srvFormat = toD3DTextureFormat(m_readViewFormat.format, m_readViewFormat.srgb ? sRGB : Flags());
} }
QRHI_RES_RHI(QRhiD3D12);
mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1); mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
sampleDesc = rhiD->effectiveSampleDesc(m_sampleCount, dxgiFormat); sampleDesc = rhiD->effectiveSampleDesc(m_sampleCount, dxgiFormat);
if (sampleDesc.Count > 1) { if (sampleDesc.Count > 1) {

View File

@ -1562,11 +1562,9 @@ void QWindowsContext::setAsyncExpose(bool value)
DWORD QWindowsContext::readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue) DWORD QWindowsContext::readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue)
{ {
const auto value = const auto advancedSettings = QWinRegistryKey(
QWinRegistryKey(HKEY_CURRENT_USER, HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)");
LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)") return advancedSettings.value<DWORD>(subKey).value_or(defaultValue);
.dwordValue(subKey);
return value.second ? value.first : defaultValue;
} }
static inline bool isEmptyRect(const RECT &rect) static inline bool isEmptyRect(const RECT &rect)

View File

@ -501,7 +501,8 @@ QWindowsTheme *QWindowsTheme::m_instance = nullptr;
QWindowsTheme::QWindowsTheme() QWindowsTheme::QWindowsTheme()
{ {
m_instance = this; m_instance = this;
s_colorScheme = QWindowsTheme::queryColorScheme(); s_colorScheme = Qt::ColorScheme::Unknown; // Used inside QWindowsTheme::effectiveColorScheme();
s_colorScheme = QWindowsTheme::effectiveColorScheme();
std::fill(m_fonts, m_fonts + NFonts, nullptr); std::fill(m_fonts, m_fonts + NFonts, nullptr);
std::fill(m_palettes, m_palettes + NPalettes, nullptr); std::fill(m_palettes, m_palettes + NPalettes, nullptr);
refresh(); refresh();
@ -596,12 +597,15 @@ Qt::ColorScheme QWindowsTheme::colorScheme() const
Qt::ColorScheme QWindowsTheme::effectiveColorScheme() Qt::ColorScheme QWindowsTheme::effectiveColorScheme()
{ {
auto integration = QWindowsIntegration::instance();
if (queryHighContrast()) if (queryHighContrast())
return Qt::ColorScheme::Unknown; return Qt::ColorScheme::Unknown;
if (s_colorSchemeOverride != Qt::ColorScheme::Unknown) if (s_colorSchemeOverride != Qt::ColorScheme::Unknown)
return s_colorSchemeOverride; return s_colorSchemeOverride;
if (s_colorScheme != Qt::ColorScheme::Unknown) if (s_colorScheme != Qt::ColorScheme::Unknown)
return s_colorScheme; return s_colorScheme;
if (!integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle))
return Qt::ColorScheme::Light;
return queryColorScheme(); return queryColorScheme();
} }
@ -1186,9 +1190,11 @@ Qt::ColorScheme QWindowsTheme::queryColorScheme()
if (queryHighContrast()) if (queryHighContrast())
return Qt::ColorScheme::Unknown; return Qt::ColorScheme::Unknown;
const auto setting = QWinRegistryKey(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)") QWinRegistryKey personalizeKey{
.dwordValue(L"AppsUseLightTheme"); HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)"
return setting.second && setting.first == 0 ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light; };
const bool useDarkTheme = personalizeKey.value<DWORD>(L"AppsUseLightTheme") == 0;
return useDarkTheme ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
} }
bool QWindowsTheme::queryHighContrast() bool QWindowsTheme::queryHighContrast()

View File

@ -1401,10 +1401,12 @@ void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
const HWND newParent = newParentWindow ? reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(nullptr); const HWND newParent = newParentWindow ? reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(nullptr);
const bool isTopLevel = !newParent; const bool isTopLevel = !newParent;
const DWORD oldStyle = style(); const DWORD oldStyle = style();
qCDebug(lcQpaWindow) << __FUNCTION__ << window() << "newParent=" qCDebug(lcQpaWindow) << __FUNCTION__ << window() << "newParent="
<< newParentWindow << newParent << "oldStyle=" << debugWinStyle(oldStyle); << newParentWindow << newParent << "oldStyle=" << debugWinStyle(oldStyle);
SetParent(m_hwnd, newParent);
if (wasTopLevel != isTopLevel) { // Top level window flags need to be set/cleared manually. auto updateWindowFlags = [=]{
// Top level window flags need to be set/cleared manually.
DWORD newStyle = oldStyle; DWORD newStyle = oldStyle;
if (isTopLevel) { if (isTopLevel) {
newStyle = m_topLevelStyle; newStyle = m_topLevelStyle;
@ -1414,6 +1416,20 @@ void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
newStyle |= WS_CHILD; newStyle |= WS_CHILD;
} }
SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle); SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
};
if (wasTopLevel && !isTopLevel) {
// Becoming a child window requires the style
// flags to be updated before reparenting.
updateWindowFlags();
}
SetParent(m_hwnd, newParent);
if (!wasTopLevel && isTopLevel) {
// Becoming a top level window requires the style
// flags to be updated after reparenting.
updateWindowFlags();
} }
} }
@ -2496,12 +2512,6 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
return result; 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) void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
{ {
qCDebug(lcQpaWindow) << __FUNCTION__ << this << window() qCDebug(lcQpaWindow) << __FUNCTION__ << this << window()
@ -2518,20 +2528,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
GetWindowPlacement(m_data.hwnd, &windowPlacement); GetWindowPlacement(m_data.hwnd, &windowPlacement);
const RECT geometry = RECTfromQRect(m_data.restoreGeometry); const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
windowPlacement.rcNormalPosition = geometry; windowPlacement.rcNormalPosition = geometry;
correctWindowPlacement(windowPlacement);
// 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 // 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 // manually to avoid unhiding a hidden window with the subsequent call to
@ -2563,6 +2560,65 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
} }
} }
// Apply corrections to window placement in Windows 10
// Related to task bar on top or left.
inline bool QWindowsBaseWindow::hasMaximumHeight() const
{
return window()->maximumHeight() != QWINDOWSIZE_MAX;
}
inline bool QWindowsBaseWindow::hasMaximumWidth() const
{
return window()->maximumWidth() != QWINDOWSIZE_MAX;
}
inline bool QWindowsBaseWindow::hasMaximumSize() const
{
return hasMaximumHeight() || hasMaximumWidth();
}
void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
{
static const auto windows11 = QOperatingSystemVersion::Windows11_21H2;
static const bool isWindows10 = QOperatingSystemVersion::current() < windows11;
if (!isWindows10)
return;
// Correct normal position by placement offset on Windows 10
// (where task bar can be on any side of the screen)
const QPoint offset = windowPlacementOffset(m_data.hwnd, m_data.restoreGeometry.topLeft());
windowPlacement.rcNormalPosition = RECTfromQRect(m_data.restoreGeometry.translated(-offset));
qCDebug(lcQpaWindow) << "Corrected normal position by" << -offset;
// 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.
if (hasMaximumSize()) {
const QMargins margins = frameMargins_sys();
const QPoint topLeft = window()->screen()->geometry().topLeft();
windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() };
qCDebug(lcQpaWindow) << "Window has maximum size. Corrected topLeft by"
<< -margins.left();
// If there is a placement offset correct width/height unless restricted,
// in order to fit window onto the screen.
if (offset.x() > 0 && !hasMaximumWidth()) {
const int adjust = offset.x() / window()->devicePixelRatio();
window()->setWidth(window()->width() - adjust);
qCDebug(lcQpaWindow) << "Width shortened by" << adjust << "logical pixels.";
}
if (offset.y() > 0 && !hasMaximumHeight()) {
const int adjust = offset.y() / window()->devicePixelRatio();
window()->setHeight(window()->height() - adjust);
qCDebug(lcQpaWindow) << "Height shortened by" << adjust << "logical pixels.";
}
}
}
void QWindowsWindow::updateRestoreGeometry() void QWindowsWindow::updateRestoreGeometry()
{ {
m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd); m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
@ -2707,8 +2763,24 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
setFlag(WithinMaximize); setFlag(WithinMaximize);
if (newState & Qt::WindowFullScreen) if (newState & Qt::WindowFullScreen)
setFlag(MaximizeToFullScreen); setFlag(MaximizeToFullScreen);
ShowWindow(m_data.hwnd, if (m_data.flags & Qt::FramelessWindowHint) {
(newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE); if (newState == Qt::WindowNoState) {
const QRect &rect = m_savedFrameGeometry;
MoveWindow(m_data.hwnd, rect.x(), rect.y(), rect.width(), rect.height(), true);
} else {
HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
MONITORINFO monitorInfo = {};
monitorInfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &monitorInfo);
const RECT &rect = monitorInfo.rcWork;
m_savedFrameGeometry = geometry();
MoveWindow(m_data.hwnd, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top, true);
}
} else {
ShowWindow(m_data.hwnd,
(newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
}
clearFlag(WithinMaximize); clearFlag(WithinMaximize);
clearFlag(MaximizeToFullScreen); clearFlag(MaximizeToFullScreen);
} else if (visible && (oldState & newState & Qt::WindowMinimized)) { } else if (visible && (oldState & newState & Qt::WindowMinimized)) {

View File

@ -261,16 +261,13 @@ static BOOL GetDisplayAutoRotationPreferences(
static BOOL SetProcessDpiAwarenessContext( static BOOL SetProcessDpiAwarenessContext(
IN DPI_AWARENESS_CONTEXT DpiContext) IN DPI_AWARENESS_CONTEXT DpiContext)
{ {
switch ((ULONG_PTR)DpiContext) { if ((ULONG_PTR)DpiContext == (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE) {
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE:
//NOTHING; //NOTHING;
break; } else if ((ULONG_PTR)DpiContext == (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ||
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE: (ULONG_PTR)DpiContext == (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ||
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: (ULONG_PTR)DpiContext == (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) {
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2:
SetProcessDPIAware(); SetProcessDPIAware();
break; } else {
default:
return FALSE; return FALSE;
} }
@ -287,14 +284,13 @@ static BOOL AreDpiAwarenessContextsEqual(
static BOOL IsValidDpiAwarenessContext( static BOOL IsValidDpiAwarenessContext(
IN DPI_AWARENESS_CONTEXT Value) IN DPI_AWARENESS_CONTEXT Value)
{ {
switch ((ULONG_PTR)Value) { if ((ULONG_PTR)Value == (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE ||
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE: (ULONG_PTR)Value == (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ||
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED: (ULONG_PTR)Value == (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ||
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE: (ULONG_PTR)Value == (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ||
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: (ULONG_PTR)Value == (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) {
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2:
return TRUE; return TRUE;
default: } else {
return FALSE; return FALSE;
} }
} }

View File

@ -59,7 +59,9 @@
#include <algorithm> #include <algorithm>
#if defined(Q_OS_WIN)
#include "../../plugins/platforms/windows/vxkex.h" #include "../../plugins/platforms/windows/vxkex.h"
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -256,8 +258,10 @@ void QWindowsStyle::polish(QPalette &pal)
QCommonStyle::polish(pal); QCommonStyle::polish(pal);
} }
#if defined(Q_OS_WIN)
typedef BOOL (WINAPI *GetSystemMetricsForDpiFunc)(int, UINT); typedef BOOL (WINAPI *GetSystemMetricsForDpiFunc)(int, UINT);
typedef BOOL (WINAPI *SystemParametersInfoForDpiFunc)(UINT, UINT, PVOID, UINT, UINT); typedef BOOL (WINAPI *SystemParametersInfoForDpiFunc)(UINT, UINT, PVOID, UINT, UINT);
#endif
int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *, const QWidget *widget) int QWindowsStylePrivate::pixelMetricFromSystemDp(QStyle::PixelMetric pm, const QStyleOption *, const QWidget *widget)
{ {