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"
31#include <QtGui/qwindow.h>
32#include <qpa/qwindowsysteminterface.h>
33#include <qpa/qwindowsysteminterface_p.h>
34#include <qpa/qplatformnativeinterface.h>
35#include <QtGui/qguiapplication.h>
36#include <QtGui/qopenglcontext.h>
37#include <QtGui/qpointingdevice.h>
39#include <QtCore/qhash.h>
40#include <QtCore/qstringlist.h>
41#include <QtCore/qdebug.h>
42#include <QtCore/qsysinfo.h>
43#include <QtCore/qscopedpointer.h>
44#include <QtCore/qscopeguard.h>
45#include <QtCore/private/qwinregistry_p.h>
46#if QT_CONFIG(cpp_winrt)
47# include <QtCore/private/qfactorycacheregistration_p.h>
49#include <QtCore/private/qsystemerror_p.h>
50#include <QtCore/private/quniquehandle_types_windows_p.h>
52#include <QtGui/private/qwindowsguieventdispatcher_p.h>
53#include <QtGui/private/qwindowsthemecache_p.h>
60#include <shellscalingapi.h>
64using namespace Qt::StringLiterals;
67Q_LOGGING_CATEGORY(lcQpaEvents,
"qt.qpa.events")
68Q_LOGGING_CATEGORY(lcQpaGl,
"qt.qpa.gl")
69Q_LOGGING_CATEGORY(lcQpaMime,
"qt.qpa.mime")
70Q_LOGGING_CATEGORY(lcQpaInputMethods,
"qt.qpa.input.methods")
71Q_LOGGING_CATEGORY(lcQpaDialogs,
"qt.qpa.dialogs")
72Q_LOGGING_CATEGORY(lcQpaMenus,
"qt.qpa.menus")
73Q_LOGGING_CATEGORY(lcQpaTablet,
"qt.qpa.input.tablet")
74Q_LOGGING_CATEGORY(lcQpaAccessibility,
"qt.qpa.accessibility")
75Q_LOGGING_CATEGORY(lcQpaUiAutomation,
"qt.qpa.uiautomation")
76Q_LOGGING_CATEGORY(lcQpaTrayIcon,
"qt.qpa.trayicon")
77Q_LOGGING_CATEGORY(lcQpaScreen,
"qt.qpa.screen")
78Q_LOGGING_CATEGORY(lcQpaTheme,
"qt.qpa.theme")
80int QWindowsContext::verbose = 0;
82#if !defined(LANG_SYRIAC)
83# define LANG_SYRIAC 0x5a
90 if (
const int nLayouts = GetKeyboardLayoutList(0,
nullptr)) {
91 QScopedArrayPointer<HKL> lpList(
new HKL[nLayouts]);
92 GetKeyboardLayoutList(nLayouts, lpList.data());
93 for (
int i = 0; i < nLayouts; ++i) {
94 switch (PRIMARYLANGID((quintptr)lpList[i])) {
108#if QT_CONFIG(sessionmanager)
109static inline QWindowsSessionManager *platformSessionManager()
111 auto *guiPrivate =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
112 auto *managerPrivate =
static_cast<QSessionManagerPrivate*>(QObjectPrivate::get(guiPrivate->session_manager));
113 return static_cast<QWindowsSessionManager *>(managerPrivate->platformSessionManager);
116static inline bool sessionManagerInteractionBlocked()
118 return platformSessionManager()->isInteractionBlocked();
127
128
129
130
131
132
133
148#if QT_CONFIG(tabletevent)
164 if (m_pointerHandler.touchDevice())
166 m_displayContext.reset(GetDC(
nullptr));
167 m_defaultDPI = GetDeviceCaps(m_displayContext.get(), LOGPIXELSY);
170 m_keyMapper.setUseRTLExtensions(
true);
172 if (FAILED(m_oleInitializeResult)) {
173 qWarning() <<
"QWindowsContext: OleInitialize() failed: "
174 << QSystemError::windowsComString(m_oleInitializeResult);
186#if QT_CONFIG(tabletevent)
187 d->m_tabletSupport.reset();
190 if (d->m_powerNotification)
191 UnregisterPowerSettingNotification(d->m_powerNotification);
193 if (d->m_powerDummyWindow)
194 DestroyWindow(d->m_powerDummyWindow);
197 theme->destroyThemeChangeWindow();
199 d->m_screenManager.destroyWindow();
201 if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) {
202#ifdef QT_USE_FACTORY_CACHE_REGISTRATION
203 detail::QWinRTFactoryCacheRegistration::clearAllCaches();
208 d->m_screenManager.clearScreens();
209 m_instance =
nullptr;
219 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
221 auto touchDevice = d->m_pointerHandler.touchDevice();
222 if (touchDevice.isNull()) {
223 const bool mouseEmulation =
224 (integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) == 0;
225 touchDevice = QWindowsPointerHandler::createTouchDevice(mouseEmulation);
227 if (touchDevice.isNull())
229 d->m_pointerHandler.setTouchDevice(touchDevice);
230 QWindowSystemInterface::registerInputDevice(touchDevice.data());
232 d->m_systemInfo |= QWindowsContext::SI_SupportsTouch;
242 if (QGuiApplicationPrivate::is_app_running
243 && (d->m_systemInfo & QWindowsContext::SI_SupportsTouch) != 0) {
244 for (QWindowsWindow *w : std::as_const(d->m_windows))
245 w->registerTouchWindow();
251#if QT_CONFIG(tabletevent)
252 d->m_tabletSupport.reset(QWindowsTabletSupport::create());
261#if QT_CONFIG(tabletevent)
262 d->m_tabletSupport.reset();
269LRESULT QT_WIN_CALLBACK qWindowsPowerWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
271 if (message != WM_POWERBROADCAST || wParam != PBT_POWERSETTINGCHANGE)
272 return DefWindowProc(hwnd, message, wParam, lParam);
274 static bool initialized =
false;
277 return DefWindowProc(hwnd, message, wParam, lParam);
280 auto setting =
reinterpret_cast<
const POWERBROADCAST_SETTING *>(lParam);
282 auto data =
reinterpret_cast<
const DWORD *>(&setting->Data);
285 const auto tlw = QGuiApplication::topLevelWindows();
287 if (w->isVisible() && w->windowState() != Qt::WindowMinimized) {
288 if (
auto tw = QWindowsWindow::windowsWindowOf(w)) {
289 if (HWND hwnd = tw->handle()) {
290 InvalidateRect(hwnd,
nullptr,
false);
297 return DefWindowProc(hwnd, message, wParam, lParam);
302 if (d->m_powerNotification)
305 d->m_powerDummyWindow = createDummyWindow(QStringLiteral(
"PowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc);
306 if (!d->m_powerDummyWindow)
309 d->m_powerNotification = RegisterPowerSettingNotification(d->m_powerDummyWindow, &GUID_MONITOR_POWER_ON, DEVICE_NOTIFY_WINDOW_HANDLE);
310 if (!d->m_powerNotification) {
311 DestroyWindow(d->m_powerDummyWindow);
312 d->m_powerDummyWindow =
nullptr;
320#if QT_CONFIG(tabletevent)
321 QWindowsTabletSupport::setAbsoluteRange(a);
329 d->m_keyMapper.setDetectAltGrModifier(a);
336 if (!IsValidDpiAwarenessContext(context))
355 const auto context = GetWindowDpiAwarenessContext(hwnd);
356 return dpiAwarenessContextToQtDpiAwareness(context);
368 const auto context = GetThreadDpiAwarenessContext();
369 return dpiAwarenessContextToQtDpiAwareness(context);
375 switch (dpiAwareness) {
378 case QtWindows::DpiAwareness::Unaware:
380 case QtWindows::DpiAwareness::System:
382 case QtWindows::DpiAwareness::PerMonitor:
384 case QtWindows::DpiAwareness::PerMonitorVersion2:
386 case QtWindows::DpiAwareness::Unaware_GdiScaled:
392#ifndef QT_NO_DEBUG_STREAM
395 const QDebugStateSaver saver(d);
396 QString message = u"QtWindows::DpiAwareness::"_s;
397 switch (dpiAwareness) {
398 case QtWindows::DpiAwareness::Invalid:
399 message += u"Invalid"_s;
401 case QtWindows::DpiAwareness::Unaware:
402 message += u"Unaware"_s;
404 case QtWindows::DpiAwareness::System:
405 message += u"System"_s;
407 case QtWindows::DpiAwareness::PerMonitor:
408 message += u"PerMonitor"_s;
410 case QtWindows::DpiAwareness::PerMonitorVersion2:
411 message += u"PerMonitorVersion2"_s;
413 case QtWindows::DpiAwareness::Unaware_GdiScaled:
414 message += u"Unaware_GdiScaled"_s;
417 d.nospace().noquote() << message;
424 qCDebug(lcQpaWindow) <<
__FUNCTION__ << dpiAwareness;
425 [[maybe_unused]]
const auto updatePMv2Status = qScopeGuard([](){
431 const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness);
432 if (!IsValidDpiAwarenessContext(context)) {
433 qCWarning(lcQpaWindow) << dpiAwareness <<
"is not supported by current system.";
436 if (!SetProcessDpiAwarenessContext(context)) {
437 qCWarning(lcQpaWindow).noquote().nospace()
438 <<
"SetProcessDpiAwarenessContext() failed: "
439 << QSystemError::windowsString()
440 <<
"\nQt's default DPI awareness context is "
441 <<
"DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
442 <<
"are doing, you can overwrite this default using qt.conf "
443 <<
"(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
456 return d->m_systemInfo;
461 return d->m_keyMapper.useRTLExtensions();
466 return &d->m_keyMapper;
476 const QSharedPointer<QWindowCreationContext> old = d->m_creationContext;
477 d->m_creationContext = ctx;
483 return d->m_creationContext;
488 return d->m_defaultDPI;
493 return d->m_displayContext.get();
498 return d->m_keyMapper.keyGrabber();
503 d->m_keyMapper.setKeyGrabber(w);
508 return GetDeviceCaps(d->m_displayContext.get(), BITSPIXEL);
513 d->m_windows.insert(hwnd, w);
518 const HandleBaseWindowHash::iterator it = d->m_windows.find(hwnd);
519 if (it != d->m_windows.end()) {
520 if (d->m_keyMapper.keyGrabber() == it.value()->window())
521 d->m_keyMapper.setKeyGrabber(
nullptr);
522 d->m_windows.erase(it);
528 for (
auto it = d->m_windows.cbegin(), end = d->m_windows.cend(); it != end; ++it) {
529 if ((*it)->menuBar() == mb)
537 return d->m_windows.value(hwnd);
547 for (HWND w = hwnd; w; w = GetParent(w)) {
548 window = d->m_windows.value(w);
566 return d->m_pointerHandler.windowUnderMouse();
571 d->m_pointerHandler.clearWindowUnderMouse();
575
576
577
578
579
580
581
582
583
584
590 POINT point = screenPoint;
591 screenToClient(*hwnd, &point);
593 const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags);
594 if (!child || child == *hwnd)
607 if (!(cwexFlags & CWP_SKIPTRANSPARENT)
608 && (GetWindowLongPtr(child, GWL_EXSTYLE) & WS_EX_TRANSPARENT)) {
609 const HWND nonTransparentChild = ChildWindowFromPointEx(*hwnd, point, cwexFlags | CWP_SKIPTRANSPARENT);
610 if (!nonTransparentChild || nonTransparentChild == *hwnd)
613 *result = nonTransparentWindow;
614 *hwnd = nonTransparentChild;
623 const QPoint &screenPointIn,
624 unsigned cwex_flags)
const
627 const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() };
628 while (findPlatformWindowHelper(screenPoint, cwex_flags,
this, &parent, &result)) {}
631 if (result ==
nullptr) {
632 if (
const HWND window = WindowFromPoint(screenPoint))
641 const DWORD sessionId = WTSGetActiveConsoleSessionId();
642 if (sessionId != 0xFFFFFFFF) {
643 LPTSTR buffer =
nullptr;
645#if !defined(Q_CC_MINGW)
646 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
647 WTSSessionInfoEx, &buffer, &size) == TRUE
649 const WTSINFOEXW *info =
reinterpret_cast<WTSINFOEXW *>(buffer);
650 result = info->Level == 1 && info->Data.WTSInfoExLevel1.SessionFlags == WTS_SESSIONSTATE_LOCK;
651 WTSFreeMemory(buffer);
655 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
656 WTS_INFO_CLASS(25), &buffer, &size) == TRUE
658 const DWORD *p =
reinterpret_cast<DWORD *>(buffer);
659 const DWORD level = *p;
660 const DWORD sessionFlags = *(p + 4);
661 result = level == 1 && sessionFlags == 1;
662 WTSFreeMemory(buffer);
671 return d->m_mimeConverter;
676 return d->m_screenManager;
681#if QT_CONFIG(tabletevent)
682 return d->m_tabletSupport.data();
689
690
691
694 const wchar_t *windowName,
695 WNDPROC wndProc, DWORD style)
698 wndProc = DefWindowProc;
699 QString className = d->m_windowClassRegistry.registerWindowClass(classNameIn, wndProc);
700 return CreateWindowEx(0,
reinterpret_cast<LPCWSTR>(className.utf16()),
702 CW_USEDEFAULT, CW_USEDEFAULT,
703 CW_USEDEFAULT, CW_USEDEFAULT,
704 HWND_MESSAGE,
nullptr,
static_cast<HINSTANCE>(GetModuleHandle(
nullptr)),
nullptr);
710 SetWindowPos(hwnd,
nullptr, 0, 0, 0, 0,
711 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
717 const BOOL result = dpi != 0
718 ? SystemParametersInfoForDpi(action, param, out, 0, dpi)
719 : SystemParametersInfo(action, param, out, 0);
720 return result == TRUE;
724 const QPlatformScreen *screen)
730 const QPlatformWindow *win)
737 memset(ncm, 0,
sizeof(NONCLIENTMETRICS));
738 ncm->cbSize =
sizeof(NONCLIENTMETRICS);
743 const QPlatformScreen *screen)
745 const int dpi = screen ? qRound(screen->logicalDpi().first) : 0;
746 return nonClientMetrics(ncm,
unsigned(dpi));
749bool QWindowsContext::nonClientMetricsForWindow(NONCLIENTMETRICS *ncm,
const QPlatformWindow *win)
751 return nonClientMetricsForScreen(ncm, win ? win->screen() :
nullptr);
765 return window->isTopLevel()
768 && (window->surfaceType() != QSurface::OpenGLSurface
769 || QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL)
777 case WM_IME_STARTCOMPOSITION:
778 case WM_IME_ENDCOMPOSITION:
779 case WM_IME_COMPOSITION:
784 case WM_NCMOUSEHOVER:
785 case WM_NCMOUSELEAVE:
790 case WM_DWMNCRENDERINGCHANGED:
796 return (m >= WM_MOUSEFIRST && m <= WM_MOUSELAST)
797 || (m >= WM_NCMOUSEMOVE && m <= WM_NCXBUTTONDBLCLK)
798 || (m >= WM_KEYFIRST && m <= WM_KEYLAST);
805 if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
806 result = EnableNonClientDpiScaling(hwnd) != FALSE;
808 const DWORD errorCode = GetLastError();
809 qErrnoWarning(
int(errorCode),
"EnableNonClientDpiScaling() failed for HWND %p (%lu)",
817
818
819
820
824 WPARAM wParam, LPARAM lParam,
832 msg.message = message;
835 msg.time = GetMessageTime();
836 msg.pt.x = msg.pt.y = 0;
838 msg.pt.x = GET_X_LPARAM(lParam);
839 msg.pt.y = GET_Y_LPARAM(lParam);
843 clientToScreen(msg.hwnd, &msg.pt);
846 GetCursorPos(&msg.pt);
850 *platformWindowPtr = platformWindow;
854 if (!isInputMessage(msg.message) && filterNativeEvent(&msg, result))
857 if (platformWindow && filterNativeEvent(platformWindow->window(), &msg, result))
864 if (!windowsInputContext) {
870 return windowsInputContext->startComposition(hwnd);
872 return windowsInputContext->composition(hwnd, lParam);
874 return windowsInputContext->endComposition(hwnd);
876 return windowsInputContext->handleIME_Request(wParam, lParam, result);
892 qWarning() <<
"External WM_DESTROY received for " << platformWindow->window()
893 <<
", parent: " << platformWindow->window()->parent()
894 <<
", transient parent: " << platformWindow->window()->transientParent();
908#if QT_CONFIG(accessibility)
909 return QWindowsUiaAccessibility::handleWmGetObject(hwnd, wParam, lParam, result);
915 return d->m_screenManager.handleScreenChanges();
924 if (!platformWindow && !d->m_creationContext.isNull()) {
926 case QtWindows::QuerySizeHints:
927 d->m_creationContext->applyToMinMaxInfo(
reinterpret_cast<MINMAXINFO *>(lParam));
929 case QtWindows::ResizeEvent:
930 d->m_creationContext->obtainedSize = QSize(LOWORD(lParam), HIWORD(lParam));
932 case QtWindows::MoveEvent:
933 d->m_creationContext->obtainedPos = QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
936 if (shouldHaveNonClientDpiScaling(d->m_creationContext->window) &&
939 !QWindowsContextPrivate::m_v2DpiAware) {
940 enableNonClientDpiScaling(msg.hwnd);
944 return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->window, d->m_creationContext->customMargins, msg, result);
946 return QWindowsWindow::handleGeometryChangingMessage(&msg, d->m_creationContext->window,
947 d->m_creationContext->margins + d->m_creationContext->customMargins);
952 if (platformWindow) {
957 qCDebug(lcQpaEvents) <<
"Event window: " << platformWindow->window();
959 qWarning(
"%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
960 __FUNCTION__, message,
961 QWindowsGuiEventDispatcher::windowsMessageName(message), hwnd);
967 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
970 if (wParam == DBT_DEVNODES_CHANGED)
975 wic->handleInputLanguageChanged(wParam, lParam);
977 case QtWindows::KeyDownEvent:
978 case QtWindows::KeyEvent:
979 case QtWindows::InputMethodKeyEvent:
980 case QtWindows::InputMethodKeyDownEvent:
981 case QtWindows::AppCommandEvent:
982 return sessionManagerInteractionBlocked() || d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
986 if (QWindowsPopupMenu::notifyAboutToShow(
reinterpret_cast<HMENU>(wParam)))
988 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
990 return platformWindow
->menuBar()->notifyAboutToShow(
reinterpret_cast<HMENU>(wParam));
994 if (QWindowsPopupMenu::notifyTriggered(LOWORD(wParam)))
996 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
998 return platformWindow
->menuBar()->notifyTriggered(LOWORD(wParam));
1003 QWindow *window = platformWindow->window();
1004 platformWindow->handleResized(
static_cast<
int>(wParam), lParam);
1005 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1010 platformWindow->getSizeHints(
reinterpret_cast<MINMAXINFO *>(lParam));
1013 return QWindowsGeometryHint::handleCalculateSize(platformWindow->window(), platformWindow->customMargins(), msg, result);
1015 QWindow *window = platformWindow->window();
1016 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1018 return platformWindow->handleNonClientHitTest(
QPoint(msg.pt.x, msg.pt.y), result);
1021 return platformWindow->handleNonClientActivate(result);
1023 return platformWindow->handleGeometryChanging(&msg);
1025 QWindow *window = platformWindow->window();
1026 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1028 return platformWindow->handleWmPaint(hwnd, message, wParam, lParam, result);
1033 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
1037 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1040 if (!IsZoomed(hwnd))
1045 platformWindow->checkForScreenChanged();
1046 handleExitSizeMove(platformWindow->window());
1047 if (!IsZoomed(hwnd))
1057 QWindow *window = platformWindow->window();
1058 while (window && (window->flags() & Qt::WindowTransparentForInput))
1059 window = window->parent();
1062 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
1068 case QtWindows::PointerEvent:
1069 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1071 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus)
1075 handleFocusEvent(et, platformWindow);
1078 if (!platformWindow->window()->isVisible()) {
1086 case QtWindows::CloseEvent:
1087 QWindowSystemInterface::handleCloseEvent(platformWindow->window());
1096 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1097 *result = LRESULT(MA_NOACTIVATE);
1100#if QT_CONFIG(tabletevent)
1101 if (!d->m_tabletSupport.isNull())
1102 d->m_tabletSupport->notifyActivate();
1105 if (
const QWindow *modalWindow = QGuiApplication::modalWindow()) {
1106 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(modalWindow);
1107 Q_ASSERT(platformWindow);
1113 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1114 *result = LRESULT(MA_NOACTIVATE);
1118#ifndef QT_NO_CONTEXTMENU
1119 case QtWindows::ContextMenu:
1120 return handleContextMenuEvent(platformWindow->window(), msg);
1123#ifndef QT_NO_WHATSTHIS
1124 QWindowSystemInterface::handleEnterWhatsThisEvent();
1129 platformWindow->handleDpiScaledSize(wParam, lParam, result);
1132 platformWindow->handleDpiChanged(hwnd, wParam, lParam);
1135 platformWindow->handleDpiChangedAfterParent(hwnd);
1137#if QT_CONFIG(sessionmanager)
1138 case QtWindows::QueryEndSessionApplicationEvent: {
1139 QWindowsSessionManager *sessionManager = platformSessionManager();
1140 if (sessionManager->isActive()) {
1141 *result = sessionManager->wasCanceled() ? 0 : 1;
1145 sessionManager->setActive(
true);
1146 sessionManager->blocksInteraction();
1147 sessionManager->clearCancellation();
1149 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1150 qGuiAppPriv->commitData();
1152 if (lParam & ENDSESSION_LOGOFF)
1155 *result = sessionManager->wasCanceled() ? 0 : 1;
1158 case QtWindows::EndSessionApplicationEvent: {
1159 QWindowsSessionManager *sessionManager = platformSessionManager();
1161 sessionManager->setActive(
false);
1162 sessionManager->allowsInteraction();
1163 const bool endsession = wParam != 0;
1167 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1168 if (endsession && !qGuiAppPriv->aboutToQuitEmitted) {
1169 qGuiAppPriv->aboutToQuitEmitted =
true;
1170 int index = QGuiApplication::staticMetaObject.indexOfSignal(
"aboutToQuit()");
1171 qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,
nullptr);
1173 QGuiApplication::quit();
1190
1191
1192
1193
1197 QWindow *nextActiveWindow =
nullptr;
1199 QWindow *topWindow = QWindowsWindow::topLevelOf(platformWindow->window());
1200 QWindow *modalWindow =
nullptr;
1201 if (QGuiApplicationPrivate::instance()->isWindowBlocked(topWindow, &modalWindow) && topWindow != modalWindow) {
1202 modalWindow->requestActivate();
1208 QWindow *currentFocusWindow = QGuiApplication::focusWindow();
1209 if (currentFocusWindow && currentFocusWindow != platformWindow->window()) {
1210 currentFocusWindow->requestActivate();
1214 nextActiveWindow = platformWindow->window();
1218 if (
const HWND nextActiveHwnd = GetFocus())
1219 if (
QWindowsWindow *nextActivePlatformWindow = findClosestPlatformWindow(nextActiveHwnd))
1220 if (nextActivePlatformWindow != platformWindow)
1221 nextActiveWindow = nextActivePlatformWindow->window();
1223 if (nextActiveWindow != d->m_lastActiveWindow) {
1224 d->m_lastActiveWindow = nextActiveWindow;
1225 QWindowSystemInterface::handleFocusWindowChanged(nextActiveWindow, Qt::ActiveWindowFocusReason);
1229#ifndef QT_NO_CONTEXTMENU
1230bool QWindowsContext::handleContextMenuEvent(QWindow *window,
const MSG &msg)
1232 bool mouseTriggered =
false;
1235 if (msg.lParam !=
int(0xffffffff)) {
1236 mouseTriggered =
true;
1237 globalPos.setX(msg.pt.x);
1238 globalPos.setY(msg.pt.y);
1239 pos = QWindowsGeometryHint::mapFromGlobal(msg.hwnd, globalPos);
1242 if (GetClientRect(msg.hwnd, &clientRect)) {
1243 if (pos.x() < clientRect.left || pos.x() >= clientRect.right ||
1244 pos.y() < clientRect.top || pos.y() >= clientRect.bottom)
1254 QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
1255 keyMapper()->queryKeyboardModifiers());
1272 const Qt::MouseButtons currentButtons = QWindowsPointerHandler::queryMouseButtons();
1273 const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons();
1274 if (currentButtons == appButtons)
1276 const Qt::KeyboardModifiers keyboardModifiers =
keyMapper()->queryKeyboardModifiers();
1277 const QPoint globalPos = QWindowsCursor::mousePosition();
1278 const QPlatformWindow *platWin = window->handle();
1279 const QPoint localPos = platWin->mapFromGlobal(globalPos);
1280 const QEvent::Type type = platWin->geometry().contains(globalPos)
1281 ? QEvent::MouseButtonRelease : QEvent::NonClientAreaMouseButtonRelease;
1282 for (Qt::MouseButton button : {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}) {
1283 if (appButtons.testFlag(button) && !currentButtons.testFlag(button)) {
1284 QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
1285 currentButtons, button, type, keyboardModifiers);
1288 d->m_pointerHandler.clearEvents();
1293 return d->m_asyncExpose;
1298 d->m_asyncExpose = value;
1301DWORD
QWindowsContext::readAdvancedExplorerSettings(
const wchar_t *subKey, DWORD defaultValue)
1303 const auto advancedSettings = QWinRegistryKey(
1304 HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)");
1305 return advancedSettings.value<DWORD>(subKey).value_or(defaultValue);
1310 return rect.right - rect.left == 0 && rect.bottom - rect.top == 0;
1315 return QMargins(client.left - frame.left, client.top - frame.top,
1316 frame.right - client.right, frame.bottom - client.bottom);
1321 RECT result = {0, 0, 0, 0};
1322 if (message == WM_NCCALCSIZE && wParam)
1323 result =
reinterpret_cast<
const NCCALCSIZE_PARAMS *>(lParam)->rgrc[n];
1329 WINDOWPLACEMENT windowPlacement;
1330 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1331 return GetWindowPlacement(hwnd, &windowPlacement) && windowPlacement.showCmd == SW_SHOWMINIMIZED;
1336 return (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) == 0;
1340
1341
1342
1343
1344
1345
1347LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1350 const QtWindows::WindowsEventType et = windowsEventType(message, wParam, lParam);
1351 QWindowsWindow *platformWindow =
nullptr;
1352 const RECT ncCalcSizeFrame = rectFromNcCalcSize(message, wParam, lParam, 0);
1353 const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow);
1354 if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
1355 if (
const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) {
1356 qCDebug(lcQpaEvents).nospace() <<
"EVENT: hwd=" << hwnd <<
' ' << eventName
1357 <<
" msg=0x" << Qt::hex << message <<
" et=0x" << et << Qt::dec <<
" wp="
1358 <<
int(wParam) <<
" at " << GET_X_LPARAM(lParam) <<
','
1359 << GET_Y_LPARAM(lParam) <<
" handled=" << handled;
1363 result = DefWindowProc(hwnd, message, wParam, lParam);
1369 if (message == WM_NCCALCSIZE && !isEmptyRect(ncCalcSizeFrame) && isTopLevel(hwnd) && !isMinimized(hwnd)) {
1370 const QMargins margins =
1371 marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0));
1372 if (margins.left() >= 0) {
1373 if (platformWindow) {
1374 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"WM_NCCALCSIZE for" << hwnd << margins;
1375 platformWindow->setFullFrameMargins(margins);
1377 const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext();
1379 ctx->margins = margins;
1392 QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
1393 qintptr filterResult = 0;
1394 if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) {
1395 *result = LRESULT(filterResult);
1404 qintptr filterResult = 0;
1405 if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), msg, &filterResult)) {
1406 *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()
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
QWindowsWindowClassRegistry m_windowClassRegistry
QWindowsPointerHandler m_pointerHandler
QUniqueHDCHandle m_displayContext
QWindowsScreenManager m_screenManager
QWindow * m_lastActiveWindow
QWindowsMimeRegistry m_mimeConverter
QWindowsContext::HandleBaseWindowHash m_windows
QSharedPointer< QWindowCreationContext > m_creationContext
HPOWERNOTIFY m_powerNotification