rewrite osx menus to use carbon command events to work around all MenuSelect problems on carbon on 9. r=beard/sr=sfraser, bug#58227

This commit is contained in:
pinkerton%netscape.com 2001-10-25 13:58:13 +00:00
parent ab90544f95
commit 96d12a2ec0
18 changed files with 185 additions and 171 deletions

View File

@ -24,3 +24,8 @@
#define _IMPL_NS_WIDGET 1
#include "WidgetDebug.prefix"
#if !TARGET_CARBON
#define USE_MENUSELECT 1
#endif

View File

@ -24,3 +24,7 @@
#define _IMPL_NS_WIDGET 1
#include "Widget.prefix"
#if !TARGET_CARBON
#define USE_MENUSELECT 1
#endif

View File

@ -48,6 +48,8 @@ class nsIMenuItem;
class nsIMenuListener;
class nsIChangeManager;
class nsIContent;
class nsIMenuCommandDispatcher;
// {ab6cea83-00ff-11d5-bb6f-f432a43ead7c}
#define NS_IMENU_IID \

View File

@ -5,3 +5,4 @@
nsMacMessageSink.h
nsMacMessagePump.h
nsIChangeManager.idl
nsIMenuCommandDispatcher.idl

View File

@ -89,6 +89,7 @@ CPPSRCS = nsAppShell.cpp \
XPIDLSRCS += \
nsIChangeManager.idl \
nsIMenuCommandDispatcher.idl \
$(NULL)
GARBAGE += $(GFX_LCPPSRCS)

View File

@ -528,6 +528,8 @@ PRBool nsMacEventHandler::HandleOSEvent ( EventRecord& aOSEvent )
}
#if USE_MENUSELECT
//-------------------------------------------------------------------------
//
// Handle Menu commands
@ -592,6 +594,7 @@ PRBool nsMacEventHandler::HandleMenuCommand(
return eventHandled;
}
#endif
//-------------------------------------------------------------------------
//

View File

@ -138,7 +138,9 @@ public:
virtual ~nsMacEventHandler();
virtual PRBool HandleOSEvent(EventRecord& aOSEvent);
#if USE_MENUSELECT
virtual PRBool HandleMenuCommand(EventRecord& aOSEvent, long aMenuResult);
#endif
// Tell Gecko that a drag event has occurred and should go into Gecko
virtual PRBool DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers ) ;

View File

@ -540,11 +540,13 @@ void nsMacMessagePump::DoMouseDown(EventRecord &anEvent)
nsWatchTask::GetTask().Suspend();
long menuResult = ::MenuSelect(anEvent.where);
nsWatchTask::GetTask().Resume();
#if USE_MENUSELECT
if (HiWord(menuResult) != 0)
{
menuResult = ConvertOSMenuResultToPPMenuResult(menuResult);
DoMenu(anEvent, menuResult);
}
#endif
}
break;
@ -798,6 +800,7 @@ void nsMacMessagePump::DoKey(EventRecord &anEvent)
//}
//else
{
#if USE_MENUSELECT
PRBool handled = DispatchOSEventToRaptor(anEvent, GetFrontApplicationWindow());
/* we want to call this if cmdKey is pressed and no other modifier keys are pressed */
if((!handled) && (anEvent.what == keyDown) && (anEvent.modifiers == cmdKey) )
@ -810,6 +813,7 @@ void nsMacMessagePump::DoKey(EventRecord &anEvent)
DoMenu(anEvent, menuResult);
}
}
#endif
}
}
@ -841,13 +845,13 @@ void nsMacMessagePump::DoDisk(const EventRecord& anEvent)
//-------------------------------------------------------------------------
extern Boolean SIOUXIsAppWindow(WindowPtr window);
#if USE_MENUSELECT
void nsMacMessagePump::DoMenu(EventRecord &anEvent, long menuResult)
{
// The app can handle its menu commands here or
// in the nsNativeBrowserWindow and nsNativeViewerApp
#if !TARGET_CARBON
extern const PRInt16 kAppleMenuID; // Danger Will Robinson!!! - this currently requires
extern const PRInt16 kAppleMenuID; // Danger Will Robinson!!! - this currently requires
// APPLE_MENU_HACK to be defined in nsMenu.h
// One of these days it'll become a non-hack
// and things will be less convoluted
@ -869,7 +873,6 @@ extern const PRInt16 kAppleMenuID; // Danger Will Robinson!!! - this currently r
return;
}
}
#endif
// Note that we still give Raptor a shot at the event as it will eventually
// handle the About... selection
@ -877,7 +880,7 @@ extern const PRInt16 kAppleMenuID; // Danger Will Robinson!!! - this currently r
HiliteMenu(0);
}
#endif
//-------------------------------------------------------------------------
//
@ -934,6 +937,9 @@ PRBool nsMacMessagePump::DispatchOSEventToRaptor(
}
#if USE_MENUSELECT
//-------------------------------------------------------------------------
//
// DispatchMenuCommandToRaptor
@ -952,3 +958,4 @@ PRBool nsMacMessagePump::DispatchMenuCommandToRaptor(
return handled;
}
#endif

