summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm10
-rw-r--r--chrome/browser/cocoa/chrome_browser_window.h17
-rw-r--r--chrome/browser/cocoa/chrome_browser_window.mm53
-rw-r--r--chrome/browser/cocoa/chrome_browser_window_unittest.mm59
-rw-r--r--chrome/browser/cocoa/chrome_event_processing_window.h32
-rw-r--r--chrome/browser/cocoa/chrome_event_processing_window.mm69
-rw-r--r--chrome/browser/cocoa/chrome_event_processing_window_unittest.mm111
-rw-r--r--chrome/browser/cocoa/fullscreen_window.h5
-rwxr-xr-xchrome/chrome.gyp3
9 files changed, 233 insertions, 126 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index 030384d..d80e9f8 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -932,6 +932,12 @@ willPositionSheet:(NSWindow*)sheet
[content removeFromSuperview];
[fullscreen_window_ setContentView:content];
[self setWindow:fullscreen_window_.get()];
+ [window_ setWindowController:nil];
+ [window_ setDelegate:nil];
+ // Required for proper event dispatch.
+ [fullscreen_window_ setWindowController:self];
+ [fullscreen_window_ setDelegate:self];
+
// Minimize our UI. This call triggers a relayout, so it needs to come
// after we move the contentview to the new window.
[self adjustUIForFullscreen:fullscreen];
@@ -947,6 +953,10 @@ willPositionSheet:(NSWindow*)sheet
[content setAutoresizesSubviews:NO];
[content removeFromSuperview];
[window_ setContentView:content];
+ [fullscreen_window_ setDelegate:nil];
+ [fullscreen_window_ setWindowController:nil];
+ [window_ setWindowController:self];
+ [window_ setDelegate:self];
[self setWindow:window_.get()];
// This call triggers a relayout, so it needs to come after we move the
// contentview to the new window.
diff --git a/chrome/browser/cocoa/chrome_browser_window.h b/chrome/browser/cocoa/chrome_browser_window.h
index f69978c..19a846f 100644
--- a/chrome/browser/cocoa/chrome_browser_window.h
+++ b/chrome/browser/cocoa/chrome_browser_window.h
@@ -8,6 +8,7 @@
#import <Cocoa/Cocoa.h>
#include "base/scoped_nsobject.h"
+#include "chrome/browser/cocoa/chrome_event_processing_window.h"
// Offset from the top of the window frame to the top of the window controls
// (zoom, close, miniaturize) for a window with a tabstrip.
@@ -28,7 +29,7 @@ const NSInteger kChromeWindowButtonsInterButtonSpacing = 7;
// 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. We also handle our own window controls and custom window frame drawing.
-@interface ChromeBrowserWindow : NSWindow {
+@interface ChromeBrowserWindow : ChromeEventProcessingWindow {
@private
BOOL shouldHideTitle_;
NSButton* closeButton_;
@@ -38,19 +39,6 @@ const NSInteger kChromeWindowButtonsInterButtonSpacing = 7;
scoped_nsobject<NSTrackingArea> widgetTrackingArea_;
}
-// See global_keyboard_shortcuts_mac.h for details on the next two functions.
-
-// Checks if |event| is a window keyboard shortcut. If so, dispatches it to the
-// window controller's |executeCommand:| and returns |YES|.
-- (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event;
-
-// Checks if |event| is a browser keyboard shortcut. If so, dispatches it to the
-// window controller's |executeCommand:| and returns |YES|.
-- (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event;
-
-// Override, so we can handle global keyboard events.
-- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
-
// Tells the window to suppress title drawing.
- (void)setShouldHideTitle:(BOOL)flag;
@@ -60,6 +48,7 @@ const NSInteger kChromeWindowButtonsInterButtonSpacing = 7;
// Update the tracking areas for our window widgets as appropriate.
- (void)updateTrackingAreas;
+
@end
@interface ChromeBrowserWindow (UndocumentedAPI)
diff --git a/chrome/browser/cocoa/chrome_browser_window.mm b/chrome/browser/cocoa/chrome_browser_window.mm
index fdc34de..6ad0426 100644
--- a/chrome/browser/cocoa/chrome_browser_window.mm
+++ b/chrome/browser/cocoa/chrome_browser_window.mm
@@ -24,9 +24,8 @@
- (NSView*)frameView;
@end
-typedef int (*KeyToCommandMapper)(bool, bool, bool, int);
-
@implementation ChromeBrowserWindow
+
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
@@ -282,56 +281,6 @@ typedef int (*KeyToCommandMapper)(bool, bool, bool, int);
return entered_;
}
-- (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event fromTable:
- (KeyToCommandMapper)commandForKeyboardShortcut {
- // Extract info from |event|.
- NSUInteger modifers = [event modifierFlags];
- const bool cmdKey = modifers & NSCommandKeyMask;
- const bool shiftKey = modifers & NSShiftKeyMask;
- const bool cntrlKey = modifers & NSControlKeyMask;
- const int keyCode = [event keyCode];
-
- int cmdNum = commandForKeyboardShortcut(cmdKey, shiftKey, cntrlKey,
- keyCode);
-
- BrowserWindowController* controller =
- (BrowserWindowController*)[self delegate];
- // A bit of sanity.
- DCHECK([controller isKindOfClass:[BrowserWindowController class]]);
- DCHECK([controller respondsToSelector:@selector(executeCommand:)]);
-
- if (cmdNum != -1) {
- [controller executeCommand:cmdNum];
- return YES;
- }
- return NO;
-}
-
-- (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event {
- return [self handleExtraKeyboardShortcut:event
- fromTable:CommandForWindowKeyboardShortcut];
-}
-
-- (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event {
- return [self handleExtraKeyboardShortcut:event
- fromTable:CommandForBrowserKeyboardShortcut];
-}
-
-- (BOOL)performKeyEquivalent:(NSEvent*)event {
- // Give the web site a chance to handle the event. If it doesn't want to
- // handle it, it will call us back with one of the |handle*| methods above.
- NSResponder* r = [self firstResponder];
- if ([r isKindOfClass:[RenderWidgetHostViewCocoa class]])
- return [r performKeyEquivalent:event];
-
- // Handle per-window shortcuts like cmd-1, but do not handle browser-level
- // shortcuts like cmd-left (else, cmd-left would do history navigation even
- // if e.g. the Omnibox has focus).
- if ([self handleExtraWindowKeyboardShortcut:event])
- return YES;
- return [super performKeyEquivalent:event];
-}
-
- (void)setShouldHideTitle:(BOOL)flag {
shouldHideTitle_ = flag;
}
diff --git a/chrome/browser/cocoa/chrome_browser_window_unittest.mm b/chrome/browser/cocoa/chrome_browser_window_unittest.mm
index be01bc6..4982918 100644
--- a/chrome/browser/cocoa/chrome_browser_window_unittest.mm
+++ b/chrome/browser/cocoa/chrome_browser_window_unittest.mm
@@ -12,22 +12,6 @@
#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:
@@ -70,48 +54,6 @@ 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]];
- // -stub to satisfy the DCHECK.
- BOOL yes = YES;
- [[[delegate stub] 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]];
- // -stub to satisfy the DCHECK.
- BOOL yes = YES;
- [[[delegate stub] 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
@@ -191,4 +133,3 @@ TEST_F(ChromeBrowserWindowTest, DISABLED_WindowWidgetTrackingArea) {
EXPECT_TRUE(foundArea);
}
-} // namespace
diff --git a/chrome/browser/cocoa/chrome_event_processing_window.h b/chrome/browser/cocoa/chrome_event_processing_window.h
new file mode 100644
index 0000000..b3cc116
--- /dev/null
+++ b/chrome/browser/cocoa/chrome_event_processing_window.h
@@ -0,0 +1,32 @@
+// 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_EVENT_PROCESSING_WINDOW_H_
+#define CHROME_BROWSER_COCOA_CHROME_EVENT_PROCESSING_WINDOW_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_nsobject.h"
+
+// Override NSWindow to access unhandled keyboard events (for command
+// processing); subclassing NSWindow is the only method to do
+// this.
+@interface ChromeEventProcessingWindow : NSWindow
+
+// See global_keyboard_shortcuts_mac.h for details on the next two functions.
+
+// Checks if |event| is a window keyboard shortcut. If so, dispatches it to the
+// window controller's |executeCommand:| and returns |YES|.
+- (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event;
+
+// Checks if |event| is a browser keyboard shortcut. If so, dispatches it to the
+// window controller's |executeCommand:| and returns |YES|.
+- (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event;
+
+// Override, so we can handle global keyboard events.
+- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_CHROME_EVENT_PROCESSING_WINDOW_H_
diff --git a/chrome/browser/cocoa/chrome_event_processing_window.mm b/chrome/browser/cocoa/chrome_event_processing_window.mm
new file mode 100644
index 0000000..7a82ab4
--- /dev/null
+++ b/chrome/browser/cocoa/chrome_event_processing_window.mm
@@ -0,0 +1,69 @@
+// 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 "chrome/browser/cocoa/chrome_event_processing_window.h"
+
+#include "base/logging.h"
+#import "chrome/browser/cocoa/browser_window_controller.h"
+#import "chrome/browser/cocoa/browser_frame_view.h"
+#import "chrome/browser/cocoa/tab_strip_controller.h"
+#import "chrome/browser/renderer_host/render_widget_host_view_mac.h"
+#include "chrome/browser/global_keyboard_shortcuts_mac.h"
+
+typedef int (*KeyToCommandMapper)(bool, bool, bool, int);
+
+@implementation ChromeEventProcessingWindow
+
+- (BOOL)handleExtraKeyboardShortcut:(NSEvent*)event fromTable:
+ (KeyToCommandMapper)commandForKeyboardShortcut {
+ // Extract info from |event|.
+ NSUInteger modifers = [event modifierFlags];
+ const bool cmdKey = modifers & NSCommandKeyMask;
+ const bool shiftKey = modifers & NSShiftKeyMask;
+ const bool cntrlKey = modifers & NSControlKeyMask;
+ const int keyCode = [event keyCode];
+
+ int cmdNum = commandForKeyboardShortcut(cmdKey, shiftKey, cntrlKey,
+ keyCode);
+
+ BrowserWindowController* controller =
+ (BrowserWindowController*)[self delegate];
+ // A bit of sanity.
+ DCHECK([controller isKindOfClass:[BrowserWindowController class]]);
+ DCHECK([controller respondsToSelector:@selector(executeCommand:)]);
+
+ if (cmdNum != -1) {
+ [controller executeCommand:cmdNum];
+ return YES;
+ }
+ return NO;
+}
+
+- (BOOL)handleExtraWindowKeyboardShortcut:(NSEvent*)event {
+ return [self handleExtraKeyboardShortcut:event
+ fromTable:CommandForWindowKeyboardShortcut];
+}
+
+- (BOOL)handleExtraBrowserKeyboardShortcut:(NSEvent*)event {
+ return [self handleExtraKeyboardShortcut:event
+ fromTable:CommandForBrowserKeyboardShortcut];
+}
+
+- (BOOL)performKeyEquivalent:(NSEvent*)event {
+ // Give the web site a chance to handle the event. If it doesn't want to
+ // handle it, it will call us back with one of the |handle*| methods above.
+ NSResponder* r = [self firstResponder];
+ if ([r isKindOfClass:[RenderWidgetHostViewCocoa class]])
+ return [r performKeyEquivalent:event];
+
+ // Handle per-window shortcuts like cmd-1, but do not handle browser-level
+ // shortcuts like cmd-left (else, cmd-left would do history navigation even
+ // if e.g. the Omnibox has focus).
+ if ([self handleExtraWindowKeyboardShortcut:event])
+ return YES;
+ return [super performKeyEquivalent:event];
+}
+
+@end // ChromeEventProcessingWindow
+
diff --git a/chrome/browser/cocoa/chrome_event_processing_window_unittest.mm b/chrome/browser/cocoa/chrome_event_processing_window_unittest.mm
new file mode 100644
index 0000000..817cf4c
--- /dev/null
+++ b/chrome/browser/cocoa/chrome_event_processing_window_unittest.mm
@@ -0,0 +1,111 @@
+// 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_event_processing_window.h"
+#import "chrome/browser/cocoa/browser_window_controller.h"
+#import "chrome/browser/cocoa/browser_frame_view.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 ChromeEventProcessingWindowTest : public PlatformTest {
+ public:
+ ChromeEventProcessingWindowTest() {
+ // Create a window.
+ const NSUInteger mask = NSTitledWindowMask | NSClosableWindowMask |
+ NSMiniaturizableWindowMask | NSResizableWindowMask;
+ window_.reset([[ChromeEventProcessingWindow 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<ChromeEventProcessingWindow> window_;
+};
+
+// 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(ChromeEventProcessingWindowTest,
+ PerformKeyEquivalentForwardToExecuteCommand) {
+ NSEvent* event = KeyEvent(NSCommandKeyMask, kVK_ANSI_1);
+
+ id delegate = [OCMockObject mockForClass:[BrowserWindowController class]];
+ // -stub to satisfy the DCHECK.
+ BOOL yes = YES;
+ [[[delegate stub] 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(ChromeEventProcessingWindowTest, PerformKeyEquivalentNoForward) {
+ NSEvent* event = KeyEvent(0, 0);
+
+ id delegate = [OCMockObject mockForClass:[BrowserWindowController class]];
+ // -stub to satisfy the DCHECK.
+ BOOL yes = YES;
+ [[[delegate stub] 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];
+}
+
+
+} // namespace
diff --git a/chrome/browser/cocoa/fullscreen_window.h b/chrome/browser/cocoa/fullscreen_window.h
index 1f944e4..313c72a 100644
--- a/chrome/browser/cocoa/fullscreen_window.h
+++ b/chrome/browser/cocoa/fullscreen_window.h
@@ -3,11 +3,14 @@
// found in the LICENSE file.
#include <Cocoa/Cocoa.h>
+#import "chrome/browser/cocoa/chrome_event_processing_window.h"
// A FullscreenWindow is a borderless window suitable for going
// fullscreen. The returned window is NOT release when closed and is
// not initially visible.
-@interface FullscreenWindow : NSWindow
+// FullscreenWindow derives from ChromeEventProcessingWindow to inherit
+// special event handling (e.g. handleExtraKeyboardShortcut).
+@interface FullscreenWindow : ChromeEventProcessingWindow
// Initialize a FullscreenWindow for the given screen.
// Designated initializer.
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 1f922cc..6bba4f0 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1049,6 +1049,8 @@
'browser/cocoa/bubble_view.mm',
'browser/cocoa/chrome_browser_window.h',
'browser/cocoa/chrome_browser_window.mm',
+ 'browser/cocoa/chrome_event_processing_window.h',
+ 'browser/cocoa/chrome_event_processing_window.mm',
'browser/cocoa/clear_browsing_data_controller.h',
'browser/cocoa/clear_browsing_data_controller.mm',
'browser/cocoa/clickhold_button_cell.h',
@@ -4376,6 +4378,7 @@
'browser/cocoa/browser_window_controller_unittest.mm',
'browser/cocoa/bubble_view_unittest.mm',
'browser/cocoa/chrome_browser_window_unittest.mm',
+ 'browser/cocoa/chrome_event_processing_window_unittest.mm',
'browser/cocoa/clear_browsing_data_controller_unittest.mm',
'browser/cocoa/clickhold_button_cell_unittest.mm',
'browser/cocoa/cocoa_test_helper.h',