зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
63222ede1c
Коммит
a04efa0b76
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче