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);
472 if ((flags & Qt::MSWindowsFixedSizeDialogHint) || !(flags & Qt::WindowMaximizeButtonHint))
476 return (flags & Qt::CustomizeWindowHint) ||
477 w->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX);
482 const LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
483 return (style & WS_CHILD) || (flags & Qt::FramelessWindowHint);
489bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha, qreal opacity)
491 const LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
493 const bool needsLayered = (flags & Qt::WindowTransparentForInput)
494 || (hasAlpha && hasNoNativeFrame(hwnd, flags)) || opacity < 1.0;
495 const bool isLayered = (exStyle & WS_EX_LAYERED);
496 if (needsLayered != isLayered) {
498 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
500 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
506static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha,
bool accelerated, qreal level)
508 if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) {
509 const BYTE alpha = BYTE(qRound(255.0 * level));
510 if (hasAlpha && !accelerated && QWindowsWindow::hasNoNativeFrame(hwnd, flags)) {
512 BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
513 UpdateLayeredWindow(hwnd,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, 0, &blend, ULW_ALPHA);
515 SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
517 }
else if (IsWindowVisible(hwnd)) {
518 InvalidateRect(hwnd,
nullptr, TRUE);
527 return GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
528 + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
532
533
534
538 POINT pt = {screenPoint.x(), screenPoint.y()};
539 if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
542 if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
543 const int gap = getResizeBorderThickness(dpiX);
544 return QMargins(gap, 0, gap, gap);
552 const UINT dpi = GetDpiForWindow(hwnd);
553 const int gap = getResizeBorderThickness(dpi);
554 return QMargins(gap, 0, gap, gap);
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
590 void fromWindow(
const QWindow *w,
const Qt::WindowFlags flags,
unsigned creationFlags = 0);
593 void initialize(
const QWindow *w, HWND h,
bool frameChange, qreal opacityLevel)
const;
610 QDebugStateSaver saver(debug);
613 debug <<
"WindowCreationData: " << d.flags
616 debug <<
" parent=" << d.parentHandle;
617 debug <<
" popup=" << d.popup <<
" dialog=" << d.dialog
618 <<
" embedded=" << d.embedded <<
" tool=" << d.tool
619 <<
"\n style=" << debugWinStyle(d.style);
621 debug <<
"\n exStyle=" << debugWinExStyle(d.exStyle);
629 flags &= ~Qt::WindowFullscreenButtonHint;
632 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint
633 |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
637 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
642 if ((flags & Qt::WindowType_Mask) == Qt::SplashScreen)
643 flags |= Qt::FramelessWindowHint;
648 const auto getDeviceName = [](
const QScreen *screen) -> QString {
649 if (
const auto s =
static_cast<
const QWindowsScreen *>(screen->handle()))
650 return s->data().deviceName;
653 QScreen *winScreen = w ? w->screen() : QGuiApplication::primaryScreen();
654 if (winScreen && getDeviceName(winScreen) != name) {
655 const auto screens = winScreen->virtualSiblings();
656 for (QScreen *screen : screens) {
657 if (getDeviceName(screen) == name)
664static QPoint calcPosition(
const QWindow *w,
const QWindowCreationContextPtr &context,
const QMargins &invMargins)
666 const QPoint orgPos(context->frameX - invMargins.left(), context->frameY - invMargins.top());
668 if (!w || w->type() != Qt::Window)
672 const QScreen *screenForGL = QWindowsWindow::forcedScreenForGLWindow(w);
676 const QPoint posFrame(context->frameX, context->frameY);
677 const QMargins margins = context->margins;
678 const QRect scrGeo = screenForGL->handle()->availableGeometry();
681 if (scrGeo.contains(orgPos))
686 if (scrGeo.contains(posFrame))
690 const auto screens = screenForGL->virtualSiblings();
691 const QScreen *orgScreen =
nullptr;
692 for (QScreen *screen : screens) {
693 if (screen->handle()->availableGeometry().contains(posFrame)) {
698 const QPoint ctPos = QPoint(qMax(scrGeo.left(), scrGeo.center().x()
699 + (margins.right() - margins.left() - context->frameWidth)/2),
700 qMax(scrGeo.top(), scrGeo.center().y()
701 + (margins.bottom() - margins.top() - context->frameHeight)/2));
707 const QRect orgGeo = orgScreen->handle()->availableGeometry();
708 const QRect orgFrame(
QPoint(context->frameX, context->frameY),
709 QSize(context->frameWidth, context->frameHeight));
712 if (orgGeo.center() == (orgFrame - margins).center())
716 const QPoint newPos(scrGeo.left() + ((posFrame.x() - orgGeo.left()) * scrGeo.width()) / orgGeo.width(),
717 scrGeo.top() + ((posFrame.y() - orgGeo.top()) * scrGeo.height()) / orgGeo.height());
718 const QPoint newPosNoMargin(newPos.x() - invMargins.left(), newPos.y() - invMargins.top());
720 return scrGeo.contains(newPosNoMargin) ? newPosNoMargin : newPos;
724 unsigned creationFlags)
731 QVariant prop = w->property(QWindowsWindow::embeddedNativeParentHandleProperty);
732 if (prop.isValid()) {
734 parentHandle =
reinterpret_cast<HWND>(prop.value<WId>());
748 fixTopLevelWindowFlags(flags);
750 type =
static_cast<Qt::WindowType>(
int(flags) & Qt::WindowType_Mask);
766 if ((flags & Qt::MSWindowsFixedSizeDialogHint))
775 if (QGuiApplication::layoutDirection() == Qt::RightToLeft
776 && (QWindowsIntegration::instance()->options() & QWindowsIntegration::RtlEnabled) != 0) {
777 exStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
782 flags |= Qt::WindowStaysOnTopHint;
784 if (
const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
785 parentHandle = QWindowsWindow::handleOf(parentWindow);
788 if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
791 if (flags & Qt::FramelessWindowHint)
793 else if (flags & Qt::WindowTitleHint)
794 style = WS_OVERLAPPED;
801 style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
803 if (flags & Qt::WindowDoesNotAcceptFocus)
804 exStyle |= WS_EX_NOACTIVATE;
807 if ((type == Qt::Window || dialog || tool)) {
808 if (!(flags & Qt::FramelessWindowHint)) {
810 if (flags & Qt::MSWindowsFixedSizeDialogHint) {
811 style |= WS_DLGFRAME;
813 style |= WS_THICKFRAME;
815 if (flags & Qt::WindowTitleHint)
818 if (flags & Qt::WindowSystemMenuHint)
820 else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
821 style |= WS_SYSMENU | WS_BORDER;
822 exStyle |= WS_EX_DLGMODALFRAME;
824 const bool showMinimizeButton = flags & Qt::WindowMinimizeButtonHint;
825 if (showMinimizeButton)
826 style |= WS_MINIMIZEBOX;
827 const bool showMaximizeButton = shouldShowMaximizeButton(w, flags);
828 if (showMaximizeButton)
829 style |= WS_MAXIMIZEBOX;
830 if (showMinimizeButton || showMaximizeButton)
833 exStyle |= WS_EX_TOOLWINDOW;
834 if ((flags & Qt::WindowContextHelpButtonHint) && !showMinimizeButton
835 && !showMaximizeButton)
836 exStyle |= WS_EX_CONTEXTHELP;
838 exStyle |= WS_EX_TOOLWINDOW;
843 if (flagsIn & Qt::WindowTransparentForInput)
844 exStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT;
847 if (qEnvironmentVariableIntValue(
"QT_QPA_DISABLE_REDIRECTION_SURFACE"))
848 exStyle |= WS_EX_NOREDIRECTIONBITMAP;
854 if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
858 if (!QWindowsIntegration::instance()->darkModeHandling().testFlag(QWindowsApplication::DarkModeWindowFrames))
863 auto *dWindow = QWindowPrivate::get(
const_cast<QWindow*>(w));
864 const QPalette windowPal = dWindow->windowPalette();
865 return windowPal.color(QPalette::WindowText).lightness()
866 > windowPal.color(QPalette::Window).lightness();
872 return getResizeBorderThickness(dpi) +
873 ::GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
880 result.flags = flags;
882 const auto appinst =
reinterpret_cast<HINSTANCE>(GetModuleHandle(
nullptr));
885 const QString windowTitlebarName = QWindowsContext::instance()->registerWindowClass(QStringLiteral(
"_q_titlebar"), DefWindowProc, CS_VREDRAW|CS_HREDRAW,
nullptr,
false);
887 const QScreen *screen{};
888 const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
889 defaultWindowWidth, defaultWindowHeight,
892 if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
893 title =
topLevel ? qAppName() : w->objectName();
895 const auto *titleUtf16 =
reinterpret_cast<
const wchar_t *>(title.utf16());
896 const auto *classNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowClassName.utf16());
897 const auto *classTitleBarNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowTitlebarName.utf16());
902 rect, data.customMargins,
906 const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME))
907 && !(result.flags & Qt::FramelessWindowHint);
908 QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w)
909 ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();
911 qCDebug(lcQpaWindow).nospace()
912 <<
"CreateWindowEx: " << w <<
" class=" << windowClassName <<
" title=" << title
913 <<
'\n' << *
this <<
"\nrequested: " << rect <<
": "
914 << context->frameWidth <<
'x' << context->frameHeight
915 <<
'+' << context->frameX <<
'+' << context->frameY
916 <<
" custom margins: " << context->customMargins
917 <<
" invisible margins: " << invMargins;
920 QPoint pos = calcPosition(w, context, invMargins);
923 int mirrorParentWidth = 0;
924 if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) {
926 GetClientRect(parentHandle, &rect);
927 mirrorParentWidth = rect.right;
929 if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT)
930 pos.setX(mirrorParentWidth - context->frameWidth - pos.x());
932 result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
935 context->frameWidth, context->frameHeight,
936 parentHandle,
nullptr, appinst,
nullptr);
938 const UINT dpi = ::GetDpiForWindow(result.hwnd);
939 const int titleBarHeight = getTitleBarHeight_sys(dpi);
940 result.hwndTitlebar = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,
941 classTitleBarNameUtf16, classTitleBarNameUtf16,
943 context->frameWidth, titleBarHeight,
944 nullptr,
nullptr, appinst,
nullptr);
946 qCDebug(lcQpaWindow).nospace()
947 <<
"CreateWindowEx: returns " << w <<
' ' << result.hwnd <<
" obtained geometry: "
948 << context->obtainedPos << context->obtainedSize <<
' ' << context->margins;
951 qErrnoWarning(
"%s: CreateWindowEx failed",
__FUNCTION__);
955 if (QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark && shouldApplyDarkFrame(w))
956 QWindowsWindow::setDarkBorderToWindow(result.hwnd,
true);
958 if (mirrorParentWidth != 0) {
959 context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
960 - context->obtainedPos.x());
963 QRect obtainedGeometry(context->obtainedPos, context->obtainedSize);
965 result.geometry = obtainedGeometry;
966 result.restoreGeometry = frameGeometry(result.hwnd, topLevel);
967 result.fullFrameMargins = context->margins;
970 result.customMargins = context->customMargins;
978 const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
979 const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
981 const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
982 if (oldStyle != newStyle)
983 SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
984 const LONG_PTR newExStyle =
exStyle;
985 if (newExStyle != oldExStyle)
986 SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
987 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << hwnd << *
this
988 <<
"\n Style from " << debugWinStyle(DWORD(oldStyle)) <<
"\n to "
989 << debugWinStyle(DWORD(newStyle)) <<
"\n ExStyle from "
990 << debugWinExStyle(DWORD(oldExStyle)) <<
" to "
991 << debugWinExStyle(DWORD(newExStyle));
998 UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER;
1000 swpFlags |= SWP_FRAMECHANGED;
1002 swpFlags |= SWP_NOACTIVATE;
1003 if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
1004 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, swpFlags);
1005 if (flags & Qt::WindowStaysOnBottomHint)
1006 qWarning(
"QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time");
1007 }
else if (flags & Qt::WindowStaysOnBottomHint) {
1008 SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, swpFlags);
1009 }
else if (frameChange) {
1010 SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, swpFlags);
1012 if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
1013 HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
1014 if (flags & Qt::WindowCloseButtonHint)
1015 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
1017 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
1019 if (flags & Qt::ExpandedClientAreaHint) {
1020 MARGINS margins = { -1, -1, -1, -1 };
1021 DwmExtendFrameIntoClientArea(hwnd, &margins);
1023 MARGINS margins = { 0, 0, 0, 0 };
1024 DwmExtendFrameIntoClientArea(hwnd, &margins);
1027 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
1031 const bool hasAlpha = w->format().hasAlpha();
1032 if (isAccelerated && hasAlpha)
1033 applyBlurBehindWindow(hwnd);
1034 setWindowOpacity(hwnd, flags, hasAlpha, isAccelerated, opacityLevel);
1041 if (QHighDpiScaling::isActive()) {
1042 const qreal factor = QHighDpiScaling::factor(s);
1043 if (!qFuzzyCompare(factor, qreal(1))) {
1044 if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
1045 dip.setWidth(qRound(qreal(dip.width()) * factor));
1046 if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX)
1047 dip.setHeight(qRound(qreal(dip.height()) * factor));
1057 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1064 DWORD style = hwnd !=
nullptr ? DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)) : 0;
1065 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1069
1070
1071
1072
1073
1074
1075
1076
1080 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1082 RECT rect = {0,0,0,0};
1083 style &= ~DWORD(WS_OVERLAPPED);
1084 if (AdjustWindowRectEx(&rect, style, FALSE, exStyle) == FALSE)
1085 qErrnoWarning(
"%s: AdjustWindowRectEx failed",
__FUNCTION__);
1086 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1087 qAbs(rect.right), qAbs(rect.bottom));
1088 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1089 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1090 <<
' ' << rect <<
' ' << result;
1096 return frameOnPrimaryScreen(w, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1097 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1102 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1104 RECT rect = {0,0,0,0};
1105 style &= ~DWORD(WS_OVERLAPPED);
1106 if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
unsigned(qRound(dpi))) == FALSE) {
1107 qErrnoWarning(
"%s: AdjustWindowRectExForDpi failed",
__FUNCTION__);
1109 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1110 qAbs(rect.right), qAbs(rect.bottom));
1111 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1112 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1114 <<
' ' << rect <<
' ' << result;
1120 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1122 if (QWindowsScreenManager::isSingleScreen())
1123 return frameOnPrimaryScreen(w, style, exStyle);
1125 auto screen = screenManager.screenForHwnd(hwnd);
1127 screen = screenManager.screens().value(0);
1128 const auto dpi = screen ? screen->logicalDpi().first : qreal(96);
1129 return frame(w, style, exStyle, dpi);
1134 return frame(w, hwnd, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1135 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1140 DWORD style, DWORD exStyle)
1142 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1145 || !QWindowsContext::shouldHaveNonClientDpiScaling(w)) {
1146 return frameOnPrimaryScreen(w, style, exStyle);
1152 screen = screenManager.screens().value(0);
1154 dpi = screen->logicalDpi().first;
1155 return QWindowsGeometryHint::frame(w, style, exStyle, dpi);
1158bool QWindowsGeometryHint::handleCalculateSize(
const QWindow *window,
const QMargins &customMargins,
const MSG &msg, LRESULT *result)
1161 if (msg.wParam && window->flags() & Qt::FramelessWindowHint) {
1165 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window);
1167 const bool clientAreaExpanded = platformWindow !=
nullptr ? platformWindow->isClientAreaExpanded() : window->flags() & Qt::ExpandedClientAreaHint;
1169 if (msg.wParam && clientAreaExpanded) {
1171 const bool maximized = IsZoomed(msg.hwnd) && window->visibility() != QWindow::FullScreen;
1172 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1173 RECT *clientArea = &ncp->rgrc[0];
1174 const int border = getResizeBorderThickness(96);
1176 clientArea->top += border;
1177 clientArea->bottom -= border;
1178 clientArea->left += border;
1179 clientArea->right -= border;
1184 if (!msg.wParam || customMargins.isNull())
1186 *result = DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1187 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1188 const RECT oldClientArea = ncp->rgrc[0];
1189 ncp->rgrc[0].left += customMargins.left();
1190 ncp->rgrc[0].top += customMargins.top();
1191 ncp->rgrc[0].right -= customMargins.right();
1192 ncp->rgrc[0].bottom -= customMargins.bottom();
1194 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << oldClientArea <<
'+' << customMargins <<
"-->"
1195 << ncp->rgrc[0] <<
' ' << ncp->rgrc[1] <<
' ' << ncp->rgrc[2]
1196 <<
' ' << ncp->lppos->cx <<
',' << ncp->lppos->cy;
1201 const QMargins &margins,
1202 QSize *minimumSize, QSize *maximumSize)
1204 *minimumSize = toNativeSizeConstrained(w->minimumSize(), screen);
1205 *maximumSize = toNativeSizeConstrained(w->maximumSize(), screen);
1207 const int maximumWidth = qMax(maximumSize->width(), minimumSize->width());
1208 const int maximumHeight = qMax(maximumSize->height(), minimumSize->height());
1209 const int frameWidth = margins.left() + margins.right();
1210 const int frameHeight = margins.top() + margins.bottom();
1212 if (minimumSize->width() > 0)
1213 minimumSize->rwidth() += frameWidth;
1214 if (minimumSize->height() > 0)
1215 minimumSize->rheight() += frameHeight;
1216 if (maximumWidth < QWINDOWSIZE_MAX)
1217 maximumSize->setWidth(maximumWidth + frameWidth);
1218 if (maximumHeight < QWINDOWSIZE_MAX)
1219 maximumSize->setHeight(maximumHeight + frameHeight);
1223 const QScreen *screen,
1224 const QMargins &margins,
1229 frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize);
1230 qCDebug(lcQpaWindow).nospace() <<
'>' <<
__FUNCTION__ <<
'<' <<
" min="
1231 << minimumSize.width() <<
',' << minimumSize.height()
1232 <<
" max=" << maximumSize.width() <<
',' << maximumSize.height()
1233 <<
" margins=" << margins
1236 if (minimumSize.width() > 0)
1237 mmi->ptMinTrackSize.x = minimumSize.width();
1238 if (minimumSize.height() > 0)
1239 mmi->ptMinTrackSize.y = minimumSize.height();
1241 if (maximumSize.width() < QWINDOWSIZE_MAX)
1242 mmi->ptMaxTrackSize.x = maximumSize.width();
1243 if (maximumSize.height() < QWINDOWSIZE_MAX)
1244 mmi->ptMaxTrackSize.y = maximumSize.height();
1245 qCDebug(lcQpaWindow).nospace() <<
'<' <<
__FUNCTION__ <<
" out " << *mmi;
1249 const QMargins &margins,
1252 applyToMinMaxInfo(w, w->screen(), margins, mmi);
1257 return qt_window_private(
const_cast<QWindow *>(w))->positionPolicy
1258 == QWindowPrivate::WindowFrameInclusive;
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1280 return (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0;
1286 if (QPlatformWindow *pw = w->handle())
1287 return static_cast<QWindowsBaseWindow *>(pw);
1295 return bw ? bw->handle() : HWND(
nullptr);
1300 const HWND parent = parentHwnd();
1301 return !parent || parent == GetDesktopWindow();
1306 return frameGeometry(handle(), isTopLevel());
1311 return frameGeometry_sys().marginsRemoved(fullFrameMargins());
1316 return QWindowsGeometryHint::frame(window(), handle(), style(), exStyle());
1322 ULONG touchFlags = 0;
1323 if (IsTouchWindow(handle(), &touchFlags) == FALSE)
1325 TouchWindowTouchTypes result;
1326 if ((touchFlags & TWF_FINETOUCH) != 0)
1327 result.setFlag(TouchWindowTouchType::FineTouch);
1328 if ((touchFlags & TWF_WANTPALM) != 0)
1329 result.setFlag(TouchWindowTouchType::WantPalmTouch);
1335 SetWindowPos(handle(),
nullptr , 0, 0, 0, 0,
1336 SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1341 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1342 const Qt::WindowType type = window()->type();
1343 if (type == Qt::Popup
1344 || type == Qt::SubWindow
1345 || !(window()->flags() & Qt::WindowStaysOnBottomHint)) {
1346 SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1352 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1353 if (!(window()->flags() & Qt::WindowStaysOnTopHint))
1354 SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1359 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << title;
1360 SetWindowText(handle(),
reinterpret_cast<
const wchar_t *>(title.utf16()));
1365 return QWindowsGeometryHint::mapToGlobal(handle(), pos);
1370 return QWindowsGeometryHint::mapFromGlobal(handle(), pos);
1396 switch (event->type()) {
1397 case QEvent::ChildWindowAdded:
1398 if (!(GetWindowLongPtr(handle(), GWL_STYLE) & WS_CLIPCHILDREN)) {
1399 auto *childWindowEvent =
static_cast<QChildWindowEvent*>(event);
1400 qWarning() << childWindowEvent->child() <<
"added as child to"
1401 << window() <<
"which does not have WS_CLIPCHILDREN set."
1402 <<
"This will result in drawing artifacts!";
1409 return QPlatformWindow::windowEvent(event);
1413
1414
1415
1416
1417
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1434 , m_topLevelStyle(0)
1436 if (QPlatformWindow::parent())
1437 setParent(QPlatformWindow::parent());
1442 if (QPlatformWindow::parent())
1449 const HWND newParent = newParentWindow ?
reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(
nullptr);
1450 const bool isTopLevel = !newParent;
1451 const DWORD oldStyle =
style();
1453 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() <<
"newParent="
1454 << newParentWindow << newParent <<
"oldStyle=" << debugWinStyle(oldStyle);
1456 auto updateWindowFlags = [&] {
1458 DWORD newStyle = oldStyle;
1460 newStyle = m_topLevelStyle;
1462 m_topLevelStyle = oldStyle;
1463 newStyle &= ~(WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW);
1464 newStyle |= WS_CHILD;
1466 SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
1469 if (wasTopLevel && !isTopLevel) {
1472 updateWindowFlags();
1475 SetParent(m_hwnd, newParent);
1477 if (!wasTopLevel && isTopLevel) {
1480 updateWindowFlags();
1486 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << visible;
1488 ShowWindow(handle(), SW_SHOWNOACTIVATE);
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1514 const QRect &geometryIn,
const QRect &geometry,
1516 DWORD style, DWORD exStyle) :
1519 requestedGeometryIn(geometryIn),
1520 requestedGeometry(geometry),
1521 obtainedPos(geometryIn.topLeft()),
1522 obtainedSize(geometryIn.size()),
1523 margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle))
1530 if (!(w->flags() & Qt::FramelessWindowHint))
1533 if (geometry.isValid()
1534 || !qt_window_private(
const_cast<QWindow *>(w))->resizeAutomatic) {
1535 frameX = geometry.x();
1536 frameY = geometry.y();
1537 const QMargins effectiveMargins = margins + customMargins;
1538 frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right();
1539 frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom();
1541 menuHeight = GetSystemMetrics(SM_CYMENU);
1542 frameHeight += menuHeight;
1544 const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel();
1545 if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) {
1546 frameX -= effectiveMargins.left();
1547 frameY -= effectiveMargins.top();
1551 qCDebug(lcQpaWindow).nospace()
1552 <<
__FUNCTION__ <<
' ' << w <<
' ' << geometry
1553 <<
" pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w)
1554 <<
" frame=" << frameWidth <<
'x' << frameHeight <<
'+'
1555 << frameX <<
'+' << frameY
1556 <<
" margins=" << margins <<
" custom margins=" << customMargins;
1561 QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi);
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1593 m_cursor(
new CursorHandle)
1594#if QT_CONFIG(vulkan)
1595 , m_vkSurface(VK_NULL_HANDLE)
1598 QWindowsContext::instance()->addWindow(m_data.hwnd,
this);
1600 if (aWindow->flags().testFlags(Qt::ExpandedClientAreaHint)) {
1601 SetParent(m_data.hwndTitlebar, m_data.hwnd);
1602 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
1605 if (aWindow->surfaceType() == QWindow::Direct3DSurface)
1607#if QT_CONFIG(opengl)
1608 if (aWindow->surfaceType() == QWindow::OpenGLSurface)
1609 setFlag(OpenGLSurface);
1611#if QT_CONFIG(vulkan)
1612 if (aWindow->surfaceType() == QSurface::VulkanSurface)
1613 setFlag(VulkanSurface);
1615 updateDropSite(window()->isTopLevel());
1619 if (!touchWindowTouchTypes_sys().has_value())
1622 const qreal opacity = qt_window_private(aWindow)->opacity;
1623 if (!qFuzzyCompare(opacity, qreal(1.0)))
1624 setOpacity(opacity);
1626 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
1628 if (aWindow->isTopLevel())
1629 setWindowIcon(aWindow->icon());
1637 if (m_vsyncServiceCallbackId != 0)
1638 QDxgiVSyncService::instance()->unregisterCallback(m_vsyncServiceCallbackId);
1640 QWindowsThemeCache::clearThemeCache(m_data.hwnd);
1641 if (testFlag(TouchRegistered))
1642 UnregisterTouchWindow(m_data.hwnd);
1650 QWindowCreationContextPtr creationContext =
1653 QWindow *w = window();
1654 setWindowState(w->windowStates());
1658 const Qt::WindowState state = w->windowState();
1659 const QRect obtainedGeometry(creationContext->obtainedPos, creationContext->obtainedSize);
1660 QPlatformScreen *obtainedScreen = screenForGeometry(obtainedGeometry);
1661 if (obtainedScreen && screen() != obtainedScreen)
1662 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(w, obtainedScreen->screen());
1663 if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen
1664 && creationContext->requestedGeometryIn != obtainedGeometry) {
1665 QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
1667 QWindowsWindow::setSavedDpi(GetDpiForWindow(handle()));
1672 return window()->requestedFormat();
1675void QWindowsWindow::fireExpose(
const QRegion ®ion,
bool force)
1677 if (region.isEmpty() && !force)
1681 QWindowSystemInterface::handleExposeEvent(window(), region);
1686 fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), force);
1691 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << m_data.hwnd;
1695 const auto tlw = QGuiApplication::topLevelWindows();
1696 for (QWindow *w : tlw) {
1697 if (w->transientParent() == window()) {
1698 if (QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(w))
1699 tw->updateTransientParent();
1703 if (context->windowUnderMouse() == window())
1707 setDropSiteEnabled(
false);
1708#if QT_CONFIG(vulkan)
1710 QVulkanInstance *inst = window()->vulkanInstance();
1712 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
1713 m_vkSurface = VK_NULL_HANDLE;
1720 m_surface =
nullptr;
1723 DestroyWindow(m_data.hwnd);
1724 context->removeWindow(m_data.hwnd);
1725 m_data.hwnd =
nullptr;
1731 bool enabled =
false;
1732 bool parentIsEmbedded =
false;
1737 const QWindow *parent = window()->parent();
1738 if (parent && parent->handle() && parent->handle()->isForeignWindow())
1739 parentIsEmbedded =
true;
1742 if (topLevel || parentIsEmbedded) {
1743 switch (window()->type()) {
1756 setDropSiteEnabled(enabled);
1761 if (isDropSiteEnabled() == dropEnabled)
1763 qCDebug(lcQpaMime) <<
__FUNCTION__ << window() << dropEnabled;
1764#if QT_CONFIG(clipboard) && QT_CONFIG(draganddrop)
1766 Q_ASSERT(m_data.hwnd);
1767 m_dropTarget =
new QWindowsOleDropTarget(window());
1768 RegisterDragDrop(m_data.hwnd, m_dropTarget);
1769 CoLockObjectExternal(m_dropTarget,
true,
true);
1771 CoLockObjectExternal(m_dropTarget,
false,
true);
1772 m_dropTarget->Release();
1773 RevokeDragDrop(m_data.hwnd);
1774 m_dropTarget =
nullptr;
1783 m_screenForGLInitialized =
false;
1788 m_screenForGLInitialized =
false;
1793 static QString forceToScreen;
1794 if (!m_screenForGLInitialized) {
1796 m_screenForGLInitialized =
true;
1798 return forceToScreen.isEmpty() ?
nullptr : screenForDeviceName(w, forceToScreen);
1805 while (QWindow *parent = w->parent())
1808 if (
const QPlatformWindow *handle = w->handle()) {
1809 const auto *ww =
static_cast<
const QWindowsWindow *>(handle);
1810 if (ww->isEmbedded()) {
1811 HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
1812 const HWND desktopHwnd = GetDesktopWindow();
1814 while (parentHWND && parentHWND != desktopHwnd) {
1815 if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
1816 return topLevelOf(ancestor->window());
1817 parentHWND = GetAncestor(parentHWND, GA_PARENT);
1827 const QString &title)
1830 creationData.fromWindow(w, parameters.flags);
1833 creationData.initialize(w, result.hwnd, !parameters.customMargins.isNull(), 1);
1839 const QWindow *win = window();
1840 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << win << m_data.hwnd << visible;
1853 if (win->type() == Qt::Popup && !win->parent() && !QGuiApplication::focusWindow())
1854 SetForegroundWindow(m_data.hwnd);
1858 if (window()->flags() & Qt::Popup)
1859 ShowWindow(m_data.hwnd, SW_HIDE);
1862 fireExpose(QRegion());
1869 return m_data.hwnd && IsWindowVisible(m_data.hwnd);
1875 if (
const HWND activeHwnd = GetForegroundWindow())
1876 if (m_data.hwnd == activeHwnd || IsChild(activeHwnd, m_data.hwnd))
1883 const auto *childWindow =
static_cast<
const QWindowsWindow *>(child);
1884 return IsChild(m_data.hwnd, childWindow->handle());
1889 return m_data.embedded;
1894 return m_data.hwnd ? QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos) : pos;
1899 return m_data.hwnd ? QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos) : pos;
1909 if (window()->type() == Qt::Popup)
1912 const HWND oldTransientParent = GetWindow(m_data.hwnd, GW_OWNER);
1913 HWND newTransientParent =
nullptr;
1914 if (
const QWindow *tp = window()->transientParent())
1915 if (
const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp))
1917 newTransientParent = tw->handle();
1921 while (newTransientParent && (GetWindowLongPtr(newTransientParent, GWL_STYLE) & WS_CHILD) != 0)
1922 newTransientParent = GetParent(newTransientParent);
1924 if (newTransientParent != oldTransientParent)
1925 SetWindowLongPtr(m_data.hwnd,
GWL_HWNDPARENT, LONG_PTR(newTransientParent));
1931 const QVariant showWithoutActivating = window->property(
"_q_showWithoutActivating");
1932 return showWithoutActivating.isValid() && showWithoutActivating.toBool();
1937 WINDOWPLACEMENT windowPlacement;
1938 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1939 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1940 windowPlacement.showCmd = SW_SHOWMINIMIZED;
1941 windowPlacement.rcNormalPosition = RECTfromQRect(r);
1942 SetWindowPlacement(hwnd, &windowPlacement);
1949 WINDOWPLACEMENT windowPlacement;
1950 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1951 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1953 windowPlacement.flags |= WPF_RESTORETOMAXIMIZED;
1955 windowPlacement.flags &= ~WPF_RESTORETOMAXIMIZED;
1956 SetWindowPlacement(hwnd, &windowPlacement);
1963 int sm = SW_SHOWNORMAL;
1964 bool fakedMaximize =
false;
1965 bool restoreMaximize =
false;
1966 const QWindow *w = window();
1967 const Qt::WindowFlags flags = w->flags();
1968 const Qt::WindowType type = w->type();
1969 if (w->isTopLevel()) {
1970 const Qt::WindowStates state = w->windowStates();
1971 if (state & Qt::WindowMinimized) {
1972 sm = SW_SHOWMINIMIZED;
1974 sm = SW_SHOWMINNOACTIVE;
1975 if (state & Qt::WindowMaximized)
1976 restoreMaximize =
true;
1978 updateTransientParent();
1979 if (state & Qt::WindowMaximized) {
1980 sm = SW_SHOWMAXIMIZED;
1986 if (flags & Qt::WindowTitleHint &&
1987 !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
1988 fakedMaximize = TRUE;
1989 setStyle(style() | WS_MAXIMIZEBOX);
1994 if (type == Qt::Popup ||
1995 type == Qt::ToolTip ||
1997 (flags & Qt::WindowDoesNotAcceptFocus) ||
1998 testShowWithoutActivating(w))
1999 sm = SW_SHOWNOACTIVATE;
2001 if (w->windowStates() & Qt::WindowMaximized)
2004 ShowWindow(m_data.hwnd, sm);
2008 if (fakedMaximize) {
2009 setStyle(style() & ~WS_MAXIMIZEBOX);
2010 SetWindowPos(m_data.hwnd,
nullptr, 0, 0, 0, 0,
2011 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
2012 | SWP_FRAMECHANGED);
2014 if (restoreMaximize)
2015 setRestoreMaximizedFlag(m_data.hwnd);
2020 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << newParent;
2023 setParent_sys(newParent);
2029 HWND oldParentHWND = parentHwnd();
2030 HWND newParentHWND =
nullptr;
2032 const auto *parentW =
static_cast<
const QWindowsWindow *>(parent);
2033 newParentHWND = parentW->handle();
2038 HWND desktopHwnd = GetDesktopWindow();
2039 if (oldParentHWND == desktopHwnd)
2040 oldParentHWND =
nullptr;
2041 if (newParentHWND == desktopHwnd)
2042 newParentHWND =
nullptr;
2044 if (newParentHWND != oldParentHWND) {
2045 const bool wasTopLevel = oldParentHWND ==
nullptr;
2046 const bool isTopLevel = newParentHWND ==
nullptr;
2049 SetParent(m_data.hwnd, newParentHWND);
2055 if (wasTopLevel != isTopLevel) {
2056 setDropSiteEnabled(
false);
2057 setWindowFlags_sys(window()->flags(),
unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
2058 updateDropSite(isTopLevel);
2065 fireExpose(QRegion());
2070 const QWindow *w = window();
2071 if (windowIsAccelerated(w) && w->format().hasAlpha())
2072 applyBlurBehindWindow(handle());
2077 return QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) /
2078 QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi);
2088 const UINT dpi = UINT(wParam);
2089 const qreal scale = dpiRelativeScale(dpi);
2090 const QMargins margins = fullFrameMargins();
2091 if (!(m_data.flags & Qt::FramelessWindowHint)) {
2097 m_data.customMargins *= scale;
2100 const QSize windowSize = (geometry().size() * scale).grownBy((margins * scale) + customMargins());
2101 SIZE *size =
reinterpret_cast<SIZE *>(lParam);
2102 size->cx = windowSize.width();
2103 size->cy = windowSize.height();
2109 const UINT dpi = HIWORD(wParam);
2110 const qreal scale = dpiRelativeScale(dpi);
2113 QWindowsThemeCache::clearThemeCache(hwnd);
2118 if (!IsZoomed(hwnd))
2119 m_data.restoreGeometry.setSize(m_data.restoreGeometry.size() * scale);
2137 if (!m_inSetgeometry) {
2139 const auto prcNewWindow =
reinterpret_cast<RECT *>(lParam);
2140 SetWindowPos(hwnd,
nullptr, prcNewWindow->left, prcNewWindow->top,
2141 prcNewWindow->right - prcNewWindow->left,
2142 prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
2146 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2147 handleGeometryChange();
2152 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
2157 const UINT dpi = GetDpiForWindow(hwnd);
2158 const qreal scale = dpiRelativeScale(dpi);
2165 QRect currentGeometry = geometry();
2166 QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
2167 setGeometry(scaledGeometry);
2173 wp.length =
sizeof(WINDOWPLACEMENT);
2174 if (GetWindowPlacement(hwnd, &wp)) {
2175 const QRect result = qrectFromRECT(wp.rcNormalPosition);
2176 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
2184 const bool fakeFullScreen =
2185 m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen);
2186 const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
2187 const QMargins margins = fakeFullScreen
2188 ? QWindowsGeometryHint::frame(window(), handle(), m_savedStyle, 0)
2189 : fullFrameMargins();
2190 return frame.isValid() ? frame.marginsRemoved(margins) : frame;
2195 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
2196 const int titleBarHeight = getTitleBarHeight_sys(96);
2198 return QMargins(0, titleBarHeight, 0, 0);
2204 const QRect &requestedRect,
2205 const QRect &obtainedRect,
2206 const QMargins &fullMargins,
2207 const QMargins &customMargins)
2210 QDebug debug(&result);
2213 const auto window = platformWindow->window();
2214 debug <<
"Unable to set geometry ";
2215 formatBriefRectangle(debug, requestedRect);
2216 debug <<
" (frame: ";
2217 formatBriefRectangle(debug, requestedRect + fullMargins);
2218 debug <<
") on " << window->metaObject()->className() <<
"/\""
2219 << window->objectName() <<
"\" on \"" << window->screen()->name()
2220 <<
"\". Resulting geometry: ";
2221 formatBriefRectangle(debug, obtainedRect);
2222 debug <<
" (frame: ";
2223 formatBriefRectangle(debug, obtainedRect + fullMargins);
2224 debug <<
") margins: ";
2225 formatBriefMargins(debug, fullMargins);
2226 if (!customMargins.isNull()) {
2227 debug <<
" custom margin: ";
2228 formatBriefMargins(debug, customMargins);
2230 const auto minimumSize = window->minimumSize();
2231 const bool hasMinimumSize = !minimumSize.isEmpty();
2233 debug <<
" minimum size: " << minimumSize.width() <<
'x' << minimumSize.height();
2234 const auto maximumSize = window->maximumSize();
2235 const bool hasMaximumSize = maximumSize.width() != QWINDOWSIZE_MAX || maximumSize.height() != QWINDOWSIZE_MAX;
2237 debug <<
" maximum size: " << maximumSize.width() <<
'x' << maximumSize.height();
2238 if (hasMinimumSize || hasMaximumSize) {
2239 MINMAXINFO minmaxInfo;
2240 memset(&minmaxInfo, 0,
sizeof(minmaxInfo));
2241 platformWindow->getSizeHints(&minmaxInfo);
2242 debug <<
' ' << minmaxInfo;
2250 QScopedValueRollback b(m_inSetgeometry,
true);
2252 QRect rect = rectIn;
2255 if (QWindowsGeometryHint::positionIncludesFrame(window())) {
2256 const QMargins margins = frameMargins();
2257 rect.moveTopLeft(rect.topLeft() +
QPoint(margins.left(), margins.top()));
2259 if (m_windowState & Qt::WindowMinimized)
2260 m_data.geometry = rect;
2266 setGeometry_sys(rect);
2268 if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) {
2269 const auto warning =
2270 msgUnableToSetGeometry(
this, rectIn, m_data.geometry,
2271 fullFrameMargins(), customMargins());
2272 qWarning(
"%s: %s",
__FUNCTION__, qPrintable(warning));
2275 QPlatformWindow::setGeometry(rect);
2282 if (!IsIconic(m_data.hwnd) && !testFlag(WithinSetParent))
2283 handleGeometryChange();
2289 if ((m_data.flags.testFlag(Qt::FramelessWindowHint)
2290 || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))
2291 && IsZoomed(m_data.hwnd)) {
2292 const int resizedWidth = LOWORD(lParam);
2293 const int resizedHeight = HIWORD(lParam);
2295 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTOPRIMARY);
2296 MONITORINFO monitorInfo = {};
2297 monitorInfo.cbSize =
sizeof(MONITORINFO);
2298 GetMonitorInfoW(monitor, &monitorInfo);
2300 int correctLeft = monitorInfo.rcMonitor.left;
2301 int correctTop = monitorInfo.rcMonitor.top;
2302 int correctWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
2303 int correctHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
2305 if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
2306 const int borderWidth = invisibleMargins(m_data.hwnd).left();
2307 correctLeft -= borderWidth;
2308 correctTop -= borderWidth;
2309 correctWidth += borderWidth * 2;
2310 correctHeight += borderWidth * 2;
2313 if (resizedWidth != correctWidth || resizedHeight != correctHeight) {
2314 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"correcting: " << resizedWidth <<
"x"
2315 << resizedHeight <<
" -> " << correctWidth <<
"x" << correctHeight;
2316 SetWindowPos(m_data.hwnd,
nullptr, correctLeft, correctTop, correctWidth, correctHeight,
2317 SWP_NOZORDER | SWP_NOACTIVATE);
2325 case SIZE_MINIMIZED:
2326 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2327 handleWindowStateChange(m_windowState | Qt::WindowMinimized);
2329 case SIZE_MAXIMIZED:
2330 handleGeometryChange();
2331 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2332 handleWindowStateChange(Qt::WindowMaximized | (isFullScreen_sys() ? Qt::WindowFullScreen
2333 : Qt::WindowNoState));
2336 handleGeometryChange();
2338 if (isFullScreen_sys())
2339 handleWindowStateChange(
2340 Qt::WindowFullScreen
2341 | (testFlag(MaximizeToFullScreen) ? Qt::WindowMaximized : Qt::WindowNoState));
2342 else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
2343 handleWindowStateChange(Qt::WindowNoState);
2349static inline bool equalDpi(
const QDpi &d1,
const QDpi &d2)
2351 return qFuzzyCompare(d1.first, d2.first) && qFuzzyCompare(d1.second, d2.second);
2359 QPlatformScreen *currentScreen = screen();
2360 auto topLevel = isTopLevel_sys() ? m_data.hwnd : GetAncestor(m_data.hwnd, GA_ROOT);
2364 if (newScreen ==
nullptr || newScreen == currentScreen)
2368 const bool changingDpi = !equalDpi(QDpi(savedDpi(), savedDpi()), newScreen->logicalDpi());
2372 qCDebug(lcQpaWindow).noquote().nospace() <<
__FUNCTION__
2373 <<
' ' << window() <<
" \"" << (currentScreen ? currentScreen->name() : QString())
2374 <<
"\"->\"" << newScreen->name() <<
'"';
2376 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
2381 const QRect previousGeometry = m_data.geometry;
2382 m_data.geometry = geometry_sys();
2384 QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
2389 && m_data.geometry.size() != previousGeometry.size()
2391 && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
2392 fireFullExpose(
true);
2398 if (testFlag(SynchronousGeometryChangeEvent))
2399 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2406 qCDebug(lcQpaEvents) <<
__FUNCTION__ <<
this << window() << m_data.geometry;
2408 if (m_data.flags & Qt::ExpandedClientAreaHint) {
2409 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
2410 MoveWindow(m_data.hwndTitlebar, 0, 0, m_data.geometry.width(), titleBarHeight,
true);
2416 const QMargins margins = fullFrameMargins();
2417 const QRect frameGeometry = rect + margins;
2419 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ << window()
2420 <<
"\n from " << geometry_sys() <<
" frame: "
2421 << margins <<
" to " <<rect
2422 <<
" new frame: " << frameGeometry;
2424 bool result =
false;
2425 const HWND hwnd = handle();
2426 WINDOWPLACEMENT windowPlacement;
2427 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2428 GetWindowPlacement(hwnd, &windowPlacement);
2431 if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(hwnd))
2432 || windowPlacement.showCmd == SW_SHOWMINIMIZED) {
2433 windowPlacement.rcNormalPosition =
2434 RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(hwnd, frameGeometry.topLeft())));
2435 windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
2436 result = SetWindowPlacement(hwnd, &windowPlacement);
2438 int x = frameGeometry.x();
2439 if (!window()->isTopLevel()) {
2440 const HWND parentHandle = GetParent(hwnd);
2441 if (isRtlLayout(parentHandle)) {
2443 GetClientRect(parentHandle, &rect);
2444 x = rect.right - frameGeometry.width() - x;
2447 result = MoveWindow(hwnd, x, frameGeometry.y(),
2448 frameGeometry.width(), frameGeometry.height(),
true);
2450 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ << window()
2451 <<
"\n resulting " << result << geometry_sys();
2455
2456
2457
2458
2459
2464 m_hdc = GetDC(handle());
2465 if (QGuiApplication::layoutDirection() == Qt::RightToLeft)
2466 SetLayout(m_hdc, 0);
2472
2473
2474
2475
2476
2481 ReleaseDC(handle(), m_hdc);
2488#if QT_CONFIG(dynamicgl)
2489 return QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()
2490 && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL;
2499 if (message == WM_ERASEBKGND) {
2504 if (!window()->isVisible() && (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0)
2507 if (!GetUpdateRect(m_data.hwnd, 0, FALSE))
2514 InvalidateRect(hwnd,
nullptr,
false);
2516 BeginPaint(hwnd, &ps);
2521 fireExpose(QRegion(qrectFromRECT(ps.rcPaint)),
true);
2522 if (!QWindowsContext::instance()->asyncExpose())
2523 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2525 EndPaint(hwnd, &ps);
2531 m_windowTitle = QWindowsWindow::formatWindowTitle(title);
2532 setWindowTitle_sys(m_windowTitle);
2537 return m_windowTitle;
2542 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window() <<
"\n from: "
2543 << m_data.flags <<
"\n to: " << flags;
2544 const QRect oldGeometry = geometry();
2545 if (m_data.flags != flags) {
2546 m_data.flags = flags;
2548 m_data = setWindowFlags_sys(flags);
2549 updateDropSite(window()->isTopLevel());
2556 const QRect newGeometry = geometry_sys();
2557 if (oldGeometry != newGeometry)
2558 handleGeometryChange();
2560 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
"\n returns: "
2561 << m_data.flags <<
" geometry " << oldGeometry <<
"->" << newGeometry;
2565 unsigned flags)
const
2568 creationData.fromWindow(window(), wt, flags);
2569 creationData.applyWindowFlags(m_data.hwnd);
2570 creationData.initialize(window(), m_data.hwnd,
true, m_opacity);
2572 if (creationData.flags.testFlag(Qt::ExpandedClientAreaHint)) {
2573 SetParent(m_data.hwndTitlebar, m_data.hwnd);
2574 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
2576 if (IsWindowVisible(m_data.hwndTitlebar)) {
2577 SetParent(m_data.hwndTitlebar, HWND_MESSAGE);
2578 ShowWindow(m_data.hwndTitlebar, SW_HIDE);
2583 result.flags = creationData.flags;
2585 result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME))
2586 && !(creationData.flags & Qt::FramelessWindowHint);
2590void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
2592 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window()
2593 <<
"\n from " << m_windowState <<
" to " << state;
2594 m_windowState = state;
2595 QWindowSystemInterface::handleWindowStateChanged(window(), state);
2596 if (state & Qt::WindowMinimized) {
2598 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2601 if (state & Qt::WindowMaximized) {
2602 WINDOWPLACEMENT windowPlacement{};
2603 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2604 GetWindowPlacement(m_data.hwnd, &windowPlacement);
2605 const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
2606 windowPlacement.rcNormalPosition = geometry;
2607 correctWindowPlacement(windowPlacement);
2613 windowPlacement.showCmd = SW_HIDE;
2614 SetWindowPlacement(m_data.hwnd, &windowPlacement);
2618 QWindow *w = window();
2619 bool exposeEventsSent =
false;
2622 exposeEventsSent =
true;
2624 const QWindowList allWindows = QGuiApplication::allWindows();
2625 for (QWindow *child : allWindows) {
2626 if (child != w && child->isVisible() && child->transientParent() == w) {
2627 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
2628 if (platformWindow && platformWindow->isLayered()) {
2629 platformWindow->fireFullExpose();
2630 exposeEventsSent =
true;
2634 if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
2635 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2644 return window()->maximumHeight() != QWINDOWSIZE_MAX;
2649 return window()->maximumWidth() != QWINDOWSIZE_MAX;
2657void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
2659 static const auto windows11 = QOperatingSystemVersion::Windows11_21H2;
2660 static const bool isWindows10 = QOperatingSystemVersion::current() < windows11;
2666 const QPoint offset = windowPlacementOffset(m_data.hwnd, m_data.restoreGeometry.topLeft());
2667 windowPlacement.rcNormalPosition = RECTfromQRect(m_data.restoreGeometry.translated(-offset));
2668 qCDebug(lcQpaWindow) <<
"Corrected normal position by" << -offset;
2677 const QMargins margins = frameMargins_sys();
2678 const QPoint topLeft = window()->screen()->geometry().topLeft();
2679 windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() };
2680 qCDebug(lcQpaWindow) <<
"Window has maximum size. Corrected topLeft by"
2686 const int adjust = offset.x() / window()->devicePixelRatio();
2687 window()->setWidth(window()->width() - adjust);
2688 qCDebug(lcQpaWindow) <<
"Width shortened by" << adjust <<
"logical pixels.";
2691 const int adjust = offset.y() / window()->devicePixelRatio();
2692 window()->setHeight(window()->height() - adjust);
2693 qCDebug(lcQpaWindow) <<
"Height shortened by" << adjust <<
"logical pixels.";
2700 m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
2706 setWindowState_sys(state);
2707 m_windowState = state;
2713 const QWindow *w = window();
2714 if (!w->isTopLevel())
2716 QRect geometry = geometry_sys();
2718 geometry += QMargins(1, 1, 1, 1);
2719 QPlatformScreen *screen = screenForGeometry(geometry);
2720 return screen && geometry == screen->geometry();
2724
2725
2726
2727
2728
2729
2730
2731
2732
2734void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
2736 const Qt::WindowStates oldState = m_windowState;
2737 if (oldState == newState)
2739 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window()
2740 <<
" from " << oldState <<
" to " << newState;
2743 auto stateChange = oldState ^ newState;
2745 if (stateChange & Qt::WindowFullScreen) {
2746 if (newState & Qt::WindowFullScreen) {
2747 UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
2751 if (!m_savedStyle) {
2752 m_savedStyle =
style();
2753 if ((oldState & Qt::WindowMinimized) || (oldState & Qt::WindowMaximized)) {
2754 const QRect nf = normalFrameGeometry(m_data.hwnd);
2756 m_savedFrameGeometry = nf;
2758 m_savedFrameGeometry = frameGeometry_sys();
2761 if (newState & Qt::WindowMaximized)
2763 if (m_savedStyle & WS_SYSMENU)
2764 newStyle |= WS_SYSMENU;
2766 newStyle |= WS_VISIBLE;
2767 if (testFlag(HasBorderInFullScreen))
2768 newStyle |= WS_BORDER;
2770 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2771 MONITORINFO monitorInfo = {};
2772 monitorInfo.cbSize =
sizeof(MONITORINFO);
2773 GetMonitorInfoW(monitor, &monitorInfo);
2774 const QRect screenGeometry(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
2775 monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
2776 monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
2777 if (newState & Qt::WindowMinimized) {
2778 setMinimizedGeometry(m_data.hwnd, screenGeometry);
2779 if (stateChange & Qt::WindowMaximized)
2780 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2782 const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
2785 SetWindowPos(m_data.hwnd, HWND_TOP, screenGeometry.left(), screenGeometry.top(), screenGeometry.width(), screenGeometry.height(), swpf);
2789 QWindowSystemInterface::handleGeometryChange(window(), screenGeometry);
2790 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2794 unsigned newStyle = m_savedStyle ? m_savedStyle :
style();
2796 newStyle |= WS_VISIBLE;
2799 const QScreen *screen = window()->screen();
2801 screen = QGuiApplication::primaryScreen();
2803 if (
const auto platformScreen = screen->handle()) {
2804 if (!platformScreen->geometry().intersects(m_savedFrameGeometry))
2805 m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft());
2808 if (newState & Qt::WindowMinimized) {
2809 setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry);
2810 if (stateChange & Qt::WindowMaximized)
2811 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2813 UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
2814 if (!m_savedFrameGeometry.isValid())
2815 swpf |= SWP_NOSIZE | SWP_NOMOVE;
2820 if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
2821 ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
2822 SetWindowPos(m_data.hwnd,
nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
2823 m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
2829 ShowWindow(m_data.hwnd,
2830 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
2835 m_savedFrameGeometry = QRect();
2837 }
else if ((oldState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
2838 if (visible && !(newState & Qt::WindowMinimized)) {
2840 if (newState & Qt::WindowFullScreen)
2842 if (m_data.flags & Qt::FramelessWindowHint) {
2843 if (newState == Qt::WindowNoState) {
2844 const QRect &rect = m_savedFrameGeometry;
2845 MoveWindow(m_data.hwnd, rect.x(), rect.y(), rect.width(), rect.height(),
true);
2847 HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2848 MONITORINFO monitorInfo = {};
2849 monitorInfo.cbSize =
sizeof(MONITORINFO);
2850 GetMonitorInfo(monitor, &monitorInfo);
2851 const RECT &rect = monitorInfo.rcWork;
2852 m_savedFrameGeometry = geometry();
2853 MoveWindow(m_data.hwnd, rect.left, rect.top,
2854 rect.right - rect.left, rect.bottom - rect.top,
true);
2857 ShowWindow(m_data.hwnd,
2858 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
2862 }
else if (visible && (oldState & newState & Qt::WindowMinimized)) {
2864 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2868 if (stateChange & Qt::WindowMinimized) {
2870 ShowWindow(m_data.hwnd,
2871 (newState & Qt::WindowMinimized) ? SW_MINIMIZE :
2872 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
2873 if ((newState & Qt::WindowMinimized) && (stateChange & Qt::WindowMaximized))
2874 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2877 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
this << window() << newState;
2882 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinStyle(s);
2884 SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
2890 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinExStyle(s);
2891 SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
2896 switch (event->type()) {
2897 case QEvent::ApplicationPaletteChange:
2898 setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
2900 case QEvent::WindowBlocked:
2906 case QEvent::WindowUnblocked:
2914 return QWindowsBaseWindow::windowEvent(event);
2919 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
2924 bool result =
false;
2925 if ((windowPos->flags & SWP_NOSIZE) == 0) {
2927 GetWindowRect(windowPos->hwnd, &rect);
2928 result = rect.right - rect.left != windowPos->cx || rect.bottom - rect.top != windowPos->cy;
2933bool QWindowsWindow::handleGeometryChangingMessage(MSG *message,
const QWindow *qWindow,
const QMargins &margins)
2935 auto *windowPos =
reinterpret_cast<WINDOWPOS *>(message->lParam);
2936 const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
2937 windowPos->cx, windowPos->cy);
2938 const QRect suggestedGeometry = suggestedFrameGeometry - margins;
2945 if (isResize(windowPos))
2946 windowPos->flags |= SWP_NOCOPYBITS;
2948 if ((windowPos->flags & SWP_NOZORDER) == 0) {
2949 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(qWindow)) {
2950 QWindow *parentWindow = qWindow->parent();
2951 HWND parentHWND = GetAncestor(windowPos->hwnd, GA_PARENT);
2952 HWND desktopHWND = GetDesktopWindow();
2953 platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND);
2955 if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint))
2956 windowPos->hwndInsertAfter = HWND_BOTTOM;
2958 if (!qWindow->isTopLevel())
2960 if (windowPos->flags & SWP_NOSIZE)
2962 const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
2963 if (!correctedGeometryF.isValid())
2965 const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
2966 if (correctedFrameGeometry == suggestedFrameGeometry)
2968 windowPos->x = correctedFrameGeometry.left();
2969 windowPos->y = correctedFrameGeometry.top();
2970 windowPos->cx = correctedFrameGeometry.width();
2971 windowPos->cy = correctedFrameGeometry.height();
2977 const QMargins margins = window()->isTopLevel() ? fullFrameMargins() : QMargins();
2978 return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
2983 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2985 if (m_data.fullFrameMargins != newMargins) {
2986 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << m_data.fullFrameMargins <<
"->" << newMargins;
2987 m_data.fullFrameMargins = newMargins;
2994 if (GetMenu(m_data.hwnd))
2995 QWindowsContext::forceNcCalcSize(m_data.hwnd);
2997 calculateFullFrameMargins();
3002 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3015 GetWindowRect(handle(), &windowRect);
3016 GetClientRect(handle(), &clientRect);
3022 if (qrectFromRECT(windowRect).size() == qrectFromRECT(clientRect).size())
3027 const auto systemMargins = testFlag(DisableNonClientScaling)
3028 ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd)
3029 : frameMargins_sys();
3030 const int extendedClientAreaBorder = window()->flags().testFlag(Qt::ExpandedClientAreaHint) ? qRound(QHighDpiScaling::factor(window())) * 2 : 0;
3031 const QMargins actualMargins = systemMargins + customMargins() - extendedClientAreaBorder;
3033 const int yDiff = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
3034 const bool typicalFrame = (actualMargins.left() == actualMargins.right())
3035 && (actualMargins.right() == actualMargins.bottom());
3037 const QMargins adjustedMargins = typicalFrame ?
3038 QMargins(actualMargins.left(), (yDiff - actualMargins.bottom()),
3039 actualMargins.right(), actualMargins.bottom())
3042 setFullFrameMargins(adjustedMargins);
3047 QMargins result = fullFrameMargins();
3048 if (isTopLevel() && m_data.hasFrame)
3049 result -= invisibleMargins(m_data.hwnd);
3055 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3057 return m_data.fullFrameMargins;
3062 qCDebug(lcQpaWindow) <<
__FUNCTION__ << level;
3063 if (!qFuzzyCompare(m_opacity, level)) {
3066 setWindowOpacity(m_data.hwnd, m_data.flags,
3067 window()->format().hasAlpha(), testFlag(OpenGLSurface) || testFlag(VulkanSurface) || testFlag(Direct3DSurface),
3074 return CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
3079 if (
const HRGN rectRegion = createRectRegion(rect)) {
3080 HRGN result = CreateRectRgn(0, 0, 0, 0);
3081 if (CombineRgn(result, *winRegion, rectRegion, RGN_OR)) {
3082 DeleteObject(*winRegion);
3083 *winRegion = result;
3085 DeleteObject(rectRegion);
3091 auto it = region.begin();
3092 const auto end = region.end();
3095 HRGN hRegion = createRectRegion(*it);
3097 addRectToWinRegion(*it, &hRegion);
3103 if (region.isEmpty()) {
3104 SetWindowRgn(m_data.hwnd,
nullptr,
true);
3107 const HRGN winRegion = qRegionToWinRegion(region);
3110 if (window()->isTopLevel()) {
3111 const QMargins margins = fullFrameMargins();
3112 OffsetRgn(winRegion, margins.left(), margins.top());
3116 if (!SetWindowRgn(m_data.hwnd, winRegion,
true))
3117 DeleteObject(winRegion);
3122 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
3128 if (QGuiApplication::applicationState() == Qt::ApplicationActive
3129 || activationBehavior != QWindowsApplication::AlwaysActivateWindow) {
3130 SetForegroundWindow(m_data.hwnd);
3131 SetFocus(m_data.hwnd);
3140 if (m_data.flags & Qt::WindowStaysOnBottomHint) {
3141 qCWarning(lcQpaWindow) <<
3142 "Windows with Qt::WindowStaysOnBottomHint can't be brought to the foreground.";
3145 if (m_data.flags & Qt::WindowStaysOnTopHint) {
3146 qCWarning(lcQpaWindow) <<
3147 "Windows with Qt::WindowStaysOnTopHint will always be on the foreground.";
3150 if (window()->type() == Qt::ToolTip) {
3151 qCWarning(lcQpaWindow) <<
"ToolTip windows should not be activated.";
3156 if (!IsWindowVisible(m_data.hwnd))
3157 ShowWindow(m_data.hwnd, SW_SHOW);
3159 if (IsIconic(m_data.hwnd)) {
3160 ShowWindow(m_data.hwnd, SW_RESTORE);
3167 const HWND oldForegroundWindow = GetForegroundWindow();
3168 if (!oldForegroundWindow)
3173 if (SendMessageTimeoutW(oldForegroundWindow, WM_NULL, 0, 0,
3174 SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000,
nullptr) == 0) {
3175 qCWarning(lcQpaWindow) <<
"The foreground window hangs, can't activate current window.";
3179 const DWORD windowThreadProcessId = GetWindowThreadProcessId(oldForegroundWindow,
nullptr);
3180 const DWORD currentThreadId = GetCurrentThreadId();
3182 AttachThreadInput(windowThreadProcessId, currentThreadId, TRUE);
3183 const auto cleanup = qScopeGuard([windowThreadProcessId, currentThreadId](){
3184 AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE);
3187 BringWindowToTop(m_data.hwnd);
3191 SetActiveWindow(m_data.hwnd);
3197 qWarning(
"%s: No handle",
__FUNCTION__);
3200 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << grab;
3204 context->setKeyGrabber(window());
3206 if (context->keyGrabber() == window())
3207 context->setKeyGrabber(
nullptr);
3214 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << grab;
3216 qWarning(
"%s: No handle",
__FUNCTION__);
3220 qWarning(
"%s: Not setting mouse grab for invisible window %s/'%s'",
3221 __FUNCTION__, window()->metaObject()->className(),
3222 qPrintable(window()->objectName()));
3229 SetCapture(m_data.hwnd);
3239 if (edges == Qt::LeftEdge)
3241 else if (edges == (Qt::RightEdge))
3243 else if (edges == (Qt::TopEdge))
3245 else if (edges == (Qt::TopEdge | Qt::LeftEdge))
3247 else if (edges == (Qt::TopEdge | Qt::RightEdge))
3249 else if (edges == (Qt::BottomEdge))
3251 else if (edges == (Qt::BottomEdge | Qt::LeftEdge))
3253 else if (edges == (Qt::BottomEdge | Qt::RightEdge))
3261 if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
3265 PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0);
3273 PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 , 0);
3288 QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
3289 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << *mmi;
3295 const QWindow *w = window();
3296 const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
3297 const QRect geom = geometry();
3298 static auto oldMouseButtonState = Qt::NoButton;
3300 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
3301 bool isDefaultTitleBar = !w->flags().testFlag(Qt::CustomizeWindowHint);
3302 bool isCustomized = w->flags().testFlags(Qt::CustomizeWindowHint) && w->flags().testAnyFlags(Qt::WindowTitleHint|
3303 Qt::WindowMinimizeButtonHint|
3304 Qt::WindowMaximizeButtonHint|
3305 Qt::WindowCloseButtonHint);
3306 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3307 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3308 const int titleButtonWidth = titleBarHeight * 1.5;
3309 const bool mouseButtonsSwapped = GetSystemMetrics(SM_SWAPBUTTON);
3310 auto mouseButtons = Qt::NoButton;
3311 if (mouseButtonsSwapped)
3312 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::RightButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::LeftButton : Qt::NoButton);
3314 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::LeftButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::RightButton : Qt::NoButton);
3317 if (isCustomized || isDefaultTitleBar) {
3320 if (globalPos.y() < geom.top() + titleBarHeight) {
3321 if (m_data.flags.testFlags(Qt::WindowCloseButtonHint) || isDefaultTitleBar) {
3322 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right())) {
3323 if (mouseButtons == Qt::LeftButton)
3327 }
if (m_data.flags.testFlags(Qt::WindowMaximizeButtonHint) || isDefaultTitleBar) {
3328 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3329 if (mouseButtons == Qt::LeftButton) {
3330 if (IsZoomed(m_data.hwnd))
3333 *result = HTMAXBUTTON;
3337 }
if (m_data.flags.testFlags(Qt::WindowMinimizeButtonHint) || isDefaultTitleBar) {
3338 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3339 if (mouseButtons == Qt::LeftButton)
3340 *result = HTMINBUTTON;
3343 }
if ((isCustomized || isDefaultTitleBar) &&
3344 *result == HTCLIENT){
3345 QWindow* wnd = window();
3346 if (mouseButtons != oldMouseButtonState) {
3347 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3348 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3349 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3350 if (!accepted && mouseButtons == Qt::RightButton)
3351 *result = HTSYSMENU;
3352 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3353 *result = HTCAPTION;
3357 }
else if (w->flags().testFlag(Qt::CustomizeWindowHint)) {
3359 QWindow* wnd = window();
3360 if (mouseButtons != oldMouseButtonState) {
3361 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3362 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3363 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3364 if (!accepted && mouseButtons == Qt::RightButton)
3365 *result = HTSYSMENU;
3366 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3367 *result = HTCAPTION;
3370 oldMouseButtonState = mouseButtons;
3373 const bool left = (globalPos.x() >= geom.left()) && (globalPos.x() < geom.left() + border);
3374 const bool right = (globalPos.x() > geom.right() - border) && (globalPos.x() <= geom.right());
3375 const bool top = (globalPos.y() >= geom.top()) && (globalPos.y() < geom.top() + border);
3376 const bool bottom = (globalPos.y() > geom.bottom() - border) && (globalPos.y() <= geom.bottom());
3378 if (left || right || top || bottom) {
3380 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3382 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3384 *result = top ? HTTOP : HTBOTTOM;
3390 const_cast<QWindow *>(w)->close();
3393 const_cast<QWindow *>(w)->showMaximized();
3396 const_cast<QWindow *>(w)->showMinimized();
3399 const_cast<QWindow *>(w)->showNormal();
3402 HWND hwnd =
reinterpret_cast<HWND>(w->winId());
3403 HMENU sysMenu = GetSystemMenu(hwnd,
false);
3404 TrackPopupMenu(sysMenu, 0, globalPos.x(), globalPos.y(), 0, hwnd,
nullptr);
3413 if (m_data.flags & Qt::ExpandedClientAreaHint) {
3414 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3419 const QRect rect = geom;
3420 const bool left = (globalPos.x() >= rect.left()) && (globalPos.x() < rect.left() + border);
3421 const bool right = (globalPos.x() > rect.right() - border) && (globalPos.x() <= rect.right());
3422 const bool top = (globalPos.y() >= rect.top()) && (globalPos.y() < rect.top() + border);
3423 const bool bottom = (globalPos.y() > rect.bottom() - border) && (globalPos.y() <= rect.bottom());
3426 if (left || right || top || bottom) {
3428 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3430 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3432 *result = top ? HTTOP : HTBOTTOM;
3440 if (!w->isTopLevel()
3441 || (m_windowState != Qt::WindowNoState)
3443 || (m_data.flags & Qt::FramelessWindowHint)) {
3446 const QSize minimumSize = w->minimumSize();
3447 if (minimumSize.isEmpty())
3449 const QSize maximumSize = w->maximumSize();
3450 const bool fixedWidth = minimumSize.width() == maximumSize.width();
3451 const bool fixedHeight = minimumSize.height() == maximumSize.height();
3452 if (!fixedWidth && !fixedHeight)
3454 const QSize size = w->size();
3456 if (localPos.y() >= size.height()) {
3460 if (localPos.y() < 0) {
3461 const int topResizeBarPos = invisibleMargins(m_data.hwnd).left() - frameMargins().top();
3462 if (localPos.y() < topResizeBarPos) {
3463 *result = HTCAPTION;
3468 if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
3480 if (m_data.flags & Qt::FramelessWindowHint) {
3489 HWND hwnd = m_data.hwndTitlebar;
3490 QWindow *wnd = window();
3493 GetWindowRect(hwnd, &windowRect);
3495 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3496 const int titleButtonWidth = titleBarHeight * 1.5;
3497 const qreal factor = QHighDpiScaling::factor(wnd);
3498 const int windowWidth = windowRect.right - windowRect.left;
3501 GetCursorPos(&localPos);
3502 MapWindowPoints(HWND_DESKTOP, m_data.hwnd, &localPos, 1);
3504 const bool isDarkmode = QWindowsIntegration::instance()->darkModeHandling().testFlags(QWindowsApplication::DarkModeWindowFrames) &&
3505 qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
3506 const bool isWindows11orAbove = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11;
3508 const QBrush closeButtonBrush(QColor(0xC4, 0x2C, 0x1E, 255));
3509 const QBrush minMaxButtonBrush = QBrush(isDarkmode ? QColor(0xFF, 0xFF, 0xFF, 0x40) : QColor(0x00, 0x00, 0x00, 0x20));
3510 const QBrush titleBarBackgroundColor = QBrush(isDarkmode ? QColor(0x1F, 0x1F, 0x1F, 0xFF) : QColor(0xF3, 0xF3, 0xF3, 0xFF));
3511 const QPen textPen = QPen(isDarkmode ? QColor(0xFF, 0xFF, 0xFD, 0xFF) : QColor(0x00, 0x00, 0x00, 0xFF));
3513 QImage image(windowWidth, titleBarHeight, QImage::Format_ARGB32);
3515 p.setCompositionMode(QPainter::CompositionMode_Clear);
3516 p.fillRect(0, 0, windowWidth, titleBarHeight, Qt::transparent);
3518 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
3520 p.setBrush(titleBarBackgroundColor);
3521 p.setPen(Qt::NoPen);
3522 if (!wnd->flags().testFlags(Qt::NoTitleBarBackgroundHint)) {
3524 titleRect.setWidth(windowWidth);
3525 titleRect.setHeight(titleBarHeight);
3526 p.drawRect(titleRect);
3529 if (wnd->flags().testFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3533 titleRect.setWidth(windowWidth);
3534 titleRect.setHeight(titleBarHeight);
3536 titleRect.adjust(factor * 4, 0, 0, 0);
3537 QRect iconRect(titleRect.x(), titleRect.y() + factor * 8, factor * 16, factor * 16);
3538 if (wnd->icon().isNull()) {
3539 static QIcon defaultIcon;
3540 if (defaultIcon.isNull()) {
3541 const QImage defaultIconImage = QImage::fromHICON(LoadIcon(0, IDI_APPLICATION));
3542 defaultIcon = QIcon(QPixmap::fromImage(defaultIconImage));
3544 defaultIcon.paint(&p, iconRect);
3546 wnd->icon().paint(&p, iconRect);
3548 titleRect.adjust(factor * 24, 0, 0, 0);
3552 titleFont.setPointSize(factor * 9);
3553 titleFont.setWeight(QFont::Thin);
3554 titleFont.setHintingPreference(QFont::PreferFullHinting);
3555 p.setFont(titleFont);
3556 const QString title = wnd->title().isEmpty() ? qApp->applicationName() : wnd->title();
3557 p.drawText(titleRect, title, QTextOption(Qt::AlignVCenter));
3561 const QString assetFontName = isWindows11orAbove ? QStringLiteral(
"Segoe Fluent Icons") : QStringLiteral(
"Segoe MDL2 Assets");
3562 QFont assetFont = QFont(assetFontName, factor * 7);
3563 assetFont.setWeight(QFont::Thin);
3564 assetFont.setHintingPreference(QFont::PreferFullHinting);
3565 p.setFont(assetFont);
3566 p.setBrush(closeButtonBrush);
3567 p.setPen(Qt::NoPen);
3568 if (wnd->flags().testFlags(Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3571 rect.setX(windowWidth - titleButtonWidth * buttons);
3572 rect.setWidth(titleButtonWidth);
3573 rect.setHeight(titleBarHeight);
3574 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3575 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3576 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3578 const QPen closeButtonHoveredPen = QPen(QColor(0xFF, 0xFF, 0xFD, 0xFF));
3579 p.setPen(closeButtonHoveredPen);
3583 p.drawText(rect, QStringLiteral(
"\uE8BB"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3587 p.setBrush(minMaxButtonBrush);
3588 p.setPen(Qt::NoPen);
3589 if (wnd->flags().testFlags(Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3592 rect.setX(windowWidth - titleButtonWidth * buttons);
3593 rect.setWidth(titleButtonWidth);
3594 rect.setHeight(titleBarHeight);
3595 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3596 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3597 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3601 p.drawText(rect,QStringLiteral(
"\uE922"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3605 p.setBrush(minMaxButtonBrush);
3606 p.setPen(Qt::NoPen);
3607 if (wnd->flags().testFlags(Qt::WindowMinimizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3610 rect.setX(windowWidth - titleButtonWidth * buttons);
3611 rect.setWidth(titleButtonWidth);
3612 rect.setHeight(titleBarHeight);
3613 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3614 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3615 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3619 p.drawText(rect,QStringLiteral(
"\uE921"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3625 HBITMAP bmp = image.toHBITMAP();
3627 HDC hdc = GetDC(hwnd);
3629 HDC memdc = CreateCompatibleDC(hdc);
3630 HGDIOBJ original = SelectObject(memdc, bmp);
3633 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
3634 POINT ptLocation = { 0, 0 };
3635 SIZE szWnd = { windowWidth, titleBarHeight };
3636 POINT ptSrc = { 0, 0 };
3637 UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
3638 SelectObject(hdc, original);
3641 DeleteObject(memdc);
3642 ReleaseDC(hwnd,hdc);
3649 if (QScreen *screen = w->screen())
3650 if (
const QPlatformScreen *platformScreen = screen->handle())
3651 if (QPlatformCursor *cursor = platformScreen->cursor())
3652 return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
3653 return CursorHandlePtr(
new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
3662 if (underMouse == w)
3664 for (
const QWindow *p = underMouse; p ; p = p->parent()) {
3667 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p);
3668 if (platformWindow && !platformWindow->cursor()->isNull())
3676
3677
3678
3679
3689 if (m_cursor->isNull()) {
3690 if (
const QWindow *p = window()->parent()) {
3691 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p))
3694 SetCursor(defaultCursor(window())->handle());
3697 SetCursor(m_cursor->handle());
3705 bool changed = c->handle() != m_cursor->handle();
3713 const bool apply = applyNewCursor(window());
3714 qCDebug(lcQpaWindow) << window() <<
__FUNCTION__
3715 << c->handle() <<
" doApply=" << apply;
3738 UINT timeOutMs = GetCaretBlinkTime();
3739 if (!timeOutMs || timeOutMs == INFINITE)
3743 info.cbSize =
sizeof(info);
3744 info.hwnd = m_data.hwnd;
3745 info.dwFlags = FLASHW_TRAY;
3746 info.dwTimeout = timeOutMs;
3747 info.uCount = durationMs == 0 ? 10 : UINT(durationMs) / timeOutMs;
3748 FlashWindowEx(&info);
3754 info.cbSize =
sizeof(info);
3755 info.hwnd = m_data.hwnd;
3756 info.dwFlags = FLASHW_STOP;
3759 FlashWindowEx(&info);
3764 return (style() & WS_DISABLED) == 0;
3769 const unsigned oldStyle =
style();
3770 unsigned newStyle = oldStyle;
3772 newStyle &= ~WS_DISABLED;
3774 newStyle |= WS_DISABLED;
3776 if (newStyle != oldStyle)
3782 if (!icon.isNull()) {
3784 const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)), 1);
3786 return qt_pixmapToWinHICON(pm);
3796 m_iconSmall = createHIcon(icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
3797 m_iconBig = createHIcon(icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
3800 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3801 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconBig));
3803 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3804 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconSmall));
3811 return window()->isTopLevel() && !m_data.embedded;
3821 const BOOL darkBorder = d ? TRUE : FALSE;
3826 qCWarning(lcQpaWindow,
"%s: Unable to set %s window border.",
__FUNCTION__, d ?
"dark" :
"light");
3833 d = d && shouldApplyDarkFrame(window());
3835 setDarkBorderToWindow(m_data.hwnd, d);
3840 return m_menuBar.data();
3850 if (m_data.flags & Qt::FramelessWindowHint)
3852 return m_data.customMargins;
3856
3857
3858
3859
3860
3861
3862
3863
3867 if (m_data.flags & Qt::FramelessWindowHint) {
3868 qCWarning(lcQpaWindow) <<
"You should not set custom margins for a frameless window.";
3871 if (newCustomMargins != m_data.customMargins) {
3872 const QMargins oldCustomMargins = m_data.customMargins;
3873 m_data.customMargins = newCustomMargins;
3875 const QRect currentFrameGeometry = frameGeometry_sys();
3876 const QPoint topLeft = currentFrameGeometry.topLeft();
3877 QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
3878 newFrame.moveTo(topLeft);
3879 qCDebug(lcQpaWindow) <<
__FUNCTION__ << oldCustomMargins <<
"->" << newCustomMargins
3880 << currentFrameGeometry <<
"->" << newFrame;
3881 SetWindowPos(m_data.hwnd,
nullptr, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
3887#if QT_CONFIG(vulkan)
3888 Q_UNUSED(nativeConfig);
3890 if (window()->surfaceType() == QSurface::VulkanSurface) {
3892 QVulkanInstance *inst = window()->vulkanInstance();
3894 m_vkSurface =
static_cast<QWindowsVulkanInstance *>(inst->handle())->createSurface(handle());
3896 qWarning(
"Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
3900 return &m_vkSurface;
3902#elif defined(QT_NO_OPENGL)
3904 Q_UNUSED(nativeConfig);
3909 if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
3910 m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig, err);
3921#if QT_CONFIG(vulkan)
3923 QVulkanInstance *inst = window()->vulkanInstance();
3925 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
3926 m_vkSurface = VK_NULL_HANDLE;
3933 m_surface =
nullptr;
3946 const auto currentTouchTypes = touchWindowTouchTypes_sys();
3947 if (currentTouchTypes.has_value() && currentTouchTypes.value() == touchTypes)
3951 ULONG touchFlags = 0;
3952 if (touchTypes.testFlag(TouchWindowTouchType::FineTouch))
3953 touchFlags |= TWF_FINETOUCH;
3954 if (touchTypes.testFlag(TouchWindowTouchType::WantPalmTouch))
3955 touchFlags |= TWF_WANTPALM;
3956 if (RegisterTouchWindow(m_data.hwnd, touchFlags))
3959 qErrnoWarning(
"RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
3964 if (QPlatformWindow *handle = window->handle())
3965 static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border);
3972 m_borderInFullScreenDefault = border;
3989 if (m_windowState == Qt::WindowFullScreen) {
3990 LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE);
3994 style &= ~WS_BORDER;
3995 SetWindowLongPtr(handle(), GWL_STYLE, style);
4001 return QPlatformWindow::formatWindowTitle(title, QStringLiteral(
" - "));
4011 QWindow *w = window();
4012 QDxgiVSyncService *vs = QDxgiVSyncService::instance();
4013 if (vs->supportsWindow(w)) {
4014 if (m_vsyncServiceCallbackId == 0) {
4015 m_vsyncServiceCallbackId = vs->registerCallback([
this, w](
const QDxgiVSyncService::CallbackWindowList &windowList, qint64) {
4016 if (windowList.contains(w)) {
4021 if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) {
4022 QMetaObject::invokeMethod(w, [w] {
4023 auto *self =
static_cast<QWindowsWindow *>(w->handle());
4026 self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready);
4027 self->deliverUpdateRequest();
4034 m_vsyncUpdatePending.testAndSetRelease(UpdateState::Ready, UpdateState::Requested);
4036 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 initialize() override
Called as part of QWindow::create(), after constructing the window.
void handleDpiChangedAfterParent(HWND hwnd)
void checkForScreenChanged(ScreenChangeMode mode=FromGeometryChange)
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 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)