15#if QT_CONFIG(tabletevent)
16# include "qwindowstabletsupport.h"
19#include <private/qguiapplication_p.h>
20#if QT_CONFIG(accessibility)
21# include "uiautomation/qwindowsuiaaccessibility.h"
23#if QT_CONFIG(sessionmanager)
24# include <private/qsessionmanager_p.h>
25# include "qwindowssessionmanager.h"
30#include <QtGui/qwindow.h>
31#include <qpa/qwindowsysteminterface.h>
32#include <qpa/qwindowsysteminterface_p.h>
33#include <qpa/qplatformnativeinterface.h>
34#include <QtGui/qguiapplication.h>
35#include <QtGui/qopenglcontext.h>
36#include <QtGui/qpointingdevice.h>
38#include <QtCore/qset.h>
39#include <QtCore/qhash.h>
40#include <QtCore/qlibraryinfo.h>
41#include <QtCore/qstringlist.h>
42#include <QtCore/qdebug.h>
43#include <QtCore/qsysinfo.h>
44#include <QtCore/qscopedpointer.h>
45#include <QtCore/quuid.h>
46#include <QtCore/qscopeguard.h>
47#include <QtCore/private/qwinregistry_p.h>
48#if QT_CONFIG(cpp_winrt)
49# include <QtCore/private/qfactorycacheregistration_p.h>
51#include <QtCore/private/qsystemerror_p.h>
53#include <QtGui/private/qwindowsguieventdispatcher_p.h>
54#include <QtGui/private/qwindowsthemecache_p.h>
61#include <shellscalingapi.h>
65using namespace Qt::StringLiterals;
68Q_LOGGING_CATEGORY(lcQpaEvents,
"qt.qpa.events")
69Q_LOGGING_CATEGORY(lcQpaGl,
"qt.qpa.gl")
70Q_LOGGING_CATEGORY(lcQpaMime,
"qt.qpa.mime")
71Q_LOGGING_CATEGORY(lcQpaInputMethods,
"qt.qpa.input.methods")
72Q_LOGGING_CATEGORY(lcQpaDialogs,
"qt.qpa.dialogs")
73Q_LOGGING_CATEGORY(lcQpaMenus,
"qt.qpa.menus")
74Q_LOGGING_CATEGORY(lcQpaTablet,
"qt.qpa.input.tablet")
75Q_LOGGING_CATEGORY(lcQpaAccessibility,
"qt.qpa.accessibility")
76Q_LOGGING_CATEGORY(lcQpaUiAutomation,
"qt.qpa.uiautomation")
77Q_LOGGING_CATEGORY(lcQpaTrayIcon,
"qt.qpa.trayicon")
78Q_LOGGING_CATEGORY(lcQpaScreen,
"qt.qpa.screen")
79Q_LOGGING_CATEGORY(lcQpaTheme,
"qt.qpa.theme")
81int QWindowsContext::verbose = 0;
83#if !defined(LANG_SYRIAC)
84# define LANG_SYRIAC 0x5a
91 if (
const int nLayouts = GetKeyboardLayoutList(0,
nullptr)) {
92 QScopedArrayPointer<HKL> lpList(
new HKL[nLayouts]);
93 GetKeyboardLayoutList(nLayouts, lpList.data());
94 for (
int i = 0; i < nLayouts; ++i) {
95 switch (PRIMARYLANGID((quintptr)lpList[i])) {
109#if QT_CONFIG(sessionmanager)
110static inline QWindowsSessionManager *platformSessionManager()
112 auto *guiPrivate =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
113 auto *managerPrivate =
static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(guiPrivate->session_manager));
114 return static_cast<QWindowsSessionManager *>(managerPrivate->platformSessionManager);
117static inline bool sessionManagerInteractionBlocked()
119 return platformSessionManager()->isInteractionBlocked();
128
129
130
131
132
133
134
149#if QT_CONFIG(tabletevent)
165 if (m_pointerHandler.touchDevice())
167 m_displayContext = GetDC(
nullptr);
168 m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY);
171 m_keyMapper.setUseRTLExtensions(
true);
173 if (FAILED(m_oleInitializeResult)) {
174 qWarning() <<
"QWindowsContext: OleInitialize() failed: "
175 << QSystemError::windowsComString(m_oleInitializeResult);
187#if QT_CONFIG(tabletevent)
188 d->m_tabletSupport.reset();
191 if (d->m_powerNotification)
192 UnregisterPowerSettingNotification(d->m_powerNotification);
194 if (d->m_powerDummyWindow)
195 DestroyWindow(d->m_powerDummyWindow);
198 theme->destroyThemeChangeWindow();
200 d->m_screenManager.destroyWindow();
202 unregisterWindowClasses();
203 if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) {
204#ifdef QT_USE_FACTORY_CACHE_REGISTRATION
205 detail::QWinRTFactoryCacheRegistration::clearAllCaches();
210 d->m_screenManager.clearScreens();
211 if (d->m_displayContext)
212 ReleaseDC(
nullptr, d->m_displayContext);
213 m_instance =
nullptr;
223 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
225 auto touchDevice = d->m_pointerHandler.touchDevice();
226 if (touchDevice.isNull()) {
227 const bool mouseEmulation =
228 (integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) == 0;
229 touchDevice = QWindowsPointerHandler::createTouchDevice(mouseEmulation);
231 if (touchDevice.isNull())
233 d->m_pointerHandler.setTouchDevice(touchDevice);
234 QWindowSystemInterface::registerInputDevice(touchDevice.data());
236 d->m_systemInfo |= QWindowsContext::SI_SupportsTouch;
246 if (QGuiApplicationPrivate::is_app_running
247 && (d->m_systemInfo & QWindowsContext::SI_SupportsTouch) != 0) {
248 for (QWindowsWindow *w : std::as_const(d->m_windows))
249 w->registerTouchWindow();
255#if QT_CONFIG(tabletevent)
256 d->m_tabletSupport.reset(QWindowsTabletSupport::create());
265#if QT_CONFIG(tabletevent)
266 d->m_tabletSupport.reset();
273LRESULT QT_WIN_CALLBACK qWindowsPowerWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
275 if (message != WM_POWERBROADCAST || wParam != PBT_POWERSETTINGCHANGE)
276 return DefWindowProc(hwnd, message, wParam, lParam);
278 static bool initialized =
false;
281 return DefWindowProc(hwnd, message, wParam, lParam);
284 auto setting =
reinterpret_cast<
const POWERBROADCAST_SETTING *>(lParam);
286 auto data =
reinterpret_cast<
const DWORD *>(&setting->Data);
289 const auto tlw = QGuiApplication::topLevelWindows();
291 if (w->isVisible() && w->windowState() != Qt::WindowMinimized) {
292 if (
auto tw = QWindowsWindow::windowsWindowOf(w)) {
293 if (HWND hwnd = tw->handle()) {
294 InvalidateRect(hwnd,
nullptr,
false);
301 return DefWindowProc(hwnd, message, wParam, lParam);
306 if (d->m_powerNotification)
309 d->m_powerDummyWindow = createDummyWindow(QStringLiteral(
"PowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc);
310 if (!d->m_powerDummyWindow)
313 d->m_powerNotification = RegisterPowerSettingNotification(d->m_powerDummyWindow, &GUID_MONITOR_POWER_ON, DEVICE_NOTIFY_WINDOW_HANDLE);
314 if (!d->m_powerNotification) {
315 DestroyWindow(d->m_powerDummyWindow);
316 d->m_powerDummyWindow =
nullptr;
324#if QT_CONFIG(tabletevent)
325 QWindowsTabletSupport::setAbsoluteRange(a);
333 d->m_keyMapper.setDetectAltGrModifier(a);
340 if (!IsValidDpiAwarenessContext(context))
359 const auto context = GetWindowDpiAwarenessContext(hwnd);
360 return dpiAwarenessContextToQtDpiAwareness(context);
372 const auto context = GetThreadDpiAwarenessContext();
373 return dpiAwarenessContextToQtDpiAwareness(context);
379 switch (dpiAwareness) {
382 case QtWindows::DpiAwareness::Unaware:
384 case QtWindows::DpiAwareness::System:
386 case QtWindows::DpiAwareness::PerMonitor:
388 case QtWindows::DpiAwareness::PerMonitorVersion2:
390 case QtWindows::DpiAwareness::Unaware_GdiScaled:
396#ifndef QT_NO_DEBUG_STREAM
399 const QDebugStateSaver saver(d);
400 QString message = u"QtWindows::DpiAwareness::"_s;
401 switch (dpiAwareness) {
402 case QtWindows::DpiAwareness::Invalid:
403 message += u"Invalid"_s;
405 case QtWindows::DpiAwareness::Unaware:
406 message += u"Unaware"_s;
408 case QtWindows::DpiAwareness::System:
409 message += u"System"_s;
411 case QtWindows::DpiAwareness::PerMonitor:
412 message += u"PerMonitor"_s;
414 case QtWindows::DpiAwareness::PerMonitorVersion2:
415 message += u"PerMonitorVersion2"_s;
417 case QtWindows::DpiAwareness::Unaware_GdiScaled:
418 message += u"Unaware_GdiScaled"_s;
421 d.nospace().noquote() << message;
428 qCDebug(lcQpaWindow) <<
__FUNCTION__ << dpiAwareness;
429 [[maybe_unused]]
const auto updatePMv2Status = qScopeGuard([](){
435 const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness);
436 if (!IsValidDpiAwarenessContext(context)) {
437 qCWarning(lcQpaWindow) << dpiAwareness <<
"is not supported by current system.";
440 if (!SetProcessDpiAwarenessContext(context)) {
441 qCWarning(lcQpaWindow).noquote().nospace()
442 <<
"SetProcessDpiAwarenessContext() failed: "
443 << QSystemError::windowsString()
444 <<
"\nQt's default DPI awareness context is "
445 <<
"DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
446 <<
"are doing, you can overwrite this default using qt.conf "
447 <<
"(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
460 return d->m_systemInfo;
465 return d->m_keyMapper.useRTLExtensions();
470 return &d->m_keyMapper;
480 const QSharedPointer<QWindowCreationContext> old = d->m_creationContext;
481 d->m_creationContext = ctx;
487 return d->m_creationContext;
492 return d->m_defaultDPI;
497 return d->m_displayContext;
502 return d->m_keyMapper.keyGrabber();
507 d->m_keyMapper.setKeyGrabber(w);
512 static QString result;
513 if (result.isEmpty()) {
514 QTextStream str(&result);
515 str <<
"Qt" << QT_VERSION_MAJOR << QT_VERSION_MINOR << QT_VERSION_PATCH;
516 if (QLibraryInfo::isDebugBuild())
519# define xstr(s) str(s)
521 str << xstr(QT_NAMESPACE);
534 const Qt::WindowFlags flags = w->flags();
535 const Qt::WindowFlags type = flags & Qt::WindowType_Mask;
537 uint style = CS_DBLCLKS;
541 if (w->surfaceType() == QSurface::OpenGLSurface || (flags & Qt::MSWindowsOwnDC))
543 if (!(flags & Qt::NoDropShadowWindowHint)
544 && (type == Qt::Popup || w->property(
"_q_windowsDropShadow").toBool())) {
545 style |= CS_DROPSHADOW;
551 style |= CS_SAVEBITS;
555 if (!(flags & Qt::WindowSystemMenuHint))
560 QString cname = classNamePrefix();
561 cname +=
"QWindow"_L1;
567 cname +=
"ToolTip"_L1;
575 if (style & CS_DROPSHADOW)
576 cname +=
"DropShadow"_L1;
577 if (style & CS_SAVEBITS)
578 cname +=
"SaveBits"_L1;
579 if (style & CS_OWNDC)
584 return registerWindowClass(cname, qWindowsWndProc, style,
nullptr, icon);
600 const auto appInstance =
static_cast<HINSTANCE>(GetModuleHandle(
nullptr));
602 const bool classExists = GetClassInfo(appInstance,
reinterpret_cast<LPCWSTR>(cname.utf16()), &wcinfo) != FALSE
603 && wcinfo.lpfnWndProc != proc;
606 cname += QUuid::createUuid().toString();
608 if (d->m_registeredWindowClassNames.contains(cname))
612 wc.cbSize =
sizeof(WNDCLASSEX);
614 wc.lpfnWndProc = proc;
617 wc.hInstance = appInstance;
618 wc.hCursor =
nullptr;
619 wc.hbrBackground = brush;
621 wc.hIcon =
static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
623 int sw = GetSystemMetrics(SM_CXSMICON);
624 int sh = GetSystemMetrics(SM_CYSMICON);
625 wc.hIconSm =
static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0));
627 wc.hIcon =
static_cast<HICON>(LoadImage(
nullptr, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED));
628 wc.hIconSm =
nullptr;
632 wc.hIconSm =
nullptr;
635 wc.lpszMenuName =
nullptr;
636 wc.lpszClassName =
reinterpret_cast<LPCWSTR>(cname.utf16());
637 ATOM atom = RegisterClassEx(&wc);
639 qErrnoWarning(
"QApplication::regClass: Registering window class '%s' failed.",
642 d->m_registeredWindowClassNames.insert(cname);
643 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
' ' << cname
644 <<
" style=0x" << Qt::hex << style << Qt::dec
645 <<
" brush=" << brush <<
" icon=" << icon <<
" atom=" << atom;
651 const auto appInstance =
static_cast<HINSTANCE>(GetModuleHandle(
nullptr));
653 for (
const QString &name : std::as_const(d->m_registeredWindowClassNames)) {
654 if (!UnregisterClass(
reinterpret_cast<LPCWSTR>(name.utf16()), appInstance) && QWindowsContext::verbose)
655 qErrnoWarning(
"UnregisterClass failed for '%s'", qPrintable(name));
657 d->m_registeredWindowClassNames.clear();
662 return GetDeviceCaps(d->m_displayContext, BITSPIXEL);
667 d->m_windows.insert(hwnd, w);
672 const HandleBaseWindowHash::iterator it = d->m_windows.find(hwnd);
673 if (it != d->m_windows.end()) {
674 if (d->m_keyMapper.keyGrabber() == it.value()->window())
675 d->m_keyMapper.setKeyGrabber(
nullptr);
676 d->m_windows.erase(it);
682 for (
auto it = d->m_windows.cbegin(), end = d->m_windows.cend(); it != end; ++it) {
683 if ((*it)->menuBar() == mb)
691 return d->m_windows.value(hwnd);
701 for (HWND w = hwnd; w; w = GetParent(w)) {
702 window = d->m_windows.value(w);
720 return d->m_pointerHandler.windowUnderMouse();
725 d->m_pointerHandler.clearWindowUnderMouse();
729
730
731
732
733
734
735
736
737
738
744 POINT point = screenPoint;
745 screenToClient(*hwnd, &point);
747 const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags);
748 if (!child || child == *hwnd)
761 if (!(cwexFlags & CWP_SKIPTRANSPARENT)
762 && (GetWindowLongPtr(child, GWL_EXSTYLE) & WS_EX_TRANSPARENT)) {
763 const HWND nonTransparentChild = ChildWindowFromPointEx(*hwnd, point, cwexFlags | CWP_SKIPTRANSPARENT);
764 if (!nonTransparentChild || nonTransparentChild == *hwnd)
767 *result = nonTransparentWindow;
768 *hwnd = nonTransparentChild;
777 const QPoint &screenPointIn,
778 unsigned cwex_flags)
const
781 const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() };
782 while (findPlatformWindowHelper(screenPoint, cwex_flags,
this, &parent, &result)) {}
785 if (result ==
nullptr) {
786 if (
const HWND window = WindowFromPoint(screenPoint))
795 const DWORD sessionId = WTSGetActiveConsoleSessionId();
796 if (sessionId != 0xFFFFFFFF) {
797 LPTSTR buffer =
nullptr;
799#if !defined(Q_CC_MINGW)
800 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
801 WTSSessionInfoEx, &buffer, &size) == TRUE
803 const WTSINFOEXW *info =
reinterpret_cast<WTSINFOEXW *>(buffer);
804 result = info->Level == 1 && info->Data.WTSInfoExLevel1.SessionFlags == WTS_SESSIONSTATE_LOCK;
805 WTSFreeMemory(buffer);
809 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
810 WTS_INFO_CLASS(25), &buffer, &size) == TRUE
812 const DWORD *p =
reinterpret_cast<DWORD *>(buffer);
813 const DWORD level = *p;
814 const DWORD sessionFlags = *(p + 4);
815 result = level == 1 && sessionFlags == 1;
816 WTSFreeMemory(buffer);
825 return d->m_mimeConverter;
830 return d->m_screenManager;
835#if QT_CONFIG(tabletevent)
836 return d->m_tabletSupport.data();
843
844
845
848 const wchar_t *windowName,
849 WNDPROC wndProc, DWORD style)
852 wndProc = DefWindowProc;
853 QString className = registerWindowClass(classNamePrefix() + classNameIn, wndProc);
854 return CreateWindowEx(0,
reinterpret_cast<LPCWSTR>(className.utf16()),
856 CW_USEDEFAULT, CW_USEDEFAULT,
857 CW_USEDEFAULT, CW_USEDEFAULT,
858 HWND_MESSAGE,
nullptr,
static_cast<HINSTANCE>(GetModuleHandle(
nullptr)),
nullptr);
864 SetWindowPos(hwnd,
nullptr, 0, 0, 0, 0,
865 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
871 const BOOL result = dpi != 0
872 ? SystemParametersInfoForDpi(action, param, out, 0, dpi)
873 : SystemParametersInfo(action, param, out, 0);
874 return result == TRUE;
878 const QPlatformScreen *screen)
884 const QPlatformWindow *win)
891 memset(ncm, 0,
sizeof(NONCLIENTMETRICS));
892 ncm->cbSize =
sizeof(NONCLIENTMETRICS);
893 return systemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm->cbSize, ncm, dpi);
897 const QPlatformScreen *screen)
899 const int dpi = screen ? qRound(screen->logicalDpi().first) : 0;
900 return nonClientMetrics(ncm,
unsigned(dpi));
903bool QWindowsContext::nonClientMetricsForWindow(NONCLIENTMETRICS *ncm,
const QPlatformWindow *win)
905 return nonClientMetricsForScreen(ncm, win ? win->screen() :
nullptr);
919 return window->isTopLevel()
922 && (window->surfaceType() != QSurface::OpenGLSurface
923 || QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL)
931 case WM_IME_STARTCOMPOSITION:
932 case WM_IME_ENDCOMPOSITION:
933 case WM_IME_COMPOSITION:
938 case WM_NCMOUSEHOVER:
939 case WM_NCMOUSELEAVE:
944 case WM_DWMNCRENDERINGCHANGED:
950 return (m >= WM_MOUSEFIRST && m <= WM_MOUSELAST)
951 || (m >= WM_NCMOUSEMOVE && m <= WM_NCXBUTTONDBLCLK)
952 || (m >= WM_KEYFIRST && m <= WM_KEYLAST);
959 if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
960 result = EnableNonClientDpiScaling(hwnd) != FALSE;
962 const DWORD errorCode = GetLastError();
963 qErrnoWarning(
int(errorCode),
"EnableNonClientDpiScaling() failed for HWND %p (%lu)",
971
972
973
974
978 WPARAM wParam, LPARAM lParam,
986 msg.message = message;
989 msg.time = GetMessageTime();
990 msg.pt.x = msg.pt.y = 0;
992 msg.pt.x = GET_X_LPARAM(lParam);
993 msg.pt.y = GET_Y_LPARAM(lParam);
997 clientToScreen(msg.hwnd, &msg.pt);
1000 GetCursorPos(&msg.pt);
1004 *platformWindowPtr = platformWindow;
1008 if (!isInputMessage(msg.message) && filterNativeEvent(&msg, result))
1011 if (platformWindow && filterNativeEvent(platformWindow->window(), &msg, result))
1018 if (!windowsInputContext) {
1024 return windowsInputContext->startComposition(hwnd);
1026 return windowsInputContext->composition(hwnd, lParam);
1028 return windowsInputContext->endComposition(hwnd);
1030 return windowsInputContext->handleIME_Request(wParam, lParam, result);
1046 qWarning() <<
"External WM_DESTROY received for " << platformWindow->window()
1047 <<
", parent: " << platformWindow->window()->parent()
1048 <<
", transient parent: " << platformWindow->window()->transientParent();
1062#if QT_CONFIG(accessibility)
1063 return QWindowsUiaAccessibility::handleWmGetObject(hwnd, wParam, lParam, result);
1069 return d->m_screenManager.handleScreenChanges();
1078 if (!platformWindow && !d->m_creationContext.isNull()) {
1080 case QtWindows::QuerySizeHints:
1081 d->m_creationContext->applyToMinMaxInfo(
reinterpret_cast<MINMAXINFO *>(lParam));
1083 case QtWindows::ResizeEvent:
1084 d->m_creationContext->obtainedSize = QSize(LOWORD(lParam), HIWORD(lParam));
1086 case QtWindows::MoveEvent:
1087 d->m_creationContext->obtainedPos = QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
1090 if (shouldHaveNonClientDpiScaling(d->m_creationContext->window) &&
1093 !QWindowsContextPrivate::m_v2DpiAware) {
1094 enableNonClientDpiScaling(msg.hwnd);
1097 case QtWindows::CalculateSize:
1098 return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->window, d->m_creationContext->customMargins, msg, result);
1099 case QtWindows::GeometryChangingEvent:
1100 return QWindowsWindow::handleGeometryChangingMessage(&msg, d->m_creationContext->window,
1101 d->m_creationContext->margins + d->m_creationContext->customMargins);
1106 if (platformWindow) {
1110 if (QWindowsContext::verbose > 1)
1111 qCDebug(lcQpaEvents) <<
"Event window: " << platformWindow->window();
1113 qWarning(
"%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
1114 __FUNCTION__, message,
1115 QWindowsGuiEventDispatcher::windowsMessageName(message), hwnd);
1121 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
1124 if (wParam == DBT_DEVNODES_CHANGED)
1129 wic->handleInputLanguageChanged(wParam, lParam);
1131 case QtWindows::KeyDownEvent:
1132 case QtWindows::KeyEvent:
1133 case QtWindows::InputMethodKeyEvent:
1134 case QtWindows::InputMethodKeyDownEvent:
1135 case QtWindows::AppCommandEvent:
1136 return sessionManagerInteractionBlocked() || d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
1140 if (QWindowsPopupMenu::notifyAboutToShow(
reinterpret_cast<HMENU>(wParam)))
1142 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
1144 return platformWindow
->menuBar()->notifyAboutToShow(
reinterpret_cast<HMENU>(wParam));
1148 if (QWindowsPopupMenu::notifyTriggered(LOWORD(wParam)))
1150 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
1152 return platformWindow
->menuBar()->notifyTriggered(LOWORD(wParam));
1157 QWindow *window = platformWindow->window();
1158 platformWindow->handleResized(
static_cast<
int>(wParam), lParam);
1159 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1164 platformWindow->getSizeHints(
reinterpret_cast<MINMAXINFO *>(lParam));
1167 return QWindowsGeometryHint::handleCalculateSize(platformWindow->window(), platformWindow->customMargins(), msg, result);
1169 QWindow *window = platformWindow->window();
1170 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1172 return platformWindow->handleNonClientHitTest(
QPoint(msg.pt.x, msg.pt.y), result);
1175 return platformWindow->handleNonClientActivate(result);
1177 return platformWindow->handleGeometryChanging(&msg);
1179 QWindow *window = platformWindow->window();
1180 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1182 return platformWindow->handleWmPaint(hwnd, message, wParam, lParam, result);
1187 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
1191 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1194 if (!IsZoomed(hwnd))
1199 platformWindow->checkForScreenChanged();
1200 handleExitSizeMove(platformWindow->window());
1201 if (!IsZoomed(hwnd))
1211 QWindow *window = platformWindow->window();
1212 while (window && (window->flags() & Qt::WindowTransparentForInput))
1213 window = window->parent();
1216 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
1222 case QtWindows::PointerEvent:
1223 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1225 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus)
1229 handleFocusEvent(et, platformWindow);
1232 if (!platformWindow->window()->isVisible()) {
1240 case QtWindows::CloseEvent:
1241 QWindowSystemInterface::handleCloseEvent(platformWindow->window());
1250 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1251 *result = LRESULT(MA_NOACTIVATE);
1254#if QT_CONFIG(tabletevent)
1255 if (!d->m_tabletSupport.isNull())
1256 d->m_tabletSupport->notifyActivate();
1259 if (
const QWindow *modalWindow = QGuiApplication::modalWindow()) {
1260 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(modalWindow);
1261 Q_ASSERT(platformWindow);
1267 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1268 *result = LRESULT(MA_NOACTIVATE);
1272#ifndef QT_NO_CONTEXTMENU
1273 case QtWindows::ContextMenu:
1274 return handleContextMenuEvent(platformWindow->window(), msg);
1277#ifndef QT_NO_WHATSTHIS
1278 QWindowSystemInterface::handleEnterWhatsThisEvent();
1283 platformWindow->handleDpiScaledSize(wParam, lParam, result);
1286 platformWindow->handleDpiChanged(hwnd, wParam, lParam);
1289 platformWindow->handleDpiChangedAfterParent(hwnd);
1291#if QT_CONFIG(sessionmanager)
1292 case QtWindows::QueryEndSessionApplicationEvent: {
1293 QWindowsSessionManager *sessionManager = platformSessionManager();
1294 if (sessionManager->isActive()) {
1295 *result = sessionManager->wasCanceled() ? 0 : 1;
1299 sessionManager->setActive(
true);
1300 sessionManager->blocksInteraction();
1301 sessionManager->clearCancellation();
1303 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1304 qGuiAppPriv->commitData();
1306 if (lParam & ENDSESSION_LOGOFF)
1309 *result = sessionManager->wasCanceled() ? 0 : 1;
1312 case QtWindows::EndSessionApplicationEvent: {
1313 QWindowsSessionManager *sessionManager = platformSessionManager();
1315 sessionManager->setActive(
false);
1316 sessionManager->allowsInteraction();
1317 const bool endsession = wParam != 0;
1321 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1322 if (endsession && !qGuiAppPriv->aboutToQuitEmitted) {
1323 qGuiAppPriv->aboutToQuitEmitted =
true;
1324 int index = QGuiApplication::staticMetaObject.indexOfSignal(
"aboutToQuit()");
1325 qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,
nullptr);
1327 QGuiApplication::quit();
1344
1345
1346
1347
1351 QWindow *nextActiveWindow =
nullptr;
1353 QWindow *topWindow = QWindowsWindow::topLevelOf(platformWindow->window());
1354 QWindow *modalWindow =
nullptr;
1355 if (QGuiApplicationPrivate::instance()->isWindowBlocked(topWindow, &modalWindow) && topWindow != modalWindow) {
1356 modalWindow->requestActivate();
1362 QWindow *currentFocusWindow = QGuiApplication::focusWindow();
1363 if (currentFocusWindow && currentFocusWindow != platformWindow->window()) {
1364 currentFocusWindow->requestActivate();
1368 nextActiveWindow = platformWindow->window();
1372 if (
const HWND nextActiveHwnd = GetFocus())
1373 if (
QWindowsWindow *nextActivePlatformWindow = findClosestPlatformWindow(nextActiveHwnd))
1374 if (nextActivePlatformWindow != platformWindow)
1375 nextActiveWindow = nextActivePlatformWindow->window();
1377 if (nextActiveWindow != d->m_lastActiveWindow) {
1378 d->m_lastActiveWindow = nextActiveWindow;
1379 QWindowSystemInterface::handleFocusWindowChanged(nextActiveWindow, Qt::ActiveWindowFocusReason);
1383#ifndef QT_NO_CONTEXTMENU
1384bool QWindowsContext::handleContextMenuEvent(QWindow *window,
const MSG &msg)
1386 bool mouseTriggered =
false;
1389 if (msg.lParam !=
int(0xffffffff)) {
1390 mouseTriggered =
true;
1391 globalPos.setX(msg.pt.x);
1392 globalPos.setY(msg.pt.y);
1393 pos = QWindowsGeometryHint::mapFromGlobal(msg.hwnd, globalPos);
1396 if (GetClientRect(msg.hwnd, &clientRect)) {
1397 if (pos.x() < clientRect.left || pos.x() >= clientRect.right ||
1398 pos.y() < clientRect.top || pos.y() >= clientRect.bottom)
1408 QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
1409 keyMapper()->queryKeyboardModifiers());
1426 const Qt::MouseButtons currentButtons = QWindowsPointerHandler::queryMouseButtons();
1427 const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons();
1428 if (currentButtons == appButtons)
1430 const Qt::KeyboardModifiers keyboardModifiers =
keyMapper()->queryKeyboardModifiers();
1431 const QPoint globalPos = QWindowsCursor::mousePosition();
1432 const QPlatformWindow *platWin = window->handle();
1433 const QPoint localPos = platWin->mapFromGlobal(globalPos);
1434 const QEvent::Type type = platWin->geometry().contains(globalPos)
1435 ? QEvent::MouseButtonRelease : QEvent::NonClientAreaMouseButtonRelease;
1436 for (Qt::MouseButton button : {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}) {
1437 if (appButtons.testFlag(button) && !currentButtons.testFlag(button)) {
1438 QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
1439 currentButtons, button, type, keyboardModifiers);
1442 d->m_pointerHandler.clearEvents();
1447 return d->m_asyncExpose;
1452 d->m_asyncExpose = value;
1455DWORD
QWindowsContext::readAdvancedExplorerSettings(
const wchar_t *subKey, DWORD defaultValue)
1457 const auto advancedSettings = QWinRegistryKey(
1458 HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)");
1459 return advancedSettings.value<DWORD>(subKey).value_or(defaultValue);
1464 return rect.right - rect.left == 0 && rect.bottom - rect.top == 0;
1469 return QMargins(client.left - frame.left, client.top - frame.top,
1470 frame.right - client.right, frame.bottom - client.bottom);
1475 RECT result = {0, 0, 0, 0};
1476 if (message == WM_NCCALCSIZE && wParam)
1477 result =
reinterpret_cast<
const NCCALCSIZE_PARAMS *>(lParam)->rgrc[n];
1483 WINDOWPLACEMENT windowPlacement;
1484 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1485 return GetWindowPlacement(hwnd, &windowPlacement) && windowPlacement.showCmd == SW_SHOWMINIMIZED;
1490 return (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) == 0;
1494
1495
1496
1497
1498
1499
1501LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1504 const QtWindows::WindowsEventType et = windowsEventType(message, wParam, lParam);
1505 QWindowsWindow *platformWindow =
nullptr;
1506 const RECT ncCalcSizeFrame = rectFromNcCalcSize(message, wParam, lParam, 0);
1507 const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow);
1508 if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
1509 if (
const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) {
1510 qCDebug(lcQpaEvents).nospace() <<
"EVENT: hwd=" << hwnd <<
' ' << eventName
1511 <<
" msg=0x" << Qt::hex << message <<
" et=0x" << et << Qt::dec <<
" wp="
1512 <<
int(wParam) <<
" at " << GET_X_LPARAM(lParam) <<
','
1513 << GET_Y_LPARAM(lParam) <<
" handled=" << handled;
1517 result = DefWindowProc(hwnd, message, wParam, lParam);
1523 if (message == WM_NCCALCSIZE && !isEmptyRect(ncCalcSizeFrame) && isTopLevel(hwnd) && !isMinimized(hwnd)) {
1524 const QMargins margins =
1525 marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0));
1526 if (margins.left() >= 0) {
1527 if (platformWindow) {
1528 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"WM_NCCALCSIZE for" << hwnd << margins;
1529 platformWindow->setFullFrameMargins(margins);
1531 const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext();
1533 ctx->margins = margins;
1546 QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
1547 qintptr filterResult = 0;
1548 if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) {
1549 *result = LRESULT(filterResult);
1558 qintptr filterResult = 0;
1559 if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), msg, &filterResult)) {
1560 *result = LRESULT(filterResult);
\inmodule QtCore\reentrant
Singleton container for all relevant information.
QSharedPointer< QWindowCreationContext > windowCreationContext() const
QWindowsScreenManager & screenManager()
QWindowsWindow * findClosestPlatformWindow(HWND) const
QWindow * findWindow(HWND) const
void addWindow(HWND, QWindowsWindow *w)
static bool systemParametersInfoForScreen(unsigned action, unsigned param, void *out, const QPlatformScreen *screen=nullptr)
static bool setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwareness)
void clearWindowUnderMouse()
HDC displayContext() const
QWindowsTabletSupport * tabletSupport() const
static bool systemParametersInfoForWindow(unsigned action, unsigned param, void *out, const QPlatformWindow *win=nullptr)
static void setTabletAbsoluteRange(int a)
void registerTouchWindows()
QWindowsWindow * findPlatformWindowAt(HWND parent, const QPoint &screenPoint, unsigned cwex_flags) const
bool initTouch(unsigned integrationOptions)
HWND createDummyWindow(const QString &classNameIn, const wchar_t *windowName, WNDPROC wndProc=nullptr, DWORD style=WS_OVERLAPPED)
Convenience to create a non-visible, message-only dummy window for example used as clipboard watcher ...
void setAsyncExpose(bool value)
QSharedPointer< QWindowCreationContext > setWindowCreationContext(const QSharedPointer< QWindowCreationContext > &ctx)
bool windowsProc(HWND hwnd, UINT message, QtWindows::WindowsEventType et, WPARAM wParam, LPARAM lParam, LRESULT *result, QWindowsWindow **platformWindowPtr)
Main windows procedure registered for windows.
unsigned systemInfo() const
static QtWindows::DpiAwareness processDpiAwareness()
QWindowsWindow * findPlatformWindow(HWND) const
QWindow * keyGrabber() const
QWindowsWindow * findPlatformWindow(const QWindowsMenuBar *mb) const
QWindow * windowUnderMouse() const
QPlatformKeyMapper * keyMapper() const
bool useRTLExtensions() const
static bool systemParametersInfo(unsigned action, unsigned param, void *out, unsigned dpi=0)
QWindowsMimeRegistry & mimeConverter() const
static bool isSessionLocked()
bool initPowerNotificationHandler()
HandleBaseWindowHash & windows()
static QWindowsContext * instance()
QString registerWindowClass(QString cname, WNDPROC proc, unsigned style=0, HBRUSH brush=nullptr, bool icon=false)
void setDetectAltGrModifier(bool a)
Platform cursor implementation.
static bool hasOverrideCursor()
static void enforceOverrideCursor()
Windows Input context implementation.
static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled)
void updateApplicationBadge()
static QWindowsIntegration * instance()
Translates Windows keys to QWindowSystemInterface events.
Manages the list of QWindowsMimeConverter instances.
Manages a list of QWindowsScreen.
Tablet support for Windows.
static QWindowsTheme * instance()
void alertWindow(int durationMs=0)
bool testFlag(unsigned f) const
void setFlag(unsigned f) const
void clearFlag(unsigned f) const
static void settingsChanged()
static const char * embeddedNativeParentHandleProperty
QWindowsMenuBar * menuBar() const
bool frameStrutEventsEnabled() const override
Reimplement this method to return whether frame strut events are enabled.
@ WithinSetParent
Automatic mouse capture on button press.
void updateRestoreGeometry()
void updateCustomTitlebar()
void handleCompositionSettingsChanged()
WindowsEventType
Enumerations for WM_XX events.
@ PointerActivateWindowEvent
@ InputMethodEndCompositionEvent
@ InputLanguageChangeEvent
@ ShowEventOnParentRestoring
@ InputMethodCompositionEvent
@ InputMethodOpenCandidateWindowEvent
@ MouseActivateWindowEvent
@ DpiChangedAfterParentEvent
@ InputMethodStartCompositionEvent
@ CompositionSettingsChanged
@ InputMethodCloseCandidateWindowEvent
@ AccessibleObjectFromWindowRequest
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
#define DPI_AWARENESS_CONTEXT_UNAWARE
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE
#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED
static bool isTopLevel(HWND hwnd)
static RECT rectFromNcCalcSize(UINT message, WPARAM wParam, LPARAM lParam, int n)
static bool enableNonClientDpiScaling(HWND hwnd)
static bool isInputMessage(UINT m)
static DPI_AWARENESS_CONTEXT qtDpiAwarenessToDpiAwarenessContext(QtWindows::DpiAwareness dpiAwareness)
static bool isMinimized(HWND hwnd)
static QMargins marginsFromRects(const RECT &frame, const RECT &client)
static bool useRTL_Extensions()
static bool sessionManagerInteractionBlocked()
static QWindowsInputContext * windowsInputContext()
static QtWindows::DpiAwareness dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT context)
static QByteArray nativeEventType()
static bool isEmptyRect(const RECT &rect)
static bool findPlatformWindowHelper(const POINT &screenPoint, unsigned cwexFlags, const QWindowsContext *context, HWND *hwnd, QWindowsWindow **result)
Find a child window at a screen point.
const HRESULT m_oleInitializeResult
QWindowsKeyMapper m_keyMapper
QWindowsPointerHandler m_pointerHandler
QSet< QString > m_registeredWindowClassNames
QWindowsScreenManager m_screenManager
QWindow * m_lastActiveWindow
QWindowsMimeRegistry m_mimeConverter
QWindowsContext::HandleBaseWindowHash m_windows
QSharedPointer< QWindowCreationContext > m_creationContext
HPOWERNOTIFY m_powerNotification