summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/nibs/en.lproj/MainMenu.xib82
-rw-r--r--chrome/browser/app_controller_mac.h7
-rw-r--r--chrome/browser/app_controller_mac.mm112
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm5
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.h4
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm12
-rw-r--r--chrome/browser/cocoa/tab_strip_controller_unittest.mm7
7 files changed, 182 insertions, 47 deletions
diff --git a/chrome/app/nibs/en.lproj/MainMenu.xib b/chrome/app/nibs/en.lproj/MainMenu.xib
index 1e452d8..e0a917c 100644
--- a/chrome/app/nibs/en.lproj/MainMenu.xib
+++ b/chrome/app/nibs/en.lproj/MainMenu.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">352.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="111"/>
+ <integer value="81"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -305,7 +305,8 @@
<object class="NSMenuItem" id="776162233">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Close Window</string>
- <string key="NSKeyEquiv"/>
+ <string key="NSKeyEquiv">w</string>
+ <int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="353210768"/>
<reference key="NSMixedImage" ref="549394948"/>
@@ -313,8 +314,7 @@
<object class="NSMenuItem" id="1059729334">
<reference key="NSMenu" ref="720053764"/>
<string key="NSTitle">Close Tab</string>
- <string key="NSKeyEquiv">w</string>
- <int key="NSKeyEquivModMask">1048576</int>
+ <string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="353210768"/>
<reference key="NSMixedImage" ref="549394948"/>
@@ -1573,6 +1573,22 @@
<int key="connectionID">615</int>
</object>
<object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">closeWindowMenuItem_</string>
+ <reference key="source" ref="168151378"/>
+ <reference key="destination" ref="776162233"/>
+ </object>
+ <int key="connectionID">622</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">closeTabMenuItem_</string>
+ <reference key="source" ref="168151378"/>
+ <reference key="destination" ref="1059729334"/>
+ </object>
+ <int key="connectionID">623</int>
+ </object>
+ <object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">orderFrontStandardAboutPanel:</string>
<reference key="source" ref="168151378"/>
@@ -2669,7 +2685,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<integer value="1" id="9"/>
- <string>{{929, 698}, {190, 23}}</string>
+ <string>{{715, 938}, {190, 23}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>{{596, 852}, {216, 23}}</string>
@@ -2779,7 +2795,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>{{525, 802}, {197, 73}}</string>
- <string>{{398, 662}, {535, 20}}</string>
+ <string>{{539, 1064}, {535, 20}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>{74, 862}</string>
@@ -2879,7 +2895,7 @@
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
- <string>{{561, 418}, {249, 303}}</string>
+ <string>{{645, 761}, {249, 303}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>{{323, 672}, {199, 203}}</string>
@@ -2911,49 +2927,12 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">619</int>
+ <int key="maxID">623</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
- <string key="className">AboutController</string>
- <string key="superclassName">NSWindowController</string>
- <object class="NSMutableDictionary" key="actions">
- <string key="NS.key.0">updateNow:</string>
- <string key="NS.object.0">id</string>
- </object>
- <object class="NSMutableDictionary" key="outlets">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSMutableArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>spinner_</string>
- <string>upToDate_</string>
- <string>updateCompleted_</string>
- <string>version_</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>NSProgressIndicator</string>
- <string>NSTextField</string>
- <string>NSTextField</string>
- <string>NSTextField</string>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">browser/cocoa/about_controller.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">AboutController</string>
- <string key="superclassName">NSWindowController</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBUserSource</string>
- <string key="minorKey"/>
- </object>
- </object>
- <object class="IBPartialClassDescription">
<string key="className">AppController</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="actions">
@@ -2972,8 +2951,17 @@
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
- <string key="NS.key.0">aboutController_</string>
- <string key="NS.object.0">AboutController</string>
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>closeTabMenuItem_</string>
+ <string>closeWindowMenuItem_</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSMenuItem</string>
+ <string>NSMenuItem</string>
+ </object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h
index bf2aebc..e47bc00 100644
--- a/chrome/browser/app_controller_mac.h
+++ b/chrome/browser/app_controller_mac.h
@@ -34,6 +34,13 @@ class Profile;
// only needed during early startup, it points to a valid vector during early
// startup and is NULL during the rest of app execution.
scoped_ptr<std::vector<GURL> > pendingURLs_;
+
+ // Outlets for the close tab/window menu items so that we can adjust the
+ // commmand-key equivalent depending on the kind of window and how many
+ // tabs it has.
+ IBOutlet NSMenuItem* closeTabMenuItem_;
+ IBOutlet NSMenuItem* closeWindowMenuItem_;
+ BOOL fileMenuUpdatePending_; // ensure we only do this once per notificaion.
}
- (IBAction)quit:(id)sender;
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 436fa6c..fbf2ef0 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -17,6 +17,8 @@
#import "chrome/browser/cocoa/encoding_menu_controller_delegate_mac.h"
#import "chrome/browser/cocoa/menu_localizer.h"
#import "chrome/browser/cocoa/preferences_window_controller.h"
+#import "chrome/browser/cocoa/tab_strip_controller.h"
+#import "chrome/browser/cocoa/tab_window_controller.h"
#include "chrome/browser/command_updater.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
@@ -31,6 +33,7 @@
withReply:(NSAppleEventDescriptor*)reply;
- (void)openFiles:(NSAppleEventDescriptor*)event
withReply:(NSAppleEventDescriptor*)reply;
+- (void)windowLayeringDidChange:(NSNotification*)inNotification;
@end
@implementation AppController
@@ -56,10 +59,119 @@
forEventClass:kCoreEventClass
andEventID:kAEOpenDocuments];
+ // Register for various window layering changes. We use these to update
+ // various UI elements (command-key equivalents, etc) when the frontmost
+ // window changes.
+ NSNotificationCenter* notificationCenter =
+ [NSNotificationCenter defaultCenter];
+ [notificationCenter
+ addObserver:self
+ selector:@selector(windowLayeringDidChange:)
+ name:NSWindowDidBecomeKeyNotification
+ object:nil];
+ [notificationCenter
+ addObserver:self
+ selector:@selector(windowLayeringDidChange:)
+ name:NSWindowDidResignKeyNotification
+ object:nil];
+ [notificationCenter
+ addObserver:self
+ selector:@selector(windowLayeringDidChange:)
+ name:NSWindowDidBecomeMainNotification
+ object:nil];
+ [notificationCenter
+ addObserver:self
+ selector:@selector(windowLayeringDidChange:)
+ name:NSWindowDidResignMainNotification
+ object:nil];
+
+ // Register for a notification that the number of tabs changes in windows
+ // so we can adjust the close tab/window command keys.
+ [notificationCenter
+ addObserver:self
+ selector:@selector(tabsChanged:)
+ name:kTabStripNumberOfTabsChanged
+ object:nil];
+
// Set up the command updater for when there are no windows open
[self initMenuState];
}
+// Called when the app is shutting down. Clean-up as appropriate.
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+// Helper routine to get the window controller if the key window is a tabbed
+// window, or nil if not. Examples of non-tabbed windows are "about" or
+// "preferences".
+- (TabWindowController*)keyWindowTabController {
+ NSWindowController* keyWindowController =
+ [[[NSApplication sharedApplication] keyWindow] windowController];
+ if ([keyWindowController isKindOfClass:[TabWindowController class]])
+ return (TabWindowController*)keyWindowController;
+
+ return nil;
+}
+
+// If the window has tabs, make "close window" be cmd-shift-w, otherwise leave
+// it as the normal cmd-w. Capitalization of the key equivalent affects whether
+// the shift modifer is used.
+- (void)adjustCloseWindowMenuItemKeyEquivalent:(BOOL)inHaveTabs {
+ [closeWindowMenuItem_ setKeyEquivalent:(inHaveTabs ? @"W" : @"w")];
+}
+
+// If the window has tabs, make "close tab" take over cmd-w, otherwise it
+// shouldn't have any key-equivalent because it should be disabled.
+- (void)adjustCloseTabMenuItemKeyEquivalent:(BOOL)hasTabs {
+ if (hasTabs) {
+ [closeTabMenuItem_ setKeyEquivalent:@"w"];
+ [closeTabMenuItem_ setKeyEquivalentModifierMask:NSCommandKeyMask];
+ } else {
+ [closeTabMenuItem_ setKeyEquivalent:@""];
+ [closeTabMenuItem_ setKeyEquivalentModifierMask:0];
+ }
+}
+
+// See if we have a window with tabs open, and adjust the key equivalents for
+// Close Tab/Close Window accordingly
+- (void)fixCloseMenuItemKeyEquivalents {
+ TabWindowController* tabController = [self keyWindowTabController];
+ BOOL windowWithMultipleTabs =
+ (tabController && [tabController numberOfTabs] > 1);
+ [self adjustCloseWindowMenuItemKeyEquivalent:windowWithMultipleTabs];
+ [self adjustCloseTabMenuItemKeyEquivalent:windowWithMultipleTabs];
+ fileMenuUpdatePending_ = NO;
+}
+
+// Fix up the "close tab/close window" command-key equivalents. We do this
+// after a delay to ensure that window layer state has been set by the time
+// we do the enabling.
+- (void)delayedFixCloseMenuItemKeyEquivalents {
+ if (!fileMenuUpdatePending_) {
+ [self performSelector:@selector(fixCloseMenuItemKeyEquivalents)
+ withObject:nil
+ afterDelay:0];
+ fileMenuUpdatePending_ = YES;
+ }
+}
+
+// Called when we get a notification about the window layering changing to
+// update the UI based on the new main window.
+- (void)windowLayeringDidChange:(NSNotification*)notify {
+ [self delayedFixCloseMenuItemKeyEquivalents];
+
+ // TODO(pinkerton): If we have other things here, such as inspector panels
+ // that follow the contents of the selected webpage, we would update those
+ // here.
+}
+
+// Called when the number of tabs changes in one of the browser windows. The
+// object is the tab strip controller, but we don't currently care.
+- (void)tabsChanged:(NSNotification*)notify {
+ [self delayedFixCloseMenuItemKeyEquivalents];
+}
+
// If the auto-update interval is not set, make it 5 hours.
// This code is specific to Mac Chrome Dev Channel.
// Placed here for 2 reasons:
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index 2070be8..1129a6c 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -309,6 +309,11 @@ willPositionSheet:(NSWindow *)sheet
// Generate return value (enabled state)
enable = browser_->command_updater()->IsCommandEnabled(tag) ? YES : NO;
+ // Disable "close tab" if we're not the key window or if there's only
+ // one tab.
+ if (tag == IDC_CLOSE_TAB)
+ enable &= [self numberOfTabs] > 1 && [[self window] isKeyWindow];
+
// If the item is toggleable, find it's toggle state and
// try to update it. This is a little awkward, but the alternative is
// to check after a commandDispatch, which seems worse.
diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h
index eeab6b0..6004768 100644
--- a/chrome/browser/cocoa/tab_strip_controller.h
+++ b/chrome/browser/cocoa/tab_strip_controller.h
@@ -106,4 +106,8 @@ class ToolbarModel;
+ (CGFloat)defaultTabHeight;
@end
+// Notification sent when the number of tabs changes. The object will be this
+// controller.
+extern NSString* const kTabStripNumberOfTabsChanged;
+
#endif // CHROME_BROWSER_COCOA_TAB_STRIP_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
index 6fed79f..b81b455 100644
--- a/chrome/browser/cocoa/tab_strip_controller.mm
+++ b/chrome/browser/cocoa/tab_strip_controller.mm
@@ -22,6 +22,8 @@
#include "chrome/browser/tabs/tab_strip_model.h"
#include "grit/generated_resources.h"
+NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged";
+
// A simple view class that prevents the windowserver from dragging the
// area behind tabs. Sometimes core animation confuses it.
@interface TabStripControllerDragBlockingView : NSView
@@ -337,6 +339,11 @@
if (!inForeground) {
[self layoutTabs];
}
+
+ // Send a broadcast that the number of tabs have changed.
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:kTabStripNumberOfTabsChanged
+ object:self];
}
// Called when a notification is received from the model to select a particular
@@ -397,6 +404,11 @@
// Once we're totally done with the tab, delete its controller
[tabArray_ removeObjectAtIndex:index];
+ // Send a broadcast that the number of tabs have changed.
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:kTabStripNumberOfTabsChanged
+ object:self];
+
[self layoutTabs];
}
diff --git a/chrome/browser/cocoa/tab_strip_controller_unittest.mm b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
index 386b8e1..7470bb9 100644
--- a/chrome/browser/cocoa/tab_strip_controller_unittest.mm
+++ b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
@@ -127,4 +127,11 @@ TEST_F(TabStripControllerTest, RearrangeTabs) {
// if you don't do anything with it. http://crbug.com/10899
}
+// Test that changing the number of tabs broadcasts a
+// kTabStripNumberOfTabsChanged notifiction.
+TEST_F(TabStripControllerTest, Notifications) {
+ // TODO(pinkerton): Creating a TabContents crashes an unrelated test, even
+ // if you don't do anything with it. http://crbug.com/10899
+}
+
} // namespace