summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser.cc15
-rw-r--r--chrome/browser/browser.h1
-rw-r--r--chrome/browser/browser_window.h5
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.h1
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm4
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h3
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm19
-rw-r--r--chrome/browser/cocoa/browser_window_controller_private.mm1
-rw-r--r--chrome/browser/cocoa/tabpose_window.h36
-rw-r--r--chrome/browser/cocoa/tabpose_window.mm131
-rw-r--r--chrome/browser/cocoa/tabpose_window_unittest.mm35
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/test/test_browser_window.h1
14 files changed, 254 insertions, 1 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 13f6b54..cdd32ae 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -1340,6 +1340,20 @@ void Browser::SelectPreviousTab() {
tabstrip_model_.SelectPreviousTab();
}
+void Browser::OpenTabpose() {
+#if defined(OS_MACOSX)
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableExposeForTabs)) {
+ return;
+ }
+
+ UserMetrics::RecordAction(UserMetricsAction("OpenTabpose"), profile_);
+ window()->OpenTabpose();
+#else
+ NOTREACHED();
+#endif
+}
+
void Browser::MoveTabNext() {
UserMetrics::RecordAction(UserMetricsAction("MoveTabNext"), profile_);
tabstrip_model_.MoveTabNext();
@@ -1978,6 +1992,7 @@ void Browser::ExecuteCommandWithDisposition(
case IDC_CLOSE_TAB: CloseTab(); break;
case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
case IDC_SELECT_PREVIOUS_TAB: SelectPreviousTab(); break;
+ case IDC_TABPOSE: OpenTabpose(); break;
case IDC_MOVE_TAB_NEXT: MoveTabNext(); break;
case IDC_MOVE_TAB_PREVIOUS: MoveTabPrevious(); break;
case IDC_SELECT_TAB_0:
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index 7938bc1..87456fb 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -433,6 +433,7 @@ class Browser : public TabStripModelDelegate,
void CloseTab();
void SelectNextTab();
void SelectPreviousTab();
+ void OpenTabpose();
void MoveTabNext();
void MoveTabPrevious();
void SelectNumberedTab(int index);
diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h
index b02ffea..444796e 100644
--- a/chrome/browser/browser_window.h
+++ b/chrome/browser/browser_window.h
@@ -310,6 +310,11 @@ class BrowserWindow {
// Switches between available tabstrip display modes.
virtual void ToggleTabStripMode() = 0;
+#if defined(OS_MACOSX)
+ // Opens the tabpose view.
+ virtual void OpenTabpose() = 0;
+#endif
+
// Construct a BrowserWindow implementation for the specified |browser|.
static BrowserWindow* CreateBrowserWindow(Browser* browser);
diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h
index 47e32b2..4559567 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/cocoa/browser_window_cocoa.h
@@ -106,6 +106,7 @@ class BrowserWindowCocoa : public BrowserWindow,
virtual void Copy();
virtual void Paste();
virtual void ToggleTabStripMode();
+ virtual void OpenTabpose();
// Overridden from NotificationObserver
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index 8b16348..2b12cda 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -553,6 +553,10 @@ void BrowserWindowCocoa::ToggleTabStripMode() {
[controller_ toggleTabStripDisplayMode];
}
+void BrowserWindowCocoa::OpenTabpose() {
+ [controller_ toggleTabStripDisplayMode];
+}
+
void BrowserWindowCocoa::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h
index 816feb2..274e23b 100644
--- a/chrome/browser/cocoa/browser_window_controller.h
+++ b/chrome/browser/cocoa/browser_window_controller.h
@@ -337,6 +337,9 @@ class TabStripModelObserverBridge;
// Returns YES if any of the views in the floating bar currently has focus.
- (BOOL)floatingBarHasFocus;
+// Opens the tabpose window.
+- (void)openTabpose;
+
@end // @interface BrowserWindowController(Fullscreen)
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index 61741e99..d31659b0 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -44,6 +44,7 @@
#import "chrome/browser/cocoa/tab_strip_controller.h"
#import "chrome/browser/cocoa/tab_strip_view.h"
#import "chrome/browser/cocoa/tab_view.h"
+#import "chrome/browser/cocoa/tabpose_window.h"
#import "chrome/browser/cocoa/toolbar_controller.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/sync/profile_sync_service.h"
@@ -1473,6 +1474,7 @@
// TODO(pinkerton): figure out page-up, http://crbug.com/16305
} else if ([event deltaY] < -0.5) {
// TODO(pinkerton): figure out page-down, http://crbug.com/16305
+ browser_->ExecuteCommand(IDC_TABPOSE);
}
// Ensure the command is valid first (ExecuteCommand() won't do that) and
@@ -1841,6 +1843,23 @@ willAnimateFromState:(bookmarks::VisualState)oldState
return [focused isKindOfClass:[AutocompleteTextFieldEditor class]];
}
+- (void)openTabpose {
+ NSUInteger modifierFlags = [[NSApp currentEvent] modifierFlags];
+ BOOL slomo = (modifierFlags & NSShiftKeyMask) != 0;
+
+ // Cover info bars, inspector window, and detached bookmark bar on NTP.
+ // Do not cover download shelf.
+ NSRect activeArea = [[self tabContentArea] frame];
+ activeArea.size.height +=
+ NSHeight([[infoBarContainerController_ view] frame]);
+ if ([self isBookmarkBarVisible] && [self placeBookmarkBarBelowInfoBar]) {
+ NSView* bookmarkBarView = [bookmarkBarController_ view];
+ activeArea.size.height += NSHeight([bookmarkBarView frame]);
+ }
+
+ [TabposeWindow openTabposeFor:[self window] rect:activeArea slomo:slomo];
+}
+
@end // @implementation BrowserWindowController(Fullscreen)
diff --git a/chrome/browser/cocoa/browser_window_controller_private.mm b/chrome/browser/cocoa/browser_window_controller_private.mm
index 9f14c2e..21d6f2b 100644
--- a/chrome/browser/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/cocoa/browser_window_controller_private.mm
@@ -26,7 +26,6 @@
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/common/pref_names.h"
-
namespace {
// Space between the incognito badge and the right edge of the window.
diff --git a/chrome/browser/cocoa/tabpose_window.h b/chrome/browser/cocoa/tabpose_window.h
new file mode 100644
index 0000000..0efb90c
--- /dev/null
+++ b/chrome/browser/cocoa/tabpose_window.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2010 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_TABPOSE_WINDOW_H_
+#define CHROME_BROWSER_COCOA_TABPOSE_WINDOW_H_
+#pragma once
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_cftyperef.h"
+
+// A TabposeWindow shows an overview of open tabs and lets the user select a new
+// active tab. The window blocks clicks on the tab strip and the download
+// shelf. Every open browser window has its own overlay, and they are
+// independent of each other.
+@interface TabposeWindow : NSWindow {
+ @private
+ // The root layer added to the content view. Covers the whole window.
+ CALayer* rootLayer_; // weak
+
+ // The layer showing the background layer. Covers the whole visible area.
+ CALayer* bgLayer_; // weak
+
+ scoped_cftyperef<CGColorRef> gray_;
+}
+
+// Shows a TabposeWindow on top of |parent|, with |rect| being the active area.
+// If |slomo| is YES, then the appearance animation is shown in slow motion.
+// The window blocks all keyboard and mouse events and releases itself when
+// closed.
++ (id)openTabposeFor:(NSWindow*)parent rect:(NSRect)rect slomo:(BOOL)slomo;
+@end
+
+#endif // CHROME_BROWSER_COCOA_TABPOSE_WINDOW_H_
+
diff --git a/chrome/browser/cocoa/tabpose_window.mm b/chrome/browser/cocoa/tabpose_window.mm
new file mode 100644
index 0000000..c69c5c1
--- /dev/null
+++ b/chrome/browser/cocoa/tabpose_window.mm
@@ -0,0 +1,131 @@
+// Copyright (c) 2010 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/tabpose_window.h"
+
+#import <QuartzCore/QuartzCore.h>
+
+const int kTopGradientHeight = 15;
+
+// CAGradientLayer is 10.6-only -- roll our own.
+@interface DarkGradientLayer : CALayer
+- (void)drawInContext:(CGContextRef)context;
+@end
+
+@implementation DarkGradientLayer
+- (void)drawInContext:(CGContextRef)context {
+ scoped_cftyperef<CGColorSpaceRef> grayColorSpace(
+ CGColorSpaceCreateWithName(kCGColorSpaceGenericGray));
+ CGFloat grays[] = { 0.277, 1.0, 0.39, 1.0 };
+ CGFloat locations[] = { 0, 1 };
+ scoped_cftyperef<CGGradientRef> gradient(CGGradientCreateWithColorComponents(
+ grayColorSpace.get(), grays, locations, arraysize(locations)));
+ CGPoint topLeft = CGPointMake(0.0, kTopGradientHeight);
+ CGContextDrawLinearGradient(context, gradient.get(), topLeft, CGPointZero, 0);
+}
+@end
+
+@interface TabposeWindow (Private)
+- (id)initForWindow:(NSWindow*)parent rect:(NSRect)rect slomo:(BOOL)slomo;
+- (void)setUpLayers:(NSRect)bgLayerRect;
+@end
+
+@implementation TabposeWindow
+
++ (id)openTabposeFor:(NSWindow*)parent rect:(NSRect)rect slomo:(BOOL)slomo {
+ // Releases itself when closed.
+ return [[TabposeWindow alloc] initForWindow:parent rect:rect slomo:slomo];
+}
+
+- (id)initForWindow:(NSWindow*)parent rect:(NSRect)rect slomo:(BOOL)slomo {
+ NSRect frame = [parent frame];
+ if ((self = [super initWithContentRect:frame
+ styleMask:NSBorderlessWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO])) {
+ [self setReleasedWhenClosed:YES];
+ [self setOpaque:NO];
+ [self setBackgroundColor:[NSColor clearColor]];
+ [self setUpLayers:rect];
+ [parent addChildWindow:self ordered:NSWindowAbove];
+ [self makeKeyAndOrderFront:self];
+ }
+ return self;
+}
+
+- (void)setUpLayers:(NSRect)bgLayerRect {
+ // Root layer -- covers whole window.
+ rootLayer_ = [CALayer layer];
+ [[self contentView] setLayer:rootLayer_];
+ [[self contentView] setWantsLayer:YES];
+
+ // Background layer -- the visible part of the window.
+ gray_.reset(CGColorCreateGenericGray(0.39, 1.0));
+ bgLayer_ = [CALayer layer];
+ bgLayer_.backgroundColor = gray_;
+ bgLayer_.frame = NSRectToCGRect(bgLayerRect);
+ bgLayer_.masksToBounds = YES;
+ [rootLayer_ addSublayer:bgLayer_];
+
+ // Top gradient.
+ CALayer* gradientLayer = [DarkGradientLayer layer];
+ gradientLayer.frame = CGRectMake(
+ 0,
+ NSHeight(bgLayerRect) - kTopGradientHeight,
+ NSWidth(bgLayerRect),
+ kTopGradientHeight);
+ [gradientLayer setNeedsDisplay]; // Draw once.
+ [bgLayer_ addSublayer:gradientLayer];
+}
+
+- (BOOL)canBecomeKeyWindow {
+ return YES;
+}
+
+- (void)keyDown:(NSEvent*)event {
+ // Overridden to prevent beeps.
+}
+
+- (void)keyUp:(NSEvent*)event {
+ NSString* characters = [event characters];
+ if ([characters length] < 1)
+ return;
+
+ unichar character = [characters characterAtIndex:0];
+ switch (character) {
+ case NSEnterCharacter:
+ case NSNewlineCharacter:
+ case NSCarriageReturnCharacter:
+ case ' ':
+ case '\e': // Escape
+ [self close];
+ break;
+ }
+}
+
+- (void)mouseDown:(NSEvent*)event {
+ [self close];
+}
+
+- (void)swipeWithEvent:(NSEvent*)event {
+ if ([event deltaY] > 0.5) // Swipe up
+ [self close];
+}
+
+- (void)close {
+ // Prevent parent window from disappearing.
+ [[self parentWindow] removeChildWindow:self];
+ [super close];
+}
+
+- (void)commandDispatch:(id)sender {
+ // Without this, -validateUserInterfaceItem: is not called.
+}
+
+- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
+ // Disable all browser-related menu items.
+ return NO;
+}
+
+@end
diff --git a/chrome/browser/cocoa/tabpose_window_unittest.mm b/chrome/browser/cocoa/tabpose_window_unittest.mm
new file mode 100644
index 0000000..8f6f239
--- /dev/null
+++ b/chrome/browser/cocoa/tabpose_window_unittest.mm
@@ -0,0 +1,35 @@
+// Copyright (c) 2010 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/tabpose_window.h"
+
+#include "base/scoped_nsobject.h"
+#import "chrome/browser/cocoa/browser_test_helper.h"
+#import "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class TabposeWindowTest : public CocoaTest {
+ public:
+ BrowserTestHelper browser_helper_;
+};
+
+// Check that this doesn't leak.
+TEST_F(TabposeWindowTest, TestShow) {
+ scoped_nsobject<NSWindow> parent([[NSWindow alloc]
+ initWithContentRect:NSMakeRect(100, 200, 300, 200)
+ styleMask:NSTitledWindowMask
+ backing:NSBackingStoreBuffered
+ defer:NO]);
+ [parent orderFront:nil];
+ EXPECT_TRUE([parent isVisible]);
+
+ base::ScopedNSAutoreleasePool pool;
+ TabposeWindow* window =
+ [TabposeWindow openTabposeFor:parent.get()
+ rect:NSMakeRect(10, 20, 50, 60)
+ slomo:NO];
+
+ // Should release the window.
+ [window mouseDown:nil];
+}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 887fa5e..1b5ea58 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -999,6 +999,8 @@
'browser/cocoa/tab_window_controller.mm',
'browser/cocoa/table_row_nsimage_cache.h',
'browser/cocoa/table_row_nsimage_cache.mm',
+ 'browser/cocoa/tabpose_window.h',
+ 'browser/cocoa/tabpose_window.mm',
'browser/cocoa/task_manager_mac.h',
'browser/cocoa/task_manager_mac.mm',
'browser/cocoa/themed_window.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 8ad0be2..0ffbb01 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -884,6 +884,7 @@
'browser/cocoa/tab_view_unittest.mm',
'browser/cocoa/tab_view_picker_table_unittest.mm',
'browser/cocoa/table_row_nsimage_cache_unittest.mm',
+ 'browser/cocoa/tabpose_window_unittest.mm',
'browser/cocoa/task_manager_mac_unittest.mm',
'browser/cocoa/test_event_utils.h',
'browser/cocoa/test_event_utils.mm',
diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h
index 4ac3d1c..5cfbd0b 100644
--- a/chrome/test/test_browser_window.h
+++ b/chrome/test/test_browser_window.h
@@ -103,6 +103,7 @@ class TestBrowserWindow : public BrowserWindow {
virtual void Copy() { }
virtual void Paste() { }
virtual void ToggleTabStripMode() {}
+ virtual void OpenTabpose() {}
protected:
virtual void DestroyBrowser() {}