Fix leak of EventRef when firing menuitem command, and fix leak of empty string. Some general cleanup from CF -> Carbon. r=josh, b=358563

This commit is contained in:
hwaara%gmail.com 2006-10-31 10:29:30 +00:00
Родитель aa6fd6a6cf
Коммит 621d5e29e4
3 изменённых файлов: 38 добавлений и 34 удалений

Просмотреть файл

@ -108,7 +108,7 @@ nsMenuBarX::~nsMenuBarX()
mDocument->RemoveMutationObserver(this);
}
[mRootMenu autorelease];
[mRootMenu release];
}
nsEventStatus
@ -547,15 +547,9 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString
return nil;
}
// get the label into NSString* form
NSString* labelString = (NSString*)::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)label.get(),
label.Length());
if (!labelString)
labelString = [@"" retain];
// Get more information about the key equivalent. Start by
// finding the key node we need.
NSString* keyEquiv = [@"" retain];
NSString* keyEquiv = nil;
unsigned int macKeyModifiers = 0;
if (!key.IsEmpty()) {
nsCOMPtr<nsIDOMElement> keyElement;
@ -566,10 +560,7 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString
nsAutoString keyChar(NS_LITERAL_STRING(" "));
keyContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::key, keyChar);
if (!keyChar.EqualsLiteral(" ")) {
keyEquiv = (NSString*)::CFStringCreateWithCharacters(kCFAllocatorDefault, (UniChar*)keyChar.get(),
keyChar.Length());
[keyEquiv autorelease];
keyEquiv = [[keyEquiv lowercaseString] retain];
keyEquiv = [[NSString stringWithCharacters:keyChar.get() length:keyChar.Length()] lowercaseString];
}
// now grab the key equivalent modifiers
nsAutoString modifiersStr;
@ -580,13 +571,17 @@ NSMenuItem* nsMenuBarX::CreateNativeAppMenuItem(nsIMenu* inMenu, const nsAString
macKeyModifiers = MenuHelpersX::MacModifiersForGeckoModifiers(geckoModifiers);
}
}
// get the label into NSString-form
NSString* labelString = [NSString stringWithCharacters:label.get() length:label.Length()];
if (!labelString)
labelString = @"";
if (!keyEquiv)
keyEquiv = @"";
// put together the actual NSMenuItem
NSMenuItem* newMenuItem = [[NSMenuItem alloc] initWithTitle:labelString action:action keyEquivalent:keyEquiv];
[labelString release];
[keyEquiv release];
[newMenuItem setTag:tag];
[newMenuItem setTarget:target];
[newMenuItem setKeyEquivalentModifierMask:macKeyModifiers];
@ -652,6 +647,8 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
itemBeingAdded = nil;
// Add separator after About menu
[sApplicationMenu addItem:[NSMenuItem separatorItem]];
}
@ -662,6 +659,8 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
itemBeingAdded = nil;
// Add separator after Preferences menu
[sApplicationMenu addItem:[NSMenuItem separatorItem]];
}
@ -671,14 +670,14 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
0, nil);
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
itemBeingAdded = nil;
// set this menu item up as the Mac OS X Services menu
NSMenu* servicesMenu = [[NSMenu alloc] initWithTitle:@""];
[itemBeingAdded setSubmenu:servicesMenu];
[NSApp setServicesMenu:servicesMenu];
[itemBeingAdded release];
// Add separator after Services menu
[sApplicationMenu addItem:[NSMenuItem separatorItem]];
}
@ -691,6 +690,8 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
itemBeingAdded = nil;
addHideShowSeparator = TRUE;
}
@ -700,6 +701,8 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
itemBeingAdded = nil;
addHideShowSeparator = TRUE;
}
@ -709,6 +712,8 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
itemBeingAdded = nil;
addHideShowSeparator = TRUE;
}
@ -722,6 +727,7 @@ nsMenuBarX::CreateApplicationMenu(nsIMenu* inMenu)
if (itemBeingAdded) {
[sApplicationMenu addItem:itemBeingAdded];
[itemBeingAdded release];
itemBeingAdded = nil;
}
else {
// the current application does not have a DOM node for "Quit". Add one
@ -1024,10 +1030,9 @@ NSString* MenuHelpersX::CreateTruncatedCocoaLabel(nsString itemLabel)
// easy way to compute what this should be given the system font, etc, so we're just going
// to hard code it to something reasonable and bigger fonts will just have to deal.
const short kMaxItemPixelWidth = 300;
CFMutableStringRef labelRef = ::CFStringCreateMutable(kCFAllocatorDefault, itemLabel.Length());
::CFStringAppendCharacters(labelRef, (UniChar*)itemLabel.get(), itemLabel.Length());
::TruncateThemeText(labelRef, kThemeMenuItemFont, kThemeStateActive, kMaxItemPixelWidth, truncMiddle, NULL);
return (NSString*)labelRef; // caller releases
NSMutableString *label = [[NSMutableString stringWithCharacters:itemLabel.get() length:itemLabel.Length()] retain];
::TruncateThemeText((CFMutableStringRef)label, kThemeMenuItemFont, kThemeStateActive, kMaxItemPixelWidth, truncMiddle, NULL);
return label; // caller releases
}
PRUint8 MenuHelpersX::GeckoModifiersForNodeAttribute(char* modifiersAttribute)
@ -1108,6 +1113,7 @@ unsigned int MenuHelpersX::MacModifiersForGeckoModifiers(PRUint8 geckoModifiers)
err = ::SendEventToEventTarget(newEvent, GetWindowEventTarget((WindowRef)[nsMenuBarX::sEventTargetWindow windowRef]));
NS_ASSERTION(err == noErr, "Carbon event for menu hit not sent!");
}
ReleaseEvent(newEvent);
}
}

