diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 455d0350e01..4674efe5680 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1381,7 +1381,7 @@ namespace QtPrivate }; template - struct IsGadgetHelper { enum { Value = false }; }; + struct IsGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; template struct IsGadgetHelper @@ -1389,11 +1389,14 @@ namespace QtPrivate template static char checkType(void (X::*)()); static void *checkType(void (T::*)()); - enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + enum { + IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), + IsGadgetOrDerivedFrom = true + }; }; template - struct IsPointerToGadgetHelper { enum { Value = false }; }; + struct IsPointerToGadgetHelper { enum { IsRealGadget = false, IsGadgetOrDerivedFrom = false }; }; template struct IsPointerToGadgetHelper @@ -1402,7 +1405,10 @@ namespace QtPrivate template static char checkType(void (X::*)()); static void *checkType(void (T::*)()); - enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; + enum { + IsRealGadget = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *), + IsGadgetOrDerivedFrom = true + }; }; @@ -1435,12 +1441,12 @@ namespace QtPrivate static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template - struct MetaObjectForType::Value>::type> + struct MetaObjectForType::IsGadgetOrDerivedFrom>::type> { static inline const QMetaObject *value() { return &T::staticMetaObject; } }; template - struct MetaObjectForType::Value>::Type> + struct MetaObjectForType::IsGadgetOrDerivedFrom>::type> { static inline const QMetaObject *value() { return &IsPointerToGadgetHelper::BaseType::staticMetaObject; } }; @@ -1599,8 +1605,8 @@ namespace QtPrivate template ::Value ? QMetaType::PointerToQObject : - QtPrivate::IsGadgetHelper::Value ? QMetaType::IsGadget : - QtPrivate::IsPointerToGadgetHelper::Value ? QMetaType::PointerToGadget : + QtPrivate::IsGadgetHelper::IsRealGadget ? QMetaType::IsGadget : + QtPrivate::IsPointerToGadgetHelper::IsRealGadget ? QMetaType::PointerToGadget : QtPrivate::IsQEnumHelper::Value ? QMetaType::IsEnumeration : 0> struct QMetaTypeIdQObject { @@ -1653,8 +1659,8 @@ namespace QtPrivate { | (IsWeakPointerToTypeDerivedFromQObject::Value ? QMetaType::WeakPointerToQObject : 0) | (IsTrackingPointerToTypeDerivedFromQObject::Value ? QMetaType::TrackingPointerToQObject : 0) | (std::is_enum::value ? QMetaType::IsEnumeration : 0) - | (IsGadgetHelper::Value ? QMetaType::IsGadget : 0) - | (IsPointerToGadgetHelper::Value ? QMetaType::PointerToGadget : 0) + | (IsGadgetHelper::IsGadgetOrDerivedFrom ? QMetaType::IsGadget : 0) + | (IsPointerToGadgetHelper::IsGadgetOrDerivedFrom ? QMetaType::PointerToGadget : 0) }; }; diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 6c24e19bfaa..769a18f9e01 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -250,9 +250,12 @@ QT_BEGIN_NAMESPACE /*! \fn template void QScopedPointer::reset(T *other = 0) - Deletes the existing object it is pointing to if any, and sets its pointer to + Deletes the existing object it is pointing to (if any), and sets its pointer to \a other. QScopedPointer now owns \a other and will delete it in its destructor. + + To clear the pointer held without deleting the object it points to (and hence take ownership + of the object), use \l take() instead. */ /*! diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 39d2857212a..0302d585b5e 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -956,7 +956,7 @@ void QXcbConnection::xi2UpdateScrollingDevice(ScrollingDevice &scrollingDevice) return; } QPointF lastScrollPosition; - if (lcQpaXInput().isDebugEnabled()) + if (lcQpaXInputEvents().isDebugEnabled()) lastScrollPosition = scrollingDevice.lastScrollPosition; for (int c = 0; c < deviceInfo->num_classes; ++c) { XIAnyClassInfo *classInfo = deviceInfo->classes[c]; diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index e9a6e536a75..fed096f3114 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2333,7 +2333,7 @@ void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) #if QT_CONFIG(xinput2) static inline int fixed1616ToInt(FP1616 val) { - return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); + return int(qreal(val) / 0x10000); } void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source) diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 511db1a72c0..a6ae61545b8 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -963,7 +963,9 @@ bool QLabel::event(QEvent *e) if (type == QEvent::Shortcut) { QShortcutEvent *se = static_cast(e); if (se->shortcutId() == d->shortcutId) { - QWidget * w = d->buddy; + QWidget *w = d->buddy; + if (!w) + return QFrame::event(e); if (w->focusPolicy() != Qt::NoFocus) w->setFocus(Qt::ShortcutFocusReason); #if QT_CONFIG(abstractbutton) @@ -1162,7 +1164,15 @@ void QLabelPrivate::updateLabel() void QLabel::setBuddy(QWidget *buddy) { Q_D(QLabel); + + if (d->buddy) + disconnect(d->buddy, SIGNAL(destroyed()), this, SLOT(_q_buddyDeleted())); + d->buddy = buddy; + + if (buddy) + connect(buddy, SIGNAL(destroyed()), this, SLOT(_q_buddyDeleted())); + if (d->isTextLabel) { if (d->shortcutId) releaseShortcut(d->shortcutId); @@ -1203,6 +1213,13 @@ void QLabelPrivate::updateShortcut() shortcutId = q->grabShortcut(QKeySequence::mnemonic(text)); } + +void QLabelPrivate::_q_buddyDeleted() +{ + Q_Q(QLabel); + q->setBuddy(nullptr); +} + #endif // QT_NO_SHORTCUT #if QT_CONFIG(movie) diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h index e1cc333a1c8..2f5db5a7d3e 100644 --- a/src/widgets/widgets/qlabel.h +++ b/src/widgets/widgets/qlabel.h @@ -158,6 +158,9 @@ private: #endif Q_PRIVATE_SLOT(d_func(), void _q_linkHovered(const QString &)) +#ifndef QT_NO_SHORTCUT + Q_PRIVATE_SLOT(d_func(), void _q_buddyDeleted()) +#endif friend class QTipLabel; friend class QMessageBoxPrivate; friend class QBalloonTip; diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index e05a5b5c359..59188563a95 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -89,6 +89,7 @@ public: #endif #ifndef QT_NO_SHORTCUT void updateShortcut(); + void _q_buddyDeleted(); #endif inline bool needTextControl() const { return isTextLabel diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index cc628ee26e3..c6fd5d17c2d 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -141,6 +141,14 @@ public: class CustomNonQObject {}; class GadgetDerived : public CustomGadget {}; +// cannot use Q_GADGET due to moc limitations but wants to behave like +// a Q_GADGET in Qml land +template +class GadgetDerivedAndTyped : public CustomGadget {}; + +Q_DECLARE_METATYPE(GadgetDerivedAndTyped) +Q_DECLARE_METATYPE(GadgetDerivedAndTyped*) + void tst_QMetaType::defined() { QCOMPARE(int(QMetaTypeId2::Defined), 1); @@ -157,6 +165,10 @@ void tst_QMetaType::defined() QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); QVERIFY(!QMetaTypeId2::Defined); + + // registered with Q_DECLARE_METATYPE + QVERIFY(QMetaTypeId2>::Defined); + QVERIFY(QMetaTypeId2*>::Defined); } struct Bar @@ -396,6 +408,10 @@ void tst_QMetaType::typeName_data() QTest::newRow("CustomGadget*") << ::qMetaTypeId() << QString::fromLatin1("CustomGadget*"); QTest::newRow("CustomQObject::CustomQEnum") << ::qMetaTypeId() << QString::fromLatin1("CustomQObject::CustomQEnum"); QTest::newRow("Qt::ArrowType") << ::qMetaTypeId() << QString::fromLatin1("Qt::ArrowType"); + + // template instance class derived from Q_GADGET enabled class + QTest::newRow("GadgetDerivedAndTyped") << ::qMetaTypeId>() << QString::fromLatin1("GadgetDerivedAndTyped"); + QTest::newRow("GadgetDerivedAndTyped*") << ::qMetaTypeId*>() << QString::fromLatin1("GadgetDerivedAndTyped*"); } void tst_QMetaType::typeName() @@ -1703,6 +1719,9 @@ void tst_QMetaType::metaObject_data() QTest::newRow("MyGadget*") << ::qMetaTypeId() << &MyGadget::staticMetaObject << false << true << false; QTest::newRow("MyEnum") << ::qMetaTypeId() << &MyGadget::staticMetaObject << false << false << false; QTest::newRow("Qt::ScrollBarPolicy") << ::qMetaTypeId() << &QObject::staticQtMetaObject << false << false << false; + + QTest::newRow("GadgetDerivedAndTyped") << ::qMetaTypeId>() << &GadgetDerivedAndTyped::staticMetaObject << true << false << false; + QTest::newRow("GadgetDerivedAndTyped*") << ::qMetaTypeId*>() << &GadgetDerivedAndTyped::staticMetaObject << false << true << false; } diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp index ced1d08d65f..ac4c8c8d4e7 100644 --- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp +++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp @@ -966,12 +966,14 @@ void tst_QVarLengthArray::insertMove() QCOMPARE(MyBase::liveCount, 4); vec.append(std::move(m3)); + QVERIFY(m3.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); QCOMPARE(MyBase::errorCount, 0); QCOMPARE(MyBase::liveCount, 4); QCOMPARE(MyBase::movedCount, 1); vec.push_back(std::move(m4)); + QVERIFY(m4.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); QVERIFY(vec.at(1).wasConstructedAt(&m4)); QCOMPARE(MyBase::errorCount, 0); @@ -979,6 +981,7 @@ void tst_QVarLengthArray::insertMove() QCOMPARE(MyBase::movedCount, 2); vec.prepend(std::move(m1)); + QVERIFY(m1.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m3)); QVERIFY(vec.at(2).wasConstructedAt(&m4)); @@ -987,9 +990,11 @@ void tst_QVarLengthArray::insertMove() QCOMPARE(MyBase::movedCount, 3); vec.insert(1, std::move(m2)); + QVERIFY(m2.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m2)); QVERIFY(vec.at(2).wasConstructedAt(&m3)); + QVERIFY(vec.at(3).wasConstructedAt(&m4)); QCOMPARE(MyBase::copyCount, 0); QCOMPARE(MyBase::liveCount, 4); @@ -1014,15 +1019,19 @@ void tst_QVarLengthArray::nonCopyable() int *const ptr4 = val4.get(); vec.append(std::move(val3)); + QVERIFY(!val3); QVERIFY(ptr3 == vec.at(0).get()); vec.append(std::move(val4)); + QVERIFY(!val4); QVERIFY(ptr3 == vec.at(0).get()); QVERIFY(ptr4 == vec.at(1).get()); vec.prepend(std::move(val1)); + QVERIFY(!val1); QVERIFY(ptr1 == vec.at(0).get()); QVERIFY(ptr3 == vec.at(1).get()); QVERIFY(ptr4 == vec.at(2).get()); vec.insert(1, std::move(val2)); + QVERIFY(!val2); QVERIFY(ptr1 == vec.at(0).get()); QVERIFY(ptr2 == vec.at(1).get()); QVERIFY(ptr3 == vec.at(2).get()); diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index ef10357b6db..600291715a3 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -2895,26 +2895,40 @@ void tst_QVector::insertMove() const const int instancesCount = Movable::counter.loadAcquire(); { QVector vec; + vec.reserve(5); + Movable m0; Movable m1; Movable m2; Movable m3; Movable m4; vec.append(std::move(m3)); + QVERIFY(m3.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); vec.push_back(std::move(m4)); + QVERIFY(m4.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m3)); QVERIFY(vec.at(1).wasConstructedAt(&m4)); vec.prepend(std::move(m1)); + QVERIFY(m1.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m3)); QVERIFY(vec.at(2).wasConstructedAt(&m4)); vec.insert(1, std::move(m2)); + QVERIFY(m2.wasConstructedAt(nullptr)); QVERIFY(vec.at(0).wasConstructedAt(&m1)); QVERIFY(vec.at(1).wasConstructedAt(&m2)); QVERIFY(vec.at(2).wasConstructedAt(&m3)); + QVERIFY(vec.at(3).wasConstructedAt(&m4)); + vec.push_front(std::move(m0)); + QVERIFY(m0.wasConstructedAt(nullptr)); + QVERIFY(vec.at(0).wasConstructedAt(&m0)); + QVERIFY(vec.at(1).wasConstructedAt(&m1)); + QVERIFY(vec.at(2).wasConstructedAt(&m2)); + QVERIFY(vec.at(3).wasConstructedAt(&m3)); + QVERIFY(vec.at(4).wasConstructedAt(&m4)); - QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 8); + QCOMPARE(Movable::counter.loadAcquire(), instancesCount + 10); } QCOMPARE(Movable::counter.loadAcquire(), instancesCount); } diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index 0410856790e..b2b45bb2377 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -693,7 +693,7 @@ QT_WARNING_DISABLE_GCC("-Wunused-local-typedefs") [[noreturn]] void attribute_f1(); void attribute_f2 [[noreturn]] (); # if (defined(__cpp_namespace_attributes) && __cpp_namespace_attributes >= 201411) && __has_cpp_attribute(deprecated) -namespace NS [[deprecated]] { } +namespace [[deprecated]] NS { } # endif #endif diff --git a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp index 500ec2e1fa8..84071962bca 100644 --- a/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp +++ b/tests/auto/widgets/widgets/qlabel/tst_qlabel.cpp @@ -178,9 +178,11 @@ void tst_QLabel::setBuddy() test_label= new QLabel( test_box ); test_label->setText( "&Test with a buddy" ); QWidget *test_edit = new QLineEdit( test_box ); + QWidget *test_edit2 = new QLineEdit( test_box ); QVBoxLayout *layout = new QVBoxLayout(test_box); layout->addWidget(test_label); layout->addWidget(test_edit); + layout->addWidget(test_edit2); test_box->show(); qApp->setActiveWindow(test_box); QVERIFY(test_box->isActiveWindow()); @@ -190,6 +192,16 @@ void tst_QLabel::setBuddy() QVERIFY( !test_edit->hasFocus() ); QTest::keyClick( test_box, 't', Qt::AltModifier ); QVERIFY( test_edit->hasFocus() ); + + // Setting a new buddy should disconnect the old one's destroyed() signal + test_label->setBuddy(test_edit2); + delete test_edit; + QCOMPARE(test_label->buddy(), test_edit2); + + // And deleting our own buddy should disconnect and not crash + delete test_edit2; + QTest::keyClick(test_box, 't', Qt::AltModifier ); + delete test_box; } #endif