View File

@ -97,13 +97,17 @@ private:
void DoMouseMove(EventRecord &anEvent);
void DoUpdate(EventRecord &anEvent);
void DoKey(EventRecord &anEvent);
#if USE_MENUSELECT
void DoMenu(EventRecord &anEvent, long menuResult);
#endif
void DoDisk(const EventRecord &anEvent);
void DoActivate(EventRecord &anEvent);
void DoIdle(EventRecord &anEvent);
PRBool DispatchOSEventToRaptor(EventRecord &anEvent, WindowPtr aWindow);
#if USE_MENUSELECT
PRBool DispatchMenuCommandToRaptor(EventRecord &anEvent, long menuResult);
#endif
PRBool BrowserIsBusy();

View File

@ -64,6 +64,7 @@ NS_EXPORT PRBool nsMacMessageSink::DispatchOSEvent(
}
#if USE_MENUSELECT
//-------------------------------------------------------------------------
//
// DispatchMenuCommand
@ -85,6 +86,7 @@ NS_EXPORT PRBool nsMacMessageSink::DispatchMenuCommand(
}
return eventHandled;
}
#endif
#pragma mark -

View File

@ -75,7 +75,9 @@ private:
public:
PRBool DispatchOSEvent(EventRecord &anEvent, WindowPtr aWindow);
#if USE_MENUSELECT
PRBool DispatchMenuCommand(EventRecord &anEvent, long menuResult, WindowPtr aWindow);
#endif
static void AddRaptorWindowToList(WindowPtr wind, nsMacWindow* theRaptorWindow);
static void RemoveRaptorWindowFromList(WindowPtr wind);

View File

@ -1322,6 +1322,8 @@ PRBool nsMacWindow::HandleOSEvent ( EventRecord& aOSEvent )
}
#if USE_MENUSELECT
//-------------------------------------------------------------------------
//
// Handle Menu commands
@ -1337,6 +1339,8 @@ PRBool nsMacWindow::HandleMenuCommand ( EventRecord& aOSEvent, long aMenuResult
return retVal;
}
#endif
//-------------------------------------------------------------------------
// Pass notification of some drag event to Gecko
//

View File

@ -110,9 +110,11 @@ public:
virtual PRBool HandleOSEvent(
EventRecord& aOSEvent);
#if USE_MENUSELECT
virtual PRBool HandleMenuCommand(
EventRecord& aOSEvent,
long aMenuResult);
#endif
// be notified that a some form of drag event needs to go into Gecko
virtual PRBool DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers ) ;

View File

