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);
183# pragma warning( disable : 4996
)
190#if QT_CONFIG(tabletevent)
191 d->m_tabletSupport.reset();
194 if (d->m_powerNotification)
195 UnregisterPowerSettingNotification(d->m_powerNotification);
197 if (d->m_powerDummyWindow)
198 DestroyWindow(d->m_powerDummyWindow);
201 theme->destroyThemeChangeWindow();
203 d->m_screenManager.destroyWindow();
205 unregisterWindowClasses();
206 if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) {
207#ifdef QT_USE_FACTORY_CACHE_REGISTRATION
208 detail::QWinRTFactoryCacheRegistration::clearAllCaches();
213 d->m_screenManager.clearScreens();
214 if (d->m_displayContext)
215 ReleaseDC(
nullptr, d->m_displayContext);
216 m_instance =
nullptr;
226 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
228 auto touchDevice = d->m_pointerHandler.touchDevice();
229 if (touchDevice.isNull()) {
230 const bool mouseEmulation =
231 (integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) == 0;
232 touchDevice = QWindowsPointerHandler::createTouchDevice(mouseEmulation);
234 if (touchDevice.isNull())
236 d->m_pointerHandler.setTouchDevice(touchDevice);
237 QWindowSystemInterface::registerInputDevice(touchDevice.data());
239 d->m_systemInfo |= QWindowsContext::SI_SupportsTouch;
249 if (QGuiApplicationPrivate::is_app_running
250 && (d->m_systemInfo & QWindowsContext::SI_SupportsTouch) != 0) {
251 for (QWindowsWindow *w : std::as_const(d->m_windows))
252 w->registerTouchWindow();
258#if QT_CONFIG(tabletevent)
259 d->m_tabletSupport.reset(QWindowsTabletSupport::create());
268#if QT_CONFIG(tabletevent)
269 d->m_tabletSupport.reset();
276LRESULT QT_WIN_CALLBACK qWindowsPowerWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
278 if (message != WM_POWERBROADCAST || wParam != PBT_POWERSETTINGCHANGE)
279 return DefWindowProc(hwnd, message, wParam, lParam);
281 static bool initialized =
false;
284 return DefWindowProc(hwnd, message, wParam, lParam);
287 auto setting =
reinterpret_cast<
const POWERBROADCAST_SETTING *>(lParam);
289 auto data =
reinterpret_cast<
const DWORD *>(&setting->Data);
292 const auto tlw = QGuiApplication::topLevelWindows();
294 if (w->isVisible() && w->windowState() != Qt::WindowMinimized) {
295 if (
auto tw = QWindowsWindow::windowsWindowOf(w)) {
296 if (HWND hwnd = tw->handle()) {
297 InvalidateRect(hwnd,
nullptr,
false);
304 return DefWindowProc(hwnd, message, wParam, lParam);
309 if (d->m_powerNotification)
312 d->m_powerDummyWindow = createDummyWindow(QStringLiteral(
"PowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc);
313 if (!d->m_powerDummyWindow)
316 d->m_powerNotification = RegisterPowerSettingNotification(d->m_powerDummyWindow, &GUID_MONITOR_POWER_ON, DEVICE_NOTIFY_WINDOW_HANDLE);
317 if (!d->m_powerNotification) {
318 DestroyWindow(d->m_powerDummyWindow);
319 d->m_powerDummyWindow =
nullptr;
327#if QT_CONFIG(tabletevent)
328 QWindowsTabletSupport::setAbsoluteRange(a);
336 d->m_keyMapper.setDetectAltGrModifier(a);
343 if (!IsValidDpiAwarenessContext(context))
362 const auto context = GetWindowDpiAwarenessContext(hwnd);
363 return dpiAwarenessContextToQtDpiAwareness(context);
375 const auto context = GetThreadDpiAwarenessContext();
376 return dpiAwarenessContextToQtDpiAwareness(context);
382 switch (dpiAwareness) {
385 case QtWindows::DpiAwareness::Unaware:
387 case QtWindows::DpiAwareness::System:
389 case QtWindows::DpiAwareness::PerMonitor:
391 case QtWindows::DpiAwareness::PerMonitorVersion2:
393 case QtWindows::DpiAwareness::Unaware_GdiScaled:
399#ifndef QT_NO_DEBUG_STREAM
402 const QDebugStateSaver saver(d);
403 QString message = u"QtWindows::DpiAwareness::"_s;
404 switch (dpiAwareness) {
405 case QtWindows::DpiAwareness::Invalid:
406 message += u"Invalid"_s;
408 case QtWindows::DpiAwareness::Unaware:
409 message += u"Unaware"_s;
411 case QtWindows::DpiAwareness::System:
412 message += u"System"_s;
414 case QtWindows::DpiAwareness::PerMonitor:
415 message += u"PerMonitor"_s;
417 case QtWindows::DpiAwareness::PerMonitorVersion2:
418 message += u"PerMonitorVersion2"_s;
420 case QtWindows::DpiAwareness::Unaware_GdiScaled:
421 message += u"Unaware_GdiScaled"_s;
424 d.nospace().noquote() << message;
431 qCDebug(lcQpaWindow) <<
__FUNCTION__ << dpiAwareness;
432 [[maybe_unused]]
const auto updatePMv2Status = qScopeGuard([](){
438 const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness);
439 if (!IsValidDpiAwarenessContext(context)) {
440 qCWarning(lcQpaWindow) << dpiAwareness <<
"is not supported by current system.";
443 if (!SetProcessDpiAwarenessContext(context)) {
444 qCWarning(lcQpaWindow).noquote().nospace()
445 <<
"SetProcessDpiAwarenessContext() failed: "
446 << QSystemError::windowsString()
447 <<
"\nQt's default DPI awareness context is "
448 <<
"DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
449 <<
"are doing, you can overwrite this default using qt.conf "
450 <<
"(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
463 return d->m_systemInfo;
468 return d->m_keyMapper.useRTLExtensions();
473 return &d->m_keyMapper;
483 const QSharedPointer<QWindowCreationContext> old = d->m_creationContext;
484 d->m_creationContext = ctx;
490 return d->m_creationContext;
495 return d->m_defaultDPI;
500 return d->m_displayContext;
505 return d->m_keyMapper.keyGrabber();
510 d->m_keyMapper.setKeyGrabber(w);
515 static QString result;
516 if (result.isEmpty()) {
517 QTextStream str(&result);
518 str <<
"Qt" << QT_VERSION_MAJOR << QT_VERSION_MINOR << QT_VERSION_PATCH;
519 if (QLibraryInfo::isDebugBuild())
522# define xstr(s) str(s)
524 str << xstr(QT_NAMESPACE);
537 const Qt::WindowFlags flags = w->flags();
538 const Qt::WindowFlags type = flags & Qt::WindowType_Mask;
540 uint style = CS_DBLCLKS;
544 if (w->surfaceType() == QSurface::OpenGLSurface || (flags & Qt::MSWindowsOwnDC))
546 if (!(flags & Qt::NoDropShadowWindowHint)
547 && (type == Qt::Popup || w->property(
"_q_windowsDropShadow").toBool())) {
548 style |= CS_DROPSHADOW;
554 style |= CS_SAVEBITS;
558 if (!(flags & Qt::WindowSystemMenuHint))
563 QString cname = classNamePrefix();
564 cname +=
"QWindow"_L1;
570 cname +=
"ToolTip"_L1;
578 if (style & CS_DROPSHADOW)
579 cname +=
"DropShadow"_L1;
580 if (style & CS_SAVEBITS)
581 cname +=
"SaveBits"_L1;
582 if (style & CS_OWNDC)
587 return registerWindowClass(cname, qWindowsWndProc, style,
nullptr, icon);
603 const auto appInstance =
static_cast<HINSTANCE>(GetModuleHandle(
nullptr));
605 const bool classExists = GetClassInfo(appInstance,
reinterpret_cast<LPCWSTR>(cname.utf16()), &wcinfo) != FALSE
606 && wcinfo.lpfnWndProc != proc;
609 cname += QUuid::createUuid().toString();
611 if (d->m_registeredWindowClassNames.contains(cname))
615 wc.cbSize =
sizeof(WNDCLASSEX);
617 wc.lpfnWndProc = proc;
620 wc.hInstance = appInstance;
621 wc.hCursor =
nullptr;
622 wc.hbrBackground = brush;
624 wc.hIcon =
static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
626 int sw = GetSystemMetrics(SM_CXSMICON);
627 int sh = GetSystemMetrics(SM_CYSMICON);
628 wc.hIconSm =
static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0));
630 wc.hIcon =
static_cast<HICON>(LoadImage(
nullptr, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED));
631 wc.hIconSm =
nullptr;
635 wc.hIconSm =
nullptr;
638 wc.lpszMenuName =
nullptr;
639 wc.lpszClassName =
reinterpret_cast<LPCWSTR>(cname.utf16());
640 ATOM atom = RegisterClassEx(&wc);
642 qErrnoWarning(
"QApplication::regClass: Registering window class '%s' failed.",
645 d->m_registeredWindowClassNames.insert(cname);
646 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
' ' << cname
647 <<
" style=0x" << Qt::hex << style << Qt::dec
648 <<
" brush=" << brush <<
" icon=" << icon <<
" atom=" << atom;
654 const auto appInstance =
static_cast<HINSTANCE>(GetModuleHandle(
nullptr));
656 for (
const QString &name : std::as_const(d->m_registeredWindowClassNames)) {
657 if (!UnregisterClass(
reinterpret_cast<LPCWSTR>(name.utf16()), appInstance) && QWindowsContext::verbose)
658 qErrnoWarning(
"UnregisterClass failed for '%s'", qPrintable(name));
660 d->m_registeredWindowClassNames.clear();
665 return GetDeviceCaps(d->m_displayContext, BITSPIXEL);
670 d->m_windows.insert(hwnd, w);
675 const HandleBaseWindowHash::iterator it = d->m_windows.find(hwnd);
676 if (it != d->m_windows.end()) {
677 if (d->m_keyMapper.keyGrabber() == it.value()->window())
678 d->m_keyMapper.setKeyGrabber(
nullptr);
679 d->m_windows.erase(it);
685 for (
auto it = d->m_windows.cbegin(), end = d->m_windows.cend(); it != end; ++it) {
686 if ((*it)->menuBar() == mb)
694 return d->m_windows.value(hwnd);
704 for (HWND w = hwnd; w; w = GetParent(w)) {
705 window = d->m_windows.value(w);
723 return d->m_pointerHandler.windowUnderMouse();
728 d->m_pointerHandler.clearWindowUnderMouse();
732
733
734
735
736
737
738
739
740
741
747 POINT point = screenPoint;
748 screenToClient(*hwnd, &point);
750 const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags);
751 if (!child || child == *hwnd)
764 if (!(cwexFlags & CWP_SKIPTRANSPARENT)
765 && (GetWindowLongPtr(child, GWL_EXSTYLE) & WS_EX_TRANSPARENT)) {
766 const HWND nonTransparentChild = ChildWindowFromPointEx(*hwnd, point, cwexFlags | CWP_SKIPTRANSPARENT);
767 if (!nonTransparentChild || nonTransparentChild == *hwnd)
770 *result = nonTransparentWindow;
771 *hwnd = nonTransparentChild;
780 const QPoint &screenPointIn,
781 unsigned cwex_flags)
const
784 const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() };
785 while (findPlatformWindowHelper(screenPoint, cwex_flags,
this, &parent, &result)) {}
788 if (result ==
nullptr) {
789 if (
const HWND window = WindowFromPoint(screenPoint))
798 const DWORD sessionId = WTSGetActiveConsoleSessionId();
799 if (sessionId != 0xFFFFFFFF) {
800 LPTSTR buffer =
nullptr;
802#if !defined(Q_CC_MINGW)
803 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
804 WTSSessionInfoEx, &buffer, &size) == TRUE
806 const WTSINFOEXW *info =
reinterpret_cast<WTSINFOEXW *>(buffer);
807 result = info->Level == 1 && info->Data.WTSInfoExLevel1.SessionFlags == WTS_SESSIONSTATE_LOCK;
808 WTSFreeMemory(buffer);
812 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
813 WTS_INFO_CLASS(25), &buffer, &size) == TRUE
815 const DWORD *p =
reinterpret_cast<DWORD *>(buffer);
816 const DWORD level = *p;
817 const DWORD sessionFlags = *(p + 4);
818 result = level == 1 && sessionFlags == 1;
819 WTSFreeMemory(buffer);
828 return d->m_mimeConverter;
833 return d->m_screenManager;
838#if QT_CONFIG(tabletevent)
839 return d->m_tabletSupport.data();
846
847
848
851 const wchar_t *windowName,
852 WNDPROC wndProc, DWORD style)
855 wndProc = DefWindowProc;
856 QString className = registerWindowClass(classNamePrefix() + classNameIn, wndProc);
857 return CreateWindowEx(0,
reinterpret_cast<LPCWSTR>(className.utf16()),
859 CW_USEDEFAULT, CW_USEDEFAULT,
860 CW_USEDEFAULT, CW_USEDEFAULT,
861 HWND_MESSAGE,
nullptr,
static_cast<HINSTANCE>(GetModuleHandle(
nullptr)),
nullptr);
867 SetWindowPos(hwnd,
nullptr, 0, 0, 0, 0,
868 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
874 const BOOL result = dpi != 0
875 ? SystemParametersInfoForDpi(action, param, out, 0, dpi)
876 : SystemParametersInfo(action, param, out, 0);
877 return result == TRUE;
881 const QPlatformScreen *screen)
887 const QPlatformWindow *win)
894 memset(ncm, 0,
sizeof(NONCLIENTMETRICS));
895 ncm->cbSize =
sizeof(NONCLIENTMETRICS);
896 return systemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm->cbSize, ncm, dpi);
900 const QPlatformScreen *screen)
902 const int dpi = screen ? qRound(screen->logicalDpi().first) : 0;
903 return nonClientMetrics(ncm,
unsigned(dpi));
906bool QWindowsContext::nonClientMetricsForWindow(NONCLIENTMETRICS *ncm,
const QPlatformWindow *win)
908 return nonClientMetricsForScreen(ncm, win ? win->screen() :
nullptr);
922 return window->isTopLevel()
925 && (window->surfaceType() != QSurface::OpenGLSurface
926 || QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL)
934 case WM_IME_STARTCOMPOSITION:
935 case WM_IME_ENDCOMPOSITION:
936 case WM_IME_COMPOSITION:
941 case WM_NCMOUSEHOVER:
942 case WM_NCMOUSELEAVE:
947 case WM_DWMNCRENDERINGCHANGED:
953 return (m >= WM_MOUSEFIRST && m <= WM_MOUSELAST)
954 || (m >= WM_NCMOUSEMOVE && m <= WM_NCXBUTTONDBLCLK)
955 || (m >= WM_KEYFIRST && m <= WM_KEYLAST);
962 if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
963 result = EnableNonClientDpiScaling(hwnd) != FALSE;
965 const DWORD errorCode = GetLastError();
966 qErrnoWarning(
int(errorCode),
"EnableNonClientDpiScaling() failed for HWND %p (%lu)",
974
975
976
977
981 WPARAM wParam, LPARAM lParam,
989 msg.message = message;
992 msg.time = GetMessageTime();
993 msg.pt.x = msg.pt.y = 0;
995 msg.pt.x = GET_X_LPARAM(lParam);
996 msg.pt.y = GET_Y_LPARAM(lParam);
1000 clientToScreen(msg.hwnd, &msg.pt);
1003 GetCursorPos(&msg.pt);
1007 *platformWindowPtr = platformWindow;
1011 if (!isInputMessage(msg.message) && filterNativeEvent(&msg, result))
1014 if (platformWindow && filterNativeEvent(platformWindow->window(), &msg, result))
1021 if (!windowsInputContext) {
1027 return windowsInputContext->startComposition(hwnd);
1029 return windowsInputContext->composition(hwnd, lParam);
1031 return windowsInputContext->endComposition(hwnd);
1033 return windowsInputContext->handleIME_Request(wParam, lParam, result);
1049 qWarning() <<
"External WM_DESTROY received for " << platformWindow->window()
1050 <<
", parent: " << platformWindow->window()->parent()
1051 <<
", transient parent: " << platformWindow->window()->transientParent();
1065#if QT_CONFIG(accessibility)
1066 return QWindowsUiaAccessibility::handleWmGetObject(hwnd, wParam, lParam, result);
1072 return d->m_screenManager.handleScreenChanges();
1081 if (!platformWindow && !d->m_creationContext.isNull()) {
1083 case QtWindows::QuerySizeHints:
1084 d->m_creationContext->applyToMinMaxInfo(
reinterpret_cast<MINMAXINFO *>(lParam));
1086 case QtWindows::ResizeEvent:
1087 d->m_creationContext->obtainedSize = QSize(LOWORD(lParam), HIWORD(lParam));
1089 case QtWindows::MoveEvent:
1090 d->m_creationContext->obtainedPos = QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
1093 if (shouldHaveNonClientDpiScaling(d->m_creationContext->window) &&
1096 !QWindowsContextPrivate::m_v2DpiAware) {
1097 enableNonClientDpiScaling(msg.hwnd);
1100 case QtWindows::CalculateSize:
1101 return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->window, d->m_creationContext->customMargins, msg, result);
1102 case QtWindows::GeometryChangingEvent:
1103 return QWindowsWindow::handleGeometryChangingMessage(&msg, d->m_creationContext->window,
1104 d->m_creationContext->margins + d->m_creationContext->customMargins);
1109 if (platformWindow) {
1113 if (QWindowsContext::verbose > 1)
1114 qCDebug(lcQpaEvents) <<
"Event window: " << platformWindow->window();
1116 qWarning(
"%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
1117 __FUNCTION__, message,
1118 QWindowsGuiEventDispatcher::windowsMessageName(message), hwnd);
1124 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
1127 if (wParam == DBT_DEVNODES_CHANGED)
1132 wic->handleInputLanguageChanged(wParam, lParam);
1134 case QtWindows::KeyDownEvent:
1135 case QtWindows::KeyEvent:
1136 case QtWindows::InputMethodKeyEvent:
1137 case QtWindows::InputMethodKeyDownEvent:
1138 case QtWindows::AppCommandEvent:
1139 return sessionManagerInteractionBlocked() || d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
1143 if (QWindowsPopupMenu::notifyAboutToShow(
reinterpret_cast<HMENU>(wParam)))
1145 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
1147 return platformWindow
->menuBar()->notifyAboutToShow(
reinterpret_cast<HMENU>(wParam));
1151 if (QWindowsPopupMenu::notifyTriggered(LOWORD(wParam)))
1153 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
1155 return platformWindow
->menuBar()->notifyTriggered(LOWORD(wParam));
1160 QWindow *window = platformWindow->window();
1161 platformWindow->handleResized(
static_cast<
int>(wParam), lParam);
1162 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1167 platformWindow->getSizeHints(
reinterpret_cast<MINMAXINFO *>(lParam));
1170 return QWindowsGeometryHint::handleCalculateSize(platformWindow->window(), platformWindow->customMargins(), msg, result);
1172 QWindow *window = platformWindow->window();
1173 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1175 return platformWindow->handleNonClientHitTest(
QPoint(msg.pt.x, msg.pt.y), result);
1178 return platformWindow->handleNonClientActivate(result);
1180 return platformWindow->handleGeometryChanging(&msg);
1182 QWindow *window = platformWindow->window();
1183 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1185 return platformWindow->handleWmPaint(hwnd, message, wParam, lParam, result);
1190 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
1194 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1197 if (!IsZoomed(hwnd))
1203 handleExitSizeMove(platformWindow->window());
1204 if (!IsZoomed(hwnd))
1214 QWindow *window = platformWindow->window();
1215 while (window && (window->flags() & Qt::WindowTransparentForInput))
1216 window = window->parent();
1219 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
1225 case QtWindows::PointerEvent:
1226 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1228 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus)
1232 handleFocusEvent(et, platformWindow);
1235 if (!platformWindow->window()->isVisible()) {
1243 case QtWindows::CloseEvent:
1244 QWindowSystemInterface::handleCloseEvent(platformWindow->window());
1253 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1254 *result = LRESULT(MA_NOACTIVATE);
1257#if QT_CONFIG(tabletevent)
1258 if (!d->m_tabletSupport.isNull())
1259 d->m_tabletSupport->notifyActivate();
1262 if (
const QWindow *modalWindow = QGuiApplication::modalWindow()) {
1263 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(modalWindow);
1264 Q_ASSERT(platformWindow);
1270 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1271 *result = LRESULT(MA_NOACTIVATE);
1275#ifndef QT_NO_CONTEXTMENU
1276 case QtWindows::ContextMenu:
1277 return handleContextMenuEvent(platformWindow->window(), msg);
1280#ifndef QT_NO_WHATSTHIS
1281 QWindowSystemInterface::handleEnterWhatsThisEvent();
1286 platformWindow->handleDpiScaledSize(wParam, lParam, result);
1289 platformWindow->handleDpiChanged(hwnd, wParam, lParam);
1292 platformWindow->handleDpiChangedAfterParent(hwnd);
1294#if QT_CONFIG(sessionmanager)
1295 case QtWindows::QueryEndSessionApplicationEvent: {
1296 QWindowsSessionManager *sessionManager = platformSessionManager();
1297 if (sessionManager->isActive()) {
1298 *result = sessionManager->wasCanceled() ? 0 : 1;
1302 sessionManager->setActive(
true);
1303 sessionManager->blocksInteraction();
1304 sessionManager->clearCancellation();
1306 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1307 qGuiAppPriv->commitData();
1309 if (lParam & ENDSESSION_LOGOFF)
1312 *result = sessionManager->wasCanceled() ? 0 : 1;
1315 case QtWindows::EndSessionApplicationEvent: {
1316 QWindowsSessionManager *sessionManager = platformSessionManager();
1318 sessionManager->setActive(
false);
1319 sessionManager->allowsInteraction();
1320 const bool endsession = wParam != 0;
1324 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1325 if (endsession && !qGuiAppPriv->aboutToQuitEmitted) {
1326 qGuiAppPriv->aboutToQuitEmitted =
true;
1327 int index = QGuiApplication::staticMetaObject.indexOfSignal(
"aboutToQuit()");
1328 qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,
nullptr);
1330 QGuiApplication::quit();
1347
1348
1349
1350
1354 QWindow *nextActiveWindow =
nullptr;
1356 QWindow *topWindow = QWindowsWindow::topLevelOf(platformWindow->window());
1357 QWindow *modalWindow =
nullptr;
1358 if (QGuiApplicationPrivate::instance()->isWindowBlocked(topWindow, &modalWindow) && topWindow != modalWindow) {
1359 modalWindow->requestActivate();
1365 QWindow *currentFocusWindow = QGuiApplication::focusWindow();
1366 if (currentFocusWindow && currentFocusWindow != platformWindow->window()) {
1367 currentFocusWindow->requestActivate();
1371 nextActiveWindow = platformWindow->window();
1375 if (
const HWND nextActiveHwnd = GetFocus())
1376 if (
QWindowsWindow *nextActivePlatformWindow = findClosestPlatformWindow(nextActiveHwnd))
1377 if (nextActivePlatformWindow != platformWindow)
1378 nextActiveWindow = nextActivePlatformWindow->window();
1380 if (nextActiveWindow != d->m_lastActiveWindow) {
1381 d->m_lastActiveWindow = nextActiveWindow;
1382 QWindowSystemInterface::handleFocusWindowChanged(nextActiveWindow, Qt::ActiveWindowFocusReason);
1386#ifndef QT_NO_CONTEXTMENU
1387bool QWindowsContext::handleContextMenuEvent(QWindow *window,
const MSG &msg)
1389 bool mouseTriggered =
false;
1392 if (msg.lParam !=
int(0xffffffff)) {
1393 mouseTriggered =
true;
1394 globalPos.setX(msg.pt.x);
1395 globalPos.setY(msg.pt.y);
1396 pos = QWindowsGeometryHint::mapFromGlobal(msg.hwnd, globalPos);
1399 if (GetClientRect(msg.hwnd, &clientRect)) {
1400 if (pos.x() < clientRect.left || pos.x() >= clientRect.right ||
1401 pos.y() < clientRect.top || pos.y() >= clientRect.bottom)
1411 QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
1412 keyMapper()->queryKeyboardModifiers());
1429 const Qt::MouseButtons currentButtons = QWindowsPointerHandler::queryMouseButtons();
1430 const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons();
1431 if (currentButtons == appButtons)
1433 const Qt::KeyboardModifiers keyboardModifiers =
keyMapper()->queryKeyboardModifiers();
1434 const QPoint globalPos = QWindowsCursor::mousePosition();
1435 const QPlatformWindow *platWin = window->handle();
1436 const QPoint localPos = platWin->mapFromGlobal(globalPos);
1437 const QEvent::Type type = platWin->geometry().contains(globalPos)
1438 ? QEvent::MouseButtonRelease : QEvent::NonClientAreaMouseButtonRelease;
1439 for (Qt::MouseButton button : {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}) {
1440 if (appButtons.testFlag(button) && !currentButtons.testFlag(button)) {
1441 QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
1442 currentButtons, button, type, keyboardModifiers);
1445 d->m_pointerHandler.clearEvents();
1450 return d->m_asyncExpose;
1455 d->m_asyncExpose = value;
1458DWORD
QWindowsContext::readAdvancedExplorerSettings(
const wchar_t *subKey, DWORD defaultValue)
1460 const auto advancedSettings = QWinRegistryKey(
1461 HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)");
1462 return advancedSettings.value<DWORD>(subKey).value_or(defaultValue);
1467 return rect.right - rect.left == 0 && rect.bottom - rect.top == 0;
1472 return QMargins(client.left - frame.left, client.top - frame.top,
1473 frame.right - client.right, frame.bottom - client.bottom);
1478 RECT result = {0, 0, 0, 0};
1479 if (message == WM_NCCALCSIZE && wParam)
1480 result =
reinterpret_cast<
const NCCALCSIZE_PARAMS *>(lParam)->rgrc[n];
1486 WINDOWPLACEMENT windowPlacement;
1487 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1488 return GetWindowPlacement(hwnd, &windowPlacement) && windowPlacement.showCmd == SW_SHOWMINIMIZED;
1493 return (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) == 0;
1497
1498
1499
1500
1501
1502
1504LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1507 const QtWindows::WindowsEventType et = windowsEventType(message, wParam, lParam);
1508 QWindowsWindow *platformWindow =
nullptr;
1509 const RECT ncCalcSizeFrame = rectFromNcCalcSize(message, wParam, lParam, 0);
1510 const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow);
1511 if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
1512 if (
const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) {
1513 qCDebug(lcQpaEvents).nospace() <<
"EVENT: hwd=" << hwnd <<
' ' << eventName
1514 <<
" msg=0x" << Qt::hex << message <<
" et=0x" << et << Qt::dec <<
" wp="
1515 <<
int(wParam) <<
" at " << GET_X_LPARAM(lParam) <<
','
1516 << GET_Y_LPARAM(lParam) <<
" handled=" << handled;
1520 result = DefWindowProc(hwnd, message, wParam, lParam);
1526 if (message == WM_NCCALCSIZE && !isEmptyRect(ncCalcSizeFrame) && isTopLevel(hwnd) && !isMinimized(hwnd)) {
1527 const QMargins margins =
1528 marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0));
1529 if (margins.left() >= 0) {
1530 if (platformWindow) {
1531 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"WM_NCCALCSIZE for" << hwnd << margins;
1532 platformWindow->setFullFrameMargins(margins);
1534 const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext();
1536 ctx->margins = margins;
1549 QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
1550 qintptr filterResult = 0;
1551 if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) {
1552 *result = LRESULT(filterResult);
1561 qintptr filterResult = 0;
1562 if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), msg, &filterResult)) {
1563 *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)
void checkForScreenChanged(ScreenChangeMode mode=FromGeometryChange)
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