diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2019-07-24 15:47:28 +0200 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2019-07-25 10:15:41 +0200 |
commit | 0ce3f7d62b93427ca5d0f4284ba774691cbbd4a7 (patch) | |
tree | 7922148e2b4bbe77cec38973d45b0d2711babb2a | |
parent | 65cdd0f36678a6b77caf9cf0007ad44c51f7f7af (diff) |
QMacStyle: workaround NSSliderCell's cached/stale geometry
It's a bit cheesy solution, but works as I've noticed first on
QSlider's with a ticks direction 'both'. Works because we were
already using numberOfTickMarks property to trigger a special
behavior for HIG non-compliant widgets. Works for our case too
- we trigger a geometry update.
Fixes: QTBUG-76811
Change-Id: I2cbf00d42d98e78519b281d138a2f74227ef5449
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r-- | src/plugins/styles/mac/qmacstyle_mac.mm | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm index e10aa33623..1d88d2c647 100644 --- a/src/plugins/styles/mac/qmacstyle_mac.mm +++ b/src/plugins/styles/mac/qmacstyle_mac.mm @@ -137,6 +137,8 @@ #include <qpa/qplatformtheme.h> #include <QtGui/private/qcoregraphics_p.h> +#include <cmath> + QT_USE_NAMESPACE static QWindow *qt_getWindow(const QWidget *widget) @@ -514,6 +516,37 @@ static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl) return true; } +static void fixStaleGeometry(NSSlider *slider) +{ + // If it's later fixed in AppKit, this function is not needed. + // On macOS Mojave we suddenly have NSSliderCell with a cached + // (and stale) geometry, thus its -drawKnob, -drawBarInside:flipped:, + // -drawTickMarks fail to render the slider properly. Setting the number + // of tickmarks triggers an update in geometry. + + Q_ASSERT(slider); + + if (QOperatingSystemVersion::current() < QOperatingSystemVersion::MacOSMojave) + return; + + NSSliderCell *cell = slider.cell; + const NSRect barRect = [cell barRectFlipped:NO]; + const NSSize sliderSize = slider.frame.size; + CGFloat difference = 0.; + if (slider.vertical) + difference = std::abs(sliderSize.height - barRect.size.height); + else + difference = std::abs(sliderSize.width - barRect.size.width); + + if (difference > 6.) { + // Stale ... + const auto nOfTicks = slider.numberOfTickMarks; + // Non-zero, different from nOfTicks to force update + slider.numberOfTickMarks = nOfTicks + 10; + slider.numberOfTickMarks = nOfTicks; + } +} + static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY) { QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); @@ -5318,6 +5351,8 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex #endif { [slider calcSize]; + if (!hasDoubleTicks) + fixStaleGeometry(slider); NSSliderCell *cell = slider.cell; const int numberOfTickMarks = slider.numberOfTickMarks; |