Просмотреть файл

@ -60,6 +60,7 @@ class nsMenuX;
@interface MenuDelegate : NSObject
{
nsMenuX* mGeckoMenu; // weak ref
EventHandlerRef mEventHandler;
BOOL mHaveInstalledCarbonEvents;
}
- (id)initWithGeckoMenu:(nsMenuX*)geckoMenu;
@ -159,8 +160,6 @@ protected:
PRPackedBool mNeedsRebuild;
PRPackedBool mConstructed;
PRPackedBool mVisible; // are we visible to the user?
EventHandlerRef mHandler; // our event handler
};
#endif // nsMenuX_h__

Просмотреть файл

@ -101,8 +101,7 @@ NS_IMPL_ISUPPORTS4(nsMenuX, nsIMenu, nsIMenuListener, nsIChangeObserver, nsISupp
nsMenuX::nsMenuX()
: mParent(nsnull), mManager(nsnull), mMacMenuID(0), mMacMenu(nil),
mIsEnabled(PR_TRUE), mDestroyHandlerCalled(PR_FALSE),
mNeedsRebuild(PR_TRUE), mConstructed(PR_FALSE), mVisible(PR_TRUE),
mHandler(nsnull)
mNeedsRebuild(PR_TRUE), mConstructed(PR_FALSE), mVisible(PR_TRUE)
{
mMenuDelegate = [[MenuDelegate alloc] initWithGeckoMenu:this];
@ -115,13 +114,8 @@ nsMenuX::~nsMenuX()
{
RemoveAll();
if (mMacMenu) {
if (mHandler)
::RemoveEventHandler(mHandler);
[mMacMenu autorelease];
}
[mMenuDelegate autorelease];
[mMacMenu release];
[mMenuDelegate release];
// alert the change notifier we don't care no more
mManager->Unregister(mMenuContent);
@ -275,7 +269,7 @@ NS_IMETHODIMP nsMenuX::AddMenu(nsIMenu * aMenu)
PRBool enabled;
aMenu->GetEnabled(&enabled);
NSString *newCocoaLabelString = MenuHelpersX::CreateTruncatedCocoaLabel(label);
NSMenuItem* newNativeMenuItem= [[NSMenuItem alloc] initWithTitle:newCocoaLabelString action:nil keyEquivalent:@""];
NSMenuItem* newNativeMenuItem = [[NSMenuItem alloc] initWithTitle:newCocoaLabelString action:nil keyEquivalent:@""];
[newNativeMenuItem setEnabled:enabled];
[mMacMenu addItem:newNativeMenuItem];
[newCocoaLabelString release];
@ -1216,6 +1210,11 @@ static OSStatus InstallMyMenuEventHandler(MenuRef menuRef, void* userData, Event
return self;
}
- (void)dealloc
{
RemoveEventHandler(mEventHandler);
[super dealloc];
}
// You can get a MenuRef from an NSMenu*, but not until it has been made visible
// or added to the main menu bar. Basically, Cocoa is attempting lazy loading,
@ -1228,7 +1227,7 @@ static OSStatus InstallMyMenuEventHandler(MenuRef menuRef, void* userData, Event
if (!mHaveInstalledCarbonEvents) {
MenuRef myMenuRef = _NSGetCarbonMenu(aMenu);
if (myMenuRef) {
InstallMyMenuEventHandler(myMenuRef, mGeckoMenu, nil); // can't be nil because we need to clean up
InstallMyMenuEventHandler(myMenuRef, mGeckoMenu, &mEventHandler);
mHaveInstalledCarbonEvents = TRUE;
}
}