[Style] Warn about the broken Windows native styles and stop resolving System to them (#7461)

* [Style] Fall back to the built-in windows style instead of windowsvista

The Windows Vista native style is broken the same way as the Windows 11 one,
so the sanitizer now catches both and falls back to the built-in QWindowsStyle
instead of the Vista plugin. The style picker no longer offers either.

* [Style] Keep Windows native styles selectable but warn about them

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-10-09 11:07:22 +02:00 • committed by GitHub
parent 205e1ecebf
commit 6bed5d6f67
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 38 additions and 17 deletions

View file

@ -111,12 +111,17 @@ struct PaletteColorInfo
static QString usableDefaultStyle(const QString &style)
{
// The Windows 11 native style is broken: dragging cards across zones can
// Only the OS/default ("System") style is sanitized: the Windows 11 and
// Windows Vista native styles are broken (dragging cards across zones can
// shrink the board to a tiny grey window that is unfixable without
// rejoining. It is never usable, so guard against it no matter how it was
// requested (OS default or an explicit "windows11" theme choice) and fall
// back to the Vista style.
return style.compare("windows11", Qt::CaseInsensitive) == 0 ? QStringLiteral("windowsvista") : style;
// rejoining), so a "System" choice falls through to the built-in "windows"
// style (QWindowsStyle) instead. They remain selectable by hand, where the
// settings page warns about them.
if (style.compare("windows11", Qt::CaseInsensitive) == 0 ||
style.compare("windowsvista", Qt::CaseInsensitive) == 0) {
return QStringLiteral("windows");
}
return style;
}
ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
@ -496,14 +501,13 @@ void ThemeManager::applyStyleAndPalette(const QString &themeName,
if (themeName == FUSION_THEME_NAME) {
styleName = "Fusion";
} else {
// "System" resolves through the guard, which steers the broken
// Windows native styles to "windows". An explicitly chosen style
// name is honored as-is.
styleName = usableDefaultStyle(defaultStyleName);
}
}
// The Windows 11 style is broken even when selected explicitly in a theme,
// so sanitize the resolved name here rather than trusting the theme config.
styleName = usableDefaultStyle(styleName);
QStyle *style = QStyleFactory::create(styleName);
if (!style) {
style = QStyleFactory::create(usableDefaultStyle(defaultStyleName));

View file

@ -74,15 +74,10 @@ AppearanceSettingsPage::AppearanceSettingsPage()
connect(&schemeCombo, &QComboBox::currentIndexChanged, this,
[this] { themeManager->setColorScheme(schemeCombo.currentData().toString()); });
// Qt widget style; "System" lets the application decide
// Qt widget style; "System" lets the application decide. The broken Windows
// native styles are still offered, but selecting one raises a warning.
styleCombo.addItem(tr("System"), QStringLiteral("System"));
for (const QString &key : QStyleFactory::keys()) {
// The Windows 11 native style is broken (board rendering glitches when
// moving cards), so never offer it; it is already sanitized at apply
// time in ThemeManager.
if (key.compare("windows11", Qt::CaseInsensitive) == 0) {
continue;
}
styleCombo.addItem(key, key);
}
@ -92,6 +87,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
connect(&styleCombo, &QComboBox::currentIndexChanged, this,
[this] { themeManager->setStyleName(styleCombo.currentData().toString()); });
connect(&styleCombo, &QComboBox::currentIndexChanged, this, &AppearanceSettingsPage::updateStyleWarning);
connect(themeManager, &ThemeManager::themeChanged, this, [this, dirPath] {
const QString newDir = themeManager->getAvailableThemes().value(SettingsCache::instance().getThemeName());
@ -108,6 +104,8 @@ AppearanceSettingsPage::AppearanceSettingsPage()
const int styleIdx = currentStyle.isEmpty() ? 0 : styleCombo.findData(currentStyle);
styleCombo.setCurrentIndex(styleIdx >= 0 ? styleIdx : 0);
styleCombo.blockSignals(false);
updateStyleWarning();
});
connect(&editPaletteButton, &QPushButton::clicked, this, &AppearanceSettingsPage::editPalette);
@ -120,7 +118,11 @@ AppearanceSettingsPage::AppearanceSettingsPage()
themeGrid->addWidget(&schemeCombo, 2, 1);
themeGrid->addWidget(&styleComboLabel, 3, 0);
themeGrid->addWidget(&styleCombo, 3, 1);
themeGrid->addWidget(&editPaletteButton, 4, 1);
themeGrid->addWidget(&styleWarningLabel, 4, 0, 1, 2);
themeGrid->addWidget(&editPaletteButton, 5, 1);
styleWarningLabel.setWordWrap(true);
styleWarningLabel.setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
themeGroupBox = new QGroupBox;
themeGroupBox->setLayout(themeGrid);
@ -465,6 +467,14 @@ void AppearanceSettingsPage::updateHomeTabSettingsVisibility()
homeTabDisplayCardNameCheckBox.setVisible(visible);
}
void AppearanceSettingsPage::updateStyleWarning()
{
const QString style = styleCombo.currentData().toString();
const bool broken =
style.compare("windows11", Qt::CaseInsensitive) == 0 || style.compare("windowsvista", Qt::CaseInsensitive) == 0;
styleWarningLabel.setVisible(broken);
}
void AppearanceSettingsPage::showShortcutsChanged(QT_STATE_CHANGED_T value)
{
SettingsCache::instance().userInterface().setShowShortcuts(value);
@ -527,6 +537,11 @@ void AppearanceSettingsPage::retranslateUi()
schemeComboLabel.setText(tr("Active theme palette:"));
styleComboLabel.setText(tr("Active theme style:"));
styleCombo.setToolTip(tr("Qt widget style saved to this theme (\"System\" lets the application decide)"));
styleWarningLabel.setText(
tr("Warning: the Windows 11 and Windows Vista styles are buggy and can render controls such as combo boxes "
"unreadable, especially in dark mode. Fusion is the recommended style on every platform: it is Qt's "
"cross-platform style and the one Cockatrice is developed against."));
updateStyleWarning();
editPaletteButton.setText(tr("Edit theme palette"));
homeTabGroupBox->setTitle(tr("Home tab settings"));

View file

@ -22,6 +22,7 @@ private slots:
void openThemeLocation();
void editPalette();
void updateHomeTabSettingsVisibility();
void updateStyleWarning();
void showShortcutsChanged(QT_STATE_CHANGED_T enabled);
void overrideAllCardArtWithPersonalPreferenceToggled(QT_STATE_CHANGED_T enabled);
@ -37,6 +38,7 @@ private:
QComboBox schemeCombo;
QLabel styleComboLabel;
QComboBox styleCombo;
QLabel styleWarningLabel;
QPushButton editPaletteButton;
QLabel homeTabBackgroundSourceLabel;