QTabBar: let styles draw tab text with foreground role

QTabBar::setTabTextColor's documentation and implementation suggests
that the set color will always be used unless invalid, and that the
foreground role is used otherwise. QTabBar then sets the foregroundRole
palette entry to the specified color before calling the style. The intent
is evidently that the tabTextColor is used no matter the foregroundRole
(which by default is the role that contrasts with the background role).

If the styles always paint the text with WindowText, then the tabTextColor
gets ignored if the foregroundRole is not WindowText (perhaps because
the backgroundRole is set to Base).

Fix this by respecting the widget's foregroundRole when painting the tab
label in the common style (which is the only style that implements
drawControl for CE_TabBarTabLabel). QMacStyle and QStyleSheetStyle
need to be adjusted to prepare the palette consistently with the logic
in QTabBar.

Pick-to: 6.3 6.2
Fixes: QTBUG-101456
Change-Id: I077a2034eebfe3f56cea28917494f4db01e48747
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Volker Hilsheimer 2022-03-19 12:09:40 +01:00
parent eaabd0c545
commit 4ac00ca901
3 changed files with 7 additions and 4 deletions

View File

@ -4098,6 +4098,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
case CE_TabBarTabLabel:
if (const auto *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
QStyleOptionTab myTab = *tab;
const auto foregroundRole = w ? w->foregroundRole() : QPalette::WindowText;
const auto tabDirection = QMacStylePrivate::tabDirection(tab->shape);
const bool verticalTabs = tabDirection == QMacStylePrivate::East
|| tabDirection == QMacStylePrivate::West;
@ -4111,11 +4112,11 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (!myTab.documentMode && (myTab.state & State_Selected) && (myTab.state & State_Active))
if (const auto *tabBar = qobject_cast<const QTabBar *>(w))
if (!tabBar->tabTextColor(tabBar->currentIndex()).isValid())
myTab.palette.setColor(QPalette::WindowText, Qt::white);
myTab.palette.setColor(foregroundRole, Qt::white);
if (myTab.documentMode && isDarkMode()) {
bool active = (myTab.state & State_Selected) && (myTab.state & State_Active);
myTab.palette.setColor(QPalette::WindowText, active ? Qt::white : Qt::gray);
myTab.palette.setColor(foregroundRole, active ? Qt::white : Qt::gray);
}
int heightOffset = 0;

View File

@ -2004,7 +2004,8 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
p->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
}
proxy()->drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text, QPalette::WindowText);
proxy()->drawItemText(p, tr, alignment, tab->palette, tab->state & State_Enabled, tab->text,
widget ? widget->foregroundRole() : QPalette::WindowText);
if (verticalTabs)
p->restore();

View File

@ -4390,6 +4390,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
case CE_TabBarTabLabel:
case CE_TabBarTabShape:
if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
const auto foregroundRole = w ? w->foregroundRole() : QPalette::WindowText;
QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab);
QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, opt->rect, opt->direction);
if (ce == CE_TabBarTabShape && subRule.hasDrawable() && tab->shape < QTabBar::TriangularNorth) {
@ -4397,7 +4398,7 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
return;
}
QStyleOptionTab tabCopy(*tab);
subRule.configurePalette(&tabCopy.palette, QPalette::WindowText, QPalette::Base);
subRule.configurePalette(&tabCopy.palette, foregroundRole, QPalette::Base);
QFont oldFont = p->font();
if (subRule.hasFont)
p->setFont(subRule.font.resolve(p->font()));