FIXED: Memory Leak with tooltips

Only populate the tooltips handler functions when necessary (when there is a tooltip and when the view is in a window) or clear them otherwise.

Tests in /Tests/AppKit/CPViewTest.j
This commit is contained in:
Antoine Mercadal
2015-03-05 16:59:37 -08:00
parent 9cb3eefdc4
commit 027a317291
2 changed files with 91 additions and 12 deletions
+18 -11
View File
@@ -312,13 +312,6 @@ var CPViewHighDPIDrawingEnabled = YES;
_viewClassFlags = CPViewFlags[classUID];
}
- (void)_setupToolTipHandlers
{
_toolTipInstalled = NO;
_toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
_toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
}
+ (CPSet)keyPathsForValuesAffectingFrame
{
return [CPSet setWithObjects:@"frameOrigin", @"frameSize"];
@@ -387,7 +380,6 @@ var CPViewHighDPIDrawingEnabled = YES;
_DOMImageSizes = [];
#endif
[self _setupToolTipHandlers];
[self _setupViewFlags];
[self _loadThemeAttributes];
@@ -412,12 +404,16 @@ var CPViewHighDPIDrawingEnabled = YES;
_toolTip = aToolTip;
if (_toolTip)
[self _manageToolTipInstallation];
}
- (void)_manageToolTipInstallation
{
if ([self window] && _toolTip)
[self _installToolTipEventHandlers];
else
[self _uninstallToolTipEventHandlers];
}
/*! @ignore
Install the handlers for the tooltip
@@ -427,6 +423,12 @@ var CPViewHighDPIDrawingEnabled = YES;
if (_toolTipInstalled)
return;
if (!_toolTipFunctionIn)
_toolTipFunctionIn = function(e) { [_CPToolTip scheduleToolTipForView:self]; }
if (!_toolTipFunctionOut)
_toolTipFunctionOut = function(e) { [_CPToolTip invalidateCurrentToolTipIfNeeded]; };
#if PLATFORM(DOM)
if (_DOMElement.addEventListener)
{
@@ -469,6 +471,9 @@ var CPViewHighDPIDrawingEnabled = YES;
}
#endif
_toolTipFunctionIn = nil;
_toolTipFunctionOut = nil;
_toolTipInstalled = NO;
}
@@ -807,6 +812,8 @@ var CPViewHighDPIDrawingEnabled = YES;
[self viewDidMoveToWindow];
[self _manageToolTipInstallation];
[[self window] _dirtyKeyViewLoop];
}
@@ -834,6 +841,7 @@ var CPViewHighDPIDrawingEnabled = YES;
{
// if (_graphicsContext)
[self setNeedsDisplay:YES];
}
/*!
@@ -3555,7 +3563,6 @@ var CPViewAutoresizingMaskKey = @"CPViewAutoresizingMask",
_hitTests = ![aCoder containsValueForKey:CPViewHitTestsKey] || [aCoder decodeBoolForKey:CPViewHitTestsKey];
[self _setupToolTipHandlers];
_toolTip = [aCoder decodeObjectForKey:CPViewToolTipKey];
if (_toolTip)
+73 -1
View File
@@ -699,6 +699,78 @@ var methodCalled;
[self assert:expectedRestult equals:methodCalled];
}
- (void)testToolTipInitialEmpty
{
[self assert:nil equals:view._toolTip];
[self assert:nil equals:view._toolTipInstalled];
[self assert:nil equals:view._toolTipFunctionIn];
[self assert:nil equals:view._toolTipFunctionOut];
}
- (void)testToolTipWithToolTipAndNoWindow
{
[view setToolTip:@"tooltip"];
[self assert:@"tooltip" equals:view._toolTip];
[self assert:nil equals:view._toolTipInstalled];
[self assert:nil equals:view._toolTipFunctionIn];
[self assert:nil equals:view._toolTipFunctionOut];
}
- (void)testToolTipWithToolTipAndWindow
{
[view setToolTip:@"tooltip"];
[[window contentView] addSubview:view]
[self assert:@"tooltip" equals:view._toolTip];
[self assertTrue:view._toolTipInstalled];
[self assertTrue:!!view._toolTipFunctionIn];
[self assertTrue:!!view._toolTipFunctionOut];
}
- (void)testToolTipWithToolTipAndWindowThenNoWindow
{
[view setToolTip:@"tooltip"];
[[window contentView] addSubview:view]
[view removeFromSuperview];
[self assert:@"tooltip" equals:view._toolTip];
[self assert:NO equals:view._toolTipInstalled];
[self assert:nil equals:view._toolTipFunctionIn];
[self assert:nil equals:view._toolTipFunctionOut];
}
- (void)testToolTipWithNoToolTipAndWindowThenNoWindowThenToolTip
{
[self assert:nil equals:view._toolTip];
[self assert:nil equals:view._toolTipInstalled];
[self assert:nil equals:view._toolTipFunctionIn];
[self assert:nil equals:view._toolTipFunctionOut];
[[window contentView] addSubview:view];
[self assert:nil equals:view._toolTip];
[self assert:nil equals:view._toolTipInstalled];
[self assert:nil equals:view._toolTipFunctionIn];
[self assert:nil equals:view._toolTipFunctionOut];
[view setToolTip:@"tooltip"];
[self assert:@"tooltip" equals:view._toolTip];
[self assertTrue:view._toolTipInstalled];
[self assertTrue:!!view._toolTipFunctionIn];
[self assertTrue:!!view._toolTipFunctionOut];
[view removeFromSuperview];
[self assert:@"tooltip" equals:view._toolTip];
[self assert:NO equals:view._toolTipInstalled];
[self assert:nil equals:view._toolTipFunctionIn];
[self assert:nil equals:view._toolTipFunctionOut];
}
@end
@implementation CPLayoutView : CPView
@@ -747,4 +819,4 @@ var methodCalled;
return YES;
}
@end
@end