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:
@@ -71,6 +71,7 @@ REQUIRES = xpcom \
|
||||
mimetype \
|
||||
unicharutil \
|
||||
exthandler \
|
||||
appshell \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_CAIRO_GFX
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ nsMenuItemX::nsMenuItemX()
|
||||
|
||||
nsMenuItemX::~nsMenuItemX()
|
||||
{
|
||||
[mNativeMenuItem release];
|
||||
[mNativeMenuItem autorelease];
|
||||
mManager->Unregister(mContent);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user