From 0ce3f7d62b93427ca5d0f4284ba774691cbbd4a7 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 24 Jul 2019 15:47:28 +0200 Subject: 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 --- src/plugins/styles/mac/qmacstyle_mac.mm | 35 +++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'src') 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 #include +#include + 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; -- cgit v1.2.3