diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-05-06 19:09:50 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-05-07 09:33:12 (GMT) |
commit | 85ccffc829fd0d5a29e84f90bcab460770ea8601 (patch) | |
tree | f1518021982528e7408c5164464d97a5846b4556 /tests/auto/qstylesheetstyle | |
parent | e5233c4fd9a6f80ec5251cb847d08d7a088301a2 (diff) | |
download | Qt-85ccffc829fd0d5a29e84f90bcab460770ea8601.zip Qt-85ccffc829fd0d5a29e84f90bcab460770ea8601.tar.gz Qt-85ccffc829fd0d5a29e84f90bcab460770ea8601.tar.bz2 |
Fix crash with stylesheet if widget change style in the changeEvent
The problem appeared with KLineEdit and its proxy style.
When setting a stylesheet, we create a QStyleSheetStyle in 9# and set it
to the widget, which receive a changeEvent, that will set again the style
so 3# will create a new QStyleSheetStyle with the new proxy. and set it.
in 2# we will dereference the 'old' QStyleSheetStyle (the one created in #9)
that will destroy it.
Then, later in #7, we will still access that style ('newStyle') and we crash
0# QStyleSheetStyle::~QStyleSheetStyle()
1# QStyleSheetStyle::deref()
2# QWidgetPrivate::setStyle_helper(QStyle*, bool, bool)
3# QWidget::setStyle(QStyle*) (qwidget.cpp:2523)
4# ChangeEventWidget::changeEvent(QEvent*)
[...]
6# QCoreApplication::sendEvent(QObject*, QEvent*)
7# QWidgetPrivate::setStyle_helper(QStyle*, bool, bool)
9# QWidget::setStyleSheet(QString const&) (qwidget.cpp:2470)
The solution is to change the order, and do not use 'newstyle' after
we sent the event.
The origStyle is now protected wy a QWeakPointer, but this is
just for safety reason and not related to the crash.
Reviewed-by: JBache
Diffstat (limited to 'tests/auto/qstylesheetstyle')
-rw-r--r-- | tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp index e0512a9..e370309 100644 --- a/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -98,6 +98,7 @@ private slots: void complexWidgetFocus(); void task188195_baseBackground(); void task232085_spinBoxLineEditBg(); + void changeStyleInChangeEvent(); //at the end because it mess with the style. void widgetStyle(); @@ -1256,7 +1257,7 @@ void tst_QStyleSheetStyle::proxyStyle() QStyleOptionViewItemV4 opt; opt.initFrom(w); opt.features |= QStyleOptionViewItemV2::HasCheckIndicator; - QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, + QVERIFY(pb5->style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt, pb5).width() == 3); delete w; delete proxy; @@ -1579,6 +1580,34 @@ void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg() .toLocal8Bit().constData()); } +class ChangeEventWidget : public QWidget +{ public: + void changeEvent(QEvent * event) + { + if(event->type() == QEvent::StyleChange) { + static bool recurse = false; + if (!recurse) { + recurse = true; + QStyle *style = new QMotifStyle; + style->setParent(this); + setStyle(style); + recurse = false; + } + } + QWidget::changeEvent(event); + } +}; + +void tst_QStyleSheetStyle::changeStyleInChangeEvent() +{ //must not crash; + ChangeEventWidget wid; + wid.ensurePolished(); + wid.setStyleSheet(" /* */ "); + wid.ensurePolished(); + wid.setStyleSheet(" /* ** */ "); + wid.ensurePolished(); +} + QTEST_MAIN(tst_QStyleSheetStyle) #include "tst_qstylesheetstyle.moc" |