@ -76,7 +76,8 @@ static NS_DEFINE_CID(kMenuBarCID, NS_MENUBAR_CID);
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
static NS_DEFINE_CID(kMenuItemCID, NS_MENUITEM_CID);
NS_IMPL_ISUPPORTS5(nsMenuBarX, nsIMenuBar, nsIMenuListener, nsIDocumentObserver, nsIChangeManager, nsISupportsWeakReference)
NS_IMPL_ISUPPORTS6(nsMenuBarX, nsIMenuBar, nsIMenuListener, nsIDocumentObserver,
nsIChangeManager, nsIMenuCommandDispatcher, nsISupportsWeakReference)
MenuRef nsMenuBarX::sAppleMenu = nsnull;
EventHandlerUPP nsMenuBarX::sCommandEventHandler = nsnull;
@ -86,12 +87,9 @@ EventHandlerUPP nsMenuBarX::sCommandEventHandler = nsnull;
// nsMenuBarX constructor
//
nsMenuBarX::nsMenuBarX()
: mNumMenus(0), mParent(nsnull), mIsMenuBarAdded(PR_FALSE), mDocument(nsnull), mCurrentCommandID(1)
{
NS_INIT_REFCNT();
mNumMenus = 0;
mParent = nsnull;
mIsMenuBarAdded = PR_FALSE;
mDocument = nsnull;
OSStatus status = ::CreateNewMenu(0, 0, &mRootMenu);
NS_ASSERTION(status == noErr, "nsMenuBarX::nsMenuBarX: creation of root menu failed.");
@ -246,8 +244,6 @@ nsMenuBarX :: RegisterAsDocumentObserver ( nsIWebShell* inWebShell )
} // RegisterAsDocumentObesrver
#if TARGET_CARBON
//
// AquifyMenuBar
//
@ -271,20 +267,34 @@ nsMenuBarX :: AquifyMenuBar ( )
HideItem ( domDoc, NS_LITERAL_STRING("menu_PrefsSeparator"), nsnull );
HideItem ( domDoc, NS_LITERAL_STRING("menu_preferences"), getter_AddRefs(mPrefItemContent) );
}
} // AquifyMenuBar
//
// InstallCommandEventHandler
//
// Grab our window and install an event handler to handle command events which are
// used to drive the action when the user chooses an item from a menu. We have to install
// it on the window because the menubar isn't in the event chain for a menu command event.
//
OSStatus
nsMenuBarX :: InstallCommandEventHandler ( )
{
OSStatus err = noErr;
// Install the command handler to deal with prefs/quit. We have to install it on the window because the
// menubar isn't in the event chain for a menu command event. Don't enable the prefs item
// just yet, wait until we actually find a pref node in the DOM.
WindowRef myWindow = NS_REINTERPRET_CAST(WindowRef, mParent->GetNativeData(NS_NATIVE_DISPLAY));
NS_ASSERTION ( myWindow, "Can't get WindowRef to install command handler!" );
if ( myWindow && sCommandEventHandler ) {
EventTypeSpec commandEventList[] = { {kEventClassCommand, kEventCommandProcess},
{kEventClassCommand, kEventCommandUpdateStatus} };
OSStatus err = ::InstallWindowEventHandler ( myWindow, sCommandEventHandler, 2, commandEventList, this, NULL );
const EventTypeSpec commandEventList[] = { {kEventClassCommand, kEventCommandProcess},
{kEventClassCommand, kEventCommandUpdateStatus} };
err = ::InstallWindowEventHandler ( myWindow, sCommandEventHandler, 2, commandEventList, this, NULL );
NS_ASSERTION ( err == noErr, "Uh oh, command handler not installed" );
}
} // AquifyMenuBar
return err;
} // InstallCommandEventHandler
//
@ -292,9 +302,6 @@ nsMenuBarX :: AquifyMenuBar ( )
//
// Processes Command carbon events from enabling/selecting of items in the menu.
//
// NOTE: eventually, all menu dispatching will go through this routine, for now, we only
// dispatch prefs and quit this way
//
pascal OSStatus
nsMenuBarX :: CommandEventHandler ( EventHandlerCallRef inHandlerChain, EventRef inEvent, void* userData )
{
@ -327,12 +334,36 @@ nsMenuBarX :: CommandEventHandler ( EventHandlerCallRef inHandlerChain, EventRef
handled = noErr;
break;
}
#if NOT_YET
case kHICommandAbout:
{
// the 'about' command is special because we don't have a nsIMenu or nsIMenuItem
// for the apple menu. Grovel for the content node with an id of "aboutName"
// and call it directly.
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(self->mDocument);
if ( xulDoc ) {
nsCOMPtr<nsIDOMElement> domElement;
xulDoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(domElement));
nsCOMPtr<nsIContent> aboutContent ( do_QueryInterface(domElement) );
self->ExecuteCommand(aboutContent);
}
handled = noErr;
break;
#endif
}
default:
{
// given the commandID, look it up in our hashtable and dispatch to
// that content node. Recall that we store weak pointers to the content
// nodes in the hash table.
nsPRUint32Key key ( command.commandID );
nsIMenuItem* content = NS_REINTERPRET_CAST(nsIMenuItem*, self->mObserverTable.Get(&key));
if ( content )
content->DoCommand();
handled = noErr;
break;
}
} // switch on commandID
break;
}
@ -410,9 +441,6 @@ nsMenuBarX :: HideItem ( nsIDOMDocument* inDoc, nsAReadableString & inID, nsICon
} // HideItem
#endif
nsEventStatus
nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
void * menubarNode, void * aWebShell )
@ -426,14 +454,15 @@ nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWin
Create(aParentWindow);
#if TARGET_CARBON
// if we're on X (using aqua UI guidelines for menus), remove quit and prefs
// from our menubar.
SInt32 result = 0L;
OSStatus err = ::Gestalt ( gestaltMenuMgrAttr, &result );
if ( !err && (result & gestaltMenuMgrAquaLayoutMask) )
AquifyMenuBar();
#endif
err = InstallCommandEventHandler();
if ( err )
return nsEventStatus_eIgnore;
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (webShell) RegisterAsDocumentObserver(webShell);
@ -613,6 +642,8 @@ nsMenuBarX :: CreateAppleMenu ( nsIMenu* inMenu )
::CFRelease(labelRef);
}
::SetMenuItemCommandID(sAppleMenu, 1, kHICommandAbout);
::AppendMenu(sAppleMenu, "\p-");
}
@ -937,6 +968,56 @@ nsMenuBarX :: Lookup ( nsIContent *aContent, nsIChangeObserver **_retval )
#pragma mark -
//
// Implementation methods for nsIMenuCommandDispatcher
//
//
// Register
//
// Given a menu item, creates a unique 4-character command ID and
// maps it to the item. Returns the id for use by the client.
//
NS_IMETHODIMP
nsMenuBarX :: Register ( nsIMenuItem* inMenuItem, PRUint32* outCommandID )
{
// no real need to check for uniqueness. We always start afresh with each
// window at 1. Even if we did get close to the reserved Apple command id's,
// those don't start until at least ' ', which is integer 538976288. If
// we have that many menu items in one window, I think we have other problems.
// put it in the table, set out param for client
nsPRUint32Key key ( mCurrentCommandID );
mObserverTable.Put ( &key, inMenuItem );
*outCommandID = mCurrentCommandID;
// make id unique for next time
++mCurrentCommandID;
return NS_OK;
}
//
// Unregister
//
// Removes the mapping between the given 4-character command ID
// and its associated menu item.
//
NS_IMETHODIMP
nsMenuBarX :: Unregister ( PRUint32 inCommandID )
{
nsPRUint32Key key ( inCommandID );
mObserverTable.Remove ( &key );
return NS_OK;
}
#pragma mark -
//
// WebShellToPresContext
//

