зеркало из https://github.com/mozilla/pjs.git
Bug 436063 - Don't manually build the window list in the Dock menu. Instead call [NSApp setWindowsMenu:] during startup so that Cocoa will build the list for us. r=josh
This commit is contained in:
Родитель
481331354a
Коммит
a1c21c98d2
|
@ -48,10 +48,7 @@
|
|||
#import <Carbon/Carbon.h>
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsINativeAppSupport.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsAppRunner.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsCommandLineServiceMac.h"
|
||||
|
@ -104,7 +101,7 @@ SetupMacApplicationDelegate()
|
|||
|
||||
// Create the delegate. This should be around for the lifetime of the app.
|
||||
MacApplicationDelegate *delegate = [[MacApplicationDelegate alloc] init];
|
||||
[[NSApplication sharedApplication] setDelegate:delegate];
|
||||
[NSApp setDelegate:delegate];
|
||||
|
||||
[pool release];
|
||||
|
||||
|
@ -129,6 +126,14 @@ SetupMacApplicationDelegate()
|
|||
andSelector:@selector(handleAppleEvent:withReplyEvent:)
|
||||
forEventClass:'WWW!'
|
||||
andEventID:'OURL'];
|
||||
|
||||
if (![NSApp windowsMenu]) {
|
||||
// If the application has a windows menu, it will keep it up to date and
|
||||
// prepend the window list to the Dock menu automatically.
|
||||
NSMenu* windowsMenu = [[NSMenu alloc] initWithTitle:@"Window"];
|
||||
[NSApp setWindowsMenu:windowsMenu];
|
||||
[windowsMenu release];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
||||
|
@ -205,92 +210,19 @@ SetupMacApplicationDelegate()
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
// Drill down from nsIXULWindow and get an NSWindow. We get passed nsISupports
|
||||
// because that's what nsISimpleEnumerator returns.
|
||||
|
||||
static NSWindow* GetCocoaWindowForXULWindow(nsISupports *aXULWindow)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(aXULWindow, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
rv = baseWindow->GetMainWidget(getter_AddRefs(widget));
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
// If it fails, we return nil anyway, no biggie
|
||||
return (NSWindow *)widget->GetNativeData(NS_NATIVE_WINDOW);
|
||||
}
|
||||
|
||||
// Create the menu that shows up in the Dock.
|
||||
|
||||
- (NSMenu*)applicationDockMenu:(NSApplication*)sender
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
// Why we're not just using Cocoa to enumerate our windows:
|
||||
// The Dock thinks we're a Carbon app, probably because we don't have a
|
||||
// blessed Window menu, so we get none of the automatic handling for dock
|
||||
// menus that Cocoa apps get. Add in Cocoa being a bit braindead when you hide
|
||||
// the app, and we end up having to get our list of windows via XPCOM. Ugh.
|
||||
|
||||
// Get the window mediator to do all our lookups.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIWindowMediator> wm = do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
|
||||
// Get the frontmost window
|
||||
nsCOMPtr<nsISimpleEnumerator> orderedWindowList;
|
||||
rv = wm->GetZOrderXULWindowEnumerator(nsnull, PR_TRUE,
|
||||
getter_AddRefs(orderedWindowList));
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
PRBool anyWindows = false;
|
||||
rv = orderedWindowList->HasMoreElements(&anyWindows);
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
nsCOMPtr<nsISupports> frontWindow;
|
||||
rv = orderedWindowList->GetNext(getter_AddRefs(frontWindow));
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
|
||||
// Get our list of windows and prepare to iterate. We use this list, ordered
|
||||
// by window creation date, instead of the z-ordered list because that's what
|
||||
// native apps do.
|
||||
nsCOMPtr<nsISimpleEnumerator> windowList;
|
||||
rv = wm->GetXULWindowEnumerator(nsnull, getter_AddRefs(windowList));
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
|
||||
// Create the NSMenu that will contain the dock menu items.
|
||||
NSMenu *menu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||
[menu setAutoenablesItems:NO];
|
||||
|
||||
// Iterate through our list of windows to create our menu
|
||||
PRBool more;
|
||||
while (NS_SUCCEEDED(windowList->HasMoreElements(&more)) && more) {
|
||||
// Get our native window
|
||||
nsCOMPtr<nsISupports> xulWindow;
|
||||
rv = windowList->GetNext(getter_AddRefs(xulWindow));
|
||||
NS_ENSURE_SUCCESS(rv, nil);
|
||||
NSWindow *cocoaWindow = GetCocoaWindowForXULWindow(xulWindow);
|
||||
if (!cocoaWindow) continue;
|
||||
|
||||
NSString *windowTitle = [cocoaWindow title];
|
||||
if (!windowTitle) continue;
|
||||
|
||||
// Now, create a menu item, and add it to the menu
|
||||
NSMenuItem *menuItem = [[NSMenuItem alloc]
|
||||
initWithTitle:windowTitle
|
||||
action:@selector(dockMenuItemSelected:)
|
||||
keyEquivalent:@""];
|
||||
[menuItem setTarget:self];
|
||||
[menuItem setRepresentedObject:cocoaWindow];
|
||||
|
||||
// If this is the foreground window, put a checkmark next to it
|
||||
if (SameCOMIdentity(xulWindow, frontWindow))
|
||||
[menuItem setState:NSOnState];
|
||||
|
||||
[menu addItem:menuItem];
|
||||
[menuItem release];
|
||||
}
|
||||
|
||||
// Add application-specific dock menu items. On error, do not insert the
|
||||
// dock menu items.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMacDockSupport> dockSupport = do_GetService("@mozilla.org/widget/macdocksupport;1", &rv);
|
||||
if (NS_FAILED(rv) || !dockSupport)
|
||||
return menu;
|
||||
|
@ -332,18 +264,6 @@ static NSWindow* GetCocoaWindowForXULWindow(nsISupports *aXULWindow)
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
// One of our dock menu items was selected
|
||||
- (void)dockMenuItemSelected:(id)sender
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
// Our represented object is an NSWindow
|
||||
[[sender representedObject] makeKeyAndOrderFront:nil];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
// If we don't handle applicationShouldTerminate:, a call to [NSApp terminate:]
|
||||
// (from the browser or from the OS) can result in an unclean shutdown.
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
|
|
Загрузка…
Ссылка в новой задаче