From 810a7d925af4a7aea741e8319d9dddce5947710a Mon Sep 17 00:00:00 2001 From: Joseph Spiros Date: Thu, 10 Nov 2005 02:00:27 +0000 Subject: [PATCH] I've added a one second cache to the NSMenu proxy because otherwise the menu provider may be creating new instances on every method call, and when a menu is displayed, something like 24 methods are called, so that's 24 (potentially different) instances. I also had the ITStatusItem directly set the cell's menu, rather than setting itself's menu, this way, everything will work fine if you change your mind and decide to use setMenu: instead of setMenuProvider:. --- ITStatusItem.h | 1 + ITStatusItem.m | 47 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/ITStatusItem.h b/ITStatusItem.h index 7085c78..4ed0643 100644 --- a/ITStatusItem.h +++ b/ITStatusItem.h @@ -22,6 +22,7 @@ @interface ITStatusItem : NSStatusItem { id _menuProvider; + NSMenu *_menuProxy; } - (id)initWithStatusBar:(NSStatusBar *)statusBar withLength:(float)length; diff --git a/ITStatusItem.m b/ITStatusItem.m index d4e078a..0978705 100644 --- a/ITStatusItem.m +++ b/ITStatusItem.m @@ -1,8 +1,11 @@ #import "ITStatusItem.h" +#import @interface ITStatusItemMenuProxy : NSProxy { id menuProvider; ITStatusItem *statusItem; + AbsoluteTime cachedTime; + NSMenu *menu; } - (id)initWithMenuProvider:(id )provider statusItem:(ITStatusItem *)item; @@ -21,24 +24,30 @@ - (id)initWithMenuProvider:(id )provider statusItem:(ITStatusItem *)item { menuProvider = [provider retain]; statusItem = [item retain]; + cachedTime = UpTime(); + menu = nil; return self; } - (void)forwardInvocation:(NSInvocation *)anInvocation { - NSMenu *temporaryMenu = [[menuProvider menuForStatusItem:statusItem] retain]; - [anInvocation setTarget:temporaryMenu]; + AbsoluteTime diff = SubAbsoluteFromAbsolute(UpTime(),cachedTime); + + if (!menu || diff.lo > 1000000) { + [menu release]; + menu = [[menuProvider menuForStatusItem:statusItem] retain]; + cachedTime = UpTime(); + } + + [anInvocation setTarget:menu]; [anInvocation invoke]; - [temporaryMenu release]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { - NSMenu *temporaryMenu = [[menuProvider menuForStatusItem:statusItem] retain]; - NSMethodSignature *signature = [temporaryMenu methodSignatureForSelector:aSelector]; - [temporaryMenu release]; - return signature; + return [NSMenu instanceMethodSignatureForSelector:aSelector]; } - (void)dealloc { + [menu release]; [statusItem release]; [menuProvider release]; [super dealloc]; @@ -53,6 +62,11 @@ - (NSStatusBarButton *)_button; @end +@protocol _ITStatusItemNSStatusBarButtonMethods +- (NSMenu *)statusMenu; +- (void)setStatusMenu:(NSMenu *)menu; +@end + @protocol _ITStatusItemNSStatusItemPantherCompatability - (void)setAlternateImage:(NSImage *)image; - (NSImage *)alternateImage; @@ -74,6 +88,8 @@ static BOOL _ITStatusItemShouldKillShadow = NO; - (id)_initInStatusBar:(NSStatusBar *)statusBar withLength:(float)length withPriority:(int)priority { if ((self = [super _initInStatusBar:statusBar withLength:length withPriority:priority])) { + _menuProvider = nil; + _menuProxy = nil; if (_ITStatusItemShouldKillShadow) { [[(NSButton *)[self _button] cell] setType:NSNullCellType]; } @@ -102,13 +118,20 @@ static BOOL _ITStatusItemShouldKillShadow = NO; } - (void)setMenuProvider:(id )provider { - [_menuProvider autorelease]; - _menuProvider = [provider retain]; - if (provider) { - [self setMenu:[[ITStatusItemMenuProxy alloc] initWithMenuProvider:_menuProvider statusItem:self]]; + [_menuProxy autorelease]; + _menuProxy = nil; + _menuProvider = provider; + if (_menuProvider) { + _menuProxy = [[ITStatusItemMenuProxy alloc] initWithMenuProvider:_menuProvider statusItem:self]; + [(id <_ITStatusItemNSStatusBarButtonMethods>)[self _button] setStatusMenu:_menuProxy]; } else { - [self setMenu:nil]; + [self setMenu:[self menu]]; } } +- (void)dealloc { + [_menuProxy release]; + [super dealloc]; +} + @end \ No newline at end of file -- 2.20.1