5#include <QtCore/qt_windows.h>
6#include <QtGui/qstylehints.h>
11#if QT_CONFIG(draganddrop)
12# include "qwindowsdrag.h"
18#if QT_CONFIG(dynamicgl)
19# include "qwindowsglcontext.h"
25# include "qwindowscursor.h"
30#include <QtGui/qguiapplication.h>
31#include <QtGui/qscreen.h>
32#include <QtGui/qwindow.h>
33#include <QtGui/qregion.h>
34#include <QtGui/qopenglcontext.h>
35#include <QtGui/qpainterpath.h>
36#include <QtGui/private/qwindowsthemecache_p.h>
37#include <private/qwindow_p.h>
38#include <private/qguiapplication_p.h>
39#include <private/qhighdpiscaling_p.h>
40#include <qpa/qwindowsysteminterface.h>
41#include <private/qsystemlibrary_p.h>
42#include <private/qwinregistry_p.h>
45#include <QtCore/qdebug.h>
46#include <QtCore/qlibraryinfo.h>
47#include <QtCore/qoperatingsystemversion.h>
52#include "qwindowsvulkaninstance.h"
55#include <shellscalingapi.h>
57#include <private/qdxgivsyncservice_p.h>
60# define GWL_HWNDPARENT (-8
)
65using namespace Qt::StringLiterals;
67using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>;
74Q_GUI_EXPORT HICON qt_pixmapToWinHICON(
const QPixmap &);
79 rc += QByteArray::number(qulonglong(style), 16);
84 if (style & WS_OVERLAPPED)
85 rc +=
" WS_OVERLAPPED";
86 if (style & WS_CLIPSIBLINGS)
87 rc +=
" WS_CLIPSIBLINGS";
88 if (style & WS_CLIPCHILDREN)
89 rc +=
" WS_CLIPCHILDREN";
90 if (style & WS_THICKFRAME)
91 rc +=
" WS_THICKFRAME";
92 if (style & WS_DLGFRAME)
94 if (style & WS_SYSMENU)
96 if (style & WS_MINIMIZEBOX)
97 rc +=
" WS_MINIMIZEBOX";
98 if (style & WS_MAXIMIZEBOX)
99 rc +=
" WS_MAXIMIZEBOX";
100 if (style & WS_BORDER)
102 if (style & WS_CAPTION)
104 if (style & WS_CHILDWINDOW)
105 rc +=
" WS_CHILDWINDOW";
106 if (style & WS_DISABLED)
107 rc +=
" WS_DISABLED";
108 if (style & WS_GROUP)
110 if (style & WS_HSCROLL)
112 if (style & WS_ICONIC)
114 if (style & WS_MAXIMIZE)
115 rc +=
" WS_MAXIMIZE";
116 if (style & WS_MINIMIZE)
117 rc +=
" WS_MINIMIZE";
118 if (style & WS_SIZEBOX)
120 if (style & WS_TABSTOP)
122 if (style & WS_TILED)
124 if (style & WS_VISIBLE)
126 if (style & WS_VSCROLL)
133 QByteArray rc =
"0x";
134 rc += QByteArray::number(qulonglong(exStyle), 16);
135 if (exStyle & WS_EX_TOOLWINDOW)
136 rc +=
" WS_EX_TOOLWINDOW";
137 if (exStyle & WS_EX_CONTEXTHELP)
138 rc +=
" WS_EX_CONTEXTHELP";
139 if (exStyle & WS_EX_LAYERED)
140 rc +=
" WS_EX_LAYERED";
141 if (exStyle & WS_EX_DLGMODALFRAME)
142 rc +=
" WS_EX_DLGMODALFRAME";
143 if (exStyle & WS_EX_LAYOUTRTL)
144 rc +=
" WS_EX_LAYOUTRTL";
145 if (exStyle & WS_EX_NOINHERITLAYOUT)
146 rc +=
" WS_EX_NOINHERITLAYOUT";
147 if (exStyle & WS_EX_ACCEPTFILES)
148 rc +=
" WS_EX_ACCEPTFILES";
149 if (exStyle & WS_EX_APPWINDOW)
150 rc +=
" WS_EX_APPWINDOW";
151 if (exStyle & WS_EX_CLIENTEDGE)
152 rc +=
" WS_EX_CLIENTEDGE";
153 if (exStyle & WS_EX_COMPOSITED)
154 rc +=
" WS_EX_COMPOSITED";
155 if (exStyle & WS_EX_CONTROLPARENT)
156 rc +=
" WS_EX_CONTROLPARENT";
157 if (exStyle & WS_EX_LEFT)
159 if (exStyle & WS_EX_LEFTSCROLLBAR)
160 rc +=
" WS_EX_LEFTSCROLLBAR";
161 if (exStyle & WS_EX_LTRREADING)
162 rc +=
" WS_EX_LTRREADING";
163 if (exStyle & WS_EX_MDICHILD)
164 rc +=
" WS_EX_MDICHILD";
165 if (exStyle & WS_EX_NOACTIVATE)
166 rc +=
" WS_EX_NOACTIVATE";
167 if (exStyle & WS_EX_NOPARENTNOTIFY)
168 rc +=
" WS_EX_NOPARENTNOTIFY";
169 if (exStyle & WS_EX_NOREDIRECTIONBITMAP)
170 rc +=
" WS_EX_NOREDIRECTIONBITMAP";
171 if (exStyle & WS_EX_RIGHT)
172 rc +=
" WS_EX_RIGHT";
173 if (exStyle & WS_EX_RIGHTSCROLLBAR)
174 rc +=
" WS_EX_RIGHTSCROLLBAR";
175 if (exStyle & WS_EX_RTLREADING)
176 rc +=
" WS_EX_RTLREADING";
177 if (exStyle & WS_EX_STATICEDGE)
178 rc +=
" WS_EX_STATICEDGE";
179 if (exStyle & WS_EX_TOPMOST)
180 rc +=
" WS_EX_TOPMOST";
181 if (exStyle & WS_EX_TRANSPARENT)
182 rc +=
" WS_EX_TRANSPARENT";
183 if (exStyle & WS_EX_WINDOWEDGE)
184 rc +=
" WS_EX_WINDOWEDGE";
190 QByteArray rc =
"0x";
191 rc += QByteArray::number(flags, 16);
192 if (flags & SWP_FRAMECHANGED)
193 rc +=
" SWP_FRAMECHANGED";
194 if (flags & SWP_HIDEWINDOW)
195 rc +=
" SWP_HIDEWINDOW";
196 if (flags & SWP_NOACTIVATE)
197 rc +=
" SWP_NOACTIVATE";
198 if (flags & SWP_NOCOPYBITS)
199 rc +=
" SWP_NOCOPYBITS";
200 if (flags & SWP_NOMOVE)
202 if (flags & SWP_NOOWNERZORDER)
203 rc +=
" SWP_NOOWNERZORDER";
204 if (flags & SWP_NOREDRAW)
205 rc +=
" SWP_NOREDRAW";
206 if (flags & SWP_NOSENDCHANGING)
207 rc +=
" SWP_NOSENDCHANGING";
208 if (flags & SWP_NOSIZE)
210 if (flags & SWP_NOZORDER)
211 rc +=
" SWP_NOZORDER";
212 if (flags & SWP_SHOWWINDOW)
213 rc +=
" SWP_SHOWWINDOW";
214 if (flags & SWP_ASYNCWINDOWPOS)
215 rc +=
" SWP_ASYNCWINDOWPOS";
216 if (flags & SWP_DEFERERASE)
217 rc +=
" SWP_DEFERERASE";
218 if (flags & SWP_DRAWFRAME)
219 rc +=
" SWP_DRAWFRAME";
220 if (flags & SWP_NOREPOSITION)
221 rc +=
" SWP_NOREPOSITION";
227 QByteArray rc =
"0x";
228 rc += QByteArray::number(flags, 16);
229 if (flags & WPF_SETMINPOSITION)
230 rc +=
" WPF_SETMINPOSITION";
231 if (flags & WPF_RESTORETOMAXIMIZED)
232 rc +=
" WPF_RESTORETOMAXIMIZED";
233 if (flags & WPF_ASYNCWINDOWPLACEMENT)
234 rc +=
" WPF_ASYNCWINDOWPLACEMENT";
241 rc += QByteArray::number(cmd);
244 if (cmd == SW_SHOWNORMAL)
245 rc +=
" SW_SHOWNORMAL";
246 if (cmd == SW_NORMAL)
248 if (cmd == SW_SHOWMINIMIZED)
249 rc +=
" SW_SHOWMINIMIZED";
250 if (cmd == SW_SHOWMAXIMIZED)
251 rc +=
" SW_SHOWMAXIMIZED";
252 if (cmd == SW_MAXIMIZE)
253 rc +=
" SW_MAXIMIZE";
254 if (cmd == SW_SHOWNOACTIVATE)
255 rc +=
" SW_SHOWNOACTIVATE";
258 if (cmd == SW_MINIMIZE)
259 rc +=
" SW_MINIMIZE";
260 if (cmd == SW_SHOWMINNOACTIVE)
261 rc +=
" SW_SHOWMINNOACTIVE";
262 if (cmd == SW_SHOWNA)
264 if (cmd == SW_RESTORE)
266 if (cmd == SW_SHOWDEFAULT)
267 rc +=
" SW_SHOWDEFAULT";
268 if (cmd == SW_FORCEMINIMIZE)
269 rc +=
" SW_FORCEMINIMIZE";
275 return QSize(rect.right -rect.left, rect.bottom - rect.top);
280 return QRect(
QPoint(rect.left, rect.top), qSizeOfRect(rect));
285 const int x = rect.left();
286 const int y = rect.top();
287 RECT result = { x, y, x + rect.width(), y + rect.height() };
291#ifndef QT_NO_DEBUG_STREAM
292QDebug operator<<(QDebug d,
const RECT &r)
294 QDebugStateSaver saver(d);
296 d <<
"RECT(left=" << r.left <<
", top=" << r.top
297 <<
", right=" << r.right <<
", bottom=" << r.bottom
298 <<
" (" << r.right - r.left <<
'x' << r.bottom - r.top <<
"))";
302QDebug operator<<(QDebug d,
const POINT &p)
304 QDebugStateSaver saver(d);
306 d <<
"POINT(x=" << p.x <<
", y=" << p.y <<
')';
310QDebug operator<<(QDebug d,
const WINDOWPOS &wp)
312 QDebugStateSaver saver(d);
315 d <<
"WINDOWPOS(flags=" << debugWinSwpPos(wp.flags) <<
", hwnd="
316 << wp.hwnd <<
", hwndInsertAfter=" << wp.hwndInsertAfter <<
", x=" << wp.x
317 <<
", y=" << wp.y <<
", cx=" << wp.cx <<
", cy=" << wp.cy <<
')';
321QDebug operator<<(QDebug d,
const NCCALCSIZE_PARAMS &p)
323 QDebugStateSaver saver(d);
325 d <<
"NCCALCSIZE_PARAMS(rgrc=[" << p.rgrc[0] <<
", " << p.rgrc[1] <<
", "
326 << p.rgrc[2] <<
"], lppos=" << *p.lppos <<
')';
330QDebug operator<<(QDebug d,
const MINMAXINFO &i)
332 QDebugStateSaver saver(d);
334 d <<
"MINMAXINFO(maxSize=" << i.ptMaxSize <<
", "
335 <<
"maxpos=" << i.ptMaxPosition <<
", "
336 <<
"maxtrack=" << i.ptMaxTrackSize <<
", "
337 <<
"mintrack=" << i.ptMinTrackSize <<
')';
341QDebug operator<<(QDebug d,
const WINDOWPLACEMENT &wp)
343 QDebugStateSaver saver(d);
346 d <<
"WINDOWPLACEMENT(flags=" << debugWindowPlacementFlags(wp.flags) <<
", showCmd="
347 << debugShowWindowCmd(wp.showCmd) <<
", ptMinPosition=" << wp.ptMinPosition
348 <<
", ptMaxPosition=" << wp.ptMaxPosition <<
", rcNormalPosition="
349 << wp.rcNormalPosition <<
')';
353QDebug operator<<(QDebug d,
const GUID &guid)
355 QDebugStateSaver saver(d);
357 d <<
'{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(u'0')
358 << qSetFieldWidth(8) << guid.Data1
359 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
360 << guid.Data2 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
361 << guid.Data3 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
362 << qSetFieldWidth(2) << guid.Data4[0] << guid.Data4[1]
363 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(2);
364 for (
int i = 2; i < 8; ++i)
366 d << qSetFieldWidth(0) <<
'}';
373 d << r.width() <<
'x' << r.height() << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
378 d << m.left() <<
", " << m.top() <<
", " << m.right() <<
", " << m.bottom();
385 if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
388 const QWindowsScreen *screen = screenManager.screens().size() == 1
389 ? screenManager.screens().constFirst() : screenManager
.screenAtDp(point
);
391 return screen->availableGeometry().topLeft() - screen->geometry().topLeft();
399 RECT rect = { 0, 0, 0, 0 };
401 WINDOWPLACEMENT windowPlacement;
402 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
403 GetWindowPlacement(hwnd, &windowPlacement);
404 if (windowPlacement.showCmd == SW_SHOWMINIMIZED) {
405 const QRect result = qrectFromRECT(windowPlacement.rcNormalPosition);
406 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
409 GetWindowRect(hwnd, &rect);
410 const HWND parent = GetParent(hwnd);
411 if (parent && !topLevel) {
412 const int width = rect.right - rect.left;
413 const int height = rect.bottom - rect.top;
414 POINT leftTop = { rect.left, rect.top };
415 screenToClient(parent, &leftTop);
416 rect.left = leftTop.x;
417 rect.top = leftTop.y;
418 rect.right = leftTop.x + width;
419 rect.bottom = leftTop.y + height;
421 return qrectFromRECT(rect);
427 if (!IsWindowVisible(hwnd))
428 return QWindow::Hidden;
429 WINDOWPLACEMENT windowPlacement;
430 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
431 if (GetWindowPlacement(hwnd, &windowPlacement)) {
432 switch (windowPlacement.showCmd) {
433 case SW_SHOWMINIMIZED:
435 case SW_FORCEMINIMIZE:
436 return QWindow::Minimized;
437 case SW_SHOWMAXIMIZED:
438 return QWindow::Maximized;
443 return QWindow::Windowed;
448 switch (w->surfaceType()) {
449 case QSurface::OpenGLSurface:
450 case QSurface::VulkanSurface:
451 case QSurface::Direct3DSurface:
460 DWM_BLURBEHIND blurBehind = {0, 0,
nullptr, 0};
462 blurBehind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
463 blurBehind.fEnable = TRUE;
464 blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
466 const bool result = DwmEnableBlurBehindWindow(hwnd, &blurBehind) == S_OK;
468 if (blurBehind.hRgnBlur)
469 DeleteObject(blurBehind.hRgnBlur);
477 if ((flags & Qt::MSWindowsFixedSizeDialogHint) || !(flags & Qt::WindowMaximizeButtonHint))
481 return (flags & Qt::CustomizeWindowHint) ||
482 w->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX);
487 const LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
488 return (style & WS_CHILD) || (flags & Qt::FramelessWindowHint);
494bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha, qreal opacity)
496 const LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
498 const bool needsLayered = (flags & Qt::WindowTransparentForInput)
499 || (hasAlpha && hasNoNativeFrame(hwnd, flags)) || opacity < 1.0;
500 const bool isLayered = (exStyle & WS_EX_LAYERED);
501 if (needsLayered != isLayered) {
503 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
505 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
511static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha,
bool accelerated, qreal level)
513 if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) {
514 const BYTE alpha = BYTE(qRound(255.0 * level));
515 if (hasAlpha && !accelerated && QWindowsWindow::hasNoNativeFrame(hwnd, flags)) {
517 BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
518 UpdateLayeredWindow(hwnd,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, 0, &blend, ULW_ALPHA);
520 SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
522 }
else if (IsWindowVisible(hwnd)) {
523 InvalidateRect(hwnd,
nullptr, TRUE);
532 return GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
533 + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
537
538
539
543 POINT pt = {screenPoint.x(), screenPoint.y()};
544 if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
547 if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
548 const int gap = getResizeBorderThickness(dpiX);
549 return QMargins(gap, 0, gap, gap);
557 const UINT dpi = GetDpiForWindow(hwnd);
558 const int gap = getResizeBorderThickness(dpi);
559 return QMargins(gap, 0, gap, gap);
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
595 void fromWindow(
const QWindow *w,
const Qt::WindowFlags flags,
unsigned creationFlags = 0);
598 void initialize(
const QWindow *w, HWND h,
bool frameChange, qreal opacityLevel)
const;
615 QDebugStateSaver saver(debug);
618 debug <<
"WindowCreationData: " << d.flags
621 debug <<
" parent=" << d.parentHandle;
622 debug <<
" popup=" << d.popup <<
" dialog=" << d.dialog
623 <<
" embedded=" << d.embedded <<
" tool=" << d.tool
624 <<
"\n style=" << debugWinStyle(d.style);
626 debug <<
"\n exStyle=" << debugWinExStyle(d.exStyle);
634 flags &= ~Qt::WindowFullscreenButtonHint;
639 constexpr Qt::WindowFlags clientAreaHints =
640 Qt::ExpandedClientAreaHint | Qt::NoTitleBarBackgroundHint;
641 switch (flags & ~clientAreaHints) {
643 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint
644 |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
648 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
653 if ((flags & Qt::WindowType_Mask) == Qt::SplashScreen)
654 flags |= Qt::FramelessWindowHint;
659 const auto getDeviceName = [](
const QScreen *screen) -> QString {
660 if (
const auto s =
static_cast<
const QWindowsScreen *>(screen->handle()))
661 return s->data().deviceName;
664 QScreen *winScreen = w ? w->screen() : QGuiApplication::primaryScreen();
665 if (winScreen && getDeviceName(winScreen) != name) {
666 const auto screens = winScreen->virtualSiblings();
667 for (QScreen *screen : screens) {
668 if (getDeviceName(screen) == name)
675static QPoint calcPosition(
const QWindow *w,
const QWindowCreationContextPtr &context,
const QMargins &invMargins)
677 const QPoint orgPos(context->frameX - invMargins.left(), context->frameY - invMargins.top());
679 if (!w || w->type() != Qt::Window)
683 const QScreen *screenForGL = QWindowsWindow::forcedScreenForGLWindow(w);
687 const QPoint posFrame(context->frameX, context->frameY);
688 const QMargins margins = context->margins;
689 const QRect scrGeo = screenForGL->handle()->availableGeometry();
692 if (scrGeo.contains(orgPos))
697 if (scrGeo.contains(posFrame))
701 const auto screens = screenForGL->virtualSiblings();
702 const QScreen *orgScreen =
nullptr;
703 for (QScreen *screen : screens) {
704 if (screen->handle()->availableGeometry().contains(posFrame)) {
709 const QPoint ctPos = QPoint(qMax(scrGeo.left(), scrGeo.center().x()
710 + (margins.right() - margins.left() - context->frameWidth)/2),
711 qMax(scrGeo.top(), scrGeo.center().y()
712 + (margins.bottom() - margins.top() - context->frameHeight)/2));
718 const QRect orgGeo = orgScreen->handle()->availableGeometry();
719 const QRect orgFrame(
QPoint(context->frameX, context->frameY),
720 QSize(context->frameWidth, context->frameHeight));
723 if (orgGeo.center() == (orgFrame - margins).center())
727 const QPoint newPos(scrGeo.left() + ((posFrame.x() - orgGeo.left()) * scrGeo.width()) / orgGeo.width(),
728 scrGeo.top() + ((posFrame.y() - orgGeo.top()) * scrGeo.height()) / orgGeo.height());
729 const QPoint newPosNoMargin(newPos.x() - invMargins.left(), newPos.y() - invMargins.top());
731 return scrGeo.contains(newPosNoMargin) ? newPosNoMargin : newPos;
735 unsigned creationFlags)
742 QVariant prop = w->property(QWindowsWindow::embeddedNativeParentHandleProperty);
743 if (prop.isValid()) {
745 parentHandle =
reinterpret_cast<HWND>(prop.value<WId>());
759 fixTopLevelWindowFlags(flags);
761 type =
static_cast<Qt::WindowType>(
int(flags) & Qt::WindowType_Mask);
777 if ((flags & Qt::MSWindowsFixedSizeDialogHint))
786 if (QGuiApplication::layoutDirection() == Qt::RightToLeft
787 && (QWindowsIntegration::instance()->options() & QWindowsIntegration::RtlEnabled) != 0) {
788 exStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
793 flags |= Qt::WindowStaysOnTopHint;
795 if (
const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
796 parentHandle = QWindowsWindow::handleOf(parentWindow);
799 if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
802 if (flags & Qt::FramelessWindowHint)
804 else if (flags & Qt::WindowTitleHint)
805 style = WS_OVERLAPPED;
812 style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
814 if (flags & Qt::WindowDoesNotAcceptFocus)
815 exStyle |= WS_EX_NOACTIVATE;
818 if ((type == Qt::Window || dialog || tool)) {
819 if (!(flags & Qt::FramelessWindowHint)) {
821 if (flags & Qt::MSWindowsFixedSizeDialogHint) {
822 style |= WS_DLGFRAME;
824 style |= WS_THICKFRAME;
826 if (flags & Qt::WindowTitleHint)
829 if (flags & Qt::WindowSystemMenuHint)
831 else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
832 style |= WS_SYSMENU | WS_BORDER;
833 exStyle |= WS_EX_DLGMODALFRAME;
835 const bool showMinimizeButton = flags & Qt::WindowMinimizeButtonHint;
836 if (showMinimizeButton)
837 style |= WS_MINIMIZEBOX;
838 const bool showMaximizeButton = shouldShowMaximizeButton(w, flags);
839 if (showMaximizeButton)
840 style |= WS_MAXIMIZEBOX;
841 if (showMinimizeButton || showMaximizeButton)
844 exStyle |= WS_EX_TOOLWINDOW;
845 if ((flags & Qt::WindowContextHelpButtonHint) && !showMinimizeButton
846 && !showMaximizeButton)
847 exStyle |= WS_EX_CONTEXTHELP;
849 exStyle |= WS_EX_TOOLWINDOW;
854 if (flagsIn & Qt::WindowTransparentForInput)
855 exStyle |= WS_EX_TRANSPARENT;
858 if (qEnvironmentVariableIntValue(
"QT_QPA_DISABLE_REDIRECTION_SURFACE"))
859 exStyle |= WS_EX_NOREDIRECTIONBITMAP;
865 if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
874 auto *dWindow = QWindowPrivate::get(
const_cast<QWindow*>(w));
875 const QPalette windowPal = dWindow->windowPalette();
876 return windowPal.color(QPalette::WindowText).lightness()
877 > windowPal.color(QPalette::Window).lightness();
883 return getResizeBorderThickness(dpi) +
884 ::GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
891 result.flags = flags;
893 const auto appinst =
reinterpret_cast<HINSTANCE>(GetModuleHandle(
nullptr));
898 windowTitlebarDescription.name =
"_q_titlebar"_L1;
899 windowTitlebarDescription.style = CS_VREDRAW | CS_HREDRAW;
903 const QScreen *screen{};
904 const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
905 defaultWindowWidth, defaultWindowHeight,
908 if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
909 title =
topLevel ? qAppName() : w->objectName();
911 const auto *titleUtf16 =
reinterpret_cast<
const wchar_t *>(title.utf16());
912 const auto *classNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowClassName.utf16());
913 const auto *classTitleBarNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowTitlebarName.utf16());
918 rect, data.customMargins,
922 const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME))
923 && !(result.flags & Qt::FramelessWindowHint);
924 QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w)
925 ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();
927 qCDebug(lcQpaWindow).nospace()
928 <<
"CreateWindowEx: " << w <<
" class=" << windowClassName <<
" title=" << title
929 <<
'\n' << *
this <<
"\nrequested: " << rect <<
": "
930 << context->frameWidth <<
'x' << context->frameHeight
931 <<
'+' << context->frameX <<
'+' << context->frameY
932 <<
" custom margins: " << context->customMargins
933 <<
" invisible margins: " << invMargins;
936 QPoint pos = calcPosition(w, context, invMargins);
939 int mirrorParentWidth = 0;
940 if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) {
942 GetClientRect(parentHandle, &rect);
943 mirrorParentWidth = rect.right;
945 if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT)
946 pos.setX(mirrorParentWidth - context->frameWidth - pos.x());
948 result.hwnd = CreateWindowEx(
exStyle, classNameUtf16, titleUtf16,
951 context->frameWidth, context->frameHeight,
952 parentHandle,
nullptr, appinst,
nullptr);
954 const UINT dpi = ::GetDpiForWindow(result.hwnd);
955 const int titleBarHeight = getTitleBarHeight_sys(dpi);
956 result.hwndTitlebar = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,
957 classTitleBarNameUtf16, classTitleBarNameUtf16,
959 context->frameWidth, titleBarHeight,
960 nullptr,
nullptr, appinst,
nullptr);
962 qCDebug(lcQpaWindow).nospace()
963 <<
"CreateWindowEx: returns " << w <<
' ' << result.hwnd <<
" obtained geometry: "
964 << context->obtainedPos << context->obtainedSize <<
' ' << context->margins;
967 qErrnoWarning(
"%s: CreateWindowEx failed",
__FUNCTION__);
971 if (QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark && shouldApplyDarkFrame(w))
972 QWindowsWindow::setDarkBorderToWindow(result.hwnd,
true);
974 if (mirrorParentWidth != 0) {
975 context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
976 - context->obtainedPos.x());
979 QRect obtainedGeometry(context->obtainedPos, context->obtainedSize);
981 result.geometry = obtainedGeometry;
982 result.restoreGeometry = frameGeometry(result.hwnd, topLevel);
983 result.fullFrameMargins = context->margins;
986 result.customMargins = context->customMargins;
994 const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
995 const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
997 const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
998 if (oldStyle != newStyle)
999 SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
1000 const LONG_PTR newExStyle =
exStyle;
1001 if (newExStyle != oldExStyle)
1002 SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
1003 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << hwnd << *
this
1004 <<
"\n Style from " << debugWinStyle(DWORD(oldStyle)) <<
"\n to "
1005 << debugWinStyle(DWORD(newStyle)) <<
"\n ExStyle from "
1006 << debugWinExStyle(DWORD(oldExStyle)) <<
" to "
1007 << debugWinExStyle(DWORD(newExStyle));
1014 UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER;
1016 swpFlags |= SWP_FRAMECHANGED;
1018 swpFlags |= SWP_NOACTIVATE;
1019 if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
1020 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, swpFlags);
1021 if (flags & Qt::WindowStaysOnBottomHint)
1022 qWarning(
"QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time");
1023 }
else if (flags & Qt::WindowStaysOnBottomHint) {
1024 SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, swpFlags);
1025 }
else if (frameChange) {
1026 SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, swpFlags);
1028 if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
1029 HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
1030 if (flags & Qt::WindowCloseButtonHint)
1031 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
1033 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
1035 if (flags & Qt::ExpandedClientAreaHint) {
1036 MARGINS margins = { -1, -1, -1, -1 };
1037 DwmExtendFrameIntoClientArea(hwnd, &margins);
1039 MARGINS margins = { 0, 0, 0, 0 };
1040 DwmExtendFrameIntoClientArea(hwnd, &margins);
1043 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
1047 const bool hasAlpha = w->format().hasAlpha();
1048 if (isAccelerated && hasAlpha)
1049 applyBlurBehindWindow(hwnd);
1050 setWindowOpacity(hwnd, flags, hasAlpha, isAccelerated, opacityLevel);
1057 if (QHighDpiScaling::isActive()) {
1058 const qreal factor = QHighDpiScaling::factor(s);
1059 if (!qFuzzyCompare(factor, qreal(1))) {
1060 if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
1061 dip.setWidth(qRound(qreal(dip.width()) * factor));
1062 if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX)
1063 dip.setHeight(qRound(qreal(dip.height()) * factor));
1073 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1080 DWORD style = hwnd !=
nullptr ? DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)) : 0;
1081 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1085
1086
1087
1088
1089
1090
1091
1092
1096 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1098 RECT rect = {0,0,0,0};
1099 style &= ~DWORD(WS_OVERLAPPED);
1100 if (AdjustWindowRectEx(&rect, style, FALSE, exStyle) == FALSE)
1101 qErrnoWarning(
"%s: AdjustWindowRectEx failed",
__FUNCTION__);
1102 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1103 qAbs(rect.right), qAbs(rect.bottom));
1104 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1105 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1106 <<
' ' << rect <<
' ' << result;
1112 return frameOnPrimaryScreen(w, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1113 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1118 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1120 RECT rect = {0,0,0,0};
1121 style &= ~DWORD(WS_OVERLAPPED);
1122 if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
unsigned(qRound(dpi))) == FALSE) {
1123 qErrnoWarning(
"%s: AdjustWindowRectExForDpi failed",
__FUNCTION__);
1125 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1126 qAbs(rect.right), qAbs(rect.bottom));
1127 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1128 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1130 <<
' ' << rect <<
' ' << result;
1136 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1138 if (QWindowsScreenManager::isSingleScreen())
1139 return frameOnPrimaryScreen(w, style, exStyle);
1141 auto screen = screenManager.screenForHwnd(hwnd);
1143 screen = screenManager.screens().value(0);
1144 const auto dpi = screen ? screen->logicalDpi().first : qreal(96);
1145 return frame(w, style, exStyle, dpi);
1150 return frame(w, hwnd, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1151 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1156 DWORD style, DWORD exStyle)
1158 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1161 || !QWindowsContext::shouldHaveNonClientDpiScaling(w)) {
1162 return frameOnPrimaryScreen(w, style, exStyle);
1168 screen = screenManager.screens().value(0);
1170 dpi = screen->logicalDpi().first;
1171 return QWindowsGeometryHint::frame(w, style, exStyle, dpi);
1174bool QWindowsGeometryHint::handleCalculateSize(
const QWindow *window,
const QMargins &customMargins,
const MSG &msg, LRESULT *result)
1177 if (msg.wParam && window->flags() & Qt::FramelessWindowHint) {
1181 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window);
1183 const bool clientAreaExpanded = platformWindow !=
nullptr ? platformWindow->isClientAreaExpanded() : window->flags() & Qt::ExpandedClientAreaHint;
1185 if (msg.wParam && clientAreaExpanded) {
1187 const bool maximized = IsZoomed(msg.hwnd) && window->visibility() != QWindow::FullScreen;
1188 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1189 RECT *clientArea = &ncp->rgrc[0];
1190 const int border = getResizeBorderThickness(96);
1192 clientArea->top += border;
1193 clientArea->bottom -= border;
1194 clientArea->left += border;
1195 clientArea->right -= border;
1200 if (!msg.wParam || customMargins.isNull())
1202 *result = DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1203 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1204 const RECT oldClientArea = ncp->rgrc[0];
1205 ncp->rgrc[0].left += customMargins.left();
1206 ncp->rgrc[0].top += customMargins.top();
1207 ncp->rgrc[0].right -= customMargins.right();
1208 ncp->rgrc[0].bottom -= customMargins.bottom();
1210 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << oldClientArea <<
'+' << customMargins <<
"-->"
1211 << ncp->rgrc[0] <<
' ' << ncp->rgrc[1] <<
' ' << ncp->rgrc[2]
1212 <<
' ' << ncp->lppos->cx <<
',' << ncp->lppos->cy;
1217 const QMargins &margins,
1218 QSize *minimumSize, QSize *maximumSize)
1220 *minimumSize = toNativeSizeConstrained(w->minimumSize(), screen);
1221 *maximumSize = toNativeSizeConstrained(w->maximumSize(), screen);
1223 const int maximumWidth = qMax(maximumSize->width(), minimumSize->width());
1224 const int maximumHeight = qMax(maximumSize->height(), minimumSize->height());
1225 const int frameWidth = margins.left() + margins.right();
1226 const int frameHeight = margins.top() + margins.bottom();
1228 if (minimumSize->width() > 0)
1229 minimumSize->rwidth() += frameWidth;
1230 if (minimumSize->height() > 0)
1231 minimumSize->rheight() += frameHeight;
1232 if (maximumWidth < QWINDOWSIZE_MAX)
1233 maximumSize->setWidth(maximumWidth + frameWidth);
1234 if (maximumHeight < QWINDOWSIZE_MAX)
1235 maximumSize->setHeight(maximumHeight + frameHeight);
1239 const QScreen *screen,
1240 const QMargins &margins,
1245 frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize);
1246 qCDebug(lcQpaWindow).nospace() <<
'>' <<
__FUNCTION__ <<
'<' <<
" min="
1247 << minimumSize.width() <<
',' << minimumSize.height()
1248 <<
" max=" << maximumSize.width() <<
',' << maximumSize.height()
1249 <<
" margins=" << margins
1252 if (minimumSize.width() > 0)
1253 mmi->ptMinTrackSize.x = minimumSize.width();
1254 if (minimumSize.height() > 0)
1255 mmi->ptMinTrackSize.y = minimumSize.height();
1257 if (maximumSize.width() < QWINDOWSIZE_MAX)
1258 mmi->ptMaxTrackSize.x = maximumSize.width();
1259 if (maximumSize.height() < QWINDOWSIZE_MAX)
1260 mmi->ptMaxTrackSize.y = maximumSize.height();
1261 qCDebug(lcQpaWindow).nospace() <<
'<' <<
__FUNCTION__ <<
" out " << *mmi;
1265 const QMargins &margins,
1268 applyToMinMaxInfo(w, w->screen(), margins, mmi);
1273 return qt_window_private(
const_cast<QWindow *>(w))->positionPolicy
1274 == QWindowPrivate::WindowFrameInclusive;
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1296 return (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0;
1302 if (QPlatformWindow *pw = w->handle())
1303 return static_cast<QWindowsBaseWindow *>(pw);
1311 return bw ? bw->handle() : HWND(
nullptr);
1316 const HWND parent = parentHwnd();
1317 return !parent || parent == GetDesktopWindow();
1322 return frameGeometry(handle(), isTopLevel());
1327 return frameGeometry_sys().marginsRemoved(fullFrameMargins());
1332 return QWindowsGeometryHint::frame(window(), handle(), style(), exStyle());
1338 ULONG touchFlags = 0;
1339 if (IsTouchWindow(handle(), &touchFlags) == FALSE)
1341 TouchWindowTouchTypes result;
1342 if ((touchFlags & TWF_FINETOUCH) != 0)
1343 result.setFlag(TouchWindowTouchType::FineTouch);
1344 if ((touchFlags & TWF_WANTPALM) != 0)
1345 result.setFlag(TouchWindowTouchType::WantPalmTouch);
1351 SetWindowPos(handle(),
nullptr , 0, 0, 0, 0,
1352 SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1357 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1358 const Qt::WindowType type = window()->type();
1359 if (type == Qt::Popup
1360 || type == Qt::SubWindow
1361 || !(window()->flags() & Qt::WindowStaysOnBottomHint)) {
1362 SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1368 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1369 if (!(window()->flags() & Qt::WindowStaysOnTopHint))
1370 SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1375 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << title;
1376 SetWindowText(handle(),
reinterpret_cast<
const wchar_t *>(title.utf16()));
1381 return QWindowsGeometryHint::mapToGlobal(handle(), pos);
1386 return QWindowsGeometryHint::mapFromGlobal(handle(), pos);
1412 switch (event->type()) {
1413 case QEvent::ChildWindowAdded:
1414 if (!(GetWindowLongPtr(handle(), GWL_STYLE) & WS_CLIPCHILDREN)) {
1415 auto *childWindowEvent =
static_cast<QChildWindowEvent*>(event);
1416 qWarning() << childWindowEvent->child() <<
"added as child to"
1417 << window() <<
"which does not have WS_CLIPCHILDREN set."
1418 <<
"This will result in drawing artifacts!";
1425 return QPlatformWindow::windowEvent(event);
1429
1430
1431
1432
1433
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1450 , m_topLevelStyle(0)
1452 if (QPlatformWindow::parent())
1453 setParent(QPlatformWindow::parent());
1458 if (QPlatformWindow::parent())
1465 const HWND newParent = newParentWindow ?
reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(
nullptr);
1466 const bool isTopLevel = !newParent;
1467 const DWORD oldStyle =
style();
1469 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() <<
"newParent="
1470 << newParentWindow << newParent <<
"oldStyle=" << debugWinStyle(oldStyle);
1472 auto updateWindowFlags = [&] {
1474 DWORD newStyle = oldStyle;
1476 newStyle = m_topLevelStyle;
1478 m_topLevelStyle = oldStyle;
1479 newStyle &= ~(WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW);
1480 newStyle |= WS_CHILD;
1482 SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
1485 if (wasTopLevel && !isTopLevel) {
1488 updateWindowFlags();
1491 SetParent(m_hwnd, newParent);
1493 if (!wasTopLevel && isTopLevel) {
1496 updateWindowFlags();
1502 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << visible;
1504 ShowWindow(handle(), SW_SHOWNOACTIVATE);
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1530 const QRect &geometryIn,
const QRect &geometry,
1532 DWORD style, DWORD exStyle) :
1535 requestedGeometryIn(geometryIn),
1536 requestedGeometry(geometry),
1537 obtainedPos(geometryIn.topLeft()),
1538 obtainedSize(geometryIn.size()),
1539 margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle))
1546 if (!(w->flags() & Qt::FramelessWindowHint))
1549 if (geometry.isValid()
1550 || !qt_window_private(
const_cast<QWindow *>(w))->resizeAutomatic) {
1551 frameX = geometry.x();
1552 frameY = geometry.y();
1553 const QMargins effectiveMargins = margins + customMargins;
1554 frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right();
1555 frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom();
1558 frameHeight += menuHeight;
1560 const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel();
1561 if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) {
1562 frameX -= effectiveMargins.left();
1563 frameY -= effectiveMargins.top();
1567 qCDebug(lcQpaWindow).nospace()
1568 <<
__FUNCTION__ <<
' ' << w <<
' ' << geometry
1569 <<
" pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w)
1570 <<
" frame=" << frameWidth <<
'x' << frameHeight <<
'+'
1571 << frameX <<
'+' << frameY
1572 <<
" margins=" << margins <<
" custom margins=" << customMargins;
1577 QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi);
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1609 m_cursor(
new CursorHandle)
1610#if QT_CONFIG(vulkan)
1611 , m_vkSurface(VK_NULL_HANDLE)
1616 if (aWindow->flags().testFlags(Qt::ExpandedClientAreaHint)) {
1617 SetParent(m_data.hwndTitlebar, m_data.hwnd);
1618 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
1621 if (aWindow->surfaceType() == QWindow::Direct3DSurface)
1623#if QT_CONFIG(opengl)
1624 if (aWindow->surfaceType() == QWindow::OpenGLSurface)
1625 setFlag(OpenGLSurface);
1627#if QT_CONFIG(vulkan)
1628 if (aWindow->surfaceType() == QSurface::VulkanSurface)
1629 setFlag(VulkanSurface);
1631 updateDropSite(window()->isTopLevel());
1635 if (!touchWindowTouchTypes_sys().has_value())
1638 const qreal opacity = qt_window_private(aWindow)->opacity;
1639 if (!qFuzzyCompare(opacity, qreal(1.0)))
1640 setOpacity(opacity);
1642 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
1644 if (aWindow->isTopLevel())
1645 setWindowIcon(aWindow->icon());
1653 if (m_vsyncServiceCallbackId != 0)
1654 QDxgiVSyncService::instance()->unregisterCallback(m_vsyncServiceCallbackId);
1656 QWindowsThemeCache::clearThemeCache(m_data.hwnd);
1658 UnregisterTouchWindow(m_data.hwnd);
1666 QWindowCreationContextPtr creationContext =
1669 QWindow *w = window();
1670 setWindowState(w->windowStates());
1674 const Qt::WindowState state = w->windowState();
1675 const QRect obtainedGeometry(creationContext->obtainedPos, creationContext->obtainedSize);
1676 QPlatformScreen *obtainedScreen = screenForGeometry(obtainedGeometry);
1677 if (obtainedScreen && screen() != obtainedScreen)
1678 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(w, obtainedScreen->screen());
1679 if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen
1680 && creationContext->requestedGeometryIn != obtainedGeometry) {
1681 QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
1688 return window()->requestedFormat();
1691void QWindowsWindow::fireExpose(
const QRegion ®ion,
bool force)
1693 if (region.isEmpty() && !force)
1697 QWindowSystemInterface::handleExposeEvent(window(), region);
1702 fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), force);
1707 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << m_data.hwnd;
1711 const auto tlw = QGuiApplication::topLevelWindows();
1712 for (QWindow *w : tlw) {
1713 if (w->transientParent() == window()) {
1714 if (QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(w))
1715 tw->updateTransientParent();
1719 if (context->windowUnderMouse() == window())
1723 setDropSiteEnabled(
false);
1724#if QT_CONFIG(vulkan)
1726 QVulkanInstance *inst = window()->vulkanInstance();
1728 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
1729 m_vkSurface = VK_NULL_HANDLE;
1736 m_surface =
nullptr;
1739 DestroyWindow(m_data.hwndTitlebar);
1740 DestroyWindow(m_data.hwnd);
1741 context->removeWindow(m_data.hwnd);
1742 m_data.hwndTitlebar =
nullptr;
1743 m_data.hwnd =
nullptr;
1749 bool enabled =
false;
1750 bool parentIsEmbedded =
false;
1755 const QWindow *parent = window()->parent();
1756 if (parent && parent->handle() && parent->handle()->isForeignWindow())
1757 parentIsEmbedded =
true;
1760 if (topLevel || parentIsEmbedded) {
1761 switch (window()->type()) {
1774 setDropSiteEnabled(enabled);
1779 if (isDropSiteEnabled() == dropEnabled)
1781 qCDebug(lcQpaMime) <<
__FUNCTION__ << window() << dropEnabled;
1782#if QT_CONFIG(clipboard) && QT_CONFIG(draganddrop)
1784 Q_ASSERT(m_data.hwnd);
1785 m_dropTarget =
new QWindowsOleDropTarget(window());
1786 RegisterDragDrop(m_data.hwnd, m_dropTarget);
1787 CoLockObjectExternal(m_dropTarget,
true,
true);
1789 CoLockObjectExternal(m_dropTarget,
false,
true);
1790 m_dropTarget->Release();
1791 RevokeDragDrop(m_data.hwnd);
1792 m_dropTarget =
nullptr;
1801 m_screenForGLInitialized =
false;
1806 m_screenForGLInitialized =
false;
1811 static QString forceToScreen;
1812 if (!m_screenForGLInitialized) {
1814 m_screenForGLInitialized =
true;
1816 return forceToScreen.isEmpty() ?
nullptr : screenForDeviceName(w, forceToScreen);
1823 while (QWindow *parent = w->parent())
1826 if (
const QPlatformWindow *handle = w->handle()) {
1827 const auto *ww =
static_cast<
const QWindowsWindow *>(handle);
1828 if (ww->isEmbedded()) {
1829 HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
1830 const HWND desktopHwnd = GetDesktopWindow();
1832 while (parentHWND && parentHWND != desktopHwnd) {
1833 if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
1834 return topLevelOf(ancestor->window());
1835 parentHWND = GetAncestor(parentHWND, GA_PARENT);
1845 const QString &title)
1848 creationData.fromWindow(w, parameters.flags);
1851 creationData.initialize(w, result.hwnd, !parameters.customMargins.isNull(), 1);
1857 const QWindow *win = window();
1858 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << win << m_data.hwnd << visible;
1871 if (win->type() == Qt::Popup && !win->parent() && !QGuiApplication::focusWindow())
1872 SetForegroundWindow(m_data.hwnd);
1876 if (window()->flags() & Qt::Popup)
1877 ShowWindow(m_data.hwnd, SW_HIDE);
1880 fireExpose(QRegion());
1887 return m_data.hwnd && IsWindowVisible(m_data.hwnd);
1893 if (
const HWND activeHwnd = GetForegroundWindow())
1894 if (m_data.hwnd == activeHwnd || IsChild(activeHwnd, m_data.hwnd))
1901 const auto *childWindow =
static_cast<
const QWindowsWindow *>(child);
1902 return IsChild(m_data.hwnd, childWindow->handle());
1907 return m_data.embedded;
1912 return m_data.hwnd ? QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos) : pos;
1917 return m_data.hwnd ? QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos) : pos;
1927 if (window()->type() == Qt::Popup)
1930 const HWND oldTransientParent = GetWindow(m_data.hwnd, GW_OWNER);
1931 HWND newTransientParent =
nullptr;
1932 if (
const QWindow *tp = window()->transientParent()) {
1933 if (
const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp)) {
1935 newTransientParent = tw->handle();
1938 newTransientParent = tbw->handle();
1944 while (newTransientParent && (GetWindowLongPtr(newTransientParent, GWL_STYLE) & WS_CHILD) != 0)
1945 newTransientParent = GetParent(newTransientParent);
1947 if (newTransientParent != oldTransientParent)
1948 SetWindowLongPtr(m_data.hwnd,
GWL_HWNDPARENT, LONG_PTR(newTransientParent));
1954 const QVariant showWithoutActivating = window->property(
"_q_showWithoutActivating");
1955 return showWithoutActivating.isValid() && showWithoutActivating.toBool();
1960 WINDOWPLACEMENT windowPlacement;
1961 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1962 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1963 windowPlacement.showCmd = SW_SHOWMINIMIZED;
1964 windowPlacement.rcNormalPosition = RECTfromQRect(r);
1965 SetWindowPlacement(hwnd, &windowPlacement);
1972 WINDOWPLACEMENT windowPlacement;
1973 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1974 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1976 windowPlacement.flags |= WPF_RESTORETOMAXIMIZED;
1978 windowPlacement.flags &= ~WPF_RESTORETOMAXIMIZED;
1979 SetWindowPlacement(hwnd, &windowPlacement);
1986 int sm = SW_SHOWNORMAL;
1987 bool fakedMaximize =
false;
1988 bool restoreMaximize =
false;
1989 const QWindow *w = window();
1990 const Qt::WindowFlags flags = w->flags();
1991 const Qt::WindowType type = w->type();
1992 if (w->isTopLevel()) {
1993 const Qt::WindowStates state = w->windowStates();
1994 if (state & Qt::WindowMinimized) {
1995 sm = SW_SHOWMINIMIZED;
1997 sm = SW_SHOWMINNOACTIVE;
1998 if (state & Qt::WindowMaximized)
1999 restoreMaximize =
true;
2001 updateTransientParent();
2002 if (state & Qt::WindowMaximized) {
2003 sm = SW_SHOWMAXIMIZED;
2009 if (flags & Qt::WindowTitleHint &&
2010 !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
2011 fakedMaximize = TRUE;
2012 setStyle(style() | WS_MAXIMIZEBOX);
2017 if (type == Qt::Popup ||
2018 type == Qt::ToolTip ||
2020 (flags & Qt::WindowDoesNotAcceptFocus) ||
2021 testShowWithoutActivating(w))
2022 sm = SW_SHOWNOACTIVATE;
2024 if (w->windowStates() & Qt::WindowMaximized)
2027 ShowWindow(m_data.hwnd, sm);
2031 if (fakedMaximize) {
2032 setStyle(style() & ~WS_MAXIMIZEBOX);
2033 SetWindowPos(m_data.hwnd,
nullptr, 0, 0, 0, 0,
2034 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
2035 | SWP_FRAMECHANGED);
2037 if (restoreMaximize)
2038 setRestoreMaximizedFlag(m_data.hwnd);
2043 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << newParent;
2046 setParent_sys(newParent);
2052 HWND oldParentHWND = parentHwnd();
2053 HWND newParentHWND =
nullptr;
2055 const auto *parentW =
static_cast<
const QWindowsWindow *>(parent);
2056 newParentHWND = parentW->handle();
2061 HWND desktopHwnd = GetDesktopWindow();
2062 if (oldParentHWND == desktopHwnd)
2063 oldParentHWND =
nullptr;
2064 if (newParentHWND == desktopHwnd)
2065 newParentHWND =
nullptr;
2067 if (newParentHWND != oldParentHWND) {
2068 const bool wasTopLevel = oldParentHWND ==
nullptr;
2069 const bool isTopLevel = newParentHWND ==
nullptr;
2072 SetParent(m_data.hwnd, newParentHWND);
2078 if (wasTopLevel != isTopLevel) {
2079 setDropSiteEnabled(
false);
2080 m_data = setWindowFlags_sys(window()->flags(),
unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
2087 m_data.fullFrameMargins = {};
2088 updateDropSite(isTopLevel);
2095 fireExpose(QRegion());
2100 const QWindow *w = window();
2102 applyBlurBehindWindow(handle());
2107 return QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) /
2108 QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi);
2118 const UINT dpi = UINT(wParam);
2119 const qreal scale = dpiRelativeScale(dpi);
2120 const QMargins margins = fullFrameMargins();
2121 if (!(m_data.flags & Qt::FramelessWindowHint)) {
2127 m_data.customMargins *= scale;
2130 const QSize windowSize = (geometry().size() * scale).grownBy((margins * scale) + customMargins());
2131 SIZE *size =
reinterpret_cast<SIZE *>(lParam);
2132 size->cx = windowSize.width();
2133 size->cy = windowSize.height();
2139 const UINT dpi = HIWORD(wParam);
2140 const qreal scale = dpiRelativeScale(dpi);
2143 QWindowsThemeCache::clearThemeCache(hwnd);
2146 const auto prcNewWindow =
reinterpret_cast<
const RECT *>(lParam);
2147 checkForScreenChanged(QWindowsWindow::FromDpiChange, !m_inSetgeometry ? prcNewWindow :
nullptr);
2149 if (!IsZoomed(hwnd))
2150 m_data.restoreGeometry.setSize(m_data.restoreGeometry.size() * scale);
2168 if (!m_inSetgeometry) {
2170 SetWindowPos(hwnd,
nullptr, prcNewWindow->left, prcNewWindow->top,
2171 prcNewWindow->right - prcNewWindow->left,
2172 prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
2176 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2177 handleGeometryChange();
2188 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
2193 const UINT dpi = GetDpiForWindow(hwnd);
2194 const qreal scale = dpiRelativeScale(dpi);
2197 checkForScreenChanged(QWindowsWindow::FromDpiChange);
2201 QRect currentGeometry = geometry();
2202 QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
2203 setGeometry(scaledGeometry);
2209 wp.length =
sizeof(WINDOWPLACEMENT);
2210 if (GetWindowPlacement(hwnd, &wp)) {
2211 const QRect result = qrectFromRECT(wp.rcNormalPosition);
2212 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
2220 const bool fakeFullScreen =
2221 m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen);
2222 const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
2223 const QMargins margins = fakeFullScreen
2224 ? QWindowsGeometryHint::frame(window(), handle(), m_savedStyle, 0)
2225 : fullFrameMargins();
2226 return frame.isValid() ? frame.marginsRemoved(margins) : frame;
2231 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
2232 const int titleBarHeight = getTitleBarHeight_sys(96);
2234 return QMargins(0, titleBarHeight, 0, 0);
2240 const QRect &requestedRect,
2241 const QRect &obtainedRect,
2242 const QMargins &fullMargins,
2243 const QMargins &customMargins)
2246 QDebug debug(&result);
2249 const auto window = platformWindow->window();
2250 debug <<
"Unable to set geometry ";
2251 formatBriefRectangle(debug, requestedRect);
2252 debug <<
" (frame: ";
2253 formatBriefRectangle(debug, requestedRect + fullMargins);
2254 debug <<
") on " << window->metaObject()->className() <<
"/\""
2255 << window->objectName() <<
"\" on \"" << window->screen()->name()
2256 <<
"\". Resulting geometry: ";
2257 formatBriefRectangle(debug, obtainedRect);
2258 debug <<
" (frame: ";
2259 formatBriefRectangle(debug, obtainedRect + fullMargins);
2260 debug <<
") margins: ";
2261 formatBriefMargins(debug, fullMargins);
2262 if (!customMargins.isNull()) {
2263 debug <<
" custom margin: ";
2264 formatBriefMargins(debug, customMargins);
2266 const auto minimumSize = window->minimumSize();
2267 const bool hasMinimumSize = !minimumSize.isEmpty();
2269 debug <<
" minimum size: " << minimumSize.width() <<
'x' << minimumSize.height();
2270 const auto maximumSize = window->maximumSize();
2271 const bool hasMaximumSize = maximumSize.width() != QWINDOWSIZE_MAX || maximumSize.height() != QWINDOWSIZE_MAX;
2273 debug <<
" maximum size: " << maximumSize.width() <<
'x' << maximumSize.height();
2274 if (hasMinimumSize || hasMaximumSize) {
2275 MINMAXINFO minmaxInfo;
2276 memset(&minmaxInfo, 0,
sizeof(minmaxInfo));
2277 platformWindow->getSizeHints(&minmaxInfo);
2278 debug <<
' ' << minmaxInfo;
2286 QScopedValueRollback b(m_inSetgeometry,
true);
2288 QRect rect = rectIn;
2291 if (QWindowsGeometryHint::positionIncludesFrame(window())) {
2292 const QMargins margins = frameMargins();
2293 rect.moveTopLeft(rect.topLeft() +
QPoint(margins.left(), margins.top()));
2295 if (m_windowState & Qt::WindowMinimized)
2296 m_data.geometry = rect;
2302 setGeometry_sys(rect);
2304 if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) {
2305 const auto warning =
2306 msgUnableToSetGeometry(
this, rectIn, m_data.geometry,
2307 fullFrameMargins(), customMargins());
2308 qWarning(
"%s: %s",
__FUNCTION__, qPrintable(warning));
2311 QPlatformWindow::setGeometry(rect);
2319 handleGeometryChange();
2325 if ((m_data.flags.testFlag(Qt::FramelessWindowHint)
2326 || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))
2327 && IsZoomed(m_data.hwnd)) {
2328 const int resizedWidth = LOWORD(lParam);
2329 const int resizedHeight = HIWORD(lParam);
2331 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTOPRIMARY);
2332 MONITORINFO monitorInfo = {};
2333 monitorInfo.cbSize =
sizeof(MONITORINFO);
2334 GetMonitorInfoW(monitor, &monitorInfo);
2336 int correctLeft = monitorInfo.rcMonitor.left;
2337 int correctTop = monitorInfo.rcMonitor.top;
2338 int correctWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
2339 int correctHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
2341 if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
2342 const int borderWidth = invisibleMargins(m_data.hwnd).left();
2343 correctLeft -= borderWidth;
2344 correctTop -= borderWidth;
2345 correctWidth += borderWidth * 2;
2346 correctHeight += borderWidth * 2;
2349 if (resizedWidth != correctWidth || resizedHeight != correctHeight) {
2350 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"correcting: " << resizedWidth <<
"x"
2351 << resizedHeight <<
" -> " << correctWidth <<
"x" << correctHeight;
2352 SetWindowPos(m_data.hwnd,
nullptr, correctLeft, correctTop, correctWidth, correctHeight,
2353 SWP_NOZORDER | SWP_NOACTIVATE);
2361 case SIZE_MINIMIZED:
2362 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2363 handleWindowStateChange(m_windowState | Qt::WindowMinimized);
2365 case SIZE_MAXIMIZED:
2366 handleGeometryChange();
2368 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2369 handleWindowStateChange(Qt::WindowMaximized | (isFullScreen_sys() ? Qt::WindowFullScreen
2370 : Qt::WindowNoState));
2373 handleGeometryChange();
2375 if (isFullScreen_sys())
2376 handleWindowStateChange(
2377 Qt::WindowFullScreen
2378 | (testFlag(MaximizeToFullScreen) ? Qt::WindowMaximized : Qt::WindowNoState));
2379 else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
2380 handleWindowStateChange(Qt::WindowNoState);
2386static inline bool equalDpi(
const QDpi &d1,
const QDpi &d2)
2388 return qFuzzyCompare(d1.first, d2.first) && qFuzzyCompare(d1.second, d2.second);
2396 QPlatformScreen *currentScreen = screen();
2397 auto topLevel = isTopLevel_sys() ? m_data.hwnd : GetAncestor(m_data.hwnd, GA_ROOT);
2402 if (newScreen ==
nullptr || newScreen == currentScreen)
2406 const bool changingDpi = !equalDpi(QDpi(savedDpi(), savedDpi()), newScreen->logicalDpi());
2410 qCDebug(lcQpaWindow).noquote().nospace() <<
__FUNCTION__
2411 <<
' ' << window() <<
" \"" << (currentScreen ? currentScreen->name() : QString())
2412 <<
"\"->\"" << newScreen->name() <<
'"';
2414 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
2419 const QRect previousGeometry = m_data.geometry;
2421 m_data.geometry = geometry_sys();
2424 if (m_data.geometry == previousGeometry)
2426 QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
2431 && m_data.geometry.size() != previousGeometry.size()
2433 && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
2434 fireFullExpose(
true);
2438 checkForScreenChanged();
2440 if (testFlag(SynchronousGeometryChangeEvent))
2441 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2448 qCDebug(lcQpaEvents) <<
__FUNCTION__ <<
this << window() << m_data.geometry;
2450 if (m_data.flags & Qt::ExpandedClientAreaHint) {
2451 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
2452 MoveWindow(m_data.hwndTitlebar, 0, 0, m_data.geometry.width(), titleBarHeight,
true);
2458 const QMargins margins = fullFrameMargins();
2459 const QRect frameGeometry = rect + margins;
2461 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ << window()
2462 <<
"\n from " << geometry_sys() <<
" frame: "
2463 << margins <<
" to " <<rect
2464 <<
" new frame: " << frameGeometry;
2466 bool result =
false;
2467 const HWND hwnd = handle();
2468 WINDOWPLACEMENT windowPlacement;
2469 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2470 GetWindowPlacement(hwnd, &windowPlacement);
2473 if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(hwnd))
2474 || windowPlacement.showCmd == SW_SHOWMINIMIZED) {
2475 windowPlacement.rcNormalPosition =
2476 RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(hwnd, frameGeometry.topLeft())));
2477 windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
2478 result = SetWindowPlacement(hwnd, &windowPlacement);
2480 int x = frameGeometry.x();
2481 if (!window()->isTopLevel()) {
2482 const HWND parentHandle = GetParent(hwnd);
2483 if (isRtlLayout(parentHandle)) {
2485 GetClientRect(parentHandle, &rect);
2486 x = rect.right - frameGeometry.width() - x;
2489 result = MoveWindow(hwnd, x, frameGeometry.y(),
2490 frameGeometry.width(), frameGeometry.height(),
true);
2492 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ << window()
2493 <<
"\n resulting " << result << geometry_sys();
2497
2498
2499
2500
2501
2506 m_hdc = GetDC(handle());
2507 if (QGuiApplication::layoutDirection() == Qt::RightToLeft)
2508 SetLayout(m_hdc, 0);
2514
2515
2516
2517
2518
2523 ReleaseDC(handle(), m_hdc);
2530#if QT_CONFIG(dynamicgl)
2531 return QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()
2532 && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL;
2541 if (message == WM_ERASEBKGND) {
2546 if (!window()->isVisible() && (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0)
2549 if (!GetUpdateRect(m_data.hwnd, 0, FALSE))
2556 InvalidateRect(hwnd,
nullptr,
false);
2558 BeginPaint(hwnd, &ps);
2563 fireExpose(QRegion(qrectFromRECT(ps.rcPaint)),
true);
2564 if (!QWindowsContext::instance()->asyncExpose())
2565 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2567 EndPaint(hwnd, &ps);
2573 m_windowTitle = QWindowsWindow::formatWindowTitle(title);
2574 setWindowTitle_sys(m_windowTitle);
2579 return m_windowTitle;
2584 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window() <<
"\n from: "
2585 << m_data.flags <<
"\n to: " << flags;
2586 const QRect oldGeometry = geometry();
2587 if (m_data.flags != flags) {
2588 m_data.flags = flags;
2590 m_data = setWindowFlags_sys(flags);
2591 updateDropSite(window()->isTopLevel());
2598 const QRect newGeometry = geometry_sys();
2599 if (oldGeometry != newGeometry)
2600 handleGeometryChange();
2602 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
"\n returns: "
2603 << m_data.flags <<
" geometry " << oldGeometry <<
"->" << newGeometry;
2607 unsigned flags)
const
2610 creationData.fromWindow(window(), wt, flags);
2611 creationData.applyWindowFlags(m_data.hwnd);
2612 creationData.initialize(window(), m_data.hwnd,
true, m_opacity);
2614 if (creationData.flags.testFlag(Qt::ExpandedClientAreaHint)) {
2615 SetParent(m_data.hwndTitlebar, m_data.hwnd);
2616 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
2618 if (IsWindowVisible(m_data.hwndTitlebar)) {
2619 SetParent(m_data.hwndTitlebar, HWND_MESSAGE);
2620 ShowWindow(m_data.hwndTitlebar, SW_HIDE);
2625 result.flags = creationData.flags;
2627 result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME))
2628 && !(creationData.flags & Qt::FramelessWindowHint);
2632void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
2634 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window()
2635 <<
"\n from " << m_windowState <<
" to " << state;
2636 m_windowState = state;
2637 QWindowSystemInterface::handleWindowStateChanged(window(), state);
2638 if (state & Qt::WindowMinimized) {
2640 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2643 if (state & Qt::WindowMaximized) {
2644 WINDOWPLACEMENT windowPlacement{};
2645 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2646 GetWindowPlacement(m_data.hwnd, &windowPlacement);
2647 const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
2648 windowPlacement.rcNormalPosition = geometry;
2649 correctWindowPlacement(windowPlacement);
2655 windowPlacement.showCmd = SW_HIDE;
2656 SetWindowPlacement(m_data.hwnd, &windowPlacement);
2660 QWindow *w = window();
2661 bool exposeEventsSent =
false;
2664 exposeEventsSent =
true;
2666 const QWindowList allWindows = QGuiApplication::allWindows();
2667 for (QWindow *child : allWindows) {
2668 if (child != w && child->isVisible() && child->transientParent() == w) {
2669 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
2670 if (platformWindow && platformWindow->isLayered()) {
2671 platformWindow->fireFullExpose();
2672 exposeEventsSent =
true;
2676 if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
2677 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2686 return window()->maximumHeight() != QWINDOWSIZE_MAX;
2691 return window()->maximumWidth() != QWINDOWSIZE_MAX;
2699void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
2701 static const auto windows11 = QOperatingSystemVersion::Windows11_21H2;
2702 static const bool isWindows10 = QOperatingSystemVersion::current() < windows11;
2708 const QPoint offset = windowPlacementOffset(m_data.hwnd, m_data.restoreGeometry.topLeft());
2709 windowPlacement.rcNormalPosition = RECTfromQRect(m_data.restoreGeometry.translated(-offset));
2710 qCDebug(lcQpaWindow) <<
"Corrected normal position by" << -offset;
2719 const QMargins margins = frameMargins_sys();
2720 const QPoint topLeft = window()->screen()->geometry().topLeft();
2721 windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() };
2722 qCDebug(lcQpaWindow) <<
"Window has maximum size. Corrected topLeft by"
2728 const int adjust = offset.x() / window()->devicePixelRatio();
2729 window()->setWidth(window()->width() - adjust);
2730 qCDebug(lcQpaWindow) <<
"Width shortened by" << adjust <<
"logical pixels.";
2733 const int adjust = offset.y() / window()->devicePixelRatio();
2734 window()->setHeight(window()->height() - adjust);
2735 qCDebug(lcQpaWindow) <<
"Height shortened by" << adjust <<
"logical pixels.";
2742 m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
2748 setWindowState_sys(state);
2749 m_windowState = state;
2755 const QWindow *w = window();
2756 if (!w->isTopLevel())
2758 QRect geometry = geometry_sys();
2760 geometry += QMargins(1, 1, 1, 1);
2761 QPlatformScreen *screen = screenForGeometry(geometry);
2762 return screen && geometry == screen->geometry();
2766
2767
2768
2769
2770
2771
2772
2773
2774
2776void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
2778 const Qt::WindowStates oldState = m_windowState;
2779 if (oldState == newState)
2781 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window()
2782 <<
" from " << oldState <<
" to " << newState;
2785 auto stateChange = oldState ^ newState;
2787 if (stateChange & Qt::WindowFullScreen) {
2788 if (newState & Qt::WindowFullScreen) {
2789 UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
2793 if (!m_savedStyle) {
2794 m_savedStyle =
style();
2795 if ((oldState & Qt::WindowMinimized) || (oldState & Qt::WindowMaximized)) {
2796 const QRect nf = normalFrameGeometry(m_data.hwnd);
2798 m_savedFrameGeometry = nf;
2800 m_savedFrameGeometry = frameGeometry_sys();
2803 if (newState & Qt::WindowMaximized)
2805 if (m_savedStyle & WS_SYSMENU)
2806 newStyle |= WS_SYSMENU;
2808 newStyle |= WS_VISIBLE;
2809 if (testFlag(HasBorderInFullScreen))
2810 newStyle |= WS_BORDER;
2812 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2813 MONITORINFO monitorInfo = {};
2814 monitorInfo.cbSize =
sizeof(MONITORINFO);
2815 GetMonitorInfoW(monitor, &monitorInfo);
2816 const QRect screenGeometry(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
2817 monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
2818 monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
2819 if (newState & Qt::WindowMinimized) {
2820 setMinimizedGeometry(m_data.hwnd, screenGeometry);
2821 if (stateChange & Qt::WindowMaximized)
2822 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2824 const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
2827 SetWindowPos(m_data.hwnd, HWND_TOP, screenGeometry.left(), screenGeometry.top(), screenGeometry.width(), screenGeometry.height(), swpf);
2831 QWindowSystemInterface::handleGeometryChange(window(), screenGeometry);
2832 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2836 unsigned newStyle = m_savedStyle ? m_savedStyle :
style();
2838 newStyle |= WS_VISIBLE;
2841 const QScreen *screen = window()->screen();
2843 screen = QGuiApplication::primaryScreen();
2845 if (
const auto platformScreen = screen->handle()) {
2846 if (!platformScreen->geometry().intersects(m_savedFrameGeometry))
2847 m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft());
2850 if (newState & Qt::WindowMinimized) {
2851 setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry);
2852 if (stateChange & Qt::WindowMaximized)
2853 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2855 UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
2856 if (!m_savedFrameGeometry.isValid())
2857 swpf |= SWP_NOSIZE | SWP_NOMOVE;
2862 if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
2863 ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
2864 SetWindowPos(m_data.hwnd,
nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
2865 m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
2871 ShowWindow(m_data.hwnd,
2872 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
2877 m_savedFrameGeometry = QRect();
2879 }
else if ((oldState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
2880 if (visible && !(newState & Qt::WindowMinimized)) {
2882 if (newState & Qt::WindowFullScreen)
2884 if (m_data.flags & Qt::FramelessWindowHint) {
2885 if (newState == Qt::WindowNoState) {
2886 const QRect &rect = m_savedFrameGeometry;
2887 MoveWindow(m_data.hwnd, rect.x(), rect.y(), rect.width(), rect.height(),
true);
2889 HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2890 MONITORINFO monitorInfo = {};
2891 monitorInfo.cbSize =
sizeof(MONITORINFO);
2892 GetMonitorInfo(monitor, &monitorInfo);
2893 const RECT &rect = monitorInfo.rcWork;
2894 m_savedFrameGeometry = geometry();
2895 MoveWindow(m_data.hwnd, rect.left, rect.top,
2896 rect.right - rect.left, rect.bottom - rect.top,
true);
2899 ShowWindow(m_data.hwnd,
2900 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
2904 }
else if (visible && (oldState & newState & Qt::WindowMinimized)) {
2906 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2910 if (stateChange & Qt::WindowMinimized) {
2912 ShowWindow(m_data.hwnd,
2913 (newState & Qt::WindowMinimized) ? SW_MINIMIZE :
2914 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
2915 if ((newState & Qt::WindowMinimized) && (stateChange & Qt::WindowMaximized))
2916 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2919 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
this << window() << newState;
2924 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinStyle(s);
2926 SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
2932 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinExStyle(s);
2933 SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
2938 switch (event->type()) {
2939 case QEvent::ApplicationPaletteChange:
2940 setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
2942 case QEvent::WindowBlocked:
2948 case QEvent::WindowUnblocked:
2956 return QWindowsBaseWindow::windowEvent(event);
2961 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
2966 bool result =
false;
2967 if ((windowPos->flags & SWP_NOSIZE) == 0) {
2969 GetWindowRect(windowPos->hwnd, &rect);
2970 result = rect.right - rect.left != windowPos->cx || rect.bottom - rect.top != windowPos->cy;
2975bool QWindowsWindow::handleGeometryChangingMessage(MSG *message,
const QWindow *qWindow,
const QMargins &margins)
2977 auto *windowPos =
reinterpret_cast<WINDOWPOS *>(message->lParam);
2978 const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
2979 windowPos->cx, windowPos->cy);
2980 const QRect suggestedGeometry = suggestedFrameGeometry - margins;
2987 if (isResize(windowPos))
2988 windowPos->flags |= SWP_NOCOPYBITS;
2990 if ((windowPos->flags & SWP_NOZORDER) == 0) {
2991 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(qWindow)) {
2992 QWindow *parentWindow = qWindow->parent();
2993 HWND parentHWND = GetAncestor(windowPos->hwnd, GA_PARENT);
2994 HWND desktopHWND = GetDesktopWindow();
2995 platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND);
2997 if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint))
2998 windowPos->hwndInsertAfter = HWND_BOTTOM;
3000 if (!qWindow->isTopLevel())
3002 if (windowPos->flags & SWP_NOSIZE)
3004 const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
3005 if (!correctedGeometryF.isValid())
3007 const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
3008 if (correctedFrameGeometry == suggestedFrameGeometry)
3010 windowPos->x = correctedFrameGeometry.left();
3011 windowPos->y = correctedFrameGeometry.top();
3012 windowPos->cx = correctedFrameGeometry.width();
3013 windowPos->cy = correctedFrameGeometry.height();
3019 const QMargins margins = window()->isTopLevel() ? fullFrameMargins() : QMargins();
3020 return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
3025 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3027 if (m_data.fullFrameMargins != newMargins) {
3028 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << m_data.fullFrameMargins <<
"->" << newMargins;
3029 m_data.fullFrameMargins = newMargins;
3036 if (GetMenu(m_data.hwnd))
3037 QWindowsContext::forceNcCalcSize(m_data.hwnd);
3039 calculateFullFrameMargins();
3044 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3057 GetWindowRect(handle(), &windowRect);
3058 GetClientRect(handle(), &clientRect);
3064 if (qSizeOfRect(windowRect) == qSizeOfRect(clientRect))
3069 const auto systemMargins = testFlag(DisableNonClientScaling)
3070 ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd)
3071 : frameMargins_sys();
3072 const int extendedClientAreaBorder = window()->flags().testFlag(Qt::ExpandedClientAreaHint) ? qRound(QHighDpiScaling::factor(window())) * 2 : 0;
3073 const QMargins actualMargins = systemMargins + customMargins() - extendedClientAreaBorder;
3075 const int yDiff = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
3076 const bool typicalFrame = (actualMargins.left() == actualMargins.right())
3077 && (actualMargins.right() == actualMargins.bottom());
3079 const QMargins adjustedMargins = typicalFrame ?
3080 QMargins(actualMargins.left(), (yDiff - actualMargins.bottom()),
3081 actualMargins.right(), actualMargins.bottom())
3084 setFullFrameMargins(adjustedMargins);
3089 QMargins result = fullFrameMargins();
3090 if (isTopLevel() && m_data.hasFrame)
3091 result -= invisibleMargins(m_data.hwnd);
3097 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3099 return m_data.fullFrameMargins;
3104 qCDebug(lcQpaWindow) <<
__FUNCTION__ << level;
3105 if (!qFuzzyCompare(m_opacity, level)) {
3108 setWindowOpacity(m_data.hwnd, m_data.flags,
3116 return CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
3121 if (
const HRGN rectRegion = createRectRegion(rect)) {
3122 HRGN result = CreateRectRgn(0, 0, 0, 0);
3123 if (CombineRgn(result, *winRegion, rectRegion, RGN_OR)) {
3124 DeleteObject(*winRegion);
3125 *winRegion = result;
3127 DeleteObject(rectRegion);
3133 auto it = region.begin();
3134 const auto end = region.end();
3137 HRGN hRegion = createRectRegion(*it);
3139 addRectToWinRegion(*it, &hRegion);
3145 if (region.isEmpty()) {
3146 SetWindowRgn(m_data.hwnd,
nullptr,
true);
3149 const HRGN winRegion = qRegionToWinRegion(region);
3152 if (window()->isTopLevel()) {
3153 const QMargins margins = fullFrameMargins();
3154 OffsetRgn(winRegion, margins.left(), margins.top());
3158 if (!SetWindowRgn(m_data.hwnd, winRegion,
true))
3159 DeleteObject(winRegion);
3164 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
3170 if (QGuiApplication::applicationState() == Qt::ApplicationActive
3171 || activationBehavior != QWindowsApplication::AlwaysActivateWindow) {
3172 SetForegroundWindow(m_data.hwnd);
3173 SetFocus(m_data.hwnd);
3182 if (m_data.flags & Qt::WindowStaysOnBottomHint) {
3183 qCWarning(lcQpaWindow) <<
3184 "Windows with Qt::WindowStaysOnBottomHint can't be brought to the foreground.";
3187 if (m_data.flags & Qt::WindowStaysOnTopHint) {
3188 qCWarning(lcQpaWindow) <<
3189 "Windows with Qt::WindowStaysOnTopHint will always be on the foreground.";
3192 if (window()->type() == Qt::ToolTip) {
3193 qCWarning(lcQpaWindow) <<
"ToolTip windows should not be activated.";
3198 if (!IsWindowVisible(m_data.hwnd))
3199 ShowWindow(m_data.hwnd, SW_SHOW);
3201 if (IsIconic(m_data.hwnd)) {
3202 ShowWindow(m_data.hwnd, SW_RESTORE);
3209 const HWND oldForegroundWindow = GetForegroundWindow();
3210 if (!oldForegroundWindow)
3215 if (SendMessageTimeoutW(oldForegroundWindow, WM_NULL, 0, 0,
3216 SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000,
nullptr) == 0) {
3217 qCWarning(lcQpaWindow) <<
"The foreground window hangs, can't activate current window.";
3221 const DWORD windowThreadProcessId = GetWindowThreadProcessId(oldForegroundWindow,
nullptr);
3222 const DWORD currentThreadId = GetCurrentThreadId();
3224 AttachThreadInput(windowThreadProcessId, currentThreadId, TRUE);
3225 const auto cleanup = qScopeGuard([windowThreadProcessId, currentThreadId](){
3226 AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE);
3229 BringWindowToTop(m_data.hwnd);
3233 SetActiveWindow(m_data.hwnd);
3239 qWarning(
"%s: No handle",
__FUNCTION__);
3242 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << grab;
3246 context->setKeyGrabber(window());
3248 if (context->keyGrabber() == window())
3249 context->setKeyGrabber(
nullptr);
3256 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << grab;
3258 qWarning(
"%s: No handle",
__FUNCTION__);
3262 qWarning(
"%s: Not setting mouse grab for invisible window %s/'%s'",
3263 __FUNCTION__, window()->metaObject()->className(),
3264 qPrintable(window()->objectName()));
3271 SetCapture(m_data.hwnd);
3281 if (edges == Qt::LeftEdge)
3283 else if (edges == (Qt::RightEdge))
3285 else if (edges == (Qt::TopEdge))
3287 else if (edges == (Qt::TopEdge | Qt::LeftEdge))
3289 else if (edges == (Qt::TopEdge | Qt::RightEdge))
3291 else if (edges == (Qt::BottomEdge))
3293 else if (edges == (Qt::BottomEdge | Qt::LeftEdge))
3295 else if (edges == (Qt::BottomEdge | Qt::RightEdge))
3303 if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
3307 PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0);
3315 PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 , 0);
3330 QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
3331 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << *mmi;
3337 const QWindow *w = window();
3338 const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
3339 const QRect geom = geometry();
3340 static auto oldMouseButtonState = Qt::NoButton;
3342 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
3343 bool isDefaultTitleBar = !w->flags().testFlag(Qt::CustomizeWindowHint);
3344 bool isCustomized = w->flags().testFlags(Qt::CustomizeWindowHint) && w->flags().testAnyFlags(Qt::WindowTitleHint|
3345 Qt::WindowMinimizeButtonHint|
3346 Qt::WindowMaximizeButtonHint|
3347 Qt::WindowCloseButtonHint);
3348 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3349 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3350 const int titleButtonWidth = titleBarHeight * 1.5;
3351 const bool mouseButtonsSwapped = GetSystemMetrics(SM_SWAPBUTTON);
3352 auto mouseButtons = Qt::NoButton;
3353 if (mouseButtonsSwapped)
3354 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::RightButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::LeftButton : Qt::NoButton);
3356 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::LeftButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::RightButton : Qt::NoButton);
3359 if (isCustomized || isDefaultTitleBar) {
3362 if (globalPos.y() < geom.top() + titleBarHeight) {
3363 if (m_data.flags.testFlags(Qt::WindowCloseButtonHint) || isDefaultTitleBar) {
3364 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right())) {
3365 if (mouseButtons == Qt::LeftButton)
3369 }
if (m_data.flags.testFlags(Qt::WindowMaximizeButtonHint) || isDefaultTitleBar) {
3370 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3371 if (mouseButtons == Qt::LeftButton) {
3372 if (IsZoomed(m_data.hwnd))
3375 *result = HTMAXBUTTON;
3379 }
if (m_data.flags.testFlags(Qt::WindowMinimizeButtonHint) || isDefaultTitleBar) {
3380 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3381 if (mouseButtons == Qt::LeftButton)
3382 *result = HTMINBUTTON;
3385 }
if ((isCustomized || isDefaultTitleBar) &&
3386 *result == HTCLIENT){
3387 QWindow* wnd = window();
3388 if (mouseButtons != oldMouseButtonState) {
3389 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3390 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3391 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3392 if (!accepted && mouseButtons == Qt::RightButton)
3393 *result = HTSYSMENU;
3394 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3395 *result = HTCAPTION;
3399 }
else if (w->flags().testFlag(Qt::CustomizeWindowHint)) {
3401 QWindow* wnd = window();
3402 if (mouseButtons != oldMouseButtonState) {
3403 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3404 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3405 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3406 if (!accepted && mouseButtons == Qt::RightButton)
3407 *result = HTSYSMENU;
3408 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3409 *result = HTCAPTION;
3412 oldMouseButtonState = mouseButtons;
3415 const bool left = (globalPos.x() >= geom.left()) && (globalPos.x() < geom.left() + border);
3416 const bool right = (globalPos.x() > geom.right() - border) && (globalPos.x() <= geom.right());
3417 const bool top = (globalPos.y() >= geom.top()) && (globalPos.y() < geom.top() + border);
3418 const bool bottom = (globalPos.y() > geom.bottom() - border) && (globalPos.y() <= geom.bottom());
3420 if (left || right || top || bottom) {
3422 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3424 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3426 *result = top ? HTTOP : HTBOTTOM;
3432 const_cast<QWindow *>(w)->close();
3435 const_cast<QWindow *>(w)->showMaximized();
3438 const_cast<QWindow *>(w)->showMinimized();
3441 const_cast<QWindow *>(w)->showNormal();
3444 HWND hwnd =
reinterpret_cast<HWND>(w->winId());
3445 HMENU sysMenu = GetSystemMenu(hwnd,
false);
3446 TrackPopupMenu(sysMenu, 0, globalPos.x(), globalPos.y(), 0, hwnd,
nullptr);
3455 if (m_data.flags & Qt::ExpandedClientAreaHint) {
3456 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3461 const QRect rect = geom;
3462 const bool left = (globalPos.x() >= rect.left()) && (globalPos.x() < rect.left() + border);
3463 const bool right = (globalPos.x() > rect.right() - border) && (globalPos.x() <= rect.right());
3464 const bool top = (globalPos.y() >= rect.top()) && (globalPos.y() < rect.top() + border);
3465 const bool bottom = (globalPos.y() > rect.bottom() - border) && (globalPos.y() <= rect.bottom());
3468 if (left || right || top || bottom) {
3470 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3472 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3474 *result = top ? HTTOP : HTBOTTOM;
3482 if (!w->isTopLevel()
3483 || (m_windowState != Qt::WindowNoState)
3485 || (m_data.flags & Qt::FramelessWindowHint)) {
3488 const QSize minimumSize = w->minimumSize();
3489 if (minimumSize.isEmpty())
3491 const QSize maximumSize = w->maximumSize();
3492 const bool fixedWidth = minimumSize.width() == maximumSize.width();
3493 const bool fixedHeight = minimumSize.height() == maximumSize.height();
3494 if (!fixedWidth && !fixedHeight)
3496 const QSize size = w->size();
3498 if (localPos.y() >= size.height()) {
3502 if (localPos.y() < 0) {
3503 const int topResizeBarPos = invisibleMargins(m_data.hwnd).left() - frameMargins().top();
3504 if (localPos.y() < topResizeBarPos) {
3505 *result = HTCAPTION;
3510 if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
3522 if (m_data.flags & Qt::FramelessWindowHint) {
3531 HWND hwnd = m_data.hwndTitlebar;
3532 QWindow *wnd = window();
3535 GetWindowRect(hwnd, &windowRect);
3537 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3538 const int titleButtonWidth = titleBarHeight * 1.5;
3539 const qreal factor = QHighDpiScaling::factor(wnd);
3540 const int windowWidth = windowRect.right - windowRect.left;
3543 GetCursorPos(&localPos);
3544 MapWindowPoints(HWND_DESKTOP, m_data.hwnd, &localPos, 1);
3546 const bool isDarkmode = QWindowsIntegration::instance()->darkModeHandling().testFlags(QWindowsApplication::DarkModeWindowFrames) &&
3547 qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
3548 const bool isWindows11orAbove = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11;
3550 const QBrush closeButtonBrush(QColor(0xC4, 0x2C, 0x1E, 255));
3551 const QBrush minMaxButtonBrush = QBrush(isDarkmode ? QColor(0xFF, 0xFF, 0xFF, 0x40) : QColor(0x00, 0x00, 0x00, 0x20));
3552 const QBrush titleBarBackgroundColor = QBrush(isDarkmode ? QColor(0x1F, 0x1F, 0x1F, 0xFF) : QColor(0xF3, 0xF3, 0xF3, 0xFF));
3553 const QPen textPen = QPen(isDarkmode ? QColor(0xFF, 0xFF, 0xFD, 0xFF) : QColor(0x00, 0x00, 0x00, 0xFF));
3555 QImage image(windowWidth, titleBarHeight, QImage::Format_ARGB32);
3557 p.setCompositionMode(QPainter::CompositionMode_Clear);
3558 p.fillRect(0, 0, windowWidth, titleBarHeight, Qt::transparent);
3560 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
3562 p.setBrush(titleBarBackgroundColor);
3563 p.setPen(Qt::NoPen);
3564 if (!wnd->flags().testFlags(Qt::NoTitleBarBackgroundHint)) {
3566 titleRect.setWidth(windowWidth);
3567 titleRect.setHeight(titleBarHeight);
3568 p.drawRect(titleRect);
3571 if (wnd->flags().testFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3575 titleRect.setWidth(windowWidth);
3576 titleRect.setHeight(titleBarHeight);
3578 titleRect.adjust(factor * 4, 0, 0, 0);
3579 QRect iconRect(titleRect.x(), titleRect.y() + factor * 8, factor * 16, factor * 16);
3580 if (wnd->icon().isNull()) {
3581 static QIcon defaultIcon;
3582 if (defaultIcon.isNull()) {
3583 const QImage defaultIconImage = QImage::fromHICON(LoadIcon(0, IDI_APPLICATION));
3584 defaultIcon = QIcon(QPixmap::fromImage(defaultIconImage));
3586 defaultIcon.paint(&p, iconRect);
3588 wnd->icon().paint(&p, iconRect);
3590 titleRect.adjust(factor * 24, 0, 0, 0);
3594 titleFont.setPointSize(factor * 9);
3595 titleFont.setWeight(QFont::Thin);
3596 titleFont.setHintingPreference(QFont::PreferFullHinting);
3597 p.setFont(titleFont);
3598 const QString title = wnd->title().isEmpty() ? qApp->applicationName() : wnd->title();
3599 p.drawText(titleRect, title, QTextOption(Qt::AlignVCenter));
3603 const QString assetFontName = isWindows11orAbove ? QStringLiteral(
"Segoe Fluent Icons") : QStringLiteral(
"Segoe MDL2 Assets");
3604 QFont assetFont = QFont(assetFontName, factor * 7);
3605 assetFont.setWeight(QFont::Thin);
3606 assetFont.setHintingPreference(QFont::PreferFullHinting);
3607 p.setFont(assetFont);
3608 p.setBrush(closeButtonBrush);
3609 p.setPen(Qt::NoPen);
3610 if (wnd->flags().testFlags(Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3613 rect.setX(windowWidth - titleButtonWidth * buttons);
3614 rect.setWidth(titleButtonWidth);
3615 rect.setHeight(titleBarHeight);
3616 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3617 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3618 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3620 const QPen closeButtonHoveredPen = QPen(QColor(0xFF, 0xFF, 0xFD, 0xFF));
3621 p.setPen(closeButtonHoveredPen);
3625 p.drawText(rect, QStringLiteral(
"\uE8BB"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3629 p.setBrush(minMaxButtonBrush);
3630 p.setPen(Qt::NoPen);
3631 if (wnd->flags().testFlags(Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3634 rect.setX(windowWidth - titleButtonWidth * buttons);
3635 rect.setWidth(titleButtonWidth);
3636 rect.setHeight(titleBarHeight);
3637 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3638 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3639 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3644 const QString maximizeGlyph = IsZoomed(m_data.hwnd) ? QStringLiteral(
"\uE923")
3645 : QStringLiteral(
"\uE922");
3646 p.drawText(rect, maximizeGlyph, QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3650 p.setBrush(minMaxButtonBrush);
3651 p.setPen(Qt::NoPen);
3652 if (wnd->flags().testFlags(Qt::WindowMinimizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3655 rect.setX(windowWidth - titleButtonWidth * buttons);
3656 rect.setWidth(titleButtonWidth);
3657 rect.setHeight(titleBarHeight);
3658 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3659 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3660 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3664 p.drawText(rect,QStringLiteral(
"\uE921"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3670 HBITMAP bmp = image.toHBITMAP();
3672 HDC hdc = GetDC(hwnd);
3674 HDC memdc = CreateCompatibleDC(hdc);
3675 HGDIOBJ original = SelectObject(memdc, bmp);
3678 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
3679 POINT ptLocation = { 0, 0 };
3680 SIZE szWnd = { windowWidth, titleBarHeight };
3681 POINT ptSrc = { 0, 0 };
3682 UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
3683 SelectObject(hdc, original);
3686 DeleteObject(memdc);
3687 ReleaseDC(hwnd,hdc);
3694 if (QScreen *screen = w->screen())
3695 if (
const QPlatformScreen *platformScreen = screen->handle())
3696 if (QPlatformCursor *cursor = platformScreen->cursor())
3697 return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
3698 return CursorHandlePtr(
new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
3707 if (underMouse == w)
3709 for (
const QWindow *p = underMouse; p ; p = p->parent()) {
3712 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p);
3713 if (platformWindow && !platformWindow->cursor()->isNull())
3721
3722
3723
3724
3734 if (m_cursor->isNull()) {
3735 if (
const QWindow *p = window()->parent()) {
3736 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p))
3739 SetCursor(defaultCursor(window())->handle());
3742 SetCursor(m_cursor->handle());
3750 bool changed = c->handle() != m_cursor->handle();
3758 const bool apply = applyNewCursor(window());
3759 qCDebug(lcQpaWindow) << window() <<
__FUNCTION__
3760 << c->handle() <<
" doApply=" << apply;
3783 UINT timeOutMs = GetCaretBlinkTime();
3784 if (!timeOutMs || timeOutMs == INFINITE)
3788 info.cbSize =
sizeof(info);
3789 info.hwnd = m_data.hwnd;
3790 info.dwFlags = FLASHW_TRAY;
3791 info.dwTimeout = timeOutMs;
3792 info.uCount = durationMs == 0 ? 10 : UINT(durationMs) / timeOutMs;
3793 FlashWindowEx(&info);
3799 info.cbSize =
sizeof(info);
3800 info.hwnd = m_data.hwnd;
3801 info.dwFlags = FLASHW_STOP;
3804 FlashWindowEx(&info);
3809 return (style() & WS_DISABLED) == 0;
3814 const unsigned oldStyle =
style();
3815 unsigned newStyle = oldStyle;
3817 newStyle &= ~WS_DISABLED;
3819 newStyle |= WS_DISABLED;
3821 if (newStyle != oldStyle)
3827 if (!icon.isNull()) {
3829 const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)), 1);
3831 return qt_pixmapToWinHICON(pm);
3841 m_iconSmall = createHIcon(icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
3842 m_iconBig = createHIcon(icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
3845 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3846 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconBig));
3848 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3849 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconSmall));
3856 return window()->isTopLevel() && !m_data.embedded;
3866 const BOOL darkBorder = d ? TRUE : FALSE;
3871 qCWarning(lcQpaWindow,
"%s: Unable to set %s window border.",
__FUNCTION__, d ?
"dark" :
"light");
3878 d = d && shouldApplyDarkFrame(window());
3880 setDarkBorderToWindow(m_data.hwnd, d);
3885 return m_menuBar.data();
3895 if (m_data.flags & Qt::FramelessWindowHint)
3897 return m_data.customMargins;
3901
3902
3903
3904
3905
3906
3907
3908
3912 if (m_data.flags & Qt::FramelessWindowHint) {
3913 qCWarning(lcQpaWindow) <<
"You should not set custom margins for a frameless window.";
3916 if (newCustomMargins != m_data.customMargins) {
3917 const QMargins oldCustomMargins = m_data.customMargins;
3918 m_data.customMargins = newCustomMargins;
3920 const QRect currentFrameGeometry = frameGeometry_sys();
3921 const QPoint topLeft = currentFrameGeometry.topLeft();
3922 QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
3923 newFrame.moveTo(topLeft);
3924 qCDebug(lcQpaWindow) <<
__FUNCTION__ << oldCustomMargins <<
"->" << newCustomMargins
3925 << currentFrameGeometry <<
"->" << newFrame;
3926 SetWindowPos(m_data.hwnd,
nullptr, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
3932#if QT_CONFIG(vulkan)
3933 Q_UNUSED(nativeConfig);
3935 if (window()->surfaceType() == QSurface::VulkanSurface) {
3937 QVulkanInstance *inst = window()->vulkanInstance();
3939 m_vkSurface =
static_cast<QWindowsVulkanInstance *>(inst->handle())->createSurface(handle());
3941 qWarning(
"Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
3945 return &m_vkSurface;
3947#elif defined(QT_NO_OPENGL)
3949 Q_UNUSED(nativeConfig);
3966#if QT_CONFIG(vulkan)
3968 QVulkanInstance *inst = window()->vulkanInstance();
3970 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
3971 m_vkSurface = VK_NULL_HANDLE;
3978 m_surface =
nullptr;
3991 const auto currentTouchTypes = touchWindowTouchTypes_sys();
3992 if (currentTouchTypes.has_value() && currentTouchTypes.value() == touchTypes)
3996 ULONG touchFlags = 0;
3997 if (touchTypes.testFlag(TouchWindowTouchType::FineTouch))
3998 touchFlags |= TWF_FINETOUCH;
3999 if (touchTypes.testFlag(TouchWindowTouchType::WantPalmTouch))
4000 touchFlags |= TWF_WANTPALM;
4001 if (RegisterTouchWindow(m_data.hwnd, touchFlags))
4004 qErrnoWarning(
"RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
4009 if (QPlatformWindow *handle = window->handle())
4010 static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border);
4017 m_borderInFullScreenDefault = border;
4034 if (m_windowState == Qt::WindowFullScreen) {
4035 LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE);
4039 style &= ~WS_BORDER;
4040 SetWindowLongPtr(handle(), GWL_STYLE, style);
4046 return QPlatformWindow::formatWindowTitle(title, QStringLiteral(
" - "));
4056 QWindow *w = window();
4057 QDxgiVSyncService *vs = QDxgiVSyncService::instance();
4058 if (vs->supportsWindow(w)) {
4059 if (m_vsyncServiceCallbackId == 0) {
4060 m_vsyncServiceCallbackId = vs->registerCallback([
this, w](
const QDxgiVSyncService::CallbackWindowList &windowList, qint64) {
4061 if (windowList.contains(w)) {
4066 if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) {
4067 QWindowsWindow *oldSelf =
this;
4068 qsizetype oldCallbackId = m_vsyncServiceCallbackId;
4069 QMetaObject::invokeMethod(w, [w, oldSelf, oldCallbackId] {
4071 auto *self =
static_cast<QWindowsWindow *>(w->handle());
4074 if (self && self == oldSelf && self->m_vsyncServiceCallbackId == oldCallbackId) {
4076 self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready);
4077 self->deliverUpdateRequest();
4084 m_vsyncUpdatePending.testAndSetRelease(UpdateState::Ready, UpdateState::Requested);
4086 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 * createWindowSurface(void *, void *, int *)
virtual void destroyWindowSurface(void *)
static QWindowsWindowClassRegistry * instance()
void alertWindow(int durationMs=0)
void setWindowFlags(Qt::WindowFlags flags) override
Requests setting the window flags of this surface to flags.
void setCustomMargins(const QMargins &m) override
Sets custom margins to be added to the default margins determined by the windows style in the handlin...
void setMenuBar(QWindowsMenuBar *mb)
void invalidateSurface() override
Invalidates the window's surface by releasing its surface buffers.
HDC getDC()
Allocates a HDC for the window or returns the temporary one obtained from WinAPI BeginPaint within a ...
QMargins fullFrameMargins() const override
void checkForScreenChanged(ScreenChangeMode mode=FromGeometryChange, const RECT *suggestedRect=nullptr)
void initialize() override
Called as part of QWindow::create(), after constructing the window.
void handleDpiChangedAfterParent(HWND hwnd)
void requestUpdate() override
Requests an QEvent::UpdateRequest event.
bool testFlag(unsigned f) const
void setFlag(unsigned f) const
void clearFlag(unsigned f) const
void setFrameStrutEventsEnabled(bool enabled) override
Reimplement this method to set whether frame strut events should be sent to enabled.
static void settingsChanged()
void getSizeHints(MINMAXINFO *mmi) const
static void setHasBorderInFullScreenDefault(bool border)
~QWindowsWindow() override
bool handleWmPaint(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
bool setMouseGrabEnabled(bool grab) override
void propagateSizeHints() override
Reimplement to propagate the size hints of the QWindow.
void applyCursor()
Applies to cursor property set on the window to the global cursor.
bool handleGeometryChanging(MSG *message) const
bool isActive() const override
Returns true if the window should appear active from a style perspective.
void setStyle(unsigned s) const
QString windowTitle() const override
Reimplement to return the actual window title used in the underlying windowing system unless the titl...
static void displayChanged()
bool setKeyboardGrabEnabled(bool grab) override
bool windowEvent(QEvent *event) override
Reimplement this method to be able to do any platform specific event handling.
void setGeometry(const QRect &rect) override
This function is called by Qt whenever a window is moved or resized using the QWindow API.
void setEnabled(bool enabled)
void setVisible(bool visible) override
Reimplemented in subclasses to show the surface if visible is true, and hide it if visible is false.
QSurfaceFormat format() const override
Returns the actual surface format of the window.
static const char * embeddedNativeParentHandleProperty
QWindowsMenuBar * menuBar() const
void handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
void registerTouchWindow()
QMargins frameMargins() const override
void setWindowIcon(const QIcon &icon) override
Reimplement to set the window icon to icon.
void handleResized(int wParam, LPARAM lParam)
void setOpacity(qreal level) override
Reimplement to be able to let Qt set the opacity level of a window.
bool isEmbedded() const override
Returns true if the window is a child of a non-Qt window.
QMargins customMargins() const override
bool handleNonClientActivate(LRESULT *result) const
QRect normalGeometry() const override
Returns the geometry of a window in 'normal' state (neither maximized, fullscreen nor minimized) for ...
void setExStyle(unsigned s) const
qreal dpiRelativeScale(const UINT dpi) const
QMargins safeAreaMargins() const override
The safe area margins of a window represent the area that is safe to place content within,...
void setSavedDpi(int dpi)
void requestActivateWindow() override
Reimplement to let Qt be able to request activation/focus for a window.
void handleDpiScaledSize(WPARAM wParam, LPARAM lParam, LRESULT *result)
void updateFullFrameMargins()
@ SynchronousGeometryChangeEvent
@ WithinSetParent
Automatic mouse capture on button press.
@ FrameStrutEventsEnabled
static const char * hasBorderInFullScreenProperty
bool startSystemMove() override
Reimplement this method to start a system move operation if the system supports it and return true to...
bool isTopLevel() const override
void releaseDC()
Releases the HDC for the window or does nothing in case it was obtained from WinAPI BeginPaint within...
void updateRestoreGeometry()
void setWindowState(Qt::WindowStates state) override
Requests setting the window state of this surface to type.
void setCursor(const CursorHandlePtr &c)
void updateCustomTitlebar()
bool hasBorderInFullScreen() const override
bool hasMouseCapture() const
void * surface(void *nativeConfig, int *err)
void setHasBorderInFullScreen(bool border) override
void handleCompositionSettingsChanged()
void setWindowTitle(const QString &title) override
Reimplement to set the window title to title.
void setDarkBorder(bool d)
bool startSystemResize(Qt::Edges edges) override
Reimplement this method to start a system resize operation if the system supports it and return true ...
void setFullFrameMargins(const QMargins &newMargins)
void setMask(const QRegion ®ion) override
Reimplement to be able to let Qt set the mask of a window.
void setAlertState(bool enabled) override
Reimplement this method to set whether the window demands attention (for example, by flashing the tas...
bool isAlertState() const override
Reimplement this method return whether the window is in an alert state.
Combined button and popup list for selecting options.
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)