summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/libpng/ANNOUNCE27
-rw-r--r--src/3rdparty/libpng/CHANGES11
-rw-r--r--src/3rdparty/libpng/README2
-rw-r--r--src/3rdparty/libpng/libpng-manual.txt16
-rw-r--r--src/3rdparty/libpng/png.c4
-rw-r--r--src/3rdparty/libpng/png.h14
-rw-r--r--src/3rdparty/libpng/pngconf.h2
-rw-r--r--src/3rdparty/libpng/pnglibconf.h2
-rw-r--r--src/3rdparty/libpng/pngpread.c8
-rw-r--r--src/3rdparty/libpng/pngpriv.h6
-rw-r--r--src/3rdparty/libpng/pngread.c7
-rw-r--r--src/3rdparty/libpng/pngrutil.c12
-rw-r--r--src/3rdparty/libpng/qt_attribution.json4
-rw-r--r--src/corelib/io/qsavefile.cpp1
-rw-r--r--src/corelib/io/qsavefile.h1
-rw-r--r--src/corelib/io/qsavefile_p.h1
-rw-r--r--src/corelib/kernel/qvariant.h11
-rw-r--r--src/gui/kernel/qtestsupport_gui.cpp63
-rw-r--r--src/gui/kernel/qtestsupport_gui.h16
-rw-r--r--src/gui/painting/qbackingstoredefaultcompositor.cpp17
-rw-r--r--src/gui/painting/qbackingstoredefaultcompositor_p.h3
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp5
-rw-r--r--src/gui/painting/qplatformbackingstore.h3
-rw-r--r--src/gui/painting/qrhibackingstore.cpp17
-rw-r--r--src/network/socket/qnativesocketengine.cpp13
-rw-r--r--src/opengl/qopenglcompositorbackingstore.cpp4
-rw-r--r--src/opengl/qopenglcompositorbackingstore_p.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp204
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h3
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp150
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style_p.h2
-rw-r--r--src/plugins/styles/modernwindows/qwindowsvistastyle.cpp8
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.cpp63
-rw-r--r--src/widgets/kernel/qtestsupport_widgets.h13
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp14
-rw-r--r--src/widgets/styles/qcommonstyle.cpp3
-rw-r--r--src/widgets/styles/qstyle.cpp12
-rw-r--r--src/widgets/styles/qstyle.h2
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp2
-rw-r--r--src/widgets/widgets/qcombobox.cpp16
45 files changed, 456 insertions, 340 deletions
diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE
index 90c766594e7..516e078082d 100644
--- a/src/3rdparty/libpng/ANNOUNCE
+++ b/src/3rdparty/libpng/ANNOUNCE
@@ -1,5 +1,5 @@
-libpng 1.6.49 - June 12, 2025
-=============================
+libpng 1.6.50 - July 1, 2025
+============================
This is a public release of libpng, intended for use in production code.
@@ -9,13 +9,13 @@ Files available for download
Source files with LF line endings (for Unix/Linux):
- * libpng-1.6.49.tar.xz (LZMA-compressed, recommended)
- * libpng-1.6.49.tar.gz (deflate-compressed)
+ * libpng-1.6.50.tar.xz (LZMA-compressed, recommended)
+ * libpng-1.6.50.tar.gz (deflate-compressed)
Source files with CRLF line endings (for Windows):
- * lpng1649.7z (LZMA-compressed, recommended)
- * lpng1649.zip (deflate-compressed)
+ * lpng1650.7z (LZMA-compressed, recommended)
+ * lpng1650.zip (deflate-compressed)
Other information:
@@ -25,13 +25,18 @@ Other information:
* TRADEMARK.md
-Changes from version 1.6.48 to version 1.6.49
+Changes from version 1.6.49 to version 1.6.50
---------------------------------------------
- * Added SIMD-optimized code for the RISC-V Vector Extension (RVV).
- (Contributed by Manfred Schlaegl, Dragos Tiselice and Filip Wasil)
- * Added various fixes and improvements to the build scripts and to
- the sample code.
+ * Improved the detection of the RVV Extension on the RISC-V platform.
+ (Contributed by Filip Wasil)
+ * Replaced inline ASM with C intrinsics in the RVV code.
+ (Contributed by Filip Wasil)
+ * Fixed a decoder defect in which unknown chunks trailing IDAT, set
+ to go through the unknown chunk handler, incorrectly triggered
+ out-of-place IEND errors.
+ (Contributed by John Bowler)
+ * Fixed the CMake file for cross-platform builds that require `libm`.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES
index 0c0fa6dc70b..b6499b1f34c 100644
--- a/src/3rdparty/libpng/CHANGES
+++ b/src/3rdparty/libpng/CHANGES
@@ -6267,6 +6267,17 @@ Version 1.6.49 [June 12, 2025]
Added various fixes and improvements to the build scripts and to
the sample code.
+Version 1.6.50 [July 1, 2025]
+ Improved the detection of the RVV Extension on the RISC-V platform.
+ (Contributed by Filip Wasil)
+ Replaced inline ASM with C intrinsics in the RVV code.
+ (Contributed by Filip Wasil)
+ Fixed a decoder defect in which unknown chunks trailing IDAT, set
+ to go through the unknown chunk handler, incorrectly triggered
+ out-of-place IEND errors.
+ (Contributed by John Bowler)
+ Fixed the CMake file for cross-platform builds that require `libm`.
+
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
Subscription is required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README
index 9f2b2d0ed53..2eb633ac0fb 100644
--- a/src/3rdparty/libpng/README
+++ b/src/3rdparty/libpng/README
@@ -1,4 +1,4 @@
-README for libpng version 1.6.49
+README for libpng version 1.6.50
================================
See the note about version numbers near the top of `png.h`.
diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt
index f4e151f0c23..6c07e1022b6 100644
--- a/src/3rdparty/libpng/libpng-manual.txt
+++ b/src/3rdparty/libpng/libpng-manual.txt
@@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
- libpng version 1.6.36, December 2018, through 1.6.49 - June 2025
+ libpng version 1.6.36, December 2018, through 1.6.50 - July 2025
Updated and distributed by Cosmin Truta
Copyright (c) 2018-2025 Cosmin Truta
@@ -65,18 +65,22 @@ Libpng was written as a companion to the PNG specification, as a way
of reducing the amount of time and effort it takes to support the PNG
file format in application programs.
-The PNG specification (second edition), November 2003, is available as
+The PNG specification (Third Edition), June 2025, is available as
+a W3C Recommendation at
+<https://www.w3.org/TR/2025/REC-png-3-20250624/>.
+
+The PNG specification (Second Edition), November 2003, is available as
a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
<https://www.w3.org/TR/2003/REC-PNG-20031110/>.
The W3C and ISO documents have identical technical content.
The PNG-1.2 specification is available at
-<https://png-mng.sourceforge.io/pub/png/spec/1.2/>.
-It is technically equivalent
-to the PNG specification (second edition) but has some additional material.
+<https://www.libpng.org/pub/png/spec/1.2/>.
+It is technically equivalent to the PNG specification (Second Edition)
+but has some additional material.
The PNG-1.0 specification is available as RFC 2083 at
-<https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
+<https://www.libpng.org/pub/png/spec/1.0/> and as a
W3C Recommendation at <https://www.w3.org/TR/REC-png-961001>.
Some additional chunks are described in the special-purpose public chunks
diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c
index 8a77b6db5f2..6e21915c402 100644
--- a/src/3rdparty/libpng/png.c
+++ b/src/3rdparty/libpng/png.c
@@ -13,7 +13,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_49 Your_png_h_is_not_version_1_6_49;
+typedef png_libpng_version_1_6_50 Your_png_h_is_not_version_1_6_50;
/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
* corresponding macro definitions. This causes a compile time failure if
@@ -815,7 +815,7 @@ png_get_copyright(png_const_structrp png_ptr)
return PNG_STRING_COPYRIGHT
#else
return PNG_STRING_NEWLINE \
- "libpng version 1.6.49" PNG_STRING_NEWLINE \
+ "libpng version 1.6.50" PNG_STRING_NEWLINE \
"Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
PNG_STRING_NEWLINE \
diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h
index f43e49c521a..b9985e81680 100644
--- a/src/3rdparty/libpng/png.h
+++ b/src/3rdparty/libpng/png.h
@@ -1,6 +1,6 @@
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.49
+ * libpng version 1.6.50
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
@@ -14,7 +14,7 @@
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.35, July 2018:
* Glenn Randers-Pehrson
- * libpng versions 1.6.36, December 2018, through 1.6.49, June 2025:
+ * libpng versions 1.6.36, December 2018, through 1.6.50, July 2025:
* Cosmin Truta
* See also "Contributing Authors", below.
*/
@@ -238,7 +238,7 @@
* ...
* 1.5.30 15 10530 15.so.15.30[.0]
* ...
- * 1.6.49 16 10649 16.so.16.49[.0]
+ * 1.6.50 16 10650 16.so.16.50[.0]
*
* Henceforth the source version will match the shared-library major and
* minor numbers; the shared-library major version number will be used for
@@ -274,7 +274,7 @@
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.49"
+#define PNG_LIBPNG_VER_STRING "1.6.50"
#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
/* The versions of shared library builds should stay in sync, going forward */
@@ -285,7 +285,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 49
+#define PNG_LIBPNG_VER_RELEASE 50
/* This should be zero for a public release, or non-zero for a
* development version.
@@ -316,7 +316,7 @@
* From version 1.0.1 it is:
* XXYYZZ, where XX=major, YY=minor, ZZ=release
*/
-#define PNG_LIBPNG_VER 10649 /* 1.6.49 */
+#define PNG_LIBPNG_VER 10650 /* 1.6.50 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@@ -426,7 +426,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char* png_libpng_version_1_6_49;
+typedef char* png_libpng_version_1_6_50;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h
index e92a3b1eca4..d1081b54ddd 100644
--- a/src/3rdparty/libpng/pngconf.h
+++ b/src/3rdparty/libpng/pngconf.h
@@ -1,6 +1,6 @@
/* pngconf.h - machine-configurable file for libpng
*
- * libpng version 1.6.49
+ * libpng version 1.6.50
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h
index ea61c441ba6..f15fc16dade 100644
--- a/src/3rdparty/libpng/pnglibconf.h
+++ b/src/3rdparty/libpng/pnglibconf.h
@@ -1,6 +1,6 @@
/* pnglibconf.h - library build configuration */
-/* libpng version 1.6.49 */
+/* libpng version 1.6.50 */
/* Copyright (c) 2018-2025 Cosmin Truta */
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c
index 0a3e822cf47..37aa432aeca 100644
--- a/src/3rdparty/libpng/pngpread.c
+++ b/src/3rdparty/libpng/pngpread.c
@@ -229,6 +229,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_benign_error(png_ptr, "Too many IDATs found");
}
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
+ {
+ /* These flags must be set consistently for all non-IDAT chunks,
+ * including the unknown chunks.
+ */
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT;
+ }
+
if (chunk_name == png_IHDR)
{
if (png_ptr->push_length != 13)
diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h
index cb44a6aec8a..e3054b90aae 100644
--- a/src/3rdparty/libpng/pngpriv.h
+++ b/src/3rdparty/libpng/pngpriv.h
@@ -154,11 +154,7 @@
* to configure or put -DPNG_RISCV_RVV_OPT=2 in CPPFLAGS.
*/
-# if defined(__riscv) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
-# define PNG_RISCV_RVV_OPT 1
-# else
-# define PNG_RISCV_RVV_OPT 0
-# endif
+# define PNG_RISCV_RVV_OPT 0
#endif
#if PNG_ARM_NEON_OPT > 0
diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c
index a0dbf2ae208..212afb7d215 100644
--- a/src/3rdparty/libpng/pngread.c
+++ b/src/3rdparty/libpng/pngread.c
@@ -702,7 +702,12 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
png_uint_32 chunk_name = png_ptr->chunk_name;
if (chunk_name != png_IDAT)
- png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+ {
+ /* These flags must be set consistently for all non-IDAT chunks,
+ * including the unknown chunks.
+ */
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT;
+ }
if (chunk_name == png_IEND)
png_handle_chunk(png_ptr, info_ptr, length);
diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c
index 7d9a00186dc..e7c7bbe48e9 100644
--- a/src/3rdparty/libpng/pngrutil.c
+++ b/src/3rdparty/libpng/pngrutil.c
@@ -2412,10 +2412,6 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
#endif
- /* TODO: this doesn't work and shouldn't be necessary. */
- if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
buffer = png_read_buffer(png_ptr, length+1);
if (buffer == NULL)
@@ -2486,10 +2482,6 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
#endif
- /* TODO: should not be necessary. */
- if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
/* Note, "length" is sufficient here; we won't be adding
* a null terminator later. The limit check in png_handle_chunk should be
* sufficient.
@@ -2606,10 +2598,6 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
#endif
- /* TODO: should not be necessary. */
- if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
- png_ptr->mode |= PNG_AFTER_IDAT;
-
buffer = png_read_buffer(png_ptr, length+1);
if (buffer == NULL)
diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json
index 49d0b6ca79f..9327dee564c 100644
--- a/src/3rdparty/libpng/qt_attribution.json
+++ b/src/3rdparty/libpng/qt_attribution.json
@@ -7,8 +7,8 @@
"Description": "libpng is the official PNG reference library.",
"Homepage": "http://www.libpng.org/pub/png/libpng.html",
- "Version": "1.6.49",
- "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.49.tar.xz",
+ "Version": "1.6.50",
+ "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.50.tar.xz",
"PURL": "pkg:github/pnggroup/libpng@v$<VERSION>",
"CPE": "cpe:2.3:a:libpng:libpng:$<VERSION>:*:*:*:*:*:*:*",
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 91f168f20f6..a7d101dc124 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -1,5 +1,6 @@
// Copyright (C) 2012 David Faure <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:critical reason:guaranteed-behavior
#include "qsavefile.h"
diff --git a/src/corelib/io/qsavefile.h b/src/corelib/io/qsavefile.h
index bf0a91bae74..5e8cffe7c38 100644
--- a/src/corelib/io/qsavefile.h
+++ b/src/corelib/io/qsavefile.h
@@ -1,5 +1,6 @@
// Copyright (C) 2012 David Faure <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:header-decls-only
#ifndef QSAVEFILE_H
#define QSAVEFILE_H
diff --git a/src/corelib/io/qsavefile_p.h b/src/corelib/io/qsavefile_p.h
index 50ecdad2daf..e1dcc0abe23 100644
--- a/src/corelib/io/qsavefile_p.h
+++ b/src/corelib/io/qsavefile_p.h
@@ -1,5 +1,6 @@
// Copyright (C) 2013 David Faure <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+// Qt-Security score:significant reason:header-decls-only
#ifndef QSAVEFILE_P_H
#define QSAVEFILE_P_H
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 31f5869c9d9..e9d3ffb9ae3 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -332,7 +332,16 @@ public:
inline void swap(QVariant &other) noexcept { std::swap(d, other.d); }
int userType() const { return typeId(); }
- int typeId() const { return metaType().id(); }
+ int typeId() const
+ {
+ // QVariant types are always registered (see fromMetaType())
+ const QtPrivate::QMetaTypeInterface *mt = metaType().iface();
+ if (!mt)
+ return 0;
+ int id = mt->typeId.loadRelaxed();
+ // Q_ASSUME(id > 0);
+ return id;
+ }
const char *typeName() const;
QMetaType metaType() const;
diff --git a/src/gui/kernel/qtestsupport_gui.cpp b/src/gui/kernel/qtestsupport_gui.cpp
index ca62798ddfd..dfcea928fd8 100644
--- a/src/gui/kernel/qtestsupport_gui.cpp
+++ b/src/gui/kernel/qtestsupport_gui.cpp
@@ -24,8 +24,19 @@ QT_BEGIN_NAMESPACE
/*!
\since 5.0
+ \overload
- Returns \c true, if \a window is active within \a timeout milliseconds. Otherwise returns \c false.
+ The \a timeout is in milliseconds.
+*/
+bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
+{
+ return qWaitForWindowActive(window, QDeadlineTimer{timeout, Qt::TimerType::PreciseTimer});
+}
+
+/*!
+ \since 6.10
+
+ Returns \c true, if \a window is active within \a timeout. Otherwise returns \c false.
The method is useful in tests that call QWindow::show() and rely on the window actually being
active (i.e. being visible and having focus) before proceeding.
@@ -38,7 +49,7 @@ QT_BEGIN_NAMESPACE
\sa qWaitForWindowExposed(), qWaitForWindowFocused(), QWindow::isActive()
*/
-Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
+bool QTest::qWaitForWindowActive(QWindow *window, QDeadlineTimer timeout)
{
if (Q_UNLIKELY(!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))) {
qWarning() << "qWaitForWindowActive was called on a platform that doesn't support window"
@@ -52,6 +63,17 @@ Q_GUI_EXPORT bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
}
/*!
+ \since 6.10
+ \overload
+
+ This function uses the default timeout of 5 seconds.
+*/
+bool QTest::qWaitForWindowActive(QWindow *window)
+{
+ return qWaitForWindowActive(window, Internal::defaultTryTimeout);
+}
+
+/*!
\since 6.7
Returns \c true, if \a window is the focus window within \a timeout. Otherwise returns \c false.
@@ -73,9 +95,31 @@ Q_GUI_EXPORT bool QTest::qWaitForWindowFocused(QWindow *window, QDeadlineTimer t
}
/*!
+ \since 6.10
+ \overload
+
+ This function uses the default timeout of 5 seconds.
+*/
+bool QTest::qWaitForWindowFocused(QWindow *window)
+{
+ return qWaitForWindowFocused(window, Internal::defaultTryTimeout);
+}
+
+/*!
\since 5.0
+ \overload
+
+ The \a timeout is in milliseconds.
+*/
+bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
+{
+ return qWaitForWindowExposed(window, std::chrono::milliseconds(timeout));
+}
- Returns \c true, if \a window is exposed within \a timeout milliseconds. Otherwise returns \c false.
+/*!
+ \since 6.10
+
+ Returns \c true, if \a window is exposed within \a timeout. Otherwise returns \c false.
The method is useful in tests that call QWindow::show() and rely on the window actually being
being visible before proceeding.
@@ -86,11 +130,22 @@ Q_GUI_EXPORT bool QTest::qWaitForWindowFocused(QWindow *window, QDeadlineTimer t
\sa qWaitForWindowActive(), QWindow::isExposed()
*/
-Q_GUI_EXPORT bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
+bool QTest::qWaitForWindowExposed(QWindow *window, QDeadlineTimer timeout)
{
return QTest::qWaitFor([&]() { return window->isExposed(); }, timeout);
}
+/*!
+ \since 6.10
+ \overload
+
+ This function uses the default timeout of 5 seconds.
+*/
+bool QTest::qWaitForWindowExposed(QWindow *window)
+{
+ return qWaitForWindowExposed(window, Internal::defaultTryTimeout);
+}
+
namespace QTest {
QTouchEventSequence::~QTouchEventSequence()
diff --git a/src/gui/kernel/qtestsupport_gui.h b/src/gui/kernel/qtestsupport_gui.h
index 951d9df1c7c..39278c2f034 100644
--- a/src/gui/kernel/qtestsupport_gui.h
+++ b/src/gui/kernel/qtestsupport_gui.h
@@ -23,12 +23,16 @@ Q_GUI_EXPORT bool qt_handleTouchEventv2(QWindow *w, const QPointingDevice *devic
namespace QTest {
-[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowActive(QWindow *window,
- int timeout = static_cast<int>(Internal::defaultTryTimeout.count()));
-[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowFocused(QWindow *window,
- QDeadlineTimer timeout = Internal::defaultTryTimeout);
-[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window,
- int timeout = static_cast<int>(Internal::defaultTryTimeout.count()));
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowActive(QWindow *window, int timeout);
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowActive(QWindow *window, QDeadlineTimer timeout);
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowActive(QWindow *window);
+
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowFocused(QWindow *window, QDeadlineTimer timeout);
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowFocused(QWindow *window);
+
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window, int timeout);
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window, QDeadlineTimer timeout);
+[[nodiscard]] Q_GUI_EXPORT bool qWaitForWindowExposed(QWindow *window);
Q_GUI_EXPORT QPointingDevice * createTouchDevice(QInputDevice::DeviceType devType = QInputDevice::DeviceType::TouchScreen,
QInputDevice::Capabilities caps = QInputDevice::Capability::Position);
diff --git a/src/gui/painting/qbackingstoredefaultcompositor.cpp b/src/gui/painting/qbackingstoredefaultcompositor.cpp
index c1452ca7688..41ab7c97f8c 100644
--- a/src/gui/painting/qbackingstoredefaultcompositor.cpp
+++ b/src/gui/painting/qbackingstoredefaultcompositor.cpp
@@ -460,11 +460,20 @@ QPlatformBackingStore::FlushResult QBackingStoreDefaultCompositor::flush(QPlatfo
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground)
+ bool translucentBackground,
+ qreal sourceTransformFactor)
{
if (!rhi)
return QPlatformBackingStore::FlushFailed;
+ // Note, the sourceTransformFactor is different from the sourceDevicePixelRatio,
+ // as the former may reflect the fact that the region and offset is pre-transformed,
+ // in which case we don't need to do a full transform here based on the source DPR.
+ // In the default case where no explicit source transform has been passed, we fall
+ // back to the source device pixel ratio.
+ if (!sourceTransformFactor)
+ sourceTransformFactor = sourceDevicePixelRatio;
+
Q_ASSERT(textures); // may be empty if there are no render-to-texture widgets at all, but null it cannot be
if (!m_rhi) {
@@ -508,7 +517,7 @@ QPlatformBackingStore::FlushResult QBackingStoreDefaultCompositor::flush(QPlatfo
const QImage::Format format = QImage::toImageFormat(graphicsBuffer->format());
const QSize size = graphicsBuffer->size();
QImage wrapperImage(graphicsBuffer->data(), size.width(), size.height(), graphicsBuffer->bytesPerLine(), format);
- toTexture(wrapperImage, rhi, resourceUpdates, scaledRegion(region, sourceDevicePixelRatio, offset), &flags);
+ toTexture(wrapperImage, rhi, resourceUpdates, scaledRegion(region, sourceTransformFactor, offset), &flags);
gotTextureFromGraphicsBuffer = true;
graphicsBuffer->unlock();
if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft)
@@ -516,7 +525,7 @@ QPlatformBackingStore::FlushResult QBackingStoreDefaultCompositor::flush(QPlatfo
}
}
if (!gotTextureFromGraphicsBuffer)
- toTexture(backingStore, rhi, resourceUpdates, scaledRegion(region, sourceDevicePixelRatio, offset), &flags);
+ toTexture(backingStore, rhi, resourceUpdates, scaledRegion(region, sourceTransformFactor, offset), &flags);
ensureResources(resourceUpdates, swapchain->renderPassDescriptor());
@@ -549,7 +558,7 @@ QPlatformBackingStore::FlushResult QBackingStoreDefaultCompositor::flush(QPlatfo
// The backingstore is for the entire tlw. In case of native children, offset tells the position
// relative to the tlw. The window rect is scaled by the source device pixel ratio to get
// the source rect.
- const QPoint sourceWindowOffset = scaledOffset(offset, sourceDevicePixelRatio);
+ const QPoint sourceWindowOffset = scaledOffset(offset, sourceTransformFactor);
const QRect srcRect = toBottomLeftRect(sourceWindowRect.translated(sourceWindowOffset), m_texture->pixelSize().height());
const QMatrix3x3 source = sourceTransform(srcRect, m_texture->pixelSize(), origin);
QMatrix4x4 target; // identity
diff --git a/src/gui/painting/qbackingstoredefaultcompositor_p.h b/src/gui/painting/qbackingstoredefaultcompositor_p.h
index c5a8ffd328e..cdc9d098099 100644
--- a/src/gui/painting/qbackingstoredefaultcompositor_p.h
+++ b/src/gui/painting/qbackingstoredefaultcompositor_p.h
@@ -41,7 +41,8 @@ public:
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground);
+ bool translucentBackground,
+ qreal sourceTransformFactor);
private:
enum UpdateUniformOption {
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index 21e89d67fd2..2acc5ef7c52 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -213,14 +213,15 @@ QPlatformBackingStore::FlushResult QPlatformBackingStore::rhiFlush(QWindow *wind
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground)
+ bool translucentBackground,
+ qreal sourceTransformFactor)
{
auto &surfaceSupport = d_ptr->surfaceSupport[window->surfaceType()];
return surfaceSupport.compositor.flush(this,
surfaceSupport.rhiSupport.rhi(),
surfaceSupport.rhiSupport.swapChainForWindow(window),
window, sourceDevicePixelRatio, region, offset, textures,
- translucentBackground);
+ translucentBackground, sourceTransformFactor);
}
/*!
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index a6cb43b4e66..86035b98bea 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -151,7 +151,8 @@ public:
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground);
+ bool translucentBackground,
+ qreal sourceTransformFactor = 0);
virtual QImage toImage() const;
diff --git a/src/gui/painting/qrhibackingstore.cpp b/src/gui/painting/qrhibackingstore.cpp
index d59cc2d83c5..3d9932e5ee2 100644
--- a/src/gui/painting/qrhibackingstore.cpp
+++ b/src/gui/painting/qrhibackingstore.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qrhibackingstore_p.h"
+#include "qpa/qplatformwindow.h"
#include <private/qimage_p.h>
QT_BEGIN_NAMESPACE
@@ -43,10 +44,22 @@ void QRhiBackingStore::flush(QWindow *flushedWindow, const QRegion &region, cons
createRhi(flushedWindow, rhiConfig);
}
+ // The backing store operates on behalf of its window(), even if we're
+ // flushing a child window, so pull the source DPR from the window().
+ const qreal sourceDevicePixelRatio = window()->devicePixelRatio();
+
+ // QBackingStore::flush will convert the region and offset from device independent
+ // pixels to native pixels before calling QPlatformBackingStore::flush, which means
+ // we can't pass on the window's DPR as the sourceTransformFactor, as that will include
+ // the Qt scale factor, which has already been applied. Instead we ask the platform
+ // window, which only reflect the remaining scale factor from the OS.
+ const qreal sourceTransformFactor = flushedWindow->handle()->devicePixelRatio();
+
static QPlatformTextureList emptyTextureList;
bool translucentBackground = m_image.hasAlphaChannel();
- rhiFlush(flushedWindow, flushedWindow->devicePixelRatio(),
- region, offset, &emptyTextureList, translucentBackground);
+ rhiFlush(flushedWindow, sourceDevicePixelRatio,
+ region, offset, &emptyTextureList, translucentBackground,
+ sourceTransformFactor);
}
QImage::Format QRhiBackingStore::format() const
diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp
index 4c8b3ebf3f8..ca5fb50f086 100644
--- a/src/network/socket/qnativesocketengine.cpp
+++ b/src/network/socket/qnativesocketengine.cpp
@@ -429,11 +429,14 @@ bool QNativeSocketEngine::initialize(QAbstractSocket::SocketType socketType, QAb
if (socketType == QAbstractSocket::UdpSocket) {
// Set the broadcasting flag if it's a UDP socket.
- if (!setOption(BroadcastSocketOption, 1)) {
- d->setError(QAbstractSocket::UnsupportedSocketOperationError,
- QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
- close();
- return false;
+ // IPv6 does not support broadcast — only set option for IPv4
+ if (protocol == QAbstractSocket::IPv4Protocol) {
+ if (!setOption(BroadcastSocketOption, 1)) {
+ d->setError(QAbstractSocket::UnsupportedSocketOperationError,
+ QNativeSocketEnginePrivate::BroadcastingInitFailedErrorString);
+ close();
+ return false;
+ }
}
// Set some extra flags that are interesting to us, but accept failure
diff --git a/src/opengl/qopenglcompositorbackingstore.cpp b/src/opengl/qopenglcompositorbackingstore.cpp
index 20c86fb8adc..95dd1a562a6 100644
--- a/src/opengl/qopenglcompositorbackingstore.cpp
+++ b/src/opengl/qopenglcompositorbackingstore.cpp
@@ -163,7 +163,8 @@ QPlatformBackingStore::FlushResult QOpenGLCompositorBackingStore::rhiFlush(QWind
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground)
+ bool translucentBackground,
+ qreal sourceTransformFactor)
{
// QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top.
@@ -171,6 +172,7 @@ QPlatformBackingStore::FlushResult QOpenGLCompositorBackingStore::rhiFlush(QWind
Q_UNUSED(offset);
Q_UNUSED(translucentBackground);
Q_UNUSED(sourceDevicePixelRatio);
+ Q_UNUSED(sourceTransformFactor);
m_rhi = rhi(window);
Q_ASSERT(m_rhi);
diff --git a/src/opengl/qopenglcompositorbackingstore_p.h b/src/opengl/qopenglcompositorbackingstore_p.h
index 4512e2d589e..b50629000cf 100644
--- a/src/opengl/qopenglcompositorbackingstore_p.h
+++ b/src/opengl/qopenglcompositorbackingstore_p.h
@@ -48,7 +48,8 @@ public:
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground) override;
+ bool translucentBackground,
+ qreal sourceTransformFactor = 0) override;
const QPlatformTextureList *textures() const { return m_textures; }
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index 71b6015a54d..79aed15a1d0 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -44,7 +44,8 @@ public:
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground) override;
+ bool translucentBackground,
+ qreal sourceTransformFactor) override;
QImage toImage() const override;
QPlatformGraphicsBuffer *graphicsBuffer() const override;
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 78d23b01dea..186aeaac44d 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -457,7 +457,8 @@ QPlatformBackingStore::FlushResult QCALayerBackingStore::rhiFlush(QWindow *windo
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground)
+ bool translucentBackground,
+ qreal sourceTransformFactor)
{
if (!m_buffers.back()) {
qCWarning(lcQpaBackingStore) << "Flush requested with no back buffer. Ignoring.";
@@ -466,7 +467,8 @@ QPlatformBackingStore::FlushResult QCALayerBackingStore::rhiFlush(QWindow *windo
finalizeBackBuffer();
- return QPlatformBackingStore::rhiFlush(window, sourceDevicePixelRatio, region, offset, textures, translucentBackground);
+ return QPlatformBackingStore::rhiFlush(window, sourceDevicePixelRatio,
+ region, offset, textures, translucentBackground, sourceTransformFactor);
}
QImage QCALayerBackingStore::toImage() const
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 3fe837a2c03..a407cde2a7c 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -1156,9 +1156,13 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::MoveEvent:
platformWindow->handleMoved();
return true;
- case QtWindows::ResizeEvent:
+ case QtWindows::ResizeEvent: {
+ QWindow *window = platformWindow->window();
platformWindow->handleResized(static_cast<int>(wParam), lParam);
+ if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
+ platformWindow->updateCustomTitlebar();
return true;
+ }
case QtWindows::QuerySizeHints:
platformWindow->getSizeHints(reinterpret_cast<MINMAXINFO *>(lParam));
return true;// maybe available on some SDKs revisit WM_NCCALCSIZE
@@ -1174,8 +1178,12 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return platformWindow->handleNonClientActivate(result);
case QtWindows::GeometryChangingEvent:
return platformWindow->handleGeometryChanging(&msg);
- case QtWindows::ExposeEvent:
+ case QtWindows::ExposeEvent: {
+ QWindow *window = platformWindow->window();
+ if (window->flags().testFlags(Qt::ExpandedClientAreaHint))
+ platformWindow->updateCustomTitlebar();
return platformWindow->handleWmPaint(hwnd, message, wParam, lParam, result);
+ }
case QtWindows::NonClientMouseEvent:
if (!platformWindow->frameStrutEventsEnabled())
break;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index a4bb59cf42c..731673b61db 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -284,40 +284,6 @@ static inline RECT RECTfromQRect(const QRect &rect)
return result;
}
-static LRESULT WINAPI WndProcTitleBar(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- HWND parentHwnd = reinterpret_cast<HWND>(GetWindowLongPtr(hwnd, GWL_HWNDPARENT));
- QWindowsWindow* platformWindow = QWindowsContext::instance()->findPlatformWindow(parentHwnd);
-
- switch (message) {
- case WM_SHOWWINDOW:
- ShowWindow(hwnd,SW_HIDE);
- if ((BOOL)wParam == TRUE)
- platformWindow->transitionAnimatedCustomTitleBar();
- return 0;
- case WM_SIZE: {
- if (platformWindow)
- platformWindow->updateCustomTitlebar();
- break;
- }
- case WM_NCHITTEST:
- return HTTRANSPARENT;
- case WM_TIMER:
- ShowWindow(hwnd, SW_SHOWNOACTIVATE);
- platformWindow->updateCustomTitlebar();
- break;
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- BeginPaint(hwnd, &ps);
- EndPaint(hwnd, &ps);
- return 0;
- }
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
-}
-
-
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const RECT &r)
{
@@ -917,7 +883,7 @@ QWindowsWindowData
const auto appinst = reinterpret_cast<HINSTANCE>(GetModuleHandle(nullptr));
const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);
- const QString windowTitlebarName = QWindowsContext::instance()->registerWindowClass(QStringLiteral("_q_titlebar"), WndProcTitleBar, CS_VREDRAW|CS_HREDRAW, nullptr, false);
+ const QString windowTitlebarName = QWindowsContext::instance()->registerWindowClass(QStringLiteral("_q_titlebar"), DefWindowProc, CS_VREDRAW|CS_HREDRAW, nullptr, false);
const QScreen *screen{};
const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
@@ -970,15 +936,13 @@ QWindowsWindowData
context->frameWidth, context->frameHeight,
parentHandle, nullptr, appinst, nullptr);
- if (w->flags().testFlags(Qt::ExpandedClientAreaHint)) {
- const UINT dpi = ::GetDpiForWindow(result.hwnd);
- const int titleBarHeight = getTitleBarHeight_sys(dpi);
- result.hwndTitlebar = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT,
- classTitleBarNameUtf16, classTitleBarNameUtf16,
- WS_POPUP, 0, 0,
- context->frameWidth, titleBarHeight,
- result.hwnd, nullptr, appinst, nullptr);
- }
+ const UINT dpi = ::GetDpiForWindow(result.hwnd);
+ const int titleBarHeight = getTitleBarHeight_sys(dpi);
+ result.hwndTitlebar = CreateWindowEx(WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,
+ classTitleBarNameUtf16, classTitleBarNameUtf16,
+ 0, 0, 0,
+ context->frameWidth, titleBarHeight,
+ nullptr, nullptr, appinst, nullptr);
qCDebug(lcQpaWindow).nospace()
<< "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
@@ -1056,6 +1020,9 @@ void WindowCreationData::initialize(const QWindow *w, HWND hwnd, bool frameChang
if (flags & Qt::ExpandedClientAreaHint) { // Gives us the rounded corners looks and the frame shadow
MARGINS margins = { -1, -1, -1, -1 };
DwmExtendFrameIntoClientArea(hwnd, &margins);
+ } else {
+ MARGINS margins = { 0, 0, 0, 0 };
+ DwmExtendFrameIntoClientArea(hwnd, &margins);
}
} else { // child.
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, swpFlags);
@@ -1196,19 +1163,21 @@ bool QWindowsGeometryHint::handleCalculateSize(const QWindow *window, const QMar
*result = 0;
return true;
}
+ const QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(window);
+ // In case the platformwindow was not yet created, use the initial windowflags provided by the user.
+ const bool clientAreaExpanded = platformWindow != nullptr ? platformWindow->isClientAreaExpanded() : window->flags() & Qt::ExpandedClientAreaHint;
// Return 0 to remove the window's border
- const bool clientAreaExpanded = window->flags() & Qt::ExpandedClientAreaHint;
if (msg.wParam && clientAreaExpanded) {
// Prevent content from being cutoff by border for maximized, but not fullscreened windows.
- if (IsZoomed(msg.hwnd) && window->visibility() != QWindow::FullScreen) {
- auto *ncp = reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
- RECT *clientArea = &ncp->rgrc[0];
- const int border = getResizeBorderThickness(QWindowsWindow::windowsWindowOf(window)->savedDpi());
+ const bool maximized = IsZoomed(msg.hwnd) && window->visibility() != QWindow::FullScreen;
+ auto *ncp = reinterpret_cast<NCCALCSIZE_PARAMS *>(msg.lParam);
+ RECT *clientArea = &ncp->rgrc[0];
+ const int border = getResizeBorderThickness(96);
+ if (maximized)
clientArea->top += border;
- clientArea->bottom -= border;
- clientArea->left += border;
- clientArea->right -= border;
- }
+ clientArea->bottom -= border;
+ clientArea->left += border;
+ clientArea->right -= border;
*result = 0;
return true;
}
@@ -1628,6 +1597,12 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
#endif
{
QWindowsContext::instance()->addWindow(m_data.hwnd, this);
+
+ if (aWindow->flags().testFlags(Qt::ExpandedClientAreaHint)) {
+ SetParent(m_data.hwndTitlebar, m_data.hwnd);
+ ShowWindow(m_data.hwndTitlebar, SW_SHOW);
+ }
+
const Qt::WindowType type = aWindow->type();
if (type == Qt::Desktop)
return; // No further handling for Qt::Desktop
@@ -1852,21 +1827,6 @@ QWindow *QWindowsWindow::topLevelOf(QWindow *w)
return w;
}
-// Checks whether the Window is tiled with Aero snap
-bool QWindowsWindow::isWindowArranged(HWND hwnd)
-{
- typedef BOOL(WINAPI* PIsWindowArranged)(HWND);
- static PIsWindowArranged pIsWindowArranged = nullptr;
- static bool resolved = false;
- if (!resolved) {
- resolved = true;
- pIsWindowArranged = (PIsWindowArranged)QSystemLibrary::resolve(QLatin1String("user32.dll"), "IsWindowArranged");
- }
- if (pIsWindowArranged == nullptr)
- return false;
- return pIsWindowArranged(hwnd);
-}
-
QWindowsWindowData
QWindowsWindowData::create(const QWindow *w,
const QWindowsWindowData &parameters,
@@ -1908,13 +1868,6 @@ void QWindowsWindow::setVisible(bool visible)
fireExpose(QRegion());
}
}
- if (m_data.hwndTitlebar) {
- if (visible) {
- SetWindowPos(m_data.hwndTitlebar, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- } else {
- ShowWindow(m_data.hwndTitlebar, SW_HIDE);
- }
- }
}
bool QWindowsWindow::isVisible() const
@@ -2055,10 +2008,6 @@ void QWindowsWindow::show_sys() const
setFlag(WithinMaximize); // QTBUG-8361
ShowWindow(m_data.hwnd, sm);
- if (m_data.flags.testFlag(Qt::ExpandedClientAreaHint)) {
- ShowWindow(m_data.hwndTitlebar, sm);
- SetActiveWindow(m_data.hwnd);
- }
clearFlag(WithinMaximize);
@@ -2250,7 +2199,7 @@ QRect QWindowsWindow::normalGeometry() const
QMargins QWindowsWindow::safeAreaMargins() const
{
if (m_data.flags.testFlags(Qt::ExpandedClientAreaHint)) {
- const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
+ const int titleBarHeight = getTitleBarHeight_sys(96);
return QMargins(0, titleBarHeight, 0, 0);
}
@@ -2462,15 +2411,9 @@ void QWindowsWindow::handleGeometryChange()
clearFlag(SynchronousGeometryChangeEvent);
qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry;
- if (m_data.hwndTitlebar) {
- bool arranged = QWindowsWindow::isWindowArranged(m_data.hwnd);
- if (arranged || (m_windowWasArranged && !arranged))
- transitionAnimatedCustomTitleBar();
-
+ if (m_data.flags & Qt::ExpandedClientAreaHint) {
const int titleBarHeight = getTitleBarHeight_sys(savedDpi());
- MoveWindow(m_data.hwndTitlebar, m_data.geometry.x(), m_data.geometry.y(),
- m_data.geometry.width(), titleBarHeight, true);
- m_windowWasArranged = arranged;
+ MoveWindow(m_data.hwndTitlebar, 0, 0, m_data.geometry.width(), titleBarHeight, true);
}
}
@@ -2632,6 +2575,16 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
creationData.applyWindowFlags(m_data.hwnd);
creationData.initialize(window(), m_data.hwnd, true, m_opacity);
+ if (creationData.flags.testFlag(Qt::ExpandedClientAreaHint)) {
+ SetParent(m_data.hwndTitlebar, m_data.hwnd);
+ ShowWindow(m_data.hwndTitlebar, SW_SHOW);
+ } else {
+ if (IsWindowVisible(m_data.hwndTitlebar)) {
+ SetParent(m_data.hwndTitlebar, HWND_MESSAGE);
+ ShowWindow(m_data.hwndTitlebar, SW_HIDE);
+ }
+ }
+
QWindowsWindowData result = m_data;
result.flags = creationData.flags;
result.embedded = creationData.embedded;
@@ -2650,7 +2603,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
handleHidden();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); // Tell QQuickWindow to stop rendering now.
} else {
- transitionAnimatedCustomTitleBar();
+ updateCustomTitlebar();
if (state & Qt::WindowMaximized) {
WINDOWPLACEMENT windowPlacement{};
windowPlacement.length = sizeof(WINDOWPLACEMENT);
@@ -2748,20 +2701,6 @@ void QWindowsWindow::correctWindowPlacement(WINDOWPLACEMENT &windowPlacement)
}
}
-void QWindowsWindow::transitionAnimatedCustomTitleBar()
-{
- if (!m_data.hwndTitlebar)
- return;
- const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Control Panel\Desktop\WindowMetrics)");
- if (registry.isValid() && registry.value(LR"(MinAnimate)") == 1) {
- ShowWindow(m_data.hwndTitlebar, SW_HIDE);
- SetTimer(m_data.hwndTitlebar, 1, 200, nullptr);
- } else {
- ShowWindow(m_data.hwndTitlebar, SW_SHOWNOACTIVATE);
- updateCustomTitlebar();
- }
-}
-
void QWindowsWindow::updateRestoreGeometry()
{
m_data.restoreGeometry = normalFrameGeometry(m_data.hwnd);
@@ -3083,7 +3022,8 @@ void QWindowsWindow::calculateFullFrameMargins()
const auto systemMargins = testFlag(DisableNonClientScaling)
? QWindowsGeometryHint::frameOnPrimaryScreen(window(), m_data.hwnd)
: frameMargins_sys();
- const QMargins actualMargins = systemMargins + customMargins();
+ const int extendedClientAreaBorder = window()->flags().testFlag(Qt::ExpandedClientAreaHint) ? qRound(QHighDpiScaling::factor(window())) * 2 : 0;
+ const QMargins actualMargins = systemMargins + customMargins() - extendedClientAreaBorder;
const int yDiff = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
const bool typicalFrame = (actualMargins.left() == actualMargins.right())
@@ -3522,19 +3462,6 @@ bool QWindowsWindow::handleNonClientActivate(LRESULT *result) const
return false;
}
-static void _q_drawCustomTitleBarButton(QPainter& p, const QRectF& r)
-{
- QPainterPath path(QPointF(r.x(), r.y()));
- QRectF rightCorner(r.x() + r.width() - 2.0, r.y() + 4.0, 2, 2);
- QRectF leftCorner(r.x(), r.y() + 4, 2, 2);
- path.lineTo(r.x() + r.width() - 5.0f, r.y());
- path.arcTo(rightCorner, 90, -90);
- path.lineTo(r.x() + r.width(), r.y() + r.height() - 1);
- path.lineTo(r.x(), r.y() + r.height() - 1);
- path.closeSubpath();
- p.drawPath(path);
-}
-
void QWindowsWindow::updateCustomTitlebar()
{
HWND hwnd = m_data.hwndTitlebar;
@@ -3550,7 +3477,7 @@ void QWindowsWindow::updateCustomTitlebar()
POINT localPos;
GetCursorPos(&localPos);
- MapWindowPoints(HWND_DESKTOP, hwnd, &localPos, 1);
+ MapWindowPoints(HWND_DESKTOP, m_data.hwnd, &localPos, 1);
const bool isDarkmode = QWindowsIntegration::instance()->darkModeHandling().testFlags(QWindowsApplication::DarkModeWindowFrames) &&
qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
@@ -3572,25 +3499,9 @@ void QWindowsWindow::updateCustomTitlebar()
p.setPen(Qt::NoPen);
if (!wnd->flags().testFlags(Qt::NoTitleBarBackgroundHint)) {
QRect titleRect;
- titleRect.setX(2);
titleRect.setWidth(windowWidth);
titleRect.setHeight(titleBarHeight);
-
- if (isWindows11orAbove) {
- QPainterPath path(QPointF(titleRect.x() + 4.0f, titleRect.y()));
- QRectF rightCorner(titleRect.x() + titleRect.width() - 4.0, titleRect.y() + 4.0, 2, 2);
- QRectF leftCorner(titleRect.x(), titleRect.y() + 4, 2, 2);
- path.lineTo(titleRect.x() + titleRect.width() - 7.0f, titleRect.y());
- path.arcTo(rightCorner, 90, -90);
- path.lineTo(titleRect.x() + titleRect.width() - 2.0, titleRect.y() + titleRect.height() - 1);
- path.lineTo(titleRect.x(), titleRect.y() + titleRect.height() - 1);
- path.lineTo(titleRect.x(), titleRect.y() + 4.0f);
- path.arcTo(leftCorner, -90, -90);
- path.closeSubpath();
- p.drawPath(path);
- } else {
- p.drawRect(titleRect);
- }
+ p.drawRect(titleRect);
}
if (wnd->flags().testFlags(Qt::WindowTitleHint | Qt::CustomizeWindowHint) || !wnd->flags().testFlag(Qt::CustomizeWindowHint)) {
@@ -3636,15 +3547,12 @@ void QWindowsWindow::updateCustomTitlebar()
QRectF rect;
rect.setY(1);
rect.setX(windowWidth - titleButtonWidth * buttons);
- rect.setWidth(titleButtonWidth - 1);
+ rect.setWidth(titleButtonWidth);
rect.setHeight(titleBarHeight);
if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
- if (isWindows11orAbove && buttons == 1)
- _q_drawCustomTitleBarButton(p, rect);
- else
- p.drawRect(rect);
+ p.drawRect(rect);
const QPen closeButtonHoveredPen = QPen(QColor(0xFF, 0xFF, 0xFD, 0xFF));
p.setPen(closeButtonHoveredPen);
} else {
@@ -3660,15 +3568,12 @@ void QWindowsWindow::updateCustomTitlebar()
QRectF rect;
rect.setY(1);
rect.setX(windowWidth - titleButtonWidth * buttons);
- rect.setWidth(titleButtonWidth - 1);
+ rect.setWidth(titleButtonWidth);
rect.setHeight(titleBarHeight);
if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
- if (isWindows11orAbove && buttons == 1)
- _q_drawCustomTitleBarButton(p, rect);
- else
- p.drawRect(rect);
+ p.drawRect(rect);
}
p.setPen(textPen);
p.drawText(rect,QStringLiteral("\uE922"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
@@ -3681,15 +3586,12 @@ void QWindowsWindow::updateCustomTitlebar()
QRectF rect;
rect.setY(1);
rect.setX(windowWidth - titleButtonWidth * buttons);
- rect.setWidth(titleButtonWidth - 1);
+ rect.setWidth(titleButtonWidth);
rect.setHeight(titleBarHeight);
if (localPos.x > (windowWidth - buttons * titleButtonWidth) &&
localPos.x < (windowWidth - (buttons - 1) * titleButtonWidth) &&
localPos.y > rect.y() && localPos.y < rect.y() + rect.height()) {
- if (isWindows11orAbove && buttons == 1)
- _q_drawCustomTitleBarButton(p, rect);
- else
- p.drawRect(rect);
+ p.drawRect(rect);
}
p.setPen(textPen);
p.drawText(rect,QStringLiteral("\uE921"), QTextOption(Qt::AlignVCenter | Qt::AlignHCenter));
@@ -3707,7 +3609,7 @@ void QWindowsWindow::updateCustomTitlebar()
BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
- POINT ptLocation = { windowRect.left, windowRect.top };
+ POINT ptLocation = { 0, 0 };
SIZE szWnd = { windowWidth, titleBarHeight };
POINT ptSrc = { 0, 0 };
UpdateLayeredWindow(hwnd, hdc, &ptLocation, &szWnd, memdc, &ptSrc, 0, &blend, ULW_ALPHA);
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index b67bd2850b3..a0e150aeb01 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -307,7 +307,6 @@ public:
static QWindow *topLevelOf(QWindow *w);
static inline void *userDataOf(HWND hwnd);
static inline void setUserDataOf(HWND hwnd, void *ud);
- static bool isWindowArranged(HWND hwnd);
static bool hasNoNativeFrame(HWND hwnd, Qt::WindowFlags flags);
static bool setWindowLayered(HWND hwnd, Qt::WindowFlags flags, bool hasAlpha, qreal opacity);
@@ -359,12 +358,10 @@ public:
int savedDpi() const { return m_savedDpi; }
qreal dpiRelativeScale(const UINT dpi) const;
- bool isFrameless() const { return m_data.flags.testFlag(Qt::FramelessWindowHint); }
+ bool isClientAreaExpanded() const { return m_data.flags.testFlag(Qt::ExpandedClientAreaHint); }
void requestUpdate() override;
- void transitionAnimatedCustomTitleBar();
-
private:
inline void show_sys() const;
inline QWindowsWindowData setWindowFlags_sys(Qt::WindowFlags wt, unsigned flags = 0) const;
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 8353fac6a92..fda47944d9d 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -870,7 +870,8 @@ QPlatformBackingStore::FlushResult QXcbBackingStore::rhiFlush(QWindow *window,
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground)
+ bool translucentBackground,
+ qreal sourceTransformFactor)
{
if (!m_image || m_image->size().isEmpty())
return FlushFailed;
@@ -878,7 +879,7 @@ QPlatformBackingStore::FlushResult QXcbBackingStore::rhiFlush(QWindow *window,
m_image->flushScrolledRegion(true);
auto result = QPlatformBackingStore::rhiFlush(window, sourceDevicePixelRatio, region, offset,
- textures, translucentBackground);
+ textures, translucentBackground, sourceTransformFactor);
if (result != FlushSuccess)
return result;
QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
index 674640780eb..5cda9e1ab79 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.h
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -27,7 +27,8 @@ public:
const QRegion &region,
const QPoint &offset,
QPlatformTextureList *textures,
- bool translucentBackground) override;
+ bool translucentBackground,
+ qreal sourceTransformFactor) override;
QImage toImage() const override;
QPlatformGraphicsBuffer *graphicsBuffer() const override;
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index e2e4fce357e..7ae48a302f4 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -242,11 +242,11 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
QCachedPainter cp(painter, QLatin1StringView("win11_spinbox") % HexString<uint8_t>(colorSchemeIndex),
sb, sb->rect.size());
if (cp.needsPainting()) {
- const auto frameRect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1));
+ const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
drawRoundedRect(cp.painter(), frameRect, Qt::NoPen, option->palette.brush(QPalette::Base));
if (sb->frame && (sub & SC_SpinBoxFrame))
- drawLineEditFrame(cp.painter(), option);
+ drawLineEditFrame(cp.painter(), frameRect, option);
const bool isMouseOver = state & State_MouseOver;
const bool hasFocus = state & State_HasFocus;
@@ -412,11 +412,11 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
#if QT_CONFIG(combobox)
case CC_ComboBox:
if (const QStyleOptionComboBox *combobox = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
- const auto frameRect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1));
+ const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
drawRoundedRect(painter, frameRect, Qt::NoPen, option->palette.brush(QPalette::Base));
if (combobox->frame)
- drawLineEditFrame(painter, option);
+ drawLineEditFrame(painter, frameRect, option);
const bool isMouseOver = state & State_MouseOver;
const bool hasFocus = state & State_HasFocus;
@@ -668,7 +668,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
t->setStartValue(styleObject->property("_q_inner_radius").toFloat());
t->setEndValue(7.0f);
if (option->state & State_Sunken)
- t->setEndValue(2.0f);
+ t->setEndValue(4.0f);
else if (option->state & State_MouseOver && !(option->state & State_On))
t->setEndValue(7.0f);
else if (option->state & State_MouseOver && (option->state & State_On))
@@ -709,27 +709,19 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
switch (element) {
case PE_PanelTipLabel: {
- QRectF tipRect = option->rect.marginsRemoved(QMargins(1,1,1,1));
- painter->setPen(Qt::NoPen);
- painter->setBrush(option->palette.toolTipBase());
- painter->drawRoundedRect(tipRect, secondLevelRoundingRadius, secondLevelRoundingRadius);
-
- painter->setPen(highContrastTheme == true ? option->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
- painter->setBrush(Qt::NoBrush);
- painter->drawRoundedRect(tipRect.marginsAdded(QMarginsF(0.5,0.5,0.5,0.5)), secondLevelRoundingRadius, secondLevelRoundingRadius);
+ const auto rect = QRectF(option->rect).marginsRemoved(QMarginsF(0.5, 0.5, 0.5, 0.5));
+ const auto pen = highContrastTheme ? option->palette.buttonText().color()
+ : winUI3Color(frameColorLight);
+ drawRoundedRect(painter, rect, pen, option->palette.toolTipBase());
break;
}
case PE_FrameTabWidget:
#if QT_CONFIG(tabwidget)
if (const QStyleOptionTabWidgetFrame *frame = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) {
- QRectF frameRect = frame->rect.marginsRemoved(QMargins(0,0,0,0));
- painter->setPen(Qt::NoPen);
- painter->setBrush(frame->palette.base());
- painter->drawRoundedRect(frameRect, secondLevelRoundingRadius, secondLevelRoundingRadius);
-
- painter->setPen(highContrastTheme == true ? frame->palette.buttonText().color() : WINUI3Colors[colorSchemeIndex][frameColorLight]);
- painter->setBrush(Qt::NoBrush);
- painter->drawRoundedRect(frameRect.marginsRemoved(QMarginsF(0.5,0.5,0.5,0.5)), secondLevelRoundingRadius, secondLevelRoundingRadius);
+ const auto rect = QRectF(option->rect).marginsRemoved(QMarginsF(0.5, 0.5, 0.5, 0.5));
+ const auto pen = highContrastTheme ? frame->palette.buttonText().color()
+ : winUI3Color(frameColorLight);
+ drawRoundedRect(painter, rect, pen, frame->palette.base());
}
#endif // QT_CONFIG(tabwidget)
break;
@@ -763,40 +755,41 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
}
break;
- case PE_IndicatorCheckBox:
- {
+ case PE_IndicatorCheckBox: {
const bool isRtl = option->direction == Qt::RightToLeft;
- QNumberStyleAnimation* animation = qobject_cast<QNumberStyleAnimation*>(d->animation(option->styleObject));
- QFontMetrics fm(d->assetFont);
+ const bool isOn = option->state & State_On;
+ const bool isPartial = option->state & State_NoChange;
QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0);
- QPointF center = QPointF(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
+ const QPointF center = rect.center();
rect.setWidth(15);
rect.setHeight(15);
rect.moveCenter(center);
- float clipWidth = animation != nullptr ? animation->currentValue() : 1.0f;
- QRectF clipRect = fm.boundingRect(QStringLiteral(u"\uE73E"));
- clipRect.moveCenter(center);
- clipRect.setLeft(rect.x() + (rect.width() - clipRect.width()) / 2.0);
- clipRect.setWidth(clipWidth * clipRect.width());
-
- painter->setPen(Qt::NoPen);
- painter->setBrush(buttonFillBrush(option));
- painter->drawRoundedRect(rect, secondLevelRoundingRadius, secondLevelRoundingRadius, Qt::AbsoluteSize);
-
- painter->setPen(highContrastTheme == true ? option->palette.buttonText().color()
- : WINUI3Colors[colorSchemeIndex][frameColorStrong]);
- painter->setBrush(Qt::NoBrush);
- painter->drawRoundedRect(rect, secondLevelRoundingRadius + 0.5, secondLevelRoundingRadius + 0.5, Qt::AbsoluteSize);
+ QPen borderPen(Qt::NoPen);
+ if (!isOn && !isPartial) {
+ borderPen = highContrastTheme ? option->palette.buttonText().color()
+ : winUI3Color(frameColorStrong);
+ }
+ drawRoundedRect(painter, rect, borderPen, buttonFillBrush(option));
- painter->setFont(d->assetFont);
- painter->setPen(option->palette.highlightedText().color());
- painter->setBrush(option->palette.highlightedText());
- if (option->state & State_On)
+ if (isOn) {
+ painter->setFont(d->assetFont);
+ painter->setPen(option->palette.color(QPalette::Window));
+ QNumberStyleAnimation *animation = qobject_cast<QNumberStyleAnimation *>(
+ d->animation(option->styleObject));
+ QFontMetrics fm(d->assetFont);
+ float clipWidth = animation != nullptr ? animation->currentValue() : 1.0f;
+ QRectF clipRect = fm.boundingRect(QStringLiteral(u"\uE73E"));
+ clipRect.moveCenter(center);
+ clipRect.setLeft(rect.x() + (rect.width() - clipRect.width()) / 2.0);
+ clipRect.setWidth(clipWidth * clipRect.width());
painter->drawText(clipRect, Qt::AlignVCenter | Qt::AlignLeft, QStringLiteral(u"\uE73E"));
- else if (option->state & State_NoChange)
- painter->drawText(rect, Qt::AlignVCenter | Qt::AlignHCenter, QStringLiteral(u"\uE73C"));
+ } else if (isPartial) {
+ painter->setFont(d->assetFont);
+ painter->setPen(option->palette.color(QPalette::Window));
+ painter->drawText(rect, Qt::AlignCenter, QStringLiteral(u"\uE73C"));
+ }
}
break;
case PE_IndicatorBranch: {
@@ -814,9 +807,9 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
}
break;
- case PE_IndicatorRadioButton:
- {
+ case PE_IndicatorRadioButton: {
const bool isRtl = option->direction == Qt::RightToLeft;
+ const bool isOn = option->state & State_On;
qreal innerRadius = option->state & State_On ? 4.0f :7.0f;
if (option->styleObject) {
if (option->styleObject->property("_q_end_radius").isNull())
@@ -826,34 +819,26 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
option->styleObject->setProperty("_q_inner_radius", innerRadius);
}
- QPainterPath path;
QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0);
- QPointF center = QPoint(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
- rect.setWidth(15);
- rect.setHeight(15);
- rect.moveCenter(center);
- QRectF innerRect = rect;
- innerRect.setWidth(8);
- innerRect.setHeight(8);
- innerRect.moveCenter(center);
-
- painter->setPen(Qt::NoPen);
- painter->setBrush(option->palette.accent());
- path.addEllipse(center,7,7);
- path.addEllipse(center,innerRadius,innerRadius);
- painter->drawPath(path);
-
- painter->setPen(WINUI3Colors[colorSchemeIndex][frameColorStrong]);
- painter->setBrush(Qt::NoBrush);
- painter->drawEllipse(center, 7.5, 7.5);
- painter->drawEllipse(center,innerRadius + 0.5, innerRadius + 0.5);
+ const QPointF center = rect.center();
- painter->setPen(Qt::NoPen);
- if (option->state & State_MouseOver && option->state & State_Enabled)
- painter->setBrush(option->palette.window().color().darker(107));
- else
- painter->setBrush(option->palette.window());
- painter->drawEllipse(center,innerRadius, innerRadius);
+ if (isOn) {
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(buttonFillBrush(option));
+ QPainterPath path;
+ path.addEllipse(center, 7.5, 7.5);
+ path.addEllipse(center, innerRadius, innerRadius);
+ painter->drawPath(path);
+ QColor fillColor = option->palette.window().color();
+ if (option->state & State_MouseOver && option->state & State_Enabled)
+ fillColor = fillColor.darker(107);
+ painter->setBrush(fillColor);
+ painter->drawEllipse(center, innerRadius, innerRadius);
+ } else {
+ painter->setPen(winUI3Color(frameColorStrong));
+ painter->setBrush(buttonFillBrush(option));
+ painter->drawEllipse(center, 7.5, 7.5);
+ }
}
break;
case PE_PanelButtonTool:
@@ -910,7 +895,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
case PE_PanelLineEdit:
if (const auto *panel = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- const auto frameRect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1));
+ const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
drawRoundedRect(painter, frameRect, Qt::NoPen, option->palette.brush(QPalette::Base));
if (panel->lineWidth > 0)
@@ -922,12 +907,14 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor));
}
break;
- case PE_FrameLineEdit:
- drawLineEditFrame(painter, option);
+ case PE_FrameLineEdit: {
+ const auto frameRect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
+ drawLineEditFrame(painter, frameRect, option);
break;
+ }
case PE_Frame: {
if (const auto *frame = qstyleoption_cast<const QStyleOptionFrame *>(option)) {
- const auto rect = option->rect.marginsRemoved(QMargins(1, 1, 1, 1));
+ const auto rect = QRectF(option->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
if (qobject_cast<const QComboBoxPrivateContainer *>(widget)) {
QPen pen;
if (highContrastTheme)
@@ -941,7 +928,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
if (frame->frameShape == QFrame::NoFrame)
break;
- drawLineEditFrame(painter, option, qobject_cast<const QTextEdit *>(widget) != nullptr);
+ drawLineEditFrame(painter, rect, option, qobject_cast<const QTextEdit *>(widget) != nullptr);
}
break;
}
@@ -2357,7 +2344,7 @@ QBrush QWindows11Style::buttonFillBrush(const QStyleOption *option)
if (!isOn && option->state & QStyle::State_AutoRaise)
return Qt::NoBrush;
if (option->state & QStyle::State_MouseOver)
- brush.setColor(isOn ? brush.color().lighter(107) : brush.color().darker(107));
+ brush.setColor(isOn ? brush.color().lighter(115) : brush.color().darker(107));
return brush;
}
@@ -2377,9 +2364,8 @@ QColor QWindows11Style::buttonLabelColor(const QStyleOption *option, int colorSc
: option->palette.buttonText().color();
}
-void QWindows11Style::drawLineEditFrame(QPainter *p, const QStyleOption *o, bool isEditable) const
+void QWindows11Style::drawLineEditFrame(QPainter *p, const QRectF &rect, const QStyleOption *o, bool isEditable) const
{
- const auto rect = QRectF(o->rect).marginsRemoved(QMarginsF(1.5, 1.5, 1.5, 1.5));
const bool isHovered = o->state & State_MouseOver;
const auto frameCol = highContrastTheme
? o->palette.color(isHovered ? QPalette::Accent
diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h
index 51514737259..eccedc5bf67 100644
--- a/src/plugins/styles/modernwindows/qwindows11style_p.h
+++ b/src/plugins/styles/modernwindows/qwindows11style_p.h
@@ -75,7 +75,7 @@ protected:
private:
static inline QBrush buttonFillBrush(const QStyleOption *option);
static inline QColor buttonLabelColor(const QStyleOption *option, int colorSchemeIndex);
- void drawLineEditFrame(QPainter *p, const QStyleOption *o, bool isEditable = true) const;
+ void drawLineEditFrame(QPainter *p, const QRectF &rect, const QStyleOption *o, bool isEditable = true) const;
inline QColor winUI3Color(enum WINUI3Color col) const;
private:
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
index 0301b770a1e..52a98b0f9bb 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
@@ -2301,6 +2301,14 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
ret = 1;
break;
+ case SH_ComboBox_ListMouseTracking_Current:
+ ret = 0;
+ break;
+
+ case SH_ComboBox_ListMouseTracking_Active:
+ ret = 1;
+ break;
+
default:
ret = QWindowsStyle::styleHint(hint, option, widget, returnData);
break;
diff --git a/src/widgets/kernel/qtestsupport_widgets.cpp b/src/widgets/kernel/qtestsupport_widgets.cpp
index 5a7200e58aa..ce40ba8c6dd 100644
--- a/src/widgets/kernel/qtestsupport_widgets.cpp
+++ b/src/widgets/kernel/qtestsupport_widgets.cpp
@@ -31,6 +31,17 @@ static bool qWaitForWidgetWindow(QWidget *w, Predicate predicate, QDeadlineTimer
/*!
\since 5.0
+ \overload
+
+ The \a timeout is in milliseconds.
+*/
+bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
+{
+ return qWaitForWindowActive(widget, QDeadlineTimer{timeout, Qt::TimerType::PreciseTimer});
+}
+
+/*!
+ \since 6.10
Returns \c true if \a widget is active within \a timeout milliseconds. Otherwise returns \c false.
@@ -45,7 +56,7 @@ static bool qWaitForWidgetWindow(QWidget *w, Predicate predicate, QDeadlineTimer
\sa qWaitForWindowExposed(), QWidget::isActiveWindow()
*/
-Q_WIDGETS_EXPORT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
+bool QTest::qWaitForWindowActive(QWidget *widget, QDeadlineTimer timeout)
{
if (Q_UNLIKELY(!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation))) {
qWarning() << "qWaitForWindowActive was called on a platform that doesn't support window"
@@ -57,9 +68,19 @@ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
}
return qWaitForWidgetWindow(widget,
[&](QWindow *window) { return window->isActive(); },
- QDeadlineTimer{timeout, Qt::TimerType::PreciseTimer});
+ timeout);
}
+/*!
+ \since 6.10
+ \overload
+
+ This function uses the default timeout of 5 seconds.
+*/
+bool QTest::qWaitForWindowActive(QWidget *widget)
+{
+ return qWaitForWindowActive(widget, Internal::defaultTryTimeout);
+}
/*!
\since 6.7
@@ -86,7 +107,30 @@ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowFocused(QWidget *widget, QDeadlineTim
}
/*!
+ \since 6.10
+ \overload
+
+ This function uses the default timeout of 5 seconds.
+*/
+bool QTest::qWaitForWindowFocused(QWidget *widget)
+{
+ return qWaitForWindowFocused(widget, Internal::defaultTryTimeout);
+}
+
+/*!
\since 5.0
+ \overload
+
+ The \a timeout is in milliseconds.
+*/
+bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
+{
+ return qWaitForWindowExposed(widget, std::chrono::milliseconds(timeout));
+}
+
+
+/*!
+ \since 6.10
Returns \c true if \a widget is exposed within \a timeout milliseconds. Otherwise returns \c false.
@@ -99,11 +143,22 @@ Q_WIDGETS_EXPORT bool QTest::qWaitForWindowFocused(QWidget *widget, QDeadlineTim
\sa qWaitForWindowActive(), QWidget::isVisible(), QWindow::isExposed()
*/
-Q_WIDGETS_EXPORT bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
+bool QTest::qWaitForWindowExposed(QWidget *widget, QDeadlineTimer timeout)
{
return qWaitForWidgetWindow(widget,
[&](QWindow *window) { return window->isExposed(); },
- QDeadlineTimer{timeout, Qt::TimerType::PreciseTimer});
+ timeout);
+}
+
+/*!
+ \since 6.10
+ \overload
+
+ This function uses the default timeout of 5 seconds.
+*/
+bool QTest::qWaitForWindowExposed(QWidget *widget)
+{
+ return qWaitForWindowExposed(widget, Internal::defaultTryTimeout);
}
namespace QTest {
diff --git a/src/widgets/kernel/qtestsupport_widgets.h b/src/widgets/kernel/qtestsupport_widgets.h
index b49e68db651..4b5e5ff7772 100644
--- a/src/widgets/kernel/qtestsupport_widgets.h
+++ b/src/widgets/kernel/qtestsupport_widgets.h
@@ -14,9 +14,16 @@ class QWidget;
namespace QTest {
-[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowActive(QWidget *widget, int timeout = 5000);
-[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowFocused(QWidget *widget, QDeadlineTimer timeout = std::chrono::seconds{5});
-[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowExposed(QWidget *widget, int timeout = 5000);
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowActive(QWidget *widget, int timeout);
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowActive(QWidget *widget, QDeadlineTimer timeout);
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowActive(QWidget *widget);
+
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowFocused(QWidget *widget, QDeadlineTimer timeout);
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowFocused(QWidget *widget);
+
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowExposed(QWidget *widget, int timeout);
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowExposed(QWidget *widget, QDeadlineTimer timeout);
+[[nodiscard]] Q_WIDGETS_EXPORT bool qWaitForWindowExposed(QWidget *widget);
class Q_WIDGETS_EXPORT QTouchEventWidgetSequence : public QTouchEventSequence
{
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 4cf2934a2dc..b85446121bd 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -622,7 +622,21 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
}
}
QApplicationPrivate::replayMousePress = false;
+#ifndef QT_NO_CONTEXTMENU
+ } else if (event->type() == QGuiApplicationPrivate::contextMenuEventType()
+ && event->button() == Qt::RightButton) {
+ QWidget *receiver = activePopupWidget;
+ if (qt_button_down)
+ receiver = qt_button_down;
+ else if (popupChild)
+ receiver = popupChild;
+ const QPoint localPos = receiver->mapFromGlobal(event->globalPosition().toPoint());
+ QContextMenuEvent e(QContextMenuEvent::Mouse, localPos, event->globalPosition().toPoint(), event->modifiers());
+ QApplication::forwardEvent(receiver, &e, event);
+ }
+#else
}
+#endif
if (releaseAfter) {
qt_button_down = nullptr;
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index b5972411534..60ec043d094 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -5434,7 +5434,8 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
case SH_Menu_AllowActiveAndDisabled:
case SH_Menu_SpaceActivatesItem:
case SH_ScrollView_FrameOnlyAroundContents:
- case SH_ComboBox_ListMouseTracking:
+ case SH_ComboBox_ListMouseTracking_Current:
+ case SH_ComboBox_ListMouseTracking_Active:
case SH_Menu_MouseTracking:
case SH_MenuBar_MouseTracking:
case SH_ItemView_ChangeHighlightOnFocus:
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 6bb0728cfd4..e72e645e69c 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1736,8 +1736,16 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
by pressing Alt, followed by using the arrow keys to select
the desired item.
- \value SH_ComboBox_ListMouseTracking Mouse tracking in combobox
- drop-down lists.
+ \value SH_ComboBox_ListMouseTracking_Current Mouse tracking in
+ combobox drop-down lists, the item under the cursor is made
+ the current item (QStyle::State_Selected).
+
+ \value SH_ComboBox_ListMouseTracking same as
+ SH_ComboBox_ListMouseTracking_Current
+
+ \value SH_ComboBox_ListMouseTracking_Active Mouse tracking in
+ combobox drop-down lists, the item under the cursor is not
+ made the current item, only active (QStyle::State_MouseOver).
\value SH_Menu_MouseTracking Mouse tracking in popup menus.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index db09eedc70d..d6bccf9f698 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -602,6 +602,7 @@ public:
SH_ScrollView_FrameOnlyAroundContents,
SH_MenuBar_AltKeyNavigation,
SH_ComboBox_ListMouseTracking,
+ SH_ComboBox_ListMouseTracking_Current = SH_ComboBox_ListMouseTracking,
SH_Menu_MouseTracking,
SH_MenuBar_MouseTracking,
SH_ItemView_ChangeHighlightOnFocus,
@@ -704,6 +705,7 @@ public:
SH_TabBar_AllowWheelScrolling,
SH_Table_AlwaysDrawLeftTopGridLines,
SH_SpinBox_SelectOnStep,
+ SH_ComboBox_ListMouseTracking_Active,
// Add new style hint values here
SH_CustomBase = 0xf0000000
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 907628f224e..d6daa681798 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -461,7 +461,7 @@ int QWindowsStyle::styleHint(StyleHint hint, const QStyleOption *opt, const QWid
case SH_MenuBar_AltKeyNavigation:
case SH_MenuBar_MouseTracking:
case SH_Menu_MouseTracking:
- case SH_ComboBox_ListMouseTracking:
+ case SH_ComboBox_ListMouseTracking_Current:
case SH_Slider_StopMouseOverSlider:
case SH_MainWindow_SpaceBelowMenuBar:
ret = 1;
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index fbec606ae4a..aa58ac8d75d 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -640,8 +640,10 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView)
if (usePopup)
view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
#endif
- if (combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking, &opt, combo) ||
- usePopup) {
+ if (usePopup ||
+ combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking_Current, &opt, combo) ||
+ combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking_Active, &opt, combo)
+ ) {
view->setMouseTracking(true);
}
view->setSelectionMode(QAbstractItemView::SingleSelection);
@@ -775,10 +777,12 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e)
QPoint vector = widget->mapToGlobal(m->position().toPoint()) - initialClickPosition;
if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive())
blockMouseReleaseTimer.stop();
- QModelIndex indexUnderMouse = view->indexAt(m->position().toPoint());
- if (indexUnderMouse.isValid()
- && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
- view->setCurrentIndex(indexUnderMouse);
+ if (combo->style()->styleHint(QStyle::SH_ComboBox_ListMouseTracking_Current, nullptr, combo)) {
+ QModelIndex indexUnderMouse = view->indexAt(m->position().toPoint());
+ if (indexUnderMouse.isValid()
+ && !QComboBoxDelegate::isSeparator(indexUnderMouse)) {
+ view->setCurrentIndex(indexUnderMouse);
+ }
}
}
break;