16#if QT_CONFIG(tabletevent)
17# include "qwindowstabletsupport.h"
20#include <private/qguiapplication_p.h>
21#if QT_CONFIG(accessibility)
22# include "uiautomation/qwindowsuiaaccessibility.h"
24#if QT_CONFIG(sessionmanager)
25# include <private/qsessionmanager_p.h>
26# include "qwindowssessionmanager.h"
32#include <QtGui/qwindow.h>
33#include <qpa/qwindowsysteminterface.h>
34#include <qpa/qwindowsysteminterface_p.h>
35#include <qpa/qplatformnativeinterface.h>
36#include <QtGui/qguiapplication.h>
37#include <QtGui/qopenglcontext.h>
38#include <QtGui/qpointingdevice.h>
40#include <QtCore/qhash.h>
41#include <QtCore/qstringlist.h>
42#include <QtCore/qdebug.h>
43#include <QtCore/qsysinfo.h>
44#include <QtCore/qscopedpointer.h>
45#include <QtCore/qscopeguard.h>
46#include <QtCore/private/qwinregistry_p.h>
47#if QT_CONFIG(cpp_winrt)
48# include <QtCore/private/qfactorycacheregistration_p.h>
50#include <QtCore/private/qsystemerror_p.h>
51#include <QtCore/private/quniquehandle_types_windows_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.reset(GetDC(
nullptr));
168 m_defaultDPI = GetDeviceCaps(m_displayContext.get(), 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 if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) {
203#ifdef QT_USE_FACTORY_CACHE_REGISTRATION
204 detail::QWinRTFactoryCacheRegistration::clearAllCaches();
209 d->m_screenManager.clearScreens();
210 m_instance =
nullptr;
220 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
222 auto touchDevice = d->m_pointerHandler.touchDevice();
223 if (touchDevice.isNull()) {
224 const bool mouseEmulation =
225 (integrationOptions & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) == 0;
226 touchDevice = QWindowsPointerHandler::createTouchDevice(mouseEmulation);
228 if (touchDevice.isNull())
230 d->m_pointerHandler.setTouchDevice(touchDevice);
231 QWindowSystemInterface::registerInputDevice(touchDevice.data());
233 d->m_systemInfo |= QWindowsContext::SI_SupportsTouch;
243 if (QGuiApplicationPrivate::is_app_running
244 && (d->m_systemInfo & QWindowsContext::SI_SupportsTouch) != 0) {
245 for (QWindowsWindow *w : std::as_const(d->m_windows))
246 w->registerTouchWindow();
252#if QT_CONFIG(tabletevent)
253 d->m_tabletSupport.reset(QWindowsTabletSupport::create());
262#if QT_CONFIG(tabletevent)
263 d->m_tabletSupport.reset();
270LRESULT QT_WIN_CALLBACK qWindowsPowerWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
272 if (message != WM_POWERBROADCAST || wParam != PBT_POWERSETTINGCHANGE)
273 return DefWindowProc(hwnd, message, wParam, lParam);
275 static bool initialized =
false;
278 return DefWindowProc(hwnd, message, wParam, lParam);
281 auto setting =
reinterpret_cast<
const POWERBROADCAST_SETTING *>(lParam);
283 auto data =
reinterpret_cast<
const DWORD *>(&setting->Data);
286 const auto tlw = QGuiApplication::topLevelWindows();
288 if (w->isVisible() && w->windowState() != Qt::WindowMinimized) {
289 if (
auto tw = QWindowsWindow::windowsWindowOf(w)) {
290 if (HWND hwnd = tw->handle()) {
291 InvalidateRect(hwnd,
nullptr,
false);
298 return DefWindowProc(hwnd, message, wParam, lParam);
303 if (d->m_powerNotification)
306 d->m_powerDummyWindow = createDummyWindow(QStringLiteral(
"PowerDummyWindow"), L"QtPowerDummyWindow", qWindowsPowerWindowProc);
307 if (!d->m_powerDummyWindow)
310 d->m_powerNotification = RegisterPowerSettingNotification(d->m_powerDummyWindow, &GUID_MONITOR_POWER_ON, DEVICE_NOTIFY_WINDOW_HANDLE);
311 if (!d->m_powerNotification) {
312 DestroyWindow(d->m_powerDummyWindow);
313 d->m_powerDummyWindow =
nullptr;
321#if QT_CONFIG(tabletevent)
322 QWindowsTabletSupport::setAbsoluteRange(a);
330 d->m_keyMapper.setDetectAltGrModifier(a);
337 if (!IsValidDpiAwarenessContext(context))
356 const auto context = GetWindowDpiAwarenessContext(hwnd);
357 return dpiAwarenessContextToQtDpiAwareness(context);
369 const auto context = GetThreadDpiAwarenessContext();
370 return dpiAwarenessContextToQtDpiAwareness(context);
376 switch (dpiAwareness) {
379 case QtWindows::DpiAwareness::Unaware:
381 case QtWindows::DpiAwareness::System:
383 case QtWindows::DpiAwareness::PerMonitor:
385 case QtWindows::DpiAwareness::PerMonitorVersion2:
387 case QtWindows::DpiAwareness::Unaware_GdiScaled:
393#ifndef QT_NO_DEBUG_STREAM
396 const QDebugStateSaver saver(d);
397 QString message = u"QtWindows::DpiAwareness::"_s;
398 switch (dpiAwareness) {
399 case QtWindows::DpiAwareness::Invalid:
400 message += u"Invalid"_s;
402 case QtWindows::DpiAwareness::Unaware:
403 message += u"Unaware"_s;
405 case QtWindows::DpiAwareness::System:
406 message += u"System"_s;
408 case QtWindows::DpiAwareness::PerMonitor:
409 message += u"PerMonitor"_s;
411 case QtWindows::DpiAwareness::PerMonitorVersion2:
412 message += u"PerMonitorVersion2"_s;
414 case QtWindows::DpiAwareness::Unaware_GdiScaled:
415 message += u"Unaware_GdiScaled"_s;
418 d.nospace().noquote() << message;
425 qCDebug(lcQpaWindow) <<
__FUNCTION__ << dpiAwareness;
426 [[maybe_unused]]
const auto updatePMv2Status = qScopeGuard([](){
432 const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness);
433 if (!IsValidDpiAwarenessContext(context)) {
434 qCWarning(lcQpaWindow) << dpiAwareness <<
"is not supported by current system.";
437 if (!SetProcessDpiAwarenessContext(context)) {
438 qCWarning(lcQpaWindow).noquote().nospace()
439 <<
"SetProcessDpiAwarenessContext() failed: "
440 << QSystemError::windowsString()
441 <<
"\nQt's default DPI awareness context is "
442 <<
"DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
443 <<
"are doing, you can overwrite this default using qt.conf "
444 <<
"(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
457 return d->m_systemInfo;
462 return d->m_keyMapper.useRTLExtensions();
467 return &d->m_keyMapper;
477 const QSharedPointer<QWindowCreationContext> old = d->m_creationContext;
478 d->m_creationContext = ctx;
484 return d->m_creationContext;
489 return d->m_defaultDPI;
494 return d->m_displayContext.get();
499 return d->m_keyMapper.keyGrabber();
504 d->m_keyMapper.setKeyGrabber(w);
509 return GetDeviceCaps(d->m_displayContext.get(), BITSPIXEL);
514 d->m_windows.insert(hwnd, w);
519 const HandleBaseWindowHash::iterator it = d->m_windows.find(hwnd);
520 if (it != d->m_windows.end()) {
521 if (d->m_keyMapper.keyGrabber() == it.value()->window())
522 d->m_keyMapper.setKeyGrabber(
nullptr);
523 d->m_windows.erase(it);
529 for (
auto it = d->m_windows.cbegin(), end = d->m_windows.cend(); it != end; ++it) {
530 if ((*it)->menuBar() == mb)
538 return d->m_windows.value(hwnd);
548 for (HWND w = hwnd; w; w = GetParent(w)) {
549 window = d->m_windows.value(w);
567 return d->m_pointerHandler.windowUnderMouse();
572 d->m_pointerHandler.clearWindowUnderMouse();
576
577
578
579
580
581
582
583
584
585
591 POINT point = screenPoint;
592 screenToClient(*hwnd, &point);
594 const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags);
595 if (!child || child == *hwnd)
608 if (!(cwexFlags & CWP_SKIPTRANSPARENT)
609 && (GetWindowLongPtr(child, GWL_EXSTYLE) & WS_EX_TRANSPARENT)) {
610 const HWND nonTransparentChild = ChildWindowFromPointEx(*hwnd, point, cwexFlags | CWP_SKIPTRANSPARENT);
611 if (!nonTransparentChild || nonTransparentChild == *hwnd)
614 *result = nonTransparentWindow;
615 *hwnd = nonTransparentChild;
624 const QPoint &screenPointIn,
625 unsigned cwex_flags)
const
628 const POINT screenPoint = { screenPointIn.x(), screenPointIn.y() };
629 while (findPlatformWindowHelper(screenPoint, cwex_flags,
this, &parent, &result)) {}
632 if (result ==
nullptr) {
633 if (
const HWND window = WindowFromPoint(screenPoint))
642 const DWORD sessionId = WTSGetActiveConsoleSessionId();
643 if (sessionId != 0xFFFFFFFF) {
644 LPTSTR buffer =
nullptr;
646#if !defined(Q_CC_MINGW)
647 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
648 WTSSessionInfoEx, &buffer, &size) == TRUE
650 const WTSINFOEXW *info =
reinterpret_cast<WTSINFOEXW *>(buffer);
651 result = info->Level == 1 && info->Data.WTSInfoExLevel1.SessionFlags == WTS_SESSIONSTATE_LOCK;
652 WTSFreeMemory(buffer);
656 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId,
657 WTS_INFO_CLASS(25), &buffer, &size) == TRUE
659 const DWORD *p =
reinterpret_cast<DWORD *>(buffer);
660 const DWORD level = *p;
661 const DWORD sessionFlags = *(p + 4);
662 result = level == 1 && sessionFlags == 1;
663 WTSFreeMemory(buffer);
672 return d->m_mimeConverter;
677 return d->m_screenManager;
682#if QT_CONFIG(tabletevent)
683 return d->m_tabletSupport.data();
690
691
692
695 const wchar_t *windowName,
696 WNDPROC wndProc, DWORD style)
699 wndProc = DefWindowProc;
700 QString className = d->m_windowClassRegistry.registerWindowClass(classNameIn, wndProc);
701 return CreateWindowEx(0,
reinterpret_cast<LPCWSTR>(className.utf16()),
703 CW_USEDEFAULT, CW_USEDEFAULT,
704 CW_USEDEFAULT, CW_USEDEFAULT,
705 HWND_MESSAGE,
nullptr,
static_cast<HINSTANCE>(GetModuleHandle(
nullptr)),
nullptr);
711 SetWindowPos(hwnd,
nullptr, 0, 0, 0, 0,
712 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
718 const BOOL result = dpi != 0
719 ? SystemParametersInfoForDpi(action, param, out, 0, dpi)
720 : SystemParametersInfo(action, param, out, 0);
721 return result == TRUE;
725 const QPlatformScreen *screen)
731 const QPlatformWindow *win)
738 memset(ncm, 0,
sizeof(NONCLIENTMETRICS));
739 ncm->cbSize =
sizeof(NONCLIENTMETRICS);
744 const QPlatformScreen *screen)
746 const int dpi = screen ? qRound(screen->logicalDpi().first) : 0;
747 return nonClientMetrics(ncm,
unsigned(dpi));
750bool QWindowsContext::nonClientMetricsForWindow(NONCLIENTMETRICS *ncm,
const QPlatformWindow *win)
752 return nonClientMetricsForScreen(ncm, win ? win->screen() :
nullptr);
766 return window->isTopLevel()
769 && (window->surfaceType() != QSurface::OpenGLSurface
770 || QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL)
778 case WM_IME_STARTCOMPOSITION:
779 case WM_IME_ENDCOMPOSITION:
780 case WM_IME_COMPOSITION:
785 case WM_NCMOUSEHOVER:
786 case WM_NCMOUSELEAVE:
791 case WM_DWMNCRENDERINGCHANGED:
797 return (m >= WM_MOUSEFIRST && m <= WM_MOUSELAST)
798 || (m >= WM_NCMOUSEMOVE && m <= WM_NCXBUTTONDBLCLK)
799 || (m >= WM_KEYFIRST && m <= WM_KEYLAST);
806 if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
807 result = EnableNonClientDpiScaling(hwnd) != FALSE;
809 const DWORD errorCode = GetLastError();
810 qErrnoWarning(
int(errorCode),
"EnableNonClientDpiScaling() failed for HWND %p (%lu)",
818
819
820
821
825 WPARAM wParam, LPARAM lParam,
833 msg.message = message;
836 msg.time = GetMessageTime();
837 msg.pt.x = msg.pt.y = 0;
839 msg.pt.x = GET_X_LPARAM(lParam);
840 msg.pt.y = GET_Y_LPARAM(lParam);
844 clientToScreen(msg.hwnd, &msg.pt);
847 GetCursorPos(&msg.pt);
851 *platformWindowPtr = platformWindow;
855 if (!isInputMessage(msg.message) && filterNativeEvent(&msg, result))
858 if (platformWindow && filterNativeEvent(platformWindow->window(), &msg, result))
865 if (!windowsInputContext) {
871 return windowsInputContext->startComposition(hwnd);
873 return windowsInputContext->composition(hwnd, lParam);
875 return windowsInputContext->endComposition(hwnd);
877 return windowsInputContext->handleIME_Request(wParam, lParam, result);
893 qWarning() <<
"External WM_DESTROY received for " << platformWindow->window()
894 <<
", parent: " << platformWindow->window()->parent()
895 <<
", transient parent: " << platformWindow->window()->transientParent();
909#if QT_CONFIG(accessibility)
910 return QWindowsUiaAccessibility::handleWmGetObject(hwnd, wParam, lParam, result);
916 return d->m_screenManager.handleScreenChanges();
925 if (!platformWindow && !d->m_creationContext.isNull()) {
927 case QtWindows::QuerySizeHints:
928 d->m_creationContext->applyToMinMaxInfo(
reinterpret_cast<MINMAXINFO *>(lParam));
930 case QtWindows::ResizeEvent:
931 d->m_creationContext->obtainedSize = QSize(LOWORD(lParam), HIWORD(lParam));
933 case QtWindows::MoveEvent:
934 d->m_creationContext->obtainedPos = QPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
937 if (shouldHaveNonClientDpiScaling(d->m_creationContext->window) &&
940 !QWindowsContextPrivate::m_v2DpiAware) {
941 enableNonClientDpiScaling(msg.hwnd);
945 return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->window, d->m_creationContext->customMargins, msg, result);
947 return QWindowsWindow::handleGeometryChangingMessage(&msg, d->m_creationContext->window,
948 d->m_creationContext->margins + d->m_creationContext->customMargins);
953 if (platformWindow) {
958 qCDebug(lcQpaEvents) <<
"Event window: " << platformWindow->window();
960 qWarning(
"%s: No Qt Window found for event 0x%x (%s), hwnd=0x%p.",
961 __FUNCTION__, message,
962 QWindowsGuiEventDispatcher::windowsMessageName(message), hwnd);
968 if (d->m_systemInfo & QWindowsContext::SI_SupportsTouch)
971 if (wParam == DBT_DEVNODES_CHANGED)
976 wic->handleInputLanguageChanged(wParam, lParam);
978 case QtWindows::KeyDownEvent:
979 case QtWindows::KeyEvent:
980 case QtWindows::InputMethodKeyEvent:
981 case QtWindows::InputMethodKeyDownEvent:
982 case QtWindows::AppCommandEvent:
983 return sessionManagerInteractionBlocked() || d->m_keyMapper.translateKeyEvent(platformWindow->window(), hwnd, msg, result);
987 if (QWindowsPopupMenu::notifyAboutToShow(
reinterpret_cast<HMENU>(wParam)))
989 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
991 return platformWindow
->menuBar()->notifyAboutToShow(
reinterpret_cast<HMENU>(wParam));
995 if (QWindowsPopupMenu::notifyTriggered(LOWORD(wParam)))
997 if (platformWindow ==
nullptr || platformWindow
->menuBar() ==
nullptr)
999 return platformWindow
->menuBar()->notifyTriggered(LOWORD(wParam));
1004 QWindow *window = platformWindow->window();
1005 platformWindow->handleResized(
static_cast<
int>(wParam), lParam);
1006 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1011 platformWindow->getSizeHints(
reinterpret_cast<MINMAXINFO *>(lParam));
1014 return QWindowsGeometryHint::handleCalculateSize(platformWindow->window(), platformWindow->customMargins(), msg, result);
1016 QWindow *window = platformWindow->window();
1017 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1019 return platformWindow->handleNonClientHitTest(
QPoint(msg.pt.x, msg.pt.y), result);
1022 return platformWindow->handleNonClientActivate(result);
1024 return platformWindow->handleGeometryChanging(&msg);
1026 QWindow *window = platformWindow->window();
1027 if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
1029 return platformWindow->handleWmPaint(hwnd, message, wParam, lParam, result);
1034 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(platformWindow->window(), hwnd, et, msg, result);
1038 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1041 if (!IsZoomed(hwnd))
1046 platformWindow->checkForScreenChanged();
1047 handleExitSizeMove(platformWindow->window());
1048 if (!IsZoomed(hwnd))
1058 QWindow *window = platformWindow->window();
1059 while (window && (window->flags() & Qt::WindowTransparentForInput))
1060 window = window->parent();
1063 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translateMouseEvent(window, hwnd, et, msg, result);
1069 case QtWindows::PointerEvent:
1070 return sessionManagerInteractionBlocked() || d->m_pointerHandler.translatePointerEvent(platformWindow->window(), hwnd, et, msg, result);
1072 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus)
1076 handleFocusEvent(et, platformWindow);
1079 if (!platformWindow->window()->isVisible()) {
1087 case QtWindows::CloseEvent:
1088 QWindowSystemInterface::handleCloseEvent(platformWindow->window());
1097 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1098 *result = LRESULT(MA_NOACTIVATE);
1101#if QT_CONFIG(tabletevent)
1102 if (!d->m_tabletSupport.isNull())
1103 d->m_tabletSupport->notifyActivate();
1106 if (
const QWindow *modalWindow = QGuiApplication::modalWindow()) {
1107 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(modalWindow);
1108 Q_ASSERT(platformWindow);
1114 if (platformWindow->window()->flags() & Qt::WindowDoesNotAcceptFocus) {
1115 *result = LRESULT(MA_NOACTIVATE);
1119#ifndef QT_NO_CONTEXTMENU
1120 case QtWindows::ContextMenu:
1121 return handleContextMenuEvent(platformWindow->window(), msg);
1124#ifndef QT_NO_WHATSTHIS
1125 QWindowSystemInterface::handleEnterWhatsThisEvent();
1130 platformWindow->handleDpiScaledSize(wParam, lParam, result);
1133 platformWindow->handleDpiChanged(hwnd, wParam, lParam);
1136 platformWindow->handleDpiChangedAfterParent(hwnd);
1138#if QT_CONFIG(sessionmanager)
1139 case QtWindows::QueryEndSessionApplicationEvent: {
1140 QWindowsSessionManager *sessionManager = platformSessionManager();
1141 if (sessionManager->isActive()) {
1142 *result = sessionManager->wasCanceled() ? 0 : 1;
1146 sessionManager->setActive(
true);
1147 sessionManager->blocksInteraction();
1148 sessionManager->clearCancellation();
1150 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1151 qGuiAppPriv->commitData();
1153 if (lParam & ENDSESSION_LOGOFF)
1156 *result = sessionManager->wasCanceled() ? 0 : 1;
1159 case QtWindows::EndSessionApplicationEvent: {
1160 QWindowsSessionManager *sessionManager = platformSessionManager();
1162 sessionManager->setActive(
false);
1163 sessionManager->allowsInteraction();
1164 const bool endsession = wParam != 0;
1168 auto *qGuiAppPriv =
static_cast<QGuiApplicationPrivate*>(QObjectPrivate::get(qApp));
1169 if (endsession && !qGuiAppPriv->aboutToQuitEmitted) {
1170 qGuiAppPriv->aboutToQuitEmitted =
true;
1171 int index = QGuiApplication::staticMetaObject.indexOfSignal(
"aboutToQuit()");
1172 qApp->qt_metacall(QMetaObject::InvokeMetaMethod, index,
nullptr);
1174 QGuiApplication::quit();
1191
1192
1193
1194
1198 QWindow *nextActiveWindow =
nullptr;
1200 QWindow *topWindow = QWindowsWindow::topLevelOf(platformWindow->window());
1201 QWindow *modalWindow =
nullptr;
1202 if (QGuiApplicationPrivate::instance()->isWindowBlocked(topWindow, &modalWindow) && topWindow != modalWindow) {
1203 modalWindow->requestActivate();
1209 QWindow *currentFocusWindow = QGuiApplication::focusWindow();
1210 if (currentFocusWindow && currentFocusWindow != platformWindow->window()) {
1211 currentFocusWindow->requestActivate();
1215 nextActiveWindow = platformWindow->window();
1219 if (
const HWND nextActiveHwnd = GetFocus())
1220 if (
QWindowsWindow *nextActivePlatformWindow = findClosestPlatformWindow(nextActiveHwnd))
1221 if (nextActivePlatformWindow != platformWindow)
1222 nextActiveWindow = nextActivePlatformWindow->window();
1224 if (nextActiveWindow != d->m_lastActiveWindow) {
1225 d->m_lastActiveWindow = nextActiveWindow;
1226 QWindowSystemInterface::handleFocusWindowChanged(nextActiveWindow, Qt::ActiveWindowFocusReason);
1230#ifndef QT_NO_CONTEXTMENU
1231bool QWindowsContext::handleContextMenuEvent(QWindow *window,
const MSG &msg)
1233 bool mouseTriggered =
false;
1236 if (msg.lParam !=
int(0xffffffff)) {
1237 mouseTriggered =
true;
1238 globalPos.setX(msg.pt.x);
1239 globalPos.setY(msg.pt.y);
1240 pos = QWindowsGeometryHint::mapFromGlobal(msg.hwnd, globalPos);
1243 if (GetClientRect(msg.hwnd, &clientRect)) {
1244 if (pos.x() < clientRect.left || pos.x() >= clientRect.right ||
1245 pos.y() < clientRect.top || pos.y() >= clientRect.bottom)
1255 QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
1256 keyMapper()->queryKeyboardModifiers());
1273 const Qt::MouseButtons currentButtons = QWindowsPointerHandler::queryMouseButtons();
1274 const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons();
1275 if (currentButtons == appButtons)
1277 const Qt::KeyboardModifiers keyboardModifiers =
keyMapper()->queryKeyboardModifiers();
1278 const QPoint globalPos = QWindowsCursor::mousePosition();
1279 const QPlatformWindow *platWin = window->handle();
1280 const QPoint localPos = platWin->mapFromGlobal(globalPos);
1281 const QEvent::Type type = platWin->geometry().contains(globalPos)
1282 ? QEvent::MouseButtonRelease : QEvent::NonClientAreaMouseButtonRelease;
1283 for (Qt::MouseButton button : {Qt::LeftButton, Qt::RightButton, Qt::MiddleButton}) {
1284 if (appButtons.testFlag(button) && !currentButtons.testFlag(button)) {
1285 QWindowSystemInterface::handleMouseEvent(window, localPos, globalPos,
1286 currentButtons, button, type, keyboardModifiers);
1289 d->m_pointerHandler.clearEvents();
1294 return d->m_asyncExpose;
1299 d->m_asyncExpose = value;
1302DWORD
QWindowsContext::readAdvancedExplorerSettings(
const wchar_t *subKey, DWORD defaultValue)
1304 const auto advancedSettings = QWinRegistryKey(
1305 HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced)");
1306 return advancedSettings.value<DWORD>(subKey).value_or(defaultValue);
1311 return rect.right - rect.left == 0 && rect.bottom - rect.top == 0;
1316 return QMargins(client.left - frame.left, client.top - frame.top,
1317 frame.right - client.right, frame.bottom - client.bottom);
1322 RECT result = {0, 0, 0, 0};
1323 if (message == WM_NCCALCSIZE && wParam)
1324 result =
reinterpret_cast<
const NCCALCSIZE_PARAMS *>(lParam)->rgrc[n];
1330 WINDOWPLACEMENT windowPlacement;
1331 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1332 return GetWindowPlacement(hwnd, &windowPlacement) && windowPlacement.showCmd == SW_SHOWMINIMIZED;
1337 return (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) == 0;
1341
1342
1343
1344
1345
1346
1348LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1351 const QtWindows::WindowsEventType et = windowsEventType(message, wParam, lParam);
1352 QWindowsWindow *platformWindow =
nullptr;
1353 const RECT ncCalcSizeFrame = rectFromNcCalcSize(message, wParam, lParam, 0);
1354 const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow);
1355 if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
1356 if (
const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) {
1357 qCDebug(lcQpaEvents).nospace() <<
"EVENT: hwd=" << hwnd <<
' ' << eventName
1358 <<
" msg=0x" << Qt::hex << message <<
" et=0x" << et << Qt::dec <<
" wp="
1359 <<
int(wParam) <<
" at " << GET_X_LPARAM(lParam) <<
','
1360 << GET_Y_LPARAM(lParam) <<
" handled=" << handled;
1364 result = DefWindowProc(hwnd, message, wParam, lParam);
1370 if (message == WM_NCCALCSIZE && !isEmptyRect(ncCalcSizeFrame) && isTopLevel(hwnd) && !isMinimized(hwnd)) {
1371 const QMargins margins =
1372 marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0));
1373 if (margins.left() >= 0) {
1374 if (platformWindow) {
1375 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"WM_NCCALCSIZE for" << hwnd << margins;
1376 platformWindow->setFullFrameMargins(margins);
1378 const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext();
1380 ctx->margins = margins;
1393 QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance();
1394 qintptr filterResult = 0;
1395 if (dispatcher && dispatcher->filterNativeEvent(nativeEventType(), msg, &filterResult)) {
1396 *result = LRESULT(filterResult);
1405 qintptr filterResult = 0;
1406 if (QWindowSystemInterface::handleNativeEvent(window, nativeEventType(), msg, &filterResult)) {
1407 *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