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>
This commit is contained in:
Timur Pocheptsov 2019-07-24 15:47:28 +02:00
parent 65cdd0f366
commit 0ce3f7d62b

View File

@ -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;