From 14071b5a8e15b1f9ce0bf601a96ae365fa8983aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 21 Jun 2019 13:40:50 +0200 Subject: Clarify call to initializeWidgetFontHash in QApplication::setStyle The call was added in c49c96fbb13912, "Reinitialize system palette when setting a new style", but adding it along with the palette code seems like a mistake. The potentially dirty widget font hash needs to be reset for all style changes. Change-Id: I411f56bb833819213c5485d7585fc5e3e9bd8983 Reviewed-by: Timur Pocheptsov --- src/widgets/kernel/qapplication.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index dfa1bc23b1..b3938df78a 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1133,12 +1133,18 @@ void QApplication::setStyle(QStyle *style) } else if (QApplicationPrivate::sys_pal) { clearSystemPalette(); initSystemPalette(); - QApplicationPrivate::initializeWidgetFontHash(); } else if (!QApplicationPrivate::sys_pal) { // Initialize the sys_pal if it hasn't happened yet... QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette()); } + // The default widget font hash is based on the platform theme, + // not the style, but the widget fonts could in theory have been + // affected by polish of the previous style, without a proper + // cleanup in unpolish, so reset it now before polishing the + // new style. + QApplicationPrivate::initializeWidgetFontHash(); + // initialize the application with the new style QApplicationPrivate::app_style->polish(qApp); -- cgit v1.2.3 From 6b06f12da6d5171d02764e9d6636c59731e2289f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 21 Jun 2019 13:45:39 +0200 Subject: Unify system palette initialization during style change We let initSystemPalette() do all the work, instead of leaving the first time initialization of the system palette to the caller, which makes the logic harder to follow. This also means first time initialization of the system palette will pick up a platform theme if available and resolve the palette using that, which was missing from the original logic. Change-Id: I84da557caf8ecedf6d96d87ebee93168ea9d73ba Reviewed-by: Timur Pocheptsov --- src/widgets/kernel/qapplication.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index b3938df78a..37948ecd8c 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -142,16 +142,19 @@ QApplicationPrivate *QApplicationPrivate::self = 0; static void initSystemPalette() { - if (!QApplicationPrivate::sys_pal) { - QPalette defaultPlatte; - if (QApplicationPrivate::app_style) - defaultPlatte = QApplicationPrivate::app_style->standardPalette(); - if (const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette()) { - QApplicationPrivate::setSystemPalette(themePalette->resolve(defaultPlatte)); - QApplicationPrivate::initializeWidgetPaletteHash(); - } else { - QApplicationPrivate::setSystemPalette(defaultPlatte); - } + if (QApplicationPrivate::sys_pal) + return; // Already initialized + + QPalette defaultPalette; + if (QApplicationPrivate::app_style) + defaultPalette = QApplicationPrivate::app_style->standardPalette(); + + auto *platformTheme = QGuiApplicationPrivate::platformTheme(); + if (const QPalette *themePalette = platformTheme ? platformTheme->palette() : nullptr) { + QApplicationPrivate::setSystemPalette(themePalette->resolve(defaultPalette)); + QApplicationPrivate::initializeWidgetPaletteHash(); + } else { + QApplicationPrivate::setSystemPalette(defaultPalette); } } @@ -1130,12 +1133,10 @@ void QApplication::setStyle(QStyle *style) // might call QApplication::setPalette() itself if (QApplicationPrivate::set_pal) { QApplication::setPalette(*QApplicationPrivate::set_pal); - } else if (QApplicationPrivate::sys_pal) { - clearSystemPalette(); + } else { + if (QApplicationPrivate::sys_pal) + clearSystemPalette(); initSystemPalette(); - } else if (!QApplicationPrivate::sys_pal) { - // Initialize the sys_pal if it hasn't happened yet... - QApplicationPrivate::setSystemPalette(QApplicationPrivate::app_style->standardPalette()); } // The default widget font hash is based on the platform theme, -- cgit v1.2.3 From f6a2b81eabae81110f678263be8558c24072c458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 21 Jun 2019 14:04:46 +0200 Subject: Update system palette on application init if needed A style may have been set before the application was created, which would have resulted in setting the system palette based on the style's palette. Once the application is initialized and we have a platform theme we need to reset the system palette. Change-Id: Ia48f57d3983535c8633741d8027f75bc0c214018 Reviewed-by: Timur Pocheptsov --- src/widgets/kernel/qapplication.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 37948ecd8c..f546ec9187 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -555,6 +555,12 @@ void QApplicationPrivate::init() // Must be called before initialize() QColormap::initialize(); + if (sys_pal) { + // Now that we have a platform theme we need to reset + // the system palette to pick up the theme colors. + clearSystemPalette(); + initSystemPalette(); + } qt_init_tooltip_palette(); QApplicationPrivate::initializeWidgetFontHash(); -- cgit v1.2.3 From a9e628e7ec6b9d5bb38e64b7129c68320322033b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 21 Jun 2019 14:17:50 +0200 Subject: Ensure override style properly clears out previous style if set QApplication::setStyle has quite a bit of logic to clean up from the old style before setting a new one. If a style has been set before the application is created, it's not enough to just delete the existing style, we need to treat it like a normal style switch. Change-Id: I2bcc2eb75567bf1bc8a32ac31467b22315a70a0b Reviewed-by: Timur Pocheptsov --- src/widgets/kernel/qapplication.cpp | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index f546ec9187..fc3b73924e 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -434,13 +434,6 @@ void QApplicationPrivate::process_cmdline() if (styleOverride.isEmpty() && qEnvironmentVariableIsSet("QT_STYLE_OVERRIDE")) styleOverride = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE")); - if (!styleOverride.isEmpty()) { - if (app_style) { - delete app_style; - app_style = 0; - } - } - // process platform-indep command line if (!qt_is_gui_used || !argc) return; @@ -606,8 +599,20 @@ void QApplicationPrivate::initialize() // needed for widgets in QML QAbstractDeclarativeData::setWidgetParent = QWidgetPrivate::setWidgetParentHelper; - if (application_type != QApplicationPrivate::Tty) - (void) QApplication::style(); // trigger creation of application style + if (application_type != QApplicationPrivate::Tty) { + if (!styleOverride.isEmpty()) { + if (auto *style = QStyleFactory::create(styleOverride.toLower())) { + QApplication::setStyle(style); + } else { + qWarning("QApplication: invalid style override '%s' passed, ignoring it.\n" + "\tAvailable styles: %s", qPrintable(styleOverride), + qPrintable(QStyleFactory::keys().join(QLatin1String(", ")))); + } + } + + // Trigger default style if none was set already + Q_UNUSED(QApplication::style()); + } #if QT_CONFIG(statemachine) // trigger registering of QStateMachine's GUI types qRegisterGuiStateMachine(); @@ -1036,15 +1041,6 @@ QStyle *QApplication::style() // Compile-time search for default style // QStyle *&app_style = QApplicationPrivate::app_style; - - if (!QApplicationPrivate::styleOverride.isEmpty()) { - const QString style = QApplicationPrivate::styleOverride.toLower(); - app_style = QStyleFactory::create(style); - if (Q_UNLIKELY(!app_style)) { - qWarning("QApplication: invalid style override passed, ignoring it.\n" - " Available styles: %s", qPrintable(QStyleFactory::keys().join(QLatin1String(", ")))); - } - } if (!app_style) app_style = QStyleFactory::create(QApplicationPrivate::desktopStyleKey()); -- cgit v1.2.3 From 96d1d44279dc582355c21956fee99d945888fb07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Jun 2019 16:02:17 +0200 Subject: Clean up QApplication::style default style construction Change-Id: I9f01e7cc5fa90fd9b1f5d12c7ce694c231158c32 Reviewed-by: Timur Pocheptsov --- src/widgets/kernel/qapplication.cpp | 49 ++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index fc3b73924e..1f26e6e41c 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1030,46 +1030,45 @@ void QApplication::setStyleSheet(const QString& styleSheet) */ QStyle *QApplication::style() { - if (QApplicationPrivate::app_style) - return QApplicationPrivate::app_style; - if (!qobject_cast(QCoreApplication::instance())) { - Q_ASSERT(!"No style available without QApplication!"); - return 0; - } - if (!QApplicationPrivate::app_style) { - // Compile-time search for default style - // - QStyle *&app_style = QApplicationPrivate::app_style; - if (!app_style) - app_style = QStyleFactory::create(QApplicationPrivate::desktopStyleKey()); + // Create default style + if (!qobject_cast(QCoreApplication::instance())) { + Q_ASSERT(!"No style available without QApplication!"); + return nullptr; + } + + auto &defaultStyle = QApplicationPrivate::app_style; - if (!app_style) { + defaultStyle = QStyleFactory::create(QApplicationPrivate::desktopStyleKey()); + if (!defaultStyle) { const QStringList styles = QStyleFactory::keys(); for (const auto &style : styles) { - if ((app_style = QStyleFactory::create(style))) + if ((defaultStyle = QStyleFactory::create(style))) break; } } - if (!app_style) { + if (!defaultStyle) { Q_ASSERT(!"No styles available!"); return 0; } - } - // take ownership of the style - QApplicationPrivate::app_style->setParent(qApp); - initSystemPalette(); + // Take ownership of the style + defaultStyle->setParent(qApp); - if (QApplicationPrivate::set_pal) // repolish set palette with the new style - QApplication::setPalette(*QApplicationPrivate::set_pal); + initSystemPalette(); + + if (QApplicationPrivate::set_pal) // Re-polish set palette with the new style + QApplication::setPalette(*QApplicationPrivate::set_pal); #ifndef QT_NO_STYLE_STYLESHEET - if (!QApplicationPrivate::styleSheet.isEmpty()) { - qApp->setStyleSheet(QApplicationPrivate::styleSheet); - } else + if (!QApplicationPrivate::styleSheet.isEmpty()) { + qApp->setStyleSheet(QApplicationPrivate::styleSheet); + } else #endif - QApplicationPrivate::app_style->polish(qApp); + { + defaultStyle->polish(qApp); + } + } return QApplicationPrivate::app_style; } -- cgit v1.2.3 From da0e7457523a5c6867c2d9b9f0346167738f0323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Jun 2019 16:24:33 +0200 Subject: Explicitly polish palette instead of relying on QApplication::setPalette The only effect calling QApplication::setPalette will have is the polish, so opt for doing it explicitly instead of the weirdly looking no-op assignment. Change-Id: Ia80b3f60e3e513b68c2993ea8417966f9ab6721e Reviewed-by: Timur Pocheptsov --- src/widgets/kernel/qapplication.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 1f26e6e41c..2a1a21596c 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1057,8 +1057,8 @@ QStyle *QApplication::style() initSystemPalette(); - if (QApplicationPrivate::set_pal) // Re-polish set palette with the new style - QApplication::setPalette(*QApplicationPrivate::set_pal); + if (auto *explicitlySetPalette = QApplicationPrivate::set_pal) + defaultStyle->polish(*explicitlySetPalette); #ifndef QT_NO_STYLE_STYLESHEET if (!QApplicationPrivate::styleSheet.isEmpty()) { @@ -1132,8 +1132,8 @@ void QApplication::setStyle(QStyle *style) // take care of possible palette requirements of certain gui // styles. Do it before polishing the application since the style // might call QApplication::setPalette() itself - if (QApplicationPrivate::set_pal) { - QApplication::setPalette(*QApplicationPrivate::set_pal); + if (auto *explicitlySetPalette = QApplicationPrivate::set_pal) { + QApplicationPrivate::app_style->polish(*explicitlySetPalette); } else { if (QApplicationPrivate::sys_pal) clearSystemPalette(); -- cgit v1.2.3 From df69364469c6816dab0f364f0687946a8d566679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 25 Jun 2019 16:53:37 +0200 Subject: Remove QApplicationPrivate::set_pal Its purpose was to track the default palette set by the programmer, but after 8fb881900c this is tracked by the Qt::AA_SetPalette attribute. The palette itself is always reflected 1:1 in the palette tracked by QGuiApplicationPrivate::app_pal. Change-Id: If3e84c8b3ae6070b6c50be7a33adb38799b3f3a5 Reviewed-by: Timur Pocheptsov --- src/widgets/kernel/qapplication.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'src/widgets/kernel/qapplication.cpp') diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 2a1a21596c..5a21a3a15c 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -382,7 +382,6 @@ QString QApplicationPrivate::styleSheet; // default application styles QPointer QApplicationPrivate::leaveAfterRelease = 0; QPalette *QApplicationPrivate::sys_pal = 0; // default system palette -QPalette *QApplicationPrivate::set_pal = 0; // default palette set by programmer QFont *QApplicationPrivate::sys_font = 0; // default system font QFont *QApplicationPrivate::set_font = 0; // default font set by programmer @@ -803,8 +802,6 @@ QApplication::~QApplication() delete QApplicationPrivate::app_pal; QApplicationPrivate::app_pal = 0; clearSystemPalette(); - delete QApplicationPrivate::set_pal; - QApplicationPrivate::set_pal = 0; app_palettes()->clear(); delete QApplicationPrivate::sys_font; @@ -1057,8 +1054,8 @@ QStyle *QApplication::style() initSystemPalette(); - if (auto *explicitlySetPalette = QApplicationPrivate::set_pal) - defaultStyle->polish(*explicitlySetPalette); + if (testAttribute(Qt::AA_SetPalette)) + defaultStyle->polish(*QGuiApplicationPrivate::app_pal); #ifndef QT_NO_STYLE_STYLESHEET if (!QApplicationPrivate::styleSheet.isEmpty()) { @@ -1132,8 +1129,8 @@ void QApplication::setStyle(QStyle *style) // take care of possible palette requirements of certain gui // styles. Do it before polishing the application since the style // might call QApplication::setPalette() itself - if (auto *explicitlySetPalette = QApplicationPrivate::set_pal) { - QApplicationPrivate::app_style->polish(*explicitlySetPalette); + if (testAttribute(Qt::AA_SetPalette)) { + QApplicationPrivate::app_style->polish(*QGuiApplicationPrivate::app_pal); } else { if (QApplicationPrivate::sys_pal) clearSystemPalette(); @@ -1397,11 +1394,8 @@ void QApplicationPrivate::setPalette_helper(const QPalette &palette, const char* // Send ApplicationPaletteChange to qApp itself, and to the widgets. qApp->d_func()->sendApplicationPaletteChange(all, className); } + if (!className && (!QApplicationPrivate::sys_pal || !palette.isCopyOf(*QApplicationPrivate::sys_pal))) { - if (!QApplicationPrivate::set_pal) - QApplicationPrivate::set_pal = new QPalette(palette); - else - *QApplicationPrivate::set_pal = palette; QCoreApplication::setAttribute(Qt::AA_SetPalette); emit qGuiApp->paletteChanged(*QGuiApplicationPrivate::app_pal); } @@ -1444,7 +1438,7 @@ void QApplicationPrivate::setSystemPalette(const QPalette &pal) else *sys_pal = pal; - if (!QApplicationPrivate::set_pal) + if (!testAttribute(Qt::AA_SetPalette)) QApplication::setPalette(*sys_pal); } -- cgit v1.2.3