diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowscontext.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowscontext.cpp | 135 |
1 files changed, 78 insertions, 57 deletions
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index cda6c99ad0..c146f8ec25 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -44,6 +44,7 @@ #include "qwindowskeymapper.h" #include "qwindowsmousehandler.h" #include "qtwindowsglobal.h" +#include "qwindowsmenu.h" #include "qwindowsmime.h" #include "qwindowsinputcontext.h" #if QT_CONFIG(tabletevent) @@ -52,7 +53,7 @@ #include "qwindowstheme.h" #include <private/qguiapplication_p.h> #ifndef QT_NO_ACCESSIBILITY -# include "accessible/qwindowsaccessibility.h" +# include "uiautomation/qwindowsuiaaccessibility.h" #endif #if QT_CONFIG(sessionmanager) # include <private/qsessionmanager_p.h> @@ -94,8 +95,11 @@ Q_LOGGING_CATEGORY(lcQpaGl, "qt.qpa.gl") Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime") Q_LOGGING_CATEGORY(lcQpaInputMethods, "qt.qpa.input.methods") Q_LOGGING_CATEGORY(lcQpaDialogs, "qt.qpa.dialogs") +Q_LOGGING_CATEGORY(lcQpaMenus, "qt.qpa.menus") 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") int QWindowsContext::verbose = 0; @@ -126,11 +130,19 @@ static inline bool useRTL_Extensions() } #if QT_CONFIG(sessionmanager) -static inline QWindowsSessionManager *platformSessionManager() { +static inline QWindowsSessionManager *platformSessionManager() +{ QGuiApplicationPrivate *guiPrivate = static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp)); QSessionManagerPrivate *managerPrivate = static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(guiPrivate->session_manager)); return static_cast<QWindowsSessionManager *>(managerPrivate->platformSessionManager); } + +static inline bool sessionManagerInteractionBlocked() +{ + return platformSessionManager()->isInteractionBlocked(); +} +#else // QT_CONFIG(sessionmanager) +static inline bool sessionManagerInteractionBlocked() { return false; } #endif static inline int windowDpiAwareness(HWND hwnd) @@ -182,26 +194,14 @@ void QWindowsUser32DLL::init() getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences"); setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences"); - if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10) { // Appears in 10.0.14393, October 2016 + if (QOperatingSystemVersion::current() + >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 14393)) { enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling"); getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext"); getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext"); } } -bool QWindowsUser32DLL::initTouch() -{ - if (!isTouchWindow && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) { - QSystemLibrary library(QStringLiteral("user32")); - isTouchWindow = (IsTouchWindow)(library.resolve("IsTouchWindow")); - registerTouchWindow = (RegisterTouchWindow)(library.resolve("RegisterTouchWindow")); - unregisterTouchWindow = (UnregisterTouchWindow)(library.resolve("UnregisterTouchWindow")); - getTouchInputInfo = (GetTouchInputInfo)(library.resolve("GetTouchInputInfo")); - closeTouchInputHandle = (CloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); - } - return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle; -} - void QWindowsShcoreDLL::init() { if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1) @@ -258,7 +258,7 @@ QWindowsContextPrivate::QWindowsContextPrivate() QWindowsContext::user32dll.init(); QWindowsContext::shcoredll.init(); - if (m_mouseHandler.touchDevice() && QWindowsContext::user32dll.initTouch()) + if (m_mouseHandler.touchDevice()) m_systemInfo |= QWindowsContext::SI_SupportsTouch; m_displayContext = GetDC(0); m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY); @@ -316,11 +316,6 @@ bool QWindowsContext::initTouch(unsigned integrationOptions) if (!touchDevice) return false; - if (!QWindowsContext::user32dll.initTouch()) { - delete touchDevice; - return false; - } - if (!(integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) touchDevice->setCapabilities(touchDevice->capabilities() | QTouchDevice::MouseEmulation); @@ -397,9 +392,11 @@ QList<int> QWindowsContext::possibleKeys(const QKeyEvent *e) const return d->m_keyMapper.possibleKeys(e); } -void QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx) +QSharedPointer<QWindowCreationContext> QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx) { + const QSharedPointer<QWindowCreationContext> old = d->m_creationContext; d->m_creationContext = ctx; + return old; } QSharedPointer<QWindowCreationContext> QWindowsContext::windowCreationContext() const @@ -441,7 +438,7 @@ QString QWindowsContext::registerWindowClass(const QWindow *w) // QOpenGLWidget or QQuickWidget later on. That cannot be detected at this stage. if (w->surfaceType() == QSurface::OpenGLSurface || (flags & Qt::MSWindowsOwnDC)) style |= CS_OWNDC; - if (!(flags & Qt::NoDropShadowWindowHint) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) + if (!(flags & Qt::NoDropShadowWindowHint) && (type == Qt::Popup || w->property("_q_windowsDropShadow").toBool())) { style |= CS_DROPSHADOW; } @@ -597,6 +594,15 @@ void QWindowsContext::removeWindow(HWND hwnd) } } +QWindowsWindow *QWindowsContext::findPlatformWindow(const QWindowsMenuBar *mb) const +{ + for (auto it = d->m_windows.cbegin(), end = d->m_windows.cend(); it != end; ++it) { + if ((*it)->menuBar() == mb) + return *it; + } + return nullptr; +} + QWindowsWindow *QWindowsContext::findPlatformWindow(HWND hwnd) const { return d->m_windows.value(hwnd); @@ -735,7 +741,7 @@ HWND QWindowsContext::createDummyWindow(const QString &classNameIn, // present in the MSVCRT.DLL found on Windows XP (QTBUG-35617). static inline QString errorMessageFromComError(const _com_error &comError) { - TCHAR *message = Q_NULLPTR; + TCHAR *message = nullptr; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, DWORD(comError.Error()), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), message, 0, NULL); @@ -850,7 +856,7 @@ static inline bool resizeOnDpiChanged(const QWindow *w) static bool shouldHaveNonClientDpiScaling(const QWindow *window) { - return QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10 + return QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10 && window->isTopLevel() && !window->property(QWindowsWindow::embeddedNativeParentHandleProperty).isValid() #if QT_CONFIG(opengl) // /QTBUG-62901, EnableNonClientDpiScaling has problems with GL @@ -934,11 +940,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, switch (et) { case QtWindows::GestureEvent: -#if QT_CONFIG(sessionmanager) - return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateGestureEvent(platformWindow->window(), hwnd, et, msg, result); -#else - return d->m_mouseHandler.translateGestureEvent(platformWindow->window(), hwnd, et, msg, result); -#endif + return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateGestureEvent(platformWindow->window(), hwnd, et, msg, result); case QtWindows::InputMethodOpenCandidateWindowEvent: case QtWindows::InputMethodCloseCandidateWindowEvent: // TODO: Release/regrab mouse if a popup has mouse grab. @@ -956,7 +958,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return false; case QtWindows::AccessibleObjectFromWindowRequest: #ifndef QT_NO_ACCESSIBILITY - return QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(hwnd, wParam, lParam, result); + return QWindowsUiaAccessibility::handleWmGetObject(hwnd, wParam, lParam, result); #else return false; #endif @@ -1027,11 +1029,23 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, case QtWindows::InputMethodKeyEvent: case QtWindows::InputMethodKeyDownEvent: case QtWindows::AppCommandEvent: -#if QT_CONFIG(sessionmanager) - return platformSessionManager()->isInteractionBlocked() ? true : d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); -#else - return d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); -#endif + return sessionManagerInteractionBlocked() || d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result); + case QtWindows::MenuAboutToShowEvent: + if (sessionManagerInteractionBlocked()) + return true; + if (QWindowsPopupMenu::notifyAboutToShow(reinterpret_cast<HMENU>(wParam))) + return true; + if (platformWindow == nullptr || platformWindow->menuBar() == nullptr) + return false; + return platformWindow->menuBar()->notifyAboutToShow(reinterpret_cast<HMENU>(wParam)); + case QtWindows::MenuCommandEvent: + if (sessionManagerInteractionBlocked()) + return true; + if (QWindowsPopupMenu::notifyTriggered(LOWORD(wParam))) + return true; + if (platformWindow == nullptr || platformWindow->menuBar() == nullptr) + return false; + return platformWindow->menuBar()->notifyTriggered(LOWORD(wParam)); case QtWindows::MoveEvent: platformWindow->handleMoved(); return true; @@ -1051,11 +1065,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, return platformWindow->handleWmPaint(hwnd, message, wParam, lParam); case QtWindows::NonClientMouseEvent: if (platformWindow->frameStrutEventsEnabled()) -#if QT_CONFIG(sessionmanager) - return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); -#else - return d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); -#endif + return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result); break; case QtWindows::EnterSizeMoveEvent: platformWindow->setFlag(QWindowsWindow::ResizeMoveActive); @@ -1065,11 +1075,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, platformWindow->checkForScreenChanged(); return true; case QtWindows::ScrollEvent: -#if QT_CONFIG(sessionmanager) - return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result); -#else - return d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result); -#endif + return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateScrollEvent(platformWindow->window(), hwnd, msg, result); case QtWindows::MouseWheelEvent: case QtWindows::MouseEvent: case QtWindows::LeaveEvent: @@ -1079,18 +1085,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message, window = window->parent(); if (!window) return false; -#if QT_CONFIG(sessionmanager) - return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result); -#else - return d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result); -#endif + return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateMouseEvent(window, hwnd, et, msg, result); } case QtWindows::TouchEvent: -#if QT_CONFIG(sessionmanager) - return platformSessionManager()->isInteractionBlocked() ? true : d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); -#else - return d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); -#endif + return sessionManagerInteractionBlocked() || d->m_mouseHandler.translateTouchEvent(platformWindow->window(), hwnd, et, msg, result); case QtWindows::FocusInEvent: // see QWindowsWindow::requestActivateWindow(). case QtWindows::FocusOutEvent: handleFocusEvent(et, platformWindow); @@ -1292,6 +1290,29 @@ QTouchDevice *QWindowsContext::touchDevice() const return d->m_mouseHandler.touchDevice(); } +static DWORD readDwordRegistrySetting(const wchar_t *regKey, const wchar_t *subKey, DWORD defaultValue) +{ + DWORD result = defaultValue; + HKEY handle; + if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &handle) == ERROR_SUCCESS) { + DWORD type; + if (RegQueryValueEx(handle, subKey, 0, &type, 0, 0) == ERROR_SUCCESS && type == REG_DWORD) { + DWORD value; + DWORD size = sizeof(result); + if (RegQueryValueEx(handle, subKey, 0, 0, reinterpret_cast<unsigned char *>(&value), &size) == ERROR_SUCCESS) + result = value; + } + RegCloseKey(handle); + } + return result; +} + +DWORD QWindowsContext::readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue) +{ + return readDwordRegistrySetting(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced", + subKey, defaultValue); +} + static inline bool isEmptyRect(const RECT &rect) { return rect.right - rect.left == 0 && rect.bottom - rect.top == 0; |