mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-05 00:35:27 +08:00
Qt 6.8.1
This commit is contained in:
@ -76,7 +76,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
|
||||
// avoid recursion.
|
||||
TlsSetValue(qt_current_thread_data_tls_index, threadData);
|
||||
QT_TRY {
|
||||
threadData->thread = new QAdoptedThread(threadData);
|
||||
threadData->thread.storeRelease(new QAdoptedThread(threadData));
|
||||
} QT_CATCH(...) {
|
||||
TlsSetValue(qt_current_thread_data_tls_index, 0);
|
||||
threadData->deref();
|
||||
@ -101,7 +101,7 @@ QThreadData *QThreadData::current(bool createIfNecessary)
|
||||
0,
|
||||
FALSE,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
qt_watch_adopted_thread(realHandle, threadData->thread);
|
||||
qt_watch_adopted_thread(realHandle, threadData->thread.loadRelaxed());
|
||||
}
|
||||
}
|
||||
return threadData;
|
||||
@ -209,7 +209,7 @@ DWORD WINAPI qt_adopted_thread_watcher_function(LPVOID)
|
||||
auto thread_p = static_cast<QThreadPrivate *>(QObjectPrivate::get(thread));
|
||||
Q_UNUSED(thread_p);
|
||||
Q_ASSERT(!thread_p->finished);
|
||||
QThreadPrivate::finish(thread);
|
||||
thread_p->finish();
|
||||
}
|
||||
data->deref();
|
||||
|
||||
@ -282,7 +282,6 @@ void qt_set_thread_name(HANDLE threadId, const QString &name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
** QThreadPrivate
|
||||
*************************************************************************/
|
||||
@ -326,7 +325,7 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
|
||||
QThread::setTerminationEnabled(true);
|
||||
thr->run();
|
||||
|
||||
finish(arg);
|
||||
thr->d_func()->finish();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -341,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.
|
||||
*/
|
||||
void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
|
||||
void QThreadPrivate::finish(bool lockAnyway) noexcept
|
||||
{
|
||||
QThread *thr = reinterpret_cast<QThread *>(arg);
|
||||
QThreadPrivate *d = thr->d_func();
|
||||
QThreadPrivate *d = this;
|
||||
QThread *thr = q_func();
|
||||
|
||||
QMutexLocker locker(lockAnyway ? &d->mutex : nullptr);
|
||||
d->isInFinish = true;
|
||||
@ -538,7 +537,7 @@ void QThread::terminate()
|
||||
}
|
||||
|
||||
TerminateThread(d->handle, 0);
|
||||
QThreadPrivate::finish(this, false);
|
||||
d->finish(false);
|
||||
}
|
||||
|
||||
bool QThread::wait(QDeadlineTimer deadline)
|
||||
@ -552,6 +551,13 @@ bool QThread::wait(QDeadlineTimer deadline)
|
||||
}
|
||||
if (d->finished || !d->running)
|
||||
return true;
|
||||
return d->wait(locker, deadline);
|
||||
}
|
||||
|
||||
bool QThreadPrivate::wait(QMutexLocker<QMutex> &locker, QDeadlineTimer deadline)
|
||||
{
|
||||
Q_ASSERT(locker.isLocked());
|
||||
QThreadPrivate *d = this;
|
||||
|
||||
++d->waiters;
|
||||
locker.mutex()->unlock();
|
||||
@ -576,7 +582,7 @@ bool QThread::wait(QDeadlineTimer deadline)
|
||||
if (ret && !d->finished) {
|
||||
// thread was terminated by someone else
|
||||
|
||||
QThreadPrivate::finish(this, false);
|
||||
d->finish(false);
|
||||
}
|
||||
|
||||
if (d->finished && !d->waiters) {
|
||||
@ -596,7 +602,7 @@ void QThread::setTerminationEnabled(bool enabled)
|
||||
QMutexLocker locker(&d->mutex);
|
||||
d->terminationEnabled = enabled;
|
||||
if (enabled && d->terminatePending) {
|
||||
QThreadPrivate::finish(thr, false);
|
||||
d->finish(false);
|
||||
locker.unlock(); // don't leave the mutex locked!
|
||||
_endthreadex(0);
|
||||
}
|
||||
|
@ -3312,6 +3312,10 @@ bool QD3D11Texture::prepareCreate(QSize *adjustedSize)
|
||||
if (tex || tex3D || tex1D)
|
||||
destroy();
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
if (!rhiD->isTextureFormatSupported(m_format, m_flags))
|
||||
return false;
|
||||
|
||||
const bool isDepth = isDepthTextureFormat(m_format);
|
||||
const bool isCube = m_flags.testFlag(CubeMap);
|
||||
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)
|
||||
: (m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize);
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D11);
|
||||
dxgiFormat = toD3DTextureFormat(m_format, m_flags);
|
||||
mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
|
||||
sampleDesc = rhiD->effectiveSampleDesc(m_sampleCount);
|
||||
|
@ -4210,6 +4210,10 @@ bool QD3D12Texture::prepareCreate(QSize *adjustedSize)
|
||||
if (!handle.isNull())
|
||||
destroy();
|
||||
|
||||
QRHI_RES_RHI(QRhiD3D12);
|
||||
if (!rhiD->isTextureFormatSupported(m_format, m_flags))
|
||||
return false;
|
||||
|
||||
const bool isDepth = isDepthTextureFormat(m_format);
|
||||
const bool isCube = m_flags.testFlag(CubeMap);
|
||||
const bool is3D = m_flags.testFlag(ThreeDimensional);
|
||||
@ -4240,7 +4244,7 @@ bool QD3D12Texture::prepareCreate(QSize *adjustedSize)
|
||||
else
|
||||
srvFormat = toD3DTextureFormat(m_readViewFormat.format, m_readViewFormat.srgb ? sRGB : Flags());
|
||||
}
|
||||
QRHI_RES_RHI(QRhiD3D12);
|
||||
|
||||
mipLevelCount = uint(hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1);
|
||||
sampleDesc = rhiD->effectiveSampleDesc(m_sampleCount, dxgiFormat);
|
||||
if (sampleDesc.Count > 1) {
|
||||
|
@ -1562,11 +1562,9 @@ void QWindowsContext::setAsyncExpose(bool value)
|
||||
|
||||
DWORD QWindowsContext::readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue)
|
||||
{
|
||||
const auto value =
|
||||
QWinRegistryKey(HKEY_CURRENT_USER,
|
||||
LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)")
|
||||
.dwordValue(subKey);
|
||||
return value.second ? value.first : defaultValue;
|
||||
const auto advancedSettings = QWinRegistryKey(
|
||||
HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)");
|
||||
return advancedSettings.value<DWORD>(subKey).value_or(defaultValue);
|
||||
}
|
||||
|
||||
static inline bool isEmptyRect(const RECT &rect)
|
||||
|
@ -501,7 +501,8 @@ QWindowsTheme *QWindowsTheme::m_instance = nullptr;
|
||||
QWindowsTheme::QWindowsTheme()
|
||||
{
|
||||
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_palettes, m_palettes + NPalettes, nullptr);
|
||||
refresh();
|
||||
@ -596,12 +597,15 @@ Qt::ColorScheme QWindowsTheme::colorScheme() const
|
||||
|
||||
Qt::ColorScheme QWindowsTheme::effectiveColorScheme()
|
||||
{
|
||||
auto integration = QWindowsIntegration::instance();
|
||||
if (queryHighContrast())
|
||||
return Qt::ColorScheme::Unknown;
|
||||
if (s_colorSchemeOverride != Qt::ColorScheme::Unknown)
|
||||
return s_colorSchemeOverride;
|
||||
if (s_colorScheme != Qt::ColorScheme::Unknown)
|
||||
return s_colorScheme;
|
||||
if (!integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle))
|
||||
return Qt::ColorScheme::Light;
|
||||
return queryColorScheme();
|
||||
}
|
||||
|
||||
@ -1186,9 +1190,11 @@ Qt::ColorScheme QWindowsTheme::queryColorScheme()
|
||||
if (queryHighContrast())
|
||||
return Qt::ColorScheme::Unknown;
|
||||
|
||||
const auto setting = QWinRegistryKey(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)")
|
||||
.dwordValue(L"AppsUseLightTheme");
|
||||
return setting.second && setting.first == 0 ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
|
||||
QWinRegistryKey personalizeKey{
|
||||
HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Themes\Personalize)"
|
||||
};
|
||||
const bool useDarkTheme = personalizeKey.value<DWORD>(L"AppsUseLightTheme") == 0;
|
||||
return useDarkTheme ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
|
||||
}
|
||||
|
||||
bool QWindowsTheme::queryHighContrast()
|
||||
|
@ -1401,10 +1401,12 @@ void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
|
||||
const HWND newParent = newParentWindow ? reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(nullptr);
|
||||
const bool isTopLevel = !newParent;
|
||||
const DWORD oldStyle = style();
|
||||
|
||||
qCDebug(lcQpaWindow) << __FUNCTION__ << window() << "newParent="
|
||||
<< 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;
|
||||
if (isTopLevel) {
|
||||
newStyle = m_topLevelStyle;
|
||||
@ -1414,6 +1416,20 @@ void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
|
||||
newStyle |= WS_CHILD;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
@ -2518,20 +2528,7 @@ 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() };
|
||||
}
|
||||
correctWindowPlacement(windowPlacement);
|
||||
|
||||
// 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
|
||||
@ -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()
|
||||
{
|
||||
m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
|
||||
@ -2707,8 +2763,24 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
|
||||
setFlag(WithinMaximize);
|
||||
if (newState & Qt::WindowFullScreen)
|
||||
setFlag(MaximizeToFullScreen);
|
||||
ShowWindow(m_data.hwnd,
|
||||
(newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
|
||||
if (m_data.flags & Qt::FramelessWindowHint) {
|
||||
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(MaximizeToFullScreen);
|
||||
} else if (visible && (oldState & newState & Qt::WindowMinimized)) {
|
||||
|
Reference in New Issue
Block a user