From b1131074199aae97b2a005cba871f6baf2a32c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 10 Apr 2017 11:17:51 +0200 Subject: QMacStyle: Fix scroller memory leak Calling initWithFrame repeatedly on the same object leaks memory since internal structures allocated on the previous init call will not be released. However, initWithFrame is the only API that can set scroller direction, which is does based on the geometry. Use two scroller objets, one for each of the horizontal and vertical cases. Task-number: QTBUG-60004 Change-Id: I5d07b62e6969a1824ab705941ac4d0340139b99c Reviewed-by: Timur Pocheptsov Reviewed-by: Gabriel de Dietrich --- src/widgets/styles/qmacstyle_mac.mm | 13 +++++++++---- src/widgets/styles/qmacstyle_mac_p_p.h | 6 +++++- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index a3b394a291..0bd2894402 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -2110,7 +2110,12 @@ QMacStyle::QMacStyle() name:NSPreferredScrollerStyleDidChangeNotification object:nil]; - d->nsscroller = [[NSScroller alloc] init]; + // Create scroller objects. Scroller internal direction setup happens + // on initWithFrame and cannot be changed later on. Create two scrollers + // initialized with fake geometry. Correct geometry is set at draw time. + d->horizontalScroller = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 200, 20)]; + d->verticalScroller = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 20, 200)]; + d->indicatorBranchButtonCell = nil; } @@ -2119,7 +2124,8 @@ QMacStyle::~QMacStyle() Q_D(QMacStyle); QMacAutoReleasePool pool; - [reinterpret_cast(d->nsscroller) release]; + [d->horizontalScroller release]; + [d->verticalScroller release]; NotificationReceiver *receiver = static_cast(d->receiver); [[NSNotificationCenter defaultCenter] removeObserver:receiver]; @@ -5451,8 +5457,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:(CGContextRef)cg flipped:NO]]; - NSScroller *scroller = reinterpret_cast(d->nsscroller); - [scroller initWithFrame:NSMakeRect(0, 0, slider->rect.width(), slider->rect.height())]; + NSScroller *scroller = isHorizontal ? d->horizontalScroller : d-> verticalScroller; // mac os behaviour: as soon as one color channel is >= 128, // the bg is considered bright, scroller is dark const QColor bgColor = QStyleHelper::backgroundColor(opt->palette, widget); diff --git a/src/widgets/styles/qmacstyle_mac_p_p.h b/src/widgets/styles/qmacstyle_mac_p_p.h index 9bbd0995a5..e5d2ffdc9d 100644 --- a/src/widgets/styles/qmacstyle_mac_p_p.h +++ b/src/widgets/styles/qmacstyle_mac_p_p.h @@ -115,6 +115,9 @@ // We mean it. // +Q_FORWARD_DECLARE_OBJC_CLASS(NSView); +Q_FORWARD_DECLARE_OBJC_CLASS(NSScroller); + QT_BEGIN_NAMESPACE /* @@ -246,7 +249,8 @@ public: CFAbsoluteTime defaultButtonStart; bool mouseDown; void* receiver; - void *nsscroller; + NSScroller *horizontalScroller; + NSScroller *verticalScroller; void *indicatorBranchButtonCell; NSView *backingStoreNSView; QHash cocoaControls; -- cgit v1.2.3