Bug 1199547 - Backout workaround from bug 722676 as it causes issues on at least OSX 10.10 and 10.11. r=mstange

This commit is contained in:
Stephen A Pohl 2016-04-05 10:42:00 +02:00
Родитель c9eb653e5e
Коммит b8403645d5
2 изменённых файлов: 11 добавлений и 135 удалений

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

@ -16,7 +16,6 @@
#include "nsString.h"
class nsMenuX;
class nsMenuBarX;
class nsIWidget;
class nsIContent;
@ -34,26 +33,11 @@ protected:
virtual ~nsNativeMenuServiceX() {}
};
@interface NSMenu (Undocumented)
// Undocumented method, present unchanged since OS X 10.6, used to temporarily
// highlight a top-level menu item when an appropriate Cmd+key combination is
// pressed.
- (void)_performActionWithHighlightingForItemAtIndex:(NSInteger)index;
@end
// Objective-C class used to allow us to intervene with keyboard event handling.
// We allow mouse actions to work normally.
@interface GeckoNSMenu : NSMenu
{
@private
nsMenuBarX *mMenuBarOwner; // Weak -- if non-null it owns us
bool mDelayResignMainMenu;
}
- (id)initWithTitle:(NSString *)aTitle andMenuBarOwner:(nsMenuBarX *)aMenuBarOwner;
- (void)resetMenuBarOwner;
- (bool)delayResignMainMenu;
- (void)setDelayResignMainMenu:(bool)aShouldDelay;
- (void)delayedPaintMenuBar:(id)unused;
@end
// Objective-C class used as action target for menu items
@ -97,7 +81,6 @@ public:
static NativeMenuItemTarget* sNativeEventTarget;
static nsMenuBarX* sLastGeckoMenuBarPainted;
static nsMenuBarX* sCurrentPaintDelayedMenuBar;
// The following content nodes have been removed from the menu system.
// We save them here for use in command handling.
@ -120,9 +103,7 @@ public:
nsMenuX* GetMenuAt(uint32_t aIndex);
nsMenuX* GetXULHelpMenu();
void SetSystemHelpMenu();
nsresult Paint(bool aDelayed = false);
void PaintMenuBarAfterDelay();
void ResetAwaitingDelayedPaint() { mAwaitingDelayedPaint = false; }
nsresult Paint();
void ForceUpdateNativeMenuAt(const nsAString& indexString);
void ForceNativeMenuReload(); // used for testing
static char GetLocalizedAccelKey(const char *shortcutID);
@ -142,8 +123,6 @@ protected:
nsTArray< nsAutoPtr<nsMenuX> > mMenuArray;
nsIWidget* mParentWindow; // [weak]
GeckoNSMenu* mNativeMenu; // root menu, representing entire menu bar
bool mAwaitingDelayedPaint;
};
#endif // nsMenuBarX_h_

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

