diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowscontext.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.cpp | 356 |
1 files changed, 181 insertions, 175 deletions
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index ae4128d073..c363b85cb3 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -11,7 +11,7 @@ #include "qwindowspointerhandler.h" #include "qtwindowsglobal.h" #include "qwindowsmenu.h" -#include "qwindowsmime.h" +#include "qwindowsmimeregistry.h" #include "qwindowsinputcontext.h" #if QT_CONFIG(tabletevent) # include "qwindowstabletsupport.h" @@ -45,13 +45,17 @@ #include <QtCore/qscopedpointer.h> #include <QtCore/quuid.h> #include <QtCore/private/qwinregistry_p.h> +#if QT_CONFIG(cpp_winrt) +# include <QtCore/private/qfactorycacheregistration_p.h> +#endif +#include <QtCore/private/qsystemerror_p.h> #include <QtGui/private/qwindowsguieventdispatcher_p.h> +#include <QtGui/private/qwindowsthemecache_p.h> #include <stdlib.h> #include <stdio.h> #include <windowsx.h> -#include <comdef.h> #include <dbt.h> #include <wtsapi32.h> #include <shellscalingapi.h> @@ -60,7 +64,7 @@ QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; -Q_LOGGING_CATEGORY(lcQpaWindows, "qt.qpa.windows") +Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window") Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events") Q_LOGGING_CATEGORY(lcQpaGl, "qt.qpa.gl") Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime") @@ -71,6 +75,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet") Q_LOGGING_CATEGORY(lcQpaAccessibility, "qt.qpa.accessibility") Q_LOGGING_CATEGORY(lcQpaUiAutomation, "qt.qpa.uiautomation") Q_LOGGING_CATEGORY(lcQpaTrayIcon, "qt.qpa.trayicon") +Q_LOGGING_CATEGORY(lcQpaScreen, "qt.qpa.screen") int QWindowsContext::verbose = 0; @@ -116,26 +121,6 @@ static inline bool sessionManagerInteractionBlocked() static inline bool sessionManagerInteractionBlocked() { return false; } #endif -static inline int windowDpiAwareness(HWND hwnd) -{ - return static_cast<int>(GetAwarenessFromDpiAwarenessContext(GetWindowDpiAwarenessContext(hwnd))); -} - -// Note: This only works within WM_NCCREATE -static bool enableNonClientDpiScaling(HWND hwnd) -{ - bool result = false; - if (windowDpiAwareness(hwnd) == 2) { - result = EnableNonClientDpiScaling(hwnd) != FALSE; - if (!result) { - const DWORD errorCode = GetLastError(); - qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)", - hwnd, errorCode); - } - } - return result; -} - QWindowsContext *QWindowsContext::m_instance = nullptr; /*! @@ -158,7 +143,7 @@ struct QWindowsContextPrivate { QWindowsKeyMapper m_keyMapper; QWindowsMouseHandler m_mouseHandler; QWindowsPointerHandler m_pointerHandler; - QWindowsMimeConverter m_mimeConverter; + QWindowsMimeRegistry m_mimeConverter; QWindowsScreenManager m_screenManager; QSharedPointer<QWindowCreationContext> m_creationContext; #if QT_CONFIG(tabletevent) @@ -190,7 +175,7 @@ QWindowsContextPrivate::QWindowsContextPrivate() m_darkMode = QWindowsTheme::queryDarkMode(); if (FAILED(m_oleInitializeResult)) { qWarning() << "QWindowsContext: OleInitialize() failed: " - << QWindowsContext::comErrorString(m_oleInitializeResult); + << QSystemError::windowsComString(m_oleInitializeResult); } } @@ -220,8 +205,12 @@ QWindowsContext::~QWindowsContext() DestroyWindow(d->m_powerDummyWindow); unregisterWindowClasses(); - if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) + if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) { +#ifdef QT_USE_FACTORY_CACHE_REGISTRATION + detail::QWinRTFactoryCacheRegistration::clearAllCaches(); +#endif OleUninitialize(); + } d->m_screenManager.clearScreens(); // Order: Potentially calls back to the windows. if (d->m_displayContext) @@ -263,7 +252,7 @@ void QWindowsContext::registerTouchWindows() { if (QGuiApplicationPrivate::is_app_running && (d->m_systemInfo & QWindowsContext::SI_SupportsTouch) != 0) { - for (QWindowsWindow *w : qAsConst(d->m_windows)) + for (QWindowsWindow *w : std::as_const(d->m_windows)) w->registerTouchWindow(); } } @@ -360,43 +349,119 @@ void QWindowsContext::setDetectAltGrModifier(bool a) d->m_keyMapper.setDetectAltGrModifier(a); } -int QWindowsContext::processDpiAwareness() -{ - PROCESS_DPI_AWARENESS result; - if (SUCCEEDED(GetProcessDpiAwareness(nullptr, &result))) { - return static_cast<int>(result); +[[nodiscard]] static inline QtWindows::DpiAwareness + dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT context) +{ + // IsValidDpiAwarenessContext() will handle the NULL pointer case. + if (!IsValidDpiAwarenessContext(context)) + return QtWindows::DpiAwareness::Invalid; + if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED)) + return QtWindows::DpiAwareness::Unaware_GdiScaled; + if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) + return QtWindows::DpiAwareness::PerMonitorVersion2; + if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) + return QtWindows::DpiAwareness::PerMonitor; + if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)) + return QtWindows::DpiAwareness::System; + if (AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE)) + return QtWindows::DpiAwareness::Unaware; + return QtWindows::DpiAwareness::Invalid; +} + +QtWindows::DpiAwareness QWindowsContext::windowDpiAwareness(HWND hwnd) +{ + if (!hwnd) + return QtWindows::DpiAwareness::Invalid; + const auto context = GetWindowDpiAwarenessContext(hwnd); + return dpiAwarenessContextToQtDpiAwareness(context); +} + +QtWindows::DpiAwareness QWindowsContext::processDpiAwareness() +{ + // Although we have GetDpiAwarenessContextForProcess(), however, + // it's only available on Win10 1903+, which is a little higher + // than Qt's minimum supported version (1809), so we can't use it. + // Luckily, MS docs said GetThreadDpiAwarenessContext() will also + // return the default DPI_AWARENESS_CONTEXT for the process if + // SetThreadDpiAwarenessContext() was never called. So we can use + // it as an equivalent. + const auto context = GetThreadDpiAwarenessContext(); + return dpiAwarenessContextToQtDpiAwareness(context); +} + +[[nodiscard]] static inline DPI_AWARENESS_CONTEXT + qtDpiAwarenessToDpiAwarenessContext(QtWindows::DpiAwareness dpiAwareness) +{ + switch (dpiAwareness) { + case QtWindows::DpiAwareness::Invalid: + return nullptr; + case QtWindows::DpiAwareness::Unaware: + return DPI_AWARENESS_CONTEXT_UNAWARE; + case QtWindows::DpiAwareness::System: + return DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; + case QtWindows::DpiAwareness::PerMonitor: + return DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE; + case QtWindows::DpiAwareness::PerMonitorVersion2: + return DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2; + case QtWindows::DpiAwareness::Unaware_GdiScaled: + return DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED; } - return -1; + return nullptr; } -void QWindowsContext::setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness) +#ifndef QT_NO_DEBUG_STREAM +QDebug operator<<(QDebug d, QtWindows::DpiAwareness dpiAwareness) { - qCDebug(lcQpaWindows) << __FUNCTION__ << dpiAwareness; - const HRESULT hr = SetProcessDpiAwareness(static_cast<PROCESS_DPI_AWARENESS>(dpiAwareness)); - // E_ACCESSDENIED means set externally (MSVC manifest or external app loading Qt plugin). - // Silence warning in that case unless debug is enabled. - if (FAILED(hr) && (hr != E_ACCESSDENIED || lcQpaWindows().isDebugEnabled())) { - qWarning().noquote().nospace() << "SetProcessDpiAwareness(" - << dpiAwareness << ") failed: " << QWindowsContext::comErrorString(hr) - << ", using " << QWindowsContext::processDpiAwareness(); + const QDebugStateSaver saver(d); + QString message = u"QtWindows::DpiAwareness::"_s; + switch (dpiAwareness) { + case QtWindows::DpiAwareness::Invalid: + message += u"Invalid"_s; + break; + case QtWindows::DpiAwareness::Unaware: + message += u"Unaware"_s; + break; + case QtWindows::DpiAwareness::System: + message += u"System"_s; + break; + case QtWindows::DpiAwareness::PerMonitor: + message += u"PerMonitor"_s; + break; + case QtWindows::DpiAwareness::PerMonitorVersion2: + message += u"PerMonitorVersion2"_s; + break; + case QtWindows::DpiAwareness::Unaware_GdiScaled: + message += u"Unaware_GdiScaled"_s; + break; } + d.nospace().noquote() << message; + return d; } +#endif -void QWindowsContext::setProcessDpiV2Awareness() +bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwareness) { - qCDebug(lcQpaWindows) << __FUNCTION__; - const BOOL ok = SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - if (ok) { - QWindowsContextPrivate::m_v2DpiAware = true; - } else { - const HRESULT errorCode = GetLastError(); - // ERROR_ACCESS_DENIED means set externally (MSVC manifest or external app loading Qt plugin). - // Silence warning in that case unless debug is enabled. - if (errorCode != ERROR_ACCESS_DENIED || lcQpaWindows().isDebugEnabled()) { - qWarning().noquote().nospace() << "setProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) failed: " - << QWindowsContext::comErrorString(errorCode); - } + qCDebug(lcQpaWindow) << __FUNCTION__ << dpiAwareness; + if (processDpiAwareness() == dpiAwareness) + return true; + const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness); + if (!IsValidDpiAwarenessContext(context)) { + qCWarning(lcQpaWindow) << dpiAwareness << "is not supported by current system."; + return false; + } + if (!SetProcessDpiAwarenessContext(context)) { + qCWarning(lcQpaWindow).noquote().nospace() + << "SetProcessDpiAwarenessContext() failed: " + << QSystemError::windowsString() + << "\nQt's default DPI awareness context is " + << "DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you " + << "are doing, you can overwrite this default using qt.conf " + << "(https://doc.qt.io/qt-6/highdpi.html#configuring-windows)."; + return false; } + QWindowsContextPrivate::m_v2DpiAware + = processDpiAwareness() == QtWindows::DpiAwareness::PerMonitorVersion2; + return true; } bool QWindowsContext::isDarkMode() @@ -419,9 +484,9 @@ bool QWindowsContext::useRTLExtensions() const return d->m_keyMapper.useRTLExtensions(); } -QList<int> QWindowsContext::possibleKeys(const QKeyEvent *e) const +QPlatformKeyMapper *QWindowsContext::keyMapper() const { - return d->m_keyMapper.possibleKeys(e); + return &d->m_keyMapper; } QWindowsContext::HandleBaseWindowHash &QWindowsContext::windows() @@ -473,6 +538,8 @@ QString QWindowsContext::classNamePrefix() # define xstr(s) str(s) # define str(s) #s str << xstr(QT_NAMESPACE); +# undef str +# undef xstr #endif } return result; @@ -533,7 +600,7 @@ QString QWindowsContext::registerWindowClass(const QWindow *w) if (icon) cname += "Icon"_L1; - return registerWindowClass(cname, qWindowsWndProc, style, GetSysColorBrush(COLOR_WINDOW), icon); + return registerWindowClass(cname, qWindowsWndProc, style, nullptr, icon); } QString QWindowsContext::registerWindowClass(QString cname, @@ -592,7 +659,7 @@ QString QWindowsContext::registerWindowClass(QString cname, qPrintable(cname)); d->m_registeredWindowClassNames.insert(cname); - qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname + qCDebug(lcQpaWindow).nospace() << __FUNCTION__ << ' ' << cname << " style=0x" << Qt::hex << style << Qt::dec << " brush=" << brush << " icon=" << icon << " atom=" << atom; return cname; @@ -602,7 +669,7 @@ void QWindowsContext::unregisterWindowClasses() { const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr)); - for (const QString &name : qAsConst(d->m_registeredWindowClassNames)) { + for (const QString &name : std::as_const(d->m_registeredWindowClassNames)) { if (!UnregisterClass(reinterpret_cast<LPCWSTR>(name.utf16()), appInstance) && QWindowsContext::verbose) qErrnoWarning("UnregisterClass failed for '%s'", qPrintable(name)); } @@ -614,23 +681,6 @@ int QWindowsContext::screenDepth() const return GetDeviceCaps(d->m_displayContext, BITSPIXEL); } -QString QWindowsContext::windowsErrorMessage(unsigned long errorCode) -{ - QString rc = QString::fromLatin1("#%1: ").arg(errorCode); - char16_t *lpMsgBuf; - - const DWORD len = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, errorCode, 0, reinterpret_cast<LPTSTR>(&lpMsgBuf), 0, nullptr); - if (len) { - rc = QString::fromUtf16(lpMsgBuf, int(len)); - LocalFree(lpMsgBuf); - } else { - rc += QString::fromLatin1("<unknown error>"); - } - return rc; -} - void QWindowsContext::addWindow(HWND hwnd, QWindowsWindow *w) { d->m_windows.insert(hwnd, w); @@ -734,6 +784,8 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c if (!(cwexFlags & CWP_SKIPTRANSPARENT) && (GetWindowLongPtr(child, GWL_EXSTYLE) & WS_EX_TRANSPARENT)) { const HWND nonTransparentChild = ChildWindowFromPointEx(*hwnd, point, cwexFlags | CWP_SKIPTRANSPARENT); + if (!nonTransparentChild || nonTransparentChild == *hwnd) + return false; if (QWindowsWindow *nonTransparentWindow = context->findPlatformWindow(nonTransparentChild)) { *result = nonTransparentWindow; *hwnd = nonTransparentChild; @@ -791,7 +843,7 @@ bool QWindowsContext::isSessionLocked() return result; } -QWindowsMimeConverter &QWindowsContext::mimeConverter() const +QWindowsMimeRegistry &QWindowsContext::mimeConverter() const { return d->m_mimeConverter; } @@ -829,79 +881,6 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, HWND_MESSAGE, nullptr, static_cast<HINSTANCE>(GetModuleHandle(nullptr)), nullptr); } -/*! - \brief Common COM error strings. -*/ - -QByteArray QWindowsContext::comErrorString(HRESULT hr) -{ - QByteArray result = QByteArrayLiteral("COM error 0x") - + QByteArray::number(quintptr(hr), 16) + ' '; - switch (hr) { - case S_OK: - result += QByteArrayLiteral("S_OK"); - break; - case S_FALSE: - result += QByteArrayLiteral("S_FALSE"); - break; - case E_UNEXPECTED: - result += QByteArrayLiteral("E_UNEXPECTED"); - break; - case E_ACCESSDENIED: - result += QByteArrayLiteral("E_ACCESSDENIED"); - break; - case CO_E_ALREADYINITIALIZED: - result += QByteArrayLiteral("CO_E_ALREADYINITIALIZED"); - break; - case CO_E_NOTINITIALIZED: - result += QByteArrayLiteral("CO_E_NOTINITIALIZED"); - break; - case RPC_E_CHANGED_MODE: - result += QByteArrayLiteral("RPC_E_CHANGED_MODE"); - break; - case OLE_E_WRONGCOMPOBJ: - result += QByteArrayLiteral("OLE_E_WRONGCOMPOBJ"); - break; - case CO_E_NOT_SUPPORTED: - result += QByteArrayLiteral("CO_E_NOT_SUPPORTED"); - break; - case E_NOTIMPL: - result += QByteArrayLiteral("E_NOTIMPL"); - break; - case E_INVALIDARG: - result += QByteArrayLiteral("E_INVALIDARG"); - break; - case E_NOINTERFACE: - result += QByteArrayLiteral("E_NOINTERFACE"); - break; - case E_POINTER: - result += QByteArrayLiteral("E_POINTER"); - break; - case E_HANDLE: - result += QByteArrayLiteral("E_HANDLE"); - break; - case E_ABORT: - result += QByteArrayLiteral("E_ABORT"); - break; - case E_FAIL: - result += QByteArrayLiteral("E_FAIL"); - break; - case RPC_E_WRONG_THREAD: - result += QByteArrayLiteral("RPC_E_WRONG_THREAD"); - break; - case RPC_E_THREAD_NOT_INIT: - result += QByteArrayLiteral("RPC_E_THREAD_NOT_INIT"); - break; - default: - break; - } - _com_error error(hr); - result += QByteArrayLiteral(" ("); - result += QString::fromWCharArray(error.ErrorMessage()).toUtf8(); - result += ')'; - return result; -} - void QWindowsContext::forceNcCalcSize(HWND hwnd) { // Force WM_NCCALCSIZE to adjust margin @@ -996,6 +975,21 @@ static inline bool isInputMessage(UINT m) || (m >= WM_KEYFIRST && m <= WM_KEYLAST); } +// Note: This only works within WM_NCCREATE +static bool enableNonClientDpiScaling(HWND hwnd) +{ + bool result = false; + if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) { + result = EnableNonClientDpiScaling(hwnd) != FALSE; + if (!result) { + const DWORD errorCode = GetLastError(); + qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)", + hwnd, errorCode); + } + } + return result; +} + /*! \brief Main windows procedure registered for windows. @@ -1093,29 +1087,25 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, #else return false; #endif - case QtWindows::DisplayChangedEvent: - if (QWindowsTheme *t = QWindowsTheme::instance()) - t->displayChanged(); - QWindowsWindow::displayChanged(); - d->m_screenManager.handleScreenChanges(); - return false; case QtWindows::SettingChangedEvent: { QWindowsWindow::settingsChanged(); // Only refresh the window theme if the user changes the personalize settings. if ((wParam == 0) && (lParam != 0) // lParam sometimes may be NULL. && (wcscmp(reinterpret_cast<LPCWSTR>(lParam), L"ImmersiveColorSet") == 0)) { const bool darkMode = QWindowsTheme::queryDarkMode(); - if (darkMode != QWindowsContextPrivate::m_darkMode) { - QWindowsContextPrivate::m_darkMode = darkMode; - auto integration = QWindowsIntegration::instance(); + const bool darkModeChanged = darkMode != QWindowsContextPrivate::m_darkMode; + QWindowsContextPrivate::m_darkMode = darkMode; + auto integration = QWindowsIntegration::instance(); + integration->updateApplicationBadge(); + if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) { + QWindowsTheme::instance()->refresh(); + QWindowSystemInterface::handleThemeChange(); + } + if (darkModeChanged) { if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames)) { for (QWindowsWindow *w : d->m_windows) w->setDarkBorder(QWindowsContextPrivate::m_darkMode); } - if (integration->darkModeHandling().testFlag(QWindowsApplication::DarkModeStyle)) { - QWindowsTheme::instance()->refresh(); - QWindowSystemInterface::handleThemeChange(); - } } } return d->m_screenManager.handleScreenChanges(); @@ -1133,7 +1123,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, d->m_creationContext->applyToMinMaxInfo(reinterpret_cast<MINMAXINFO *>(lParam)); return true; case QtWindows::ResizeEvent: - d->m_creationContext->obtainedSize = QSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + d->m_creationContext->obtainedSize = QSize(LOWORD(lParam), HIWORD(lParam)); return true; case QtWindows::MoveEvent: d->m_creationContext->obtainedPos = QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); @@ -1176,7 +1166,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, if (wParam == DBT_DEVNODES_CHANGED) initTouch(); break; - case QtWindows::KeyboardLayoutChangeEvent: + case QtWindows::InputLanguageChangeEvent: if (QWindowsInputContext *wic = windowsInputContext()) wic->handleInputLanguageChanged(wParam, lParam); Q_FALLTHROUGH(); @@ -1206,7 +1196,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, platformWindow->handleMoved(); return true; case QtWindows::ResizeEvent: - platformWindow->handleResized(static_cast<int>(wParam)); + platformWindow->handleResized(static_cast<int>(wParam), lParam); return true; case QtWindows::QuerySizeHints: platformWindow->getSizeHints(reinterpret_cast<MINMAXINFO *>(lParam)); @@ -1220,21 +1210,29 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::ExposeEvent: return platformWindow->handleWmPaint(hwnd, message, wParam, lParam, result); case QtWindows::NonClientMouseEvent: - if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled()) + if (!platformWindow->frameStrutEventsEnabled()) + break; + if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer)) return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); else return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); case QtWindows::NonClientPointerEvent: - if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer) && platformWindow->frameStrutEventsEnabled()) + if (!platformWindow->frameStrutEventsEnabled()) + break; + if ((d->m_systemInfo & QWindowsContext::SI_SupportsPointer)) return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result); break; case QtWindows::EnterSizeMoveEvent: platformWindow->setFlag(QWindowsWindow::ResizeMoveActive); + if (!IsZoomed(hwnd)) + platformWindow->updateRestoreGeometry(); return true; case QtWindows::ExitSizeMoveEvent: platformWindow->clearFlag(QWindowsWindow::ResizeMoveActive); platformWindow->checkForScreenChanged(); handleExitSizeMove(platformWindow->window()); + if (!IsZoomed(hwnd)) + platformWindow->updateRestoreGeometry(); return true; case QtWindows::ScrollEvent: if (!(d->m_systemInfo & QWindowsContext::SI_SupportsPointer)) @@ -1280,6 +1278,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, QWindowSystemInterface::handleCloseEvent(platformWindow->window()); return true; case QtWindows::ThemeChanged: { + QWindowsThemeCache::clearThemeCache(platformWindow->handle()); // Switch from Aero to Classic changes margins. if (QWindowsTheme *theme = QWindowsTheme::instance()) theme->windowsThemeChanged(platformWindow->window()); @@ -1327,6 +1326,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::DpiChangedEvent: platformWindow->handleDpiChanged(hwnd, wParam, lParam); return true; + case QtWindows::DpiChangedAfterParentEvent: + platformWindow->handleDpiChangedAfterParent(hwnd); + return true; #if QT_CONFIG(sessionmanager) case QtWindows::QueryEndSessionApplicationEvent: { QWindowsSessionManager *sessionManager = platformSessionManager(); @@ -1368,6 +1370,11 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return true; } #endif // !defined(QT_NO_SESSIONMANAGER) + case QtWindows::TaskbarButtonCreated: + // Apply application badge if this is the first time we have a taskbar + // button, or after Explorer restart. + QWindowsIntegration::instance()->updateApplicationBadge(); + break; default: break; } @@ -1410,7 +1417,7 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et, } if (nextActiveWindow != d->m_lastActiveWindow) { d->m_lastActiveWindow = nextActiveWindow; - QWindowSystemInterface::handleWindowActivated(nextActiveWindow, Qt::ActiveWindowFocusReason); + QWindowSystemInterface::handleFocusWindowChanged(nextActiveWindow, Qt::ActiveWindowFocusReason); } } @@ -1440,7 +1447,7 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg) } QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos, - QWindowsKeyMapper::queryKeyboardModifiers()); + keyMapper()->queryKeyboardModifiers()); return true; } #endif @@ -1461,7 +1468,7 @@ void QWindowsContext::handleExitSizeMove(QWindow *window) const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons(); if (currentButtons == appButtons) return; - const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); + const Qt::KeyboardModifiers keyboardModifiers = keyMapper()->queryKeyboardModifiers(); const QPoint globalPos = QWindowsCursor::mousePosition(); const QPlatformWindow *platWin = window->handle(); const QPoint localPos = platWin->mapFromGlobal(globalPos); @@ -1470,8 +1477,7 @@ void QWindowsContext::handleExitSizeMove(QWindow *window) for (Qt::MouseButton button : {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}) { if (appButtons.testFlag(button) && !currentButtons.testFlag(button)) { QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos, - currentButtons, button, type, - keyboardModifiers); + currentButtons, button, type, keyboardModifiers); } } if (d->m_systemInfo & QWindowsContext::SI_SupportsPointer) @@ -1565,7 +1571,7 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0)); if (margins.left() >= 0) { if (platformWindow) { - qCDebug(lcQpaWindows) << __FUNCTION__ << "WM_NCCALCSIZE for" << hwnd << margins; + qCDebug(lcQpaWindow) << __FUNCTION__ << "WM_NCCALCSIZE for" << hwnd << margins; platformWindow->setFullFrameMargins(margins); } else { const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext(); |