summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-02-13 20:01:51 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-02-28 12:45:36 +0000
commitc4c7bebb6ae18388f67f0c7b015ecb975177b7a7 (patch)
tree73f99ff3af0a7ef297ddac9bd0ed872afa63e774
parent3e1b877b95eddcb7efd33e5149c904dae3911617 (diff)
QStyleSheet: never treat styled scrollbars as transient
If a style sheet is applied to a scrollbar, then we cannot treat it as transient, as the QStyleSheetStyle doesn't implement any fade-in/out animation logic. And we also need to set the overlap to 0 (in both the style sheet and the macOS style) if the scrollbars are not transient; otherwise the opaque scrollbar will be placed on top of the content. Since a style sheet might only apply to a scrollbar based on its orientation, we also have to pass the style option through to all calls of the styleHint function. And since that function is also called from other QStyle implementations in the macOS style, we have to make sure that we call styleHint() on the widget's style to get the correct value based on the style sheet. Fixes: QTBUG-63381 Change-Id: Ic67ce3a7cb5089f885dabfd5a1951e3029915446 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> (cherry picked from commit f5105ea89a76d6051f058834d99385582cc61f85) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm12
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp4
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp21
-rw-r--r--src/widgets/widgets/qscrollbar.cpp25
4 files changed, 42 insertions, 20 deletions
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index afa72b3f09..c95847851e 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -2553,10 +2553,13 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
case PM_ToolBarFrameWidth:
ret = 1;
break;
- case PM_ScrollView_ScrollBarOverlap:
- ret = [NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay ?
- pixelMetric(PM_ScrollBarExtent, opt, widget) : 0;
+ case PM_ScrollView_ScrollBarOverlap: {
+ const QStyle *realStyle = widget ? widget->style() : proxy();
+ ret = realStyle->styleHint(SH_ScrollBar_Transient, opt, widget)
+ ? realStyle->pixelMetric(PM_ScrollBarExtent, opt, widget)
+ : 0;
break;
+ }
default:
ret = QCommonStyle::pixelMetric(metric, opt, widget);
break;
@@ -5192,7 +5195,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const auto cocoaSize = d->effectiveAquaSizeConstrain(opt, widget);
const CGFloat maxExpandScale = expandedKnobWidths[cocoaSize] / knobWidths[cocoaSize];
- const bool isTransient = proxy()->styleHint(SH_ScrollBar_Transient, opt, widget);
+ const QStyle *realStyle = widget ? widget->style() : proxy();
+ const bool isTransient = realStyle->styleHint(SH_ScrollBar_Transient, opt, widget);
if (!isTransient)
d->stopAnimation(opt->styleObject);
bool wasActive = false;
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 395b425080..51426f1609 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -5099,7 +5099,7 @@ int QStyleSheetStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const
break;
case PM_ScrollView_ScrollBarOverlap:
- if (!rule.hasNativeBorder() || rule.hasBox())
+ if (!proxy()->styleHint(SH_ScrollBar_Transient, opt, w))
return 0;
break;
#endif // QT_CONFIG(scrollbar)
@@ -5709,7 +5709,7 @@ int QStyleSheetStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWi
case SH_TitleBar_ShowToolTipsOnButtons: s = "titlebar-show-tooltips-on-buttons"_L1; break;
case SH_Widget_Animation_Duration: s = "widget-animation-duration"_L1; break;
case SH_ScrollBar_Transient:
- if (!rule.hasNativeBorder() || rule.hasBox())
+ if (!rule.hasNativeBorder() || rule.hasBox() || rule.hasDrawable())
return 0;
break;
default: break;
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 91fedea650..d741a70d54 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -295,22 +295,25 @@ void QAbstractScrollAreaPrivate::layoutChildren()
void QAbstractScrollAreaPrivate::layoutChildren_helper(bool *needHorizontalScrollbar, bool *needVerticalScrollbar)
{
Q_Q(QAbstractScrollArea);
- bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, hbar);
+ QStyleOptionSlider barOpt;
+
+ hbar->initStyleOption(&barOpt);
+ bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, hbar);
bool needh = *needHorizontalScrollbar || ((hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
|| ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
&& hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty())));
+ const int hscrollOverlap = hbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, hbar);
- bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, vbar);
+ vbar->initStyleOption(&barOpt);
+ bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &barOpt, vbar);
bool needv = *needVerticalScrollbar || ((vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
|| ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
&& vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty())));
+ const int vscrollOverlap = vbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &barOpt, vbar);
QStyleOption opt(0);
opt.initFrom(q);
- const int hscrollOverlap = hbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &opt, hbar);
- const int vscrollOverlap = vbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &opt, vbar);
-
const int hsbExt = hbar->sizeHint().height();
const int vsbExt = vbar->sizeHint().width();
const QPoint extPoint(vsbExt, hsbExt);
@@ -1342,10 +1345,14 @@ bool QAbstractScrollAreaPrivate::canStartScrollingAt(const QPoint &startPos) con
void QAbstractScrollAreaPrivate::flashScrollBars()
{
- bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, hbar);
+ QStyleOptionSlider opt;
+ hbar->initStyleOption(&opt);
+
+ bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, hbar);
if ((hbarpolicy != Qt::ScrollBarAlwaysOff) && (hbarpolicy == Qt::ScrollBarAsNeeded || htransient))
hbar->d_func()->flash();
- bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, vbar);
+ vbar->initStyleOption(&opt);
+ bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, vbar);
if ((vbarpolicy != Qt::ScrollBarAlwaysOff) && (vbarpolicy == Qt::ScrollBarAsNeeded || vtransient))
vbar->d_func()->flash();
}
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index ed456c56b8..28794bfdcc 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -189,7 +189,9 @@ void QScrollBarPrivate::setTransient(bool value)
if (transient != value) {
transient = value;
if (q->isVisible()) {
- if (q->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, q))
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ if (q->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, q))
q->update();
} else if (!transient) {
q->show();
@@ -200,7 +202,9 @@ void QScrollBarPrivate::setTransient(bool value)
void QScrollBarPrivate::flash()
{
Q_Q(QScrollBar);
- if (!flashed && q->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, q)) {
+ QStyleOptionSlider opt;
+ q->initStyleOption(&opt);
+ if (!flashed && q->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, q)) {
flashed = true;
if (!q->isVisible())
q->show();
@@ -284,7 +288,7 @@ void QScrollBar::initStyleOption(QStyleOptionSlider *option) const
option->upsideDown = d->invertedAppearance;
if (d->orientation == Qt::Horizontal)
option->state |= QStyle::State_Horizontal;
- if ((d->flashed || !d->transient) && style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this))
+ if ((d->flashed || !d->transient) && style()->styleHint(QStyle::SH_ScrollBar_Transient, option, this))
option->state |= QStyle::State_On;
}
@@ -341,7 +345,9 @@ void QScrollBarPrivate::init()
invertedControls = true;
pressedControl = hoverControl = QStyle::SC_None;
pointerOutsidePressedControl = false;
- transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, q);
+ QStyleOption opt;
+ opt.initFrom(q);
+ transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, q);
flashed = false;
flashTimer = 0;
q->setFocusPolicy(Qt::NoFocus);
@@ -435,12 +441,17 @@ bool QScrollBar::event(QEvent *event)
if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event))
d_func()->updateHoverControl(he->position().toPoint());
break;
- case QEvent::StyleChange:
- d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this));
+ case QEvent::StyleChange: {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, this));
break;
+ }
case QEvent::Timer:
if (static_cast<QTimerEvent *>(event)->timerId() == d->flashTimer) {
- if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, nullptr, this)) {
+ QStyleOptionSlider opt;
+ initStyleOption(&opt);
+ if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, &opt, this)) {
d->flashed = false;
update();
}