QWidget: don't re-polish when style did not change
Don't call style->unpolish()/polish() when the old and new style did not change which might happen when setting a style sheet as this might create an infinite loop and the style (re)sets some window attribute. Bailing out early is not an option here as newStyle might be a nullptr so q->style() will fall back to the application default style. Fixes: QTBUG-133332 Change-Id: Ifa9ee4fdfa64b2768337e2d90b7bbaac5f3fcd70 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> (cherry picked from commit 3252e1808c12c21f27bb4844a1497d18587a64b5) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
38c76f704b
commit
ccf61c3480
@ -2686,7 +2686,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);
|
||||
}
|
||||
|
@ -291,6 +291,7 @@ private slots:
|
||||
void setLocale();
|
||||
void propagateLocale();
|
||||
void deleteStyle();
|
||||
void dontCrashOnSetStyle();
|
||||
void multipleToplevelFocusCheck();
|
||||
void setFocus();
|
||||
#ifndef QT_NO_CURSOR
|
||||
@ -6754,6 +6755,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
|
||||
|
Loading…
x
Reference in New Issue
Block a user