diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index f36d7f094dd..0a3416a31af 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -2676,7 +2676,7 @@ void QWidgetPrivate::setStyle_helper(QStyle *newStyle, bool propagate) extra->style = newStyle; // repolish - if (polished && q->windowType() != Qt::Desktop) { + if (polished && q->windowType() != Qt::Desktop && oldStyle != q->style()) { oldStyle->unpolish(q); q->style()->polish(q); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 5c2553ce832..2ecfd262330 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -292,6 +292,7 @@ private slots: void setLocale(); void propagateLocale(); void deleteStyle(); + void dontCrashOnSetStyle(); void multipleToplevelFocusCheck(); void setFocus(); #ifndef QT_NO_CURSOR @@ -6795,6 +6796,37 @@ void tst_QWidget::deleteStyle() QCoreApplication::processEvents(); } +class TestStyle : public QCommonStyle +{ + void polish(QWidget *w) override + { + w->setWindowFlag(Qt::NoDropShadowWindowHint, true); + } + void unpolish(QWidget *w) override + { + w->setWindowFlag(Qt::NoDropShadowWindowHint, false); + } +}; + +void tst_QWidget::dontCrashOnSetStyle() +{ + const auto oldStyleName = qApp->style()->name(); + const auto resetStyleHelper = qScopeGuard([&] { + qApp->setStyleSheet({}); + qApp->setStyle(QStyleFactory::create(oldStyleName)); + }); + { + qApp->setStyle(new TestStyle); + qApp->setStyleSheet("blub"); + QComboBox w; + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); + // this created an infinite loop / stack overflow inside setStyle_helper() + // directly call polish instead waiting for the polish event + qApp->style()->polish(&w); + } +} + class TopLevelFocusCheck: public QWidget { Q_OBJECT