зеркало из https://github.com/mozilla/gecko-dev.git
Favicons not showing up in history menu (most of the time). Patch by Stan Shebs. b=379660 r=josh sr=pav
This commit is contained in:
Родитель
eef7bc4c09
Коммит
b294a2e73e
|
@ -54,6 +54,7 @@ class imgIRequest;
|
|||
class nsIMenu;
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
class nsMenuItemIconX : public imgIDecoderObserver
|
||||
|
@ -61,7 +62,8 @@ class nsMenuItemIconX : public imgIDecoderObserver
|
|||
public:
|
||||
nsMenuItemIconX(nsISupports* aMenuItem,
|
||||
nsIMenu* aMenu,
|
||||
nsIContent* aContent);
|
||||
nsIContent* aContent,
|
||||
NSMenuItem* aNativeMenuItem);
|
||||
private:
|
||||
~nsMenuItemIconX();
|
||||
|
||||
|
@ -94,6 +96,7 @@ protected:
|
|||
PRUint16 mMenuItemIndex;
|
||||
PRPackedBool mLoadedIcon;
|
||||
PRPackedBool mSetIcon;
|
||||
NSMenuItem* mNativeMenuItem;
|
||||
};
|
||||
|
||||
#endif // nsMenuItemIconX_h_
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "imgIRequest.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsMenuX.h"
|
||||
|
||||
|
||||
static const PRUint32 kIconWidth = 16;
|
||||
|
@ -85,7 +86,8 @@ NS_IMPL_ISUPPORTS2(nsMenuItemIconX, imgIContainerObserver, imgIDecoderObserver)
|
|||
|
||||
nsMenuItemIconX::nsMenuItemIconX(nsISupports* aMenuItem,
|
||||
nsIMenu* aMenu,
|
||||
nsIContent* aContent)
|
||||
nsIContent* aContent,
|
||||
NSMenuItem* aNativeMenuItem)
|
||||
: mContent(aContent)
|
||||
, mMenuItem(aMenuItem)
|
||||
, mMenu(aMenu)
|
||||
|
@ -93,7 +95,9 @@ nsMenuItemIconX::nsMenuItemIconX(nsISupports* aMenuItem,
|
|||
, mMenuItemIndex(0)
|
||||
, mLoadedIcon(PR_FALSE)
|
||||
, mSetIcon(PR_FALSE)
|
||||
, mNativeMenuItem(aNativeMenuItem)
|
||||
{
|
||||
// printf("Creating icon for menu item %d, menu %d, native item is %d\n", aMenuItem, aMenu, aNativeMenuItem);
|
||||
}
|
||||
|
||||
|
||||
|
@ -119,14 +123,23 @@ nsMenuItemIconX::SetupIcon()
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
// If our native menu item isn't filled in, it's because this icon is for
|
||||
// a submenu that wasn't given its native menu item until later.
|
||||
if (!mNativeMenuItem)
|
||||
mNativeMenuItem = (static_cast<nsMenuX*>(mMenu))->GetNativeMenuItem();
|
||||
|
||||
// Still don't have one, then something is wrong, get out of here.
|
||||
if (!mNativeMenuItem) {
|
||||
NS_ERROR("No native menu item\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> iconURI;
|
||||
rv = GetIconURI(getter_AddRefs(iconURI));
|
||||
if (NS_FAILED(rv)) {
|
||||
// There is no icon for this menu item. An icon might have been set
|
||||
// earlier. Clear it.
|
||||
OSStatus err;
|
||||
err = ::SetMenuItemIconHandle(mMenuRef, mMenuItemIndex, kMenuNoIcon, NULL);
|
||||
if (err != noErr) return NS_ERROR_FAILURE;
|
||||
[mNativeMenuItem setImage:nil];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -248,54 +261,18 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
|
|||
// prevents it from jumping around or looking misaligned.
|
||||
|
||||
static PRBool sInitializedPlaceholder;
|
||||
static CGImageRef sPlaceholderIconImage;
|
||||
static NSImage* sPlaceholderIconImage;
|
||||
if (!sInitializedPlaceholder) {
|
||||
sInitializedPlaceholder = PR_TRUE;
|
||||
|
||||
PRUint8* bitmap = (PRUint8*)malloc(kIconBytes);
|
||||
|
||||
CGColorSpaceRef colorSpace = ::CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
CGContextRef bitmapContext;
|
||||
bitmapContext = ::CGBitmapContextCreate(bitmap, kIconWidth, kIconHeight,
|
||||
kIconBitsPerComponent,
|
||||
kIconBytesPerRow,
|
||||
colorSpace,
|
||||
kCGImageAlphaPremultipliedFirst);
|
||||
if (!bitmapContext) {
|
||||
free(bitmap);
|
||||
::CGColorSpaceRelease(colorSpace);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CGRect iconRect = ::CGRectMake(0, 0, kIconWidth, kIconHeight);
|
||||
::CGContextClearRect(bitmapContext, iconRect);
|
||||
::CGContextRelease(bitmapContext);
|
||||
|
||||
CGDataProviderRef provider;
|
||||
provider = ::CGDataProviderCreateWithData(NULL, bitmap, kIconBytes,
|
||||
PRAllocCGFree);
|
||||
if (!provider) {
|
||||
free(bitmap);
|
||||
::CGColorSpaceRelease(colorSpace);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
sPlaceholderIconImage =
|
||||
::CGImageCreate(kIconWidth, kIconHeight, kIconBitsPerComponent,
|
||||
kIconBitsPerPixel, kIconBytesPerRow, colorSpace,
|
||||
kCGImageAlphaPremultipliedFirst, provider, NULL, TRUE,
|
||||
kCGRenderingIntentDefault);
|
||||
::CGColorSpaceRelease(colorSpace);
|
||||
::CGDataProviderRelease(provider);
|
||||
// Note that we only create the one and reuse it forever, so this is not a leak.
|
||||
sPlaceholderIconImage = [[NSImage alloc] initWithSize:NSMakeSize(kIconWidth, kIconHeight)];
|
||||
}
|
||||
|
||||
if (!sPlaceholderIconImage) return NS_ERROR_FAILURE;
|
||||
|
||||
OSStatus err;
|
||||
err = ::SetMenuItemIconHandle(mMenuRef, mMenuItemIndex, kMenuCGImageRefType,
|
||||
(Handle)sPlaceholderIconImage);
|
||||
if (err != noErr) return NS_ERROR_FAILURE;
|
||||
if (mNativeMenuItem)
|
||||
[mNativeMenuItem setImage:sPlaceholderIconImage];
|
||||
}
|
||||
|
||||
rv = loader->LoadImage(aIconURI, nsnull, nsnull, loadGroup, this,
|
||||
|
@ -541,11 +518,30 @@ nsMenuItemIconX::OnStopFrame(imgIRequest* aRequest,
|
|||
::CGDataProviderRelease(provider);
|
||||
if (!iconImage) return NS_ERROR_FAILURE;
|
||||
|
||||
OSStatus err;
|
||||
err = ::SetMenuItemIconHandle(mMenuRef, mMenuItemIndex, kMenuCGImageRefType,
|
||||
(Handle)iconImage);
|
||||
NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
|
||||
CGContextRef imageContext = nil;
|
||||
|
||||
// Get the image dimensions.
|
||||
imageRect.size.width = kIconWidth;
|
||||
imageRect.size.height = kIconHeight;
|
||||
|
||||
// Create a new image to receive the Quartz image data.
|
||||
NSImage* newImage = [[NSImage alloc] initWithSize:imageRect.size];
|
||||
|
||||
[newImage lockFocus];
|
||||
|
||||
// Get the Quartz context and draw.
|
||||
imageContext = (CGContextRef)[[NSGraphicsContext currentContext]
|
||||
graphicsPort];
|
||||
CGContextDrawImage(imageContext, *(CGRect*)&imageRect, iconImage);
|
||||
[newImage unlockFocus];
|
||||
|
||||
if (!mNativeMenuItem) return NS_ERROR_FAILURE;
|
||||
|
||||
[mNativeMenuItem setImage:newImage];
|
||||
|
||||
[newImage release];
|
||||
::CGImageRelease(iconImage);
|
||||
if (err != noErr) return NS_ERROR_FAILURE;
|
||||
|
||||
mLoadedIcon = PR_TRUE;
|
||||
mSetIcon = PR_TRUE;
|
||||
|
|
|
@ -143,7 +143,7 @@ NS_METHOD nsMenuItemX::Create(nsIMenu* aParent, const nsString & aLabel, PRBool
|
|||
[mNativeMenuItem setEnabled:(BOOL)mEnabled];
|
||||
}
|
||||
|
||||
mIcon = new nsMenuItemIconX(static_cast<nsIMenuItem*>(this), mMenuParent, mContent);
|
||||
mIcon = new nsMenuItemIconX(static_cast<nsIMenuItem*>(this), mMenuParent, mContent, mNativeMenuItem);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICHANGEOBSERVER
|
||||
|
||||
id GetNativeMenuItem();
|
||||
|
||||
// nsIMenuListener methods
|
||||
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
|
||||
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
|
||||
|
@ -160,6 +162,7 @@ protected:
|
|||
PRInt16 mMacMenuID;
|
||||
NSMenu* mMacMenu; // strong ref, we own it
|
||||
MenuDelegate* mMenuDelegate; // strong ref, we keep this around to get events for us
|
||||
NSMenuItem* mNativeMenuItem; // strong ref, we own
|
||||
PRPackedBool mIsEnabled;
|
||||
PRPackedBool mDestroyHandlerCalled;
|
||||
PRPackedBool mNeedsRebuild;
|
||||
|
|
|
@ -106,7 +106,7 @@ NS_IMPL_ISUPPORTS4(nsMenuX, nsIMenu, nsIMenuListener, nsIChangeObserver, nsISupp
|
|||
|
||||
|
||||
nsMenuX::nsMenuX()
|
||||
: mParent(nsnull), mManager(nsnull), mMacMenuID(0), mMacMenu(nil),
|
||||
: mParent(nsnull), mManager(nsnull), mMacMenuID(0), mMacMenu(nil), mNativeMenuItem(nil),
|
||||
mIsEnabled(PR_TRUE), mDestroyHandlerCalled(PR_FALSE),
|
||||
mNeedsRebuild(PR_TRUE), mConstructed(PR_FALSE), mVisible(PR_TRUE),
|
||||
mXBLAttached(PR_FALSE)
|
||||
|
@ -124,6 +124,7 @@ nsMenuX::~nsMenuX()
|
|||
|
||||
[mMacMenu release];
|
||||
[mMenuDelegate release];
|
||||
[mNativeMenuItem release];
|
||||
|
||||
// alert the change notifier we don't care no more
|
||||
mManager->Unregister(mMenuContent);
|
||||
|
@ -168,7 +169,7 @@ nsMenuX::Create(nsISupports * aParent, const nsAString &aLabel, const nsAString
|
|||
MenuConstruct(fake, nsnull, nsnull, nsnull);
|
||||
|
||||
if (menu)
|
||||
mIcon = new nsMenuItemIconX(static_cast<nsIMenu*>(this), menu, mMenuContent);
|
||||
mIcon = new nsMenuItemIconX(static_cast<nsIMenu*>(this), menu, mMenuContent, nsnull);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -296,15 +297,14 @@ nsresult nsMenuX::AddMenu(nsIMenu * aMenu)
|
|||
PRBool enabled;
|
||||
aMenu->GetEnabled(&enabled);
|
||||
NSString *newCocoaLabelString = MenuHelpersX::CreateTruncatedCocoaLabel(label);
|
||||
NSMenuItem* newNativeMenuItem = [[NSMenuItem alloc] initWithTitle:newCocoaLabelString action:nil keyEquivalent:@""];
|
||||
[newNativeMenuItem setEnabled:enabled];
|
||||
[mMacMenu addItem:newNativeMenuItem];
|
||||
mNativeMenuItem = [[NSMenuItem alloc] initWithTitle:newCocoaLabelString action:nil keyEquivalent:@""];
|
||||
[mNativeMenuItem setEnabled:enabled];
|
||||
[mMacMenu addItem:mNativeMenuItem];
|
||||
[newCocoaLabelString release];
|
||||
[newNativeMenuItem release];
|
||||
|
||||
NSMenu* childMenu;
|
||||
if (aMenu->GetNativeData((void**)&childMenu) == NS_OK)
|
||||
[newNativeMenuItem setSubmenu:childMenu];
|
||||
[mNativeMenuItem setSubmenu:childMenu];
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -541,7 +541,7 @@ nsEventStatus nsMenuX::MenuConstruct(
|
|||
|
||||
gConstructingMenu = PR_FALSE;
|
||||
mNeedsRebuild = PR_FALSE;
|
||||
// printf("Done building, mMenuItemVoidArray.Count() = %d \n", mMenuItemVoidArray.Count());
|
||||
// printf("Done building, mMenuItemsArray.Count() = %d \n", mMenuItemsArray.Count());
|
||||
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
@ -1031,6 +1031,13 @@ nsMenuX::GetMenuRefAndItemIndexForMenuItem(nsISupports* aMenuItem,
|
|||
}
|
||||
|
||||
|
||||
id
|
||||
nsMenuX::GetNativeMenuItem()
|
||||
{
|
||||
return mNativeMenuItem;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// nsIChangeObserver
|
||||
//
|
||||
|
|
Загрузка…
Ссылка в новой задаче