From 0aae7b95939eb0581d5560136b40ee19fb0c1cde Mon Sep 17 00:00:00 2001 From: Andreas Buhr Date: Wed, 27 Jan 2021 11:12:02 +0100 Subject: [PATCH 1/3] Add documentation for internal Q_OBJECT_COMPAT_PROPERTY The internal class QObjectCompatProperty and the associated macro Q_OBJECT_COMPAT_PROPERTY did not have any documentation so far. This patch adds some initial documentation. Task-number: QTBUG-90511 Change-Id: Ie55e7d7829363bd5a29430a4250ddba14a761912 Reviewed-by: Edward Welbourne Reviewed-by: Paul Wicking --- src/corelib/kernel/qproperty.cpp | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 070fb742232..30ad3392c00 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -1179,6 +1179,69 @@ QString QPropertyBindingError::description() const \sa {Qt's Property System}, {Qt Bindable Properties} */ +/*! + \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 QObjectBindableProperty::QObjectBindableProperty() From f1eccab04e01b3acc1a4b4c6a5fe7b3af3e2dcba Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Sun, 21 Mar 2021 04:16:44 +0100 Subject: [PATCH 2/3] Windows QPA: Fix accessibility focus event for table/tree/list The focused element within a table, tree or list was not being informed in the UI Automation focus change events, causing the focused element to be missed by screen readers. Fixes: QTBUG-91029 Pick-to: 6.0 6.1 5.15 Change-Id: I738502e6871358508b4510763018837c304b618e Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff --- .../windows/uiautomation/qwindowsuiamainprovider.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp index 18becd4ab0f..171a3c268bc 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); } From ce83e56cfeb2806181ec1daade9690f4c90b901c Mon Sep 17 00:00:00 2001 From: Fabian Kosmale Date: Tue, 23 Mar 2021 22:29:53 +0100 Subject: [PATCH 3/3] QTypeInfo: Handle T::value_type being equal to T Fix operator checks for containers whose value_type equals themselves. It does not make sense to recurse on value_type in that case. Thanks to std::disjunction having short-circuiting semantics, we can avoid that issue by checking first whether T is T::value_type. As a drive-by, check for value_type typedef before checking for begin/end in is_container. This works around an issue in gcc <= 8.1, which fails to correctly SFINAE the case where begin and end are private methods. Pick-to: 6.0 6.1 Fixes: QTBUG-89456 Change-Id: I27305a7cfe050f13a279c07f00bc229c01daa25b Reviewed-by: Ulf Hermann --- src/corelib/global/qtypeinfo.h | 17 +++++++++++++---- .../corelib/kernel/qmetatype/tst_qmetatype.cpp | 10 ++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qtypeinfo.h b/src/corelib/global/qtypeinfo.h index 9b28958d33f..58f20b7be41 100644 --- a/src/corelib/global/qtypeinfo.h +++ b/src/corelib/global/qtypeinfo.h @@ -228,8 +228,8 @@ template struct is_container : std::false_type {}; template struct is_container().begin() != std::declval().end()), bool>, - typename T::value_type + typename T::value_type, + std::is_convertible().begin() != std::declval().end()), bool> >> : std::true_type {}; @@ -259,7 +259,11 @@ struct expand_operator_equal_container : expand_operator_equal_tuple {}; // if T::value_type exists, check first T::value_type, then T itself template struct expand_operator_equal_container : - std::conjunction, expand_operator_equal_tuple> {}; + std::conjunction< + std::disjunction< + std::is_same, // avoid endless recursion + expand_operator_equal + >, expand_operator_equal_tuple> {}; // recursively check the template arguments of a tuple like object template @@ -295,7 +299,12 @@ template struct expand_operator_less_than_container : expand_operator_less_than_tuple {}; template struct expand_operator_less_than_container : - std::conjunction, expand_operator_less_than_tuple> {}; + std::conjunction< + std::disjunction< + std::is_same, + expand_operator_less_than + >, expand_operator_less_than_tuple + > {}; template using expand_operator_less_than_recursive = std::conjunction...>; diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index df9beabe737..09a51258863 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"