summaryrefslogtreecommitdiffstats
path: root/src/plugins/styles/mac/qmacstyle_mac.mm
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2021-11-10 16:38:28 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2021-11-18 22:06:21 +0000
commit4bee9cdc0ac4bbee7f061e8f6050d704032f6d0f (patch)
treeff69c1be4f8026349759bc0700480bc321109eb2 /src/plugins/styles/mac/qmacstyle_mac.mm
parentb3dc0fec2bdc8ab03107f906a94850b1b94b53af (diff)
macOS: Fix QSlider's knob positioning on Monterey
QMacStyle has a single NSSlider that is used to render any QSlider. For each QStyle API operating on a slider, the style sets the slider up with respecive properties. On macOS 12, the NSSlider maintains some states that make QSlider instances influence each other's knob position when rendering, resulting in uncontrollable jumping of the slider. This can be fixed by not using startTrackingAt/stopTracking APIs, which are however the only way we have to make the slider knob get rendered pressed - there is no property in NSSlider(Cell), and none of the NSCell attributes have any effect. So we need to use startTrackingAt, and work around the side effect by reinitializing the NSSlider by calling initWithFrame. This fixes the positioning error, but also causes flickering of the knob when dragging. To fix the flickering, we have to always call startTrackingAt for a slider that is pressed, even for calls to setupSlider that are made in QStyle APIs that are not drawing anything. Also tried with no complete success (either positiong bug or flicker): * call prepareForReuse on the NSView * always call stopTracking on the NSSlider Fixes: QTBUG-98093 Pick-to: 6.2 6.2.2 Change-Id: I3423b9f7cb125a59831c6722509ab3b74742b6ae Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/plugins/styles/mac/qmacstyle_mac.mm')
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 12b8e0c2f1..f8f2d1d0ef 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -467,7 +467,11 @@ static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl)
if (sl->minimum >= sl->maximum)
return false;
- slider.frame = sl->rect.toCGRect();
+ // NSSlider seems to cache values based on tracking and the last layout of the
+ // NSView, resulting in incorrect knob rects that break the interaction with
+ // multiple sliders. So completely reinitialize the slider.
+ [slider initWithFrame:sl->rect.toCGRect()];
+
slider.minValue = sl->minimum;
slider.maxValue = sl->maximum;
slider.intValue = sl->sliderPosition;
@@ -497,6 +501,14 @@ static bool setupSlider(NSSlider *slider, const QStyleOptionSlider *sl)
// the cell for its metrics and to draw itself.
[slider layoutSubtreeIfNeeded];
+ if (sl->state & QStyle::State_Sunken) {
+ const CGRect knobRect = [slider.cell knobRectFlipped:slider.isFlipped];
+ CGPoint pressPoint;
+ pressPoint.x = CGRectGetMidX(knobRect);
+ pressPoint.y = CGRectGetMidY(knobRect);
+ [slider.cell startTrackingAt:pressPoint inView:slider];
+ }
+
return true;
}