View File

@ -42,6 +42,7 @@
#include "nsIMenuListener.h"
#include "nsIDocumentObserver.h"
#include "nsIChangeManager.h"
#include "nsIMenuCommandDispatcher.h"
#include "nsIPresContext.h"
#include "nsSupportsArray.h"
#include "nsVoidArray.h"
@ -76,6 +77,7 @@ class nsMenuBarX : public nsIMenuBar,
public nsIMenuListener,
public nsIDocumentObserver,
public nsIChangeManager,
public nsIMenuCommandDispatcher,
public nsSupportsWeakReference
{
public:
@ -86,6 +88,7 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEMANAGER
NS_DECL_NSIMENUCOMMANDDISPATCHER
// nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
@ -171,30 +174,29 @@ protected:
void GetDocument ( nsIWebShell* inWebShell, nsIDocument** outDocument ) ;
void RegisterAsDocumentObserver ( nsIWebShell* inWebShell ) ;
#if TARGET_CARBON
// Make our menubar conform to Aqua UI guidelines
void AquifyMenuBar ( ) ;
void HideItem ( nsIDOMDocument* inDoc, nsAReadableString & inID, nsIContent** outHiddenNode ) ;
OSStatus InstallCommandEventHandler ( ) ;
// command handler for some special menu items (prefs/quit/etc)
pascal static OSStatus CommandEventHandler ( EventHandlerCallRef inHandlerChain,
EventRef inEvent, void* userData ) ;
nsEventStatus ExecuteCommand ( nsIContent* inDispatchTo ) ;
#endif
// build the Apple menu shared by all menu bars.
nsresult CreateAppleMenu ( nsIMenu* inMenu ) ;
nsHashtable mObserverTable; // stores observers for content change notification
nsHashtable mCommandMapTable; // maps CommandIDs to content nodes for CarbonEvent item selection
PRUint32 mCurrentCommandID; // unique command id (per menu-bar) to give to next item that asks
PRUint32 mNumMenus;
nsSupportsArray mMenusArray; // holds refs
nsCOMPtr<nsIContent> mMenuBarContent; // menubar content node, strong ref
#if TARGET_CARBON
nsCOMPtr<nsIContent> mPrefItemContent; // on X, holds the content node for the prefs item that has
// been removed from the menubar
nsCOMPtr<nsIContent> mQuitItemContent; // as above, but for quit
#endif
nsIWidget* mParent; // weak ref
PRBool mIsMenuBarAdded;
@ -206,9 +208,7 @@ protected:
static MenuRef sAppleMenu; // AppleMenu shared by all menubars
#if TARGET_CARBON
static EventHandlerUPP sCommandEventHandler; // carbon event handler for commands, shared
#endif
};
#endif // nsMenuBarX_h__

