summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qtypeinfo.h17
-rw-r--r--src/corelib/kernel/qproperty.cpp63
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp11
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp10
4 files changed, 97 insertions, 4 deletions
diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h
index 9b28958d33..58f20b7be4 100644
--- a/src/corelib/global/qtypeinfo.h
+++ b/src/corelib/global/qtypeinfo.h
@@ -228,8 +228,8 @@ template <typename, typename = void>
struct is_container : std::false_type {};
template <typename T>
struct is_container<T, std::void_t<
- std::is_convertible<decltype(std::declval<T>().begin() != std::declval<T>().end()), bool>,
- typename T::value_type
+ typename T::value_type,
+ std::is_convertible<decltype(std::declval<T>().begin() != std::declval<T>().end()), bool>
>> : std::true_type {};
@@ -259,7 +259,11 @@ struct expand_operator_equal_container : expand_operator_equal_tuple<T> {};
// if T::value_type exists, check first T::value_type, then T itself
template<typename T>
struct expand_operator_equal_container<T, true> :
- std::conjunction<expand_operator_equal<typename T::value_type>, expand_operator_equal_tuple<T>> {};
+ std::conjunction<
+ std::disjunction<
+ std::is_same<T, typename T::value_type>, // avoid endless recursion
+ expand_operator_equal<typename T::value_type>
+ >, expand_operator_equal_tuple<T>> {};
// recursively check the template arguments of a tuple like object
template<typename ...T>
@@ -295,7 +299,12 @@ template<typename T, bool>
struct expand_operator_less_than_container : expand_operator_less_than_tuple<T> {};
template<typename T>
struct expand_operator_less_than_container<T, true> :
- std::conjunction<expand_operator_less_than<typename T::value_type>, expand_operator_less_than_tuple<T>> {};
+ std::conjunction<
+ std::disjunction<
+ std::is_same<T, typename T::value_type>,
+ expand_operator_less_than<typename T::value_type>
+ >, expand_operator_less_than_tuple<T>
+ > {};
template<typename ...T>
using expand_operator_less_than_recursive = std::conjunction<expand_operator_less_than<T>...>;
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp
index 070fb74223..30ad3392c0 100644
--- a/src/corelib/kernel/qproperty.cpp
+++ b/src/corelib/kernel/qproperty.cpp
@@ -1180,6 +1180,69 @@ QString QPropertyBindingError::description() const
*/
/*!
+ \class QObjectCompatProperty
+ \inmodule QtCore
+ \brief The QObjectCompatProperty class is a template class to help port old
+ properties to the bindable property system.
+ \since 6.0
+ \ingroup tools
+ \internal
+
+ QObjectCompatProperty is a generic container that holds an
+ instance of \c T and behaves mostly like QProperty, just like
+ QObjectBindableProperty. It's one of the Qt internal classes implementing
+ \l {Qt Bindable Properties}. Like QObjectBindableProperty,
+ QObjectCompatProperty stores its management data structure in the surrounding
+ QObject. The last template parameter specifies a method (of the owning
+ class) to be called when the property is changed through the binding.
+ This is usually a setter.
+
+ As explained in \l {Qt Bindable Properties}, getters and setters for bindable
+ properties have to be almost trivial to be correct. However, in legacy code,
+ there is often complex logic in the setter. QObjectCompatProperty is a helper
+ to port these properties to the bindable property system.
+
+ With QObjectCompatProperty, the same rules as described in
+ \l {Bindable Property Getters and Setters} hold for the getter.
+ For the setter, the rules are different. It remains that every possible code
+ path in the setter must write to the underlying QObjectCompatProperty,
+ otherwise calling the setter might not remove a pre-existing binding, as
+ it should. However, as QObjectCompatProperty will call the setter on every
+ change, the setter is allowed to contain code like updating class internals
+ or emitting signals. Every write to the QObjectCompatProperty has to
+ be analyzed carefully to comply with the rules given in
+ \l {Writing to a Bindable Property}.
+
+ \sa Q_OBJECT_COMPAT_PROPERTY, QObjectBindableProperty, {Qt's Property System}, {Qt Bindable
+ Properties}
+*/
+
+/*!
+ \macro Q_OBJECT_COMPAT_PROPERTY(containingClass, type, name, callback)
+ \since 6.0
+ \relates QObjectCompatProperty
+ \internal
+ \brief Declares a \l QObjectCompatProperty inside \a containingClass
+ of type \a type with name \a name. The argument \a callback specifies
+ a setter function to be called when the property is changed through the binding.
+
+ \sa QObjectBindableProperty, {Qt's Property System}, {Qt Bindable Properties}
+*/
+
+/*!
+ \macro Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(containingClass, type, name, callback, value)
+ \since 6.0
+ \relates QObjectCompatProperty
+ \internal
+ \brief Declares a \l QObjectCompatProperty inside of \a containingClass
+ of type \a type with name \a name. The argument \a callback specifies
+ a setter function to be called when the property is changed through the binding.
+ \a value specifies an initialization value.
+
+ \sa QObjectBindableProperty, {Qt's Property System}, {Qt Bindable Properties}
+*/
+
+/*!
\fn template <typename Class, typename T, auto offset, auto Callback> QObjectBindableProperty<Class, T, offset, Callback>::QObjectBindableProperty()
Constructs a property with a default constructed instance of T.
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 18becd4ab0..171a3c268b 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -107,6 +107,17 @@ QWindowsUiaMainProvider::~QWindowsUiaMainProvider()
void QWindowsUiaMainProvider::notifyFocusChange(QAccessibleEvent *event)
{
if (QAccessibleInterface *accessible = event->accessibleInterface()) {
+ // If this is a table/tree/list, raise event for the focused cell/item instead.
+ if (accessible->tableInterface()) {
+ int count = accessible->childCount();
+ for (int i = 0; i < count; ++i) {
+ QAccessibleInterface *item = accessible->child(i);
+ if (item && item->isValid() && item->state().focused) {
+ accessible = item;
+ break;
+ }
+ }
+ }
if (QWindowsUiaMainProvider *provider = providerForAccessible(accessible)) {
QWindowsUiaWrapper::instance()->raiseAutomationEvent(provider, UIA_AutomationFocusChangedEventId);
}
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index df9beabe73..09a5125886 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -2128,5 +2128,15 @@ void tst_QMetaType::constexprMetaTypeIds()
Q_UNUSED(metaType);
}
+struct S {
+ using value_type = S; // used to cause compilation error with Qt6
+ int begin();
+ int end();
+};
+
+// should not cause a compilation failure
+// used to cause issues due to S being equal to S::value_type
+Q_DECLARE_METATYPE(S)
+
QTEST_MAIN(tst_QMetaType)
#include "tst_qmetatype.moc"