4#include <QtCore/qt_windows.h>
5#include <QtGui/qstylehints.h>
10#if QT_CONFIG(draganddrop)
11# include "qwindowsdrag.h"
17#if QT_CONFIG(dynamicgl)
18# include "qwindowsglcontext.h"
24# include "qwindowscursor.h"
27#include <QtGui/qguiapplication.h>
28#include <QtGui/qscreen.h>
29#include <QtGui/qwindow.h>
30#include <QtGui/qregion.h>
31#include <QtGui/qopenglcontext.h>
32#include <QtGui/qpainterpath.h>
33#include <QtGui/private/qwindowsthemecache_p.h>
34#include <private/qwindow_p.h>
35#include <private/qguiapplication_p.h>
36#include <private/qhighdpiscaling_p.h>
37#include <qpa/qwindowsysteminterface.h>
38#include <private/qsystemlibrary_p.h>
39#include <private/qwinregistry_p.h>
42#include <QtCore/qdebug.h>
43#include <QtCore/qlibraryinfo.h>
44#include <QtCore/qoperatingsystemversion.h>
49#include "qwindowsvulkaninstance.h"
52#include <shellscalingapi.h>
54#include <private/qdxgivsyncservice_p.h>
57# define GWL_HWNDPARENT (-8
)
62using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>;
69Q_GUI_EXPORT HICON qt_pixmapToWinHICON(
const QPixmap &);
74 rc += QByteArray::number(qulonglong(style), 16);
79 if (style & WS_OVERLAPPED)
80 rc +=
" WS_OVERLAPPED";
81 if (style & WS_CLIPSIBLINGS)
82 rc +=
" WS_CLIPSIBLINGS";
83 if (style & WS_CLIPCHILDREN)
84 rc +=
" WS_CLIPCHILDREN";
85 if (style & WS_THICKFRAME)
86 rc +=
" WS_THICKFRAME";
87 if (style & WS_DLGFRAME)
89 if (style & WS_SYSMENU)
91 if (style & WS_MINIMIZEBOX)
92 rc +=
" WS_MINIMIZEBOX";
93 if (style & WS_MAXIMIZEBOX)
94 rc +=
" WS_MAXIMIZEBOX";
95 if (style & WS_BORDER)
97 if (style & WS_CAPTION)
99 if (style & WS_CHILDWINDOW)
100 rc +=
" WS_CHILDWINDOW";
101 if (style & WS_DISABLED)
102 rc +=
" WS_DISABLED";
103 if (style & WS_GROUP)
105 if (style & WS_HSCROLL)
107 if (style & WS_ICONIC)
109 if (style & WS_MAXIMIZE)
110 rc +=
" WS_MAXIMIZE";
111 if (style & WS_MINIMIZE)
112 rc +=
" WS_MINIMIZE";
113 if (style & WS_SIZEBOX)
115 if (style & WS_TABSTOP)
117 if (style & WS_TILED)
119 if (style & WS_VISIBLE)
121 if (style & WS_VSCROLL)
128 QByteArray rc =
"0x";
129 rc += QByteArray::number(qulonglong(exStyle), 16);
130 if (exStyle & WS_EX_TOOLWINDOW)
131 rc +=
" WS_EX_TOOLWINDOW";
132 if (exStyle & WS_EX_CONTEXTHELP)
133 rc +=
" WS_EX_CONTEXTHELP";
134 if (exStyle & WS_EX_LAYERED)
135 rc +=
" WS_EX_LAYERED";
136 if (exStyle & WS_EX_DLGMODALFRAME)
137 rc +=
" WS_EX_DLGMODALFRAME";
138 if (exStyle & WS_EX_LAYOUTRTL)
139 rc +=
" WS_EX_LAYOUTRTL";
140 if (exStyle & WS_EX_NOINHERITLAYOUT)
141 rc +=
" WS_EX_NOINHERITLAYOUT";
142 if (exStyle & WS_EX_ACCEPTFILES)
143 rc +=
" WS_EX_ACCEPTFILES";
144 if (exStyle & WS_EX_APPWINDOW)
145 rc +=
" WS_EX_APPWINDOW";
146 if (exStyle & WS_EX_CLIENTEDGE)
147 rc +=
" WS_EX_CLIENTEDGE";
148 if (exStyle & WS_EX_COMPOSITED)
149 rc +=
" WS_EX_COMPOSITED";
150 if (exStyle & WS_EX_CONTROLPARENT)
151 rc +=
" WS_EX_CONTROLPARENT";
152 if (exStyle & WS_EX_LEFT)
154 if (exStyle & WS_EX_LEFTSCROLLBAR)
155 rc +=
" WS_EX_LEFTSCROLLBAR";
156 if (exStyle & WS_EX_LTRREADING)
157 rc +=
" WS_EX_LTRREADING";
158 if (exStyle & WS_EX_MDICHILD)
159 rc +=
" WS_EX_MDICHILD";
160 if (exStyle & WS_EX_NOACTIVATE)
161 rc +=
" WS_EX_NOACTIVATE";
162 if (exStyle & WS_EX_NOPARENTNOTIFY)
163 rc +=
" WS_EX_NOPARENTNOTIFY";
164 if (exStyle & WS_EX_NOREDIRECTIONBITMAP)
165 rc +=
" WS_EX_NOREDIRECTIONBITMAP";
166 if (exStyle & WS_EX_RIGHT)
167 rc +=
" WS_EX_RIGHT";
168 if (exStyle & WS_EX_RIGHTSCROLLBAR)
169 rc +=
" WS_EX_RIGHTSCROLLBAR";
170 if (exStyle & WS_EX_RTLREADING)
171 rc +=
" WS_EX_RTLREADING";
172 if (exStyle & WS_EX_STATICEDGE)
173 rc +=
" WS_EX_STATICEDGE";
174 if (exStyle & WS_EX_TOPMOST)
175 rc +=
" WS_EX_TOPMOST";
176 if (exStyle & WS_EX_TRANSPARENT)
177 rc +=
" WS_EX_TRANSPARENT";
178 if (exStyle & WS_EX_WINDOWEDGE)
179 rc +=
" WS_EX_WINDOWEDGE";
185 QByteArray rc =
"0x";
186 rc += QByteArray::number(flags, 16);
187 if (flags & SWP_FRAMECHANGED)
188 rc +=
" SWP_FRAMECHANGED";
189 if (flags & SWP_HIDEWINDOW)
190 rc +=
" SWP_HIDEWINDOW";
191 if (flags & SWP_NOACTIVATE)
192 rc +=
" SWP_NOACTIVATE";
193 if (flags & SWP_NOCOPYBITS)
194 rc +=
" SWP_NOCOPYBITS";
195 if (flags & SWP_NOMOVE)
197 if (flags & SWP_NOOWNERZORDER)
198 rc +=
" SWP_NOOWNERZORDER";
199 if (flags & SWP_NOREDRAW)
200 rc +=
" SWP_NOREDRAW";
201 if (flags & SWP_NOSENDCHANGING)
202 rc +=
" SWP_NOSENDCHANGING";
203 if (flags & SWP_NOSIZE)
205 if (flags & SWP_NOZORDER)
206 rc +=
" SWP_NOZORDER";
207 if (flags & SWP_SHOWWINDOW)
208 rc +=
" SWP_SHOWWINDOW";
209 if (flags & SWP_ASYNCWINDOWPOS)
210 rc +=
" SWP_ASYNCWINDOWPOS";
211 if (flags & SWP_DEFERERASE)
212 rc +=
" SWP_DEFERERASE";
213 if (flags & SWP_DRAWFRAME)
214 rc +=
" SWP_DRAWFRAME";
215 if (flags & SWP_NOREPOSITION)
216 rc +=
" SWP_NOREPOSITION";
222 QByteArray rc =
"0x";
223 rc += QByteArray::number(flags, 16);
224 if (flags & WPF_SETMINPOSITION)
225 rc +=
" WPF_SETMINPOSITION";
226 if (flags & WPF_RESTORETOMAXIMIZED)
227 rc +=
" WPF_RESTORETOMAXIMIZED";
228 if (flags & WPF_ASYNCWINDOWPLACEMENT)
229 rc +=
" WPF_ASYNCWINDOWPLACEMENT";
236 rc += QByteArray::number(cmd);
239 if (cmd == SW_SHOWNORMAL)
240 rc +=
" SW_SHOWNORMAL";
241 if (cmd == SW_NORMAL)
243 if (cmd == SW_SHOWMINIMIZED)
244 rc +=
" SW_SHOWMINIMIZED";
245 if (cmd == SW_SHOWMAXIMIZED)
246 rc +=
" SW_SHOWMAXIMIZED";
247 if (cmd == SW_MAXIMIZE)
248 rc +=
" SW_MAXIMIZE";
249 if (cmd == SW_SHOWNOACTIVATE)
250 rc +=
" SW_SHOWNOACTIVATE";
253 if (cmd == SW_MINIMIZE)
254 rc +=
" SW_MINIMIZE";
255 if (cmd == SW_SHOWMINNOACTIVE)
256 rc +=
" SW_SHOWMINNOACTIVE";
257 if (cmd == SW_SHOWNA)
259 if (cmd == SW_RESTORE)
261 if (cmd == SW_SHOWDEFAULT)
262 rc +=
" SW_SHOWDEFAULT";
263 if (cmd == SW_FORCEMINIMIZE)
264 rc +=
" SW_FORCEMINIMIZE";
270 return QSize(rect.right -rect.left, rect.bottom - rect.top);
275 return QRect(QPoint(rect.left, rect.top), qSizeOfRect(rect));
280 const int x = rect.left();
281 const int y = rect.top();
282 RECT result = { x, y, x + rect.width(), y + rect.height() };
286#ifndef QT_NO_DEBUG_STREAM
287QDebug operator<<(QDebug d,
const RECT &r)
289 QDebugStateSaver saver(d);
291 d <<
"RECT(left=" << r.left <<
", top=" << r.top
292 <<
", right=" << r.right <<
", bottom=" << r.bottom
293 <<
" (" << r.right - r.left <<
'x' << r.bottom - r.top <<
"))";
297QDebug operator<<(QDebug d,
const POINT &p)
299 QDebugStateSaver saver(d);
301 d <<
"POINT(x=" << p.x <<
", y=" << p.y <<
')';
305QDebug operator<<(QDebug d,
const WINDOWPOS &wp)
307 QDebugStateSaver saver(d);
310 d <<
"WINDOWPOS(flags=" << debugWinSwpPos(wp.flags) <<
", hwnd="
311 << wp.hwnd <<
", hwndInsertAfter=" << wp.hwndInsertAfter <<
", x=" << wp.x
312 <<
", y=" << wp.y <<
", cx=" << wp.cx <<
", cy=" << wp.cy <<
')';
316QDebug operator<<(QDebug d,
const NCCALCSIZE_PARAMS &p)
318 QDebugStateSaver saver(d);
320 d <<
"NCCALCSIZE_PARAMS(rgrc=[" << p.rgrc[0] <<
", " << p.rgrc[1] <<
", "
321 << p.rgrc[2] <<
"], lppos=" << *p.lppos <<
')';
325QDebug operator<<(QDebug d,
const MINMAXINFO &i)
327 QDebugStateSaver saver(d);
329 d <<
"MINMAXINFO(maxSize=" << i.ptMaxSize <<
", "
330 <<
"maxpos=" << i.ptMaxPosition <<
", "
331 <<
"maxtrack=" << i.ptMaxTrackSize <<
", "
332 <<
"mintrack=" << i.ptMinTrackSize <<
')';
336QDebug operator<<(QDebug d,
const WINDOWPLACEMENT &wp)
338 QDebugStateSaver saver(d);
341 d <<
"WINDOWPLACEMENT(flags=" << debugWindowPlacementFlags(wp.flags) <<
", showCmd="
342 << debugShowWindowCmd(wp.showCmd) <<
", ptMinPosition=" << wp.ptMinPosition
343 <<
", ptMaxPosition=" << wp.ptMaxPosition <<
", rcNormalPosition="
344 << wp.rcNormalPosition <<
')';
348QDebug operator<<(QDebug d,
const GUID &guid)
350 QDebugStateSaver saver(d);
352 d <<
'{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(u'0')
353 << qSetFieldWidth(8) << guid.Data1
354 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
355 << guid.Data2 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
356 << guid.Data3 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
357 << qSetFieldWidth(2) << guid.Data4[0] << guid.Data4[1]
358 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(2);
359 for (
int i = 2; i < 8; ++i)
361 d << qSetFieldWidth(0) <<
'}';
368 d << r.width() <<
'x' << r.height() << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
373 d << m.left() <<
", " << m.top() <<
", " << m.right() <<
", " << m.bottom();
380 if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
383 const QWindowsScreen *screen = screenManager.screens().size() == 1
384 ? screenManager.screens().constFirst() : screenManager
.screenAtDp(point
);
386 return screen->availableGeometry().topLeft() - screen->geometry().topLeft();
394 RECT rect = { 0, 0, 0, 0 };
396 WINDOWPLACEMENT windowPlacement;
397 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
398 GetWindowPlacement(hwnd, &windowPlacement);
399 if (windowPlacement.showCmd == SW_SHOWMINIMIZED) {
400 const QRect result = qrectFromRECT(windowPlacement.rcNormalPosition);
401 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
404 GetWindowRect(hwnd, &rect);
405 const HWND parent = GetParent(hwnd);
406 if (parent && !topLevel) {
407 const int width = rect.right - rect.left;
408 const int height = rect.bottom - rect.top;
409 POINT leftTop = { rect.left, rect.top };
410 screenToClient(parent, &leftTop);
411 rect.left = leftTop.x;
412 rect.top = leftTop.y;
413 rect.right = leftTop.x + width;
414 rect.bottom = leftTop.y + height;
416 return qrectFromRECT(rect);
422 if (!IsWindowVisible(hwnd))
423 return QWindow::Hidden;
424 WINDOWPLACEMENT windowPlacement;
425 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
426 if (GetWindowPlacement(hwnd, &windowPlacement)) {
427 switch (windowPlacement.showCmd) {
428 case SW_SHOWMINIMIZED:
430 case SW_FORCEMINIMIZE:
431 return QWindow::Minimized;
432 case SW_SHOWMAXIMIZED:
433 return QWindow::Maximized;
438 return QWindow::Windowed;
443 switch (w->surfaceType()) {
444 case QSurface::OpenGLSurface:
445 case QSurface::VulkanSurface:
446 case QSurface::Direct3DSurface:
455 DWM_BLURBEHIND blurBehind = {0, 0,
nullptr, 0};
457 blurBehind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
458 blurBehind.fEnable = TRUE;
459 blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
461 const bool result = DwmEnableBlurBehindWindow(hwnd, &blurBehind) == S_OK;
463 if (blurBehind.hRgnBlur)
464 DeleteObject(blurBehind.hRgnBlur);
471 return !flags.testFlag(Qt::CustomizeWindowHint) || flags.testFlags(Qt::CustomizeWindowHint | button);
477 return !flags.testFlag(Qt::MSWindowsFixedSizeDialogHint) &&
478 (shouldShowTitlebarButton(flags, Qt::WindowMaximizeButtonHint) ||
479 w->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
484 const LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
485 return (style & WS_CHILD) || (flags & Qt::FramelessWindowHint);
491bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha, qreal opacity)
493 const LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
495 const bool needsLayered = (flags & Qt::WindowTransparentForInput)
496 || (hasAlpha && hasNoNativeFrame(hwnd, flags)) || opacity < 1.0;
497 const bool isLayered = (exStyle & WS_EX_LAYERED);
498 if (needsLayered != isLayered) {
500 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
502 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
508static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha,
bool accelerated, qreal level)
510 if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) {
511 const BYTE alpha = BYTE(qRound(255.0 * level));
512 if (hasAlpha && !accelerated && QWindowsWindow::hasNoNativeFrame(hwnd, flags)) {
514 BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
515 UpdateLayeredWindow(hwnd,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, 0, &blend, ULW_ALPHA);
517 SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
519 }
else if (IsWindowVisible(hwnd)) {
520 InvalidateRect(hwnd,
nullptr, TRUE);
529 return GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
530 + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
534
535
536
540 POINT pt = {screenPoint.x(), screenPoint.y()};
541 if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
544 if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
545 const int gap = getResizeBorderThickness(dpiX);
546 return QMargins(gap, 0, gap, gap);
554 const UINT dpi = GetDpiForWindow(hwnd);
555 const int gap = getResizeBorderThickness(dpi);
556 return QMargins(gap, 0, gap, gap);
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
592 void fromWindow(
const QWindow *w,
const Qt::WindowFlags flags,
unsigned creationFlags = 0);
595 void initialize(
const QWindow *w, HWND h,
bool frameChange, qreal opacityLevel)
const;
612 QDebugStateSaver saver(debug);
615 debug <<
"WindowCreationData: " << d.flags
618 debug <<
" parent=" << d.parentHandle;
619 debug <<
" popup=" << d.popup <<
" dialog=" << d.dialog
620 <<
" embedded=" << d.embedded <<
" tool=" << d.tool
621 <<
"\n style=" << debugWinStyle(d.style);
623 debug <<
"\n exStyle=" << debugWinExStyle(d.exStyle);
631 flags &= ~Qt::WindowFullscreenButtonHint;
634 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint
635 |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
639 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
644 if ((flags & Qt::WindowType_Mask) == Qt::SplashScreen)
645 flags |= Qt::FramelessWindowHint;
650 const auto getDeviceName = [](
const QScreen *screen) -> QString {
651 if (
const auto s =
static_cast<
const QWindowsScreen *>(screen->handle()))
652 return s->data().deviceName;
655 QScreen *winScreen = w ? w->screen() : QGuiApplication::primaryScreen();
656 if (winScreen && getDeviceName(winScreen) != name) {
657 const auto screens = winScreen->virtualSiblings();
658 for (QScreen *screen : screens) {
659 if (getDeviceName(screen) == name)
666static QPoint calcPosition(
const QWindow *w,
const QWindowCreationContextPtr &context,
const QMargins &invMargins)
668 const QPoint orgPos(context->frameX - invMargins.left(), context->frameY - invMargins.top());
670 if (!w || w->type() != Qt::Window)
674 const QScreen *screenForGL = QWindowsWindow::forcedScreenForGLWindow(w);
678 const QPoint posFrame(context->frameX, context->frameY);
679 const QMargins margins = context->margins;
680 const QRect scrGeo = screenForGL->handle()->availableGeometry();
683 if (scrGeo.contains(orgPos))
688 if (scrGeo.contains(posFrame))
692 const auto screens = screenForGL->virtualSiblings();
693 const QScreen *orgScreen =
nullptr;
694 for (QScreen *screen : screens) {
695 if (screen->handle()->availableGeometry().contains(posFrame)) {
700 const QPoint ctPos = QPoint(qMax(scrGeo.left(), scrGeo.center().x()
701 + (margins.right() - margins.left() - context->frameWidth)/2),
702 qMax(scrGeo.top(), scrGeo.center().y()
703 + (margins.bottom() - margins.top() - context->frameHeight)/2));
709 const QRect orgGeo = orgScreen->handle()->availableGeometry();
710 const QRect orgFrame(
QPoint(context->frameX, context->frameY),
711 QSize(context->frameWidth, context->frameHeight));
714 if (orgGeo.center() == (orgFrame - margins).center())
718 const QPoint newPos(scrGeo.left() + ((posFrame.x() - orgGeo.left()) * scrGeo.width()) / orgGeo.width(),
719 scrGeo.top() + ((posFrame.y() - orgGeo.top()) * scrGeo.height()) / orgGeo.height());
720 const QPoint newPosNoMargin(newPos.x() - invMargins.left(), newPos.y() - invMargins.top());
722 return scrGeo.contains(newPosNoMargin) ? newPosNoMargin : newPos;
726 unsigned creationFlags)
733 QVariant prop = w->property(QWindowsWindow::embeddedNativeParentHandleProperty);
734 if (prop.isValid()) {
736 parentHandle =
reinterpret_cast<HWND>(prop.value<WId>());
750 fixTopLevelWindowFlags(flags);
752 type =
static_cast<Qt::WindowType>(
int(flags) & Qt::WindowType_Mask);
768 if ((flags & Qt::MSWindowsFixedSizeDialogHint))
777 if (QGuiApplication::layoutDirection() == Qt::RightToLeft
778 && (QWindowsIntegration::instance()->options() & QWindowsIntegration::RtlEnabled) != 0) {
779 exStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
784 flags |= Qt::WindowStaysOnTopHint;
786 if (
const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
787 parentHandle = QWindowsWindow::handleOf(parentWindow);
790 if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
793 if (flags & Qt::FramelessWindowHint)
795 else if (flags & Qt::WindowTitleHint)
796 style = WS_OVERLAPPED;
803 style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
805 if (flags & Qt::WindowDoesNotAcceptFocus)
806 exStyle |= WS_EX_NOACTIVATE;
809 if ((type == Qt::Window || dialog || tool)) {
810 const bool defaultTitlebar = !flags.testFlag(Qt::CustomizeWindowHint);
811 if (!(flags & Qt::FramelessWindowHint)) {
813 if (flags & Qt::MSWindowsFixedSizeDialogHint) {
814 style |= WS_DLGFRAME;
816 style |= WS_THICKFRAME;
818 if (defaultTitlebar || flags.testFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint))
821 if (defaultTitlebar || flags.testFlags(Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint))
823 else if (dialog && (defaultTitlebar || flags.testFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint)) && !(flags & Qt::FramelessWindowHint)) {
824 style |= WS_SYSMENU | WS_BORDER;
825 exStyle |= WS_EX_DLGMODALFRAME;
827 const bool showMinimizeButton = shouldShowTitlebarButton(flags, Qt::WindowMinimizeButtonHint);
828 if (showMinimizeButton)
829 style |= WS_MINIMIZEBOX;
830 const bool showMaximizeButton = shouldShowMaximizeButton(w, flags);
831 if (showMaximizeButton)
832 style |= WS_MAXIMIZEBOX;
833 if (showMinimizeButton || showMaximizeButton)
836 exStyle |= WS_EX_TOOLWINDOW;
837 if ((flags & Qt::WindowContextHelpButtonHint) && !showMinimizeButton
838 && !showMaximizeButton)
839 exStyle |= WS_EX_CONTEXTHELP;
841 exStyle |= WS_EX_TOOLWINDOW;
846 if (flagsIn & Qt::WindowTransparentForInput)
847 exStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT;
850 if (qEnvironmentVariableIntValue(
"QT_QPA_DISABLE_REDIRECTION_SURFACE"))
851 exStyle |= WS_EX_NOREDIRECTIONBITMAP;
857 if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
861 if (!QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames))
866 auto *dWindow = QWindowPrivate::get(
const_cast<QWindow*>(w));
867 const QPalette windowPal = dWindow->windowPalette();
868 return windowPal.color(QPalette::WindowText).lightness()
869 > windowPal.color(QPalette::Window).lightness();
875 return getResizeBorderThickness(dpi) +
876 ::GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
883 result.flags = flags;
885 const auto appinst =
reinterpret_cast<HINSTANCE>(GetModuleHandle(
nullptr));
888 const QString windowTitlebarName = QWindowsContext::instance()->registerWindowClass(QStringLiteral(
"_q_titlebar"), DefWindowProc, CS_VREDRAW|CS_HREDRAW,
nullptr,
false);
890 const QScreen *screen{};
891 const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
892 defaultWindowWidth, defaultWindowHeight,
895 if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
896 title =
topLevel ? qAppName() : w->objectName();
898 const auto *titleUtf16 =
reinterpret_cast<
const wchar_t *>(title.utf16());
899 const auto *classNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowClassName.utf16());
900 const auto *classTitleBarNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowTitlebarName.utf16());
905 rect, data.customMargins,
909 const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME))
910 && !(result.flags & Qt::FramelessWindowHint);
911 QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w)
912 ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();
914 qCDebug(lcQpaWindow).nospace()
915 <<
"CreateWindowEx: " << w <<
" class=" << windowClassName <<
" title=" << title
916 <<
'\n' << *
this <<
"\nrequested: " << rect <<
": "
917 << context->frameWidth <<
'x' << context->frameHeight
918 <<
'+' << context->frameX <<
'+' << context->frameY
919 <<
" custom margins: " << context->customMargins
920 <<
" invisible margins: " << invMargins;
923 QPoint pos = calcPosition(w, context, invMargins);
926 int mirrorParentWidth = 0;
927 if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) {
929 GetClientRect(parentHandle, &rect);
930 mirrorParentWidth = rect.right;
932 if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT)
933 pos.setX(mirrorParentWidth - context->frameWidth - pos.x());
935 result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
938 context->frameWidth, context->frameHeight,
939 parentHandle,
nullptr, appinst,
nullptr);
941 const UINT dpi = ::GetDpiForWindow(result.hwnd);
942 const int titleBarHeight = getTitleBarHeight_sys(dpi);
943 result.hwndTitlebar = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,
944 classTitleBarNameUtf16, classTitleBarNameUtf16,
946 context->frameWidth, titleBarHeight,
947 nullptr,
nullptr, appinst,
nullptr);
949 qCDebug(lcQpaWindow).nospace()
950 <<
"CreateWindowEx: returns " << w <<
' ' << result.hwnd <<
" obtained geometry: "
951 << context->obtainedPos << context->obtainedSize <<
' ' << context->margins;
954 qErrnoWarning(
"%s: CreateWindowEx failed",
__FUNCTION__);
958 if (QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark && shouldApplyDarkFrame(w))
959 QWindowsWindow::setDarkBorderToWindow(result.hwnd,
true);
961 if (mirrorParentWidth != 0) {
962 context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
963 - context->obtainedPos.x());
966 QRect obtainedGeometry(context->obtainedPos, context->obtainedSize);
968 result.geometry = obtainedGeometry;
969 result.restoreGeometry = frameGeometry(result.hwnd, topLevel);
970 result.fullFrameMargins = context->margins;
973 result.customMargins = context->customMargins;
981 const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
982 const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
984 const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
985 if (oldStyle != newStyle)
986 SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
987 const LONG_PTR newExStyle =
exStyle;
988 if (newExStyle != oldExStyle)
989 SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
990 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << hwnd << *
this
991 <<
"\n Style from " << debugWinStyle(DWORD(oldStyle)) <<
"\n to "
992 << debugWinStyle(DWORD(newStyle)) <<
"\n ExStyle from "
993 << debugWinExStyle(DWORD(oldExStyle)) <<
" to "
994 << debugWinExStyle(DWORD(newExStyle));
1001 UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER;
1003 swpFlags |= SWP_FRAMECHANGED;
1005 swpFlags |= SWP_NOACTIVATE;
1006 if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
1007 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, swpFlags);
1008 if (flags & Qt::WindowStaysOnBottomHint)
1009 qWarning(
"QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time");
1010 }
else if (flags & Qt::WindowStaysOnBottomHint) {
1011 SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, swpFlags);
1012 }
else if (frameChange) {
1013 SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, swpFlags);
1015 if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
1016 HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
1017 if (flags & Qt::WindowCloseButtonHint)
1018 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
1020 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
1022 if (flags & Qt::ExpandedClientAreaHint) {
1023 MARGINS margins = { -1, -1, -1, -1 };
1024 DwmExtendFrameIntoClientArea(hwnd, &margins);
1026 MARGINS margins = { 0, 0, 0, 0 };
1027 DwmExtendFrameIntoClientArea(hwnd, &margins);
1030 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
1034 const bool hasAlpha = w->format().hasAlpha();
1035 if (isAccelerated && hasAlpha)
1036 applyBlurBehindWindow(hwnd);
1037 setWindowOpacity(hwnd, flags, hasAlpha, isAccelerated, opacityLevel);
1044 if (QHighDpiScaling::isActive()) {
1045 const qreal factor = QHighDpiScaling::factor(s);
1046 if (!qFuzzyCompare(factor, qreal(1))) {
1047 if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
1048 dip.setWidth(qRound(qreal(dip.width()) * factor));
1049 if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX)
1050 dip.setHeight(qRound(qreal(dip.height()) * factor));
1060 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1067 DWORD style = hwnd !=
nullptr ? DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)) : 0;
1068 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1072
1073
1074
1075
1076
1077
1078
1079
1083 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1085 RECT rect = {0,0,0,0};
1086 style &= ~DWORD(WS_OVERLAPPED);
1087 if (AdjustWindowRectEx(&rect, style, FALSE, exStyle) == FALSE)
1088 qErrnoWarning(
"%s: AdjustWindowRectEx failed",
__FUNCTION__);
1089 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1090 qAbs(rect.right), qAbs(rect.bottom));
1091 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1092 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1093 <<
' ' << rect <<
' ' << result;
1099 return frameOnPrimaryScreen(w, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1100 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1105 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1107 RECT rect = {0,0,0,0};
1108 style &= ~DWORD(WS_OVERLAPPED);
1109 if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
unsigned(qRound(dpi))) == FALSE) {
1110 qErrnoWarning(
"%s: AdjustWindowRectExForDpi failed",
__FUNCTION__);
1112 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1113 qAbs(rect.right), qAbs(rect.bottom));
1114 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1115 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1117 <<
' ' << rect <<
' ' << result;
1123 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1125 if (QWindowsScreenManager::isSingleScreen())
1126 return frameOnPrimaryScreen(w, style, exStyle);
1128 auto screen = screenManager.screenForHwnd(hwnd);
1130 screen = screenManager.screens().value(0);
1131 const auto dpi = screen ? screen->logicalDpi().first : qreal(96);
1132 return frame(w, style, exStyle, dpi);
1137 return frame(w, hwnd, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1138 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1143 DWORD style, DWORD exStyle)
1145 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1148 || !QWindowsContext::shouldHaveNonClientDpiScaling(w)) {
1149 return frameOnPrimaryScreen(w, style, exStyle);
1155 screen = screenManager.screens().value(0);
1157 dpi = screen->logicalDpi().first;
1158 return QWindowsGeometryHint::frame(w, style, exStyle, dpi);
1161bool QWindowsGeometryHint::handleCalculateSize(
const QWindow *window,
const QMargins &customMargins,
const MSG &msg, LRESULT *result)
1164 if (msg.wParam && window->flags() & Qt::FramelessWindowHint) {
1168 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window);
1170 const bool clientAreaExpanded = platformWindow !=
nullptr ? platformWindow->isClientAreaExpanded() : window->flags() & Qt::ExpandedClientAreaHint;
1172 if (msg.wParam && clientAreaExpanded) {
1174 const bool maximized = IsZoomed(msg.hwnd) && window->visibility() != QWindow::FullScreen;
1175 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1176 RECT *clientArea = &ncp->rgrc[0];
1177 const int border = getResizeBorderThickness(96);
1179 clientArea->top += border;
1180 clientArea->bottom -= border;
1181 clientArea->left += border;
1182 clientArea->right -= border;
1187 if (!msg.wParam || customMargins.isNull())
1189 *result = DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1190 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1191 const RECT oldClientArea = ncp->rgrc[0];
1192 ncp->rgrc[0].left += customMargins.left();
1193 ncp->rgrc[0].top += customMargins.top();
1194 ncp->rgrc[0].right -= customMargins.right();
1195 ncp->rgrc[0].bottom -= customMargins.bottom();
1197 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << oldClientArea <<
'+' << customMargins <<
"-->"
1198 << ncp->rgrc[0] <<
' ' << ncp->rgrc[1] <<
' ' << ncp->rgrc[2]
1199 <<
' ' << ncp->lppos->cx <<
',' << ncp->lppos->cy;
1204 const QMargins &margins,
1205 QSize *minimumSize, QSize *maximumSize)
1207 *minimumSize = toNativeSizeConstrained(w->minimumSize(), screen);
1208 *maximumSize = toNativeSizeConstrained(w->maximumSize(), screen);
1210 const int maximumWidth = qMax(maximumSize->width(), minimumSize->width());
1211 const int maximumHeight = qMax(maximumSize->height(), minimumSize->height());
1212 const int frameWidth = margins.left() + margins.right();
1213 const int frameHeight = margins.top() + margins.bottom();
1215 if (minimumSize->width() > 0)
1216 minimumSize->rwidth() += frameWidth;
1217 if (minimumSize->height() > 0)
1218 minimumSize->rheight() += frameHeight;
1219 if (maximumWidth < QWINDOWSIZE_MAX)
1220 maximumSize->setWidth(maximumWidth + frameWidth);
1221 if (maximumHeight < QWINDOWSIZE_MAX)
1222 maximumSize->setHeight(maximumHeight + frameHeight);
1226 const QScreen *screen,
1227 const QMargins &margins,
1232 frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize);
1233 qCDebug(lcQpaWindow).nospace() <<
'>' <<
__FUNCTION__ <<
'<' <<
" min="
1234 << minimumSize.width() <<
',' << minimumSize.height()
1235 <<
" max=" << maximumSize.width() <<
',' << maximumSize.height()
1236 <<
" margins=" << margins
1239 if (minimumSize.width() > 0)
1240 mmi->ptMinTrackSize.x = minimumSize.width();
1241 if (minimumSize.height() > 0)
1242 mmi->ptMinTrackSize.y = minimumSize.height();
1244 if (maximumSize.width() < QWINDOWSIZE_MAX)
1245 mmi->ptMaxTrackSize.x = maximumSize.width();
1246 if (maximumSize.height() < QWINDOWSIZE_MAX)
1247 mmi->ptMaxTrackSize.y = maximumSize.height();
1248 qCDebug(lcQpaWindow).nospace() <<
'<' <<
__FUNCTION__ <<
" out " << *mmi;
1252 const QMargins &margins,
1255 applyToMinMaxInfo(w, w->screen(), margins, mmi);
1260 return qt_window_private(
const_cast<QWindow *>(w))->positionPolicy
1261 == QWindowPrivate::WindowFrameInclusive;
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1283 return (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0;
1289 if (QPlatformWindow *pw = w->handle())
1290 return static_cast<QWindowsBaseWindow *>(pw);
1298 return bw ? bw->handle() : HWND(
nullptr);
1303 const HWND parent = parentHwnd();
1304 return !parent || parent == GetDesktopWindow();
1309 return frameGeometry(handle(), isTopLevel());
1314 return frameGeometry_sys().marginsRemoved(fullFrameMargins());
1319 return QWindowsGeometryHint::frame(window(), handle(), style(), exStyle());
1325 ULONG touchFlags = 0;
1326 if (IsTouchWindow(handle(), &touchFlags) == FALSE)
1328 TouchWindowTouchTypes result;
1329 if ((touchFlags & TWF_FINETOUCH) != 0)
1330 result.setFlag(TouchWindowTouchType::FineTouch);
1331 if ((touchFlags & TWF_WANTPALM) != 0)
1332 result.setFlag(TouchWindowTouchType::WantPalmTouch);
1338 SetWindowPos(handle(),
nullptr , 0, 0, 0, 0,
1339 SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1344 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1345 const Qt::WindowType type = window()->type();
1346 if (type == Qt::Popup
1347 || type == Qt::SubWindow
1348 || !(window()->flags() & Qt::WindowStaysOnBottomHint)) {
1349 SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1355 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1356 if (!(window()->flags() & Qt::WindowStaysOnTopHint))
1357 SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1362 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << title;
1363 SetWindowText(handle(),
reinterpret_cast<
const wchar_t *>(title.utf16()));
1368 return QWindowsGeometryHint::mapToGlobal(handle(), pos);
1373 return QWindowsGeometryHint::mapFromGlobal(handle(), pos);
1399 switch (event->type()) {
1400 case QEvent::ChildWindowAdded:
1401 if (!(GetWindowLongPtr(handle(), GWL_STYLE) & WS_CLIPCHILDREN)) {
1402 auto *childWindowEvent =
static_cast<QChildWindowEvent*>(event);
1403 qWarning() << childWindowEvent->child() <<
"added as child to"
1404 << window() <<
"which does not have WS_CLIPCHILDREN set."
1405 <<
"This will result in drawing artifacts!";
1412 return QPlatformWindow::windowEvent(event);
1416
1417
1418
1419
1420
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1437 , m_topLevelStyle(0)
1439 if (QPlatformWindow::parent())
1440 setParent(QPlatformWindow::parent());
1445 if (QPlatformWindow::parent())
1452 const HWND newParent = newParentWindow ?
reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(
nullptr);
1453 const bool isTopLevel = !newParent;
1454 const DWORD oldStyle =
style();
1456 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() <<
"newParent="
1457 << newParentWindow << newParent <<
"oldStyle=" << debugWinStyle(oldStyle);
1459 auto updateWindowFlags = [&] {
1461 DWORD newStyle = oldStyle;
1463 newStyle = m_topLevelStyle;
1465 m_topLevelStyle = oldStyle;
1466 newStyle &= ~(WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW);
1467 newStyle |= WS_CHILD;
1469 SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
1472 if (wasTopLevel && !isTopLevel) {
1475 updateWindowFlags();
1478 SetParent(m_hwnd, newParent);
1480 if (!wasTopLevel && isTopLevel) {
1483 updateWindowFlags();
1489 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << visible;
1491 ShowWindow(handle(), SW_SHOWNOACTIVATE);
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1517 const QRect &geometryIn,
const QRect &geometry,
1519 DWORD style, DWORD exStyle) :
1522 requestedGeometryIn(geometryIn),
1523 requestedGeometry(geometry),
1524 obtainedPos(geometryIn.topLeft()),
1525 obtainedSize(geometryIn.size()),
1526 margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle))
1533 if (!(w->flags() & Qt::FramelessWindowHint))
1536 if (geometry.isValid()
1537 || !qt_window_private(
const_cast<QWindow *>(w))->resizeAutomatic) {
1538 frameX = geometry.x();
1539 frameY = geometry.y();
1540 const QMargins effectiveMargins = margins + customMargins;
1541 frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right();
1542 frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom();
1544 menuHeight = GetSystemMetrics(SM_CYMENU);
1545 frameHeight += menuHeight;
1547 const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel();
1548 if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) {
1549 frameX -= effectiveMargins.left();
1550 frameY -= effectiveMargins.top();
1554 qCDebug(lcQpaWindow).nospace()
1555 <<
__FUNCTION__ <<
' ' << w <<
' ' << geometry
1556 <<
" pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w)
1557 <<
" frame=" << frameWidth <<
'x' << frameHeight <<
'+'
1558 << frameX <<
'+' << frameY
1559 <<
" margins=" << margins <<
" custom margins=" << customMargins;
1564 QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi);
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1596 m_cursor(
new CursorHandle)
1597#if QT_CONFIG(vulkan)
1598 , m_vkSurface(VK_NULL_HANDLE)
1601 QWindowsContext::instance()->addWindow(m_data.hwnd,
this);
1603 if (aWindow->flags().testFlags(Qt::ExpandedClientAreaHint)) {
1604 SetParent(m_data.hwndTitlebar, m_data.hwnd);
1605 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
1608 if (aWindow->surfaceType() == QWindow::Direct3DSurface)
1610#if QT_CONFIG(opengl)
1611 if (aWindow->surfaceType() == QWindow::OpenGLSurface)
1612 setFlag(OpenGLSurface);
1614#if QT_CONFIG(vulkan)
1615 if (aWindow->surfaceType() == QSurface::VulkanSurface)
1616 setFlag(VulkanSurface);
1618 updateDropSite(window()->isTopLevel());
1622 if (!touchWindowTouchTypes_sys().has_value())
1625 const qreal opacity = qt_window_private(aWindow)->opacity;
1626 if (!qFuzzyCompare(opacity, qreal(1.0)))
1627 setOpacity(opacity);
1629 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
1631 if (aWindow->isTopLevel())
1632 setWindowIcon(aWindow->icon());
1640 if (m_vsyncServiceCallbackId != 0)
1641 QDxgiVSyncService::instance()->unregisterCallback(m_vsyncServiceCallbackId);
1643 QWindowsThemeCache::clearThemeCache(m_data.hwnd);
1644 if (testFlag(TouchRegistered))
1645 UnregisterTouchWindow(m_data.hwnd);
1653 QWindowCreationContextPtr creationContext =
1656 QWindow *w = window();
1657 setWindowState(w->windowStates());
1661 const Qt::WindowState state = w->windowState();
1662 const QRect obtainedGeometry(creationContext->obtainedPos, creationContext->obtainedSize);
1663 QPlatformScreen *obtainedScreen = screenForGeometry(obtainedGeometry);
1664 if (obtainedScreen && screen() != obtainedScreen)
1665 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(w, obtainedScreen->screen());
1666 if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen
1667 && creationContext->requestedGeometryIn != obtainedGeometry) {
1668 QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
1670 QWindowsWindow::setSavedDpi(GetDpiForWindow(handle()));
1675 return window()->requestedFormat();
1678void QWindowsWindow::fireExpose(
const QRegion ®ion,
bool force)
1680 if (region.isEmpty() && !force)
1684 QWindowSystemInterface::handleExposeEvent(window(), region);
1689 fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), force);
1694 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << m_data.hwnd;
1698 const auto tlw = QGuiApplication::topLevelWindows();
1699 for (QWindow *w : tlw) {
1700 if (w->transientParent() == window()) {
1701 if (QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(w))
1702 tw->updateTransientParent();
1706 if (context->windowUnderMouse() == window())
1710 setDropSiteEnabled(
false);
1711#if QT_CONFIG(vulkan)
1713 QVulkanInstance *inst = window()->vulkanInstance();
1715 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
1716 m_vkSurface = VK_NULL_HANDLE;
1723 m_surface =
nullptr;
1726 DestroyWindow(m_data.hwnd);
1727 context->removeWindow(m_data.hwnd);
1728 m_data.hwnd =
nullptr;
1734 bool enabled =
false;
1735 bool parentIsEmbedded =
false;
1740 const QWindow *parent = window()->parent();
1741 if (parent && parent->handle() && parent->handle()->isForeignWindow())
1742 parentIsEmbedded =
true;
1745 if (topLevel || parentIsEmbedded) {
1746 switch (window()->type()) {
1759 setDropSiteEnabled(enabled);
1764 if (isDropSiteEnabled() == dropEnabled)
1766 qCDebug(lcQpaMime) <<
__FUNCTION__ << window() << dropEnabled;
1767#if QT_CONFIG(clipboard) && QT_CONFIG(draganddrop)
1769 Q_ASSERT(m_data.hwnd);
1770 m_dropTarget =
new QWindowsOleDropTarget(window());
1771 RegisterDragDrop(m_data.hwnd, m_dropTarget);
1772 CoLockObjectExternal(m_dropTarget,
true,
true);
1774 CoLockObjectExternal(m_dropTarget,
false,
true);
1775 m_dropTarget->Release();
1776 RevokeDragDrop(m_data.hwnd);
1777 m_dropTarget =
nullptr;
1786 m_screenForGLInitialized =
false;
1791 m_screenForGLInitialized =
false;
1796 static QString forceToScreen;
1797 if (!m_screenForGLInitialized) {
1799 m_screenForGLInitialized =
true;
1801 return forceToScreen.isEmpty() ?
nullptr : screenForDeviceName(w, forceToScreen);
1808 while (QWindow *parent = w->parent())
1811 if (
const QPlatformWindow *handle = w->handle()) {
1812 const auto *ww =
static_cast<
const QWindowsWindow *>(handle);
1813 if (ww->isEmbedded()) {
1814 HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
1815 const HWND desktopHwnd = GetDesktopWindow();
1817 while (parentHWND && parentHWND != desktopHwnd) {
1818 if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
1819 return topLevelOf(ancestor->window());
1820 parentHWND = GetAncestor(parentHWND, GA_PARENT);
1830 const QString &title)
1833 creationData.fromWindow(w, parameters.flags);
1836 creationData.initialize(w, result.hwnd, !parameters.customMargins.isNull(), 1);
1842 const QWindow *win = window();
1843 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << win << m_data.hwnd << visible;
1856 if (win->type() == Qt::Popup && !win->parent() && !QGuiApplication::focusWindow())
1857 SetForegroundWindow(m_data.hwnd);
1861 if (window()->flags() & Qt::Popup)
1862 ShowWindow(m_data.hwnd, SW_HIDE);
1865 fireExpose(QRegion());
1872 return m_data.hwnd && IsWindowVisible(m_data.hwnd);
1878 if (
const HWND activeHwnd = GetForegroundWindow())
1879 if (m_data.hwnd == activeHwnd || IsChild(activeHwnd, m_data.hwnd))
1886 const auto *childWindow =
static_cast<
const QWindowsWindow *>(child);
1887 return IsChild(m_data.hwnd, childWindow->handle());
1892 return m_data.embedded;
1897 return m_data.hwnd ? QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos) : pos;
1902 return m_data.hwnd ? QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos) : pos;
1912 if (window()->type() == Qt::Popup)
1915 const HWND oldTransientParent = GetWindow(m_data.hwnd, GW_OWNER);
1916 HWND newTransientParent =
nullptr;
1917 if (
const QWindow *tp = window()->transientParent())
1918 if (
const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp))
1920 newTransientParent = tw->handle();
1924 while (newTransientParent && (GetWindowLongPtr(newTransientParent, GWL_STYLE) & WS_CHILD) != 0)
1925 newTransientParent = GetParent(newTransientParent);
1927 if (newTransientParent != oldTransientParent)
1928 SetWindowLongPtr(m_data.hwnd,
GWL_HWNDPARENT, LONG_PTR(newTransientParent));
1934 const QVariant showWithoutActivating = window->property(
"_q_showWithoutActivating");
1935 return showWithoutActivating.isValid() && showWithoutActivating.toBool();
1940 WINDOWPLACEMENT windowPlacement;
1941 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1942 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1943 windowPlacement.showCmd = SW_SHOWMINIMIZED;
1944 windowPlacement.rcNormalPosition = RECTfromQRect(r);
1945 SetWindowPlacement(hwnd, &windowPlacement);
1952 WINDOWPLACEMENT windowPlacement;
1953 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1954 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1956 windowPlacement.flags |= WPF_RESTORETOMAXIMIZED;
1958 windowPlacement.flags &= ~WPF_RESTORETOMAXIMIZED;
1959 SetWindowPlacement(hwnd, &windowPlacement);
1966 int sm = SW_SHOWNORMAL;
1967 bool fakedMaximize =
false;
1968 bool restoreMaximize =
false;
1969 const QWindow *w = window();
1970 const Qt::WindowFlags flags = w->flags();
1971 const Qt::WindowType type = w->type();
1972 if (w->isTopLevel()) {
1973 const Qt::WindowStates state = w->windowStates();
1974 if (state & Qt::WindowMinimized) {
1975 sm = SW_SHOWMINIMIZED;
1977 sm = SW_SHOWMINNOACTIVE;
1978 if (state & Qt::WindowMaximized)
1979 restoreMaximize =
true;
1981 updateTransientParent();
1982 if (state & Qt::WindowMaximized) {
1983 sm = SW_SHOWMAXIMIZED;
1989 if (flags & Qt::WindowTitleHint &&
1990 !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
1991 fakedMaximize = TRUE;
1992 setStyle(style() | WS_MAXIMIZEBOX);
1997 if (type == Qt::Popup ||
1998 type == Qt::ToolTip ||
2000 (flags & Qt::WindowDoesNotAcceptFocus) ||
2001 testShowWithoutActivating(w))
2002 sm = SW_SHOWNOACTIVATE;
2004 if (w->windowStates() & Qt::WindowMaximized)
2007 ShowWindow(m_data.hwnd, sm);
2011 if (fakedMaximize) {
2012 setStyle(style() & ~WS_MAXIMIZEBOX);
2013 SetWindowPos(m_data.hwnd,
nullptr, 0, 0, 0, 0,
2014 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
2015 | SWP_FRAMECHANGED);
2017 if (restoreMaximize)
2018 setRestoreMaximizedFlag(m_data.hwnd);
2023 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << newParent;
2026 setParent_sys(newParent);
2032 HWND oldParentHWND = parentHwnd();
2033 HWND newParentHWND =
nullptr;
2035 const auto *parentW =
static_cast<
const QWindowsWindow *>(parent);
2036 newParentHWND = parentW->handle();
2041 HWND desktopHwnd = GetDesktopWindow();
2042 if (oldParentHWND == desktopHwnd)
2043 oldParentHWND =
nullptr;
2044 if (newParentHWND == desktopHwnd)
2045 newParentHWND =
nullptr;
2047 if (newParentHWND != oldParentHWND) {
2048 const bool wasTopLevel = oldParentHWND ==
nullptr;
2049 const bool isTopLevel = newParentHWND ==
nullptr;
2052 SetParent(m_data.hwnd, newParentHWND);
2058 if (wasTopLevel != isTopLevel) {
2059 setDropSiteEnabled(
false);
2060 setWindowFlags_sys(window()->flags(),
unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
2061 updateDropSite(isTopLevel);
2068 fireExpose(QRegion());
2073 const QWindow *w = window();
2074 if (windowIsAccelerated(w) && w->format().hasAlpha())
2075 applyBlurBehindWindow(handle());
2080 return QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) /
2081 QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi);
2091 const UINT dpi = UINT(wParam);
2092 const qreal scale = dpiRelativeScale(dpi);
2093 const QMargins margins = fullFrameMargins();
2094 if (!(m_data.flags & Qt::FramelessWindowHint)) {
2100 m_data.customMargins *= scale;
2103 const QSize windowSize = (geometry().size() * scale).grownBy((margins * scale) + customMargins());
2104 SIZE *size =
reinterpret_cast<SIZE *>(lParam);
2105 size->cx = windowSize.width();
2106 size->cy = windowSize.height();
2112 const UINT dpi = HIWORD(wParam);
2113 const qreal scale = dpiRelativeScale(dpi);
2116 QWindowsThemeCache::clearThemeCache(hwnd);
2119 const auto prcNewWindow =
reinterpret_cast<
const RECT *>(lParam);
2120 checkForScreenChanged(QWindowsWindow::FromDpiChange, !m_inSetgeometry ? prcNewWindow :
nullptr);
2122 if (!IsZoomed(hwnd))
2123 m_data.restoreGeometry.setSize(m_data.restoreGeometry.size() * scale);
2141 if (!m_inSetgeometry) {
2143 SetWindowPos(hwnd,
nullptr, prcNewWindow->left, prcNewWindow->top,
2144 prcNewWindow->right - prcNewWindow->left,
2145 prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
2149 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2150 handleGeometryChange();
2155 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
2160 const UINT dpi = GetDpiForWindow(hwnd);
2161 const qreal scale = dpiRelativeScale(dpi);
2164 checkForScreenChanged(QWindowsWindow::FromDpiChange);
2168 QRect currentGeometry = geometry();
2169 QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
2170 setGeometry(scaledGeometry);
2176 wp.length =
sizeof(WINDOWPLACEMENT);
2177 if (GetWindowPlacement(hwnd, &wp)) {
2178 const QRect result = qrectFromRECT(wp.rcNormalPosition);
2179 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
2187 const bool fakeFullScreen =
2188 m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen);
2189 const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
2190 const QMargins margins = fakeFullScreen
2191 ? QWindowsGeometryHint::frame(window(), handle(), m_savedStyle, 0)
2192 : fullFrameMargins();
2193 return frame.isValid() ? frame.marginsRemoved(margins) : frame;
2198 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
2199 const int titleBarHeight = getTitleBarHeight_sys(96);
2201 return QMargins(0, titleBarHeight, 0, 0);
2207 const QRect &requestedRect,
2208 const QRect &obtainedRect,
2209 const QMargins &fullMargins,
2210 const QMargins &customMargins)
2213 QDebug debug(&result);
2216 const auto window = platformWindow->window();
2217 debug <<
"Unable to set geometry ";
2218 formatBriefRectangle(debug, requestedRect);
2219 debug <<
" (frame: ";
2220 formatBriefRectangle(debug, requestedRect + fullMargins);
2221 debug <<
") on " << window->metaObject()->className() <<
"/\""
2222 << window->objectName() <<
"\" on \"" << window->screen()->name()
2223 <<
"\". Resulting geometry: ";
2224 formatBriefRectangle(debug, obtainedRect);
2225 debug <<
" (frame: ";
2226 formatBriefRectangle(debug, obtainedRect + fullMargins);
2227 debug <<
") margins: ";
2228 formatBriefMargins(debug, fullMargins);
2229 if (!customMargins.isNull()) {
2230 debug <<
" custom margin: ";
2231 formatBriefMargins(debug, customMargins);
2233 const auto minimumSize = window->minimumSize();
2234 const bool hasMinimumSize = !minimumSize.isEmpty();
2236 debug <<
" minimum size: " << minimumSize.width() <<
'x' << minimumSize.height();
2237 const auto maximumSize = window->maximumSize();
2238 const bool hasMaximumSize = maximumSize.width() != QWINDOWSIZE_MAX || maximumSize.height() != QWINDOWSIZE_MAX;
2240 debug <<
" maximum size: " << maximumSize.width() <<
'x' << maximumSize.height();
2241 if (hasMinimumSize || hasMaximumSize) {
2242 MINMAXINFO minmaxInfo;
2243 memset(&minmaxInfo, 0,
sizeof(minmaxInfo));
2244 platformWindow->getSizeHints(&minmaxInfo);
2245 debug <<
' ' << minmaxInfo;
2253 QScopedValueRollback b(m_inSetgeometry,
true);
2255 QRect rect = rectIn;
2258 if (QWindowsGeometryHint::positionIncludesFrame(window())) {
2259 const QMargins margins = frameMargins();
2260 rect.moveTopLeft(rect.topLeft() +
QPoint(margins.left(), margins.top()));
2262 if (m_windowState & Qt::WindowMinimized)
2263 m_data.geometry = rect;
2269 setGeometry_sys(rect);
2271 if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) {
2272 const auto warning =
2273 msgUnableToSetGeometry(
this, rectIn, m_data.geometry,
2274 fullFrameMargins(), customMargins());
2275 qWarning(
"%s: %s",
__FUNCTION__, qPrintable(warning));
2278 QPlatformWindow::setGeometry(rect);
2285 if (!IsIconic(m_data.hwnd) && !testFlag(WithinSetParent))
2286 handleGeometryChange();
2292 if ((m_data.flags.testFlag(Qt::FramelessWindowHint)
2293 || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))
2294 && IsZoomed(m_data.hwnd)) {
2295 const int resizedWidth = LOWORD(lParam);
2296 const int resizedHeight = HIWORD(lParam);
2298 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTOPRIMARY);
2299 MONITORINFO monitorInfo = {};
2300 monitorInfo.cbSize =
sizeof(MONITORINFO);
2301 GetMonitorInfoW(monitor, &monitorInfo);
2303 int correctLeft = monitorInfo.rcMonitor.left;
2304 int correctTop = monitorInfo.rcMonitor.top;
2305 int correctWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
2306 int correctHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
2308 if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
2309 const int borderWidth = invisibleMargins(m_data.hwnd).left();
2310 correctLeft -= borderWidth;
2311 correctTop -= borderWidth;
2312 correctWidth += borderWidth * 2;
2313 correctHeight += borderWidth * 2;
2316 if (resizedWidth != correctWidth || resizedHeight != correctHeight) {
2317 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"correcting: " << resizedWidth <<
"x"
2318 << resizedHeight <<
" -> " << correctWidth <<
"x" << correctHeight;
2319 SetWindowPos(m_data.hwnd,
nullptr, correctLeft, correctTop, correctWidth, correctHeight,
2320 SWP_NOZORDER | SWP_NOACTIVATE);
2328 case SIZE_MINIMIZED:
2329 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2330 handleWindowStateChange(m_windowState | Qt::WindowMinimized);
2332 case SIZE_MAXIMIZED:
2333 handleGeometryChange();
2334 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2335 handleWindowStateChange(Qt::WindowMaximized | (isFullScreen_sys() ? Qt::WindowFullScreen
2336 : Qt::WindowNoState));
2339 handleGeometryChange();
2341 if (isFullScreen_sys())
2342 handleWindowStateChange(
2343 Qt::WindowFullScreen
2344 | (testFlag(MaximizeToFullScreen) ? Qt::WindowMaximized : Qt::WindowNoState));
2345 else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
2346 handleWindowStateChange(Qt::WindowNoState);
2352static inline bool equalDpi(
const QDpi &d1,
const QDpi &d2)
2354 return qFuzzyCompare(d1.first, d2.first) && qFuzzyCompare(d1.second, d2.second);
2362 QPlatformScreen *currentScreen = screen();
2363 auto topLevel = isTopLevel_sys() ? m_data.hwnd : GetAncestor(m_data.hwnd, GA_ROOT);
2368 if (newScreen ==
nullptr || newScreen == currentScreen)
2372 const bool changingDpi = !equalDpi(QDpi(savedDpi(), savedDpi()), newScreen->logicalDpi());
2376 qCDebug(lcQpaWindow).noquote().nospace() <<
__FUNCTION__
2377 <<
' ' << window() <<
" \"" << (currentScreen ? currentScreen->name() : QString())
2378 <<
"\"->\"" << newScreen->name() <<
'"';
2380 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
2385 const QRect previousGeometry = m_data.geometry;
2386 m_data.geometry = geometry_sys();
2388 QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
2393 && m_data.geometry.size() != previousGeometry.size()
2395 && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
2396 fireFullExpose(
true);
2400 checkForScreenChanged();
2402 if (testFlag(SynchronousGeometryChangeEvent))
2403 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2410 qCDebug(lcQpaEvents) <<
__FUNCTION__ <<
this << window() << m_data.geometry;
2412 if (m_data.flags & Qt::ExpandedClientAreaHint) {
2413 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
2414 MoveWindow(m_data.hwndTitlebar, 0, 0, m_data.geometry.width(), titleBarHeight,
true);
2420 const QMargins margins = fullFrameMargins();
2421 const QRect frameGeometry = rect + margins;
2423 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ << window()
2424 <<
"\n from " << geometry_sys() <<
" frame: "
2425 << margins <<
" to " <<rect
2426 <<
" new frame: " << frameGeometry;
2428 bool result =
false;
2429 const HWND hwnd = handle();
2430 WINDOWPLACEMENT windowPlacement;
2431 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2432 GetWindowPlacement(hwnd, &windowPlacement);
2435 if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(hwnd))
2436 || windowPlacement.showCmd == SW_SHOWMINIMIZED) {
2437 windowPlacement.rcNormalPosition =
2438 RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(hwnd, frameGeometry.topLeft())));
2439 windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
2440 result = SetWindowPlacement(hwnd, &windowPlacement);
2442 int x = frameGeometry.x();
2443 if (!window()->isTopLevel()) {
2444 const HWND parentHandle = GetParent(hwnd);
2445 if (isRtlLayout(parentHandle)) {
2447 GetClientRect(parentHandle, &rect);
2448 x = rect.right - frameGeometry.width() - x;
2451 result = MoveWindow(hwnd, x, frameGeometry.y(),
2452 frameGeometry.width(), frameGeometry.height(),
true);
2454 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ << window()
2455 <<
"\n resulting " << result << geometry_sys();
2459
2460
2461
2462
2463
2468 m_hdc = GetDC(handle());
2469 if (QGuiApplication::layoutDirection() == Qt::RightToLeft)
2470 SetLayout(m_hdc, 0);
2476
2477
2478
2479
2480
2485 ReleaseDC(handle(), m_hdc);
2492#if QT_CONFIG(dynamicgl)
2493 return QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()
2494 && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL;
2503 if (message == WM_ERASEBKGND) {
2508 if (!window()->isVisible() && (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0)
2511 if (!GetUpdateRect(m_data.hwnd, 0, FALSE))
2518 InvalidateRect(hwnd,
nullptr,
false);
2520 BeginPaint(hwnd, &ps);
2525 fireExpose(QRegion(qrectFromRECT(ps.rcPaint)),
true);
2526 if (!QWindowsContext::instance()->asyncExpose())
2527 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2529 EndPaint(hwnd, &ps);
2535 m_windowTitle = QWindowsWindow::formatWindowTitle(title);
2536 setWindowTitle_sys(m_windowTitle);
2541 return m_windowTitle;
2546 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window() <<
"\n from: "
2547 << m_data.flags <<
"\n to: " << flags;
2548 const QRect oldGeometry = geometry();
2549 if (m_data.flags != flags) {
2550 m_data.flags = flags;
2552 m_data = setWindowFlags_sys(flags);
2553 updateDropSite(window()->isTopLevel());
2560 const QRect newGeometry = geometry_sys();
2561 if (oldGeometry != newGeometry)
2562 handleGeometryChange();
2564 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
"\n returns: "
2565 << m_data.flags <<
" geometry " << oldGeometry <<
"->" << newGeometry;
2569 unsigned flags)
const
2572 creationData.fromWindow(window(), wt, flags);
2573 creationData.applyWindowFlags(m_data.hwnd);
2574 creationData.initialize(window(), m_data.hwnd,
true, m_opacity);
2576 if (creationData.flags.testFlag(Qt::ExpandedClientAreaHint)) {
2577 SetParent(m_data.hwndTitlebar, m_data.hwnd);
2578 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
2580 if (IsWindowVisible(m_data.hwndTitlebar)) {
2581 SetParent(m_data.hwndTitlebar, HWND_MESSAGE);
2582 ShowWindow(m_data.hwndTitlebar, SW_HIDE);
2587 result.flags = creationData.flags;
2589 result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME))
2590 && !(creationData.flags & Qt::FramelessWindowHint);
2594void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
2596 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window()
2597 <<
"\n from " << m_windowState <<
" to " << state;
2598 m_windowState = state;
2599 QWindowSystemInterface::handleWindowStateChanged(window(), state);
2600 if (state & Qt::WindowMinimized) {
2602 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2605 if (state & Qt::WindowMaximized) {
2606 WINDOWPLACEMENT windowPlacement{};
2607 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2608 GetWindowPlacement(m_data.hwnd, &windowPlacement);
2609 const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
2610 windowPlacement.rcNormalPosition = geometry;
2611 correctWindowPlacement(windowPlacement);
2617 windowPlacement.showCmd = SW_HIDE;
2618 SetWindowPlacement(m_data.hwnd, &windowPlacement);
2622 QWindow *w = window();
2623 bool exposeEventsSent =
false;
2626 exposeEventsSent =
true;
2628 const QWindowList allWindows = QGuiApplication::allWindows();
2629 for (QWindow *child : allWindows) {
2630 if (child != w && child->isVisible() && child->transientParent() == w) {
2631 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
2632 if (platformWindow && platformWindow->isLayered()) {
2633 platformWindow->fireFullExpose();
2634 exposeEventsSent =
true;
2638 if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
2639 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2648 return window()->maximumHeight() != QWINDOWSIZE_MAX;
2653 return window()->maximumWidth() != QWINDOWSIZE_MAX;
2661void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
2663 static const auto windows11 = QOperatingSystemVersion::Windows11_21H2;
2664 static const bool isWindows10 = QOperatingSystemVersion::current() < windows11;
2670 const QPoint offset = windowPlacementOffset(m_data.hwnd, m_data.restoreGeometry.topLeft());
2671 windowPlacement.rcNormalPosition = RECTfromQRect(m_data.restoreGeometry.translated(-offset));
2672 qCDebug(lcQpaWindow) <<
"Corrected normal position by" << -offset;
2681 const QMargins margins = frameMargins_sys();
2682 const QPoint topLeft = window()->screen()->geometry().topLeft();
2683 windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() };
2684 qCDebug(lcQpaWindow) <<
"Window has maximum size. Corrected topLeft by"
2690 const int adjust = offset.x() / window()->devicePixelRatio();
2691 window()->setWidth(window()->width() - adjust);
2692 qCDebug(lcQpaWindow) <<
"Width shortened by" << adjust <<
"logical pixels.";
2695 const int adjust = offset.y() / window()->devicePixelRatio();
2696 window()->setHeight(window()->height() - adjust);
2697 qCDebug(lcQpaWindow) <<
"Height shortened by" << adjust <<
"logical pixels.";
2704 m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
2710 setWindowState_sys(state);
2711 m_windowState = state;
2717 const QWindow *w = window();
2718 if (!w->isTopLevel())
2720 QRect geometry = geometry_sys();
2722 geometry += QMargins(1, 1, 1, 1);
2723 QPlatformScreen *screen = screenForGeometry(geometry);
2724 return screen && geometry == screen->geometry();
2728
2729
2730
2731
2732
2733
2734
2735
2736
2738void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
2740 const Qt::WindowStates oldState = m_windowState;
2741 if (oldState == newState)
2743 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window()
2744 <<
" from " << oldState <<
" to " << newState;
2747 auto stateChange = oldState ^ newState;
2749 if (stateChange & Qt::WindowFullScreen) {
2750 if (newState & Qt::WindowFullScreen) {
2751 UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
2755 if (!m_savedStyle) {
2756 m_savedStyle =
style();
2757 if ((oldState & Qt::WindowMinimized) || (oldState & Qt::WindowMaximized)) {
2758 const QRect nf = normalFrameGeometry(m_data.hwnd);
2760 m_savedFrameGeometry = nf;
2762 m_savedFrameGeometry = frameGeometry_sys();
2765 if (newState & Qt::WindowMaximized)
2767 if (m_savedStyle & WS_SYSMENU)
2768 newStyle |= WS_SYSMENU;
2770 newStyle |= WS_VISIBLE;
2771 if (testFlag(HasBorderInFullScreen))
2772 newStyle |= WS_BORDER;
2774 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2775 MONITORINFO monitorInfo = {};
2776 monitorInfo.cbSize =
sizeof(MONITORINFO);
2777 GetMonitorInfoW(monitor, &monitorInfo);
2778 const QRect screenGeometry(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
2779 monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
2780 monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
2781 if (newState & Qt::WindowMinimized) {
2782 setMinimizedGeometry(m_data.hwnd, screenGeometry);
2783 if (stateChange & Qt::WindowMaximized)
2784 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2786 const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
2789 SetWindowPos(m_data.hwnd, HWND_TOP, screenGeometry.left(), screenGeometry.top(), screenGeometry.width(), screenGeometry.height(), swpf);
2793 QWindowSystemInterface::handleGeometryChange(window(), screenGeometry);
2794 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2798 unsigned newStyle = m_savedStyle ? m_savedStyle :
style();
2800 newStyle |= WS_VISIBLE;
2803 const QScreen *screen = window()->screen();
2805 screen = QGuiApplication::primaryScreen();
2807 if (
const auto platformScreen = screen->handle()) {
2808 if (!platformScreen->geometry().intersects(m_savedFrameGeometry))
2809 m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft());
2812 if (newState & Qt::WindowMinimized) {
2813 setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry);
2814 if (stateChange & Qt::WindowMaximized)
2815 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2817 UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
2818 if (!m_savedFrameGeometry.isValid())
2819 swpf |= SWP_NOSIZE | SWP_NOMOVE;
2824 if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
2825 ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
2826 SetWindowPos(m_data.hwnd,
nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
2827 m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
2833 ShowWindow(m_data.hwnd,
2834 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
2839 m_savedFrameGeometry = QRect();
2841 }
else if ((oldState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
2842 if (visible && !(newState & Qt::WindowMinimized)) {
2844 if (newState & Qt::WindowFullScreen)
2846 if (m_data.flags & Qt::FramelessWindowHint) {
2847 if (newState == Qt::WindowNoState) {
2848 const QRect &rect = m_savedFrameGeometry;
2849 MoveWindow(m_data.hwnd, rect.x(), rect.y(), rect.width(), rect.height(),
true);
2851 HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2852 MONITORINFO monitorInfo = {};
2853 monitorInfo.cbSize =
sizeof(MONITORINFO);
2854 GetMonitorInfo(monitor, &monitorInfo);
2855 const RECT &rect = monitorInfo.rcWork;
2856 m_savedFrameGeometry = geometry();
2857 MoveWindow(m_data.hwnd, rect.left, rect.top,
2858 rect.right - rect.left, rect.bottom - rect.top,
true);
2861 ShowWindow(m_data.hwnd,
2862 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
2866 }
else if (visible && (oldState & newState & Qt::WindowMinimized)) {
2868 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2872 if (stateChange & Qt::WindowMinimized) {
2874 ShowWindow(m_data.hwnd,
2875 (newState & Qt::WindowMinimized) ? SW_MINIMIZE :
2876 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
2877 if ((newState & Qt::WindowMinimized) && (stateChange & Qt::WindowMaximized))
2878 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2881 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
this << window() << newState;
2886 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinStyle(s);
2888 SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
2894 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinExStyle(s);
2895 SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
2900 switch (event->type()) {
2901 case QEvent::ApplicationPaletteChange:
2902 setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
2904 case QEvent::WindowBlocked:
2910 case QEvent::WindowUnblocked:
2918 return QWindowsBaseWindow::windowEvent(event);
2923 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
2928 bool result =
false;
2929 if ((windowPos->flags & SWP_NOSIZE) == 0) {
2931 GetWindowRect(windowPos->hwnd, &rect);
2932 result = rect.right - rect.left != windowPos->cx || rect.bottom - rect.top != windowPos->cy;
2937bool QWindowsWindow::handleGeometryChangingMessage(MSG *message,
const QWindow *qWindow,
const QMargins &margins)
2939 auto *windowPos =
reinterpret_cast<WINDOWPOS *>(message->lParam);
2940 const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
2941 windowPos->cx, windowPos->cy);
2942 const QRect suggestedGeometry = suggestedFrameGeometry - margins;
2949 if (isResize(windowPos))
2950 windowPos->flags |= SWP_NOCOPYBITS;
2952 if ((windowPos->flags & SWP_NOZORDER) == 0) {
2953 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(qWindow)) {
2954 QWindow *parentWindow = qWindow->parent();
2955 HWND parentHWND = GetAncestor(windowPos->hwnd, GA_PARENT);
2956 HWND desktopHWND = GetDesktopWindow();
2957 platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND);
2959 if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint))
2960 windowPos->hwndInsertAfter = HWND_BOTTOM;
2962 if (!qWindow->isTopLevel())
2964 if (windowPos->flags & SWP_NOSIZE)
2966 const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
2967 if (!correctedGeometryF.isValid())
2969 const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
2970 if (correctedFrameGeometry == suggestedFrameGeometry)
2972 windowPos->x = correctedFrameGeometry.left();
2973 windowPos->y = correctedFrameGeometry.top();
2974 windowPos->cx = correctedFrameGeometry.width();
2975 windowPos->cy = correctedFrameGeometry.height();
2981 const QMargins margins = window()->isTopLevel() ? fullFrameMargins() : QMargins();
2982 return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
2987 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2989 if (m_data.fullFrameMargins != newMargins) {
2990 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << m_data.fullFrameMargins <<
"->" << newMargins;
2991 m_data.fullFrameMargins = newMargins;
2998 if (GetMenu(m_data.hwnd))
2999 QWindowsContext::forceNcCalcSize(m_data.hwnd);
3001 calculateFullFrameMargins();
3006 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3019 GetWindowRect(handle(), &windowRect);
3020 GetClientRect(handle(), &clientRect);
3026 if (qrectFromRECT(windowRect).size() == qrectFromRECT(clientRect).size())
3031 const auto systemMargins = testFlag(DisableNonClientScaling)
3032 ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd)
3033 : frameMargins_sys();
3034 const int extendedClientAreaBorder = window()->flags().testFlag(Qt::ExpandedClientAreaHint) ? qRound(QHighDpiScaling::factor(window())) * 2 : 0;
3035 const QMargins actualMargins = systemMargins + customMargins() - extendedClientAreaBorder;
3037 const int yDiff = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
3038 const bool typicalFrame = (actualMargins.left() == actualMargins.right())
3039 && (actualMargins.right() == actualMargins.bottom());
3041 const QMargins adjustedMargins = typicalFrame ?
3042 QMargins(actualMargins.left(), (yDiff - actualMargins.bottom()),
3043 actualMargins.right(), actualMargins.bottom())
3046 setFullFrameMargins(adjustedMargins);
3051 QMargins result = fullFrameMargins();
3052 if (isTopLevel() && m_data.hasFrame)
3053 result -= invisibleMargins(m_data.hwnd);
3059 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3061 return m_data.fullFrameMargins;
3066 qCDebug(lcQpaWindow) <<
__FUNCTION__ << level;
3067 if (!qFuzzyCompare(m_opacity, level)) {
3070 setWindowOpacity(m_data.hwnd, m_data.flags,
3071 window()->format().hasAlpha(), testFlag(OpenGLSurface) || testFlag(VulkanSurface) || testFlag(Direct3DSurface),
3078 return CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
3083 if (
const HRGN rectRegion = createRectRegion(rect)) {
3084 HRGN result = CreateRectRgn(0, 0, 0, 0);
3085 if (CombineRgn(result, *winRegion, rectRegion, RGN_OR)) {
3086 DeleteObject(*winRegion);
3087 *winRegion = result;
3089 DeleteObject(rectRegion);
3095 auto it = region.begin();
3096 const auto end = region.end();
3099 HRGN hRegion = createRectRegion(*it);
3101 addRectToWinRegion(*it, &hRegion);
3107 if (region.isEmpty()) {
3108 SetWindowRgn(m_data.hwnd,
nullptr,
true);
3111 const HRGN winRegion = qRegionToWinRegion(region);
3114 if (window()->isTopLevel()) {
3115 const QMargins margins = fullFrameMargins();
3116 OffsetRgn(winRegion, margins.left(), margins.top());
3120 if (!SetWindowRgn(m_data.hwnd, winRegion,
true))
3121 DeleteObject(winRegion);
3126 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
3132 if (QGuiApplication::applicationState() == Qt::ApplicationActive
3133 || activationBehavior != QWindowsApplication::AlwaysActivateWindow) {
3134 SetForegroundWindow(m_data.hwnd);
3135 SetFocus(m_data.hwnd);
3144 if (m_data.flags & Qt::WindowStaysOnBottomHint) {
3145 qCWarning(lcQpaWindow) <<
3146 "Windows with Qt::WindowStaysOnBottomHint can't be brought to the foreground.";
3149 if (m_data.flags & Qt::WindowStaysOnTopHint) {
3150 qCWarning(lcQpaWindow) <<
3151 "Windows with Qt::WindowStaysOnTopHint will always be on the foreground.";
3154 if (window()->type() == Qt::ToolTip) {
3155 qCWarning(lcQpaWindow) <<
"ToolTip windows should not be activated.";
3160 if (!IsWindowVisible(m_data.hwnd))
3161 ShowWindow(m_data.hwnd, SW_SHOW);
3163 if (IsIconic(m_data.hwnd)) {
3164 ShowWindow(m_data.hwnd, SW_RESTORE);
3171 const HWND oldForegroundWindow = GetForegroundWindow();
3172 if (!oldForegroundWindow)
3177 if (SendMessageTimeoutW(oldForegroundWindow, WM_NULL, 0, 0,
3178 SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000,
nullptr) == 0) {
3179 qCWarning(lcQpaWindow) <<
"The foreground window hangs, can't activate current window.";
3183 const DWORD windowThreadProcessId = GetWindowThreadProcessId(oldForegroundWindow,
nullptr);
3184 const DWORD currentThreadId = GetCurrentThreadId();
3186 AttachThreadInput(windowThreadProcessId, currentThreadId, TRUE);
3187 const auto cleanup = qScopeGuard([windowThreadProcessId, currentThreadId](){
3188 AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE);
3191 BringWindowToTop(m_data.hwnd);
3195 SetActiveWindow(m_data.hwnd);
3201 qWarning(
"%s: No handle",
__FUNCTION__);
3204 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << grab;
3208 context->setKeyGrabber(window());
3210 if (context->keyGrabber() == window())
3211 context->setKeyGrabber(
nullptr);
3218 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << grab;
3220 qWarning(
"%s: No handle",
__FUNCTION__);
3224 qWarning(
"%s: Not setting mouse grab for invisible window %s/'%s'",
3225 __FUNCTION__, window()->metaObject()->className(),
3226 qPrintable(window()->objectName()));
3233 SetCapture(m_data.hwnd);
3243 if (edges == Qt::LeftEdge)
3245 else if (edges == (Qt::RightEdge))
3247 else if (edges == (Qt::TopEdge))
3249 else if (edges == (Qt::TopEdge | Qt::LeftEdge))
3251 else if (edges == (Qt::TopEdge | Qt::RightEdge))
3253 else if (edges == (Qt::BottomEdge))
3255 else if (edges == (Qt::BottomEdge | Qt::LeftEdge))
3257 else if (edges == (Qt::BottomEdge | Qt::RightEdge))
3265 if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
3269 PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0);
3277 PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 , 0);
3292 QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
3293 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << *mmi;
3299 const QWindow *w = window();
3300 const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
3301 const QRect geom = geometry();
3302 static auto oldMouseButtonState = Qt::NoButton;
3304 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
3305 bool isDefaultTitleBar = !w->flags().testFlag(Qt::CustomizeWindowHint);
3306 bool isCustomized = w->flags().testFlags(Qt::CustomizeWindowHint) && w->flags().testAnyFlags(Qt::WindowTitleHint|
3307 Qt::WindowMinimizeButtonHint|
3308 Qt::WindowMaximizeButtonHint|
3309 Qt::WindowCloseButtonHint);
3310 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3311 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3312 const int titleButtonWidth = titleBarHeight * 1.5;
3313 const bool mouseButtonsSwapped = GetSystemMetrics(SM_SWAPBUTTON);
3314 auto mouseButtons = Qt::NoButton;
3315 if (mouseButtonsSwapped)
3316 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::RightButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::LeftButton : Qt::NoButton);
3318 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::LeftButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::RightButton : Qt::NoButton);
3321 if (isCustomized || isDefaultTitleBar) {
3324 if (globalPos.y() < geom.top() + titleBarHeight) {
3325 if (m_data.flags.testFlags(Qt::WindowCloseButtonHint) || isDefaultTitleBar) {
3326 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right())) {
3327 if (mouseButtons == Qt::LeftButton)
3331 }
if (m_data.flags.testFlags(Qt::WindowMaximizeButtonHint) || isDefaultTitleBar) {
3332 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3333 if (mouseButtons == Qt::LeftButton) {
3334 if (IsZoomed(m_data.hwnd))
3337 *result = HTMAXBUTTON;
3341 }
if (m_data.flags.testFlags(Qt::WindowMinimizeButtonHint) || isDefaultTitleBar) {
3342 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3343 if (mouseButtons == Qt::LeftButton)
3344 *result = HTMINBUTTON;
3347 }
if ((isCustomized || isDefaultTitleBar) &&
3348 *result == HTCLIENT){
3349 QWindow* wnd = window();
3350 if (mouseButtons != oldMouseButtonState) {
3351 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3352 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3353 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3354 if (!accepted && mouseButtons == Qt::RightButton)
3355 *result = HTSYSMENU;
3356 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3357 *result = HTCAPTION;
3361 }
else if (w->flags().testFlag(Qt::CustomizeWindowHint)) {
3363 QWindow* wnd = window();
3364 if (mouseButtons != oldMouseButtonState) {
3365 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3366 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3367 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3368 if (!accepted && mouseButtons == Qt::RightButton)
3369 *result = HTSYSMENU;
3370 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3371 *result = HTCAPTION;
3374 oldMouseButtonState = mouseButtons;
3377 const bool left = (globalPos.x() >= geom.left()) && (globalPos.x() < geom.left() + border);
3378 const bool right = (globalPos.x() > geom.right() - border) && (globalPos.x() <= geom.right());
3379 const bool top = (globalPos.y() >= geom.top()) && (globalPos.y() < geom.top() + border);
3380 const bool bottom = (globalPos.y() > geom.bottom() - border) && (globalPos.y() <= geom.bottom());
3382 if (left || right || top || bottom) {
3384 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3386 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3388 *result = top ? HTTOP : HTBOTTOM;
3394 const_cast<QWindow *>(w)->close();
3397 const_cast<QWindow *>(w)->showMaximized();
3400 const_cast<QWindow *>(w)->showMinimized();
3403 const_cast<QWindow *>(w)->showNormal();
3406 HWND hwnd =
reinterpret_cast<HWND>(w->winId());
3407 HMENU sysMenu = GetSystemMenu(hwnd,
false);
3408 TrackPopupMenu(sysMenu, 0, globalPos.x(), globalPos.y(), 0, hwnd,
nullptr);
3417 if (m_data.flags & Qt::ExpandedClientAreaHint) {
3418 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3423 const QRect rect = geom;
3424 const bool left = (globalPos.x() >= rect.left()) && (globalPos.x() < rect.left() + border);
3425 const bool right = (globalPos.x() > rect.right() - border) && (globalPos.x() <= rect.right());
3426 const bool top = (globalPos.y() >= rect.top()) && (globalPos.y() < rect.top() + border);
3427 const bool bottom = (globalPos.y() > rect.bottom() - border) && (globalPos.y() <= rect.bottom());
3430 if (left || right || top || bottom) {
3432 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3434 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3436 *result = top ? HTTOP : HTBOTTOM;
3444 if (!w->isTopLevel()
3445 || (m_windowState != Qt::WindowNoState)
3447 || (m_data.flags & Qt::FramelessWindowHint)) {
3450 const QSize minimumSize = w->minimumSize();
3451 if (minimumSize.isEmpty())
3453 const QSize maximumSize = w->maximumSize();
3454 const bool fixedWidth = minimumSize.width() == maximumSize.width();
3455 const bool fixedHeight = minimumSize.height() == maximumSize.height();
3456 if (!fixedWidth && !fixedHeight)
3458 const QSize size = w->size();
3460 if (localPos.y() >= size.height()) {
3464 if (localPos.y() < 0) {
3465 const int topResizeBarPos = invisibleMargins(m_data.hwnd).left() - frameMargins().top();
3466 if (localPos.y() < topResizeBarPos) {
3467 *result = HTCAPTION;
3472 if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
3484 if (m_data.flags & Qt::FramelessWindowHint) {
3493 HWND hwnd = m_data.hwndTitlebar;
3494 QWindow *wnd = window();
3497 GetWindowRect(hwnd, &windowRect);
3499 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3500 const int titleButtonWidth = titleBarHeight * 1.5;
3501 const qreal factor = QHighDpiScaling::factor(wnd);
3502 const int windowWidth = windowRect.right - windowRect.left;
3505 GetCursorPos(&localPos);
3506 MapWindowPoints(HWND_DESKTOP, m_data.hwnd, &localPos, 1);
3508 const bool isDarkmode = QWindowsIntegration::instance()->darkModeHandling().testFlags(QWindowsApplication::DarkModeWindowFrames) &&
3509 qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
3510 const bool isWindows11orAbove = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11;
3512 const QBrush closeButtonBrush(QColor(0xC4, 0x2C, 0x1E, 255));
3513 const QBrush minMaxButtonBrush = QBrush(isDarkmode ? QColor(0xFF, 0xFF, 0xFF, 0x40) : QColor(0x00, 0x00, 0x00, 0x20));
3514 const QBrush titleBarBackgroundColor = QBrush(isDarkmode ? QColor(0x1F, 0x1F, 0x1F, 0xFF) : QColor(0xF3, 0xF3, 0xF3, 0xFF));
3515 const QPen textPen = QPen(isDarkmode ? QColor(0xFF, 0xFF, 0xFD, 0xFF) : QColor(0x00, 0x00, 0x00, 0xFF));
3517 QImage image(windowWidth, titleBarHeight, QImage::Format_ARGB32);
3519 p.setCompositionMode(QPainter::CompositionMode_Clear);
3520 p.fillRect(0, 0, windowWidth, titleBarHeight, Qt::transparent);
3522 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
3524 p.setBrush(titleBarBackgroundColor);
3525 p.setPen(Qt::NoPen);
3526 if (!wnd->flags().testFlags(Qt::NoTitleBarBackgroundHint)) {
3528 titleRect.setWidth(windowWidth);
3529 titleRect.setHeight(titleBarHeight);
3530 p.drawRect(titleRect);
3533 if (wnd->flags().testFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3537 titleRect.setWidth(windowWidth);
3538 titleRect.setHeight(titleBarHeight);
3540 titleRect.adjust(factor * 4, 0, 0, 0);
3541 QRect iconRect(titleRect.x(), titleRect.y() + factor * 8, factor * 16, factor * 16);
3542 if (wnd->icon().isNull()) {
3543 static QIcon defaultIcon;
3544 if (defaultIcon.isNull()) {
3545 const QImage defaultIconImage = QImage::fromHICON(LoadIcon(0, IDI_APPLICATION));
3546 defaultIcon = QIcon(QPixmap::fromImage(defaultIconImage));
3548 defaultIcon.paint(&p, iconRect);
3550 wnd->icon().paint(&p, iconRect);
3552 titleRect.adjust(factor * 24, 0, 0, 0);
3556 titleFont.setPointSize(factor * 9);
3557 titleFont.setWeight(QFont::Thin);
3558 titleFont.setHintingPreference(QFont::PreferFullHinting);
3559 p.setFont(titleFont);
3560 const QString title = wnd->title().isEmpty() ? qApp->applicationName() : wnd->title();
3561 p.drawText(titleRect, title, QTextOption(Qt::AlignVCenter));
3565 const QString assetFontName = isWindows11orAbove ? QStringLiteral(
"Segoe Fluent Icons") : QStringLiteral(
"Segoe MDL2 Assets");
3566 QFont assetFont = QFont(assetFontName, factor * 7);
3567 assetFont.setWeight(QFont::Thin);
3568 assetFont.setHintingPreference(QFont::PreferFullHinting);
3569 p.setFont(assetFont);
3570 p.setBrush(closeButtonBrush);
3571 p.setPen(Qt::NoPen);
3572 if (wnd->flags().testFlags(Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3575 rect.setX(windowWidth - titleButtonWidth * buttons);
3576 rect.setWidth(titleButtonWidth);
3577 rect.setHeight(titleBarHeight);
3578 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3579 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3580 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3582 const QPen closeButtonHoveredPen = QPen(QColor(0xFF, 0xFF, 0xFD, 0xFF));
3583 p.setPen(closeButtonHoveredPen);
3587 p.drawText(rect, QStringLiteral(
"\uE8BB"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3591 p.setBrush(minMaxButtonBrush);
3592 p.setPen(Qt::NoPen);
3593 if (wnd->flags().testFlags(Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3596 rect.setX(windowWidth - titleButtonWidth * buttons);
3597 rect.setWidth(titleButtonWidth);
3598 rect.setHeight(titleBarHeight);
3599 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3600 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3601 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3605 p.drawText(rect,QStringLiteral(
"\uE922"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3609 p.setBrush(minMaxButtonBrush);
3610 p.setPen(Qt::NoPen);
3611 if (wnd->flags().testFlags(Qt::WindowMinimizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3614 rect.setX(windowWidth - titleButtonWidth * buttons);
3615 rect.setWidth(titleButtonWidth);
3616 rect.setHeight(titleBarHeight);
3617 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3618 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3619 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3623 p.drawText(rect,QStringLiteral(
"\uE921"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3629 HBITMAP bmp = image.toHBITMAP();
3631 HDC hdc = GetDC(hwnd);
3633 HDC memdc = CreateCompatibleDC(hdc);
3634 HGDIOBJ original = SelectObject(memdc, bmp);
3637 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
3638 POINT ptLocation = { 0, 0 };
3639 SIZE szWnd = { windowWidth, titleBarHeight };
3640 POINT ptSrc = { 0, 0 };
3641 UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
3642 SelectObject(hdc, original);
3645 DeleteObject(memdc);
3646 ReleaseDC(hwnd,hdc);
3653 if (QScreen *screen = w->screen())
3654 if (
const QPlatformScreen *platformScreen = screen->handle())
3655 if (QPlatformCursor *cursor = platformScreen->cursor())
3656 return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
3657 return CursorHandlePtr(
new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
3666 if (underMouse == w)
3668 for (
const QWindow *p = underMouse; p ; p = p->parent()) {
3671 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p);
3672 if (platformWindow && !platformWindow->cursor()->isNull())
3680
3681
3682
3683
3693 if (m_cursor->isNull()) {
3694 if (
const QWindow *p = window()->parent()) {
3695 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p))
3698 SetCursor(defaultCursor(window())->handle());
3701 SetCursor(m_cursor->handle());
3709 bool changed = c->handle() != m_cursor->handle();
3717 const bool apply = applyNewCursor(window());
3718 qCDebug(lcQpaWindow) << window() <<
__FUNCTION__
3719 << c->handle() <<
" doApply=" << apply;
3742 UINT timeOutMs = GetCaretBlinkTime();
3743 if (!timeOutMs || timeOutMs == INFINITE)
3747 info.cbSize =
sizeof(info);
3748 info.hwnd = m_data.hwnd;
3749 info.dwFlags = FLASHW_TRAY;
3750 info.dwTimeout = timeOutMs;
3751 info.uCount = durationMs == 0 ? 10 : UINT(durationMs) / timeOutMs;
3752 FlashWindowEx(&info);
3758 info.cbSize =
sizeof(info);
3759 info.hwnd = m_data.hwnd;
3760 info.dwFlags = FLASHW_STOP;
3763 FlashWindowEx(&info);
3768 return (style() & WS_DISABLED) == 0;
3773 const unsigned oldStyle =
style();
3774 unsigned newStyle = oldStyle;
3776 newStyle &= ~WS_DISABLED;
3778 newStyle |= WS_DISABLED;
3780 if (newStyle != oldStyle)
3786 if (!icon.isNull()) {
3788 const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)), 1);
3790 return qt_pixmapToWinHICON(pm);
3800 m_iconSmall = createHIcon(icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
3801 m_iconBig = createHIcon(icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
3804 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3805 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconBig));
3807 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3808 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconSmall));
3815 return window()->isTopLevel() && !m_data.embedded;
3825 const BOOL darkBorder = d ? TRUE : FALSE;
3830 qCWarning(lcQpaWindow,
"%s: Unable to set %s window border.",
__FUNCTION__, d ?
"dark" :
"light");
3837 d = d && shouldApplyDarkFrame(window());
3839 setDarkBorderToWindow(m_data.hwnd, d);
3844 return m_menuBar.data();
3854 if (m_data.flags & Qt::FramelessWindowHint)
3856 return m_data.customMargins;
3860
3861
3862
3863
3864
3865
3866
3867
3871 if (m_data.flags & Qt::FramelessWindowHint) {
3872 qCWarning(lcQpaWindow) <<
"You should not set custom margins for a frameless window.";
3875 if (newCustomMargins != m_data.customMargins) {
3876 const QMargins oldCustomMargins = m_data.customMargins;
3877 m_data.customMargins = newCustomMargins;
3879 const QRect currentFrameGeometry = frameGeometry_sys();
3880 const QPoint topLeft = currentFrameGeometry.topLeft();
3881 QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
3882 newFrame.moveTo(topLeft);
3883 qCDebug(lcQpaWindow) <<
__FUNCTION__ << oldCustomMargins <<
"->" << newCustomMargins
3884 << currentFrameGeometry <<
"->" << newFrame;
3885 SetWindowPos(m_data.hwnd,
nullptr, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
3891#if QT_CONFIG(vulkan)
3892 Q_UNUSED(nativeConfig);
3894 if (window()->surfaceType() == QSurface::VulkanSurface) {
3896 QVulkanInstance *inst = window()->vulkanInstance();
3898 m_vkSurface =
static_cast<QWindowsVulkanInstance *>(inst->handle())->createSurface(handle());
3900 qWarning(
"Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
3904 return &m_vkSurface;
3906#elif defined(QT_NO_OPENGL)
3908 Q_UNUSED(nativeConfig);
3913 if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
3914 m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err);
3925#if QT_CONFIG(vulkan)
3927 QVulkanInstance *inst = window()->vulkanInstance();
3929 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
3930 m_vkSurface = VK_NULL_HANDLE;
3937 m_surface =
nullptr;
3950 const auto currentTouchTypes = touchWindowTouchTypes_sys();
3951 if (currentTouchTypes.has_value() && currentTouchTypes.value() == touchTypes)
3955 ULONG touchFlags = 0;
3956 if (touchTypes.testFlag(TouchWindowTouchType::FineTouch))
3957 touchFlags |= TWF_FINETOUCH;
3958 if (touchTypes.testFlag(TouchWindowTouchType::WantPalmTouch))
3959 touchFlags |= TWF_WANTPALM;
3960 if (RegisterTouchWindow(m_data.hwnd, touchFlags))
3963 qErrnoWarning(
"RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
3968 if (QPlatformWindow *handle = window->handle())
3969 static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border);
3976 m_borderInFullScreenDefault = border;
3993 if (m_windowState == Qt::WindowFullScreen) {
3994 LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE);
3998 style &= ~WS_BORDER;
3999 SetWindowLongPtr(handle(), GWL_STYLE, style);
4005 return QPlatformWindow::formatWindowTitle(title, QStringLiteral(
" - "));
4015 QWindow *w = window();
4016 QDxgiVSyncService *vs = QDxgiVSyncService::instance();
4017 if (vs->supportsWindow(w)) {
4018 if (m_vsyncServiceCallbackId == 0) {
4019 m_vsyncServiceCallbackId = vs->registerCallback([
this, w](
const QDxgiVSyncService::CallbackWindowList &windowList, qint64) {
4020 if (windowList.contains(w)) {
4025 if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) {
4026 QWindowsWindow *oldSelf =
this;
4027 QMetaObject::invokeMethod(w, [w, oldSelf] {
4029 auto *self =
static_cast<QWindowsWindow *>(w->handle());
4030 if (self && self == oldSelf) {
4032 self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready);
4033 self->deliverUpdateRequest();
4040 m_vsyncUpdatePending.testAndSetRelease(UpdateState::Ready, UpdateState::Requested);
4042 QPlatformWindow::requestUpdate();
\inmodule QtCore\reentrant
Base class for QWindowsForeignWindow, QWindowsWindow.
QMargins frameMargins_sys() const
bool isTopLevel_sys() const
void setHasBorderInFullScreen(bool border) override
QMargins customMargins() const override
bool windowEvent(QEvent *event) override
Reimplement this method to be able to do any platform specific event handling.
bool hasBorderInFullScreen() const override
bool hasMaximumWidth() const
std::optional< TouchWindowTouchTypes > touchWindowTouchTypes_sys() const
bool hasMaximumHeight() const
QRect frameGeometry_sys() const
QRect geometry_sys() const
void setCustomMargins(const QMargins &margins) override
void setGeometry_sys(const QRect &rect) const
bool hasMaximumSize() const
void setWindowTitle_sys(const QString &title)
Singleton container for all relevant information.
QWindowsScreenManager & screenManager()
void clearWindowUnderMouse()
unsigned systemInfo() const
static QWindowsContext * instance()
Platform cursor implementation.
static bool hasOverrideCursor()
static void enforceOverrideCursor()
Window wrapping a foreign native window.
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
static QWindowsStaticOpenGLContext * staticOpenGLContext()
static QWindowsIntegration * instance()
Manages a list of QWindowsScreen.
const QWindowsScreen * screenAtDp(const QPoint &p) const
static bool isSingleScreen()
virtual void destroyWindowSurface(void *)
void alertWindow(int durationMs=0)
void setWindowFlags(Qt::WindowFlags flags) override
Requests setting the window flags of this surface to flags.
void setCustomMargins(const QMargins &m) override
Sets custom margins to be added to the default margins determined by the windows style in the handlin...
void setMenuBar(QWindowsMenuBar *mb)
void invalidateSurface() override
Invalidates the window's surface by releasing its surface buffers.
HDC getDC()
Allocates a HDC for the window or returns the temporary one obtained from WinAPI BeginPaint within a ...
QMargins fullFrameMargins() const override
void checkForScreenChanged(ScreenChangeMode mode=FromGeometryChange, const RECT *suggestedRect=nullptr)
void initialize() override
Called as part of QWindow::create(), after constructing the window.
void handleDpiChangedAfterParent(HWND hwnd)
void requestUpdate() override
Requests an QEvent::UpdateRequest event.
bool testFlag(unsigned f) const
void setFlag(unsigned f) const
void clearFlag(unsigned f) const
void setFrameStrutEventsEnabled(bool enabled) override
Reimplement this method to set whether frame strut events should be sent to enabled.
static void settingsChanged()
void getSizeHints(MINMAXINFO *mmi) const
static void setHasBorderInFullScreenDefault(bool border)
~QWindowsWindow() override
bool handleWmPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
bool setMouseGrabEnabled(bool grab) override
void propagateSizeHints() override
Reimplement to propagate the size hints of the QWindow.
void applyCursor()
Applies to cursor property set on the window to the global cursor.
bool handleGeometryChanging(MSG *message) const
bool isActive() const override
Returns true if the window should appear active from a style perspective.
void setStyle(unsigned s) const
QString windowTitle() const override
Reimplement to return the actual window title used in the underlying windowing system unless the titl...
static void displayChanged()
bool setKeyboardGrabEnabled(bool grab) override
bool windowEvent(QEvent *event) override
Reimplement this method to be able to do any platform specific event handling.
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
void setEnabled(bool enabled)
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
QSurfaceFormat format() const override
Returns the actual surface format of the window.
static const char * embeddedNativeParentHandleProperty
QWindowsMenuBar * menuBar() const
void handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
void registerTouchWindow()
QMargins frameMargins() const override
void setWindowIcon(const QIcon &icon) override
Reimplement to set the window icon to icon.
void handleResized(int wParam, LPARAM lParam)
void setOpacity(qreal level) override
Reimplement to be able to let Qt set the opacity level of a window.
bool isEmbedded() const override
Returns true if the window is a child of a non-Qt window.
QMargins customMargins() const override
bool handleNonClientActivate(LRESULT *result) const
QRect normalGeometry() const override
Returns the geometry of a window in 'normal' state (neither maximized, fullscreen nor minimized) for ...
void setExStyle(unsigned s) const
qreal dpiRelativeScale(const UINT dpi) const
QMargins safeAreaMargins() const override
The safe area margins of a window represent the area that is safe to place content within,...
void setSavedDpi(int dpi)
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
void handleDpiScaledSize(WPARAM wParam, LPARAM lParam, LRESULT *result)
void updateFullFrameMargins()
@ SynchronousGeometryChangeEvent
@ WithinSetParent
Automatic mouse capture on button press.
@ FrameStrutEventsEnabled
static const char * hasBorderInFullScreenProperty
bool startSystemMove() override
Reimplement this method to start a system move operation if the system supports it and return true to...
bool isTopLevel() const override
void releaseDC()
Releases the HDC for the window or does nothing in case it was obtained from WinAPI BeginPaint within...
void updateRestoreGeometry()
void setWindowState(Qt::WindowStates state) override
Requests setting the window state of this surface to type.
void setCursor(const CursorHandlePtr &c)
void updateCustomTitlebar()
bool hasBorderInFullScreen() const override
bool hasMouseCapture() const
void * surface(void *nativeConfig, int *err)
void setHasBorderInFullScreen(bool border) override
void handleCompositionSettingsChanged()
void setWindowTitle(const QString &title) override
Reimplement to set the window title to title.
void setDarkBorder(bool d)
bool startSystemResize(Qt::Edges edges) override
Reimplement this method to start a system resize operation if the system supports it and return true ...
void setFullFrameMargins(const QMargins &newMargins)
void setMask(const QRegion ®ion) override
Reimplement to be able to let Qt set the mask of a window.
void setAlertState(bool enabled) override
Reimplement this method to set whether the window demands attention (for example, by flashing the tas...
bool isAlertState() const override
Reimplement this method return whether the window is in an alert state.
static QSize toNativeSizeConstrained(QSize dip, const QScreen *s)
static void fixTopLevelWindowFlags(Qt::WindowFlags &flags)
static QString msgUnableToSetGeometry(const QWindowsWindow *platformWindow, const QRect &requestedRect, const QRect &obtainedRect, const QMargins &fullMargins, const QMargins &customMargins)
static bool shouldOmitFrameAdjustment(const Qt::WindowFlags flags, DWORD style)
static QRect normalFrameGeometry(HWND hwnd)
static void formatBriefRectangle(QDebug &d, const QRect &r)
static bool testShowWithoutActivating(const QWindow *window)
static bool shouldShowMaximizeButton(const QWindow *w, Qt::WindowFlags flags)
static void setMinimizedGeometry(HWND hwnd, const QRect &r)
static bool applyNewCursor(const QWindow *w)
static bool isSoftwareGl()
static HICON createHIcon(const QIcon &icon, int xSize, int ySize)
static void addRectToWinRegion(const QRect &rect, HRGN *winRegion)
static QByteArray debugWinSwpPos(UINT flags)
static HRGN createRectRegion(const QRect &r)
static QByteArray debugWinStyle(DWORD style)
static QScreen * screenForDeviceName(const QWindow *w, const QString &name)
static QPoint windowPlacementOffset(HWND hwnd, const QPoint &point)
static bool applyBlurBehindWindow(HWND hwnd)
static bool shouldShowTitlebarButton(Qt::WindowFlags flags, Qt::WindowFlags button)
static void setRestoreMaximizedFlag(HWND hwnd, bool set=true)
static RECT RECTfromQRect(const QRect &rect)
static QMargins invisibleMargins(const HWND hwnd)
static QRect frameGeometry(HWND hwnd, bool topLevel)
static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, bool accelerated, qreal level)
static QMargins invisibleMargins(QPoint screenPoint)
Calculates the dimensions of the invisible borders within the window frames which only exist on Windo...
static int getResizeBorderThickness(const UINT dpi)
static bool windowIsAccelerated(const QWindow *w)
static bool equalDpi(const QDpi &d1, const QDpi &d2)
static bool isResize(const WINDOWPOS *windowPos)
static void formatBriefMargins(QDebug &d, const QMargins &m)
static int getTitleBarHeight_sys(const UINT dpi)
static QByteArray debugWindowPlacementFlags(const UINT flags)
static QSize qSizeOfRect(const RECT &rect)
static DWORD edgesToWinOrientation(Qt::Edges edges)
static bool shouldApplyDarkFrame(const QWindow *w)
static QByteArray debugWinExStyle(DWORD exStyle)
static CursorHandlePtr defaultCursor(const QWindow *w)
static QByteArray debugShowWindowCmd(const UINT cmd)
static HRGN qRegionToWinRegion(const QRegion ®ion)
static QPoint calcPosition(const QWindow *w, const QWindowCreationContextPtr &context, const QMargins &invMargins)
@ DwmwaUseImmersiveDarkMode
@ DwmwaUseImmersiveDarkModeBefore20h1
static QRect qrectFromRECT(const RECT &rect)
static QWindow::Visibility windowVisibility_sys(HWND hwnd)
static GpuDescription detect()
Active Context for creating windows.
void applyToMinMaxInfo(MINMAXINFO *mmi) const
Stores geometry constraints and provides utility functions.
void applyWindowFlags(HWND hwnd) const
void initialize(const QWindow *w, HWND h, bool frameChange, qreal opacityLevel) const
QWindowsWindowData WindowData
WindowData create(const QWindow *w, const WindowData &data, QString title) const
void fromWindow(const QWindow *w, const Qt::WindowFlags flags, unsigned creationFlags=0)