View File

@ -201,38 +201,14 @@ NS_METHOD nsMenuItemX::IsSeparator(PRBool & aIsSep)
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
switch ( mMenuType ) {
case eCheckbox:
SetChecked(!mIsChecked);
break;
case eRadio:
{
// we only want to muck with things if we were selected and we're not
// already checked.
if ( mIsChecked )
break;
SetChecked(PR_TRUE);
break;
}
case eRegular:
break; // do nothing special
} // which menu type
DoCommand();
// this is all handled by Carbon Events
return nsEventStatus_eConsumeNoDefault;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItemX::MenuSelected(const nsMenuEvent & aMenuEvent)
{
//if(mXULCommandListener)
// return mXULCommandListener->MenuSelected(aMenuEvent);
DoCommand();
return nsEventStatus_eIgnore;
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
@ -309,7 +285,7 @@ NS_METHOD nsMenuItemX::DoCommand()
}
else
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return nsEventStatus_eConsumeNoDefault;
}

View File

@ -52,6 +52,7 @@
#include "nsIMenuItem.h"
#include "nsIMenuListener.h"
#include "nsIPresContext.h"
#include "nsIMenuCommandDispatcher.h"
#include "nsString.h"
#include "nsReadableUtils.h"
@ -293,6 +294,15 @@ NS_METHOD nsMenuX::AddMenuItem(nsIMenuItem * aMenuItem)
::SetMenuItemModifiers(mMacMenuHandle, currItemIndex, macModifiers);
// set its command. we get the unique command id from the menubar
nsCOMPtr<nsIMenuCommandDispatcher> dispatcher ( do_QueryInterface(mManager) );
if ( dispatcher ) {
PRUint32 commandID = 0L;
dispatcher->Register(aMenuItem, &commandID);
if ( commandID )
::SetMenuItemCommandID(mMacMenuHandle, currItemIndex, commandID);
}
PRBool isEnabled;
aMenuItem->GetEnabled(&isEnabled);
if(isEnabled)
@ -412,8 +422,20 @@ NS_METHOD nsMenuX::RemoveItem(const PRUint32 aPos)
//-------------------------------------------------------------------------
NS_METHOD nsMenuX::RemoveAll()
{
if (mMacMenuHandle != NULL)
if (mMacMenuHandle != NULL) {
// clear command id's
nsCOMPtr<nsIMenuCommandDispatcher> dispatcher ( do_QueryInterface(mManager) );
if ( dispatcher ) {
for ( int i = 1; i <= mNumMenuItems; ++i ) {
PRUint32 commandID = 0L;
OSErr err = ::GetMenuItemCommandID(mMacMenuHandle, i, (unsigned long*)&commandID);
if ( !err )
dispatcher->Unregister(commandID);
}
}
::DeleteMenuItems(mMacMenuHandle, 1, ::CountMenuItems(mMacMenuHandle));
}
mMenuItemsArray.Clear(); // remove all items
return NS_OK;
}
@ -455,110 +477,8 @@ NS_METHOD nsMenuX::RemoveMenuListener(nsIMenuListener * aMenuListener)
//-------------------------------------------------------------------------
nsEventStatus nsMenuX::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
//printf("MenuItemSelected called \n");
nsEventStatus eventStatus = nsEventStatus_eIgnore;
// Determine if this is the correct menu to handle the event. We can't use
// the HiWord of the command because of MenuSelect bugs in Carbon. Use
// the menuID we've been tracking manually instead. However, we don't get
// the carbon events for the apple menu, so if MenuSelect() tells us we've hit
// the apple menu (where there are no submenus we care about), it is
// actually correct and |gCurrentlyTrackedMenuID| is wrong. Go figure.
MenuID probablyWrongMenuID = HiWord(((nsMenuEvent)aMenuEvent).mCommand);
if ( probablyWrongMenuID == nsMenuBarX::kAppleMenuID )
gCurrentlyTrackedMenuID = nsMenuBarX::kAppleMenuID;
MenuID menuID = gCurrentlyTrackedMenuID;
if( menuID == nsMenuBarX::kAppleMenuID ) {
PRInt16 menuItemID = LoWord(((nsMenuEvent)aMenuEvent).mCommand);
if (menuItemID == 1) {
/* handle about app here */
nsresult rv = NS_ERROR_FAILURE;
// Go find the about menu item
if (!mMenuContent)
return nsEventStatus_eConsumeNoDefault;
nsCOMPtr<nsIDocument> doc;
mMenuContent->GetDocument(*getter_AddRefs(doc));
if (!doc)
return nsEventStatus_eConsumeNoDefault;
nsCOMPtr<nsIDOMXULDocument> xulDoc = do_QueryInterface(doc);
if (!xulDoc) {
NS_ERROR("nsIDOMDocument to nsIDOMXULDocument QI failed.");
return nsEventStatus_eConsumeNoDefault;
}
// "aboutName" is the element id for the "About &shortBrandName;"
// <menuitem/>. This is the glue code which causes any script code
// in the <menuitem/> to be executed.
nsCOMPtr<nsIDOMElement> domElement;
xulDoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(domElement));
if (!domElement)
return nsEventStatus_eConsumeNoDefault;
// Now get the pres context so we can execute the command
nsCOMPtr<nsIWebShell> webShell = do_QueryReferent(mWebShellWeakRef);
if (!webShell)
return nsEventStatus_eConsumeNoDefault;
nsCOMPtr<nsIPresContext> presContext;
MenuHelpersX::WebShellToPresContext(webShell, getter_AddRefs(presContext));
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event;
event.eventStructType = NS_MOUSE_EVENT;
event.message = NS_XUL_COMMAND;
nsCOMPtr<nsIContent> contentNode = do_QueryInterface(domElement);
if (!contentNode)
return nsEventStatus_eConsumeNoDefault;
rv = contentNode->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return nsEventStatus_eConsumeNoDefault;
}
}
else if (mMacMenuID == menuID)
{
// Call MenuItemSelected on the correct nsMenuItem
PRInt16 menuItemID = LoWord(((nsMenuEvent)aMenuEvent).mCommand);
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenuItemsArray.ElementAt(menuItemID - 1));
NS_ASSERTION(menuSupports, "Somehow our item list was torn down prematurely");
nsCOMPtr<nsIMenuListener> menuListener = do_QueryInterface(menuSupports);
if (menuListener)
{
// call our ondestroy handler now because the menu is going away.
// do it now before sending the event into the dom in case our window
// goes away.
OnDestroy();
eventStatus = menuListener->MenuItemSelected(aMenuEvent);
if(nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
// Make sure none of our submenus are the ones that should be handling this
PRUint32 numItems;
mMenuItemsArray.Count(&numItems);
for (PRUint32 i = numItems; i > 0; i--)
{
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenuItemsArray.ElementAt(i - 1));
nsCOMPtr<nsIMenu> submenu = do_QueryInterface(menuSupports);
nsCOMPtr<nsIMenuListener> menuListener = do_QueryInterface(submenu);
if (menuListener)
{
// call our ondestroy handler now because the menu is going away.
// do it now before sending the event into the dom in case our window
// goes away.
OnDestroy();
eventStatus = menuListener->MenuItemSelected(aMenuEvent);
if(nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
return eventStatus;
// all this is now handled by Carbon Events.
return nsEventStatus_eConsumeNoDefault;
}
//-------------------------------------------------------------------------

View File

@ -143,9 +143,7 @@ protected:
nsSupportsArray mMenuItemsArray; // array holds refs
nsISupports* mParent; // weak, my parent owns me
// nsIMenu* mMenuParent;
// nsIMenuBar* mMenuBarParent;
nsIChangeManager* mManager; // weak ref, it will outlive us
nsIChangeManager* mManager; // weak ref, it will outlive us [menubar]
nsWeakPtr mWebShellWeakRef; // weak ref to webshell
nsCOMPtr<nsIContent> mMenuContent; // the |menu| tag, strong ref
nsCOMPtr<nsIMenuListener> mListener; // strong ref