4#include <QtCore/qt_windows.h>
5#include <QtGui/qstylehints.h>
10#if QT_CONFIG(draganddrop)
11# include "qwindowsdrag.h"
17#if QT_CONFIG(dynamicgl)
18# include "qwindowsglcontext.h"
24# include "qwindowscursor.h"
29#include <QtGui/qguiapplication.h>
30#include <QtGui/qscreen.h>
31#include <QtGui/qwindow.h>
32#include <QtGui/qregion.h>
33#include <QtGui/qopenglcontext.h>
34#include <QtGui/qpainterpath.h>
35#include <QtGui/private/qwindowsthemecache_p.h>
36#include <private/qwindow_p.h>
37#include <private/qguiapplication_p.h>
38#include <private/qhighdpiscaling_p.h>
39#include <qpa/qwindowsysteminterface.h>
40#include <private/qsystemlibrary_p.h>
41#include <private/qwinregistry_p.h>
44#include <QtCore/qdebug.h>
45#include <QtCore/qlibraryinfo.h>
46#include <QtCore/qoperatingsystemversion.h>
51#include "qwindowsvulkaninstance.h"
54#include <shellscalingapi.h>
56#include <private/qdxgivsyncservice_p.h>
59# define GWL_HWNDPARENT (-8
)
64using namespace Qt::StringLiterals;
66using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>;
73Q_GUI_EXPORT HICON qt_pixmapToWinHICON(
const QPixmap &);
78 rc += QByteArray::number(qulonglong(style), 16);
83 if (style & WS_OVERLAPPED)
84 rc +=
" WS_OVERLAPPED";
85 if (style & WS_CLIPSIBLINGS)
86 rc +=
" WS_CLIPSIBLINGS";
87 if (style & WS_CLIPCHILDREN)
88 rc +=
" WS_CLIPCHILDREN";
89 if (style & WS_THICKFRAME)
90 rc +=
" WS_THICKFRAME";
91 if (style & WS_DLGFRAME)
93 if (style & WS_SYSMENU)
95 if (style & WS_MINIMIZEBOX)
96 rc +=
" WS_MINIMIZEBOX";
97 if (style & WS_MAXIMIZEBOX)
98 rc +=
" WS_MAXIMIZEBOX";
99 if (style & WS_BORDER)
101 if (style & WS_CAPTION)
103 if (style & WS_CHILDWINDOW)
104 rc +=
" WS_CHILDWINDOW";
105 if (style & WS_DISABLED)
106 rc +=
" WS_DISABLED";
107 if (style & WS_GROUP)
109 if (style & WS_HSCROLL)
111 if (style & WS_ICONIC)
113 if (style & WS_MAXIMIZE)
114 rc +=
" WS_MAXIMIZE";
115 if (style & WS_MINIMIZE)
116 rc +=
" WS_MINIMIZE";
117 if (style & WS_SIZEBOX)
119 if (style & WS_TABSTOP)
121 if (style & WS_TILED)
123 if (style & WS_VISIBLE)
125 if (style & WS_VSCROLL)
132 QByteArray rc =
"0x";
133 rc += QByteArray::number(qulonglong(exStyle), 16);
134 if (exStyle & WS_EX_TOOLWINDOW)
135 rc +=
" WS_EX_TOOLWINDOW";
136 if (exStyle & WS_EX_CONTEXTHELP)
137 rc +=
" WS_EX_CONTEXTHELP";
138 if (exStyle & WS_EX_LAYERED)
139 rc +=
" WS_EX_LAYERED";
140 if (exStyle & WS_EX_DLGMODALFRAME)
141 rc +=
" WS_EX_DLGMODALFRAME";
142 if (exStyle & WS_EX_LAYOUTRTL)
143 rc +=
" WS_EX_LAYOUTRTL";
144 if (exStyle & WS_EX_NOINHERITLAYOUT)
145 rc +=
" WS_EX_NOINHERITLAYOUT";
146 if (exStyle & WS_EX_ACCEPTFILES)
147 rc +=
" WS_EX_ACCEPTFILES";
148 if (exStyle & WS_EX_APPWINDOW)
149 rc +=
" WS_EX_APPWINDOW";
150 if (exStyle & WS_EX_CLIENTEDGE)
151 rc +=
" WS_EX_CLIENTEDGE";
152 if (exStyle & WS_EX_COMPOSITED)
153 rc +=
" WS_EX_COMPOSITED";
154 if (exStyle & WS_EX_CONTROLPARENT)
155 rc +=
" WS_EX_CONTROLPARENT";
156 if (exStyle & WS_EX_LEFT)
158 if (exStyle & WS_EX_LEFTSCROLLBAR)
159 rc +=
" WS_EX_LEFTSCROLLBAR";
160 if (exStyle & WS_EX_LTRREADING)
161 rc +=
" WS_EX_LTRREADING";
162 if (exStyle & WS_EX_MDICHILD)
163 rc +=
" WS_EX_MDICHILD";
164 if (exStyle & WS_EX_NOACTIVATE)
165 rc +=
" WS_EX_NOACTIVATE";
166 if (exStyle & WS_EX_NOPARENTNOTIFY)
167 rc +=
" WS_EX_NOPARENTNOTIFY";
168 if (exStyle & WS_EX_NOREDIRECTIONBITMAP)
169 rc +=
" WS_EX_NOREDIRECTIONBITMAP";
170 if (exStyle & WS_EX_RIGHT)
171 rc +=
" WS_EX_RIGHT";
172 if (exStyle & WS_EX_RIGHTSCROLLBAR)
173 rc +=
" WS_EX_RIGHTSCROLLBAR";
174 if (exStyle & WS_EX_RTLREADING)
175 rc +=
" WS_EX_RTLREADING";
176 if (exStyle & WS_EX_STATICEDGE)
177 rc +=
" WS_EX_STATICEDGE";
178 if (exStyle & WS_EX_TOPMOST)
179 rc +=
" WS_EX_TOPMOST";
180 if (exStyle & WS_EX_TRANSPARENT)
181 rc +=
" WS_EX_TRANSPARENT";
182 if (exStyle & WS_EX_WINDOWEDGE)
183 rc +=
" WS_EX_WINDOWEDGE";
189 QByteArray rc =
"0x";
190 rc += QByteArray::number(flags, 16);
191 if (flags & SWP_FRAMECHANGED)
192 rc +=
" SWP_FRAMECHANGED";
193 if (flags & SWP_HIDEWINDOW)
194 rc +=
" SWP_HIDEWINDOW";
195 if (flags & SWP_NOACTIVATE)
196 rc +=
" SWP_NOACTIVATE";
197 if (flags & SWP_NOCOPYBITS)
198 rc +=
" SWP_NOCOPYBITS";
199 if (flags & SWP_NOMOVE)
201 if (flags & SWP_NOOWNERZORDER)
202 rc +=
" SWP_NOOWNERZORDER";
203 if (flags & SWP_NOREDRAW)
204 rc +=
" SWP_NOREDRAW";
205 if (flags & SWP_NOSENDCHANGING)
206 rc +=
" SWP_NOSENDCHANGING";
207 if (flags & SWP_NOSIZE)
209 if (flags & SWP_NOZORDER)
210 rc +=
" SWP_NOZORDER";
211 if (flags & SWP_SHOWWINDOW)
212 rc +=
" SWP_SHOWWINDOW";
213 if (flags & SWP_ASYNCWINDOWPOS)
214 rc +=
" SWP_ASYNCWINDOWPOS";
215 if (flags & SWP_DEFERERASE)
216 rc +=
" SWP_DEFERERASE";
217 if (flags & SWP_DRAWFRAME)
218 rc +=
" SWP_DRAWFRAME";
219 if (flags & SWP_NOREPOSITION)
220 rc +=
" SWP_NOREPOSITION";
226 QByteArray rc =
"0x";
227 rc += QByteArray::number(flags, 16);
228 if (flags & WPF_SETMINPOSITION)
229 rc +=
" WPF_SETMINPOSITION";
230 if (flags & WPF_RESTORETOMAXIMIZED)
231 rc +=
" WPF_RESTORETOMAXIMIZED";
232 if (flags & WPF_ASYNCWINDOWPLACEMENT)
233 rc +=
" WPF_ASYNCWINDOWPLACEMENT";
240 rc += QByteArray::number(cmd);
243 if (cmd == SW_SHOWNORMAL)
244 rc +=
" SW_SHOWNORMAL";
245 if (cmd == SW_NORMAL)
247 if (cmd == SW_SHOWMINIMIZED)
248 rc +=
" SW_SHOWMINIMIZED";
249 if (cmd == SW_SHOWMAXIMIZED)
250 rc +=
" SW_SHOWMAXIMIZED";
251 if (cmd == SW_MAXIMIZE)
252 rc +=
" SW_MAXIMIZE";
253 if (cmd == SW_SHOWNOACTIVATE)
254 rc +=
" SW_SHOWNOACTIVATE";
257 if (cmd == SW_MINIMIZE)
258 rc +=
" SW_MINIMIZE";
259 if (cmd == SW_SHOWMINNOACTIVE)
260 rc +=
" SW_SHOWMINNOACTIVE";
261 if (cmd == SW_SHOWNA)
263 if (cmd == SW_RESTORE)
265 if (cmd == SW_SHOWDEFAULT)
266 rc +=
" SW_SHOWDEFAULT";
267 if (cmd == SW_FORCEMINIMIZE)
268 rc +=
" SW_FORCEMINIMIZE";
274 return QSize(rect.right -rect.left, rect.bottom - rect.top);
279 return QRect(
QPoint(rect.left, rect.top), qSizeOfRect(rect));
284 const int x = rect.left();
285 const int y = rect.top();
286 RECT result = { x, y, x + rect.width(), y + rect.height() };
290#ifndef QT_NO_DEBUG_STREAM
291QDebug operator<<(QDebug d,
const RECT &r)
293 QDebugStateSaver saver(d);
295 d <<
"RECT(left=" << r.left <<
", top=" << r.top
296 <<
", right=" << r.right <<
", bottom=" << r.bottom
297 <<
" (" << r.right - r.left <<
'x' << r.bottom - r.top <<
"))";
301QDebug operator<<(QDebug d,
const POINT &p)
303 QDebugStateSaver saver(d);
305 d <<
"POINT(x=" << p.x <<
", y=" << p.y <<
')';
309QDebug operator<<(QDebug d,
const WINDOWPOS &wp)
311 QDebugStateSaver saver(d);
314 d <<
"WINDOWPOS(flags=" << debugWinSwpPos(wp.flags) <<
", hwnd="
315 << wp.hwnd <<
", hwndInsertAfter=" << wp.hwndInsertAfter <<
", x=" << wp.x
316 <<
", y=" << wp.y <<
", cx=" << wp.cx <<
", cy=" << wp.cy <<
')';
320QDebug operator<<(QDebug d,
const NCCALCSIZE_PARAMS &p)
322 QDebugStateSaver saver(d);
324 d <<
"NCCALCSIZE_PARAMS(rgrc=[" << p.rgrc[0] <<
", " << p.rgrc[1] <<
", "
325 << p.rgrc[2] <<
"], lppos=" << *p.lppos <<
')';
329QDebug operator<<(QDebug d,
const MINMAXINFO &i)
331 QDebugStateSaver saver(d);
333 d <<
"MINMAXINFO(maxSize=" << i.ptMaxSize <<
", "
334 <<
"maxpos=" << i.ptMaxPosition <<
", "
335 <<
"maxtrack=" << i.ptMaxTrackSize <<
", "
336 <<
"mintrack=" << i.ptMinTrackSize <<
')';
340QDebug operator<<(QDebug d,
const WINDOWPLACEMENT &wp)
342 QDebugStateSaver saver(d);
345 d <<
"WINDOWPLACEMENT(flags=" << debugWindowPlacementFlags(wp.flags) <<
", showCmd="
346 << debugShowWindowCmd(wp.showCmd) <<
", ptMinPosition=" << wp.ptMinPosition
347 <<
", ptMaxPosition=" << wp.ptMaxPosition <<
", rcNormalPosition="
348 << wp.rcNormalPosition <<
')';
352QDebug operator<<(QDebug d,
const GUID &guid)
354 QDebugStateSaver saver(d);
356 d <<
'{' << Qt::hex << Qt::uppercasedigits << qSetPadChar(u'0')
357 << qSetFieldWidth(8) << guid.Data1
358 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
359 << guid.Data2 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
360 << guid.Data3 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(4)
361 << qSetFieldWidth(2) << guid.Data4[0] << guid.Data4[1]
362 << qSetFieldWidth(0) <<
'-' << qSetFieldWidth(2);
363 for (
int i = 2; i < 8; ++i)
365 d << qSetFieldWidth(0) <<
'}';
372 d << r.width() <<
'x' << r.height() << Qt::forcesign << r.x() << r.y() << Qt::noforcesign;
377 d << m.left() <<
", " << m.top() <<
", " << m.right() <<
", " << m.bottom();
384 if (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
387 const QWindowsScreen *screen = screenManager.screens().size() == 1
388 ? screenManager.screens().constFirst() : screenManager
.screenAtDp(point
);
390 return screen->availableGeometry().topLeft() - screen->geometry().topLeft();
398 RECT rect = { 0, 0, 0, 0 };
400 WINDOWPLACEMENT windowPlacement;
401 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
402 GetWindowPlacement(hwnd, &windowPlacement);
403 if (windowPlacement.showCmd == SW_SHOWMINIMIZED) {
404 const QRect result = qrectFromRECT(windowPlacement.rcNormalPosition);
405 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
408 GetWindowRect(hwnd, &rect);
409 const HWND parent = GetParent(hwnd);
410 if (parent && !topLevel) {
411 const int width = rect.right - rect.left;
412 const int height = rect.bottom - rect.top;
413 POINT leftTop = { rect.left, rect.top };
414 screenToClient(parent, &leftTop);
415 rect.left = leftTop.x;
416 rect.top = leftTop.y;
417 rect.right = leftTop.x + width;
418 rect.bottom = leftTop.y + height;
420 return qrectFromRECT(rect);
426 if (!IsWindowVisible(hwnd))
427 return QWindow::Hidden;
428 WINDOWPLACEMENT windowPlacement;
429 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
430 if (GetWindowPlacement(hwnd, &windowPlacement)) {
431 switch (windowPlacement.showCmd) {
432 case SW_SHOWMINIMIZED:
434 case SW_FORCEMINIMIZE:
435 return QWindow::Minimized;
436 case SW_SHOWMAXIMIZED:
437 return QWindow::Maximized;
442 return QWindow::Windowed;
447 switch (w->surfaceType()) {
448 case QSurface::OpenGLSurface:
449 case QSurface::VulkanSurface:
450 case QSurface::Direct3DSurface:
459 DWM_BLURBEHIND blurBehind = {0, 0,
nullptr, 0};
461 blurBehind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
462 blurBehind.fEnable = TRUE;
463 blurBehind.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
465 const bool result = DwmEnableBlurBehindWindow(hwnd, &blurBehind) == S_OK;
467 if (blurBehind.hRgnBlur)
468 DeleteObject(blurBehind.hRgnBlur);
476 if ((flags & Qt::MSWindowsFixedSizeDialogHint) || !(flags & Qt::WindowMaximizeButtonHint))
480 return (flags & Qt::CustomizeWindowHint) ||
481 w->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX);
486 const LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
487 return (style & WS_CHILD) || (flags & Qt::FramelessWindowHint);
493bool QWindowsWindow::setWindowLayered(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha, qreal opacity)
495 const LONG_PTR exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
497 const bool needsLayered = (flags & Qt::WindowTransparentForInput)
498 || (hasAlpha && hasNoNativeFrame(hwnd, flags)) || opacity < 1.0;
499 const bool isLayered = (exStyle & WS_EX_LAYERED);
500 if (needsLayered != isLayered) {
502 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);
504 SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);
510static void setWindowOpacity(HWND hwnd, Qt::WindowFlags flags,
bool hasAlpha,
bool accelerated, qreal level)
512 if (QWindowsWindow::setWindowLayered(hwnd, flags, hasAlpha, level)) {
513 const BYTE alpha = BYTE(qRound(255.0 * level));
514 if (hasAlpha && !accelerated && QWindowsWindow::hasNoNativeFrame(hwnd, flags)) {
516 BLENDFUNCTION blend = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA};
517 UpdateLayeredWindow(hwnd,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr, 0, &blend, ULW_ALPHA);
519 SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
521 }
else if (IsWindowVisible(hwnd)) {
522 InvalidateRect(hwnd,
nullptr, TRUE);
531 return GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
532 + GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
536
537
538
542 POINT pt = {screenPoint.x(), screenPoint.y()};
543 if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
546 if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
547 const int gap = getResizeBorderThickness(dpiX);
548 return QMargins(gap, 0, gap, gap);
556 const UINT dpi = GetDpiForWindow(hwnd);
557 const int gap = getResizeBorderThickness(dpi);
558 return QMargins(gap, 0, gap, gap);
562
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
594 void fromWindow(
const QWindow *w,
const Qt::WindowFlags flags,
unsigned creationFlags = 0);
597 void initialize(
const QWindow *w, HWND h,
bool frameChange, qreal opacityLevel)
const;
614 QDebugStateSaver saver(debug);
617 debug <<
"WindowCreationData: " << d.flags
620 debug <<
" parent=" << d.parentHandle;
621 debug <<
" popup=" << d.popup <<
" dialog=" << d.dialog
622 <<
" embedded=" << d.embedded <<
" tool=" << d.tool
623 <<
"\n style=" << debugWinStyle(d.style);
625 debug <<
"\n exStyle=" << debugWinExStyle(d.exStyle);
633 flags &= ~Qt::WindowFullscreenButtonHint;
636 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint
637 |Qt::WindowMaximizeButtonHint|Qt::WindowCloseButtonHint;
641 flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint;
646 if ((flags & Qt::WindowType_Mask) == Qt::SplashScreen)
647 flags |= Qt::FramelessWindowHint;
652 const auto getDeviceName = [](
const QScreen *screen) -> QString {
653 if (
const auto s =
static_cast<
const QWindowsScreen *>(screen->handle()))
654 return s->data().deviceName;
657 QScreen *winScreen = w ? w->screen() : QGuiApplication::primaryScreen();
658 if (winScreen && getDeviceName(winScreen) != name) {
659 const auto screens = winScreen->virtualSiblings();
660 for (QScreen *screen : screens) {
661 if (getDeviceName(screen) == name)
668static QPoint calcPosition(
const QWindow *w,
const QWindowCreationContextPtr &context,
const QMargins &invMargins)
670 const QPoint orgPos(context->frameX - invMargins.left(), context->frameY - invMargins.top());
672 if (!w || w->type() != Qt::Window)
676 const QScreen *screenForGL = QWindowsWindow::forcedScreenForGLWindow(w);
680 const QPoint posFrame(context->frameX, context->frameY);
681 const QMargins margins = context->margins;
682 const QRect scrGeo = screenForGL->handle()->availableGeometry();
685 if (scrGeo.contains(orgPos))
690 if (scrGeo.contains(posFrame))
694 const auto screens = screenForGL->virtualSiblings();
695 const QScreen *orgScreen =
nullptr;
696 for (QScreen *screen : screens) {
697 if (screen->handle()->availableGeometry().contains(posFrame)) {
702 const QPoint ctPos = QPoint(qMax(scrGeo.left(), scrGeo.center().x()
703 + (margins.right() - margins.left() - context->frameWidth)/2),
704 qMax(scrGeo.top(), scrGeo.center().y()
705 + (margins.bottom() - margins.top() - context->frameHeight)/2));
711 const QRect orgGeo = orgScreen->handle()->availableGeometry();
712 const QRect orgFrame(
QPoint(context->frameX, context->frameY),
713 QSize(context->frameWidth, context->frameHeight));
716 if (orgGeo.center() == (orgFrame - margins).center())
720 const QPoint newPos(scrGeo.left() + ((posFrame.x() - orgGeo.left()) * scrGeo.width()) / orgGeo.width(),
721 scrGeo.top() + ((posFrame.y() - orgGeo.top()) * scrGeo.height()) / orgGeo.height());
722 const QPoint newPosNoMargin(newPos.x() - invMargins.left(), newPos.y() - invMargins.top());
724 return scrGeo.contains(newPosNoMargin) ? newPosNoMargin : newPos;
728 unsigned creationFlags)
735 QVariant prop = w->property(QWindowsWindow::embeddedNativeParentHandleProperty);
736 if (prop.isValid()) {
738 parentHandle =
reinterpret_cast<HWND>(prop.value<WId>());
752 fixTopLevelWindowFlags(flags);
754 type =
static_cast<Qt::WindowType>(
int(flags) & Qt::WindowType_Mask);
770 if ((flags & Qt::MSWindowsFixedSizeDialogHint))
779 if (QGuiApplication::layoutDirection() == Qt::RightToLeft
780 && (QWindowsIntegration::instance()->options() & QWindowsIntegration::RtlEnabled) != 0) {
781 exStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
786 flags |= Qt::WindowStaysOnTopHint;
788 if (
const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
789 parentHandle = QWindowsWindow::handleOf(parentWindow);
792 if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
795 if (flags & Qt::FramelessWindowHint)
797 else if (flags & Qt::WindowTitleHint)
798 style = WS_OVERLAPPED;
805 style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
807 if (flags & Qt::WindowDoesNotAcceptFocus)
808 exStyle |= WS_EX_NOACTIVATE;
811 if ((type == Qt::Window || dialog || tool)) {
812 if (!(flags & Qt::FramelessWindowHint)) {
814 if (flags & Qt::MSWindowsFixedSizeDialogHint) {
815 style |= WS_DLGFRAME;
817 style |= WS_THICKFRAME;
819 if (flags & Qt::WindowTitleHint)
822 if (flags & Qt::WindowSystemMenuHint)
824 else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
825 style |= WS_SYSMENU | WS_BORDER;
826 exStyle |= WS_EX_DLGMODALFRAME;
828 const bool showMinimizeButton = flags & Qt::WindowMinimizeButtonHint;
829 if (showMinimizeButton)
830 style |= WS_MINIMIZEBOX;
831 const bool showMaximizeButton = shouldShowMaximizeButton(w, flags);
832 if (showMaximizeButton)
833 style |= WS_MAXIMIZEBOX;
834 if (showMinimizeButton || showMaximizeButton)
837 exStyle |= WS_EX_TOOLWINDOW;
838 if ((flags & Qt::WindowContextHelpButtonHint) && !showMinimizeButton
839 && !showMaximizeButton)
840 exStyle |= WS_EX_CONTEXTHELP;
842 exStyle |= WS_EX_TOOLWINDOW;
847 if (flagsIn & Qt::WindowTransparentForInput)
848 exStyle |= WS_EX_TRANSPARENT;
851 if (qEnvironmentVariableIntValue(
"QT_QPA_DISABLE_REDIRECTION_SURFACE"))
852 exStyle |= WS_EX_NOREDIRECTIONBITMAP;
858 if (!w->isTopLevel() || w->flags().testFlag(Qt::FramelessWindowHint))
867 auto *dWindow = QWindowPrivate::get(
const_cast<QWindow*>(w));
868 const QPalette windowPal = dWindow->windowPalette();
869 return windowPal.color(QPalette::WindowText).lightness()
870 > windowPal.color(QPalette::Window).lightness();
876 return getResizeBorderThickness(dpi) +
877 ::GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
884 result.flags = flags;
886 const auto appinst =
reinterpret_cast<HINSTANCE>(GetModuleHandle(
nullptr));
891 windowTitlebarDescription.name =
"_q_titlebar"_L1;
892 windowTitlebarDescription.style = CS_VREDRAW | CS_HREDRAW;
896 const QScreen *screen{};
897 const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
898 defaultWindowWidth, defaultWindowHeight,
901 if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
902 title =
topLevel ? qAppName() : w->objectName();
904 const auto *titleUtf16 =
reinterpret_cast<
const wchar_t *>(title.utf16());
905 const auto *classNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowClassName.utf16());
906 const auto *classTitleBarNameUtf16 =
reinterpret_cast<
const wchar_t *>(windowTitlebarName.utf16());
911 rect, data.customMargins,
915 const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME))
916 && !(result.flags & Qt::FramelessWindowHint);
917 QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w)
918 ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();
920 qCDebug(lcQpaWindow).nospace()
921 <<
"CreateWindowEx: " << w <<
" class=" << windowClassName <<
" title=" << title
922 <<
'\n' << *
this <<
"\nrequested: " << rect <<
": "
923 << context->frameWidth <<
'x' << context->frameHeight
924 <<
'+' << context->frameX <<
'+' << context->frameY
925 <<
" custom margins: " << context->customMargins
926 <<
" invisible margins: " << invMargins;
929 QPoint pos = calcPosition(w, context, invMargins);
932 int mirrorParentWidth = 0;
933 if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) {
935 GetClientRect(parentHandle, &rect);
936 mirrorParentWidth = rect.right;
938 if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT)
939 pos.setX(mirrorParentWidth - context->frameWidth - pos.x());
941 result.hwnd = CreateWindowEx(
exStyle, classNameUtf16, titleUtf16,
944 context->frameWidth, context->frameHeight,
945 parentHandle,
nullptr, appinst,
nullptr);
947 const UINT dpi = ::GetDpiForWindow(result.hwnd);
948 const int titleBarHeight = getTitleBarHeight_sys(dpi);
949 result.hwndTitlebar = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,
950 classTitleBarNameUtf16, classTitleBarNameUtf16,
952 context->frameWidth, titleBarHeight,
953 nullptr,
nullptr, appinst,
nullptr);
955 qCDebug(lcQpaWindow).nospace()
956 <<
"CreateWindowEx: returns " << w <<
' ' << result.hwnd <<
" obtained geometry: "
957 << context->obtainedPos << context->obtainedSize <<
' ' << context->margins;
960 qErrnoWarning(
"%s: CreateWindowEx failed",
__FUNCTION__);
964 if (QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark && shouldApplyDarkFrame(w))
965 QWindowsWindow::setDarkBorderToWindow(result.hwnd,
true);
967 if (mirrorParentWidth != 0) {
968 context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
969 - context->obtainedPos.x());
972 QRect obtainedGeometry(context->obtainedPos, context->obtainedSize);
974 result.geometry = obtainedGeometry;
975 result.restoreGeometry = frameGeometry(result.hwnd, topLevel);
976 result.fullFrameMargins = context->margins;
979 result.customMargins = context->customMargins;
987 const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
988 const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
990 const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
991 if (oldStyle != newStyle)
992 SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
993 const LONG_PTR newExStyle =
exStyle;
994 if (newExStyle != oldExStyle)
995 SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
996 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << hwnd << *
this
997 <<
"\n Style from " << debugWinStyle(DWORD(oldStyle)) <<
"\n to "
998 << debugWinStyle(DWORD(newStyle)) <<
"\n ExStyle from "
999 << debugWinExStyle(DWORD(oldExStyle)) <<
" to "
1000 << debugWinExStyle(DWORD(newExStyle));
1007 UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER;
1009 swpFlags |= SWP_FRAMECHANGED;
1011 swpFlags |= SWP_NOACTIVATE;
1012 if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) {
1013 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, swpFlags);
1014 if (flags & Qt::WindowStaysOnBottomHint)
1015 qWarning(
"QWidget: Incompatible window flags: the window can't be on top and on bottom at the same time");
1016 }
else if (flags & Qt::WindowStaysOnBottomHint) {
1017 SetWindowPos(hwnd, HWND_BOTTOM, 0, 0, 0, 0, swpFlags);
1018 }
else if (frameChange) {
1019 SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, swpFlags);
1021 if (flags & (Qt::CustomizeWindowHint|Qt::WindowTitleHint)) {
1022 HMENU systemMenu = GetSystemMenu(hwnd, FALSE);
1023 if (flags & Qt::WindowCloseButtonHint)
1024 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_ENABLED);
1026 EnableMenuItem(systemMenu, SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
1028 if (flags & Qt::ExpandedClientAreaHint) {
1029 MARGINS margins = { -1, -1, -1, -1 };
1030 DwmExtendFrameIntoClientArea(hwnd, &margins);
1032 MARGINS margins = { 0, 0, 0, 0 };
1033 DwmExtendFrameIntoClientArea(hwnd, &margins);
1036 SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
1040 const bool hasAlpha = w->format().hasAlpha();
1041 if (isAccelerated && hasAlpha)
1042 applyBlurBehindWindow(hwnd);
1043 setWindowOpacity(hwnd, flags, hasAlpha, isAccelerated, opacityLevel);
1050 if (QHighDpiScaling::isActive()) {
1051 const qreal factor = QHighDpiScaling::factor(s);
1052 if (!qFuzzyCompare(factor, qreal(1))) {
1053 if (dip.width() > 0 && dip.width() < QWINDOWSIZE_MAX)
1054 dip.setWidth(qRound(qreal(dip.width()) * factor));
1055 if (dip.height() > 0 && dip.height() < QWINDOWSIZE_MAX)
1056 dip.setHeight(qRound(qreal(dip.height()) * factor));
1066 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1073 DWORD style = hwnd !=
nullptr ? DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)) : 0;
1074 return flags.testFlag(Qt::FramelessWindowHint) && !(style & WS_MAXIMIZE);
1078
1079
1080
1081
1082
1083
1084
1085
1089 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1091 RECT rect = {0,0,0,0};
1092 style &= ~DWORD(WS_OVERLAPPED);
1093 if (AdjustWindowRectEx(&rect, style, FALSE, exStyle) == FALSE)
1094 qErrnoWarning(
"%s: AdjustWindowRectEx failed",
__FUNCTION__);
1095 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1096 qAbs(rect.right), qAbs(rect.bottom));
1097 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1098 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1099 <<
' ' << rect <<
' ' << result;
1105 return frameOnPrimaryScreen(w, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1106 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1111 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1113 RECT rect = {0,0,0,0};
1114 style &= ~DWORD(WS_OVERLAPPED);
1115 if (AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle,
unsigned(qRound(dpi))) == FALSE) {
1116 qErrnoWarning(
"%s: AdjustWindowRectExForDpi failed",
__FUNCTION__);
1118 const QMargins result(qAbs(rect.left), qAbs(rect.top),
1119 qAbs(rect.right), qAbs(rect.bottom));
1120 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ <<
" style="
1121 << Qt::showbase << Qt::hex << style <<
" exStyle=" << exStyle << Qt::dec << Qt::noshowbase
1123 <<
' ' << rect <<
' ' << result;
1129 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1131 if (QWindowsScreenManager::isSingleScreen())
1132 return frameOnPrimaryScreen(w, style, exStyle);
1134 auto screen = screenManager.screenForHwnd(hwnd);
1136 screen = screenManager.screens().value(0);
1137 const auto dpi = screen ? screen->logicalDpi().first : qreal(96);
1138 return frame(w, style, exStyle, dpi);
1143 return frame(w, hwnd, DWORD(GetWindowLongPtr(hwnd, GWL_STYLE)),
1144 DWORD(GetWindowLongPtr(hwnd, GWL_EXSTYLE)));
1149 DWORD style, DWORD exStyle)
1151 if (!w->isTopLevel() || shouldOmitFrameAdjustment(w->flags(), style))
1154 || !QWindowsContext::shouldHaveNonClientDpiScaling(w)) {
1155 return frameOnPrimaryScreen(w, style, exStyle);
1161 screen = screenManager.screens().value(0);
1163 dpi = screen->logicalDpi().first;
1164 return QWindowsGeometryHint::frame(w, style, exStyle, dpi);
1167bool QWindowsGeometryHint::handleCalculateSize(
const QWindow *window,
const QMargins &customMargins,
const MSG &msg, LRESULT *result)
1170 if (msg.wParam && window->flags() & Qt::FramelessWindowHint) {
1174 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window);
1176 const bool clientAreaExpanded = platformWindow !=
nullptr ? platformWindow->isClientAreaExpanded() : window->flags() & Qt::ExpandedClientAreaHint;
1178 if (msg.wParam && clientAreaExpanded) {
1180 const bool maximized = IsZoomed(msg.hwnd) && window->visibility() != QWindow::FullScreen;
1181 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1182 RECT *clientArea = &ncp->rgrc[0];
1183 const int border = getResizeBorderThickness(96);
1185 clientArea->top += border;
1186 clientArea->bottom -= border;
1187 clientArea->left += border;
1188 clientArea->right -= border;
1193 if (!msg.wParam || customMargins.isNull())
1195 *result = DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
1196 auto *ncp =
reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
1197 const RECT oldClientArea = ncp->rgrc[0];
1198 ncp->rgrc[0].left += customMargins.left();
1199 ncp->rgrc[0].top += customMargins.top();
1200 ncp->rgrc[0].right -= customMargins.right();
1201 ncp->rgrc[0].bottom -= customMargins.bottom();
1203 qCDebug(lcQpaWindow).nospace() <<
__FUNCTION__ << oldClientArea <<
'+' << customMargins <<
"-->"
1204 << ncp->rgrc[0] <<
' ' << ncp->rgrc[1] <<
' ' << ncp->rgrc[2]
1205 <<
' ' << ncp->lppos->cx <<
',' << ncp->lppos->cy;
1210 const QMargins &margins,
1211 QSize *minimumSize, QSize *maximumSize)
1213 *minimumSize = toNativeSizeConstrained(w->minimumSize(), screen);
1214 *maximumSize = toNativeSizeConstrained(w->maximumSize(), screen);
1216 const int maximumWidth = qMax(maximumSize->width(), minimumSize->width());
1217 const int maximumHeight = qMax(maximumSize->height(), minimumSize->height());
1218 const int frameWidth = margins.left() + margins.right();
1219 const int frameHeight = margins.top() + margins.bottom();
1221 if (minimumSize->width() > 0)
1222 minimumSize->rwidth() += frameWidth;
1223 if (minimumSize->height() > 0)
1224 minimumSize->rheight() += frameHeight;
1225 if (maximumWidth < QWINDOWSIZE_MAX)
1226 maximumSize->setWidth(maximumWidth + frameWidth);
1227 if (maximumHeight < QWINDOWSIZE_MAX)
1228 maximumSize->setHeight(maximumHeight + frameHeight);
1232 const QScreen *screen,
1233 const QMargins &margins,
1238 frameSizeConstraints(w, screen, margins, &minimumSize, &maximumSize);
1239 qCDebug(lcQpaWindow).nospace() <<
'>' <<
__FUNCTION__ <<
'<' <<
" min="
1240 << minimumSize.width() <<
',' << minimumSize.height()
1241 <<
" max=" << maximumSize.width() <<
',' << maximumSize.height()
1242 <<
" margins=" << margins
1245 if (minimumSize.width() > 0)
1246 mmi->ptMinTrackSize.x = minimumSize.width();
1247 if (minimumSize.height() > 0)
1248 mmi->ptMinTrackSize.y = minimumSize.height();
1250 if (maximumSize.width() < QWINDOWSIZE_MAX)
1251 mmi->ptMaxTrackSize.x = maximumSize.width();
1252 if (maximumSize.height() < QWINDOWSIZE_MAX)
1253 mmi->ptMaxTrackSize.y = maximumSize.height();
1254 qCDebug(lcQpaWindow).nospace() <<
'<' <<
__FUNCTION__ <<
" out " << *mmi;
1258 const QMargins &margins,
1261 applyToMinMaxInfo(w, w->screen(), margins, mmi);
1266 return qt_window_private(
const_cast<QWindow *>(w))->positionPolicy
1267 == QWindowPrivate::WindowFrameInclusive;
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1289 return (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL) != 0;
1295 if (QPlatformWindow *pw = w->handle())
1296 return static_cast<QWindowsBaseWindow *>(pw);
1304 return bw ? bw->handle() : HWND(
nullptr);
1309 const HWND parent = parentHwnd();
1310 return !parent || parent == GetDesktopWindow();
1315 return frameGeometry(handle(), isTopLevel());
1320 return frameGeometry_sys().marginsRemoved(fullFrameMargins());
1325 return QWindowsGeometryHint::frame(window(), handle(), style(), exStyle());
1331 ULONG touchFlags = 0;
1332 if (IsTouchWindow(handle(), &touchFlags) == FALSE)
1334 TouchWindowTouchTypes result;
1335 if ((touchFlags & TWF_FINETOUCH) != 0)
1336 result.setFlag(TouchWindowTouchType::FineTouch);
1337 if ((touchFlags & TWF_WANTPALM) != 0)
1338 result.setFlag(TouchWindowTouchType::WantPalmTouch);
1344 SetWindowPos(handle(),
nullptr , 0, 0, 0, 0,
1345 SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
1350 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1351 const Qt::WindowType type = window()->type();
1352 if (type == Qt::Popup
1353 || type == Qt::SubWindow
1354 || !(window()->flags() & Qt::WindowStaysOnBottomHint)) {
1355 SetWindowPos(handle(), HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1361 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
1362 if (!(window()->flags() & Qt::WindowStaysOnTopHint))
1363 SetWindowPos(handle(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
1368 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << title;
1369 SetWindowText(handle(),
reinterpret_cast<
const wchar_t *>(title.utf16()));
1374 return QWindowsGeometryHint::mapToGlobal(handle(), pos);
1379 return QWindowsGeometryHint::mapFromGlobal(handle(), pos);
1405 switch (event->type()) {
1406 case QEvent::ChildWindowAdded:
1407 if (!(GetWindowLongPtr(handle(), GWL_STYLE) & WS_CLIPCHILDREN)) {
1408 auto *childWindowEvent =
static_cast<QChildWindowEvent*>(event);
1409 qWarning() << childWindowEvent->child() <<
"added as child to"
1410 << window() <<
"which does not have WS_CLIPCHILDREN set."
1411 <<
"This will result in drawing artifacts!";
1418 return QPlatformWindow::windowEvent(event);
1422
1423
1424
1425
1426
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1443 , m_topLevelStyle(0)
1445 if (QPlatformWindow::parent())
1446 setParent(QPlatformWindow::parent());
1451 if (QPlatformWindow::parent())
1458 const HWND newParent = newParentWindow ?
reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(
nullptr);
1459 const bool isTopLevel = !newParent;
1460 const DWORD oldStyle =
style();
1462 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() <<
"newParent="
1463 << newParentWindow << newParent <<
"oldStyle=" << debugWinStyle(oldStyle);
1465 auto updateWindowFlags = [&] {
1467 DWORD newStyle = oldStyle;
1469 newStyle = m_topLevelStyle;
1471 m_topLevelStyle = oldStyle;
1472 newStyle &= ~(WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW);
1473 newStyle |= WS_CHILD;
1475 SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
1478 if (wasTopLevel && !isTopLevel) {
1481 updateWindowFlags();
1484 SetParent(m_hwnd, newParent);
1486 if (!wasTopLevel && isTopLevel) {
1489 updateWindowFlags();
1495 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << visible;
1497 ShowWindow(handle(), SW_SHOWNOACTIVATE);
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1523 const QRect &geometryIn,
const QRect &geometry,
1525 DWORD style, DWORD exStyle) :
1528 requestedGeometryIn(geometryIn),
1529 requestedGeometry(geometry),
1530 obtainedPos(geometryIn.topLeft()),
1531 obtainedSize(geometryIn.size()),
1532 margins(QWindowsGeometryHint::frame(w, geometry, style, exStyle))
1539 if (!(w->flags() & Qt::FramelessWindowHint))
1542 if (geometry.isValid()
1543 || !qt_window_private(
const_cast<QWindow *>(w))->resizeAutomatic) {
1544 frameX = geometry.x();
1545 frameY = geometry.y();
1546 const QMargins effectiveMargins = margins + customMargins;
1547 frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right();
1548 frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom();
1551 frameHeight += menuHeight;
1553 const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel();
1554 if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) {
1555 frameX -= effectiveMargins.left();
1556 frameY -= effectiveMargins.top();
1560 qCDebug(lcQpaWindow).nospace()
1561 <<
__FUNCTION__ <<
' ' << w <<
' ' << geometry
1562 <<
" pos incl. frame=" << QWindowsGeometryHint::positionIncludesFrame(w)
1563 <<
" frame=" << frameWidth <<
'x' << frameHeight <<
'+'
1564 << frameX <<
'+' << frameY
1565 <<
" margins=" << margins <<
" custom margins=" << customMargins;
1570 QWindowsGeometryHint::applyToMinMaxInfo(window, screen, margins + customMargins, mmi);
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1602 m_cursor(
new CursorHandle)
1603#if QT_CONFIG(vulkan)
1604 , m_vkSurface(VK_NULL_HANDLE)
1609 if (aWindow->flags().testFlags(Qt::ExpandedClientAreaHint)) {
1610 SetParent(m_data.hwndTitlebar, m_data.hwnd);
1611 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
1614 if (aWindow->surfaceType() == QWindow::Direct3DSurface)
1616#if QT_CONFIG(opengl)
1617 if (aWindow->surfaceType() == QWindow::OpenGLSurface)
1618 setFlag(OpenGLSurface);
1620#if QT_CONFIG(vulkan)
1621 if (aWindow->surfaceType() == QSurface::VulkanSurface)
1622 setFlag(VulkanSurface);
1624 updateDropSite(window()->isTopLevel());
1628 if (!touchWindowTouchTypes_sys().has_value())
1631 const qreal opacity = qt_window_private(aWindow)->opacity;
1632 if (!qFuzzyCompare(opacity, qreal(1.0)))
1633 setOpacity(opacity);
1635 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
1637 if (aWindow->isTopLevel())
1638 setWindowIcon(aWindow->icon());
1646 if (m_vsyncServiceCallbackId != 0)
1647 QDxgiVSyncService::instance()->unregisterCallback(m_vsyncServiceCallbackId);
1649 QWindowsThemeCache::clearThemeCache(m_data.hwnd);
1651 UnregisterTouchWindow(m_data.hwnd);
1659 QWindowCreationContextPtr creationContext =
1662 QWindow *w = window();
1663 setWindowState(w->windowStates());
1667 const Qt::WindowState state = w->windowState();
1668 const QRect obtainedGeometry(creationContext->obtainedPos, creationContext->obtainedSize);
1669 QPlatformScreen *obtainedScreen = screenForGeometry(obtainedGeometry);
1670 if (obtainedScreen && screen() != obtainedScreen)
1671 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(w, obtainedScreen->screen());
1672 if (state != Qt::WindowMaximized && state != Qt::WindowFullScreen
1673 && creationContext->requestedGeometryIn != obtainedGeometry) {
1674 QWindowSystemInterface::handleGeometryChange<QWindowSystemInterface::SynchronousDelivery>(w, obtainedGeometry);
1681 return window()->requestedFormat();
1684void QWindowsWindow::fireExpose(
const QRegion ®ion,
bool force)
1686 if (region.isEmpty() && !force)
1690 QWindowSystemInterface::handleExposeEvent(window(), region);
1695 fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), force);
1700 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << m_data.hwnd;
1704 const auto tlw = QGuiApplication::topLevelWindows();
1705 for (QWindow *w : tlw) {
1706 if (w->transientParent() == window()) {
1707 if (QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(w))
1708 tw->updateTransientParent();
1712 if (context->windowUnderMouse() == window())
1716 setDropSiteEnabled(
false);
1717#if QT_CONFIG(vulkan)
1719 QVulkanInstance *inst = window()->vulkanInstance();
1721 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
1722 m_vkSurface = VK_NULL_HANDLE;
1729 m_surface =
nullptr;
1732 DestroyWindow(m_data.hwndTitlebar);
1733 DestroyWindow(m_data.hwnd);
1734 context->removeWindow(m_data.hwnd);
1735 m_data.hwndTitlebar =
nullptr;
1736 m_data.hwnd =
nullptr;
1742 bool enabled =
false;
1743 bool parentIsEmbedded =
false;
1748 const QWindow *parent = window()->parent();
1749 if (parent && parent->handle() && parent->handle()->isForeignWindow())
1750 parentIsEmbedded =
true;
1753 if (topLevel || parentIsEmbedded) {
1754 switch (window()->type()) {
1767 setDropSiteEnabled(enabled);
1772 if (isDropSiteEnabled() == dropEnabled)
1774 qCDebug(lcQpaMime) <<
__FUNCTION__ << window() << dropEnabled;
1775#if QT_CONFIG(clipboard) && QT_CONFIG(draganddrop)
1777 Q_ASSERT(m_data.hwnd);
1778 m_dropTarget =
new QWindowsOleDropTarget(window());
1779 RegisterDragDrop(m_data.hwnd, m_dropTarget);
1780 CoLockObjectExternal(m_dropTarget,
true,
true);
1782 CoLockObjectExternal(m_dropTarget,
false,
true);
1783 m_dropTarget->Release();
1784 RevokeDragDrop(m_data.hwnd);
1785 m_dropTarget =
nullptr;
1794 m_screenForGLInitialized =
false;
1799 m_screenForGLInitialized =
false;
1804 static QString forceToScreen;
1805 if (!m_screenForGLInitialized) {
1807 m_screenForGLInitialized =
true;
1809 return forceToScreen.isEmpty() ?
nullptr : screenForDeviceName(w, forceToScreen);
1816 while (QWindow *parent = w->parent())
1819 if (
const QPlatformWindow *handle = w->handle()) {
1820 const auto *ww =
static_cast<
const QWindowsWindow *>(handle);
1821 if (ww->isEmbedded()) {
1822 HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
1823 const HWND desktopHwnd = GetDesktopWindow();
1825 while (parentHWND && parentHWND != desktopHwnd) {
1826 if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
1827 return topLevelOf(ancestor->window());
1828 parentHWND = GetAncestor(parentHWND, GA_PARENT);
1838 const QString &title)
1841 creationData.fromWindow(w, parameters.flags);
1844 creationData.initialize(w, result.hwnd, !parameters.customMargins.isNull(), 1);
1850 const QWindow *win = window();
1851 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << win << m_data.hwnd << visible;
1864 if (win->type() == Qt::Popup && !win->parent() && !QGuiApplication::focusWindow())
1865 SetForegroundWindow(m_data.hwnd);
1869 if (window()->flags() & Qt::Popup)
1870 ShowWindow(m_data.hwnd, SW_HIDE);
1873 fireExpose(QRegion());
1880 return m_data.hwnd && IsWindowVisible(m_data.hwnd);
1886 if (
const HWND activeHwnd = GetForegroundWindow())
1887 if (m_data.hwnd == activeHwnd || IsChild(activeHwnd, m_data.hwnd))
1894 const auto *childWindow =
static_cast<
const QWindowsWindow *>(child);
1895 return IsChild(m_data.hwnd, childWindow->handle());
1900 return m_data.embedded;
1905 return m_data.hwnd ? QWindowsGeometryHint::mapToGlobal(m_data.hwnd, pos) : pos;
1910 return m_data.hwnd ? QWindowsGeometryHint::mapFromGlobal(m_data.hwnd, pos) : pos;
1920 if (window()->type() == Qt::Popup)
1923 const HWND oldTransientParent = GetWindow(m_data.hwnd, GW_OWNER);
1924 HWND newTransientParent =
nullptr;
1925 if (
const QWindow *tp = window()->transientParent()) {
1926 if (
const QWindowsWindow *tw = QWindowsWindow::windowsWindowOf(tp)) {
1928 newTransientParent = tw->handle();
1931 newTransientParent = tbw->handle();
1937 while (newTransientParent && (GetWindowLongPtr(newTransientParent, GWL_STYLE) & WS_CHILD) != 0)
1938 newTransientParent = GetParent(newTransientParent);
1940 if (newTransientParent != oldTransientParent)
1941 SetWindowLongPtr(m_data.hwnd,
GWL_HWNDPARENT, LONG_PTR(newTransientParent));
1947 const QVariant showWithoutActivating = window->property(
"_q_showWithoutActivating");
1948 return showWithoutActivating.isValid() && showWithoutActivating.toBool();
1953 WINDOWPLACEMENT windowPlacement;
1954 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1955 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1956 windowPlacement.showCmd = SW_SHOWMINIMIZED;
1957 windowPlacement.rcNormalPosition = RECTfromQRect(r);
1958 SetWindowPlacement(hwnd, &windowPlacement);
1965 WINDOWPLACEMENT windowPlacement;
1966 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1967 if (GetWindowPlacement(hwnd, &windowPlacement)) {
1969 windowPlacement.flags |= WPF_RESTORETOMAXIMIZED;
1971 windowPlacement.flags &= ~WPF_RESTORETOMAXIMIZED;
1972 SetWindowPlacement(hwnd, &windowPlacement);
1979 int sm = SW_SHOWNORMAL;
1980 bool fakedMaximize =
false;
1981 bool restoreMaximize =
false;
1982 const QWindow *w = window();
1983 const Qt::WindowFlags flags = w->flags();
1984 const Qt::WindowType type = w->type();
1985 if (w->isTopLevel()) {
1986 const Qt::WindowStates state = w->windowStates();
1987 if (state & Qt::WindowMinimized) {
1988 sm = SW_SHOWMINIMIZED;
1990 sm = SW_SHOWMINNOACTIVE;
1991 if (state & Qt::WindowMaximized)
1992 restoreMaximize =
true;
1994 updateTransientParent();
1995 if (state & Qt::WindowMaximized) {
1996 sm = SW_SHOWMAXIMIZED;
2002 if (flags & Qt::WindowTitleHint &&
2003 !(flags & (Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint))) {
2004 fakedMaximize = TRUE;
2005 setStyle(style() | WS_MAXIMIZEBOX);
2010 if (type == Qt::Popup ||
2011 type == Qt::ToolTip ||
2013 (flags & Qt::WindowDoesNotAcceptFocus) ||
2014 testShowWithoutActivating(w))
2015 sm = SW_SHOWNOACTIVATE;
2017 if (w->windowStates() & Qt::WindowMaximized)
2020 ShowWindow(m_data.hwnd, sm);
2024 if (fakedMaximize) {
2025 setStyle(style() & ~WS_MAXIMIZEBOX);
2026 SetWindowPos(m_data.hwnd,
nullptr, 0, 0, 0, 0,
2027 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER
2028 | SWP_FRAMECHANGED);
2030 if (restoreMaximize)
2031 setRestoreMaximizedFlag(m_data.hwnd);
2036 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << newParent;
2039 setParent_sys(newParent);
2045 HWND oldParentHWND = parentHwnd();
2046 HWND newParentHWND =
nullptr;
2048 const auto *parentW =
static_cast<
const QWindowsWindow *>(parent);
2049 newParentHWND = parentW->handle();
2054 HWND desktopHwnd = GetDesktopWindow();
2055 if (oldParentHWND == desktopHwnd)
2056 oldParentHWND =
nullptr;
2057 if (newParentHWND == desktopHwnd)
2058 newParentHWND =
nullptr;
2060 if (newParentHWND != oldParentHWND) {
2061 const bool wasTopLevel = oldParentHWND ==
nullptr;
2062 const bool isTopLevel = newParentHWND ==
nullptr;
2065 SetParent(m_data.hwnd, newParentHWND);
2071 if (wasTopLevel != isTopLevel) {
2072 setDropSiteEnabled(
false);
2073 setWindowFlags_sys(window()->flags(),
unsigned(isTopLevel ? WindowCreationData::ForceTopLevel : WindowCreationData::ForceChild));
2074 updateDropSite(isTopLevel);
2081 fireExpose(QRegion());
2086 const QWindow *w = window();
2088 applyBlurBehindWindow(handle());
2093 return QHighDpiScaling::roundScaleFactor(qreal(dpi) / QWindowsScreen::baseDpi) /
2094 QHighDpiScaling::roundScaleFactor(qreal(savedDpi()) / QWindowsScreen::baseDpi);
2104 const UINT dpi = UINT(wParam);
2105 const qreal scale = dpiRelativeScale(dpi);
2106 const QMargins margins = fullFrameMargins();
2107 if (!(m_data.flags & Qt::FramelessWindowHint)) {
2113 m_data.customMargins *= scale;
2116 const QSize windowSize = (geometry().size() * scale).grownBy((margins * scale) + customMargins());
2117 SIZE *size =
reinterpret_cast<SIZE *>(lParam);
2118 size->cx = windowSize.width();
2119 size->cy = windowSize.height();
2125 const UINT dpi = HIWORD(wParam);
2126 const qreal scale = dpiRelativeScale(dpi);
2129 QWindowsThemeCache::clearThemeCache(hwnd);
2132 const auto prcNewWindow =
reinterpret_cast<
const RECT *>(lParam);
2133 checkForScreenChanged(QWindowsWindow::FromDpiChange, !m_inSetgeometry ? prcNewWindow :
nullptr);
2135 if (!IsZoomed(hwnd))
2136 m_data.restoreGeometry.setSize(m_data.restoreGeometry.size() * scale);
2154 if (!m_inSetgeometry) {
2156 SetWindowPos(hwnd,
nullptr, prcNewWindow->left, prcNewWindow->top,
2157 prcNewWindow->right - prcNewWindow->left,
2158 prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
2162 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
2163 handleGeometryChange();
2168 setMask(QHighDpi::toNativeLocalRegion(window()->mask(), window()));
2173 const UINT dpi = GetDpiForWindow(hwnd);
2174 const qreal scale = dpiRelativeScale(dpi);
2177 checkForScreenChanged(QWindowsWindow::FromDpiChange);
2181 QRect currentGeometry = geometry();
2182 QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
2183 setGeometry(scaledGeometry);
2189 wp.length =
sizeof(WINDOWPLACEMENT);
2190 if (GetWindowPlacement(hwnd, &wp)) {
2191 const QRect result = qrectFromRECT(wp.rcNormalPosition);
2192 return result.translated(windowPlacementOffset(hwnd, result.topLeft()));
2200 const bool fakeFullScreen =
2201 m_savedFrameGeometry.isValid() && (window()->windowStates() & Qt::WindowFullScreen);
2202 const QRect frame = fakeFullScreen ? m_savedFrameGeometry : normalFrameGeometry(m_data.hwnd);
2203 const QMargins margins = fakeFullScreen
2204 ? QWindowsGeometryHint::frame(window(), handle(), m_savedStyle, 0)
2205 : fullFrameMargins();
2206 return frame.isValid() ? frame.marginsRemoved(margins) : frame;
2211 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
2212 const int titleBarHeight = getTitleBarHeight_sys(96);
2214 return QMargins(0, titleBarHeight, 0, 0);
2220 const QRect &requestedRect,
2221 const QRect &obtainedRect,
2222 const QMargins &fullMargins,
2223 const QMargins &customMargins)
2226 QDebug debug(&result);
2229 const auto window = platformWindow->window();
2230 debug <<
"Unable to set geometry ";
2231 formatBriefRectangle(debug, requestedRect);
2232 debug <<
" (frame: ";
2233 formatBriefRectangle(debug, requestedRect + fullMargins);
2234 debug <<
") on " << window->metaObject()->className() <<
"/\""
2235 << window->objectName() <<
"\" on \"" << window->screen()->name()
2236 <<
"\". Resulting geometry: ";
2237 formatBriefRectangle(debug, obtainedRect);
2238 debug <<
" (frame: ";
2239 formatBriefRectangle(debug, obtainedRect + fullMargins);
2240 debug <<
") margins: ";
2241 formatBriefMargins(debug, fullMargins);
2242 if (!customMargins.isNull()) {
2243 debug <<
" custom margin: ";
2244 formatBriefMargins(debug, customMargins);
2246 const auto minimumSize = window->minimumSize();
2247 const bool hasMinimumSize = !minimumSize.isEmpty();
2249 debug <<
" minimum size: " << minimumSize.width() <<
'x' << minimumSize.height();
2250 const auto maximumSize = window->maximumSize();
2251 const bool hasMaximumSize = maximumSize.width() != QWINDOWSIZE_MAX || maximumSize.height() != QWINDOWSIZE_MAX;
2253 debug <<
" maximum size: " << maximumSize.width() <<
'x' << maximumSize.height();
2254 if (hasMinimumSize || hasMaximumSize) {
2255 MINMAXINFO minmaxInfo;
2256 memset(&minmaxInfo, 0,
sizeof(minmaxInfo));
2257 platformWindow->getSizeHints(&minmaxInfo);
2258 debug <<
' ' << minmaxInfo;
2266 QScopedValueRollback b(m_inSetgeometry,
true);
2268 QRect rect = rectIn;
2271 if (QWindowsGeometryHint::positionIncludesFrame(window())) {
2272 const QMargins margins = frameMargins();
2273 rect.moveTopLeft(rect.topLeft() +
QPoint(margins.left(), margins.top()));
2275 if (m_windowState & Qt::WindowMinimized)
2276 m_data.geometry = rect;
2282 setGeometry_sys(rect);
2284 if (m_data.geometry != rect && (isVisible() || QLibraryInfo::isDebugBuild())) {
2285 const auto warning =
2286 msgUnableToSetGeometry(
this, rectIn, m_data.geometry,
2287 fullFrameMargins(), customMargins());
2288 qWarning(
"%s: %s",
__FUNCTION__, qPrintable(warning));
2291 QPlatformWindow::setGeometry(rect);
2299 handleGeometryChange();
2305 if ((m_data.flags.testFlag(Qt::FramelessWindowHint)
2306 || (m_data.flags.testFlag(Qt::CustomizeWindowHint) && !m_data.flags.testFlag(Qt::WindowTitleHint)))
2307 && IsZoomed(m_data.hwnd)) {
2308 const int resizedWidth = LOWORD(lParam);
2309 const int resizedHeight = HIWORD(lParam);
2311 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTOPRIMARY);
2312 MONITORINFO monitorInfo = {};
2313 monitorInfo.cbSize =
sizeof(MONITORINFO);
2314 GetMonitorInfoW(monitor, &monitorInfo);
2316 int correctLeft = monitorInfo.rcMonitor.left;
2317 int correctTop = monitorInfo.rcMonitor.top;
2318 int correctWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
2319 int correctHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
2321 if (!m_data.flags.testFlag(Qt::FramelessWindowHint)) {
2322 const int borderWidth = invisibleMargins(m_data.hwnd).left();
2323 correctLeft -= borderWidth;
2324 correctTop -= borderWidth;
2325 correctWidth += borderWidth * 2;
2326 correctHeight += borderWidth * 2;
2329 if (resizedWidth != correctWidth || resizedHeight != correctHeight) {
2330 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
"correcting: " << resizedWidth <<
"x"
2331 << resizedHeight <<
" -> " << correctWidth <<
"x" << correctHeight;
2332 SetWindowPos(m_data.hwnd,
nullptr, correctLeft, correctTop, correctWidth, correctHeight,
2333 SWP_NOZORDER | SWP_NOACTIVATE);
2341 case SIZE_MINIMIZED:
2342 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2343 handleWindowStateChange(m_windowState | Qt::WindowMinimized);
2345 case SIZE_MAXIMIZED:
2346 handleGeometryChange();
2347 if (!testFlag(WithinSetStyle) && !testFlag(WithinSetGeometry))
2348 handleWindowStateChange(Qt::WindowMaximized | (isFullScreen_sys() ? Qt::WindowFullScreen
2349 : Qt::WindowNoState));
2352 handleGeometryChange();
2354 if (isFullScreen_sys())
2355 handleWindowStateChange(
2356 Qt::WindowFullScreen
2357 | (testFlag(MaximizeToFullScreen) ? Qt::WindowMaximized : Qt::WindowNoState));
2358 else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
2359 handleWindowStateChange(Qt::WindowNoState);
2365static inline bool equalDpi(
const QDpi &d1,
const QDpi &d2)
2367 return qFuzzyCompare(d1.first, d2.first) && qFuzzyCompare(d1.second, d2.second);
2375 QPlatformScreen *currentScreen = screen();
2376 auto topLevel = isTopLevel_sys() ? m_data.hwnd : GetAncestor(m_data.hwnd, GA_ROOT);
2381 if (newScreen ==
nullptr || newScreen == currentScreen)
2385 const bool changingDpi = !equalDpi(QDpi(savedDpi(), savedDpi()), newScreen->logicalDpi());
2389 qCDebug(lcQpaWindow).noquote().nospace() <<
__FUNCTION__
2390 <<
' ' << window() <<
" \"" << (currentScreen ? currentScreen->name() : QString())
2391 <<
"\"->\"" << newScreen->name() <<
'"';
2393 QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), newScreen->screen());
2398 const QRect previousGeometry = m_data.geometry;
2399 m_data.geometry = geometry_sys();
2401 QWindowSystemInterface::handleGeometryChange(window(), m_data.geometry);
2406 && m_data.geometry.size() != previousGeometry.size()
2408 && !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
2409 fireFullExpose(
true);
2413 checkForScreenChanged();
2415 if (testFlag(SynchronousGeometryChangeEvent))
2416 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2423 qCDebug(lcQpaEvents) <<
__FUNCTION__ <<
this << window() << m_data.geometry;
2425 if (m_data.flags & Qt::ExpandedClientAreaHint) {
2426 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
2427 MoveWindow(m_data.hwndTitlebar, 0, 0, m_data.geometry.width(), titleBarHeight,
true);
2433 const QMargins margins = fullFrameMargins();
2434 const QRect frameGeometry = rect + margins;
2436 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ << window()
2437 <<
"\n from " << geometry_sys() <<
" frame: "
2438 << margins <<
" to " <<rect
2439 <<
" new frame: " << frameGeometry;
2441 bool result =
false;
2442 const HWND hwnd = handle();
2443 WINDOWPLACEMENT windowPlacement;
2444 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2445 GetWindowPlacement(hwnd, &windowPlacement);
2448 if ((windowPlacement.showCmd == SW_MAXIMIZE && !IsWindowVisible(hwnd))
2449 || windowPlacement.showCmd == SW_SHOWMINIMIZED) {
2450 windowPlacement.rcNormalPosition =
2451 RECTfromQRect(frameGeometry.translated(-windowPlacementOffset(hwnd, frameGeometry.topLeft())));
2452 windowPlacement.showCmd = windowPlacement.showCmd == SW_SHOWMINIMIZED ? SW_SHOWMINIMIZED : SW_HIDE;
2453 result = SetWindowPlacement(hwnd, &windowPlacement);
2455 int x = frameGeometry.x();
2456 if (!window()->isTopLevel()) {
2457 const HWND parentHandle = GetParent(hwnd);
2458 if (isRtlLayout(parentHandle)) {
2460 GetClientRect(parentHandle, &rect);
2461 x = rect.right - frameGeometry.width() - x;
2464 result = MoveWindow(hwnd, x, frameGeometry.y(),
2465 frameGeometry.width(), frameGeometry.height(),
true);
2467 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ << window()
2468 <<
"\n resulting " << result << geometry_sys();
2472
2473
2474
2475
2476
2481 m_hdc = GetDC(handle());
2482 if (QGuiApplication::layoutDirection() == Qt::RightToLeft)
2483 SetLayout(m_hdc, 0);
2489
2490
2491
2492
2493
2498 ReleaseDC(handle(), m_hdc);
2505#if QT_CONFIG(dynamicgl)
2506 return QOpenGLStaticContext::opengl32.moduleIsNotOpengl32()
2507 && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL;
2516 if (message == WM_ERASEBKGND) {
2521 if (!window()->isVisible() && (GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) != 0)
2524 if (!GetUpdateRect(m_data.hwnd, 0, FALSE))
2531 InvalidateRect(hwnd,
nullptr,
false);
2533 BeginPaint(hwnd, &ps);
2538 fireExpose(QRegion(qrectFromRECT(ps.rcPaint)),
true);
2539 if (!QWindowsContext::instance()->asyncExpose())
2540 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2542 EndPaint(hwnd, &ps);
2548 m_windowTitle = QWindowsWindow::formatWindowTitle(title);
2549 setWindowTitle_sys(m_windowTitle);
2554 return m_windowTitle;
2559 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window() <<
"\n from: "
2560 << m_data.flags <<
"\n to: " << flags;
2561 const QRect oldGeometry = geometry();
2562 if (m_data.flags != flags) {
2563 m_data.flags = flags;
2565 m_data = setWindowFlags_sys(flags);
2566 updateDropSite(window()->isTopLevel());
2573 const QRect newGeometry = geometry_sys();
2574 if (oldGeometry != newGeometry)
2575 handleGeometryChange();
2577 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
"\n returns: "
2578 << m_data.flags <<
" geometry " << oldGeometry <<
"->" << newGeometry;
2582 unsigned flags)
const
2585 creationData.fromWindow(window(), wt, flags);
2586 creationData.applyWindowFlags(m_data.hwnd);
2587 creationData.initialize(window(), m_data.hwnd,
true, m_opacity);
2589 if (creationData.flags.testFlag(Qt::ExpandedClientAreaHint)) {
2590 SetParent(m_data.hwndTitlebar, m_data.hwnd);
2591 ShowWindow(m_data.hwndTitlebar, SW_SHOW);
2593 if (IsWindowVisible(m_data.hwndTitlebar)) {
2594 SetParent(m_data.hwndTitlebar, HWND_MESSAGE);
2595 ShowWindow(m_data.hwndTitlebar, SW_HIDE);
2600 result.flags = creationData.flags;
2602 result.hasFrame = (creationData.style & (WS_DLGFRAME | WS_THICKFRAME))
2603 && !(creationData.flags & Qt::FramelessWindowHint);
2607void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
2609 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window()
2610 <<
"\n from " << m_windowState <<
" to " << state;
2611 m_windowState = state;
2612 QWindowSystemInterface::handleWindowStateChanged(window(), state);
2613 if (state & Qt::WindowMinimized) {
2615 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2618 if (state & Qt::WindowMaximized) {
2619 WINDOWPLACEMENT windowPlacement{};
2620 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
2621 GetWindowPlacement(m_data.hwnd, &windowPlacement);
2622 const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
2623 windowPlacement.rcNormalPosition = geometry;
2624 correctWindowPlacement(windowPlacement);
2630 windowPlacement.showCmd = SW_HIDE;
2631 SetWindowPlacement(m_data.hwnd, &windowPlacement);
2635 QWindow *w = window();
2636 bool exposeEventsSent =
false;
2639 exposeEventsSent =
true;
2641 const QWindowList allWindows = QGuiApplication::allWindows();
2642 for (QWindow *child : allWindows) {
2643 if (child != w && child->isVisible() && child->transientParent() == w) {
2644 QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
2645 if (platformWindow && platformWindow->isLayered()) {
2646 platformWindow->fireFullExpose();
2647 exposeEventsSent =
true;
2651 if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
2652 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2661 return window()->maximumHeight() != QWINDOWSIZE_MAX;
2666 return window()->maximumWidth() != QWINDOWSIZE_MAX;
2674void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
2676 static const auto windows11 = QOperatingSystemVersion::Windows11_21H2;
2677 static const bool isWindows10 = QOperatingSystemVersion::current() < windows11;
2683 const QPoint offset = windowPlacementOffset(m_data.hwnd, m_data.restoreGeometry.topLeft());
2684 windowPlacement.rcNormalPosition = RECTfromQRect(m_data.restoreGeometry.translated(-offset));
2685 qCDebug(lcQpaWindow) <<
"Corrected normal position by" << -offset;
2694 const QMargins margins = frameMargins_sys();
2695 const QPoint topLeft = window()->screen()->geometry().topLeft();
2696 windowPlacement.ptMaxPosition = POINT{ topLeft.x() - margins.left(), topLeft.y() };
2697 qCDebug(lcQpaWindow) <<
"Window has maximum size. Corrected topLeft by"
2703 const int adjust = offset.x() / window()->devicePixelRatio();
2704 window()->setWidth(window()->width() - adjust);
2705 qCDebug(lcQpaWindow) <<
"Width shortened by" << adjust <<
"logical pixels.";
2708 const int adjust = offset.y() / window()->devicePixelRatio();
2709 window()->setHeight(window()->height() - adjust);
2710 qCDebug(lcQpaWindow) <<
"Height shortened by" << adjust <<
"logical pixels.";
2717 m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
2723 setWindowState_sys(state);
2724 m_windowState = state;
2730 const QWindow *w = window();
2731 if (!w->isTopLevel())
2733 QRect geometry = geometry_sys();
2735 geometry += QMargins(1, 1, 1, 1);
2736 QPlatformScreen *screen = screenForGeometry(geometry);
2737 return screen && geometry == screen->geometry();
2741
2742
2743
2744
2745
2746
2747
2748
2749
2751void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
2753 const Qt::WindowStates oldState = m_windowState;
2754 if (oldState == newState)
2756 qCDebug(lcQpaWindow) <<
'>' <<
__FUNCTION__ <<
this << window()
2757 <<
" from " << oldState <<
" to " << newState;
2760 auto stateChange = oldState ^ newState;
2762 if (stateChange & Qt::WindowFullScreen) {
2763 if (newState & Qt::WindowFullScreen) {
2764 UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
2768 if (!m_savedStyle) {
2769 m_savedStyle =
style();
2770 if ((oldState & Qt::WindowMinimized) || (oldState & Qt::WindowMaximized)) {
2771 const QRect nf = normalFrameGeometry(m_data.hwnd);
2773 m_savedFrameGeometry = nf;
2775 m_savedFrameGeometry = frameGeometry_sys();
2778 if (newState & Qt::WindowMaximized)
2780 if (m_savedStyle & WS_SYSMENU)
2781 newStyle |= WS_SYSMENU;
2783 newStyle |= WS_VISIBLE;
2784 if (testFlag(HasBorderInFullScreen))
2785 newStyle |= WS_BORDER;
2787 const HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2788 MONITORINFO monitorInfo = {};
2789 monitorInfo.cbSize =
sizeof(MONITORINFO);
2790 GetMonitorInfoW(monitor, &monitorInfo);
2791 const QRect screenGeometry(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
2792 monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
2793 monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top);
2794 if (newState & Qt::WindowMinimized) {
2795 setMinimizedGeometry(m_data.hwnd, screenGeometry);
2796 if (stateChange & Qt::WindowMaximized)
2797 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2799 const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
2802 SetWindowPos(m_data.hwnd, HWND_TOP, screenGeometry.left(), screenGeometry.top(), screenGeometry.width(), screenGeometry.height(), swpf);
2806 QWindowSystemInterface::handleGeometryChange(window(), screenGeometry);
2807 QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
2811 unsigned newStyle = m_savedStyle ? m_savedStyle :
style();
2813 newStyle |= WS_VISIBLE;
2816 const QScreen *screen = window()->screen();
2818 screen = QGuiApplication::primaryScreen();
2820 if (
const auto platformScreen = screen->handle()) {
2821 if (!platformScreen->geometry().intersects(m_savedFrameGeometry))
2822 m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft());
2825 if (newState & Qt::WindowMinimized) {
2826 setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry);
2827 if (stateChange & Qt::WindowMaximized)
2828 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2830 UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
2831 if (!m_savedFrameGeometry.isValid())
2832 swpf |= SWP_NOSIZE | SWP_NOMOVE;
2837 if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
2838 ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
2839 SetWindowPos(m_data.hwnd,
nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
2840 m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
2846 ShowWindow(m_data.hwnd,
2847 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
2852 m_savedFrameGeometry = QRect();
2854 }
else if ((oldState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
2855 if (visible && !(newState & Qt::WindowMinimized)) {
2857 if (newState & Qt::WindowFullScreen)
2859 if (m_data.flags & Qt::FramelessWindowHint) {
2860 if (newState == Qt::WindowNoState) {
2861 const QRect &rect = m_savedFrameGeometry;
2862 MoveWindow(m_data.hwnd, rect.x(), rect.y(), rect.width(), rect.height(),
true);
2864 HMONITOR monitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONEAREST);
2865 MONITORINFO monitorInfo = {};
2866 monitorInfo.cbSize =
sizeof(MONITORINFO);
2867 GetMonitorInfo(monitor, &monitorInfo);
2868 const RECT &rect = monitorInfo.rcWork;
2869 m_savedFrameGeometry = geometry();
2870 MoveWindow(m_data.hwnd, rect.left, rect.top,
2871 rect.right - rect.left, rect.bottom - rect.top,
true);
2874 ShowWindow(m_data.hwnd,
2875 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
2879 }
else if (visible && (oldState & newState & Qt::WindowMinimized)) {
2881 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2885 if (stateChange & Qt::WindowMinimized) {
2887 ShowWindow(m_data.hwnd,
2888 (newState & Qt::WindowMinimized) ? SW_MINIMIZE :
2889 (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
2890 if ((newState & Qt::WindowMinimized) && (stateChange & Qt::WindowMaximized))
2891 setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
2894 qCDebug(lcQpaWindow) <<
'<' <<
__FUNCTION__ <<
this << window() << newState;
2899 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinStyle(s);
2901 SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
2907 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << debugWinExStyle(s);
2908 SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
2913 switch (event->type()) {
2914 case QEvent::ApplicationPaletteChange:
2915 setDarkBorder(QWindowsTheme::instance()->colorScheme() == Qt::ColorScheme::Dark);
2917 case QEvent::WindowBlocked:
2923 case QEvent::WindowUnblocked:
2931 return QWindowsBaseWindow::windowEvent(event);
2936 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
2941 bool result =
false;
2942 if ((windowPos->flags & SWP_NOSIZE) == 0) {
2944 GetWindowRect(windowPos->hwnd, &rect);
2945 result = rect.right - rect.left != windowPos->cx || rect.bottom - rect.top != windowPos->cy;
2950bool QWindowsWindow::handleGeometryChangingMessage(MSG *message,
const QWindow *qWindow,
const QMargins &margins)
2952 auto *windowPos =
reinterpret_cast<WINDOWPOS *>(message->lParam);
2953 const QRect suggestedFrameGeometry(windowPos->x, windowPos->y,
2954 windowPos->cx, windowPos->cy);
2955 const QRect suggestedGeometry = suggestedFrameGeometry - margins;
2962 if (isResize(windowPos))
2963 windowPos->flags |= SWP_NOCOPYBITS;
2965 if ((windowPos->flags & SWP_NOZORDER) == 0) {
2966 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(qWindow)) {
2967 QWindow *parentWindow = qWindow->parent();
2968 HWND parentHWND = GetAncestor(windowPos->hwnd, GA_PARENT);
2969 HWND desktopHWND = GetDesktopWindow();
2970 platformWindow->m_data.embedded = !parentWindow && parentHWND && (parentHWND != desktopHWND);
2972 if (qWindow->flags().testFlag(Qt::WindowStaysOnBottomHint))
2973 windowPos->hwndInsertAfter = HWND_BOTTOM;
2975 if (!qWindow->isTopLevel())
2977 if (windowPos->flags & SWP_NOSIZE)
2979 const QRectF correctedGeometryF = QPlatformWindow::closestAcceptableGeometry(qWindow, suggestedGeometry);
2980 if (!correctedGeometryF.isValid())
2982 const QRect correctedFrameGeometry = correctedGeometryF.toRect() + margins;
2983 if (correctedFrameGeometry == suggestedFrameGeometry)
2985 windowPos->x = correctedFrameGeometry.left();
2986 windowPos->y = correctedFrameGeometry.top();
2987 windowPos->cx = correctedFrameGeometry.width();
2988 windowPos->cy = correctedFrameGeometry.height();
2994 const QMargins margins = window()->isTopLevel() ? fullFrameMargins() : QMargins();
2995 return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
3000 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3002 if (m_data.fullFrameMargins != newMargins) {
3003 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << m_data.fullFrameMargins <<
"->" << newMargins;
3004 m_data.fullFrameMargins = newMargins;
3011 if (GetMenu(m_data.hwnd))
3012 QWindowsContext::forceNcCalcSize(m_data.hwnd);
3014 calculateFullFrameMargins();
3019 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3032 GetWindowRect(handle(), &windowRect);
3033 GetClientRect(handle(), &clientRect);
3039 if (qrectFromRECT(windowRect).size() == qrectFromRECT(clientRect).size())
3044 const auto systemMargins = testFlag(DisableNonClientScaling)
3045 ? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd)
3046 : frameMargins_sys();
3047 const int extendedClientAreaBorder = window()->flags().testFlag(Qt::ExpandedClientAreaHint) ? qRound(QHighDpiScaling::factor(window())) * 2 : 0;
3048 const QMargins actualMargins = systemMargins + customMargins() - extendedClientAreaBorder;
3050 const int yDiff = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
3051 const bool typicalFrame = (actualMargins.left() == actualMargins.right())
3052 && (actualMargins.right() == actualMargins.bottom());
3054 const QMargins adjustedMargins = typicalFrame ?
3055 QMargins(actualMargins.left(), (yDiff - actualMargins.bottom()),
3056 actualMargins.right(), actualMargins.bottom())
3059 setFullFrameMargins(adjustedMargins);
3064 QMargins result = fullFrameMargins();
3065 if (isTopLevel() && m_data.hasFrame)
3066 result -= invisibleMargins(m_data.hwnd);
3072 if (shouldOmitFrameAdjustment(m_data.flags, m_data.hwnd))
3074 return m_data.fullFrameMargins;
3079 qCDebug(lcQpaWindow) <<
__FUNCTION__ << level;
3080 if (!qFuzzyCompare(m_opacity, level)) {
3083 setWindowOpacity(m_data.hwnd, m_data.flags,
3091 return CreateRectRgn(r.left(), r.top(), r.x() + r.width(), r.y() + r.height());
3096 if (
const HRGN rectRegion = createRectRegion(rect)) {
3097 HRGN result = CreateRectRgn(0, 0, 0, 0);
3098 if (CombineRgn(result, *winRegion, rectRegion, RGN_OR)) {
3099 DeleteObject(*winRegion);
3100 *winRegion = result;
3102 DeleteObject(rectRegion);
3108 auto it = region.begin();
3109 const auto end = region.end();
3112 HRGN hRegion = createRectRegion(*it);
3114 addRectToWinRegion(*it, &hRegion);
3120 if (region.isEmpty()) {
3121 SetWindowRgn(m_data.hwnd,
nullptr,
true);
3124 const HRGN winRegion = qRegionToWinRegion(region);
3127 if (window()->isTopLevel()) {
3128 const QMargins margins = fullFrameMargins();
3129 OffsetRgn(winRegion, margins.left(), margins.top());
3133 if (!SetWindowRgn(m_data.hwnd, winRegion,
true))
3134 DeleteObject(winRegion);
3139 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window();
3145 if (QGuiApplication::applicationState() == Qt::ApplicationActive
3146 || activationBehavior != QWindowsApplication::AlwaysActivateWindow) {
3147 SetForegroundWindow(m_data.hwnd);
3148 SetFocus(m_data.hwnd);
3157 if (m_data.flags & Qt::WindowStaysOnBottomHint) {
3158 qCWarning(lcQpaWindow) <<
3159 "Windows with Qt::WindowStaysOnBottomHint can't be brought to the foreground.";
3162 if (m_data.flags & Qt::WindowStaysOnTopHint) {
3163 qCWarning(lcQpaWindow) <<
3164 "Windows with Qt::WindowStaysOnTopHint will always be on the foreground.";
3167 if (window()->type() == Qt::ToolTip) {
3168 qCWarning(lcQpaWindow) <<
"ToolTip windows should not be activated.";
3173 if (!IsWindowVisible(m_data.hwnd))
3174 ShowWindow(m_data.hwnd, SW_SHOW);
3176 if (IsIconic(m_data.hwnd)) {
3177 ShowWindow(m_data.hwnd, SW_RESTORE);
3184 const HWND oldForegroundWindow = GetForegroundWindow();
3185 if (!oldForegroundWindow)
3190 if (SendMessageTimeoutW(oldForegroundWindow, WM_NULL, 0, 0,
3191 SMTO_BLOCK | SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000,
nullptr) == 0) {
3192 qCWarning(lcQpaWindow) <<
"The foreground window hangs, can't activate current window.";
3196 const DWORD windowThreadProcessId = GetWindowThreadProcessId(oldForegroundWindow,
nullptr);
3197 const DWORD currentThreadId = GetCurrentThreadId();
3199 AttachThreadInput(windowThreadProcessId, currentThreadId, TRUE);
3200 const auto cleanup = qScopeGuard([windowThreadProcessId, currentThreadId](){
3201 AttachThreadInput(windowThreadProcessId, currentThreadId, FALSE);
3204 BringWindowToTop(m_data.hwnd);
3208 SetActiveWindow(m_data.hwnd);
3214 qWarning(
"%s: No handle",
__FUNCTION__);
3217 qCDebug(lcQpaWindow) <<
__FUNCTION__ <<
this << window() << grab;
3221 context->setKeyGrabber(window());
3223 if (context->keyGrabber() == window())
3224 context->setKeyGrabber(
nullptr);
3231 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << grab;
3233 qWarning(
"%s: No handle",
__FUNCTION__);
3237 qWarning(
"%s: Not setting mouse grab for invisible window %s/'%s'",
3238 __FUNCTION__, window()->metaObject()->className(),
3239 qPrintable(window()->objectName()));
3246 SetCapture(m_data.hwnd);
3256 if (edges == Qt::LeftEdge)
3258 else if (edges == (Qt::RightEdge))
3260 else if (edges == (Qt::TopEdge))
3262 else if (edges == (Qt::TopEdge | Qt::LeftEdge))
3264 else if (edges == (Qt::TopEdge | Qt::RightEdge))
3266 else if (edges == (Qt::BottomEdge))
3268 else if (edges == (Qt::BottomEdge | Qt::LeftEdge))
3270 else if (edges == (Qt::BottomEdge | Qt::RightEdge))
3278 if (Q_UNLIKELY(window()->flags().testFlag(Qt::MSWindowsFixedSizeDialogHint)))
3282 PostMessage(m_data.hwnd, WM_SYSCOMMAND, edgesToWinOrientation(edges), 0);
3290 PostMessage(m_data.hwnd, WM_SYSCOMMAND, 0xF012 , 0);
3305 QWindowsGeometryHint::applyToMinMaxInfo(window(), fullFrameMargins(), mmi);
3306 qCDebug(lcQpaWindow) <<
__FUNCTION__ << window() << *mmi;
3312 const QWindow *w = window();
3313 const QPoint localPos = w->mapFromGlobal(QHighDpi::fromNativePixels(globalPos, w));
3314 const QRect geom = geometry();
3315 static auto oldMouseButtonState = Qt::NoButton;
3317 if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
3318 bool isDefaultTitleBar = !w->flags().testFlag(Qt::CustomizeWindowHint);
3319 bool isCustomized = w->flags().testFlags(Qt::CustomizeWindowHint) && w->flags().testAnyFlags(Qt::WindowTitleHint|
3320 Qt::WindowMinimizeButtonHint|
3321 Qt::WindowMaximizeButtonHint|
3322 Qt::WindowCloseButtonHint);
3323 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3324 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3325 const int titleButtonWidth = titleBarHeight * 1.5;
3326 const bool mouseButtonsSwapped = GetSystemMetrics(SM_SWAPBUTTON);
3327 auto mouseButtons = Qt::NoButton;
3328 if (mouseButtonsSwapped)
3329 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::RightButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::LeftButton : Qt::NoButton);
3331 mouseButtons = GetAsyncKeyState(VK_LBUTTON) != 0 ? Qt::LeftButton : (GetAsyncKeyState(VK_RBUTTON) ? Qt::RightButton : Qt::NoButton);
3334 if (isCustomized || isDefaultTitleBar) {
3337 if (globalPos.y() < geom.top() + titleBarHeight) {
3338 if (m_data.flags.testFlags(Qt::WindowCloseButtonHint) || isDefaultTitleBar) {
3339 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right())) {
3340 if (mouseButtons == Qt::LeftButton)
3344 }
if (m_data.flags.testFlags(Qt::WindowMaximizeButtonHint) || isDefaultTitleBar) {
3345 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3346 if (mouseButtons == Qt::LeftButton) {
3347 if (IsZoomed(m_data.hwnd))
3350 *result = HTMAXBUTTON;
3354 }
if (m_data.flags.testFlags(Qt::WindowMinimizeButtonHint) || isDefaultTitleBar) {
3355 if ((globalPos.x() > geom.right() - titleButtonWidth * buttons) && (globalPos.x() <= geom.right() - titleButtonWidth * (buttons-1))){
3356 if (mouseButtons == Qt::LeftButton)
3357 *result = HTMINBUTTON;
3360 }
if ((isCustomized || isDefaultTitleBar) &&
3361 *result == HTCLIENT){
3362 QWindow* wnd = window();
3363 if (mouseButtons != oldMouseButtonState) {
3364 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3365 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3366 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3367 if (!accepted && mouseButtons == Qt::RightButton)
3368 *result = HTSYSMENU;
3369 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3370 *result = HTCAPTION;
3374 }
else if (w->flags().testFlag(Qt::CustomizeWindowHint)) {
3376 QWindow* wnd = window();
3377 if (mouseButtons != oldMouseButtonState) {
3378 auto mouseEventType = mouseButtons == Qt::NoButton ? QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
3379 auto mouseEventButtons = mouseEventType == QEvent::MouseButtonPress ? mouseButtons : oldMouseButtonState;
3380 bool accepted = QWindowSystemInterface::handleMouseEvent<QWindowSystemInterface::SynchronousDelivery>(wnd, QHighDpi::toNativeLocalPosition(localPos, w), globalPos, mouseEventButtons, mouseEventButtons, mouseEventType);
3381 if (!accepted && mouseButtons == Qt::RightButton)
3382 *result = HTSYSMENU;
3383 else if (!accepted && globalPos.y() < geom.top() + titleBarHeight)
3384 *result = HTCAPTION;
3387 oldMouseButtonState = mouseButtons;
3390 const bool left = (globalPos.x() >= geom.left()) && (globalPos.x() < geom.left() + border);
3391 const bool right = (globalPos.x() > geom.right() - border) && (globalPos.x() <= geom.right());
3392 const bool top = (globalPos.y() >= geom.top()) && (globalPos.y() < geom.top() + border);
3393 const bool bottom = (globalPos.y() > geom.bottom() - border) && (globalPos.y() <= geom.bottom());
3395 if (left || right || top || bottom) {
3397 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3399 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3401 *result = top ? HTTOP : HTBOTTOM;
3407 const_cast<QWindow *>(w)->close();
3410 const_cast<QWindow *>(w)->showMaximized();
3413 const_cast<QWindow *>(w)->showMinimized();
3416 const_cast<QWindow *>(w)->showNormal();
3419 HWND hwnd =
reinterpret_cast<HWND>(w->winId());
3420 HMENU sysMenu = GetSystemMenu(hwnd,
false);
3421 TrackPopupMenu(sysMenu, 0, globalPos.x(), globalPos.y(), 0, hwnd,
nullptr);
3430 if (m_data.flags & Qt::ExpandedClientAreaHint) {
3431 const int border = (IsZoomed(m_data.hwnd) || isFullScreen_sys()) ? 0 : getResizeBorderThickness(savedDpi());
3436 const QRect rect = geom;
3437 const bool left = (globalPos.x() >= rect.left()) && (globalPos.x() < rect.left() + border);
3438 const bool right = (globalPos.x() > rect.right() - border) && (globalPos.x() <= rect.right());
3439 const bool top = (globalPos.y() >= rect.top()) && (globalPos.y() < rect.top() + border);
3440 const bool bottom = (globalPos.y() > rect.bottom() - border) && (globalPos.y() <= rect.bottom());
3443 if (left || right || top || bottom) {
3445 *result = top ? HTTOPLEFT : (bottom ? HTBOTTOMLEFT : HTLEFT);
3447 *result = top ? HTTOPRIGHT : (bottom ? HTBOTTOMRIGHT : HTRIGHT);
3449 *result = top ? HTTOP : HTBOTTOM;
3457 if (!w->isTopLevel()
3458 || (m_windowState != Qt::WindowNoState)
3460 || (m_data.flags & Qt::FramelessWindowHint)) {
3463 const QSize minimumSize = w->minimumSize();
3464 if (minimumSize.isEmpty())
3466 const QSize maximumSize = w->maximumSize();
3467 const bool fixedWidth = minimumSize.width() == maximumSize.width();
3468 const bool fixedHeight = minimumSize.height() == maximumSize.height();
3469 if (!fixedWidth && !fixedHeight)
3471 const QSize size = w->size();
3473 if (localPos.y() >= size.height()) {
3477 if (localPos.y() < 0) {
3478 const int topResizeBarPos = invisibleMargins(m_data.hwnd).left() - frameMargins().top();
3479 if (localPos.y() < topResizeBarPos) {
3480 *result = HTCAPTION;
3485 if (fixedWidth && (localPos.x() < 0 || localPos.x() >= size.width())) {
3497 if (m_data.flags & Qt::FramelessWindowHint) {
3506 HWND hwnd = m_data.hwndTitlebar;
3507 QWindow *wnd = window();
3510 GetWindowRect(hwnd, &windowRect);
3512 const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
3513 const int titleButtonWidth = titleBarHeight * 1.5;
3514 const qreal factor = QHighDpiScaling::factor(wnd);
3515 const int windowWidth = windowRect.right - windowRect.left;
3518 GetCursorPos(&localPos);
3519 MapWindowPoints(HWND_DESKTOP, m_data.hwnd, &localPos, 1);
3521 const bool isDarkmode = QWindowsIntegration::instance()->darkModeHandling().testFlags(QWindowsApplication::DarkModeWindowFrames) &&
3522 qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
3523 const bool isWindows11orAbove = QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11;
3525 const QBrush closeButtonBrush(QColor(0xC4, 0x2C, 0x1E, 255));
3526 const QBrush minMaxButtonBrush = QBrush(isDarkmode ? QColor(0xFF, 0xFF, 0xFF, 0x40) : QColor(0x00, 0x00, 0x00, 0x20));
3527 const QBrush titleBarBackgroundColor = QBrush(isDarkmode ? QColor(0x1F, 0x1F, 0x1F, 0xFF) : QColor(0xF3, 0xF3, 0xF3, 0xFF));
3528 const QPen textPen = QPen(isDarkmode ? QColor(0xFF, 0xFF, 0xFD, 0xFF) : QColor(0x00, 0x00, 0x00, 0xFF));
3530 QImage image(windowWidth, titleBarHeight, QImage::Format_ARGB32);
3532 p.setCompositionMode(QPainter::CompositionMode_Clear);
3533 p.fillRect(0, 0, windowWidth, titleBarHeight, Qt::transparent);
3535 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
3537 p.setBrush(titleBarBackgroundColor);
3538 p.setPen(Qt::NoPen);
3539 if (!wnd->flags().testFlags(Qt::NoTitleBarBackgroundHint)) {
3541 titleRect.setWidth(windowWidth);
3542 titleRect.setHeight(titleBarHeight);
3543 p.drawRect(titleRect);
3546 if (wnd->flags().testFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3550 titleRect.setWidth(windowWidth);
3551 titleRect.setHeight(titleBarHeight);
3553 titleRect.adjust(factor * 4, 0, 0, 0);
3554 QRect iconRect(titleRect.x(), titleRect.y() + factor * 8, factor * 16, factor * 16);
3555 if (wnd->icon().isNull()) {
3556 static QIcon defaultIcon;
3557 if (defaultIcon.isNull()) {
3558 const QImage defaultIconImage = QImage::fromHICON(LoadIcon(0, IDI_APPLICATION));
3559 defaultIcon = QIcon(QPixmap::fromImage(defaultIconImage));
3561 defaultIcon.paint(&p, iconRect);
3563 wnd->icon().paint(&p, iconRect);
3565 titleRect.adjust(factor * 24, 0, 0, 0);
3569 titleFont.setPointSize(factor * 9);
3570 titleFont.setWeight(QFont::Thin);
3571 titleFont.setHintingPreference(QFont::PreferFullHinting);
3572 p.setFont(titleFont);
3573 const QString title = wnd->title().isEmpty() ? qApp->applicationName() : wnd->title();
3574 p.drawText(titleRect, title, QTextOption(Qt::AlignVCenter));
3578 const QString assetFontName = isWindows11orAbove ? QStringLiteral(
"Segoe Fluent Icons") : QStringLiteral(
"Segoe MDL2 Assets");
3579 QFont assetFont = QFont(assetFontName, factor * 7);
3580 assetFont.setWeight(QFont::Thin);
3581 assetFont.setHintingPreference(QFont::PreferFullHinting);
3582 p.setFont(assetFont);
3583 p.setBrush(closeButtonBrush);
3584 p.setPen(Qt::NoPen);
3585 if (wnd->flags().testFlags(Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3588 rect.setX(windowWidth - titleButtonWidth * buttons);
3589 rect.setWidth(titleButtonWidth);
3590 rect.setHeight(titleBarHeight);
3591 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3592 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3593 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3595 const QPen closeButtonHoveredPen = QPen(QColor(0xFF, 0xFF, 0xFD, 0xFF));
3596 p.setPen(closeButtonHoveredPen);
3600 p.drawText(rect, QStringLiteral(
"\uE8BB"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3604 p.setBrush(minMaxButtonBrush);
3605 p.setPen(Qt::NoPen);
3606 if (wnd->flags().testFlags(Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3609 rect.setX(windowWidth - titleButtonWidth * buttons);
3610 rect.setWidth(titleButtonWidth);
3611 rect.setHeight(titleBarHeight);
3612 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3613 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3614 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3618 p.drawText(rect,QStringLiteral(
"\uE922"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3622 p.setBrush(minMaxButtonBrush);
3623 p.setPen(Qt::NoPen);
3624 if (wnd->flags().testFlags(Qt::WindowMinimizeButtonHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
3627 rect.setX(windowWidth - titleButtonWidth * buttons);
3628 rect.setWidth(titleButtonWidth);
3629 rect.setHeight(titleBarHeight);
3630 if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
3631 localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
3632 localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
3636 p.drawText(rect,QStringLiteral(
"\uE921"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
3642 HBITMAP bmp = image.toHBITMAP();
3644 HDC hdc = GetDC(hwnd);
3646 HDC memdc = CreateCompatibleDC(hdc);
3647 HGDIOBJ original = SelectObject(memdc, bmp);
3650 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
3651 POINT ptLocation = { 0, 0 };
3652 SIZE szWnd = { windowWidth, titleBarHeight };
3653 POINT ptSrc = { 0, 0 };
3654 UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
3655 SelectObject(hdc, original);
3658 DeleteObject(memdc);
3659 ReleaseDC(hwnd,hdc);
3666 if (QScreen *screen = w->screen())
3667 if (
const QPlatformScreen *platformScreen = screen->handle())
3668 if (QPlatformCursor *cursor = platformScreen->cursor())
3669 return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
3670 return CursorHandlePtr(
new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
3679 if (underMouse == w)
3681 for (
const QWindow *p = underMouse; p ; p = p->parent()) {
3684 const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p);
3685 if (platformWindow && !platformWindow->cursor()->isNull())
3693
3694
3695
3696
3706 if (m_cursor->isNull()) {
3707 if (
const QWindow *p = window()->parent()) {
3708 if (
QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(p))
3711 SetCursor(defaultCursor(window())->handle());
3714 SetCursor(m_cursor->handle());
3722 bool changed = c->handle() != m_cursor->handle();
3730 const bool apply = applyNewCursor(window());
3731 qCDebug(lcQpaWindow) << window() <<
__FUNCTION__
3732 << c->handle() <<
" doApply=" << apply;
3755 UINT timeOutMs = GetCaretBlinkTime();
3756 if (!timeOutMs || timeOutMs == INFINITE)
3760 info.cbSize =
sizeof(info);
3761 info.hwnd = m_data.hwnd;
3762 info.dwFlags = FLASHW_TRAY;
3763 info.dwTimeout = timeOutMs;
3764 info.uCount = durationMs == 0 ? 10 : UINT(durationMs) / timeOutMs;
3765 FlashWindowEx(&info);
3771 info.cbSize =
sizeof(info);
3772 info.hwnd = m_data.hwnd;
3773 info.dwFlags = FLASHW_STOP;
3776 FlashWindowEx(&info);
3781 return (style() & WS_DISABLED) == 0;
3786 const unsigned oldStyle =
style();
3787 unsigned newStyle = oldStyle;
3789 newStyle &= ~WS_DISABLED;
3791 newStyle |= WS_DISABLED;
3793 if (newStyle != oldStyle)
3799 if (!icon.isNull()) {
3801 const QPixmap pm = icon.pixmap(icon.actualSize(QSize(xSize, ySize)), 1);
3803 return qt_pixmapToWinHICON(pm);
3813 m_iconSmall = createHIcon(icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON));
3814 m_iconBig = createHIcon(icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
3817 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3818 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconBig));
3820 SendMessage(m_data.hwnd, WM_SETICON, 0 , LPARAM(m_iconSmall));
3821 SendMessage(m_data.hwnd, WM_SETICON, 1 , LPARAM(m_iconSmall));
3828 return window()->isTopLevel() && !m_data.embedded;
3838 const BOOL darkBorder = d ? TRUE : FALSE;
3843 qCWarning(lcQpaWindow,
"%s: Unable to set %s window border.",
__FUNCTION__, d ?
"dark" :
"light");
3850 d = d && shouldApplyDarkFrame(window());
3852 setDarkBorderToWindow(m_data.hwnd, d);
3857 return m_menuBar.data();
3867 if (m_data.flags & Qt::FramelessWindowHint)
3869 return m_data.customMargins;
3873
3874
3875
3876
3877
3878
3879
3880
3884 if (m_data.flags & Qt::FramelessWindowHint) {
3885 qCWarning(lcQpaWindow) <<
"You should not set custom margins for a frameless window.";
3888 if (newCustomMargins != m_data.customMargins) {
3889 const QMargins oldCustomMargins = m_data.customMargins;
3890 m_data.customMargins = newCustomMargins;
3892 const QRect currentFrameGeometry = frameGeometry_sys();
3893 const QPoint topLeft = currentFrameGeometry.topLeft();
3894 QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
3895 newFrame.moveTo(topLeft);
3896 qCDebug(lcQpaWindow) <<
__FUNCTION__ << oldCustomMargins <<
"->" << newCustomMargins
3897 << currentFrameGeometry <<
"->" << newFrame;
3898 SetWindowPos(m_data.hwnd,
nullptr, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
3904#if QT_CONFIG(vulkan)
3905 Q_UNUSED(nativeConfig);
3907 if (window()->surfaceType() == QSurface::VulkanSurface) {
3909 QVulkanInstance *inst = window()->vulkanInstance();
3911 m_vkSurface =
static_cast<QWindowsVulkanInstance *>(inst->handle())->createSurface(handle());
3913 qWarning(
"Attempted to create Vulkan surface without an instance; was QWindow::setVulkanInstance() called?");
3917 return &m_vkSurface;
3919#elif defined(QT_NO_OPENGL)
3921 Q_UNUSED(nativeConfig);
3938#if QT_CONFIG(vulkan)
3940 QVulkanInstance *inst = window()->vulkanInstance();
3942 static_cast<QWindowsVulkanInstance *>(inst->handle())->destroySurface(m_vkSurface);
3943 m_vkSurface = VK_NULL_HANDLE;
3950 m_surface =
nullptr;
3963 const auto currentTouchTypes = touchWindowTouchTypes_sys();
3964 if (currentTouchTypes.has_value() && currentTouchTypes.value() == touchTypes)
3968 ULONG touchFlags = 0;
3969 if (touchTypes.testFlag(TouchWindowTouchType::FineTouch))
3970 touchFlags |= TWF_FINETOUCH;
3971 if (touchTypes.testFlag(TouchWindowTouchType::WantPalmTouch))
3972 touchFlags |= TWF_WANTPALM;
3973 if (RegisterTouchWindow(m_data.hwnd, touchFlags))
3976 qErrnoWarning(
"RegisterTouchWindow() failed for window '%s'.", qPrintable(window()->objectName()));
3981 if (QPlatformWindow *handle = window->handle())
3982 static_cast<QWindowsWindow *>(handle)->setHasBorderInFullScreen(border);
3989 m_borderInFullScreenDefault = border;
4006 if (m_windowState == Qt::WindowFullScreen) {
4007 LONG_PTR style = GetWindowLongPtr(handle(), GWL_STYLE);
4011 style &= ~WS_BORDER;
4012 SetWindowLongPtr(handle(), GWL_STYLE, style);
4018 return QPlatformWindow::formatWindowTitle(title, QStringLiteral(
" - "));
4028 QWindow *w = window();
4029 QDxgiVSyncService *vs = QDxgiVSyncService::instance();
4030 if (vs->supportsWindow(w)) {
4031 if (m_vsyncServiceCallbackId == 0) {
4032 m_vsyncServiceCallbackId = vs->registerCallback([
this, w](
const QDxgiVSyncService::CallbackWindowList &windowList, qint64) {
4033 if (windowList.contains(w)) {
4038 if (m_vsyncUpdatePending.testAndSetAcquire(UpdateState::Requested, UpdateState::Posted)) {
4039 QWindowsWindow *oldSelf =
this;
4040 qsizetype oldCallbackId = m_vsyncServiceCallbackId;
4041 QMetaObject::invokeMethod(w, [w, oldSelf, oldCallbackId] {
4043 auto *self =
static_cast<QWindowsWindow *>(w->handle());
4046 if (self && self == oldSelf && self->m_vsyncServiceCallbackId == oldCallbackId) {
4048 self->m_vsyncUpdatePending.storeRelease(UpdateState::Ready);
4049 self->deliverUpdateRequest();
4056 m_vsyncUpdatePending.testAndSetRelease(UpdateState::Ready, UpdateState::Requested);
4058 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)