@ -30,8 +30,7 @@
#include "nsToolkitCompsCID.h"
NativeMenuItemTarget* nsMenuBarX::sNativeEventTarget = nil;
nsMenuBarX* nsMenuBarX::sLastGeckoMenuBarPainted = nullptr; // Weak
nsMenuBarX* nsMenuBarX::sCurrentPaintDelayedMenuBar = nullptr; // Weak
nsMenuBarX* nsMenuBarX::sLastGeckoMenuBarPainted = nullptr;
NSMenu* sApplicationMenu = nil;
BOOL sApplicationMenuIsFallback = NO;
BOOL gSomeMenuBarPainted = NO;
@ -58,11 +57,11 @@ NS_IMETHODIMP nsNativeMenuServiceX::CreateNativeMenuBar(nsIWidget* aParent, nsIC
}
nsMenuBarX::nsMenuBarX()
: nsMenuGroupOwnerX(), mParentWindow(nullptr), mAwaitingDelayedPaint(false)
: nsMenuGroupOwnerX(), mParentWindow(nullptr)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
mNativeMenu = [[GeckoNSMenu alloc] initWithTitle:@"MainMenuBar" andMenuBarOwner:this];
mNativeMenu = [[GeckoNSMenu alloc] initWithTitle:@"MainMenuBar"];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
@ -94,7 +93,6 @@ nsMenuBarX::~nsMenuBarX()
// before the registration hash table is destroyed.
mMenuArray.Clear();
[mNativeMenu resetMenuBarOwner];
[mNativeMenu release];
NS_OBJC_END_TRY_ABORT_BLOCK;
@ -397,15 +395,10 @@ void nsMenuBarX::SetSystemHelpMenu()
}
}
nsresult nsMenuBarX::Paint(bool aDelayed)
nsresult nsMenuBarX::Paint()
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
if (!aDelayed && mAwaitingDelayedPaint) {
return NS_OK;
}
mAwaitingDelayedPaint = false;
// Don't try to optimize anything in this painting by checking
// sLastGeckoMenuBarPainted because the menubar can be manipulated by
// native dialogs and sheet code and other things besides this paint method.
@ -415,36 +408,13 @@ nsresult nsMenuBarX::Paint(bool aDelayed)
NSMenu* outgoingMenu = [NSApp mainMenu];
NS_ASSERTION([outgoingMenu numberOfItems] > 0, "Main menu does not have any items, something is terribly wrong!");
// To work around bug 722676, we sometimes need to delay making mNativeMenu
// the main menu. This is an Apple bug that sometimes causes a top-level
// menu item to remain highlighted after pressing a Cmd+key combination that
// opens a new window, then closing the window. The OS temporarily
// highlights the appropriate top-level menu item whenever you press the
// Cmd+key combination for one of its submenus. (It does this by setting a
// "pressed" attribute on it.) The OS then uses a timer to remove this
// "pressed" attribute. But without our workaround we sometimes change the
// main menu before the timer has fired, so when it fires the menu item it
// was intended to unhighlight is no longer present in the main menu. This
// causes the item to remain semi-permanently highlighted (until you quit
// Firefox or navigate the main menu by hand).
if ((outgoingMenu != mNativeMenu) &&
[outgoingMenu isKindOfClass:[GeckoNSMenu class]]) {
if (aDelayed) {
[(GeckoNSMenu *)outgoingMenu setDelayResignMainMenu:false];
} else if ([(GeckoNSMenu *)outgoingMenu delayResignMainMenu]) {
PaintMenuBarAfterDelay();
return NS_OK;
}
}
NSMenuItem* appMenuItem = [[outgoingMenu itemAtIndex:0] retain];
[outgoingMenu removeItemAtIndex:0];
[mNativeMenu insertItem:appMenuItem atIndex:0];
[appMenuItem release];
if (outgoingMenu != mNativeMenu) {
NSMenuItem* appMenuItem = [[outgoingMenu itemAtIndex:0] retain];
[outgoingMenu removeItemAtIndex:0];
[mNativeMenu insertItem:appMenuItem atIndex:0];
[appMenuItem release];
// Set menu bar and event target.
[NSApp setMainMenu:mNativeMenu];
}
// Set menu bar and event target.
[NSApp setMainMenu:mNativeMenu];
SetSystemHelpMenu();
nsMenuBarX::sLastGeckoMenuBarPainted = this;
@ -455,19 +425,6 @@ nsresult nsMenuBarX::Paint(bool aDelayed)
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
// Used to delay a call to nsMenuBarX::Paint(). Needed to work around
// bug 722676.
void nsMenuBarX::PaintMenuBarAfterDelay()
{
mAwaitingDelayedPaint = true;
nsMenuBarX::sCurrentPaintDelayedMenuBar = this;
[mNativeMenu retain];
// The delay for Apple's unhighlight timer is 0.1f, so we make ours a bit longer.
[mNativeMenu performSelector:@selector(delayedPaintMenuBar:)
withObject:nil
afterDelay:0.15f];
}
// Returns the 'key' attribute of the 'shortcutID' object (if any) in the
// currently active menubar's DOM document. 'shortcutID' should be the id
// (i.e. the name) of a component that defines a commonly used (and
@ -817,66 +774,6 @@ static BOOL gMenuItemsExecuteCommands = YES;
@implementation GeckoNSMenu
- (id)initWithTitle:(NSString *)aTitle
{
if ((self = [super initWithTitle:aTitle])) {
mMenuBarOwner = nullptr;
mDelayResignMainMenu = false;
}
return self;
}
- (id)initWithTitle:(NSString *)aTitle andMenuBarOwner:(nsMenuBarX *)aMenuBarOwner
{
if ((self = [super initWithTitle:aTitle])) {
mMenuBarOwner = aMenuBarOwner;
mDelayResignMainMenu = false;
}
return self;
}
- (void)resetMenuBarOwner
{
mMenuBarOwner = nil;
}
- (bool)delayResignMainMenu
{
return mDelayResignMainMenu;
}
- (void)setDelayResignMainMenu:(bool)aShouldDelay
{
mDelayResignMainMenu = aShouldDelay;
}
// Used to delay a call to nsMenuBarX::Paint(). Needed to work around
// bug 722676.
- (void)delayedPaintMenuBar:(id)unused
{
if (mMenuBarOwner) {
if (mMenuBarOwner == nsMenuBarX::sCurrentPaintDelayedMenuBar) {
mMenuBarOwner->Paint(true);
nsMenuBarX::sCurrentPaintDelayedMenuBar = nullptr;
} else {
mMenuBarOwner->ResetAwaitingDelayedPaint();
}
}
[self release];
}
// Undocumented method, present unchanged since OS X 10.6, used to temporarily
// highlight a top-level menu item when an appropriate Cmd+key combination is
// pressed.
- (void)_performActionWithHighlightingForItemAtIndex:(NSInteger)index
{
NSMenu *mainMenu = [NSApp mainMenu];
if ([mainMenu isKindOfClass:[GeckoNSMenu class]]) {
[(GeckoNSMenu *)mainMenu setDelayResignMainMenu:true];
}
[super _performActionWithHighlightingForItemAtIndex:index];
}
// Keyboard commands should not cause menu items to invoke their
// commands when there is a key window because we'd rather send
// the keyboard command to the window. We still have the menus