summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtInternalTargets.cmake9
-rw-r--r--cmake/QtPublicSbomQtEntityHelpers.cmake5
-rw-r--r--doc/global/disabledwarnings.qdocconf1
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java11
-rw-r--r--src/corelib/global/qcompilerdetection.qdoc12
-rw-r--r--src/corelib/global/qrandom.cpp4
-rw-r--r--src/corelib/kernel/qvariant.h2
-rw-r--r--src/corelib/tools/qmultimap.qdoc2
-rw-r--r--src/gui/image/qicon.h2
-rw-r--r--src/gui/image/qicon_p.h5
-rw-r--r--src/gui/kernel/qevent.cpp5
-rw-r--r--src/gui/painting/qcoregraphics.mm34
-rw-r--r--src/gui/painting/qcoregraphics_p.h3
-rw-r--r--src/gui/painting/qdrawhelper_avx2.cpp4
-rw-r--r--src/gui/platform/darwin/qappleiconengine.mm16
-rw-r--r--src/gui/platform/darwin/qappleiconengine_p.h5
-rw-r--r--src/gui/rhi/qrhivulkan.cpp4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm20
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm25
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp11
-rw-r--r--src/plugins/platforms/ios/qiosdocumentpickercontroller.mm15
-rw-r--r--src/plugins/platforms/wasm/qwasmaccessibility.cpp54
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp20
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp12
-rw-r--r--tests/auto/widgets/kernel/qapplication/CMakeLists.txt7
27 files changed, 253 insertions, 57 deletions
diff --git a/cmake/QtInternalTargets.cmake b/cmake/QtInternalTargets.cmake
index 0ef27717502..2985d2edce9 100644
--- a/cmake/QtInternalTargets.cmake
+++ b/cmake/QtInternalTargets.cmake
@@ -46,17 +46,8 @@ function(qt_internal_set_warnings_are_errors_flags target target_scope)
# error: assuming signed overflow does not occur when assuming that (X + c) < X
# is always false
-Wno-error=strict-overflow
- CONDITIONS VERSION_GREATER_EQUAL 7
- OPTIONS
- # GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of
- # implicit fallthroughs.
- -Wno-error=implicit-fallthrough
CONDITIONS VERSION_GREATER_EQUAL 9
OPTIONS
- # GCC 9 introduced these but we are not clean for it.
- -Wno-error=deprecated-copy
- -Wno-error=redundant-move
- -Wno-error=init-list-lifetime
# GCC 9 introduced -Wformat-overflow in -Wall, but it is buggy:
-Wno-error=format-overflow
CONDITIONS VERSION_GREATER_EQUAL 10
diff --git a/cmake/QtPublicSbomQtEntityHelpers.cmake b/cmake/QtPublicSbomQtEntityHelpers.cmake
index d8d61eef42c..1ccc64421b1 100644
--- a/cmake/QtPublicSbomQtEntityHelpers.cmake
+++ b/cmake/QtPublicSbomQtEntityHelpers.cmake
@@ -234,9 +234,8 @@ function(_qt_internal_sbom_handle_qt_entity_cpe target)
set(cpe_list "")
- # Add the qt-specific CPE if the target is a Qt entity type, or if it's a 3rd party entity type
- # without any CPE specified.
- if(is_qt_entity_type OR (is_qt_3rd_party_entity_type AND NOT arg_CPE))
+ # Add the qt-specific CPE if the target is a Qt entity type
+ if(is_qt_entity_type)
_qt_internal_sbom_compute_security_cpe_for_qt(cpe_list)
endif()
diff --git a/doc/global/disabledwarnings.qdocconf b/doc/global/disabledwarnings.qdocconf
index c0070fca610..6da39a84e9b 100644
--- a/doc/global/disabledwarnings.qdocconf
+++ b/doc/global/disabledwarnings.qdocconf
@@ -1,4 +1,5 @@
spurious = \
+ "Undocumented property \*" \
"Missing comma in .*" \
"Missing pattern .*" \
"Unable to parse (QML|JavaScript).*" \
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java
index 1d4ec370d39..93407d52e95 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java
@@ -241,12 +241,15 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate
return;
}
- final AccessibilityEvent event =
- obtainAccessibilityEvent(AccessibilityEvent.TYPE_ANNOUNCEMENT);
+ final CharSequence className = getNodeForVirtualViewId(viewId).getClassName();
+ final int eventType =
+ className != null && className.equals("android.widget.ProgressBar")
+ ? AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
+ : AccessibilityEvent.TYPE_ANNOUNCEMENT;
+ final AccessibilityEvent event = obtainAccessibilityEvent(eventType);
event.setEnabled(true);
- event.setClassName(getNodeForVirtualViewId(viewId).getClassName());
-
+ event.setClassName(className);
event.setContentDescription(value);
if (event.getText().isEmpty() && TextUtils.isEmpty(event.getContentDescription())) {
diff --git a/src/corelib/global/qcompilerdetection.qdoc b/src/corelib/global/qcompilerdetection.qdoc
index 9b49a1491ab..e64dca74667 100644
--- a/src/corelib/global/qcompilerdetection.qdoc
+++ b/src/corelib/global/qcompilerdetection.qdoc
@@ -277,6 +277,18 @@
\row \li \c{constexpr} \li C++11 \li yes \li required
\row \li \c{constinit} \li C++20 \li no \li required
\endtable
+
+ If declaration and definition of a Q_CONSTINIT variable are separate, this
+ macro goes only on the definition, and not on the declaration:
+
+ \code
+ class C {
+ ~~~~
+ static int count; // declaration, no Q_CONSTINIT here
+ };
+ ~~~
+ Q_CONSTINIT int C::count = 0; // definition
+ \endcode
*/
/*!
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index dc7d90f4b30..8d545242095 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -699,7 +699,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
Returns the minimum value that QRandomGenerator may ever generate. That is, 0.
- \sa max(), QRandomGenerator64::min()
+ \sa max()
*/
/*!
@@ -708,7 +708,7 @@ inline QRandomGenerator::SystemGenerator &QRandomGenerator::SystemGenerator::sel
Returns the maximum value that QRandomGenerator may ever generate. That is,
\c {std::numeric_limits<result_type>::max()}.
- \sa min(), QRandomGenerator64::max()
+ \sa min()
*/
/*!
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 9b219d089b5..9117c827afe 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -377,7 +377,7 @@ public:
>::value)
: QVariant(std::in_place, QMetaType::fromType<q20::remove_cvref_t<T>>())
{
- char *data = static_cast<char *>(const_cast<void *>(constData()));
+ void *data = const_cast<void *>(constData());
new (data) T(il, std::forward<Args>(args)...);
}
diff --git a/src/corelib/tools/qmultimap.qdoc b/src/corelib/tools/qmultimap.qdoc
index fdf65f28876..dc705fdb2eb 100644
--- a/src/corelib/tools/qmultimap.qdoc
+++ b/src/corelib/tools/qmultimap.qdoc
@@ -457,7 +457,7 @@
Returns the number of items associated with key \a key.
- \sa contains(), QMultiMap::count()
+ \sa contains(), QMultiMap::count(const Key &key, const T &value)
*/
/*! \fn template <class Key, class T> qsizetype QMultiMap<Key, T>::count(const Key &key, const T &value) const
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 1e16f42626b..f4b50b07d8a 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -265,6 +265,8 @@ private:
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QIcon &);
#endif
+ friend class QIconPrivate;
+
public:
typedef QIconPrivate * DataPtr;
inline DataPtr &data_ptr() { return d; }
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
index 60985d538dc..29d88f8f222 100644
--- a/src/gui/image/qicon_p.h
+++ b/src/gui/image/qicon_p.h
@@ -34,6 +34,11 @@ public:
delete engine;
}
+ static QIconPrivate *get(QIcon *icon) { return icon->d; }
+ static const QIconPrivate *get(const QIcon *icon) { return icon->d; }
+
+ enum IconEngineHook { PlatformIconHook = 1000 };
+
static qreal pixmapDevicePixelRatio(qreal displayDevicePixelRatio, const QSize &requestedSize, const QSize &actualSize);
QIconEngine *engine;
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 7b1e76cc78f..a95f94dea7e 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -4211,7 +4211,8 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
const Qt::MouseButtons buttons = spe->buttons();
dbg << eventClassName(type) << '(';
QtDebugUtils::formatQEnum(dbg, type);
- dbg << " ts=" << spe->timestamp();
+ if (dbg.verbosity() > QDebug::DefaultVerbosity)
+ dbg << " ts=" << spe->timestamp();
if (isMouse) {
if (type != QEvent::MouseMove && type != QEvent::NonClientAreaMouseMove) {
dbg << ' ';
@@ -4338,6 +4339,8 @@ QDebug operator<<(QDebug dbg, const QEvent *e)
const QNativeGestureEvent *ne = static_cast<const QNativeGestureEvent *>(e);
dbg << "QNativeGestureEvent(";
QtDebugUtils::formatQEnum(dbg, ne->gestureType());
+ if (dbg.verbosity() > QDebug::DefaultVerbosity)
+ dbg << ", ts=" << ne->timestamp();
dbg << ", fingerCount=" << ne->fingerCount() << ", localPos=";
QtDebugUtils::formatQPoint(dbg, ne->position());
if (!qIsNull(ne->value()))
diff --git a/src/gui/painting/qcoregraphics.mm b/src/gui/painting/qcoregraphics.mm
index dfdfa8f84e7..819f3c8e5d2 100644
--- a/src/gui/painting/qcoregraphics.mm
+++ b/src/gui/painting/qcoregraphics.mm
@@ -11,6 +11,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/qcolorspace.h>
+#include <QtGui/private/qicon_p.h>
#if defined(Q_OS_MACOS)
# include <AppKit/AppKit.h>
@@ -303,6 +304,26 @@ QImage qt_mac_toQImage(CGImageRef cgImage)
return image;
}
+QImage qt_mac_padToSquareImage(const QImage &image)
+{
+ if (image.width() == image.height())
+ return image;
+
+ const int size = std::max(image.width(), image.height());
+ QImage squareImage(size, size, image.format());
+ squareImage.setDevicePixelRatio(image.devicePixelRatio());
+ squareImage.fill(Qt::transparent);
+
+ QPoint pos((size - image.width()) / (2.0 * image.devicePixelRatio()),
+ (size - image.height()) / (2.0 * image.devicePixelRatio()));
+
+ QPainter painter(&squareImage);
+ painter.drawImage(pos, image);
+ painter.end();
+
+ return squareImage;
+}
+
#ifdef Q_OS_MACOS
QT_END_NAMESPACE
@@ -383,6 +404,19 @@ QT_END_NAMESPACE
return nsImage;
}
+
++ (instancetype)internalImageFromQIcon:(const QT_PREPEND_NAMESPACE(QIcon) &)icon
+{
+ if (icon.isNull())
+ return nil;
+
+ // Check if the icon is backed by an NSImage. If so, we can use that directly.
+ auto *iconPrivate = QIconPrivate::get(&icon);
+ NSImage *iconImage = nullptr;
+ iconPrivate->engine->virtual_hook(QIconPrivate::PlatformIconHook, &iconImage);
+ return iconImage;
+}
+
@end
QT_BEGIN_NAMESPACE
diff --git a/src/gui/painting/qcoregraphics_p.h b/src/gui/painting/qcoregraphics_p.h
index 7bec19ffb98..9d176516d56 100644
--- a/src/gui/painting/qcoregraphics_p.h
+++ b/src/gui/painting/qcoregraphics_p.h
@@ -66,6 +66,7 @@ QT_END_NAMESPACE
withSize:(const QT_PREPEND_NAMESPACE(QSize) &)size
withMode:(QT_PREPEND_NAMESPACE(QIcon)::Mode)mode
withState:(QT_PREPEND_NAMESPACE(QIcon)::State)state;
++ (instancetype)internalImageFromQIcon:(const QT_PREPEND_NAMESPACE(QIcon) &)icon;
@end
QT_BEGIN_NAMESPACE
#endif // __OBJC__
@@ -74,6 +75,8 @@ QT_BEGIN_NAMESPACE
Q_GUI_EXPORT CGImageRef qt_mac_toCGImage(const QImage &qImage);
Q_GUI_EXPORT QImage qt_mac_toQImage(CGImageRef image);
+Q_GUI_EXPORT QImage qt_mac_padToSquareImage(const QImage &image);
+
Q_GUI_EXPORT void qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage);
Q_GUI_EXPORT void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform);
diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp
index d7496845197..a736b75dab2 100644
--- a/src/gui/painting/qdrawhelper_avx2.cpp
+++ b/src/gui/painting/qdrawhelper_avx2.cpp
@@ -38,6 +38,7 @@ BYTE_MUL_AVX2(__m256i &pixelVector, __m256i alphaChannel, __m256i colorMask, __m
pixelVector = _mm256_blendv_epi8(pixelVectorAG, pixelVectorRB, colorMask);
}
+#if QT_CONFIG(raster_64bit)
inline static void Q_DECL_VECTORCALL
BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, __m256i alphaChannel, __m256i colorMask, __m256i half)
{
@@ -55,6 +56,7 @@ BYTE_MUL_RGB64_AVX2(__m256i &pixelVector, __m256i alphaChannel, __m256i colorMas
pixelVectorRB = _mm256_srli_epi32(pixelVectorRB, 16);
pixelVector = _mm256_blendv_epi8(pixelVectorAG, pixelVectorRB, colorMask);
}
+#endif
// See INTERPOLATE_PIXEL_255_SSE2 for details.
inline static void Q_DECL_VECTORCALL
@@ -79,6 +81,7 @@ INTERPOLATE_PIXEL_255_AVX2(__m256i srcVector, __m256i &dstVector, __m256i alphaC
dstVector = _mm256_blendv_epi8(finalAG, finalRB, colorMask);
}
+#if QT_CONFIG(raster_64bit)
inline static void Q_DECL_VECTORCALL
INTERPOLATE_PIXEL_RGB64_AVX2(__m256i srcVector, __m256i &dstVector, __m256i alphaChannel, __m256i oneMinusAlphaChannel, __m256i colorMask, __m256i half)
{
@@ -99,6 +102,7 @@ INTERPOLATE_PIXEL_RGB64_AVX2(__m256i srcVector, __m256i &dstVector, __m256i alph
finalRB = _mm256_srli_epi32(finalRB, 16);
dstVector = _mm256_blendv_epi8(finalAG, finalRB, colorMask);
}
+#endif
// See BLEND_SOURCE_OVER_ARGB32_SSE2 for details.
inline static void Q_DECL_VECTORCALL BLEND_SOURCE_OVER_ARGB32_AVX2(quint32 *dst, const quint32 *src, const int length)
diff --git a/src/gui/platform/darwin/qappleiconengine.mm b/src/gui/platform/darwin/qappleiconengine.mm
index 3228b97fdb0..925135e9621 100644
--- a/src/gui/platform/darwin/qappleiconengine.mm
+++ b/src/gui/platform/darwin/qappleiconengine.mm
@@ -15,6 +15,7 @@
#include <QtGui/qstylehints.h>
#include <QtGui/private/qcoregraphics_p.h>
+#include <QtGui/private/qicon_p.h>
QT_BEGIN_NAMESPACE
@@ -302,6 +303,11 @@ QAppleIconEngine::~QAppleIconEngine()
[m_image release];
}
+QIcon QAppleIconEngine::fromTheme(const QString &iconName)
+{
+ return QIcon(new QAppleIconEngine(iconName));
+}
+
QIconEngine *QAppleIconEngine::clone() const
{
return new QAppleIconEngine(m_iconName);
@@ -476,4 +482,14 @@ void QAppleIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode m
#endif
}
+void QAppleIconEngine::virtual_hook(int hookIdentifier, void *data)
+{
+ // Expose underlying NSImage so we can pass it on to AppKit
+ // directly without flattening, preserving the symbol image.
+ if (hookIdentifier == QIconPrivate::PlatformIconHook)
+ *static_cast<decltype(m_image)*>(data) = m_image;
+ else
+ QIconEngine::virtual_hook(hookIdentifier, data);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/platform/darwin/qappleiconengine_p.h b/src/gui/platform/darwin/qappleiconengine_p.h
index 7d20896517b..b71386ca63a 100644
--- a/src/gui/platform/darwin/qappleiconengine_p.h
+++ b/src/gui/platform/darwin/qappleiconengine_p.h
@@ -31,6 +31,9 @@ class Q_GUI_EXPORT QAppleIconEngine : public QIconEngine
public:
QAppleIconEngine(const QString &iconName);
~QAppleIconEngine();
+
+ static QIcon fromTheme(const QString &iconName);
+
QIconEngine *clone() const override;
QString key() const override;
QString iconName() override;
@@ -44,6 +47,8 @@ public:
static QList<QSize> availableIconSizes(double aspectRatio = 1.0);
+ void virtual_hook(int hookIdentifier, void *data) override;
+
private:
const QString m_iconName;
#if defined(Q_OS_MACOS)
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 481ffd57b5d..a511eb854cb 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -406,7 +406,9 @@ static inline VmaAllocator toVmaAllocator(QVkAllocator a)
QByteArrayList QRhiVulkanInitParams::preferredInstanceExtensions()
{
return {
- QByteArrayLiteral("VK_KHR_get_physical_device_properties2")
+ QByteArrayLiteral("VK_KHR_get_physical_device_properties2"),
+ // to silence validation when e.g. on Wayland a surface format's colorspace is VK_COLOR_SPACE_PASS_THROUGH_EXT
+ QByteArrayLiteral("VK_EXT_swapchain_colorspace")
};
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 13f1a19a360..705429e5ccf 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -441,10 +441,22 @@ QPlatformKeyMapper *QCocoaIntegration::keyMapper() const
void QCocoaIntegration::setApplicationIcon(const QIcon &icon) const
{
- // Fall back to a size that looks good on the highest resolution screen available
+ if (icon.isNull()) {
+ NSApp.applicationIconImage = nil;
+ return;
+ }
+
+ // Request a size that looks good on the highest resolution screen available
// for icon engines that don't have an intrinsic size (like SVG).
- auto fallbackSize = QSizeF::fromCGSize(NSApp.dockTile.size) * qGuiApp->devicePixelRatio();
- NSApp.applicationIconImage = [NSImage imageFromQIcon:icon withSize:fallbackSize.toSize()];
+ const auto dockTitleSize = QSizeF::fromCGSize(NSApp.dockTile.size).toSize();
+ auto image = icon.pixmap(dockTitleSize, qGuiApp->devicePixelRatio()).toImage();
+
+ // The assigned image is scaled by the system to fit into the tile,
+ // but without taking aspect ratio into account, so let's pad the
+ // image up front if it's not already square.
+ image = qt_mac_padToSquareImage(image);
+
+ NSApp.applicationIconImage = [NSImage imageFromQImage:image];
}
void QCocoaIntegration::setApplicationBadge(qint64 number)
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index ca43ab421e0..a9a79665f7d 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -373,11 +373,21 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native.keyEquivalentModifierMask = NSEventModifierFlagCommand;
}
- const QIcon::Mode mode = m_enabled ? QIcon::Normal : QIcon::Disabled;
- const QIcon::State state = m_checked ? QIcon::On : QIcon::Off;
- m_native.image = [NSImage imageFromQIcon:m_icon withSize:QSize(m_iconSize, m_iconSize)
- withMode:mode
- withState:state];
+ if (auto *image = [NSImage internalImageFromQIcon:m_icon]) {
+ // The icon is backed by QAppleIconEngine, in which case we
+ // want to pass on the underlying NSImage instead of flattening
+ // to a QImage, as AppKit takes care of requesting a symbol
+ // configuration that matches the size and look of the menu,
+ // which we can't replicate otherwise. Note that this ignores
+ // any possible explicitly set icon size of the menu item.
+ m_native.image = [[image copy] autorelease];
+ } else {
+ const QIcon::Mode mode = m_enabled ? QIcon::Normal : QIcon::Disabled;
+ const QIcon::State state = m_checked ? QIcon::On : QIcon::Off;
+ m_native.image = [NSImage imageFromQIcon:m_icon withSize:QSize(m_iconSize, m_iconSize)
+ withMode:mode
+ withState:state];
+ }
m_native.state = m_checked ? NSControlStateValueOn : NSControlStateValueOff;
return m_native;
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index 1505357ee40..d5c5ed8c2e2 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -85,6 +85,19 @@ void QCocoaSystemTrayIcon::updateIcon(const QIcon &icon)
if (!m_statusItem)
return;
+ if (auto *image = [NSImage internalImageFromQIcon:icon]) {
+ // The icon is backed by QAppleIconEngine, in which case we
+ // want to pass on the underlying NSImage instead of flattening
+ // to a QImage. This preserves the isTemplate property of the
+ // image, and allows AppKit to size and configure the icon for
+ // the status bar. We also enable NSVariableStatusItemLength,
+ // to match the behavior of SwiftUI's MenuBarExtra.
+ m_statusItem.button.image = [[image copy] autorelease];
+ m_statusItem.button.imageScaling = NSImageScaleProportionallyDown;
+ m_statusItem.length = NSVariableStatusItemLength;
+ return;
+ }
+
// The recommended maximum title bar icon height is 18 points
// (device independent pixels). The menu height on past and
// current OS X versions is 22 points. Provide some future-proofing
@@ -206,7 +219,17 @@ void QCocoaSystemTrayIcon::showMessage(const QString &title, const QString &mess
auto *notification = [[NSUserNotification alloc] init];
notification.title = title.toNSString();
notification.informativeText = message.toNSString();
- notification.contentImage = [NSImage imageFromQIcon:icon];
+
+ // Request a size that looks good on the highest resolution screen available
+ // for icon engines that don't have an intrinsic size (like SVG).
+ auto image = icon.pixmap(QSize(64, 64), qGuiApp->devicePixelRatio()).toImage();
+
+ // The assigned image is scaled by the system to fit into the tile,
+ // but without taking aspect ratio into account, so let's pad the
+ // image up front if it's not already square.
+ image = qt_mac_padToSquareImage(image);
+
+ notification.contentImage = [NSImage imageFromQImage:image];
NSUserNotificationCenter *center = NSUserNotificationCenter.defaultUserNotificationCenter;
center.delegate = m_delegate;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index f9094a8f665..52f449db08b 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -400,9 +400,9 @@ QPixmap QCocoaTheme::standardPixmap(StandardPixmap sp, const QSizeF &size) const
iconType = kGenericDocumentIcon;
break;
case ToolBarHorizontalExtensionButton:
- return QIcon::fromTheme("chevron.forward.2").pixmap(size.toSize());
+ return QAppleIconEngine::fromTheme("chevron.forward.2").pixmap(size.toSize());
case ToolBarVerticalExtensionButton:
- return QIcon::fromTheme("chevron.down.2").pixmap(size.toSize());
+ return QAppleIconEngine::fromTheme("chevron.down.2").pixmap(size.toSize());
default:
break;
}
diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
index 56fda45e905..ad5c498032c 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
@@ -28,6 +28,10 @@
#include <sys/ioctl.h>
#endif
+#if defined(Q_OS_VXWORKS)
+#include <fbdev.h>
+#endif
+
#include <private/qfactoryloader_p.h>
#include <private/qcore_unix_p.h>
@@ -270,6 +274,13 @@ void QEglFSDeviceIntegration::waitForVSync(QPlatformSurface *surface) const
if (ioctl(framebuffer, FBIO_WAITFORVSYNC, &arg) == -1)
qWarning("Could not wait for vsync.");
}
+#elif defined(Q_OS_VXWORKS) && defined(FB_IOCTL_VSYNC)
+ static const bool forceSync = qEnvironmentVariableIntValue("QT_QPA_EGLFS_FORCEVSYNC");
+ if (forceSync && framebuffer != -1) {
+ int arg = 0;
+ if (ioctl(framebuffer, FB_IOCTL_VSYNC, &arg) == -1)
+ qWarning("Could not wait for vsync.");
+ }
#endif
}
diff --git a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
index 6ca6554f673..c173aa426fc 100644
--- a/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
+++ b/src/plugins/platforms/ios/qiosdocumentpickercontroller.mm
@@ -28,6 +28,19 @@
docTypes = [self computeAllowedFileTypes:results];
}
+ // FIXME: Handle security scoped URLs instead of copying resource
+ bool asCopy = [&]{
+ switch (fileDialog->options()->fileMode()) {
+ case QFileDialogOptions::AnyFile:
+ case QFileDialogOptions::ExistingFile:
+ case QFileDialogOptions::ExistingFiles:
+ return true;
+ default:
+ // Folders can't be imported
+ return false;
+ }
+ }();
+
if (!docTypes.count) {
switch (fileDialog->options()->fileMode()) {
case QFileDialogOptions::AnyFile:
@@ -45,7 +58,7 @@
}
}
- if (self = [super initForOpeningContentTypes:docTypes]) {
+ if (self = [super initForOpeningContentTypes:docTypes asCopy:asCopy]) {
m_fileDialog = fileDialog;
self.modalPresentationStyle = UIModalPresentationFormSheet;
self.delegate = self;
diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.cpp b/src/plugins/platforms/wasm/qwasmaccessibility.cpp
index d25474c9b3a..56a7c466dcd 100644
--- a/src/plugins/platforms/wasm/qwasmaccessibility.cpp
+++ b/src/plugins/platforms/wasm/qwasmaccessibility.cpp
@@ -377,15 +377,23 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
addEventListener(iface, element, "click");
} break;
+ case QAccessible::Grouping:
case QAccessible::CheckBox: {
- // QGroupBox uses both CheckBox, and a group with subwidgets
- element = document.call<emscripten::val>("createElement", std::string("input"));
- setAttribute(element, "type", "checkbox");
- setAttribute(element, "checked", iface->state().checked);
- setProperty(element, "indeterminate", iface->state().checkStateMixed);
- addEventListener(iface, element, "change");
- if (iface->childCount() > 0) {
- auto checkbox = element;
+ // Three cases:
+ // 1) role=CheckBox, childCount() == 0 -> Checkbox
+ // 2) role=CheckBox, childCount() > 0 -> GroupBox w/checkbox
+ // 3) role=Grouping -> GroupBox w/label
+
+ emscripten::val checkbox = emscripten::val::undefined();
+ if (iface->role() == QAccessible::CheckBox) {
+ checkbox = document.call<emscripten::val>("createElement", std::string("input"));
+ setAttribute(checkbox, "type", "checkbox");
+ setAttribute(checkbox, "checked", iface->state().checked);
+ setProperty(checkbox, "indeterminate", iface->state().checkStateMixed);
+ addEventListener(iface, checkbox, "change");
+ }
+
+ if (iface->childCount() > 0 || iface->role() == QAccessible::Grouping) {
auto label = document.call<emscripten::val>("createElement", std::string("span"));
const std::string id = QString::asprintf("lbid%p", iface).toStdString();
@@ -393,11 +401,16 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
element = document.call<emscripten::val>("createElement", std::string("div"));
element.call<void>("appendChild", label);
- element.call<void>("appendChild", checkbox);
setAttribute(element, "role", "group");
setAttribute(element, "aria-labelledby", id);
- addEventListener(iface, checkbox, "focus");
+
+ if (!checkbox.isUndefined()) {
+ element.call<void>("appendChild", checkbox);
+ addEventListener(iface, checkbox, "focus");
+ }
+ } else {
+ element = checkbox;
}
} break;
@@ -800,19 +813,25 @@ void QWasmAccessibility::handleCheckBoxUpdate(QAccessibleEvent *event)
void QWasmAccessibility::handleGroupBoxUpdate(QAccessibleEvent *event)
{
QAccessibleInterface *iface = event->accessibleInterface();
- const emscripten::val parent = getHtmlElement(iface);
- const emscripten::val label = parent["children"][0];
- const emscripten::val checkbox = parent["children"][1];
+
+ emscripten::val parent = getHtmlElement(iface);
+ emscripten::val label = parent["children"][0];
+ emscripten::val checkbox = emscripten::val::undefined();
+ if (iface->role() == QAccessible::CheckBox)
+ checkbox = parent["children"][1];
switch (event->type()) {
case QAccessible::Focus:
case QAccessible::NameChanged: {
setProperty(label, "innerText", iface->text(QAccessible::Name).toStdString());
- setAttribute(checkbox, "aria-label", iface->text(QAccessible::Name).toStdString());
+ if (!checkbox.isUndefined())
+ setAttribute(checkbox, "aria-label", iface->text(QAccessible::Name).toStdString());
} break;
case QAccessible::StateChanged: {
- setAttribute(checkbox, "checked", iface->state().checked);
- setProperty(checkbox, "indeterminate", iface->state().checkStateMixed);
+ if (!checkbox.isUndefined()) {
+ setAttribute(checkbox, "checked", iface->state().checked);
+ setProperty(checkbox, "indeterminate", iface->state().checkStateMixed);
+ }
} break;
default:
qCDebug(lcQpaAccessibility) << "TODO: implement handleCheckBoxUpdate for event" << event->type();
@@ -1309,6 +1328,9 @@ void QWasmAccessibility::handleUpdateByInterfaceRole(QAccessibleEvent *event)
case QAccessible::ScrollBar:
handleScrollBarUpdate(event);
break;
+ case QAccessible::Grouping:
+ handleGroupBoxUpdate(event);
+ break;
default:
qCDebug(lcQpaAccessibility) << "TODO: implement notifyAccessibilityUpdate for role" << iface->role();
};
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index c8cd7c26f61..f47682ced67 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -993,7 +993,8 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
const bool isMouseOver = state & State_MouseOver;
const bool hasFocus = state & State_HasFocus;
- if (isMouseOver && !hasFocus && !highContrastTheme)
+ const bool isEnabled = state & State_Enabled;
+ if (isMouseOver && isEnabled && hasFocus && !highContrastTheme)
drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor));
}
break;
@@ -1399,6 +1400,13 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
const qreal offset = (int(rect.height()) % 2 == 0) ? 0.5f : 0.0f;
if (isIndeterminate) {
+#if QT_CONFIG(animation)
+ auto anim = d->animation(option->styleObject);
+ if (!anim) {
+ auto anim = new QStyleAnimation(option->styleObject);
+ anim->setFrameRate(QStyleAnimation::SixtyFps);
+ d->startAnimation(anim);
+ }
constexpr auto loopDurationMSec = 4000;
const auto elapsedTime = std::chrono::time_point_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now());
@@ -1406,14 +1414,20 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
const auto handleCenter = (elapsed % loopDurationMSec) / float(loopDurationMSec);
const auto isLongHandle = (elapsed / loopDurationMSec) % 2 == 0;
const auto lengthFactor = (isLongHandle ? 33.0f : 25.0f) / 100.0f;
+#else
+ constexpr auto handleCenter = 0.5f;
+ constexpr auto lengthFactor = 1;
+#endif
const auto begin = qMax(handleCenter * (1 + lengthFactor) - lengthFactor, 0.0f);
const auto end = qMin(handleCenter * (1 + lengthFactor), 1.0f);
const auto barBegin = begin * rect.width();
const auto barEnd = end * rect.width();
rect = QRectF(QPointF(rect.left() + barBegin, rect.top()),
QPointF(rect.left() + barEnd, rect.bottom()));
- const_cast<QWidget *>(widget)->update();
} else {
+#if QT_CONFIG(animation)
+ d->stopAnimation(option->styleObject);
+#endif
const auto fillPercentage = (float(baropt->progress - baropt->minimum))
/ (float(baropt->maximum - baropt->minimum));
rect.setWidth(rect.width() * fillPercentage);
@@ -2715,7 +2729,7 @@ void QWindows11Style::drawLineEditFrame(QPainter *p, const QRectF &rect, const Q
: winUI3Color(frameColorLight);
drawRoundedRect(p, rect, frameCol, Qt::NoBrush);
- if (!isEditable)
+ if (!isEditable || StyleOptionHelper::isDisabled(o))
return;
QPainterStateGuard psg(p);
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index b2cfb27e814..d45515e0ecc 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -4658,7 +4658,14 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
#if QT_CONFIG(scrollarea)
if (const QAbstractScrollArea *sa = qobject_cast<const QAbstractScrollArea *>(w)) {
const QAbstractScrollAreaPrivate *sap = sa->d_func();
- rule.drawBackground(p, opt->rect, sap->contentsOffset());
+ bool callBaseClass = true;
+ if (rule.hasBackground()) {
+ if (rule.baseStyleCanDraw())
+ baseStyle()->drawPrimitive(pe, opt, p, w);
+ else
+ rule.drawBackground(p, opt->rect, sap->contentsOffset());
+ callBaseClass = false;
+ }
if (rule.hasBorder()) {
QRect brect = rule.borderRect(opt->rect);
if (styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, opt, w)) {
@@ -4667,7 +4674,10 @@ void QStyleSheetStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *op
brect = QStyle::visualRect(opt->direction, brect, r);
}
rule.drawBorder(p, brect);
+ callBaseClass = false;
}
+ if (!callBaseClass)
+ return;
break;
}
#endif
diff --git a/tests/auto/widgets/kernel/qapplication/CMakeLists.txt b/tests/auto/widgets/kernel/qapplication/CMakeLists.txt
index 717daf4bcd2..a4f598f3b74 100644
--- a/tests/auto/widgets/kernel/qapplication/CMakeLists.txt
+++ b/tests/auto/widgets/kernel/qapplication/CMakeLists.txt
@@ -21,9 +21,10 @@ qt_internal_add_executable(apphelper_widgets
Qt::Widgets
)
set_target_properties(apphelper_widgets PROPERTIES OUTPUT_NAME apphelper)
-set_target_properties(tst_qapplication PROPERTIES
- QT_ANDROID_EXTRA_LIBS ${CMAKE_CURRENT_BINARY_DIR}/libmodal_helper_${ANDROID_ABI}.so
-)
+
+set_property(TARGET tst_qapplication PROPERTY QT_ANDROID_EXTRA_LIBS
+ ${CMAKE_CURRENT_BINARY_DIR}/libdesktopsettingsaware_helper_${ANDROID_ABI}.so
+ ${CMAKE_CURRENT_BINARY_DIR}/libmodal_helper_${ANDROID_ABI}.so)
if(QT_FEATURE_library)
qt_internal_add_cmake_library(apphelper_widgets_plugin