diff options
| author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-02-13 20:01:51 +0100 |
|---|---|---|
| committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-02-27 19:26:05 +0100 |
| commit | f5105ea89a76d6051f058834d99385582cc61f85 (patch) | |
| tree | ae65146d0d143fd88da582fa0064c66538f240ba | |
| parent | 519e3963fad0761bac5629b1f6eabc58060265c0 (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
Pick-to: 6.5 6.4 6.2
Change-Id: Ic67ce3a7cb5089f885dabfd5a1951e3029915446
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
| -rw-r--r-- | src/plugins/styles/mac/qmacstyle_mac.mm | 12 | ||||
| -rw-r--r-- | src/widgets/styles/qstylesheetstyle.cpp | 4 | ||||
| -rw-r--r-- | src/widgets/widgets/qabstractscrollarea.cpp | 21 | ||||
| -rw-r--r-- | src/widgets/widgets/qscrollbar.cpp | 25 |
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 4e7b131e848..890dddbd1be 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 215e926031c..00adefdf4f1 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -5103,7 +5103,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) @@ -5713,7 +5713,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 91fedea6501..d741a70d546 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 ed456c56b88..28794bfdcca 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(); } |
