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 m_data = setWindowFlags_sys(window()->flags(),
unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
2081 m_data.fullFrameMargins = {};
2082 updateDropSite(isTopLevel);
2089 fireExpose(QRegion());
2094 const QWindow *w = window();
2096 applyBlurBehindWindow(handle());
2101 return QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) /
2102 QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi);
2112 const UINT dpi = UINT(wParam);
2113 const qreal scale = dpiRelativeScale(dpi);
2114 const QMargins margins = fullFrameMargins();
2115 if (!(m_data.flags & Qt::FramelessWindowHint)) {
2121 m_data.customMargins *= scale;
2124 const QSize windowSize = (geometry().size() * scale).grownBy((margins * scale) + customMargins());
2125 SIZE *size =
reinterpret_cast<SIZE *>(lParam);
2126 size->cx = windowSize.width();
2127 size->cy = windowSize.height();
2133 const UINT dpi = HIWORD(wParam);
2134 const qreal scale = dpiRelativeScale(dpi);
2137 QWindowsThemeCache::clearThemeCache(hwnd);
2140 const auto prcNewWindow =
reinterpret_cast<
const RECT *>(lParam);
2141 checkForScreenChanged(QWindowsWindow::FromDpiChange, !m_inSetgeometry ? prcNewWindow :
nullptr);
2143 if (!IsZoomed(hwnd))
2144 m_data.restoreGeometry.setSize(m_data.restoreGeometry.size() * scale);
2162 if (!m_inSetgeometry) {
2164 SetWindowPos(hwnd,
nullptr, prcNewWindow->left, prcNewWindow->top,
2165 prcNewWindow->right - prcNewWindow->left,
2166 prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
2170 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2171 handleGeometryChange();
2176 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
2181 const UINT dpi = GetDpiForWindow(hwnd);
2182 const qreal scale = dpiRelativeScale(dpi);
2185 checkForScreenChanged(QWindowsWindow::FromDpiChange);
2189 QRect currentGeometry = geometry();
2190 QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
2191 setGeometry(scaledGeometry);
2197 wp.length =
sizeof(WINDOWPLACEMENT);
2198 if (GetWindowPlacement(hwnd, &wp)) {
2199 const QRect result = qrectFromRECT(wp.rcNormalPosition);
2200 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
2208 const bool fakeFullScreen =
2209 m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen);
2210 const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
2211 const QMargins margins = fakeFullScreen
2212 ? QWindowsGeometryHint::frame(window(), handle(), m_savedStyle, 0)
2213 : fullFrameMargins();
2214 return frame.isValid() ? frame.marginsRemoved(margins) : frame;
2219 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
2220 const int titleBarHeight = getTitleBarHeight_sys(96);
2222 return QMargins(0, titleBarHeight, 0, 0);
2228 const QRect &requestedRect,
2229 const QRect &obtainedRect,
2230 const QMargins &fullMargins,
2231 const QMargins &customMargins)
2234 QDebug debug(&result);
2237 const auto window = platformWindow->window();
2238 debug <<
"Unable to set geometry ";
2239 formatBriefRectangle(debug, requestedRect);
2240 debug <<
" (frame: ";
2241 formatBriefRectangle(debug, requestedRect + fullMargins);
2242 debug <<
") on " << window->metaObject()->className() <<
"/\""
2243 << window->objectName() <<
"\" on \"" << window->screen()->name()
2244 <<
"\". Resulting geometry: ";
2245 formatBriefRectangle(debug, obtainedRect);
2246 debug <<
" (frame: ";
2247 formatBriefRectangle(debug, obtainedRect + fullMargins);
2248 debug <<
") margins: ";
2249 formatBriefMargins(debug, fullMargins);
2250 if (!customMargins.isNull()) {
2251 debug <<
" custom margin: ";
2252 formatBriefMargins(debug, customMargins);
2254 const auto minimumSize = window->minimumSize();
2255 const bool hasMinimumSize = !minimumSize.isEmpty();
2257 debug <<
" minimum size: " << minimumSize.width() <<
'x' << minimumSize.height();
2258 const auto maximumSize = window->maximumSize();
2259 const bool hasMaximumSize = maximumSize.width() != QWINDOWSIZE_MAX || maximumSize.height() != QWINDOWSIZE_MAX;
2261 debug <<
" maximum size: " << maximumSize.width() <<
'x' << maximumSize.height();
2262 if (hasMinimumSize || hasMaximumSize) {
2263 MINMAXINFO minmaxInfo;
2264 memset(&minmaxInfo, 0,
sizeof(minmaxInfo));
2265 platformWindow->getSizeHints(&minmaxInfo);
2266 debug <<
' ' << minmaxInfo;
2274 QScopedValueRollback b(m_inSetgeometry,
true);
2276 QRect rect = rectIn;
2279 if (QWindowsGeometryHint::positionIncludesFrame(window())) {
2280 const QMargins margins = frameMargins();
2281 rect.moveTopLeft(rect.topLeft() +
QPoint(margins.left(), margins.top()));
2283 if (m_windowState & Qt::WindowMinimized)
2284 m_data.geometry = rect;
2290 setGeometry_sys(rect);
2292 if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) {
2293 const auto warning =
2294 msgUnableToSetGeometry(
this, rectIn, m_data.geometry,
2295 fullFrameMargins(), customMargins());
2296 qWarning(
"%s: %s",
__FUNCTION__, qPrintable(warning));
2299 QPlatformWindow::setGeometry(rect);
2307 handleGeometryChange();
2313 if ((m_data.flags.testFlag(Qt::FramelessWindowHint)
2314 || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))
2315 && IsZoomed(m_data.hwnd)) {
2316 const int resizedWidth = LOWORD(lParam);
2317 const int resizedHeight = HIWORD(lParam);
2319 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTOPRIMARY);
2320 MONITORINFO monitorInfo = {};
2321 monitorInfo.cbSize =
sizeof(MONITORINFO);
2322 GetMonitorInfoW(monitor, &monitorInfo);
2324 int correctLeft = monitorInfo.rcMonitor.left;
2325 int correctTop = monitorInfo.rcMonitor.top;
2326 int correctWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
2327 int correctHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
2329 if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
2330 const int borderWidth = invisibleMargins(m_data.hwnd).left();
2331 correctLeft -= borderWidth;
2332 correctTop -= borderWidth;
2333 correctWidth += borderWidth * 2;
2334 correctHeight += borderWidth * 2;
2337 if (resizedWidth != correctWidth || resizedHeight != correctHeight) {
2338 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"correcting: " << resizedWidth <<
"x"
2339 << resizedHeight <<
" -> " << correctWidth <<
"x" << correctHeight;
2340 SetWindowPos(m_data.hwnd,
nullptr, correctLeft, correctTop, correctWidth, correctHeight,
2341 SWP_NOZORDER | SWP_NOACTIVATE);
2349 case SIZE_MINIMIZED:
2350 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2351 handleWindowStateChange(m_windowState | Qt::WindowMinimized);
2353 case SIZE_MAXIMIZED:
2354 handleGeometryChange();
2356 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2357 handleWindowStateChange(Qt::WindowMaximized | (isFullScreen_sys() ? Qt::WindowFullScreen
2358 : Qt::WindowNoState));
2361 handleGeometryChange();
2363 if (isFullScreen_sys())
2364 handleWindowStateChange(
2365 Qt::WindowFullScreen
2366 | (testFlag(MaximizeToFullScreen) ? Qt::WindowMaximized : Qt::WindowNoState));
2367 else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
2368 handleWindowStateChange(Qt::WindowNoState);
2374static inline bool equalDpi(
const QDpi &d1,
const QDpi &d2)
2376 return qFuzzyCompare(d1.first, d2.first) && qFuzzyCompare(d1.second, d2.second);
2384 QPlatformScreen *currentScreen = screen();
2385 auto topLevel = isTopLevel_sys() ? m_data.hwnd : GetAncestor(m_data.hwnd, GA_ROOT);
2390 if (newScreen ==
nullptr || newScreen == currentScreen)
2394 const bool changingDpi = !equalDpi(QDpi(savedDpi(), savedDpi()), newScreen->logicalDpi());
2398 qCDebug(lcQpaWindow).noquote().nospace() <<
__FUNCTION__
2399 <<
' ' << window() <<
" \"" << (currentScreen ? currentScreen->name() : QString())
2400 <<
"\"->\"" << newScreen->name() <<
'"';
2402 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
2407 const QRect previousGeometry = m_data.geometry;
2409 m_data.geometry = geometry_sys();
2412 if (m_data.geometry == previousGeometry)
2414 QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
2419 && m_data.geometry.size() != previousGeometry.size()
2421 && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
2422 fireFullExpose(
true);
2426 checkForScreenChanged();
2428 if (testFlag(SynchronousGeometryChangeEvent))
2429 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2436 qCDebug(lcQpaEvents) <<
__FUNCTION__ <<
this << window() << m_data.geometry;
2438 if (m_data.flags & Qt::ExpandedClientAreaHint) {
2439 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
2440 MoveWindow(m_data.hwndTitlebar, 0, 0, m_data.geometry.width(), titleBarHeight,
true);
2446 const QMargins margins = fullFrameMargins();
2447 const QRect frameGeometry = rect + margins;
2449 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ << window()
2450 <<
"\n from " << geometry_sys() <<
" frame: "
2451 << margins <<
" to " <<rect
2452 <<
" new frame: " << frameGeometry;
2454 bool result =
false;
2455 const HWND hwnd = handle();
2456 WINDOWPLACEMENT windowPlacement;
2457 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2458 GetWindowPlacement(hwnd, &windowPlacement);
2461 if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(hwnd))
2462 || windowPlacement.showCmd == SW_SHOWMINIMIZED) {
2463 windowPlacement.rcNormalPosition =
2464 RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(hwnd, frameGeometry.topLeft())));
2465 windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
2466 result = SetWindowPlacement(hwnd, &windowPlacement);
2468 int x = frameGeometry.x();
2469 if (!window()->isTopLevel()) {
2470 const HWND parentHandle = GetParent(hwnd);
2471 if (isRtlLayout(parentHandle)) {
2473 GetClientRect(parentHandle, &rect);
2474 x = rect.right - frameGeometry.width() - x;
2477 result = MoveWindow(hwnd, x, frameGeometry.y(),
2478 frameGeometry.width(), frameGeometry.height(),
true);
2480 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ << window()
2481 <<
"\n resulting " << result << geometry_sys();
2485
2486
2487
2488
2489
2494 m_hdc = GetDC(handle());
2495 if (QGuiApplication::layoutDirection() == Qt::RightToLeft)
2496 SetLayout(m_hdc, 0);
2502
2503
2504
2505
2506
2511 ReleaseDC(handle(), m_hdc);
2518#if QT_CONFIG(dynamicgl)
2519 return QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()
2520 && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL;
2529 if (message == WM_ERASEBKGND) {
2534 if (!window()->isVisible() && (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0)
2537 if (!GetUpdateRect(m_data.hwnd, 0, FALSE))
2544 InvalidateRect(hwnd,
nullptr,
false);
2546 BeginPaint(hwnd, &ps);
2551 fireExpose(QRegion(qrectFromRECT(ps.rcPaint)),
true);
2552 if (!QWindowsContext::instance()->asyncExpose())
2553 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2555 EndPaint(hwnd, &ps);
2561 m_windowTitle = QWindowsWindow::formatWindowTitle(title);
2562 setWindowTitle_sys(m_windowTitle);
2567 return m_windowTitle;
2572 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window() <<
"\n from: "
2573 << m_data.flags <<
"\n to: " << flags;
2574 const QRect oldGeometry = geometry();
2575 if (m_data.flags != flags) {
2576 m_data.flags = flags;
2578 m_data = setWindowFlags_sys(flags);
2579 updateDropSite(window()->isTopLevel());
2586 const QRect newGeometry = geometry_sys();
2587 if (oldGeometry != newGeometry)
2588 handleGeometryChange();
2590 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
"\n returns: "
2591 << m_data.flags <<
" geometry " << oldGeometry <<
"->" << newGeometry;
2595 unsigned flags)
const
2598 creationData.fromWindow(window(), wt, flags);
2599 creationData.applyWindowFlags(m_data.hwnd);
2600 creationData.initialize(window(), m_data.hwnd,
true, m_opacity);
2602 if (creationData.flags.testFlag(Qt::ExpandedClientAreaHint)) {
2603 SetParent(m_data.hwndTitlebar, m_data.hwnd);
2604 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
2606 if (IsWindowVisible(m_data.hwndTitlebar)) {
2607 SetParent(m_data.hwndTitlebar, HWND_MESSAGE);
2608 ShowWindow(m_data.hwndTitlebar, SW_HIDE);
2613 result.flags = creationData.flags;
2615 result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME))
2616 && !(creationData.flags & Qt::FramelessWindowHint);
2620void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
2622 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window()
2623 <<
"\n from " << m_windowState <<
" to " << state;
2624 m_windowState = state;
2625 QWindowSystemInterface::handleWindowStateChanged(window(), state);
2626 if (state & Qt::WindowMinimized) {
2628 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2631 if (state & Qt::WindowMaximized) {
2632 WINDOWPLACEMENT windowPlacement{};
2633 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2634 GetWindowPlacement(m_data.hwnd, &windowPlacement);
2635 const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
2636 windowPlacement.rcNormalPosition = geometry;
2637 correctWindowPlacement(windowPlacement);
2643 windowPlacement.showCmd = SW_HIDE;
2644 SetWindowPlacement(m_data.hwnd, &windowPlacement);
2648 QWindow *w = window();
2649 bool exposeEventsSent =
false;
2652 exposeEventsSent =
true;
2654 const QWindowList allWindows = QGuiApplication::allWindows();
2655 for (QWindow *child : allWindows) {
2656 if (child != w && child->isVisible() && child->transientParent() == w) {
2657 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
2658 if (platformWindow && platformWindow->isLayered()) {
2659 platformWindow->fireFullExpose();
2660 exposeEventsSent =
true;
2664 if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
2665 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2674 return window()->maximumHeight() != QWINDOWSIZE_MAX;
2679 return window()->maximumWidth() != QWINDOWSIZE_MAX;
2687void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
2689 static const auto windows11 = QOperatingSystemVersion::Windows11_21H2;
2690 static const bool isWindows10 = QOperatingSystemVersion::current() < windows11;
2696 const QPoint offset = windowPlacementOffset(m_data.hwnd, m_data.restoreGeometry.topLeft());
2697 windowPlacement.rcNormalPosition = RECTfromQRect(m_data.restoreGeometry.translated(-offset));
2698 qCDebug(lcQpaWindow) <<
"Corrected normal position by" << -offset;
2707 const QMargins margins = frameMargins_sys();
2708 const QPoint topLeft = window()->screen()->geometry().topLeft();
2709 windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() };
2710 qCDebug(lcQpaWindow) <<
"Window has maximum size. Corrected topLeft by"
2716 const int adjust = offset.x() / window()->devicePixelRatio();
2717 window()->setWidth(window()->width() - adjust);
2718 qCDebug(lcQpaWindow) <<
"Width shortened by" << adjust <<
"logical pixels.";
2721 const int adjust = offset.y() / window()->devicePixelRatio();
2722 window()->setHeight(window()->height() - adjust);
2723 qCDebug(lcQpaWindow) <<
"Height shortened by" << adjust <<
"logical pixels.";
2730 m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
2736 setWindowState_sys(state);
2737 m_windowState = state;
2743 const QWindow *w = window();
2744 if (!w->isTopLevel())
2746 QRect geometry = geometry_sys();
2748 geometry += QMargins(1, 1, 1, 1);
2749 QPlatformScreen *screen = screenForGeometry(geometry);
2750 return screen && geometry == screen->geometry();
2754
2755
2756
2757
2758
2759
2760
2761
2762
2764void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
2766 const Qt::WindowStates oldState = m_windowState;
2767 if (oldState == newState)
2769 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window()
2770 <<
" from " << oldState <<
" to " << newState;
2773 auto stateChange = oldState ^ newState;
2775 if (stateChange & Qt::WindowFullScreen) {
2776 if (newState & Qt::WindowFullScreen) {
2777 UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
2781 if (!m_savedStyle) {
2782 m_savedStyle =
style();
2783 if ((oldState & Qt::WindowMinimized) || (oldState & Qt::WindowMaximized)) {
2784 const QRect nf = normalFrameGeometry(m_data.hwnd);
2786 m_savedFrameGeometry = nf;
2788 m_savedFrameGeometry = frameGeometry_sys();
2791 if (newState & Qt::WindowMaximized)
2793 if (m_savedStyle & WS_SYSMENU)
2794 newStyle |= WS_SYSMENU;
2796 newStyle |= WS_VISIBLE;
2797 if (testFlag(HasBorderInFullScreen))
2798 newStyle |= WS_BORDER;
2800 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2801 MONITORINFO monitorInfo = {};
2802 monitorInfo.cbSize =
sizeof(MONITORINFO);
2803 GetMonitorInfoW(monitor, &monitorInfo);
2804 const QRect screenGeometry(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
2805 monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
2806 monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
2807 if (newState & Qt::WindowMinimized) {
2808 setMinimizedGeometry(m_data.hwnd, screenGeometry);
2809 if (stateChange & Qt::WindowMaximized)
2810 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2812 const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
2815 SetWindowPos(m_data.hwnd, HWND_TOP, screenGeometry.left(), screenGeometry.top(), screenGeometry.width(), screenGeometry.height(), swpf);
2819 QWindowSystemInterface::handleGeometryChange(window(), screenGeometry);
2820 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2824 unsigned newStyle = m_savedStyle ? m_savedStyle :
style();
2826 newStyle |= WS_VISIBLE;
2829 const QScreen *screen = window()->screen();
2831 screen = QGuiApplication::primaryScreen();
2833 if (
const auto platformScreen = screen->handle()) {
2834 if (!platformScreen->geometry().intersects(m_savedFrameGeometry))
2835 m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft());
2838 if (newState & Qt::WindowMinimized) {
2839 setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry);
2840 if (stateChange & Qt::WindowMaximized)
2841 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2843 UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
2844 if (!m_savedFrameGeometry.isValid())
2845 swpf |= SWP_NOSIZE | SWP_NOMOVE;
2850 if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
2851 ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
2852 SetWindowPos(m_data.hwnd,
nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
2853 m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
2859 ShowWindow(m_data.hwnd,
2860 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
2865 m_savedFrameGeometry = QRect();
2867 }
else if ((oldState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
2868 if (visible && !(newState & Qt::WindowMinimized)) {
2870 if (newState & Qt::WindowFullScreen)
2872 if (m_data.flags & Qt::FramelessWindowHint) {
2873 if (newState == Qt::WindowNoState) {
2874 const QRect &rect = m_savedFrameGeometry;
2875 MoveWindow(m_data.hwnd, rect.x(), rect.y(), rect.width(), rect.height(),
true);
2877 HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2878 MONITORINFO monitorInfo = {};
2879 monitorInfo.cbSize =
sizeof(MONITORINFO);
2880 GetMonitorInfo(monitor, &monitorInfo);
2881 const RECT &rect = monitorInfo.rcWork;
2882 m_savedFrameGeometry = geometry();
2883 MoveWindow(m_data.hwnd, rect.left, rect.top,
2884 rect.right - rect.left, rect.bottom - rect.top,
true);
2887 ShowWindow(m_data.hwnd,
2888 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
2892 }
else if (visible && (oldState & newState & Qt::WindowMinimized)) {
2894 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2898 if (stateChange & Qt::WindowMinimized) {
2900 ShowWindow(m_data.hwnd,
2901 (newState & Qt::WindowMinimized) ? SW_MINIMIZE :
2902 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
2903 if ((newState & Qt::WindowMinimized) && (stateChange & Qt::WindowMaximized))
2904 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2907 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
this << window() << newState;
2912 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinStyle(s);
2914 SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
2920 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinExStyle(s);
2921 SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
2926 switch (event->type()) {
2927 case QEvent::ApplicationPaletteChange:
2928 setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
2930 case QEvent::WindowBlocked:
2936 case QEvent::WindowUnblocked:
2944 return QWindowsBaseWindow::windowEvent(event);
2949 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
2954 bool result =
false;
2955 if ((windowPos->flags & SWP_NOSIZE) == 0) {
2957 GetWindowRect(windowPos->hwnd, &rect);
2958 result = rect.right - rect.left != windowPos->cx || rect.bottom - rect.top != windowPos->cy;
2963bool QWindowsWindow::handleGeometryChangingMessage(MSG *message,
const QWindow *qWindow,
const QMargins &margins)
2965 auto *windowPos =
reinterpret_cast<WINDOWPOS *>(message->lParam);
2966 const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
2967 windowPos->cx, windowPos->cy);
2968 const QRect suggestedGeometry = suggestedFrameGeometry - margins;
2975 if (isResize(windowPos))
2976 windowPos->flags |= SWP_NOCOPYBITS;
2978 if ((windowPos->flags & SWP_NOZORDER) == 0) {
2979 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(qWindow)) {
2980 QWindow *parentWindow = qWindow->parent();
2981 HWND parentHWND = GetAncestor(windowPos->hwnd, GA_PARENT);
2982 HWND desktopHWND = GetDesktopWindow();
2983 platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND);
2985 if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint))
2986 windowPos->hwndInsertAfter = HWND_BOTTOM;
2988 if (!qWindow->isTopLevel())
2990 if (windowPos->flags & SWP_NOSIZE)
2992 const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
2993 if (!correctedGeometryF.isValid())
2995 const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
2996 if (correctedFrameGeometry == suggestedFrameGeometry)
2998 windowPos->x = correctedFrameGeometry.left();
2999 windowPos->y = correctedFrameGeometry.top();
3000 windowPos->cx = correctedFrameGeometry.width();
3001 windowPos->cy = correctedFrameGeometry.height();
3007 const QMargins margins = window()->isTopLevel() ? fullFrameMargins() : QMargins();
3008 return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
3013 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3015 if (m_data.fullFrameMargins != newMargins) {
3016 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << m_data.fullFrameMargins <<
"->" << newMargins;
3017 m_data.fullFrameMargins = newMargins;
3024 if (GetMenu(m_data.hwnd))
3025 QWindowsContext::forceNcCalcSize(m_data.hwnd);
3027 calculateFullFrameMargins();
3032 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3045 GetWindowRect(handle(), &windowRect);
3046 GetClientRect(handle(), &clientRect);
3052 if (qSizeOfRect(windowRect) == qSizeOfRect(clientRect))
3057 const auto systemMargins = testFlag(DisableNonClientScaling)
3058 ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd)
3059 : frameMargins_sys();
3060 const int extendedClientAreaBorder = window()->flags().testFlag(Qt::ExpandedClientAreaHint) ? qRound(QHighDpiScaling::factor(window())) * 2 : 0;
3061 const QMargins actualMargins = systemMargins + customMargins() - extendedClientAreaBorder;
3063 const int yDiff = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
3064 const bool typicalFrame = (actualMargins.left() == actualMargins.right())
3065 && (actualMargins.right() == actualMargins.bottom());
3067 const QMargins adjustedMargins = typicalFrame ?
3068 QMargins(actualMargins.left(), (yDiff - actualMargins.bottom()),
3069 actualMargins.right(), actualMargins.bottom())
3072 setFullFrameMargins(adjustedMargins);
3077 QMargins result = fullFrameMargins();
3078 if (isTopLevel() && m_data.hasFrame)
3079 result -= invisibleMargins(m_data.hwnd);
3085 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3087 return m_data.fullFrameMargins;
3092 qCDebug(lcQpaWindow) <<
__FUNCTION__ << level;
3093 if (!qFuzzyCompare(m_opacity, level)) {
3096 setWindowOpacity(m_data.hwnd, m_data.flags,
3104 return CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
3109 if (
const HRGN rectRegion = createRectRegion(rect)) {
3110 HRGN result = CreateRectRgn(0, 0, 0, 0);
3111 if (CombineRgn(result, *winRegion, rectRegion, RGN_OR)) {
3112 DeleteObject(*winRegion);
3113 *winRegion = result;
3115 DeleteObject(rectRegion);
3121 auto it = region.begin();
3122 const auto end = region.end();
3125 HRGN hRegion = createRectRegion(*it);
3127 addRectToWinRegion(*it, &hRegion);
3133 if (region.isEmpty()) {
3134 SetWindowRgn(m_data.hwnd,
nullptr,
true);
3137 const HRGN winRegion = qRegionToWinRegion(region);
3140 if (window()->isTopLevel()) {
3141 const QMargins margins = fullFrameMargins();
3142 OffsetRgn(winRegion, margins.left(), margins.top());
3146 if (!SetWindowRgn(m_data.hwnd, winRegion,
true))
3147 DeleteObject(winRegion);
3152 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
3158 if (QGuiApplication::applicationState() == Qt::ApplicationActive
3159 || activationBehavior != QWindowsApplication::AlwaysActivateWindow) {
3160 SetForegroundWindow(m_data.hwnd);
3161 SetFocus(m_data.hwnd);
3170 if (m_data.flags & Qt::WindowStaysOnBottomHint) {
3171 qCWarning(lcQpaWindow) <<
3172 "Windows with Qt::WindowStaysOnBottomHint can't be brought to the foreground.";
3175 if (m_data.flags & Qt::WindowStaysOnTopHint) {
3176 qCWarning(lcQpaWindow) <<
3177 "Windows with Qt::WindowStaysOnTopHint will always be on the foreground.";
3180 if (window()->type() == Qt::ToolTip) {
3181 qCWarning(lcQpaWindow) <<
"ToolTip windows should not be activated.";
3186 if (!IsWindowVisible(m_data.hwnd))
3187 ShowWindow(m_data.hwnd, SW_SHOW);
3189 if (IsIconic(m_data.hwnd)) {
3190 ShowWindow(m_data.hwnd, SW_RESTORE);
3197 const HWND oldForegroundWindow = GetForegroundWindow();
3198 if (!oldForegroundWindow)
3203 if (SendMessageTimeoutW(oldForegroundWindow, WM_NULL, 0, 0,
3204 SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000,
nullptr) == 0) {
3205 qCWarning(lcQpaWindow) <<
"The foreground window hangs, can't activate current window.";
3209 const DWORD windowThreadProcessId = GetWindowThreadProcessId(oldForegroundWindow,
nullptr);
3210 const DWORD currentThreadId = GetCurrentThreadId();
3212 AttachThreadInput(windowThreadProcessId, currentThreadId, TRUE);
3213 const auto cleanup = qScopeGuard([windowThreadProcessId, currentThreadId](){
3214 AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE);
3217 BringWindowToTop(m_data.hwnd);
3221 SetActiveWindow(m_data.hwnd);
3227 qWarning(
"%s: No handle",
__FUNCTION__);
3230 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << grab;
3234 context->setKeyGrabber(window());
3236 if (context->keyGrabber() == window())
3237 context->setKeyGrabber(
nullptr);
3244 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << grab;
3246 qWarning(
"%s: No handle",
__FUNCTION__);
3250 qWarning(
"%s: Not setting mouse grab for invisible window %s/'%s'",
3251 __FUNCTION__, window()->metaObject()->className(),
3252 qPrintable(window()->objectName()));
3259 SetCapture(m_data.hwnd);
3269 if (edges == Qt::LeftEdge)
3271 else if (edges == (Qt::RightEdge))
3273 else if (edges == (Qt::TopEdge))
3275 else if (edges == (Qt::TopEdge | Qt::LeftEdge))
3277 else if (edges == (Qt::TopEdge | Qt::RightEdge))
3279 else if (edges == (Qt::BottomEdge))
3281 else if (edges == (Qt::BottomEdge | Qt::LeftEdge))
3283 else if (edges == (Qt::BottomEdge | Qt::RightEdge))
3291 if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
3295 PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0);
3303 PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 , 0);
3318 QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
3319 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << *mmi;
3325 const QWindow *w = window();
3326 const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
3327 const QRect geom = geometry();
3328 static auto oldMouseButtonState = Qt::NoButton;
3330 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
3331 bool isDefaultTitleBar = !w->flags().testFlag(Qt::CustomizeWindowHint);
3332 bool isCustomized = w->flags().testFlags(Qt::CustomizeWindowHint) && w->flags().testAnyFlags(Qt::WindowTitleHint|
3333 Qt::WindowMinimizeButtonHint|
3334 Qt::WindowMaximizeButtonHint|
3335 Qt::WindowCloseButtonHint);
3336 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3337 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3338 const int titleButtonWidth = titleBarHeight * 1.5;
3339 const bool mouseButtonsSwapped = GetSystemMetrics(SM_SWAPBUTTON);
3340 auto mouseButtons = Qt::NoButton;
3341 if (mouseButtonsSwapped)
3342 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::RightButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::LeftButton : Qt::NoButton);
3344 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::LeftButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::RightButton : Qt::NoButton);
3347 if (isCustomized || isDefaultTitleBar) {
3350 if (globalPos.y() < geom.top() + titleBarHeight) {
3351 if (m_data.flags.testFlags(Qt::WindowCloseButtonHint) || isDefaultTitleBar) {
3352 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right())) {
3353 if (mouseButtons == Qt::LeftButton)
3357 }
if (m_data.flags.testFlags(Qt::WindowMaximizeButtonHint) || isDefaultTitleBar) {
3358 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3359 if (mouseButtons == Qt::LeftButton) {
3360 if (IsZoomed(m_data.hwnd))
3363 *result = HTMAXBUTTON;
3367 }
if (m_data.flags.testFlags(Qt::WindowMinimizeButtonHint) || isDefaultTitleBar) {
3368 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3369 if (mouseButtons == Qt::LeftButton)
3370 *result = HTMINBUTTON;
3373 }
if ((isCustomized || isDefaultTitleBar) &&
3374 *result == HTCLIENT){
3375 QWindow* wnd = window();
3376 if (mouseButtons != oldMouseButtonState) {
3377 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3378 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3379 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3380 if (!accepted && mouseButtons == Qt::RightButton)
3381 *result = HTSYSMENU;
3382 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3383 *result = HTCAPTION;
3387 }
else if (w->flags().testFlag(Qt::CustomizeWindowHint)) {
3389 QWindow* wnd = window();
3390 if (mouseButtons != oldMouseButtonState) {
3391 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3392 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3393 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3394 if (!accepted && mouseButtons == Qt::RightButton)
3395 *result = HTSYSMENU;
3396 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3397 *result = HTCAPTION;
3400 oldMouseButtonState = mouseButtons;
3403 const bool left = (globalPos.x() >= geom.left()) && (globalPos.x() < geom.left() + border);
3404 const bool right = (globalPos.x() > geom.right() - border) && (globalPos.x() <= geom.right());
3405 const bool top = (globalPos.y() >= geom.top()) && (globalPos.y() < geom.top() + border);
3406 const bool bottom = (globalPos.y() > geom.bottom() - border) && (globalPos.y() <= geom.bottom());
3408 if (left || right || top || bottom) {
3410 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3412 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3414 *result = top ? HTTOP : HTBOTTOM;
3420 const_cast<QWindow *>(w)->close();
3423 const_cast<QWindow *>(w)->showMaximized();
3426 const_cast<QWindow *>(w)->showMinimized();
3429 const_cast<QWindow *>(w)->showNormal();
3432 HWND hwnd =
reinterpret_cast<HWND>(w->winId());
3433 HMENU sysMenu = GetSystemMenu(hwnd,
false);
3434 TrackPopupMenu(sysMenu, 0, globalPos.x(), globalPos.y(), 0, hwnd,
nullptr);
3443 if (m_data.flags & Qt::ExpandedClientAreaHint) {
3444 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3449 const QRect rect = geom;
3450 const bool left = (globalPos.x() >= rect.left()) && (globalPos.x() < rect.left() + border);
3451 const bool right = (globalPos.x() > rect.right() - border) && (globalPos.x() <= rect.right());
3452 const bool top = (globalPos.y() >= rect.top()) && (globalPos.y() < rect.top() + border);
3453 const bool bottom = (globalPos.y() > rect.bottom() - border) && (globalPos.y() <= rect.bottom());
3456 if (left || right || top || bottom) {
3458 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3460 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3462 *result = top ? HTTOP : HTBOTTOM;
3470 if (!w->isTopLevel()
3471 || (m_windowState != Qt::WindowNoState)
3473 || (m_data.flags & Qt::FramelessWindowHint)) {
3476 const QSize minimumSize = w->minimumSize();
3477 if (minimumSize.isEmpty())
3479 const QSize maximumSize = w->maximumSize();
3480 const bool fixedWidth = minimumSize.width() == maximumSize.width();
3481 const bool fixedHeight = minimumSize.height() == maximumSize.height();
3482 if (!fixedWidth && !fixedHeight)
3484 const QSize size = w->size();
3486 if (localPos.y() >= size.height()) {
3490 if (localPos.y() < 0) {
3491 const int topResizeBarPos = invisibleMargins(m_data.hwnd).left() - frameMargins().top();
3492 if (localPos.y() < topResizeBarPos) {
3493 *result = HTCAPTION;
3498 if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
3510 if (m_data.flags & Qt::FramelessWindowHint) {
3519 HWND hwnd = m_data.hwndTitlebar;
3520 QWindow *wnd = window();
3523 GetWindowRect(hwnd, &windowRect);
3525 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3526 const int titleButtonWidth = titleBarHeight * 1.5;
3527 const qreal factor = QHighDpiScaling::factor(wnd);
3528 const int windowWidth = windowRect.right - windowRect.left;
3531 GetCursorPos(&localPos);
3532 MapWindowPoints(HWND_DESKTOP, m_data.hwnd, &localPos, 1);
3534 const bool isDarkmode = QWindowsIntegration::instance()->darkModeHandling().testFlags(QWindowsApplication::DarkModeWindowFrames) &&
3535 qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
3536 const bool isWindows11orAbove = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11;
3538 const QBrush closeButtonBrush(QColor(0xC4, 0x2C, 0x1E, 255));
3539 const QBrush minMaxButtonBrush = QBrush(isDarkmode ? QColor(0xFF, 0xFF, 0xFF, 0x40) : QColor(0x00, 0x00, 0x00, 0x20));
3540 const QBrush titleBarBackgroundColor = QBrush(isDarkmode ? QColor(0x1F, 0x1F, 0x1F, 0xFF) : QColor(0xF3, 0xF3, 0xF3, 0xFF));
3541 const QPen textPen = QPen(isDarkmode ? QColor(0xFF, 0xFF, 0xFD, 0xFF) : QColor(0x00, 0x00, 0x00, 0xFF));
3543 QImage image(windowWidth, titleBarHeight, QImage::Format_ARGB32);
3545 p.setCompositionMode(QPainter::CompositionMode_Clear);
3546 p.fillRect(0, 0, windowWidth, titleBarHeight, Qt::transparent);
3548 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
3550 p.setBrush(titleBarBackgroundColor);
3551 p.setPen(Qt::NoPen);
3552 if (!wnd->flags().testFlags(Qt::NoTitleBarBackgroundHint)) {
3554 titleRect.setWidth(windowWidth);
3555 titleRect.setHeight(titleBarHeight);
3556 p.drawRect(titleRect);
3559 if (wnd->flags().testFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3563 titleRect.setWidth(windowWidth);
3564 titleRect.setHeight(titleBarHeight);
3566 titleRect.adjust(factor * 4, 0, 0, 0);
3567 QRect iconRect(titleRect.x(), titleRect.y() + factor * 8, factor * 16, factor * 16);
3568 if (wnd->icon().isNull()) {
3569 static QIcon defaultIcon;
3570 if (defaultIcon.isNull()) {
3571 const QImage defaultIconImage = QImage::fromHICON(LoadIcon(0, IDI_APPLICATION));
3572 defaultIcon = QIcon(QPixmap::fromImage(defaultIconImage));
3574 defaultIcon.paint(&p, iconRect);
3576 wnd->icon().paint(&p, iconRect);
3578 titleRect.adjust(factor * 24, 0, 0, 0);
3582 titleFont.setPointSize(factor * 9);
3583 titleFont.setWeight(QFont::Thin);
3584 titleFont.setHintingPreference(QFont::PreferFullHinting);
3585 p.setFont(titleFont);
3586 const QString title = wnd->title().isEmpty() ? qApp->applicationName() : wnd->title();
3587 p.drawText(titleRect, title, QTextOption(Qt::AlignVCenter));
3591 const QString assetFontName = isWindows11orAbove ? QStringLiteral(
"Segoe Fluent Icons") : QStringLiteral(
"Segoe MDL2 Assets");
3592 QFont assetFont = QFont(assetFontName, factor * 7);
3593 assetFont.setWeight(QFont::Thin);
3594 assetFont.setHintingPreference(QFont::PreferFullHinting);
3595 p.setFont(assetFont);
3596 p.setBrush(closeButtonBrush);
3597 p.setPen(Qt::NoPen);
3598 if (wnd->flags().testFlags(Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3601 rect.setX(windowWidth - titleButtonWidth * buttons);
3602 rect.setWidth(titleButtonWidth);
3603 rect.setHeight(titleBarHeight);
3604 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3605 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3606 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3608 const QPen closeButtonHoveredPen = QPen(QColor(0xFF, 0xFF, 0xFD, 0xFF));
3609 p.setPen(closeButtonHoveredPen);
3613 p.drawText(rect, QStringLiteral(
"\uE8BB"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3617 p.setBrush(minMaxButtonBrush);
3618 p.setPen(Qt::NoPen);
3619 if (wnd->flags().testFlags(Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3622 rect.setX(windowWidth - titleButtonWidth * buttons);
3623 rect.setWidth(titleButtonWidth);
3624 rect.setHeight(titleBarHeight);
3625 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3626 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3627 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3631 p.drawText(rect,QStringLiteral(
"\uE922"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3635 p.setBrush(minMaxButtonBrush);
3636 p.setPen(Qt::NoPen);
3637 if (wnd->flags().testFlags(Qt::WindowMinimizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3640 rect.setX(windowWidth - titleButtonWidth * buttons);
3641 rect.setWidth(titleButtonWidth);
3642 rect.setHeight(titleBarHeight);
3643 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3644 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3645 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3649 p.drawText(rect,QStringLiteral(
"\uE921"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3655 HBITMAP bmp = image.toHBITMAP();
3657 HDC hdc = GetDC(hwnd);
3659 HDC memdc = CreateCompatibleDC(hdc);
3660 HGDIOBJ original = SelectObject(memdc, bmp);
3663 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
3664 POINT ptLocation = { 0, 0 };
3665 SIZE szWnd = { windowWidth, titleBarHeight };
3666 POINT ptSrc = { 0, 0 };
3667 UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
3668 SelectObject(hdc, original);
3671 DeleteObject(memdc);
3672 ReleaseDC(hwnd,hdc);
3679 if (QScreen *screen = w->screen())
3680 if (
const QPlatformScreen *platformScreen = screen->handle())
3681 if (QPlatformCursor *cursor = platformScreen->cursor())
3682 return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
3683 return CursorHandlePtr(
new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
3692 if (underMouse == w)
3694 for (
const QWindow *p = underMouse; p ; p = p->parent()) {
3697 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p);
3698 if (platformWindow && !platformWindow->cursor()->isNull())
3706
3707
3708
3709
3719 if (m_cursor->isNull()) {
3720 if (
const QWindow *p = window()->parent()) {
3721 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p))
3724 SetCursor(defaultCursor(window())->handle());
3727 SetCursor(m_cursor->handle());
3735 bool changed = c->handle() != m_cursor->handle();
3743 const bool apply = applyNewCursor(window());
3744 qCDebug(lcQpaWindow) << window() <<
__FUNCTION__
3745 << c->handle() <<
" doApply=" << apply;
3768 UINT timeOutMs = GetCaretBlinkTime();
3769 if (!timeOutMs || timeOutMs == INFINITE)
3773 info.cbSize =
sizeof(info);
3774 info.hwnd = m_data.hwnd;
3775 info.dwFlags = FLASHW_TRAY;
3776 info.dwTimeout = timeOutMs;
3777 info.uCount = durationMs == 0 ? 10 : UINT(durationMs) / timeOutMs;
3778 FlashWindowEx(&info);
3784 info.cbSize =
sizeof(info);
3785 info.hwnd = m_data.hwnd;
3786 info.dwFlags = FLASHW_STOP;
3789 FlashWindowEx(&info);
3794 return (style() & WS_DISABLED) == 0;
3799 const unsigned oldStyle =
style();
3800 unsigned newStyle = oldStyle;
3802 newStyle &= ~WS_DISABLED;
3804 newStyle |= WS_DISABLED;
3806 if (newStyle != oldStyle)
3812 if (!icon.isNull()) {
3814 const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)), 1);
3816 return qt_pixmapToWinHICON(pm);
3826 m_iconSmall = createHIcon(icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
3827 m_iconBig = createHIcon(icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
3830 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3831 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconBig));
3833 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3834 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconSmall));
3841 return window()->isTopLevel() && !m_data.embedded;
3851 const BOOL darkBorder = d ? TRUE : FALSE;
3856 qCWarning(lcQpaWindow,
"%s: Unable to set %s window border.",
__FUNCTION__, d ?
"dark" :
"light");
3863 d = d && shouldApplyDarkFrame(window());
3865 setDarkBorderToWindow(m_data.hwnd, d);
3870 return m_menuBar.data();
3880 if (m_data.flags & Qt::FramelessWindowHint)
3882 return m_data.customMargins;
3886
3887
3888
3889
3890
3891
3892
3893
3897 if (m_data.flags & Qt::FramelessWindowHint) {
3898 qCWarning(lcQpaWindow) <<
"You should not set custom margins for a frameless window.";
3901 if (newCustomMargins != m_data.customMargins) {
3902 const QMargins oldCustomMargins = m_data.customMargins;
3903 m_data.customMargins = newCustomMargins;
3905 const QRect currentFrameGeometry = frameGeometry_sys();
3906 const QPoint topLeft = currentFrameGeometry.topLeft();
3907 QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
3908 newFrame.moveTo(topLeft);
3909 qCDebug(lcQpaWindow) <<
__FUNCTION__ << oldCustomMargins <<
"->" << newCustomMargins
3910 << currentFrameGeometry <<
"->" << newFrame;
3911 SetWindowPos(m_data.hwnd,
nullptr, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
3917#if QT_CONFIG(vulkan)
3918 Q_UNUSED(nativeConfig);
3920 if (window()->surfaceType() == QSurface::VulkanSurface) {
3922 QVulkanInstance *inst = window()->vulkanInstance();
3924 m_vkSurface =
static_cast<QWindowsVulkanInstance *>(inst->handle())->createSurface(handle());
3926 qWarning(
"Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
3930 return &m_vkSurface;
3932#elif defined(QT_NO_OPENGL)
3934 Q_UNUSED(nativeConfig);
3951#if QT_CONFIG(vulkan)
3953 QVulkanInstance *inst = window()->vulkanInstance();
3955 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
3956 m_vkSurface = VK_NULL_HANDLE;
3963 m_surface =
nullptr;
3976 const auto currentTouchTypes = touchWindowTouchTypes_sys();
3977 if (currentTouchTypes.has_value() && currentTouchTypes.value() == touchTypes)
3981 ULONG touchFlags = 0;
3982 if (touchTypes.testFlag(TouchWindowTouchType::FineTouch))
3983 touchFlags |= TWF_FINETOUCH;
3984 if (touchTypes.testFlag(TouchWindowTouchType::WantPalmTouch))
3985 touchFlags |= TWF_WANTPALM;
3986 if (RegisterTouchWindow(m_data.hwnd, touchFlags))
3989 qErrnoWarning(
"RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
3994 if (QPlatformWindow *handle = window->handle())
3995 static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border);
4002 m_borderInFullScreenDefault = border;
4019 if (m_windowState == Qt::WindowFullScreen) {
4020 LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE);
4024 style &= ~WS_BORDER;
4025 SetWindowLongPtr(handle(), GWL_STYLE, style);
4031 return QPlatformWindow::formatWindowTitle(title, QStringLiteral(
" - "));
4041 QWindow *w = window();
4042 QDxgiVSyncService *vs = QDxgiVSyncService::instance();
4043 if (vs->supportsWindow(w)) {
4044 if (m_vsyncServiceCallbackId == 0) {
4045 m_vsyncServiceCallbackId = vs->registerCallback([
this, w](
const QDxgiVSyncService::CallbackWindowList &windowList, qint64) {
4046 if (windowList.contains(w)) {
4051 if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) {
4052 QWindowsWindow *oldSelf =
this;
4053 qsizetype oldCallbackId = m_vsyncServiceCallbackId;
4054 QMetaObject::invokeMethod(w, [w, oldSelf, oldCallbackId] {
4056 auto *self =
static_cast<QWindowsWindow *>(w->handle());
4059 if (self && self == oldSelf && self->m_vsyncServiceCallbackId == oldCallbackId) {
4061 self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready);
4062 self->deliverUpdateRequest();
4069 m_vsyncUpdatePending.testAndSetRelease(UpdateState::Ready, UpdateState::Requested);
4071 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)