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;
637 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint
638 |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
642 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
647 if ((flags & Qt::WindowType_Mask) == Qt::SplashScreen)
648 flags |= Qt::FramelessWindowHint;
653 const auto getDeviceName = [](
const QScreen *screen) -> QString {
654 if (
const auto s =
static_cast<
const QWindowsScreen *>(screen->handle()))
655 return s->data().deviceName;
658 QScreen *winScreen = w ? w->screen() : QGuiApplication::primaryScreen();
659 if (winScreen && getDeviceName(winScreen) != name) {
660 const auto screens = winScreen->virtualSiblings();
661 for (QScreen *screen : screens) {
662 if (getDeviceName(screen) == name)
669static QPoint calcPosition(
const QWindow *w,
const QWindowCreationContextPtr &context,
const QMargins &invMargins)
671 const QPoint orgPos(context->frameX - invMargins.left(), context->frameY - invMargins.top());
673 if (!w || w->type() != Qt::Window)
677 const QScreen *screenForGL = QWindowsWindow::forcedScreenForGLWindow(w);
681 const QPoint posFrame(context->frameX, context->frameY);
682 const QMargins margins = context->margins;
683 const QRect scrGeo = screenForGL->handle()->availableGeometry();
686 if (scrGeo.contains(orgPos))
691 if (scrGeo.contains(posFrame))
695 const auto screens = screenForGL->virtualSiblings();
696 const QScreen *orgScreen =
nullptr;
697 for (QScreen *screen : screens) {
698 if (screen->handle()->availableGeometry().contains(posFrame)) {
703 const QPoint ctPos = QPoint(qMax(scrGeo.left(), scrGeo.center().x()
704 + (margins.right() - margins.left() - context->frameWidth)/2),
705 qMax(scrGeo.top(), scrGeo.center().y()
706 + (margins.bottom() - margins.top() - context->frameHeight)/2));
712 const QRect orgGeo = orgScreen->handle()->availableGeometry();
713 const QRect orgFrame(
QPoint(context->frameX, context->frameY),
714 QSize(context->frameWidth, context->frameHeight));
717 if (orgGeo.center() == (orgFrame - margins).center())
721 const QPoint newPos(scrGeo.left() + ((posFrame.x() - orgGeo.left()) * scrGeo.width()) / orgGeo.width(),
722 scrGeo.top() + ((posFrame.y() - orgGeo.top()) * scrGeo.height()) / orgGeo.height());
723 const QPoint newPosNoMargin(newPos.x() - invMargins.left(), newPos.y() - invMargins.top());
725 return scrGeo.contains(newPosNoMargin) ? newPosNoMargin : newPos;
729 unsigned creationFlags)
736 QVariant prop = w->property(QWindowsWindow::embeddedNativeParentHandleProperty);
737 if (prop.isValid()) {
739 parentHandle =
reinterpret_cast<HWND>(prop.value<WId>());
753 fixTopLevelWindowFlags(flags);
755 type =
static_cast<Qt::WindowType>(
int(flags) & Qt::WindowType_Mask);
771 if ((flags & Qt::MSWindowsFixedSizeDialogHint))
780 if (QGuiApplication::layoutDirection() == Qt::RightToLeft
781 && (QWindowsIntegration::instance()->options() & QWindowsIntegration::RtlEnabled) != 0) {
782 exStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
787 flags |= Qt::WindowStaysOnTopHint;
789 if (
const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
790 parentHandle = QWindowsWindow::handleOf(parentWindow);
793 if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
796 if (flags & Qt::FramelessWindowHint)
798 else if (flags & Qt::WindowTitleHint)
799 style = WS_OVERLAPPED;
806 style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
808 if (flags & Qt::WindowDoesNotAcceptFocus)
809 exStyle |= WS_EX_NOACTIVATE;
812 if ((type == Qt::Window || dialog || tool)) {
813 if (!(flags & Qt::FramelessWindowHint)) {
815 if (flags & Qt::MSWindowsFixedSizeDialogHint) {
816 style |= WS_DLGFRAME;
818 style |= WS_THICKFRAME;
820 if (flags & Qt::WindowTitleHint)
823 if (flags & Qt::WindowSystemMenuHint)
825 else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
826 style |= WS_SYSMENU | WS_BORDER;
827 exStyle |= WS_EX_DLGMODALFRAME;
829 const bool showMinimizeButton = flags & Qt::WindowMinimizeButtonHint;
830 if (showMinimizeButton)
831 style |= WS_MINIMIZEBOX;
832 const bool showMaximizeButton = shouldShowMaximizeButton(w, flags);
833 if (showMaximizeButton)
834 style |= WS_MAXIMIZEBOX;
835 if (showMinimizeButton || showMaximizeButton)
838 exStyle |= WS_EX_TOOLWINDOW;
839 if ((flags & Qt::WindowContextHelpButtonHint) && !showMinimizeButton
840 && !showMaximizeButton)
841 exStyle |= WS_EX_CONTEXTHELP;
843 exStyle |= WS_EX_TOOLWINDOW;
848 if (flagsIn & Qt::WindowTransparentForInput)
849 exStyle |= WS_EX_TRANSPARENT;
852 if (qEnvironmentVariableIntValue(
"QT_QPA_DISABLE_REDIRECTION_SURFACE"))
853 exStyle |= WS_EX_NOREDIRECTIONBITMAP;
859 if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
868 auto *dWindow = QWindowPrivate::get(
const_cast<QWindow*>(w));
869 const QPalette windowPal = dWindow->windowPalette();
870 return windowPal.color(QPalette::WindowText).lightness()
871 > windowPal.color(QPalette::Window).lightness();
877 return getResizeBorderThickness(dpi) +
878 ::GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
885 result.flags = flags;
887 const auto appinst =
reinterpret_cast<HINSTANCE>(GetModuleHandle(
nullptr));
892 windowTitlebarDescription.name =
"_q_titlebar"_L1;
893 windowTitlebarDescription.style = CS_VREDRAW | CS_HREDRAW;
897 const QScreen *screen{};
898 const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
899 defaultWindowWidth, defaultWindowHeight,
902 if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
903 title =
topLevel ? qAppName() : w->objectName();
905 const auto *titleUtf16 =
reinterpret_cast<
const wchar_t *>(title.utf16());
906 const auto *classNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowClassName.utf16());
907 const auto *classTitleBarNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowTitlebarName.utf16());
912 rect, data.customMargins,
916 const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME))
917 && !(result.flags & Qt::FramelessWindowHint);
918 QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w)
919 ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();
921 qCDebug(lcQpaWindow).nospace()
922 <<
"CreateWindowEx: " << w <<
" class=" << windowClassName <<
" title=" << title
923 <<
'\n' << *
this <<
"\nrequested: " << rect <<
": "
924 << context->frameWidth <<
'x' << context->frameHeight
925 <<
'+' << context->frameX <<
'+' << context->frameY
926 <<
" custom margins: " << context->customMargins
927 <<
" invisible margins: " << invMargins;
930 QPoint pos = calcPosition(w, context, invMargins);
933 int mirrorParentWidth = 0;
934 if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) {
936 GetClientRect(parentHandle, &rect);
937 mirrorParentWidth = rect.right;
939 if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT)
940 pos.setX(mirrorParentWidth - context->frameWidth - pos.x());
942 result.hwnd = CreateWindowEx(
exStyle, classNameUtf16, titleUtf16,
945 context->frameWidth, context->frameHeight,
946 parentHandle,
nullptr, appinst,
nullptr);
948 const UINT dpi = ::GetDpiForWindow(result.hwnd);
949 const int titleBarHeight = getTitleBarHeight_sys(dpi);
950 result.hwndTitlebar = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,
951 classTitleBarNameUtf16, classTitleBarNameUtf16,
953 context->frameWidth, titleBarHeight,
954 nullptr,
nullptr, appinst,
nullptr);
956 qCDebug(lcQpaWindow).nospace()
957 <<
"CreateWindowEx: returns " << w <<
' ' << result.hwnd <<
" obtained geometry: "
958 << context->obtainedPos << context->obtainedSize <<
' ' << context->margins;
961 qErrnoWarning(
"%s: CreateWindowEx failed",
__FUNCTION__);
965 if (QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark && shouldApplyDarkFrame(w))
966 QWindowsWindow::setDarkBorderToWindow(result.hwnd,
true);
968 if (mirrorParentWidth != 0) {
969 context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
970 - context->obtainedPos.x());
973 QRect obtainedGeometry(context->obtainedPos, context->obtainedSize);
975 result.geometry = obtainedGeometry;
976 result.restoreGeometry = frameGeometry(result.hwnd, topLevel);
977 result.fullFrameMargins = context->margins;
980 result.customMargins = context->customMargins;
988 const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
989 const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
991 const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
992 if (oldStyle != newStyle)
993 SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
994 const LONG_PTR newExStyle =
exStyle;
995 if (newExStyle != oldExStyle)
996 SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
997 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << hwnd << *
this
998 <<
"\n Style from " << debugWinStyle(DWORD(oldStyle)) <<
"\n to "
999 << debugWinStyle(DWORD(newStyle)) <<
"\n ExStyle from "
1000 << debugWinExStyle(DWORD(oldExStyle)) <<
" to "
1001 << debugWinExStyle(DWORD(newExStyle));
1008 UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER;
1010 swpFlags |= SWP_FRAMECHANGED;
1012 swpFlags |= SWP_NOACTIVATE;
1013 if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
1014 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, swpFlags);
1015 if (flags & Qt::WindowStaysOnBottomHint)
1016 qWarning(
"QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time");
1017 }
else if (flags & Qt::WindowStaysOnBottomHint) {
1018 SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, swpFlags);
1019 }
else if (frameChange) {
1020 SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, swpFlags);
1022 if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
1023 HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
1024 if (flags & Qt::WindowCloseButtonHint)
1025 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
1027 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
1029 if (flags & Qt::ExpandedClientAreaHint) {
1030 MARGINS margins = { -1, -1, -1, -1 };
1031 DwmExtendFrameIntoClientArea(hwnd, &margins);
1033 MARGINS margins = { 0, 0, 0, 0 };
1034 DwmExtendFrameIntoClientArea(hwnd, &margins);
1037 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
1041 const bool hasAlpha = w->format().hasAlpha();
1042 if (isAccelerated && hasAlpha)
1043 applyBlurBehindWindow(hwnd);
1044 setWindowOpacity(hwnd, flags, hasAlpha, isAccelerated, opacityLevel);
1051 if (QHighDpiScaling::isActive()) {
1052 const qreal factor = QHighDpiScaling::factor(s);
1053 if (!qFuzzyCompare(factor, qreal(1))) {
1054 if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
1055 dip.setWidth(qRound(qreal(dip.width()) * factor));
1056 if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX)
1057 dip.setHeight(qRound(qreal(dip.height()) * factor));
1067 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1074 DWORD style = hwnd !=
nullptr ? DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)) : 0;
1075 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1079
1080
1081
1082
1083
1084
1085
1086
1090 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1092 RECT rect = {0,0,0,0};
1093 style &= ~DWORD(WS_OVERLAPPED);
1094 if (AdjustWindowRectEx(&rect, style, FALSE, exStyle) == FALSE)
1095 qErrnoWarning(
"%s: AdjustWindowRectEx failed",
__FUNCTION__);
1096 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1097 qAbs(rect.right), qAbs(rect.bottom));
1098 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1099 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1100 <<
' ' << rect <<
' ' << result;
1106 return frameOnPrimaryScreen(w, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1107 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1112 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1114 RECT rect = {0,0,0,0};
1115 style &= ~DWORD(WS_OVERLAPPED);
1116 if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
unsigned(qRound(dpi))) == FALSE) {
1117 qErrnoWarning(
"%s: AdjustWindowRectExForDpi failed",
__FUNCTION__);
1119 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1120 qAbs(rect.right), qAbs(rect.bottom));
1121 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1122 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1124 <<
' ' << rect <<
' ' << result;
1130 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1132 if (QWindowsScreenManager::isSingleScreen())
1133 return frameOnPrimaryScreen(w, style, exStyle);
1135 auto screen = screenManager.screenForHwnd(hwnd);
1137 screen = screenManager.screens().value(0);
1138 const auto dpi = screen ? screen->logicalDpi().first : qreal(96);
1139 return frame(w, style, exStyle, dpi);
1144 return frame(w, hwnd, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1145 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1150 DWORD style, DWORD exStyle)
1152 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1155 || !QWindowsContext::shouldHaveNonClientDpiScaling(w)) {
1156 return frameOnPrimaryScreen(w, style, exStyle);
1162 screen = screenManager.screens().value(0);
1164 dpi = screen->logicalDpi().first;
1165 return QWindowsGeometryHint::frame(w, style, exStyle, dpi);
1168bool QWindowsGeometryHint::handleCalculateSize(
const QWindow *window,
const QMargins &customMargins,
const MSG &msg, LRESULT *result)
1171 if (msg.wParam && window->flags() & Qt::FramelessWindowHint) {
1175 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window);
1177 const bool clientAreaExpanded = platformWindow !=
nullptr ? platformWindow->isClientAreaExpanded() : window->flags() & Qt::ExpandedClientAreaHint;
1179 if (msg.wParam && clientAreaExpanded) {
1181 const bool maximized = IsZoomed(msg.hwnd) && window->visibility() != QWindow::FullScreen;
1182 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1183 RECT *clientArea = &ncp->rgrc[0];
1184 const int border = getResizeBorderThickness(96);
1186 clientArea->top += border;
1187 clientArea->bottom -= border;
1188 clientArea->left += border;
1189 clientArea->right -= border;
1194 if (!msg.wParam || customMargins.isNull())
1196 *result = DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1197 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1198 const RECT oldClientArea = ncp->rgrc[0];
1199 ncp->rgrc[0].left += customMargins.left();
1200 ncp->rgrc[0].top += customMargins.top();
1201 ncp->rgrc[0].right -= customMargins.right();
1202 ncp->rgrc[0].bottom -= customMargins.bottom();
1204 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << oldClientArea <<
'+' << customMargins <<
"-->"
1205 << ncp->rgrc[0] <<
' ' << ncp->rgrc[1] <<
' ' << ncp->rgrc[2]
1206 <<
' ' << ncp->lppos->cx <<
',' << ncp->lppos->cy;
1211 const QMargins &margins,
1212 QSize *minimumSize, QSize *maximumSize)
1214 *minimumSize = toNativeSizeConstrained(w->minimumSize(), screen);
1215 *maximumSize = toNativeSizeConstrained(w->maximumSize(), screen);
1217 const int maximumWidth = qMax(maximumSize->width(), minimumSize->width());
1218 const int maximumHeight = qMax(maximumSize->height(), minimumSize->height());
1219 const int frameWidth = margins.left() + margins.right();
1220 const int frameHeight = margins.top() + margins.bottom();
1222 if (minimumSize->width() > 0)
1223 minimumSize->rwidth() += frameWidth;
1224 if (minimumSize->height() > 0)
1225 minimumSize->rheight() += frameHeight;
1226 if (maximumWidth < QWINDOWSIZE_MAX)
1227 maximumSize->setWidth(maximumWidth + frameWidth);
1228 if (maximumHeight < QWINDOWSIZE_MAX)
1229 maximumSize->setHeight(maximumHeight + frameHeight);
1233 const QScreen *screen,
1234 const QMargins &margins,
1239 frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize);
1240 qCDebug(lcQpaWindow).nospace() <<
'>' <<
__FUNCTION__ <<
'<' <<
" min="
1241 << minimumSize.width() <<
',' << minimumSize.height()
1242 <<
" max=" << maximumSize.width() <<
',' << maximumSize.height()
1243 <<
" margins=" << margins
1246 if (minimumSize.width() > 0)
1247 mmi->ptMinTrackSize.x = minimumSize.width();
1248 if (minimumSize.height() > 0)
1249 mmi->ptMinTrackSize.y = minimumSize.height();
1251 if (maximumSize.width() < QWINDOWSIZE_MAX)
1252 mmi->ptMaxTrackSize.x = maximumSize.width();
1253 if (maximumSize.height() < QWINDOWSIZE_MAX)
1254 mmi->ptMaxTrackSize.y = maximumSize.height();
1255 qCDebug(lcQpaWindow).nospace() <<
'<' <<
__FUNCTION__ <<
" out " << *mmi;
1259 const QMargins &margins,
1262 applyToMinMaxInfo(w, w->screen(), margins, mmi);
1267 return qt_window_private(
const_cast<QWindow *>(w))->positionPolicy
1268 == QWindowPrivate::WindowFrameInclusive;
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1290 return (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0;
1296 if (QPlatformWindow *pw = w->handle())
1297 return static_cast<QWindowsBaseWindow *>(pw);
1305 return bw ? bw->handle() : HWND(
nullptr);
1310 const HWND parent = parentHwnd();
1311 return !parent || parent == GetDesktopWindow();
1316 return frameGeometry(handle(), isTopLevel());
1321 return frameGeometry_sys().marginsRemoved(fullFrameMargins());
1326 return QWindowsGeometryHint::frame(window(), handle(), style(), exStyle());
1332 ULONG touchFlags = 0;
1333 if (IsTouchWindow(handle(), &touchFlags) == FALSE)
1335 TouchWindowTouchTypes result;
1336 if ((touchFlags & TWF_FINETOUCH) != 0)
1337 result.setFlag(TouchWindowTouchType::FineTouch);
1338 if ((touchFlags & TWF_WANTPALM) != 0)
1339 result.setFlag(TouchWindowTouchType::WantPalmTouch);
1345 SetWindowPos(handle(),
nullptr , 0, 0, 0, 0,
1346 SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1351 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1352 const Qt::WindowType type = window()->type();
1353 if (type == Qt::Popup
1354 || type == Qt::SubWindow
1355 || !(window()->flags() & Qt::WindowStaysOnBottomHint)) {
1356 SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1362 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1363 if (!(window()->flags() & Qt::WindowStaysOnTopHint))
1364 SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1369 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << title;
1370 SetWindowText(handle(),
reinterpret_cast<
const wchar_t *>(title.utf16()));
1375 return QWindowsGeometryHint::mapToGlobal(handle(), pos);
1380 return QWindowsGeometryHint::mapFromGlobal(handle(), pos);
1406 switch (event->type()) {
1407 case QEvent::ChildWindowAdded:
1408 if (!(GetWindowLongPtr(handle(), GWL_STYLE) & WS_CLIPCHILDREN)) {
1409 auto *childWindowEvent =
static_cast<QChildWindowEvent*>(event);
1410 qWarning() << childWindowEvent->child() <<
"added as child to"
1411 << window() <<
"which does not have WS_CLIPCHILDREN set."
1412 <<
"This will result in drawing artifacts!";
1419 return QPlatformWindow::windowEvent(event);
1423
1424
1425
1426
1427
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1444 , m_topLevelStyle(0)
1446 if (QPlatformWindow::parent())
1447 setParent(QPlatformWindow::parent());
1452 if (QPlatformWindow::parent())
1459 const HWND newParent = newParentWindow ?
reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(
nullptr);
1460 const bool isTopLevel = !newParent;
1461 const DWORD oldStyle =
style();
1463 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() <<
"newParent="
1464 << newParentWindow << newParent <<
"oldStyle=" << debugWinStyle(oldStyle);
1466 auto updateWindowFlags = [&] {
1468 DWORD newStyle = oldStyle;
1470 newStyle = m_topLevelStyle;
1472 m_topLevelStyle = oldStyle;
1473 newStyle &= ~(WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW);
1474 newStyle |= WS_CHILD;
1476 SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
1479 if (wasTopLevel && !isTopLevel) {
1482 updateWindowFlags();
1485 SetParent(m_hwnd, newParent);
1487 if (!wasTopLevel && isTopLevel) {
1490 updateWindowFlags();
1496 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << visible;
1498 ShowWindow(handle(), SW_SHOWNOACTIVATE);
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1524 const QRect &geometryIn,
const QRect &geometry,
1526 DWORD style, DWORD exStyle) :
1529 requestedGeometryIn(geometryIn),
1530 requestedGeometry(geometry),
1531 obtainedPos(geometryIn.topLeft()),
1532 obtainedSize(geometryIn.size()),
1533 margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle))
1540 if (!(w->flags() & Qt::FramelessWindowHint))
1543 if (geometry.isValid()
1544 || !qt_window_private(
const_cast<QWindow *>(w))->resizeAutomatic) {
1545 frameX = geometry.x();
1546 frameY = geometry.y();
1547 const QMargins effectiveMargins = margins + customMargins;
1548 frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right();
1549 frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom();
1552 frameHeight += menuHeight;
1554 const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel();
1555 if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) {
1556 frameX -= effectiveMargins.left();
1557 frameY -= effectiveMargins.top();
1561 qCDebug(lcQpaWindow).nospace()
1562 <<
__FUNCTION__ <<
' ' << w <<
' ' << geometry
1563 <<
" pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w)
1564 <<
" frame=" << frameWidth <<
'x' << frameHeight <<
'+'
1565 << frameX <<
'+' << frameY
1566 <<
" margins=" << margins <<
" custom margins=" << customMargins;
1571 QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi);
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1603 m_cursor(
new CursorHandle)
1604#if QT_CONFIG(vulkan)
1605 , m_vkSurface(VK_NULL_HANDLE)
1610 if (aWindow->flags().testFlags(Qt::ExpandedClientAreaHint)) {
1611 SetParent(m_data.hwndTitlebar, m_data.hwnd);
1612 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
1615 if (aWindow->surfaceType() == QWindow::Direct3DSurface)
1617#if QT_CONFIG(opengl)
1618 if (aWindow->surfaceType() == QWindow::OpenGLSurface)
1619 setFlag(OpenGLSurface);
1621#if QT_CONFIG(vulkan)
1622 if (aWindow->surfaceType() == QSurface::VulkanSurface)
1623 setFlag(VulkanSurface);
1625 updateDropSite(window()->isTopLevel());
1629 if (!touchWindowTouchTypes_sys().has_value())
1632 const qreal opacity = qt_window_private(aWindow)->opacity;
1633 if (!qFuzzyCompare(opacity, qreal(1.0)))
1634 setOpacity(opacity);
1636 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
1638 if (aWindow->isTopLevel())
1639 setWindowIcon(aWindow->icon());
1647 if (m_vsyncServiceCallbackId != 0)
1648 QDxgiVSyncService::instance()->unregisterCallback(m_vsyncServiceCallbackId);
1650 QWindowsThemeCache::clearThemeCache(m_data.hwnd);
1652 UnregisterTouchWindow(m_data.hwnd);
1660 QWindowCreationContextPtr creationContext =
1663 QWindow *w = window();
1664 setWindowState(w->windowStates());
1668 const Qt::WindowState state = w->windowState();
1669 const QRect obtainedGeometry(creationContext->obtainedPos, creationContext->obtainedSize);
1670 QPlatformScreen *obtainedScreen = screenForGeometry(obtainedGeometry);
1671 if (obtainedScreen && screen() != obtainedScreen)
1672 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(w, obtainedScreen->screen());
1673 if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen
1674 && creationContext->requestedGeometryIn != obtainedGeometry) {
1675 QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
1682 return window()->requestedFormat();
1685void QWindowsWindow::fireExpose(
const QRegion ®ion,
bool force)
1687 if (region.isEmpty() && !force)
1691 QWindowSystemInterface::handleExposeEvent(window(), region);
1696 fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), force);
1701 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << m_data.hwnd;
1705 const auto tlw = QGuiApplication::topLevelWindows();
1706 for (QWindow *w : tlw) {
1707 if (w->transientParent() == window()) {
1708 if (QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(w))
1709 tw->updateTransientParent();
1713 if (context->windowUnderMouse() == window())
1717 setDropSiteEnabled(
false);
1718#if QT_CONFIG(vulkan)
1720 QVulkanInstance *inst = window()->vulkanInstance();
1722 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
1723 m_vkSurface = VK_NULL_HANDLE;
1730 m_surface =
nullptr;
1733 DestroyWindow(m_data.hwndTitlebar);
1734 DestroyWindow(m_data.hwnd);
1735 context->removeWindow(m_data.hwnd);
1736 m_data.hwndTitlebar =
nullptr;
1737 m_data.hwnd =
nullptr;
1743 bool enabled =
false;
1744 bool parentIsEmbedded =
false;
1749 const QWindow *parent = window()->parent();
1750 if (parent && parent->handle() && parent->handle()->isForeignWindow())
1751 parentIsEmbedded =
true;
1754 if (topLevel || parentIsEmbedded) {
1755 switch (window()->type()) {
1768 setDropSiteEnabled(enabled);
1773 if (isDropSiteEnabled() == dropEnabled)
1775 qCDebug(lcQpaMime) <<
__FUNCTION__ << window() << dropEnabled;
1776#if QT_CONFIG(clipboard) && QT_CONFIG(draganddrop)
1778 Q_ASSERT(m_data.hwnd);
1779 m_dropTarget =
new QWindowsOleDropTarget(window());
1780 RegisterDragDrop(m_data.hwnd, m_dropTarget);
1781 CoLockObjectExternal(m_dropTarget,
true,
true);
1783 CoLockObjectExternal(m_dropTarget,
false,
true);
1784 m_dropTarget->Release();
1785 RevokeDragDrop(m_data.hwnd);
1786 m_dropTarget =
nullptr;
1795 m_screenForGLInitialized =
false;
1800 m_screenForGLInitialized =
false;
1805 static QString forceToScreen;
1806 if (!m_screenForGLInitialized) {
1808 m_screenForGLInitialized =
true;
1810 return forceToScreen.isEmpty() ?
nullptr : screenForDeviceName(w, forceToScreen);
1817 while (QWindow *parent = w->parent())
1820 if (
const QPlatformWindow *handle = w->handle()) {
1821 const auto *ww =
static_cast<
const QWindowsWindow *>(handle);
1822 if (ww->isEmbedded()) {
1823 HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
1824 const HWND desktopHwnd = GetDesktopWindow();
1826 while (parentHWND && parentHWND != desktopHwnd) {
1827 if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
1828 return topLevelOf(ancestor->window());
1829 parentHWND = GetAncestor(parentHWND, GA_PARENT);
1839 const QString &title)
1842 creationData.fromWindow(w, parameters.flags);
1845 creationData.initialize(w, result.hwnd, !parameters.customMargins.isNull(), 1);
1851 const QWindow *win = window();
1852 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << win << m_data.hwnd << visible;
1865 if (win->type() == Qt::Popup && !win->parent() && !QGuiApplication::focusWindow())
1866 SetForegroundWindow(m_data.hwnd);
1870 if (window()->flags() & Qt::Popup)
1871 ShowWindow(m_data.hwnd, SW_HIDE);
1874 fireExpose(QRegion());
1881 return m_data.hwnd && IsWindowVisible(m_data.hwnd);
1887 if (
const HWND activeHwnd = GetForegroundWindow())
1888 if (m_data.hwnd == activeHwnd || IsChild(activeHwnd, m_data.hwnd))
1895 const auto *childWindow =
static_cast<
const QWindowsWindow *>(child);
1896 return IsChild(m_data.hwnd, childWindow->handle());
1901 return m_data.embedded;
1906 return m_data.hwnd ? QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos) : pos;
1911 return m_data.hwnd ? QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos) : pos;
1921 if (window()->type() == Qt::Popup)
1924 const HWND oldTransientParent = GetWindow(m_data.hwnd, GW_OWNER);
1925 HWND newTransientParent =
nullptr;
1926 if (
const QWindow *tp = window()->transientParent()) {
1927 if (
const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp)) {
1929 newTransientParent = tw->handle();
1932 newTransientParent = tbw->handle();
1938 while (newTransientParent && (GetWindowLongPtr(newTransientParent, GWL_STYLE) & WS_CHILD) != 0)
1939 newTransientParent = GetParent(newTransientParent);
1941 if (newTransientParent != oldTransientParent)
1942 SetWindowLongPtr(m_data.hwnd,
GWL_HWNDPARENT, LONG_PTR(newTransientParent));
1948 const QVariant showWithoutActivating = window->property(
"_q_showWithoutActivating");
1949 return showWithoutActivating.isValid() && showWithoutActivating.toBool();
1954 WINDOWPLACEMENT windowPlacement;
1955 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1956 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1957 windowPlacement.showCmd = SW_SHOWMINIMIZED;
1958 windowPlacement.rcNormalPosition = RECTfromQRect(r);
1959 SetWindowPlacement(hwnd, &windowPlacement);
1966 WINDOWPLACEMENT windowPlacement;
1967 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1968 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1970 windowPlacement.flags |= WPF_RESTORETOMAXIMIZED;
1972 windowPlacement.flags &= ~WPF_RESTORETOMAXIMIZED;
1973 SetWindowPlacement(hwnd, &windowPlacement);
1980 int sm = SW_SHOWNORMAL;
1981 bool fakedMaximize =
false;
1982 bool restoreMaximize =
false;
1983 const QWindow *w = window();
1984 const Qt::WindowFlags flags = w->flags();
1985 const Qt::WindowType type = w->type();
1986 if (w->isTopLevel()) {
1987 const Qt::WindowStates state = w->windowStates();
1988 if (state & Qt::WindowMinimized) {
1989 sm = SW_SHOWMINIMIZED;
1991 sm = SW_SHOWMINNOACTIVE;
1992 if (state & Qt::WindowMaximized)
1993 restoreMaximize =
true;
1995 updateTransientParent();
1996 if (state & Qt::WindowMaximized) {
1997 sm = SW_SHOWMAXIMIZED;
2003 if (flags & Qt::WindowTitleHint &&
2004 !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
2005 fakedMaximize = TRUE;
2006 setStyle(style() | WS_MAXIMIZEBOX);
2011 if (type == Qt::Popup ||
2012 type == Qt::ToolTip ||
2014 (flags & Qt::WindowDoesNotAcceptFocus) ||
2015 testShowWithoutActivating(w))
2016 sm = SW_SHOWNOACTIVATE;
2018 if (w->windowStates() & Qt::WindowMaximized)
2021 ShowWindow(m_data.hwnd, sm);
2025 if (fakedMaximize) {
2026 setStyle(style() & ~WS_MAXIMIZEBOX);
2027 SetWindowPos(m_data.hwnd,
nullptr, 0, 0, 0, 0,
2028 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
2029 | SWP_FRAMECHANGED);
2031 if (restoreMaximize)
2032 setRestoreMaximizedFlag(m_data.hwnd);
2037 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << newParent;
2040 setParent_sys(newParent);
2046 HWND oldParentHWND = parentHwnd();
2047 HWND newParentHWND =
nullptr;
2049 const auto *parentW =
static_cast<
const QWindowsWindow *>(parent);
2050 newParentHWND = parentW->handle();
2055 HWND desktopHwnd = GetDesktopWindow();
2056 if (oldParentHWND == desktopHwnd)
2057 oldParentHWND =
nullptr;
2058 if (newParentHWND == desktopHwnd)
2059 newParentHWND =
nullptr;
2061 if (newParentHWND != oldParentHWND) {
2062 const bool wasTopLevel = oldParentHWND ==
nullptr;
2063 const bool isTopLevel = newParentHWND ==
nullptr;
2066 SetParent(m_data.hwnd, newParentHWND);
2072 if (wasTopLevel != isTopLevel) {
2073 setDropSiteEnabled(
false);
2074 setWindowFlags_sys(window()->flags(),
unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
2075 updateDropSite(isTopLevel);
2082 fireExpose(QRegion());
2087 const QWindow *w = window();
2089 applyBlurBehindWindow(handle());
2094 return QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) /
2095 QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi);
2105 const UINT dpi = UINT(wParam);
2106 const qreal scale = dpiRelativeScale(dpi);
2107 const QMargins margins = fullFrameMargins();
2108 if (!(m_data.flags & Qt::FramelessWindowHint)) {
2114 m_data.customMargins *= scale;
2117 const QSize windowSize = (geometry().size() * scale).grownBy((margins * scale) + customMargins());
2118 SIZE *size =
reinterpret_cast<SIZE *>(lParam);
2119 size->cx = windowSize.width();
2120 size->cy = windowSize.height();
2126 const UINT dpi = HIWORD(wParam);
2127 const qreal scale = dpiRelativeScale(dpi);
2130 QWindowsThemeCache::clearThemeCache(hwnd);
2133 const auto prcNewWindow =
reinterpret_cast<
const RECT *>(lParam);
2134 checkForScreenChanged(QWindowsWindow::FromDpiChange, !m_inSetgeometry ? prcNewWindow :
nullptr);
2136 if (!IsZoomed(hwnd))
2137 m_data.restoreGeometry.setSize(m_data.restoreGeometry.size() * scale);
2155 if (!m_inSetgeometry) {
2157 SetWindowPos(hwnd,
nullptr, prcNewWindow->left, prcNewWindow->top,
2158 prcNewWindow->right - prcNewWindow->left,
2159 prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
2163 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2164 handleGeometryChange();
2169 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
2174 const UINT dpi = GetDpiForWindow(hwnd);
2175 const qreal scale = dpiRelativeScale(dpi);
2178 checkForScreenChanged(QWindowsWindow::FromDpiChange);
2182 QRect currentGeometry = geometry();
2183 QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
2184 setGeometry(scaledGeometry);
2190 wp.length =
sizeof(WINDOWPLACEMENT);
2191 if (GetWindowPlacement(hwnd, &wp)) {
2192 const QRect result = qrectFromRECT(wp.rcNormalPosition);
2193 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
2201 const bool fakeFullScreen =
2202 m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen);
2203 const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
2204 const QMargins margins = fakeFullScreen
2205 ? QWindowsGeometryHint::frame(window(), handle(), m_savedStyle, 0)
2206 : fullFrameMargins();
2207 return frame.isValid() ? frame.marginsRemoved(margins) : frame;
2212 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
2213 const int titleBarHeight = getTitleBarHeight_sys(96);
2215 return QMargins(0, titleBarHeight, 0, 0);
2221 const QRect &requestedRect,
2222 const QRect &obtainedRect,
2223 const QMargins &fullMargins,
2224 const QMargins &customMargins)
2227 QDebug debug(&result);
2230 const auto window = platformWindow->window();
2231 debug <<
"Unable to set geometry ";
2232 formatBriefRectangle(debug, requestedRect);
2233 debug <<
" (frame: ";
2234 formatBriefRectangle(debug, requestedRect + fullMargins);
2235 debug <<
") on " << window->metaObject()->className() <<
"/\""
2236 << window->objectName() <<
"\" on \"" << window->screen()->name()
2237 <<
"\". Resulting geometry: ";
2238 formatBriefRectangle(debug, obtainedRect);
2239 debug <<
" (frame: ";
2240 formatBriefRectangle(debug, obtainedRect + fullMargins);
2241 debug <<
") margins: ";
2242 formatBriefMargins(debug, fullMargins);
2243 if (!customMargins.isNull()) {
2244 debug <<
" custom margin: ";
2245 formatBriefMargins(debug, customMargins);
2247 const auto minimumSize = window->minimumSize();
2248 const bool hasMinimumSize = !minimumSize.isEmpty();
2250 debug <<
" minimum size: " << minimumSize.width() <<
'x' << minimumSize.height();
2251 const auto maximumSize = window->maximumSize();
2252 const bool hasMaximumSize = maximumSize.width() != QWINDOWSIZE_MAX || maximumSize.height() != QWINDOWSIZE_MAX;
2254 debug <<
" maximum size: " << maximumSize.width() <<
'x' << maximumSize.height();
2255 if (hasMinimumSize || hasMaximumSize) {
2256 MINMAXINFO minmaxInfo;
2257 memset(&minmaxInfo, 0,
sizeof(minmaxInfo));
2258 platformWindow->getSizeHints(&minmaxInfo);
2259 debug <<
' ' << minmaxInfo;
2267 QScopedValueRollback b(m_inSetgeometry,
true);
2269 QRect rect = rectIn;
2272 if (QWindowsGeometryHint::positionIncludesFrame(window())) {
2273 const QMargins margins = frameMargins();
2274 rect.moveTopLeft(rect.topLeft() +
QPoint(margins.left(), margins.top()));
2276 if (m_windowState & Qt::WindowMinimized)
2277 m_data.geometry = rect;
2283 setGeometry_sys(rect);
2285 if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) {
2286 const auto warning =
2287 msgUnableToSetGeometry(
this, rectIn, m_data.geometry,
2288 fullFrameMargins(), customMargins());
2289 qWarning(
"%s: %s",
__FUNCTION__, qPrintable(warning));
2292 QPlatformWindow::setGeometry(rect);
2300 handleGeometryChange();
2306 if ((m_data.flags.testFlag(Qt::FramelessWindowHint)
2307 || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))
2308 && IsZoomed(m_data.hwnd)) {
2309 const int resizedWidth = LOWORD(lParam);
2310 const int resizedHeight = HIWORD(lParam);
2312 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTOPRIMARY);
2313 MONITORINFO monitorInfo = {};
2314 monitorInfo.cbSize =
sizeof(MONITORINFO);
2315 GetMonitorInfoW(monitor, &monitorInfo);
2317 int correctLeft = monitorInfo.rcMonitor.left;
2318 int correctTop = monitorInfo.rcMonitor.top;
2319 int correctWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
2320 int correctHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
2322 if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
2323 const int borderWidth = invisibleMargins(m_data.hwnd).left();
2324 correctLeft -= borderWidth;
2325 correctTop -= borderWidth;
2326 correctWidth += borderWidth * 2;
2327 correctHeight += borderWidth * 2;
2330 if (resizedWidth != correctWidth || resizedHeight != correctHeight) {
2331 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"correcting: " << resizedWidth <<
"x"
2332 << resizedHeight <<
" -> " << correctWidth <<
"x" << correctHeight;
2333 SetWindowPos(m_data.hwnd,
nullptr, correctLeft, correctTop, correctWidth, correctHeight,
2334 SWP_NOZORDER | SWP_NOACTIVATE);
2342 case SIZE_MINIMIZED:
2343 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2344 handleWindowStateChange(m_windowState | Qt::WindowMinimized);
2346 case SIZE_MAXIMIZED:
2347 handleGeometryChange();
2348 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2349 handleWindowStateChange(Qt::WindowMaximized | (isFullScreen_sys() ? Qt::WindowFullScreen
2350 : Qt::WindowNoState));
2353 handleGeometryChange();
2355 if (isFullScreen_sys())
2356 handleWindowStateChange(
2357 Qt::WindowFullScreen
2358 | (testFlag(MaximizeToFullScreen) ? Qt::WindowMaximized : Qt::WindowNoState));
2359 else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
2360 handleWindowStateChange(Qt::WindowNoState);
2366static inline bool equalDpi(
const QDpi &d1,
const QDpi &d2)
2368 return qFuzzyCompare(d1.first, d2.first) && qFuzzyCompare(d1.second, d2.second);
2376 QPlatformScreen *currentScreen = screen();
2377 auto topLevel = isTopLevel_sys() ? m_data.hwnd : GetAncestor(m_data.hwnd, GA_ROOT);
2382 if (newScreen ==
nullptr || newScreen == currentScreen)
2386 const bool changingDpi = !equalDpi(QDpi(savedDpi(), savedDpi()), newScreen->logicalDpi());
2390 qCDebug(lcQpaWindow).noquote().nospace() <<
__FUNCTION__
2391 <<
' ' << window() <<
" \"" << (currentScreen ? currentScreen->name() : QString())
2392 <<
"\"->\"" << newScreen->name() <<
'"';
2394 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
2399 const QRect previousGeometry = m_data.geometry;
2401 m_data.geometry = geometry_sys();
2402 QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
2407 && m_data.geometry.size() != previousGeometry.size()
2409 && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
2410 fireFullExpose(
true);
2414 checkForScreenChanged();
2416 if (testFlag(SynchronousGeometryChangeEvent))
2417 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2424 qCDebug(lcQpaEvents) <<
__FUNCTION__ <<
this << window() << m_data.geometry;
2426 if (m_data.flags & Qt::ExpandedClientAreaHint) {
2427 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
2428 MoveWindow(m_data.hwndTitlebar, 0, 0, m_data.geometry.width(), titleBarHeight,
true);
2434 const QMargins margins = fullFrameMargins();
2435 const QRect frameGeometry = rect + margins;
2437 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ << window()
2438 <<
"\n from " << geometry_sys() <<
" frame: "
2439 << margins <<
" to " <<rect
2440 <<
" new frame: " << frameGeometry;
2442 bool result =
false;
2443 const HWND hwnd = handle();
2444 WINDOWPLACEMENT windowPlacement;
2445 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2446 GetWindowPlacement(hwnd, &windowPlacement);
2449 if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(hwnd))
2450 || windowPlacement.showCmd == SW_SHOWMINIMIZED) {
2451 windowPlacement.rcNormalPosition =
2452 RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(hwnd, frameGeometry.topLeft())));
2453 windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
2454 result = SetWindowPlacement(hwnd, &windowPlacement);
2456 int x = frameGeometry.x();
2457 if (!window()->isTopLevel()) {
2458 const HWND parentHandle = GetParent(hwnd);
2459 if (isRtlLayout(parentHandle)) {
2461 GetClientRect(parentHandle, &rect);
2462 x = rect.right - frameGeometry.width() - x;
2465 result = MoveWindow(hwnd, x, frameGeometry.y(),
2466 frameGeometry.width(), frameGeometry.height(),
true);
2468 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ << window()
2469 <<
"\n resulting " << result << geometry_sys();
2473
2474
2475
2476
2477
2482 m_hdc = GetDC(handle());
2483 if (QGuiApplication::layoutDirection() == Qt::RightToLeft)
2484 SetLayout(m_hdc, 0);
2490
2491
2492
2493
2494
2499 ReleaseDC(handle(), m_hdc);
2506#if QT_CONFIG(dynamicgl)
2507 return QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()
2508 && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL;
2517 if (message == WM_ERASEBKGND) {
2522 if (!window()->isVisible() && (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0)
2525 if (!GetUpdateRect(m_data.hwnd, 0, FALSE))
2532 InvalidateRect(hwnd,
nullptr,
false);
2534 BeginPaint(hwnd, &ps);
2539 fireExpose(QRegion(qrectFromRECT(ps.rcPaint)),
true);
2540 if (!QWindowsContext::instance()->asyncExpose())
2541 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2543 EndPaint(hwnd, &ps);
2549 m_windowTitle = QWindowsWindow::formatWindowTitle(title);
2550 setWindowTitle_sys(m_windowTitle);
2555 return m_windowTitle;
2560 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window() <<
"\n from: "
2561 << m_data.flags <<
"\n to: " << flags;
2562 const QRect oldGeometry = geometry();
2563 if (m_data.flags != flags) {
2564 m_data.flags = flags;
2566 m_data = setWindowFlags_sys(flags);
2567 updateDropSite(window()->isTopLevel());
2574 const QRect newGeometry = geometry_sys();
2575 if (oldGeometry != newGeometry)
2576 handleGeometryChange();
2578 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
"\n returns: "
2579 << m_data.flags <<
" geometry " << oldGeometry <<
"->" << newGeometry;
2583 unsigned flags)
const
2586 creationData.fromWindow(window(), wt, flags);
2587 creationData.applyWindowFlags(m_data.hwnd);
2588 creationData.initialize(window(), m_data.hwnd,
true, m_opacity);
2590 if (creationData.flags.testFlag(Qt::ExpandedClientAreaHint)) {
2591 SetParent(m_data.hwndTitlebar, m_data.hwnd);
2592 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
2594 if (IsWindowVisible(m_data.hwndTitlebar)) {
2595 SetParent(m_data.hwndTitlebar, HWND_MESSAGE);
2596 ShowWindow(m_data.hwndTitlebar, SW_HIDE);
2601 result.flags = creationData.flags;
2603 result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME))
2604 && !(creationData.flags & Qt::FramelessWindowHint);
2608void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
2610 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window()
2611 <<
"\n from " << m_windowState <<
" to " << state;
2612 m_windowState = state;
2613 QWindowSystemInterface::handleWindowStateChanged(window(), state);
2614 if (state & Qt::WindowMinimized) {
2616 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2619 if (state & Qt::WindowMaximized) {
2620 WINDOWPLACEMENT windowPlacement{};
2621 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2622 GetWindowPlacement(m_data.hwnd, &windowPlacement);
2623 const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
2624 windowPlacement.rcNormalPosition = geometry;
2625 correctWindowPlacement(windowPlacement);
2631 windowPlacement.showCmd = SW_HIDE;
2632 SetWindowPlacement(m_data.hwnd, &windowPlacement);
2636 QWindow *w = window();
2637 bool exposeEventsSent =
false;
2640 exposeEventsSent =
true;
2642 const QWindowList allWindows = QGuiApplication::allWindows();
2643 for (QWindow *child : allWindows) {
2644 if (child != w && child->isVisible() && child->transientParent() == w) {
2645 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
2646 if (platformWindow && platformWindow->isLayered()) {
2647 platformWindow->fireFullExpose();
2648 exposeEventsSent =
true;
2652 if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
2653 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2662 return window()->maximumHeight() != QWINDOWSIZE_MAX;
2667 return window()->maximumWidth() != QWINDOWSIZE_MAX;
2675void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
2677 static const auto windows11 = QOperatingSystemVersion::Windows11_21H2;
2678 static const bool isWindows10 = QOperatingSystemVersion::current() < windows11;
2684 const QPoint offset = windowPlacementOffset(m_data.hwnd, m_data.restoreGeometry.topLeft());
2685 windowPlacement.rcNormalPosition = RECTfromQRect(m_data.restoreGeometry.translated(-offset));
2686 qCDebug(lcQpaWindow) <<
"Corrected normal position by" << -offset;
2695 const QMargins margins = frameMargins_sys();
2696 const QPoint topLeft = window()->screen()->geometry().topLeft();
2697 windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() };
2698 qCDebug(lcQpaWindow) <<
"Window has maximum size. Corrected topLeft by"
2704 const int adjust = offset.x() / window()->devicePixelRatio();
2705 window()->setWidth(window()->width() - adjust);
2706 qCDebug(lcQpaWindow) <<
"Width shortened by" << adjust <<
"logical pixels.";
2709 const int adjust = offset.y() / window()->devicePixelRatio();
2710 window()->setHeight(window()->height() - adjust);
2711 qCDebug(lcQpaWindow) <<
"Height shortened by" << adjust <<
"logical pixels.";
2718 m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
2724 setWindowState_sys(state);
2725 m_windowState = state;
2731 const QWindow *w = window();
2732 if (!w->isTopLevel())
2734 QRect geometry = geometry_sys();
2736 geometry += QMargins(1, 1, 1, 1);
2737 QPlatformScreen *screen = screenForGeometry(geometry);
2738 return screen && geometry == screen->geometry();
2742
2743
2744
2745
2746
2747
2748
2749
2750
2752void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
2754 const Qt::WindowStates oldState = m_windowState;
2755 if (oldState == newState)
2757 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window()
2758 <<
" from " << oldState <<
" to " << newState;
2761 auto stateChange = oldState ^ newState;
2763 if (stateChange & Qt::WindowFullScreen) {
2764 if (newState & Qt::WindowFullScreen) {
2765 UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
2769 if (!m_savedStyle) {
2770 m_savedStyle =
style();
2771 if ((oldState & Qt::WindowMinimized) || (oldState & Qt::WindowMaximized)) {
2772 const QRect nf = normalFrameGeometry(m_data.hwnd);
2774 m_savedFrameGeometry = nf;
2776 m_savedFrameGeometry = frameGeometry_sys();
2779 if (newState & Qt::WindowMaximized)
2781 if (m_savedStyle & WS_SYSMENU)
2782 newStyle |= WS_SYSMENU;
2784 newStyle |= WS_VISIBLE;
2785 if (testFlag(HasBorderInFullScreen))
2786 newStyle |= WS_BORDER;
2788 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2789 MONITORINFO monitorInfo = {};
2790 monitorInfo.cbSize =
sizeof(MONITORINFO);
2791 GetMonitorInfoW(monitor, &monitorInfo);
2792 const QRect screenGeometry(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
2793 monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
2794 monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
2795 if (newState & Qt::WindowMinimized) {
2796 setMinimizedGeometry(m_data.hwnd, screenGeometry);
2797 if (stateChange & Qt::WindowMaximized)
2798 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2800 const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
2803 SetWindowPos(m_data.hwnd, HWND_TOP, screenGeometry.left(), screenGeometry.top(), screenGeometry.width(), screenGeometry.height(), swpf);
2807 QWindowSystemInterface::handleGeometryChange(window(), screenGeometry);
2808 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2812 unsigned newStyle = m_savedStyle ? m_savedStyle :
style();
2814 newStyle |= WS_VISIBLE;
2817 const QScreen *screen = window()->screen();
2819 screen = QGuiApplication::primaryScreen();
2821 if (
const auto platformScreen = screen->handle()) {
2822 if (!platformScreen->geometry().intersects(m_savedFrameGeometry))
2823 m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft());
2826 if (newState & Qt::WindowMinimized) {
2827 setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry);
2828 if (stateChange & Qt::WindowMaximized)
2829 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2831 UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
2832 if (!m_savedFrameGeometry.isValid())
2833 swpf |= SWP_NOSIZE | SWP_NOMOVE;
2838 if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
2839 ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
2840 SetWindowPos(m_data.hwnd,
nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
2841 m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
2847 ShowWindow(m_data.hwnd,
2848 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
2853 m_savedFrameGeometry = QRect();
2855 }
else if ((oldState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
2856 if (visible && !(newState & Qt::WindowMinimized)) {
2858 if (newState & Qt::WindowFullScreen)
2860 if (m_data.flags & Qt::FramelessWindowHint) {
2861 if (newState == Qt::WindowNoState) {
2862 const QRect &rect = m_savedFrameGeometry;
2863 MoveWindow(m_data.hwnd, rect.x(), rect.y(), rect.width(), rect.height(),
true);
2865 HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2866 MONITORINFO monitorInfo = {};
2867 monitorInfo.cbSize =
sizeof(MONITORINFO);
2868 GetMonitorInfo(monitor, &monitorInfo);
2869 const RECT &rect = monitorInfo.rcWork;
2870 m_savedFrameGeometry = geometry();
2871 MoveWindow(m_data.hwnd, rect.left, rect.top,
2872 rect.right - rect.left, rect.bottom - rect.top,
true);
2875 ShowWindow(m_data.hwnd,
2876 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
2880 }
else if (visible && (oldState & newState & Qt::WindowMinimized)) {
2882 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2886 if (stateChange & Qt::WindowMinimized) {
2888 ShowWindow(m_data.hwnd,
2889 (newState & Qt::WindowMinimized) ? SW_MINIMIZE :
2890 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
2891 if ((newState & Qt::WindowMinimized) && (stateChange & Qt::WindowMaximized))
2892 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2895 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
this << window() << newState;
2900 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinStyle(s);
2902 SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
2908 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinExStyle(s);
2909 SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
2914 switch (event->type()) {
2915 case QEvent::ApplicationPaletteChange:
2916 setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
2918 case QEvent::WindowBlocked:
2924 case QEvent::WindowUnblocked:
2932 return QWindowsBaseWindow::windowEvent(event);
2937 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
2942 bool result =
false;
2943 if ((windowPos->flags & SWP_NOSIZE) == 0) {
2945 GetWindowRect(windowPos->hwnd, &rect);
2946 result = rect.right - rect.left != windowPos->cx || rect.bottom - rect.top != windowPos->cy;
2951bool QWindowsWindow::handleGeometryChangingMessage(MSG *message,
const QWindow *qWindow,
const QMargins &margins)
2953 auto *windowPos =
reinterpret_cast<WINDOWPOS *>(message->lParam);
2954 const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
2955 windowPos->cx, windowPos->cy);
2956 const QRect suggestedGeometry = suggestedFrameGeometry - margins;
2963 if (isResize(windowPos))
2964 windowPos->flags |= SWP_NOCOPYBITS;
2966 if ((windowPos->flags & SWP_NOZORDER) == 0) {
2967 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(qWindow)) {
2968 QWindow *parentWindow = qWindow->parent();
2969 HWND parentHWND = GetAncestor(windowPos->hwnd, GA_PARENT);
2970 HWND desktopHWND = GetDesktopWindow();
2971 platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND);
2973 if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint))
2974 windowPos->hwndInsertAfter = HWND_BOTTOM;
2976 if (!qWindow->isTopLevel())
2978 if (windowPos->flags & SWP_NOSIZE)
2980 const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
2981 if (!correctedGeometryF.isValid())
2983 const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
2984 if (correctedFrameGeometry == suggestedFrameGeometry)
2986 windowPos->x = correctedFrameGeometry.left();
2987 windowPos->y = correctedFrameGeometry.top();
2988 windowPos->cx = correctedFrameGeometry.width();
2989 windowPos->cy = correctedFrameGeometry.height();
2995 const QMargins margins = window()->isTopLevel() ? fullFrameMargins() : QMargins();
2996 return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
3001 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3003 if (m_data.fullFrameMargins != newMargins) {
3004 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << m_data.fullFrameMargins <<
"->" << newMargins;
3005 m_data.fullFrameMargins = newMargins;
3012 if (GetMenu(m_data.hwnd))
3013 QWindowsContext::forceNcCalcSize(m_data.hwnd);
3015 calculateFullFrameMargins();
3020 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3033 GetWindowRect(handle(), &windowRect);
3034 GetClientRect(handle(), &clientRect);
3040 if (qrectFromRECT(windowRect).size() == qrectFromRECT(clientRect).size())
3045 const auto systemMargins = testFlag(DisableNonClientScaling)
3046 ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd)
3047 : frameMargins_sys();
3048 const int extendedClientAreaBorder = window()->flags().testFlag(Qt::ExpandedClientAreaHint) ? qRound(QHighDpiScaling::factor(window())) * 2 : 0;
3049 const QMargins actualMargins = systemMargins + customMargins() - extendedClientAreaBorder;
3051 const int yDiff = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
3052 const bool typicalFrame = (actualMargins.left() == actualMargins.right())
3053 && (actualMargins.right() == actualMargins.bottom());
3055 const QMargins adjustedMargins = typicalFrame ?
3056 QMargins(actualMargins.left(), (yDiff - actualMargins.bottom()),
3057 actualMargins.right(), actualMargins.bottom())
3060 setFullFrameMargins(adjustedMargins);
3065 QMargins result = fullFrameMargins();
3066 if (isTopLevel() && m_data.hasFrame)
3067 result -= invisibleMargins(m_data.hwnd);
3073 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3075 return m_data.fullFrameMargins;
3080 qCDebug(lcQpaWindow) <<
__FUNCTION__ << level;
3081 if (!qFuzzyCompare(m_opacity, level)) {
3084 setWindowOpacity(m_data.hwnd, m_data.flags,
3092 return CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
3097 if (
const HRGN rectRegion = createRectRegion(rect)) {
3098 HRGN result = CreateRectRgn(0, 0, 0, 0);
3099 if (CombineRgn(result, *winRegion, rectRegion, RGN_OR)) {
3100 DeleteObject(*winRegion);
3101 *winRegion = result;
3103 DeleteObject(rectRegion);
3109 auto it = region.begin();
3110 const auto end = region.end();
3113 HRGN hRegion = createRectRegion(*it);
3115 addRectToWinRegion(*it, &hRegion);
3121 if (region.isEmpty()) {
3122 SetWindowRgn(m_data.hwnd,
nullptr,
true);
3125 const HRGN winRegion = qRegionToWinRegion(region);
3128 if (window()->isTopLevel()) {
3129 const QMargins margins = fullFrameMargins();
3130 OffsetRgn(winRegion, margins.left(), margins.top());
3134 if (!SetWindowRgn(m_data.hwnd, winRegion,
true))
3135 DeleteObject(winRegion);
3140 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
3146 if (QGuiApplication::applicationState() == Qt::ApplicationActive
3147 || activationBehavior != QWindowsApplication::AlwaysActivateWindow) {
3148 SetForegroundWindow(m_data.hwnd);
3149 SetFocus(m_data.hwnd);
3158 if (m_data.flags & Qt::WindowStaysOnBottomHint) {
3159 qCWarning(lcQpaWindow) <<
3160 "Windows with Qt::WindowStaysOnBottomHint can't be brought to the foreground.";
3163 if (m_data.flags & Qt::WindowStaysOnTopHint) {
3164 qCWarning(lcQpaWindow) <<
3165 "Windows with Qt::WindowStaysOnTopHint will always be on the foreground.";
3168 if (window()->type() == Qt::ToolTip) {
3169 qCWarning(lcQpaWindow) <<
"ToolTip windows should not be activated.";
3174 if (!IsWindowVisible(m_data.hwnd))
3175 ShowWindow(m_data.hwnd, SW_SHOW);
3177 if (IsIconic(m_data.hwnd)) {
3178 ShowWindow(m_data.hwnd, SW_RESTORE);
3185 const HWND oldForegroundWindow = GetForegroundWindow();
3186 if (!oldForegroundWindow)
3191 if (SendMessageTimeoutW(oldForegroundWindow, WM_NULL, 0, 0,
3192 SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000,
nullptr) == 0) {
3193 qCWarning(lcQpaWindow) <<
"The foreground window hangs, can't activate current window.";
3197 const DWORD windowThreadProcessId = GetWindowThreadProcessId(oldForegroundWindow,
nullptr);
3198 const DWORD currentThreadId = GetCurrentThreadId();
3200 AttachThreadInput(windowThreadProcessId, currentThreadId, TRUE);
3201 const auto cleanup = qScopeGuard([windowThreadProcessId, currentThreadId](){
3202 AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE);
3205 BringWindowToTop(m_data.hwnd);
3209 SetActiveWindow(m_data.hwnd);
3215 qWarning(
"%s: No handle",
__FUNCTION__);
3218 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << grab;
3222 context->setKeyGrabber(window());
3224 if (context->keyGrabber() == window())
3225 context->setKeyGrabber(
nullptr);
3232 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << grab;
3234 qWarning(
"%s: No handle",
__FUNCTION__);
3238 qWarning(
"%s: Not setting mouse grab for invisible window %s/'%s'",
3239 __FUNCTION__, window()->metaObject()->className(),
3240 qPrintable(window()->objectName()));
3247 SetCapture(m_data.hwnd);
3257 if (edges == Qt::LeftEdge)
3259 else if (edges == (Qt::RightEdge))
3261 else if (edges == (Qt::TopEdge))
3263 else if (edges == (Qt::TopEdge | Qt::LeftEdge))
3265 else if (edges == (Qt::TopEdge | Qt::RightEdge))
3267 else if (edges == (Qt::BottomEdge))
3269 else if (edges == (Qt::BottomEdge | Qt::LeftEdge))
3271 else if (edges == (Qt::BottomEdge | Qt::RightEdge))
3279 if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
3283 PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0);
3291 PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 , 0);
3306 QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
3307 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << *mmi;
3313 const QWindow *w = window();
3314 const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
3315 const QRect geom = geometry();
3316 static auto oldMouseButtonState = Qt::NoButton;
3318 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
3319 bool isDefaultTitleBar = !w->flags().testFlag(Qt::CustomizeWindowHint);
3320 bool isCustomized = w->flags().testFlags(Qt::CustomizeWindowHint) && w->flags().testAnyFlags(Qt::WindowTitleHint|
3321 Qt::WindowMinimizeButtonHint|
3322 Qt::WindowMaximizeButtonHint|
3323 Qt::WindowCloseButtonHint);
3324 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3325 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3326 const int titleButtonWidth = titleBarHeight * 1.5;
3327 const bool mouseButtonsSwapped = GetSystemMetrics(SM_SWAPBUTTON);
3328 auto mouseButtons = Qt::NoButton;
3329 if (mouseButtonsSwapped)
3330 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::RightButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::LeftButton : Qt::NoButton);
3332 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::LeftButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::RightButton : Qt::NoButton);
3335 if (isCustomized || isDefaultTitleBar) {
3338 if (globalPos.y() < geom.top() + titleBarHeight) {
3339 if (m_data.flags.testFlags(Qt::WindowCloseButtonHint) || isDefaultTitleBar) {
3340 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right())) {
3341 if (mouseButtons == Qt::LeftButton)
3345 }
if (m_data.flags.testFlags(Qt::WindowMaximizeButtonHint) || isDefaultTitleBar) {
3346 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3347 if (mouseButtons == Qt::LeftButton) {
3348 if (IsZoomed(m_data.hwnd))
3351 *result = HTMAXBUTTON;
3355 }
if (m_data.flags.testFlags(Qt::WindowMinimizeButtonHint) || isDefaultTitleBar) {
3356 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3357 if (mouseButtons == Qt::LeftButton)
3358 *result = HTMINBUTTON;
3361 }
if ((isCustomized || isDefaultTitleBar) &&
3362 *result == HTCLIENT){
3363 QWindow* wnd = window();
3364 if (mouseButtons != oldMouseButtonState) {
3365 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3366 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3367 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3368 if (!accepted && mouseButtons == Qt::RightButton)
3369 *result = HTSYSMENU;
3370 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3371 *result = HTCAPTION;
3375 }
else if (w->flags().testFlag(Qt::CustomizeWindowHint)) {
3377 QWindow* wnd = window();
3378 if (mouseButtons != oldMouseButtonState) {
3379 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3380 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3381 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3382 if (!accepted && mouseButtons == Qt::RightButton)
3383 *result = HTSYSMENU;
3384 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3385 *result = HTCAPTION;
3388 oldMouseButtonState = mouseButtons;
3391 const bool left = (globalPos.x() >= geom.left()) && (globalPos.x() < geom.left() + border);
3392 const bool right = (globalPos.x() > geom.right() - border) && (globalPos.x() <= geom.right());
3393 const bool top = (globalPos.y() >= geom.top()) && (globalPos.y() < geom.top() + border);
3394 const bool bottom = (globalPos.y() > geom.bottom() - border) && (globalPos.y() <= geom.bottom());
3396 if (left || right || top || bottom) {
3398 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3400 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3402 *result = top ? HTTOP : HTBOTTOM;
3408 const_cast<QWindow *>(w)->close();
3411 const_cast<QWindow *>(w)->showMaximized();
3414 const_cast<QWindow *>(w)->showMinimized();
3417 const_cast<QWindow *>(w)->showNormal();
3420 HWND hwnd =
reinterpret_cast<HWND>(w->winId());
3421 HMENU sysMenu = GetSystemMenu(hwnd,
false);
3422 TrackPopupMenu(sysMenu, 0, globalPos.x(), globalPos.y(), 0, hwnd,
nullptr);
3431 if (m_data.flags & Qt::ExpandedClientAreaHint) {
3432 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3437 const QRect rect = geom;
3438 const bool left = (globalPos.x() >= rect.left()) && (globalPos.x() < rect.left() + border);
3439 const bool right = (globalPos.x() > rect.right() - border) && (globalPos.x() <= rect.right());
3440 const bool top = (globalPos.y() >= rect.top()) && (globalPos.y() < rect.top() + border);
3441 const bool bottom = (globalPos.y() > rect.bottom() - border) && (globalPos.y() <= rect.bottom());
3444 if (left || right || top || bottom) {
3446 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3448 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3450 *result = top ? HTTOP : HTBOTTOM;
3458 if (!w->isTopLevel()
3459 || (m_windowState != Qt::WindowNoState)
3461 || (m_data.flags & Qt::FramelessWindowHint)) {
3464 const QSize minimumSize = w->minimumSize();
3465 if (minimumSize.isEmpty())
3467 const QSize maximumSize = w->maximumSize();
3468 const bool fixedWidth = minimumSize.width() == maximumSize.width();
3469 const bool fixedHeight = minimumSize.height() == maximumSize.height();
3470 if (!fixedWidth && !fixedHeight)
3472 const QSize size = w->size();
3474 if (localPos.y() >= size.height()) {
3478 if (localPos.y() < 0) {
3479 const int topResizeBarPos = invisibleMargins(m_data.hwnd).left() - frameMargins().top();
3480 if (localPos.y() < topResizeBarPos) {
3481 *result = HTCAPTION;
3486 if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
3498 if (m_data.flags & Qt::FramelessWindowHint) {
3507 HWND hwnd = m_data.hwndTitlebar;
3508 QWindow *wnd = window();
3511 GetWindowRect(hwnd, &windowRect);
3513 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3514 const int titleButtonWidth = titleBarHeight * 1.5;
3515 const qreal factor = QHighDpiScaling::factor(wnd);
3516 const int windowWidth = windowRect.right - windowRect.left;
3519 GetCursorPos(&localPos);
3520 MapWindowPoints(HWND_DESKTOP, m_data.hwnd, &localPos, 1);
3522 const bool isDarkmode = QWindowsIntegration::instance()->darkModeHandling().testFlags(QWindowsApplication::DarkModeWindowFrames) &&
3523 qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
3524 const bool isWindows11orAbove = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11;
3526 const QBrush closeButtonBrush(QColor(0xC4, 0x2C, 0x1E, 255));
3527 const QBrush minMaxButtonBrush = QBrush(isDarkmode ? QColor(0xFF, 0xFF, 0xFF, 0x40) : QColor(0x00, 0x00, 0x00, 0x20));
3528 const QBrush titleBarBackgroundColor = QBrush(isDarkmode ? QColor(0x1F, 0x1F, 0x1F, 0xFF) : QColor(0xF3, 0xF3, 0xF3, 0xFF));
3529 const QPen textPen = QPen(isDarkmode ? QColor(0xFF, 0xFF, 0xFD, 0xFF) : QColor(0x00, 0x00, 0x00, 0xFF));
3531 QImage image(windowWidth, titleBarHeight, QImage::Format_ARGB32);
3533 p.setCompositionMode(QPainter::CompositionMode_Clear);
3534 p.fillRect(0, 0, windowWidth, titleBarHeight, Qt::transparent);
3536 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
3538 p.setBrush(titleBarBackgroundColor);
3539 p.setPen(Qt::NoPen);
3540 if (!wnd->flags().testFlags(Qt::NoTitleBarBackgroundHint)) {
3542 titleRect.setWidth(windowWidth);
3543 titleRect.setHeight(titleBarHeight);
3544 p.drawRect(titleRect);
3547 if (wnd->flags().testFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3551 titleRect.setWidth(windowWidth);
3552 titleRect.setHeight(titleBarHeight);
3554 titleRect.adjust(factor * 4, 0, 0, 0);
3555 QRect iconRect(titleRect.x(), titleRect.y() + factor * 8, factor * 16, factor * 16);
3556 if (wnd->icon().isNull()) {
3557 static QIcon defaultIcon;
3558 if (defaultIcon.isNull()) {
3559 const QImage defaultIconImage = QImage::fromHICON(LoadIcon(0, IDI_APPLICATION));
3560 defaultIcon = QIcon(QPixmap::fromImage(defaultIconImage));
3562 defaultIcon.paint(&p, iconRect);
3564 wnd->icon().paint(&p, iconRect);
3566 titleRect.adjust(factor * 24, 0, 0, 0);
3570 titleFont.setPointSize(factor * 9);
3571 titleFont.setWeight(QFont::Thin);
3572 titleFont.setHintingPreference(QFont::PreferFullHinting);
3573 p.setFont(titleFont);
3574 const QString title = wnd->title().isEmpty() ? qApp->applicationName() : wnd->title();
3575 p.drawText(titleRect, title, QTextOption(Qt::AlignVCenter));
3579 const QString assetFontName = isWindows11orAbove ? QStringLiteral(
"Segoe Fluent Icons") : QStringLiteral(
"Segoe MDL2 Assets");
3580 QFont assetFont = QFont(assetFontName, factor * 7);
3581 assetFont.setWeight(QFont::Thin);
3582 assetFont.setHintingPreference(QFont::PreferFullHinting);
3583 p.setFont(assetFont);
3584 p.setBrush(closeButtonBrush);
3585 p.setPen(Qt::NoPen);
3586 if (wnd->flags().testFlags(Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3589 rect.setX(windowWidth - titleButtonWidth * buttons);
3590 rect.setWidth(titleButtonWidth);
3591 rect.setHeight(titleBarHeight);
3592 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3593 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3594 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3596 const QPen closeButtonHoveredPen = QPen(QColor(0xFF, 0xFF, 0xFD, 0xFF));
3597 p.setPen(closeButtonHoveredPen);
3601 p.drawText(rect, QStringLiteral(
"\uE8BB"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3605 p.setBrush(minMaxButtonBrush);
3606 p.setPen(Qt::NoPen);
3607 if (wnd->flags().testFlags(Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3610 rect.setX(windowWidth - titleButtonWidth * buttons);
3611 rect.setWidth(titleButtonWidth);
3612 rect.setHeight(titleBarHeight);
3613 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3614 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3615 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3619 p.drawText(rect,QStringLiteral(
"\uE922"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3623 p.setBrush(minMaxButtonBrush);
3624 p.setPen(Qt::NoPen);
3625 if (wnd->flags().testFlags(Qt::WindowMinimizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3628 rect.setX(windowWidth - titleButtonWidth * buttons);
3629 rect.setWidth(titleButtonWidth);
3630 rect.setHeight(titleBarHeight);
3631 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3632 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3633 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3637 p.drawText(rect,QStringLiteral(
"\uE921"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3643 HBITMAP bmp = image.toHBITMAP();
3645 HDC hdc = GetDC(hwnd);
3647 HDC memdc = CreateCompatibleDC(hdc);
3648 HGDIOBJ original = SelectObject(memdc, bmp);
3651 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
3652 POINT ptLocation = { 0, 0 };
3653 SIZE szWnd = { windowWidth, titleBarHeight };
3654 POINT ptSrc = { 0, 0 };
3655 UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
3656 SelectObject(hdc, original);
3659 DeleteObject(memdc);
3660 ReleaseDC(hwnd,hdc);
3667 if (QScreen *screen = w->screen())
3668 if (
const QPlatformScreen *platformScreen = screen->handle())
3669 if (QPlatformCursor *cursor = platformScreen->cursor())
3670 return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
3671 return CursorHandlePtr(
new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
3680 if (underMouse == w)
3682 for (
const QWindow *p = underMouse; p ; p = p->parent()) {
3685 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p);
3686 if (platformWindow && !platformWindow->cursor()->isNull())
3694
3695
3696
3697
3707 if (m_cursor->isNull()) {
3708 if (
const QWindow *p = window()->parent()) {
3709 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p))
3712 SetCursor(defaultCursor(window())->handle());
3715 SetCursor(m_cursor->handle());
3723 bool changed = c->handle() != m_cursor->handle();
3731 const bool apply = applyNewCursor(window());
3732 qCDebug(lcQpaWindow) << window() <<
__FUNCTION__
3733 << c->handle() <<
" doApply=" << apply;
3756 UINT timeOutMs = GetCaretBlinkTime();
3757 if (!timeOutMs || timeOutMs == INFINITE)
3761 info.cbSize =
sizeof(info);
3762 info.hwnd = m_data.hwnd;
3763 info.dwFlags = FLASHW_TRAY;
3764 info.dwTimeout = timeOutMs;
3765 info.uCount = durationMs == 0 ? 10 : UINT(durationMs) / timeOutMs;
3766 FlashWindowEx(&info);
3772 info.cbSize =
sizeof(info);
3773 info.hwnd = m_data.hwnd;
3774 info.dwFlags = FLASHW_STOP;
3777 FlashWindowEx(&info);
3782 return (style() & WS_DISABLED) == 0;
3787 const unsigned oldStyle =
style();
3788 unsigned newStyle = oldStyle;
3790 newStyle &= ~WS_DISABLED;
3792 newStyle |= WS_DISABLED;
3794 if (newStyle != oldStyle)
3800 if (!icon.isNull()) {
3802 const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)), 1);
3804 return qt_pixmapToWinHICON(pm);
3814 m_iconSmall = createHIcon(icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
3815 m_iconBig = createHIcon(icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
3818 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3819 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconBig));
3821 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3822 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconSmall));
3829 return window()->isTopLevel() && !m_data.embedded;
3839 const BOOL darkBorder = d ? TRUE : FALSE;
3844 qCWarning(lcQpaWindow,
"%s: Unable to set %s window border.",
__FUNCTION__, d ?
"dark" :
"light");
3851 d = d && shouldApplyDarkFrame(window());
3853 setDarkBorderToWindow(m_data.hwnd, d);
3858 return m_menuBar.data();
3868 if (m_data.flags & Qt::FramelessWindowHint)
3870 return m_data.customMargins;
3874
3875
3876
3877
3878
3879
3880
3881
3885 if (m_data.flags & Qt::FramelessWindowHint) {
3886 qCWarning(lcQpaWindow) <<
"You should not set custom margins for a frameless window.";
3889 if (newCustomMargins != m_data.customMargins) {
3890 const QMargins oldCustomMargins = m_data.customMargins;
3891 m_data.customMargins = newCustomMargins;
3893 const QRect currentFrameGeometry = frameGeometry_sys();
3894 const QPoint topLeft = currentFrameGeometry.topLeft();
3895 QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
3896 newFrame.moveTo(topLeft);
3897 qCDebug(lcQpaWindow) <<
__FUNCTION__ << oldCustomMargins <<
"->" << newCustomMargins
3898 << currentFrameGeometry <<
"->" << newFrame;
3899 SetWindowPos(m_data.hwnd,
nullptr, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
3905#if QT_CONFIG(vulkan)
3906 Q_UNUSED(nativeConfig);
3908 if (window()->surfaceType() == QSurface::VulkanSurface) {
3910 QVulkanInstance *inst = window()->vulkanInstance();
3912 m_vkSurface =
static_cast<QWindowsVulkanInstance *>(inst->handle())->createSurface(handle());
3914 qWarning(
"Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
3918 return &m_vkSurface;
3920#elif defined(QT_NO_OPENGL)
3922 Q_UNUSED(nativeConfig);
3939#if QT_CONFIG(vulkan)
3941 QVulkanInstance *inst = window()->vulkanInstance();
3943 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
3944 m_vkSurface = VK_NULL_HANDLE;
3951 m_surface =
nullptr;
3964 const auto currentTouchTypes = touchWindowTouchTypes_sys();
3965 if (currentTouchTypes.has_value() && currentTouchTypes.value() == touchTypes)
3969 ULONG touchFlags = 0;
3970 if (touchTypes.testFlag(TouchWindowTouchType::FineTouch))
3971 touchFlags |= TWF_FINETOUCH;
3972 if (touchTypes.testFlag(TouchWindowTouchType::WantPalmTouch))
3973 touchFlags |= TWF_WANTPALM;
3974 if (RegisterTouchWindow(m_data.hwnd, touchFlags))
3977 qErrnoWarning(
"RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
3982 if (QPlatformWindow *handle = window->handle())
3983 static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border);
3990 m_borderInFullScreenDefault = border;
4007 if (m_windowState == Qt::WindowFullScreen) {
4008 LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE);
4012 style &= ~WS_BORDER;
4013 SetWindowLongPtr(handle(), GWL_STYLE, style);
4019 return QPlatformWindow::formatWindowTitle(title, QStringLiteral(
" - "));
4029 QWindow *w = window();
4030 QDxgiVSyncService *vs = QDxgiVSyncService::instance();
4031 if (vs->supportsWindow(w)) {
4032 if (m_vsyncServiceCallbackId == 0) {
4033 m_vsyncServiceCallbackId = vs->registerCallback([
this, w](
const QDxgiVSyncService::CallbackWindowList &windowList, qint64) {
4034 if (windowList.contains(w)) {
4039 if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) {
4040 QWindowsWindow *oldSelf =
this;
4041 qsizetype oldCallbackId = m_vsyncServiceCallbackId;
4042 QMetaObject::invokeMethod(w, [w, oldSelf, oldCallbackId] {
4044 auto *self =
static_cast<QWindowsWindow *>(w->handle());
4047 if (self && self == oldSelf && self->m_vsyncServiceCallbackId == oldCallbackId) {
4049 self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready);
4050 self->deliverUpdateRequest();
4057 m_vsyncUpdatePending.testAndSetRelease(UpdateState::Ready, UpdateState::Requested);
4059 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)