handle hidden window menu bar and menu bar switching in general better. gets rid of a lot of crashes. b=330586 r=pav

git-svn-id: svn://10.0.0.236/trunk@193674 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
joshmoz%gmail.com
2006-04-06 07:41:34 +00:00
parent 9d428a4bd0
commit f482ae90c3
5 changed files with 88 additions and 14 deletions

View File

@@ -71,6 +71,7 @@ REQUIRES = xpcom \
mimetype \
unicharutil \
exthandler \
appshell \
$(NULL)
ifdef MOZ_ENABLE_CAIRO_GFX

View File

@@ -38,6 +38,7 @@
#include "nsCocoaWindow.h"
#include "nsCOMPtr.h"
#include "nsIServiceManager.h" // for drag and drop
#include "nsWidgetsCID.h"
#include "nsIDragService.h"
@@ -48,7 +49,12 @@
#include "nsGUIEvent.h"
#include "nsMacResources.h"
#include "nsIRollupListener.h"
#import "nsChildView.h"
#include "nsChildView.h"
#include "nsIAppShell.h"
#include "nsIAppShellService.h"
#include "nsIBaseWindow.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIXULWindow.h"
#include "nsIEventQueueService.h"
@@ -59,6 +65,11 @@ static NS_DEFINE_CID(kCDragServiceCID, NS_DRAGSERVICE_CID);
extern nsIRollupListener * gRollupListener;
extern nsIWidget * gRollupWidget;
#define NS_APPSHELLSERVICE_CONTRACTID "@mozilla.org/appshell/appShellService;1"
// call getHiddenWindowNativeMenu, don't use this directly
static nsIMenuBar* gHiddenWindowMenuBar = nsnull;
NS_IMPL_ISUPPORTS_INHERITED0(nsCocoaWindow, Inherited)
@@ -142,6 +153,48 @@ nsCocoaWindow::~nsCocoaWindow()
}
static nsIMenuBar* GetHiddenWindowMenuBar()
{
if (gHiddenWindowMenuBar)
return gHiddenWindowMenuBar;
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
if (!appShell) {
NS_WARNING("Couldn't get AppShellService in order to get hidden window ref");
return NULL;
}
nsCOMPtr<nsIXULWindow> hiddenWindow;
appShell->GetHiddenWindow(getter_AddRefs(hiddenWindow));
if (!hiddenWindow) {
NS_WARNING("Couldn't get hidden window from appshell");
return NULL;
}
nsCOMPtr<nsIBaseWindow> baseHiddenWindow;
baseHiddenWindow = do_GetInterface(hiddenWindow);
if (!baseHiddenWindow) {
NS_WARNING("Couldn't get nsIBaseWindow from hidden window (nsIXULWindow)");
return NULL;
}
nsCOMPtr<nsIWidget> hiddenWindowWidget;
if (NS_FAILED(baseHiddenWindow->GetMainWidget(getter_AddRefs(hiddenWindowWidget)))) {
NS_WARNING("Couldn't get nsIWidget from hidden window (nsIBaseWindow)");
return NULL;
}
nsIWidget* hiddenWindowWidgetNoCOMPtr = hiddenWindowWidget;
nsIMenuBar* geckoMenuBar = NS_STATIC_CAST(nsCocoaWindow*, hiddenWindowWidgetNoCOMPtr)->GetMenuBar();
if (geckoMenuBar) {
gHiddenWindowMenuBar = geckoMenuBar;
}
return gHiddenWindowMenuBar;
}
//-------------------------------------------------------------------------
//
// Utility method for implementing both Create(nsIWidget ...) and
@@ -397,14 +450,16 @@ nsCocoaWindow::IsVisible(PRBool & aState)
//-------------------------------------------------------------------------
NS_IMETHODIMP nsCocoaWindow::Show(PRBool bState)
{
if (bState)
[mWindow orderFront:NULL];
else
[mWindow orderOut:NULL];
mVisible = bState;
return NS_OK;
if (bState) {
[mWindow orderFront:NULL];
}
else {
[mWindow orderOut:NULL];
}
mVisible = bState;
return NS_OK;
}
@@ -737,8 +792,10 @@ NS_IMETHODIMP nsCocoaWindow::CaptureRollupEvents(nsIRollupListener * aListener,
- (void)windowDidBecomeMain:(NSNotification *)aNotification
{
nsIMenuBar* myMenuBar = mGeckoWindow->GetMenuBar();
if (myMenuBar)
if (myMenuBar) {
// printf("painting window menu bar due to window becoming main\n");
myMenuBar->Paint();
}
nsGUIEvent guiEvent(PR_TRUE, NS_GOTFOCUS, mGeckoWindow);
guiEvent.time = PR_IntervalNow();
@@ -753,6 +810,12 @@ NS_IMETHODIMP nsCocoaWindow::CaptureRollupEvents(nsIRollupListener * aListener,
if (gRollupListener != nsnull && gRollupWidget != nsnull)
gRollupListener->Rollup();
nsCOMPtr<nsIMenuBar> hiddenWindowMenuBar = GetHiddenWindowMenuBar();
if (hiddenWindowMenuBar) {
// printf("painting hidden window menu bar due to nsCocoaWindow::Show(false)\n");
hiddenWindowMenuBar->Paint();
}
// tell Gecko that we lost focus
nsGUIEvent guiEvent(PR_TRUE, NS_LOSTFOCUS, mGeckoWindow);
guiEvent.time = PR_IntervalNow();

View File

@@ -98,6 +98,8 @@ public:
// |NSMenuItem|s target Objective-C objects
static NativeMenuItemTarget* sNativeEventTarget;
static NSWindow* sEventTargetWindow;
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEMANAGER
NS_DECL_NSIMENUCOMMANDDISPATCHER

View File

@@ -74,6 +74,7 @@ NS_IMPL_ISUPPORTS6(nsMenuBarX, nsIMenuBar, nsIMenuListener, nsIDocumentObserver,
NSMenu* nsMenuBarX::sApplicationMenu = nsnull;
EventHandlerUPP nsMenuBarX::sCommandEventHandler = nsnull;
NativeMenuItemTarget* nsMenuBarX::sNativeEventTarget = nil;
NSWindow* nsMenuBarX::sEventTargetWindow = nil;
nsMenuBarX::nsMenuBarX()
@@ -97,7 +98,7 @@ nsMenuBarX::~nsMenuBarX()
mDocument->RemoveObserver(observer);
}
[mRootMenu release];
[mRootMenu autorelease];
}
nsEventStatus
@@ -809,7 +810,8 @@ NS_IMETHODIMP nsMenuBarX::Paint()
[[mRootMenu itemAtIndex:0] setSubmenu:sApplicationMenu];
}
[NSApp setMainMenu:mRootMenu];
[NSApp setMainMenu:mRootMenu];
nsMenuBarX::sEventTargetWindow = (NSWindow*)mParent->GetNativeData(NS_NATIVE_WINDOW);
return NS_OK;
}
@@ -1135,6 +1137,12 @@ unsigned int MenuHelpersX::MacModifiersForGeckoModifiers(PRUint8 geckoModifiers)
// called when some menu item in this menu gets hit
-(IBAction)menuItemHit:(id)sender
{
// just abort if we don't have a target window for events
if (!nsMenuBarX::sEventTargetWindow) {
NS_WARNING("No target window for keyboard events!");
return;
}
MenuRef senderMenuRef = _NSGetCarbonMenu([sender menu]);
int senderCarbonMenuItemIndex = [[sender menu] indexOfItem:sender] + 1;
@@ -1159,7 +1167,7 @@ unsigned int MenuHelpersX::MacModifiersForGeckoModifiers(PRUint8 geckoModifiers)
if (err == noErr) {
err = ::SetEventParameter(newEvent, kEventParamDirectObject, typeHICommand, sizeof(HICommand), &menuHICommand);
if (err == noErr) {
err = ::SendEventToEventTarget(newEvent, GetWindowEventTarget((WindowRef)[[NSApp keyWindow] windowRef]));
err = ::SendEventToEventTarget(newEvent, GetWindowEventTarget((WindowRef)[nsMenuBarX::sEventTargetWindow windowRef]));
NS_ASSERTION(err == noErr, "Carbon event for menu hit not sent!");
}
}

View File

@@ -76,7 +76,7 @@ nsMenuItemX::nsMenuItemX()
nsMenuItemX::~nsMenuItemX()
{
[mNativeMenuItem release];
[mNativeMenuItem autorelease];
mManager->Unregister(mContent);
}