diff options
-rw-r--r-- | chrome/browser/cocoa/browser_window.h | 20 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_cocoa.mm | 12 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.h | 3 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 8 | ||||
-rw-r--r-- | chrome/browser/cocoa/chrome_browser_window.h | 36 | ||||
-rw-r--r-- | chrome/browser/cocoa/chrome_browser_window.mm (renamed from chrome/browser/cocoa/browser_window.mm) | 10 | ||||
-rw-r--r-- | chrome/browser/cocoa/chrome_browser_window_unittest.mm | 145 | ||||
-rw-r--r-- | chrome/browser/cocoa/cocoa_test_helper.h | 23 | ||||
-rwxr-xr-x | chrome/chrome.gyp | 5 |
9 files changed, 219 insertions, 43 deletions
diff --git a/chrome/browser/cocoa/browser_window.h b/chrome/browser/cocoa/browser_window.h deleted file mode 100644 index 3c43577..0000000 --- a/chrome/browser/cocoa/browser_window.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_COCOA_BROWSER_WINDOW_H_ -#define CHROME_BROWSER_COCOA_BROWSER_WINDOW_H_ - -#import <Cocoa/Cocoa.h> - -// Cocoa class representing a Chrome browser window. -// We need to override NSWindow with our own class since we need access to all -// unhandled keyboard events and subclassing NSWindow is the only method to do -// this. -@interface ChromeBrowserWindow : NSWindow - -// Override, so we can handle global keyboard events. -- (BOOL)performKeyEquivalent:(NSEvent*)theEvent; -@end - -#endif // CHROME_BROWSER_COCOA_BROWSER_WINDOW_H_ diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 33809ad..f32e6b4 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -102,17 +102,7 @@ void BrowserWindowCocoa::UpdateTitleBar() { NSString* newTitle = base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab()); - // Only set the title if we're a popup window. If we call setTitle on a - // regular browser window, it will show up in the titlle bar and cover the - // tab strip. - if (browser_->type() == Browser::TYPE_POPUP) - [window_ setTitle:newTitle]; - - // Window menu - [NSApp changeWindowsItem:window_ title:newTitle filename:NO]; - - // Dock - [window_ setMiniwindowTitle:newTitle]; + [window_ setTitle:newTitle]; } void BrowserWindowCocoa::ShelfVisibilityChanged() { diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h index 76223de..0bd84e9 100644 --- a/chrome/browser/cocoa/browser_window_controller.h +++ b/chrome/browser/cocoa/browser_window_controller.h @@ -23,6 +23,7 @@ class Browser; class BrowserWindow; class BrowserWindowCocoa; +@class ChromeBrowserWindow; class ConstrainedWindowMac; @class DownloadShelfController; @class ExtensionShelfController; @@ -55,7 +56,7 @@ class TabStripModelObserverBridge; // alive ensures that weak view or window pointers remain valid through // their destruction sequence. scoped_ptr<Browser> browser_; - scoped_nsobject<NSWindow> window_; + scoped_nsobject<ChromeBrowserWindow> window_; scoped_nsobject<NSWindow> fullscreen_window_; scoped_ptr<TabStripModelObserverBridge> tabObserver_; scoped_ptr<BrowserWindowCocoa> windowShim_; diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index 12d7b6c..3951e4c 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -24,6 +24,7 @@ #import "chrome/browser/cocoa/bookmark_editor_controller.h" #import "chrome/browser/cocoa/browser_window_cocoa.h" #import "chrome/browser/cocoa/browser_window_controller.h" +#import "chrome/browser/cocoa/chrome_browser_window.h" #import "chrome/browser/cocoa/download_shelf_controller.h" #import "chrome/browser/cocoa/extension_shelf_controller.h" #import "chrome/browser/cocoa/find_bar_cocoa_controller.h" @@ -360,7 +361,8 @@ willPositionSheet:(NSWindow*)sheet // message, since it just means that a menu extra (on the "system status bar") // was activated; we'll get another |-windowDidResignKey| if we ever really // lose key window status. - if ([NSApp isActive] && ([NSApp keyWindow] == window_)) + if ([NSApp isActive] && + ([NSApp keyWindow] == static_cast<NSWindow*>(window_))) return; // We need to deactivate the controls (in the "WebView"). To do this, get the @@ -1239,6 +1241,10 @@ willPositionSheet:(NSWindow*)sheet } DCHECK_GE(maxY, minY); + // Suppress title drawing for normal windows (popups use normal + // window title bars). + [window_ setShouldHideTitle:[self isNormalWindow]]; + // Place the toolbar at the top of the reserved area, but only if we're not in // fullscreen mode. NSView* toolbarView = [toolbarController_ view]; diff --git a/chrome/browser/cocoa/chrome_browser_window.h b/chrome/browser/cocoa/chrome_browser_window.h new file mode 100644 index 0000000..fb14b28 --- /dev/null +++ b/chrome/browser/cocoa/chrome_browser_window.h @@ -0,0 +1,36 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_CHROME_BROWSER_WINDOW_H_ +#define CHROME_BROWSER_COCOA_CHROME_BROWSER_WINDOW_H_ + +#import <Cocoa/Cocoa.h> + +// Cocoa class representing a Chrome browser window. +// We need to override NSWindow with our own class since we need access to all +// unhandled keyboard events and subclassing NSWindow is the only method to do +// this. +@interface ChromeBrowserWindow : NSWindow { + BOOL shouldHideTitle_; +} + +// Override, so we can handle global keyboard events. +- (BOOL)performKeyEquivalent:(NSEvent*)theEvent; + +// Tells the window to suppress title drawing. +- (void)setShouldHideTitle:(BOOL)flag; + +@end + +@interface ChromeBrowserWindow (UndocumentedAPI) + +// Undocumented Cocoa API to suppress drawing of the window's title. +// -setTitle: still works, but the title set only applies to the +// miniwindow and menus (and, importantly, Expose). Overridden to +// return |shouldHideTitle_|. +-(BOOL)_isTitleHidden; + +@end + +#endif // CHROME_BROWSER_COCOA_CHROME_BROWSER_WINDOW_H_ diff --git a/chrome/browser/cocoa/browser_window.mm b/chrome/browser/cocoa/chrome_browser_window.mm index 1ecce65..4f2f859 100644 --- a/chrome/browser/cocoa/browser_window.mm +++ b/chrome/browser/cocoa/chrome_browser_window.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "chrome/browser/cocoa/browser_window.h" +#import "chrome/browser/cocoa/chrome_browser_window.h" #include "base/logging.h" #import "chrome/browser/cocoa/browser_window_controller.h" @@ -35,4 +35,12 @@ return [super performKeyEquivalent:event]; } +- (void)setShouldHideTitle:(BOOL)flag { + shouldHideTitle_ = flag; +} + +-(BOOL)_isTitleHidden { + return shouldHideTitle_; +} + @end diff --git a/chrome/browser/cocoa/chrome_browser_window_unittest.mm b/chrome/browser/cocoa/chrome_browser_window_unittest.mm new file mode 100644 index 0000000..f48462d --- /dev/null +++ b/chrome/browser/cocoa/chrome_browser_window_unittest.mm @@ -0,0 +1,145 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> + +#include "base/scoped_nsobject.h" +#include "chrome/app/chrome_dll_resource.h" +#import "chrome/browser/cocoa/chrome_browser_window.h" +#import "chrome/browser/cocoa/browser_window_controller.h" +#import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" + +namespace { + +NSEvent* KeyEvent(const NSUInteger flags, const NSUInteger keyCode) { + return [NSEvent keyEventWithType:NSKeyDown + location:NSZeroPoint + modifierFlags:flags + timestamp:0.0 + windowNumber:0 + context:nil + characters:@"" + charactersIgnoringModifiers:@"" + isARepeat:NO + keyCode:keyCode]; +} + +class ChromeBrowserWindowTest : public PlatformTest { + public: + ChromeBrowserWindowTest() { + // Create a window. + const NSUInteger mask = NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSResizableWindowMask; + window_.reset([[ChromeBrowserWindow alloc] + initWithContentRect:NSMakeRect(0, 0, 800, 600) + styleMask:mask + backing:NSBackingStoreBuffered + defer:NO]); + if (DebugUtil::BeingDebugged()) { + [window_ orderFront:nil]; + } else { + [window_ orderBack:nil]; + } + } + + // Returns a canonical snapshot of the window. + NSData* WindowContentsAsTIFF() { + NSRect frame([window_ frame]); + frame.origin = [window_ convertScreenToBase:frame.origin]; + + NSData* pdfData = [window_ dataWithPDFInsideRect:frame]; + + // |pdfData| can differ for windows which look the same, so make it + // canonical. + NSImage* image = [[[NSImage alloc] initWithData:pdfData] autorelease]; + return [image TIFFRepresentation]; + } + + CocoaNoWindowTestHelper cocoa_helper_; + scoped_nsobject<ChromeBrowserWindow> window_; +}; + +// Baseline test that the window creates, displays, closes, and +// releases. +TEST_F(ChromeBrowserWindowTest, ShowAndClose) { + [window_ display]; +} + +// Verify that the window intercepts a particular key event and +// forwards it to [delegate executeCommand:]. Assume that other +// CommandForKeyboardShortcut() will work the same for the rest. +TEST_F(ChromeBrowserWindowTest, PerformKeyEquivalentForwardToExecuteCommand) { + NSEvent *event = KeyEvent(NSCommandKeyMask, kVK_ANSI_1); + + id delegate = [OCMockObject mockForClass:[BrowserWindowController class]]; + // To satisfy the DCHECK. + BOOL yes = YES; + [[[delegate expect] andReturnValue:OCMOCK_VALUE(yes)] + isKindOfClass:[BrowserWindowController class]]; + [[delegate expect] executeCommand:IDC_SELECT_TAB_0]; + + [window_ setDelegate:delegate]; + [window_ performKeyEquivalent:event]; + + // Don't wish to mock all the way down... + [window_ setDelegate:nil]; + [delegate verify]; +} + +// Verify that an unhandled shortcut does not get forwarded via +// -executeCommand:. +// TODO(shess) Think of a way to test that it is sent to the +// superclass. +TEST_F(ChromeBrowserWindowTest, PerformKeyEquivalentNoForward) { + NSEvent *event = KeyEvent(0, 0); + + id delegate = [OCMockObject mockForClass:[BrowserWindowController class]]; + // To satisfy the DCHECK. + BOOL yes = YES; + [[[delegate expect] andReturnValue:OCMOCK_VALUE(yes)] + isKindOfClass:[BrowserWindowController class]]; + + [window_ setDelegate:delegate]; + [window_ performKeyEquivalent:event]; + + // Don't wish to mock all the way down... + [window_ setDelegate:nil]; + [delegate verify]; +} + +// Test that undocumented title-hiding API we're using does the job. +TEST_F(ChromeBrowserWindowTest, DoesHideTitle) { + // The -display calls are not strictly necessary, but they do + // make it easier to see what's happening when debugging (without + // them the changes are never flushed to the screen). + + [window_ setTitle:@""]; + [window_ display]; + NSData* emptyTitleData = WindowContentsAsTIFF(); + + [window_ setTitle:@"This is a title"]; + [window_ display]; + NSData* thisTitleData = WindowContentsAsTIFF(); + + // The default window with a title should look different from the + // window with an emtpy title. + EXPECT_FALSE([emptyTitleData isEqualToData:thisTitleData]); + + [window_ setShouldHideTitle:YES]; + [window_ setTitle:@""]; + [window_ display]; + [window_ setTitle:@"This is a title"]; + [window_ display]; + NSData* hiddenTitleData = WindowContentsAsTIFF(); + + // With our magic setting, the window with a title should look the + // same as the window with an empty title. + EXPECT_TRUE([window_ _isTitleHidden]); + EXPECT_TRUE([emptyTitleData isEqualToData:hiddenTitleData]); +} + +} // namespace diff --git a/chrome/browser/cocoa/cocoa_test_helper.h b/chrome/browser/cocoa/cocoa_test_helper.h index ebcb4d4..8eb3438 100644 --- a/chrome/browser/cocoa/cocoa_test_helper.h +++ b/chrome/browser/cocoa/cocoa_test_helper.h @@ -47,9 +47,14 @@ // added. If your test wants one, it can derive from PlatformTest instead of // testing::Test. -class CocoaTestHelper { +// Provides the Cocoa goodness without the extraneous window. +// TODO(shess): It might make more sense to have CocoaTest as a +// PlatformTest subclass which adds the Cocoa magic, then +// CocoaViewTest as a further subclass which provides a convenience +// window. +class CocoaNoWindowTestHelper { public: - CocoaTestHelper() { + CocoaNoWindowTestHelper() { // Look in the framework bundle for resources. FilePath path; PathService::Get(base::DIR_EXE, &path); @@ -62,17 +67,21 @@ class CocoaTestHelper { // Bootstrap Cocoa. It's very unhappy without this. [NSApplication sharedApplication]; - // Create a window. + // Set the duration of AppKit-evaluated animations (such as frame changes) + // to zero for testing purposes. That way they take effect immediately. + [[NSAnimationContext currentContext] setDuration:0.0]; + } +}; + +class CocoaTestHelper : public CocoaNoWindowTestHelper { + public: + CocoaTestHelper() { window_.reset([[CocoaTestHelperWindow alloc] init]); if (DebugUtil::BeingDebugged()) { [window_ orderFront:nil]; } else { [window_ orderBack:nil]; } - - // Set the duration of AppKit-evaluated animations (such as frame changes) - // to zero for testing purposes. That way they take effect immediately. - [[NSAnimationContext currentContext] setDuration:0.0]; } // Access the Cocoa window created for the test. diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 07b32bd..d0cff67 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -985,14 +985,14 @@ 'browser/cocoa/bookmark_name_folder_controller.h', 'browser/cocoa/bookmark_name_folder_controller.mm', 'browser/cocoa/browser_test_helper.h', - 'browser/cocoa/browser_window.h', - 'browser/cocoa/browser_window.mm', 'browser/cocoa/browser_window_cocoa.h', 'browser/cocoa/browser_window_cocoa.mm', 'browser/cocoa/browser_window_controller.h', 'browser/cocoa/browser_window_controller.mm', 'browser/cocoa/bubble_view.h', 'browser/cocoa/bubble_view.mm', + 'browser/cocoa/chrome_browser_window.h', + 'browser/cocoa/chrome_browser_window.mm', 'browser/cocoa/clear_browsing_data_controller.h', 'browser/cocoa/clear_browsing_data_controller.mm', 'browser/cocoa/clickhold_button_cell.h', @@ -4184,6 +4184,7 @@ 'browser/cocoa/browser_window_cocoa_unittest.mm', 'browser/cocoa/browser_window_controller_unittest.mm', 'browser/cocoa/bubble_view_unittest.mm', + 'browser/cocoa/chrome_browser_window_unittest.mm', 'browser/cocoa/clear_browsing_data_controller_unittest.mm', 'browser/cocoa/clickhold_button_cell_unittest.mm', 'browser/cocoa/cocoa_test_helper.h', |