Set QScroller's parent to its widget, for memory management
If the widget to which the scroller was assigned is deleted, the QScroller ought to be deleted too, to avoid filtering events and then following a dangling pointer while trying to react. Fixes: QTBUG-71232 Change-Id: I62680df8d84fb630df1bd8c482df099989457542 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>bb10
parent
501ff0a18c
commit
c4ee125891
|
|
@ -488,6 +488,7 @@ QScroller::QScroller(QObject *target)
|
|||
: d_ptr(new QScrollerPrivate(this, target))
|
||||
{
|
||||
Q_ASSERT(target); // you can't create a scroller without a target in any normal way
|
||||
setParent(target);
|
||||
Q_D(QScroller);
|
||||
d->init();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ private slots:
|
|||
void scrollTo();
|
||||
void scroll();
|
||||
void overshoot();
|
||||
void multipleWindows();
|
||||
|
||||
private:
|
||||
QTouchDevice *m_touchScreen = QTest::createTouchDevice();
|
||||
|
|
@ -373,7 +374,7 @@ void tst_QScroller::scrollTo()
|
|||
|
||||
void tst_QScroller::scroll()
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
|
||||
// -- good case. normal scroll
|
||||
tst_QScrollerWidget *sw = new tst_QScrollerWidget();
|
||||
sw->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
|
|
@ -413,7 +414,7 @@ void tst_QScroller::scroll()
|
|||
|
||||
void tst_QScroller::overshoot()
|
||||
{
|
||||
#ifndef QT_NO_GESTURES
|
||||
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
|
||||
tst_QScrollerWidget *sw = new tst_QScrollerWidget();
|
||||
sw->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
QScroller::grabGesture(sw, QScroller::TouchGesture);
|
||||
|
|
@ -504,6 +505,39 @@ void tst_QScroller::overshoot()
|
|||
#endif
|
||||
}
|
||||
|
||||
void tst_QScroller::multipleWindows()
|
||||
{
|
||||
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
|
||||
QScopedPointer<tst_QScrollerWidget> sw1(new tst_QScrollerWidget());
|
||||
sw1->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
QScroller::grabGesture(sw1.data(), QScroller::TouchGesture);
|
||||
sw1->setGeometry(100, 100, 400, 300);
|
||||
QScroller *s1 = QScroller::scroller(sw1.data());
|
||||
kineticScroll(sw1.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
|
||||
// now we should be scrolling
|
||||
QTRY_COMPARE( s1->state(), QScroller::Scrolling );
|
||||
|
||||
// That was fun! Do it again!
|
||||
QScopedPointer<tst_QScrollerWidget> sw2(new tst_QScrollerWidget());
|
||||
sw2->scrollArea = QRectF(0, 0, 1000, 1000);
|
||||
QScroller::grabGesture(sw2.data(), QScroller::TouchGesture);
|
||||
sw2->setGeometry(100, 100, 400, 300);
|
||||
QScroller *s2 = QScroller::scroller(sw2.data());
|
||||
kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
|
||||
// now we should be scrolling
|
||||
QTRY_COMPARE( s2->state(), QScroller::Scrolling );
|
||||
|
||||
// wait for both to stop
|
||||
QTRY_VERIFY(s1->state() != QScroller::Scrolling);
|
||||
QTRY_VERIFY(s2->state() != QScroller::Scrolling);
|
||||
|
||||
sw1.reset(); // destroy one window
|
||||
sw2->reset(); // reset the other scroller's internal state
|
||||
// make sure we can still scroll the remaining one without crashing (QTBUG-71232)
|
||||
kineticScroll(sw2.data(), QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200));
|
||||
#endif
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QScroller)
|
||||
|
||||
#include "tst_qscroller.moc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue