diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-14 23:45:22 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-14 23:45:22 +0000 |
commit | c02ab3838f371010565d7cac859dca493160a85a (patch) | |
tree | 6c08914f4806e42991546919ea0fb2bb361d5117 | |
parent | 7b66b6f5ab80b8c32d4a57281acedb83e81461a3 (diff) | |
download | chromium_src-c02ab3838f371010565d7cac859dca493160a85a.zip chromium_src-c02ab3838f371010565d7cac859dca493160a85a.tar.gz chromium_src-c02ab3838f371010565d7cac859dca493160a85a.tar.bz2 |
Remove Tabpose feature on mac, and supporting infrastructure (PaintAtSize)
Tabpose has been behind a flag for 3 years, and UMA shows usage is very low.
It is the unique user of the RenderWidgetSnapshotTaker, and the only user of
RWH::PaintAtSize, which we want to remove.
XIB changes:
* Remove Tabpose menu entry "Show Tab Overview..."
BUG=251960, 223336
R=cevans@chromium.org, jamesr@chromium.org, sky@chromium.org, viettrungluu@chromium.org
Review URL: https://codereview.chromium.org/154083008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@251439 0039d316-1c4b-4281-b951-d872f2087c98
53 files changed, 0 insertions, 2842 deletions
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt index 9ec8fe2..0f0949f 100644 --- a/build/ios/grit_whitelist.txt +++ b/build/ios/grit_whitelist.txt @@ -553,8 +553,6 @@ IDS_FLAGS_SPELLCHECK_AUTOCORRECT_DESCRIPTION IDS_FLAGS_STACKED_TAB_STRIP_DESCRIPTION IDS_FLAGS_STACKED_TAB_STRIP_NAME IDS_FLAGS_TABLE_TITLE -IDS_FLAGS_TABPOSE_DESCRIPTION -IDS_FLAGS_TABPOSE_NAME IDS_FLAGS_TAB_GROUPS_CONTEXT_MENU_DESCRIPTION IDS_FLAGS_TAB_GROUPS_CONTEXT_MENU_NAME IDS_FLAGS_THREADED_COMPOSITING_MODE_DESCRIPTION diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index 1c7a5921e..157c2e8 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h @@ -61,7 +61,6 @@ #define IDC_MOVE_TAB_NEXT 34032 #define IDC_MOVE_TAB_PREVIOUS 34033 #define IDC_SEARCH 34035 -#define IDC_TABPOSE 34036 #define IDC_DEBUG_FRAME_TOGGLE 34038 #define IDC_PRESENTATION_MODE 34039 #define IDC_METRO_SNAP_ENABLE 34040 diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2f772bb..2d22ce0 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -5549,12 +5549,6 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_FLAGS_ENABLE" desc="The link for enabling a labs experiment."> Enable </message> - <message name="IDS_FLAGS_TABPOSE_NAME" desc="Name of the 'Tab Overview' lab."> - Tab Overview - </message> - <message name="IDS_FLAGS_TABPOSE_DESCRIPTION" desc="Description of the 'Tab Overview' lab."> - Swipe down with three fingers on your trackpad while holding the option key to see an overview of all your tabs. Click on a thumbnail to select it. Works great in fullscreen mode. - </message> <message name="IDS_FLAGS_STACKED_TAB_STRIP_NAME" desc="Name of the 'Stacked Tabs' lab."> Stacked Tabs </message> @@ -13250,9 +13244,6 @@ Some features may be unavailable. Please check that the profile exists and you <message name="IDS_PREV_TAB_MAC" desc="The Mac menu item for previous tab in the window menu."> Select Previous Tab </message> - <message name="IDS_SHOW_TABPOSE_MAC" desc="The Mac menu item for showing a tab overview. This item is in the window menu."> - Show Tab Overview... - </message> <message name="IDS_SHOW_DOWNLOADS_MAC" desc="The Mac menu item to show downloads in the window menu."> Downloads </message> diff --git a/chrome/app/nibs/MainMenu.xib b/chrome/app/nibs/MainMenu.xib index 9609e95..072920c 100644 --- a/chrome/app/nibs/MainMenu.xib +++ b/chrome/app/nibs/MainMenu.xib @@ -1128,16 +1128,6 @@ <reference key="NSMixedImage" ref="549394948"/> <int key="NSTag">34017</int> </object> - <object class="NSMenuItem" id="648879968"> - <reference key="NSMenu" ref="835318025"/> - <string key="NSTitle">^IDS_SHOW_TABPOSE_MAC</string> - <string key="NSKeyEquiv">t</string> - <int key="NSKeyEquivModMask">1310720</int> - <int key="NSMnemonicLoc">2147483647</int> - <reference key="NSOnImage" ref="353210768"/> - <reference key="NSMixedImage" ref="549394948"/> - <int key="NSTag">34036</int> - </object> <object class="NSMenuItem" id="710833675"> <reference key="NSMenu" ref="835318025"/> <bool key="NSIsDisabled">YES</bool> @@ -1781,14 +1771,6 @@ <object class="IBActionConnection" key="connection"> <string key="label">commandDispatch:</string> <reference key="source" ref="1014"/> - <reference key="destination" ref="648879968"/> - </object> - <int key="connectionID">684</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBActionConnection" key="connection"> - <string key="label">commandDispatch:</string> - <reference key="source" ref="1014"/> <reference key="destination" ref="210963491"/> </object> <int key="connectionID">693</int> @@ -1874,14 +1856,6 @@ <int key="connectionID">667</int> </object> <object class="IBConnectionRecord"> - <object class="IBOutletConnection" key="connection"> - <string key="label">tabposeMenuItem_</string> - <reference key="source" ref="168151378"/> - <reference key="destination" ref="648879968"/> - </object> - <int key="connectionID">685</int> - </object> - <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">toggleConfirmToQuit:</string> <reference key="source" ref="168151378"/> @@ -2305,7 +2279,6 @@ <reference ref="238061183"/> <reference ref="710833675"/> <reference ref="1008975930"/> - <reference ref="648879968"/> <reference ref="693413486"/> </object> <reference key="parent" ref="713487014"/> @@ -2732,11 +2705,6 @@ <reference key="parent" ref="466310130"/> </object> <object class="IBObjectRecord"> - <int key="objectID">682</int> - <reference key="object" ref="648879968"/> - <reference key="parent" ref="835318025"/> - </object> - <object class="IBObjectRecord"> <int key="objectID">636</int> <reference key="object" ref="693413486"/> <reference key="parent" ref="835318025"/> @@ -2922,7 +2890,6 @@ <string>672.IBPluginDependency</string> <string>674.IBPluginDependency</string> <string>676.IBPluginDependency</string> - <string>682.IBPluginDependency</string> <string>686.IBPluginDependency</string> <string>687.IBPluginDependency</string> <string>689.IBPluginDependency</string> @@ -3080,7 +3047,6 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>com.apple.InterfaceBuilder.CocoaPlugin</string> </object> </object> <object class="NSMutableDictionary" key="unlocalizedProperties"> @@ -3149,14 +3115,12 @@ <string>closeTabMenuItem_</string> <string>closeWindowMenuItem_</string> <string>helpMenu_</string> - <string>tabposeMenuItem_</string> </object> <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>NSMenuItem</string> <string>NSMenuItem</string> <string>NSMenu</string> - <string>NSMenuItem</string> </object> </object> <object class="NSMutableDictionary" key="toOneOutletInfosByName"> @@ -3166,7 +3130,6 @@ <string>closeTabMenuItem_</string> <string>closeWindowMenuItem_</string> <string>helpMenu_</string> - <string>tabposeMenuItem_</string> </object> <object class="NSArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -3182,10 +3145,6 @@ <string key="name">helpMenu_</string> <string key="candidateClassName">NSMenu</string> </object> - <object class="IBToOneOutletInfo"> - <string key="name">tabposeMenuItem_</string> - <string key="candidateClassName">NSMenuItem</string> - </object> </object> </object> <object class="IBClassDescriptionSource" key="sourceIdentifier"> diff --git a/chrome/app/theme/default_100_percent/common/tabpose_close.png b/chrome/app/theme/default_100_percent/common/tabpose_close.png Binary files differdeleted file mode 100644 index 69a907a..0000000 --- a/chrome/app/theme/default_100_percent/common/tabpose_close.png +++ /dev/null diff --git a/chrome/app/theme/default_100_percent/mac/tabpose_close.png b/chrome/app/theme/default_100_percent/mac/tabpose_close.png Binary files differdeleted file mode 100644 index 40ed668..0000000 --- a/chrome/app/theme/default_100_percent/mac/tabpose_close.png +++ /dev/null diff --git a/chrome/app/theme/default_200_percent/mac/tabpose_close.png b/chrome/app/theme/default_200_percent/mac/tabpose_close.png Binary files differdeleted file mode 100644 index 7fefa32..0000000 --- a/chrome/app/theme/default_200_percent/mac/tabpose_close.png +++ /dev/null diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 378f102..61fc58f 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -1075,7 +1075,6 @@ <structure type="chrome_scaled_image" name="IDR_TAB_ACTIVE_RIGHT" file="mac/tab_active_right.png" /> <structure type="chrome_scaled_image" name="IDR_SWIPE_BACK" file="back_large.png" /> <structure type="chrome_scaled_image" name="IDR_SWIPE_FORWARD" file="forward_large.png" /> - <structure type="chrome_scaled_image" name="IDR_TABPOSE_CLOSE" file="mac/tabpose_close.png" /> </if> <!-- Note: Tab close buttons are not traditional buttons. Tab close buttons fill a background with a color from the theme, tile IDR_CLOSE_1 over it, diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index e06358a..8d8cbcf 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -427,18 +427,6 @@ const Experiment::Choice kNotificationCenterTrayBehaviorChoices[] = { // When adding a new choice, add it to the end of the list. const Experiment kExperiments[] = { { - "expose-for-tabs", // FLAGS:RECORD_UMA - IDS_FLAGS_TABPOSE_NAME, - IDS_FLAGS_TABPOSE_DESCRIPTION, - kOsMac, -#if defined(OS_MACOSX) - // The switch exists only on OS X. - SINGLE_VALUE_TYPE(switches::kEnableExposeForTabs) -#else - SINGLE_VALUE_TYPE("") -#endif - }, - { "conflicting-modules-check", // FLAGS:RECORD_UMA IDS_FLAGS_CONFLICTS_CHECK_NAME, IDS_FLAGS_CONFLICTS_CHECK_DESCRIPTION, diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h index d72223b..bd6e7a5 100644 --- a/chrome/browser/app_controller_mac.h +++ b/chrome/browser/app_controller_mac.h @@ -75,9 +75,6 @@ class WorkAreaWatcherObserver; // to it. IBOutlet NSMenu* helpMenu_; - // Outlet for the tabpose menu item so we can hide it. - IBOutlet NSMenuItem* tabposeMenuItem_; - // Indicates wheter an NSPopover is currently being shown. BOOL hasPopover_; diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 9099942..f7066a6 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -741,11 +741,6 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver { [self clearStartupUrls]; } - const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); - if (!parsed_command_line.HasSwitch(switches::kEnableExposeForTabs)) { - [tabposeMenuItem_ setHidden:YES]; - } - PrefService* localState = g_browser_process->local_state(); if (localState) { localPrefRegistrar_.Init(localState); diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index 43c296a..faf5d6f 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -36,7 +36,6 @@ class PrefRegistrySimple; class PrefService; class Profile; class ProfileManager; -class RenderWidgetSnapshotTaker; class SafeBrowsingService; class StatusTray; class StorageMonitor; @@ -145,8 +144,6 @@ class BrowserProcess { virtual GpuModeManager* gpu_mode_manager() = 0; - virtual RenderWidgetSnapshotTaker* GetRenderWidgetSnapshotTaker() = 0; - virtual AutomationProviderList* GetAutomationProviderList() = 0; virtual void CreateDevToolsHttpProtocolHandler( diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 5695607..7fec85c 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -65,7 +65,6 @@ #include "chrome/browser/shell_integration.h" #include "chrome/browser/status_icons/status_tray.h" #include "chrome/browser/storage_monitor/storage_monitor.h" -#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h" #include "chrome/browser/ui/bookmarks/bookmark_prompt_controller.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" @@ -162,7 +161,6 @@ BrowserProcessImpl::BrowserProcessImpl( created_safe_browsing_service_(false), module_ref_count_(0), did_start_(false), - render_widget_snapshot_taker_(new RenderWidgetSnapshotTaker), download_status_updater_(new DownloadStatusUpdater), local_state_task_runner_(local_state_task_runner) { g_browser_process = this; @@ -551,10 +549,6 @@ GpuModeManager* BrowserProcessImpl::gpu_mode_manager() { return gpu_mode_manager_.get(); } -RenderWidgetSnapshotTaker* BrowserProcessImpl::GetRenderWidgetSnapshotTaker() { - return render_widget_snapshot_taker_.get(); -} - AutomationProviderList* BrowserProcessImpl::GetAutomationProviderList() { DCHECK(CalledOnValidThread()); #if defined(ENABLE_AUTOMATION) diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 023ee72..5e83d00 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -89,7 +89,6 @@ class BrowserProcessImpl : public BrowserProcess, virtual IconManager* icon_manager() OVERRIDE; virtual GLStringManager* gl_string_manager() OVERRIDE; virtual GpuModeManager* gpu_mode_manager() OVERRIDE; - virtual RenderWidgetSnapshotTaker* GetRenderWidgetSnapshotTaker() OVERRIDE; virtual AutomationProviderList* GetAutomationProviderList() OVERRIDE; virtual void CreateDevToolsHttpProtocolHandler( chrome::HostDesktopType host_desktop_type, @@ -241,10 +240,6 @@ class BrowserProcessImpl : public BrowserProcess, std::string locale_; - // This service just sits around and makes snapshots for renderers. It does - // nothing in the constructor so we don't have to worry about lazy init. - scoped_ptr<RenderWidgetSnapshotTaker> render_widget_snapshot_taker_; - // Download status updates (like a changing application icon on dock/taskbar) // are global per-application. DownloadStatusUpdater does no work in the ctor // so we don't have to worry about lazy initialization. diff --git a/chrome/browser/thumbnails/render_widget_snapshot_taker.cc b/chrome/browser/thumbnails/render_widget_snapshot_taker.cc deleted file mode 100644 index f9e2263..0000000 --- a/chrome/browser/thumbnails/render_widget_snapshot_taker.cc +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (c) 2012 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. - -#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h" - -#include "base/bind.h" -#include "base/memory/scoped_ptr.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host_view.h" -#include "ui/base/layout.h" -#include "ui/gfx/size.h" -#include "ui/gfx/size_conversions.h" -#include "ui/surface/transport_dib.h" - -using content::RenderWidgetHost; - -struct RenderWidgetSnapshotTaker::AsyncRequestInfo { - SnapshotReadyCallback callback; - scoped_ptr<TransportDIB> thumbnail_dib; - RenderWidgetHost* renderer; // Not owned. -}; - -RenderWidgetSnapshotTaker::RenderWidgetSnapshotTaker() { - // The BrowserProcessImpl creates this non-lazily. If you add nontrivial - // stuff here, be sure to convert it to being lazily created. - // - // We don't register for notifications here since BrowserProcessImpl creates - // us before the NotificationService is. -} - -RenderWidgetSnapshotTaker::~RenderWidgetSnapshotTaker() { -} - -void RenderWidgetSnapshotTaker::AskForSnapshot( - RenderWidgetHost* renderer, - const SnapshotReadyCallback& callback, - gfx::Size page_size, - gfx::Size desired_size) { - // We are going to render the thumbnail asynchronously now, so keep - // this callback for later lookup when the rendering is done. - static int sequence_num = 0; - sequence_num++; - float scale_factor = ui::GetImageScale(ui::GetScaleFactorForNativeView( - renderer->GetView()->GetNativeView())); - gfx::Size desired_size_in_pixel = gfx::ToFlooredSize( - gfx::ScaleSize(desired_size, scale_factor)); - scoped_ptr<TransportDIB> thumbnail_dib(TransportDIB::Create( - desired_size_in_pixel.GetArea() * 4, sequence_num)); - -#if defined(OS_LINUX) - // TODO: IPC a handle to the renderer like Windows. - // http://code.google.com/p/chromium/issues/detail?id=89777 - NOTIMPLEMENTED(); - return; -#else - -#if defined(OS_WIN) - // Duplicate the handle to the DIB here because the renderer process does not - // have permission. The duplicated handle is owned by the renderer process, - // which is responsible for closing it. - TransportDIB::Handle renderer_dib_handle; - DuplicateHandle(GetCurrentProcess(), thumbnail_dib->handle(), - renderer->GetProcess()->GetHandle(), &renderer_dib_handle, - STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE, - FALSE, 0); - if (!renderer_dib_handle) { - LOG(WARNING) << "Could not duplicate dib handle for renderer"; - return; - } -#else - TransportDIB::Handle renderer_dib_handle = thumbnail_dib->handle(); -#endif - - linked_ptr<AsyncRequestInfo> request_info(new AsyncRequestInfo); - request_info->callback = callback; - request_info->thumbnail_dib.reset(thumbnail_dib.release()); - request_info->renderer = renderer; - SnapshotCallbackMap::value_type new_value(sequence_num, request_info); - std::pair<SnapshotCallbackMap::iterator, bool> result = - callback_map_.insert(new_value); - if (!result.second) { - NOTREACHED() << "Callback already registered?"; - return; - } - - MonitorRenderer(renderer, true); - renderer->PaintAtSize( - renderer_dib_handle, sequence_num, page_size, desired_size); - -#endif // defined(USE_X11) -} - -void RenderWidgetSnapshotTaker::CancelSnapshot( - content::RenderWidgetHost* renderer) { - SnapshotCallbackMap::iterator iterator = callback_map_.begin(); - while (iterator != callback_map_.end()) { - if (iterator->second->renderer == renderer) { - SnapshotCallbackMap::iterator nuked = iterator; - ++iterator; - callback_map_.erase(nuked); - MonitorRenderer(renderer, false); - continue; - } - ++iterator; - } -} - -void RenderWidgetSnapshotTaker::WidgetDidReceivePaintAtSizeAck( - RenderWidgetHost* widget, - int sequence_num, - const gfx::Size& size) { - // Lookup the callback, run it, and erase it. - SnapshotCallbackMap::iterator item = callback_map_.find(sequence_num); - if (item != callback_map_.end()) { - DCHECK_EQ(widget, item->second->renderer); - TransportDIB* dib = item->second->thumbnail_dib.get(); - DCHECK(dib); - if (!dib || !dib->Map()) { - return; - } - - // Create an SkBitmap from the DIB. - SkBitmap non_owned_bitmap; - SkBitmap result; - - // Fill out the non_owned_bitmap with the right config. Note that - // this code assumes that the transport dib is a 32-bit ARGB - // image. - non_owned_bitmap.setConfig(SkBitmap::kARGB_8888_Config, - size.width(), size.height()); - if (dib->size() < non_owned_bitmap.getSafeSize()) - return; - non_owned_bitmap.setPixels(dib->memory()); - - // Now alloc/copy the memory so we own it and can pass it around, - // and the memory won't go away when the DIB goes away. - // TODO: Figure out a way to avoid this copy? - non_owned_bitmap.copyTo(&result, SkBitmap::kARGB_8888_Config); - - item->second->callback.Run(result); - - // We're done with the callback, and with the DIB, so delete both. - callback_map_.erase(item); - MonitorRenderer(widget, false); - } -} - -void RenderWidgetSnapshotTaker::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case content::NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK: { - std::pair<int, gfx::Size>* size_ack_details = - content::Details<std::pair<int, gfx::Size> >(details).ptr(); - WidgetDidReceivePaintAtSizeAck( - content::Source<RenderWidgetHost>(source).ptr(), - size_ack_details->first, - size_ack_details->second); - break; - } - - default: - NOTREACHED() << "Unexpected notification type: " << type; - } -} - -void RenderWidgetSnapshotTaker::MonitorRenderer(RenderWidgetHost* renderer, - bool monitor) { - content::Source<RenderWidgetHost> renderer_source = - content::Source<RenderWidgetHost>(renderer); - if (monitor) { - int new_count = ++host_monitor_counts_[renderer]; - if (new_count == 1) { - registrar_.Add( - this, - content::NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK, - renderer_source); - } - } else { - int new_count = --host_monitor_counts_[renderer]; - if (new_count == 0) { - host_monitor_counts_.erase(renderer); - registrar_.Remove( - this, - content::NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK, - renderer_source); - } - } -} diff --git a/chrome/browser/thumbnails/render_widget_snapshot_taker.h b/chrome/browser/thumbnails/render_widget_snapshot_taker.h deleted file mode 100644 index 3f8c777..0000000 --- a/chrome/browser/thumbnails/render_widget_snapshot_taker.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2012 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_THUMBNAILS_RENDER_WIDGET_SNAPSHOT_TAKER_H_ -#define CHROME_BROWSER_THUMBNAILS_RENDER_WIDGET_SNAPSHOT_TAKER_H_ - -#include <map> - -#include "base/basictypes.h" -#include "base/callback_forward.h" -#include "base/gtest_prod_util.h" -#include "base/memory/linked_ptr.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" - -class SkBitmap; - -namespace content { -class RenderWidgetHost; -} - -namespace gfx { -class Size; -} - -class RenderWidgetSnapshotTaker : public content::NotificationObserver { - public: - typedef base::Callback<void(const SkBitmap&)> SnapshotReadyCallback; - - RenderWidgetSnapshotTaker(); - virtual ~RenderWidgetSnapshotTaker(); - - // This registers a callback that can receive the resulting SkBitmap - // from the renderer when it is done rendering it. This is asynchronous, - // and it will also fetch the bitmap even if the tab is hidden. - // In addition, if the renderer has to be invoked, the scaling of - // the thumbnail happens on the rendering thread. - // - // Takes ownership of the callback object. - // - // |page_size| is the size to render the page, and |desired_size| is - // the size to scale the resulting rendered page to (which is done - // efficiently if done in the rendering thread). The resulting image - // will be less then twice the size of the |desired_size| in both - // dimensions, but might not be the exact size requested. - void AskForSnapshot(content::RenderWidgetHost* renderer, - const SnapshotReadyCallback& callback, - gfx::Size page_size, - gfx::Size desired_size); - - // Cancel any pending snapshots requested via AskForSnapshot. - void CancelSnapshot(content::RenderWidgetHost* renderer); - - private: - FRIEND_TEST_ALL_PREFIXES(RenderWidgetSnapshotTakerTest, - WidgetDidReceivePaintAtSizeAck); - FRIEND_TEST_ALL_PREFIXES(RenderWidgetSnapshotTakerTest, - WidgetDidReceivePaintAtSizeAckFail); - - // content::NotificationObserver overrides. - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE; - - // Start or stop monitoring notifications for |renderer| based on the value - // of |monitor|. - void MonitorRenderer(content::RenderWidgetHost* renderer, bool monitor); - - void WidgetDidReceivePaintAtSizeAck(content::RenderWidgetHost* widget, - int tag, - const gfx::Size& size); - - content::NotificationRegistrar registrar_; - - // Map of callback objects by sequence number. - struct AsyncRequestInfo; - typedef std::map<int, - linked_ptr<AsyncRequestInfo> > SnapshotCallbackMap; - SnapshotCallbackMap callback_map_; - - // Count of how many outstanding snapshot requests there are for each - // RenderWidgetHost. - std::map<content::RenderWidgetHost*, int> host_monitor_counts_; - - DISALLOW_COPY_AND_ASSIGN(RenderWidgetSnapshotTaker); -}; - -#endif // CHROME_BROWSER_THUMBNAILS_RENDER_WIDGET_SNAPSHOT_TAKER_H_ diff --git a/chrome/browser/thumbnails/render_widget_snapshot_taker_unittest.cc b/chrome/browser/thumbnails/render_widget_snapshot_taker_unittest.cc deleted file mode 100644 index d44a69b..0000000 --- a/chrome/browser/thumbnails/render_widget_snapshot_taker_unittest.cc +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2013 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. - -#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h" - -#include "chrome/test/base/chrome_render_view_host_test_harness.h" - -class RenderWidgetSnapshotTakerTest : public ChromeRenderViewHostTestHarness { - public: - RenderWidgetSnapshotTakerTest() : snapshot_ready_called_(false) {} - - void SnapshotReady(const SkBitmap& bitmap) { - snapshot_ready_called_ = true; - } - - bool snapshot_ready_called() const { - return snapshot_ready_called_; - } - - private: - bool snapshot_ready_called_; -}; - -#if defined(USE_X11) -// RenderWidgetHost::AskForSnapshot is not implemented for X11 -// (http://crbug.com/89777). -#define MAYBE_WidgetDidReceivePaintAtSizeAck \ - DISABLED_WidgetDidReceivePaintAtSizeAck -#else -#define MAYBE_WidgetDidReceivePaintAtSizeAck WidgetDidReceivePaintAtSizeAck -#endif - -// Just checks the callback runs in WidgetDidReceivePaintAtSizeAck. -TEST_F(RenderWidgetSnapshotTakerTest, MAYBE_WidgetDidReceivePaintAtSizeAck) { - RenderWidgetSnapshotTaker snapshot_taker; - const gfx::Size size(100, 100); - snapshot_taker.AskForSnapshot( - rvh(), - base::Bind(&RenderWidgetSnapshotTakerTest::SnapshotReady, - base::Unretained(this)), - size, - size); - EXPECT_EQ(1U, snapshot_taker.callback_map_.size()); - const int sequence_num = 1; - snapshot_taker.WidgetDidReceivePaintAtSizeAck( - content::RenderViewHostTestHarness::rvh(), - sequence_num, - size); - EXPECT_TRUE(snapshot_taker.callback_map_.empty()); - EXPECT_TRUE(snapshot_ready_called()); -} - -#if defined(USE_X11) -// RenderWidgetHost::AskForSnapshot is not implemented for X11 -// (http://crbug.com/89777). -#define MAYBE_WidgetDidReceivePaintAtSizeAckFail \ - DISABLED_WidgetDidReceivePaintAtSizeAckFail -#else -#define MAYBE_WidgetDidReceivePaintAtSizeAckFail \ - WidgetDidReceivePaintAtSizeAckFail -#endif - -// Checks the case where RenderWidgetSnapshotTaker receives an ack with a wrong -// size. The should result in a failure and the callback should not be called. -TEST_F(RenderWidgetSnapshotTakerTest, - MAYBE_WidgetDidReceivePaintAtSizeAckFail) { - RenderWidgetSnapshotTaker snapshot_taker; - const gfx::Size size(100, 100); - snapshot_taker.AskForSnapshot( - rvh(), - base::Bind(&RenderWidgetSnapshotTakerTest::SnapshotReady, - base::Unretained(this)), - size, - size); - EXPECT_EQ(1U, snapshot_taker.callback_map_.size()); - const int sequence_num = 1; - // Ensure this is bigger than the max scale factor X the size. - const gfx::Size size2(300, 300); - snapshot_taker.WidgetDidReceivePaintAtSizeAck( - content::RenderViewHostTestHarness::rvh(), - sequence_num, - size2); - EXPECT_FALSE(snapshot_taker.callback_map_.empty()); - EXPECT_FALSE(snapshot_ready_called()); -} diff --git a/chrome/browser/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/thumbnails/thumbnail_tab_helper.cc index 17f68f1..0b06279 100644 --- a/chrome/browser/thumbnails/thumbnail_tab_helper.cc +++ b/chrome/browser/thumbnails/thumbnail_tab_helper.cc @@ -6,7 +6,6 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h" #include "chrome/browser/thumbnails/thumbnail_service.h" #include "chrome/browser/thumbnails/thumbnail_service_factory.h" #include "chrome/browser/thumbnails/thumbnailing_algorithm.h" @@ -164,9 +163,6 @@ void ThumbnailTabHelper::Observe(int type, void ThumbnailTabHelper::RenderViewDeleted( content::RenderViewHost* render_view_host) { - g_browser_process->GetRenderWidgetSnapshotTaker()->CancelSnapshot( - render_view_host); - bool registered = registrar_.IsRegistered( this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 0015ff7..223136a 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc @@ -290,7 +290,6 @@ bool BrowserCommandController::IsReservedCommandOrKey( command_id == IDC_RESTORE_TAB || command_id == IDC_SELECT_NEXT_TAB || command_id == IDC_SELECT_PREVIOUS_TAB || - command_id == IDC_TABPOSE || command_id == IDC_EXIT; } @@ -415,9 +414,6 @@ void BrowserCommandController::ExecuteCommandWithDisposition( base::UserMetricsAction("Accel_SelectPreviousTab")); SelectPreviousTab(browser_); break; - case IDC_TABPOSE: - OpenTabpose(browser_); - break; case IDC_MOVE_TAB_NEXT: MoveTabNext(browser_); break; @@ -1016,7 +1012,6 @@ void BrowserCommandController::InitCommandState() { IDC_WIN8_DESKTOP_RESTART : IDC_WIN8_METRO_RESTART; command_updater_.UpdateCommandEnabled(restart_mode, normal_window); #endif - command_updater_.UpdateCommandEnabled(IDC_TABPOSE, normal_window); // Show various bits of UI command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window); diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 53a31a6..ed28675 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc @@ -555,20 +555,6 @@ void SelectPreviousTab(Browser* browser) { browser->tab_strip_model()->SelectPreviousTab(); } -void OpenTabpose(Browser* browser) { -#if defined(OS_MACOSX) - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExposeForTabs)) { - return; - } - - content::RecordAction(UserMetricsAction("OpenTabpose")); - browser->window()->OpenTabpose(); -#else - NOTREACHED(); -#endif -} - void MoveTabNext(Browser* browser) { content::RecordAction(UserMetricsAction("MoveTabNext")); browser->tab_strip_model()->MoveTabNext(); diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h index b4fa6fc..8a3b590 100644 --- a/chrome/browser/ui/browser_commands.h +++ b/chrome/browser/ui/browser_commands.h @@ -81,7 +81,6 @@ TabStripModelDelegate::RestoreTabType GetRestoreTabType( const Browser* browser); void SelectNextTab(Browser* browser); void SelectPreviousTab(Browser* browser); -void OpenTabpose(Browser* browser); // Mac-only void MoveTabNext(Browser* browser); void MoveTabPrevious(Browser* browser); void SelectNumberedTab(Browser* browser, int index); diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 6a23b11..966b529 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h @@ -318,9 +318,6 @@ class BrowserWindow : public ui::BaseWindow { virtual void Paste() = 0; #if defined(OS_MACOSX) - // Opens the tabpose view. - virtual void OpenTabpose() = 0; - // Enters Mac specific fullscreen mode with chrome displayed (e.g. omnibox) // on OSX 10.7+, a.k.a. Lion Fullscreen mode. // Invalid to call on OSX earlier than 10.7. diff --git a/chrome/browser/ui/cocoa/accelerators_cocoa.mm b/chrome/browser/ui/cocoa/accelerators_cocoa.mm index b4ee271..8291444 100644 --- a/chrome/browser/ui/cocoa/accelerators_cocoa.mm +++ b/chrome/browser/ui/cocoa/accelerators_cocoa.mm @@ -95,7 +95,6 @@ const struct AcceleratorMapping { {IDC_SELECT_NEXT_TAB, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_RIGHT}, {IDC_SELECT_PREVIOUS_TAB, NSCommandKeyMask | NSAlternateKeyMask, ui::VKEY_LEFT}, - {IDC_TABPOSE, NSCommandKeyMask | NSControlKeyMask, ui::VKEY_T}, {IDC_HELP_PAGE_VIA_MENU, NSCommandKeyMask | NSShiftKeyMask, ui::VKEY_OEM_2}, }; diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h index 24c7bbc..cb81613 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.h +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h @@ -138,7 +138,6 @@ class BrowserWindowCocoa : virtual void Cut() OVERRIDE; virtual void Copy() OVERRIDE; virtual void Paste() OVERRIDE; - virtual void OpenTabpose() OVERRIDE; virtual void EnterFullscreenWithChrome() OVERRIDE; virtual bool IsFullscreenWithChrome() OVERRIDE; virtual bool IsFullscreenWithoutChrome() OVERRIDE; diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.mm b/chrome/browser/ui/cocoa/browser_window_cocoa.mm index 40190be..d91c34a 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa.mm @@ -600,10 +600,6 @@ void BrowserWindowCocoa::Paste() { [NSApp sendAction:@selector(paste:) to:nil from:nil]; } -void BrowserWindowCocoa::OpenTabpose() { - [controller_ openTabpose]; -} - void BrowserWindowCocoa::EnterFullscreenWithChrome() { // This method cannot be called if simplified fullscreen is enabled. const CommandLine* command_line = CommandLine::ForCurrentProcess(); diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index c1b15df..b769147 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h @@ -457,9 +457,6 @@ class WebContents; // 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/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 8935203..55cf89d 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm @@ -59,7 +59,6 @@ #import "chrome/browser/ui/cocoa/tab_contents/overlayable_contents_controller.h" #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h" -#import "chrome/browser/ui/cocoa/tabpose_window.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h" #import "chrome/browser/ui/cocoa/tabs/tab_view.h" @@ -1739,7 +1738,6 @@ enum { // TODO(pinkerton): figure out page-up, http://crbug.com/16305 } else if (deltaY < -0.5) { // TODO(pinkerton): figure out page-down, http://crbug.com/16305 - chrome::ExecuteCommand(browser_.get(), IDC_TABPOSE); } // Ensure the command is valid first (ExecuteCommand() won't do that) and @@ -2167,47 +2165,6 @@ willAnimateFromState:(BookmarkBar::State)oldState return [focused isKindOfClass:[AutocompleteTextFieldEditor class]]; } -- (void)tabposeWillClose:(NSNotification*)notif { - // Re-show the container after Tabpose closes. - [[infoBarContainerController_ view] setHidden:NO]; -} - -- (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]; - // Take out the anti-spoof height so that Tabpose doesn't draw on top of the - // browser chrome. - activeArea.size.height += - NSHeight([[infoBarContainerController_ view] frame]) - - [infoBarContainerController_ overlappingTipHeight]; - if ([self isBookmarkBarVisible] && [self placeBookmarkBarBelowInfoBar]) { - NSView* bookmarkBarView = [bookmarkBarController_ view]; - activeArea.size.height += NSHeight([bookmarkBarView frame]); - } - - // Hide the infobar container so that the anti-spoof bulge doesn't show when - // Tabpose is open. - [[infoBarContainerController_ view] setHidden:YES]; - - TabposeWindow* window = - [TabposeWindow openTabposeFor:[self window] - rect:activeArea - slomo:slomo - tabStripModel:browser_->tab_strip_model()]; - - // When the Tabpose window closes, the infobar container needs to be made - // visible again. - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center addObserver:self - selector:@selector(tabposeWillClose:) - name:NSWindowWillCloseNotification - object:window]; -} - @end // @implementation BrowserWindowController(Fullscreen) diff --git a/chrome/browser/ui/cocoa/tabpose_window.h b/chrome/browser/ui/cocoa/tabpose_window.h deleted file mode 100644 index eb6ea9c4..0000000 --- a/chrome/browser/ui/cocoa/tabpose_window.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2011 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_UI_COCOA_TABPOSE_WINDOW_H_ -#define CHROME_BROWSER_UI_COCOA_TABPOSE_WINDOW_H_ - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_cftyperef.h" - -#include "base/mac/scoped_nsobject.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" - -namespace tabpose { - -class Tile; -class TileSet; - -} - -namespace tabpose { - -enum WindowState { - kFadingIn, - kFadedIn, - kFadingOut, -}; - -} // namespace tabpose - -class TabStripModel; -class TabStripModelObserverBridge; - -// 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 - tabpose::WindowState state_; - - // 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 - - // Top gradient. - CALayer* topGradient_; // weak - - // The layer drawn behind the currently selected tile. - CALayer* selectionHighlight_; // weak - - // Colors used by the layers. - base::ScopedCFTypeRef<CGColorRef> gray_; - base::ScopedCFTypeRef<CGColorRef> darkBlue_; - - TabStripModel* tabStripModel_; // weak - - // Stores all preview layers. The order in here matches the order in - // the tabstrip model. - base::scoped_nsobject<NSMutableArray> allThumbnailLayers_; - - base::scoped_nsobject<NSMutableArray> allFaviconLayers_; - base::scoped_nsobject<NSMutableArray> allTitleLayers_; - - // Manages the state of all layers. - scoped_ptr<tabpose::TileSet> tileSet_; - - // The rectangle of the window that contains all layers. This is the - // rectangle occupied by |bgLayer_|. - NSRect containingRect_; - - // Informs us of added/removed/updated tabs. - scoped_ptr<TabStripModelObserverBridge> tabStripModelObserverBridge_; - - // The icon used for the closebutton layers. - base::scoped_nsobject<NSImage> closeIcon_; - - // True if all close layers should be shown (as opposed to just the close - // layer of the currently selected thumbnail). - BOOL showAllCloseLayers_; -} - -// 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 - tabStripModel:(TabStripModel*)tabStripModel; -@end - -@interface TabposeWindow (TestingAPI) -- (void)selectTileAtIndexWithoutAnimation:(int)newIndex; -- (NSUInteger)thumbnailLayerCount; -- (int)selectedIndex; -@end - -#endif // CHROME_BROWSER_UI_COCOA_TABPOSE_WINDOW_H_ diff --git a/chrome/browser/ui/cocoa/tabpose_window.mm b/chrome/browser/ui/cocoa/tabpose_window.mm deleted file mode 100644 index f4cc4fc..0000000 --- a/chrome/browser/ui/cocoa/tabpose_window.mm +++ /dev/null @@ -1,1664 +0,0 @@ -// Copyright (c) 2012 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/ui/cocoa/tabpose_window.h" - -#import <QuartzCore/QuartzCore.h> - -#include <algorithm> - -#include "base/mac/mac_util.h" -#include "base/mac/scoped_cftyperef.h" -#include "base/memory/weak_ptr.h" -#include "base/prefs/pref_service.h" -#include "base/strings/sys_string_conversions.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/devtools/devtools_window.h" -#include "chrome/browser/extensions/tab_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h" -#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" -#import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" -#import "chrome/browser/ui/cocoa/browser_window_controller.h" -#import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" -#import "chrome/browser/ui/cocoa/tab_contents/favicon_util_mac.h" -#import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" -#import "chrome/browser/ui/cocoa/tabs/tab_strip_model_observer_bridge.h" -#include "chrome/common/pref_names.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_view.h" -#include "grit/theme_resources.h" -#include "grit/ui_resources.h" -#include "skia/ext/skia_utils_mac.h" -#include "third_party/skia/include/utils/mac/SkCGUtils.h" -#include "ui/base/cocoa/animation_utils.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image.h" -#include "ui/gfx/scoped_cg_context_save_gstate_mac.h" - -using content::BrowserThread; -using content::RenderWidgetHost; - -// Height of the bottom gradient, in pixels. -const CGFloat kBottomGradientHeight = 50; - -// The shade of gray at the top of the window. There's a gradient from -// this to |kCentralGray| at the top of the window. -const CGFloat kTopGray = 0.77; - -// The shade of gray at the center of the window. Most of the window background -// has this color. -const CGFloat kCentralGray = 0.6; - -// The shade of gray at the bottom of the window. There's a gradient from -// |kCentralGray| to this at the bottom of the window, |kBottomGradientHeight| -// high. -const CGFloat kBottomGray = 0.5; - -NSString* const kAnimationIdKey = @"AnimationId"; -NSString* const kAnimationIdFadeIn = @"FadeIn"; -NSString* const kAnimationIdFadeOut = @"FadeOut"; - -const CGFloat kDefaultAnimationDuration = 0.25; // In seconds. -const CGFloat kSlomoFactor = 4; -const CGFloat kObserverChangeAnimationDuration = 0.25; // In seconds. -const CGFloat kSelectionInset = 5; - -// CAGradientLayer is 10.6-only -- roll our own. -@interface GrayGradientLayer : CALayer { - @private - CGFloat startGray_; - CGFloat endGray_; -} -- (id)initWithStartGray:(CGFloat)startGray endGray:(CGFloat)endGray; -- (void)drawInContext:(CGContextRef)context; -@end - -@implementation GrayGradientLayer -- (id)initWithStartGray:(CGFloat)startGray endGray:(CGFloat)endGray { - if ((self = [super init])) { - startGray_ = startGray; - endGray_ = endGray; - } - return self; -} - -- (void)drawInContext:(CGContextRef)context { - base::ScopedCFTypeRef<CGColorSpaceRef> grayColorSpace( - CGColorSpaceCreateWithName(kCGColorSpaceGenericGray)); - CGFloat grays[] = { startGray_, 1.0, endGray_, 1.0 }; - CGFloat locations[] = { 0, 1 }; - base::ScopedCFTypeRef<CGGradientRef> gradient( - CGGradientCreateWithColorComponents( - grayColorSpace.get(), grays, locations, arraysize(locations))); - CGPoint topLeft = CGPointMake(0.0, self.bounds.size.height); - CGContextDrawLinearGradient(context, gradient.get(), topLeft, CGPointZero, 0); -} -@end - -namespace tabpose { -class ThumbnailLoader; -} - -// A CALayer that draws a thumbnail for a WebContents object. The layer -// tries to draw the WebContents's backing store directly if possible, and -// requests a thumbnail bitmap from the WebContents's renderer process if not. -@interface ThumbnailLayer : CALayer { - // The WebContents the thumbnail is for. - content::WebContents* contents_; // weak - - // The size the thumbnail is drawn at when zoomed in. - NSSize fullSize_; - - // Used to load a thumbnail, if required. - scoped_refptr<tabpose::ThumbnailLoader> loader_; - - // If the backing store couldn't be used and a thumbnail was returned from a - // renderer process, it's stored in |thumbnail_|. - base::ScopedCFTypeRef<CGImageRef> thumbnail_; - - // True if the layer already sent a thumbnail request to a renderer. - BOOL didSendLoad_; -} -- (id)initWithWebContents:(content::WebContents*)contents - fullSize:(NSSize)fullSize; -- (void)drawInContext:(CGContextRef)context; -- (void)setThumbnail:(const SkBitmap&)bitmap; -@end - -namespace tabpose { - -// ThumbnailLoader talks to the renderer process to load a thumbnail of a given -// RenderWidgetHost, and sends the thumbnail back to a ThumbnailLayer once it -// comes back from the renderer. -class ThumbnailLoader : public base::RefCountedThreadSafe<ThumbnailLoader> { - public: - ThumbnailLoader(gfx::Size size, RenderWidgetHost* rwh, ThumbnailLayer* layer) - : size_(size), rwh_(rwh), layer_(layer), weak_factory_(this) {} - - // Starts the fetch. - void LoadThumbnail(); - - private: - friend class base::RefCountedThreadSafe<ThumbnailLoader>; - ~ThumbnailLoader() { - } - - void DidReceiveBitmap(const SkBitmap& bitmap) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - [layer_ setThumbnail:bitmap]; - } - - gfx::Size size_; - RenderWidgetHost* rwh_; // weak - ThumbnailLayer* layer_; // weak, owns us - base::WeakPtrFactory<ThumbnailLoader> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ThumbnailLoader); -}; - -void ThumbnailLoader::LoadThumbnail() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - // As mentioned in ThumbnailLayer's -drawInContext:, it's sufficient to have - // thumbnails at the zoomed-out pixel size for all but the thumbnail the user - // clicks on in the end. But we don't don't which thumbnail that will be, so - // keep it simple and request full thumbnails for everything. - // TODO(thakis): Request smaller thumbnails for users with many tabs. - gfx::Size page_size(size_); // Logical size the renderer renders at. - gfx::Size pixel_size(size_); // Physical pixel size the image is rendered at. - - // Will send an IPC to the renderer on the IO thread. - g_browser_process->GetRenderWidgetSnapshotTaker()->AskForSnapshot( - rwh_, - base::Bind(&ThumbnailLoader::DidReceiveBitmap, - weak_factory_.GetWeakPtr()), - page_size, - pixel_size); -} - -} // namespace tabpose - -@implementation ThumbnailLayer - -- (id)initWithWebContents:(content::WebContents*)contents - fullSize:(NSSize)fullSize { - CHECK(contents); - if ((self = [super init])) { - contents_ = contents; - fullSize_ = fullSize; - } - return self; -} - -- (void)setWebContents:(content::WebContents*)contents { - contents_ = contents; -} - -- (void)setThumbnail:(const SkBitmap&)bitmap { - // SkCreateCGImageRef() holds on to |bitmaps|'s memory, so this doesn't - // create a copy. The renderer always draws data in the system colorspace. - thumbnail_.reset(SkCreateCGImageRefWithColorspace( - bitmap, base::mac::GetSystemColorSpace())); - loader_ = NULL; - [self setNeedsDisplay]; -} - -- (int)topOffset { - int topOffset = 0; - - // Medium term, we want to show thumbs of the actual info bar views, which - // means I need to create InfoBarControllers here. - NSWindow* window = [contents_->GetView()->GetNativeView() window]; - NSWindowController* windowController = [window windowController]; - if ([windowController isKindOfClass:[BrowserWindowController class]]) { - BrowserWindowController* bwc = - static_cast<BrowserWindowController*>(windowController); - InfoBarContainerController* infoBarContainer = - [bwc infoBarContainerController]; - // TODO(thakis|rsesek): This is not correct for background tabs with - // infobars as the aspect ratio will be wrong. Fix that. - topOffset += NSHeight([[infoBarContainer view] frame]) - - [infoBarContainer overlappingTipHeight]; - } - - BookmarkTabHelper* bookmark_tab_helper = - BookmarkTabHelper::FromWebContents(contents_); - Profile* profile = - Profile::FromBrowserContext(contents_->GetBrowserContext()); - bool always_show_bookmark_bar = - profile->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); - bool has_detached_bookmark_bar = - bookmark_tab_helper->ShouldShowBookmarkBar() && - !always_show_bookmark_bar; - if (has_detached_bookmark_bar) - topOffset += chrome::kNTPBookmarkBarHeight; - - return topOffset; -} - -- (int)bottomOffset { - int bottomOffset = 0; - DevToolsWindow* devToolsWindow = - DevToolsWindow::GetDockedInstanceForInspectedTab(contents_); - content::WebContents* devToolsContents = - devToolsWindow ? devToolsWindow->web_contents() : NULL; - if (devToolsContents && devToolsContents->GetRenderViewHost() && - devToolsContents->GetRenderViewHost()->GetView()) { - // The devtool's size might not be up-to-date, but since its height doesn't - // change on window resize, and since most users don't use devtools, this is - // good enough. - bottomOffset += devToolsContents->GetRenderViewHost()->GetView()-> - GetViewBounds().height(); - bottomOffset += 1; // :-( Divider line between web contents and devtools. - } - return bottomOffset; -} - -- (void)drawInContext:(CGContextRef)context { - RenderWidgetHost* rwh = contents_->GetRenderViewHost(); - // NULL if renderer crashed. - content::RenderWidgetHostView* rwhv = rwh ? rwh->GetView() : NULL; - if (!rwhv) { - // TODO(thakis): Maybe draw a sad tab layer? - [super drawInContext:context]; - return; - } - - // The size of the WebContents's RenderWidgetHost might not fit to the - // current browser window at all, for example if the window was resized while - // this WebContents object was not an active tab. - // Compute the required size ourselves. Leave room for eventual infobars and - // a detached bookmarks bar on the top, and for the devtools on the bottom. - // Download shelf is not included in the |fullSize| rect, so no need to - // correct for it here. - // TODO(thakis): This is not resolution-independent. - int topOffset = [self topOffset]; - int bottomOffset = [self bottomOffset]; - gfx::Size desiredThumbSize(fullSize_.width, - fullSize_.height - topOffset - bottomOffset); - - // We need to ask the renderer for a thumbnail if - // a) there's no backing store or - // b) the backing store's size doesn't match our required size and - // c) we didn't already send a thumbnail request to the renderer. - bool draw_backing_store = rwh->GetBackingStoreSize() == desiredThumbSize; - - // Next weirdness: The destination rect. If the layer is |fullSize_| big, the - // destination rect is (0, bottomOffset), (fullSize_.width, topOffset). But we - // might be amidst an animation, so interpolate that rect. - CGRect destRect = [self bounds]; - CGFloat scale = destRect.size.width / fullSize_.width; - destRect.origin.y += bottomOffset * scale; - destRect.size.height -= (bottomOffset + topOffset) * scale; - - // TODO(thakis): Draw infobars, detached bookmark bar as well. - - // If we haven't already, sent a thumbnail request to the renderer. - if (!draw_backing_store && !didSendLoad_) { - // Either the tab was never visible, or its backing store got evicted, or - // the size of the backing store is wrong. - - // We only need a thumbnail the size of the zoomed-out layer for all - // layers except the one the user clicks on. But since we can't know which - // layer that is, request full-resolution layers for all tabs. This is - // simple and seems to work in practice. - loader_ = new tabpose::ThumbnailLoader(desiredThumbSize, rwh, self); - loader_->LoadThumbnail(); - didSendLoad_ = YES; - - // Fill with bg color. - [super drawInContext:context]; - } - - if (draw_backing_store) { - // Backing store 'cache' hit! - // TODO(thakis): Add a sublayer for each accelerated surface in the rwhv. - // Until then, accelerated layers (CoreAnimation NPAPI plugins, compositor) - // won't show up in tabpose. - rwh->CopyFromBackingStoreToCGContext(destRect, context); - } else if (thumbnail_) { - // No cache hit, but the renderer returned a thumbnail to us. - gfx::ScopedCGContextSaveGState save_gstate(context); - CGContextSetInterpolationQuality(context, kCGInterpolationHigh); - CGContextDrawImage(context, destRect, thumbnail_.get()); - } -} - -@end - -// Given the number |n| of tiles with a desired aspect ratio of |a| and a -// desired distance |dx|, |dy| between tiles, returns how many tiles fit -// vertically into a rectangle with the dimensions |w_c|, |h_c|. This returns -// an exact solution, which is usually a fractional number. -static float FitNRectsWithAspectIntoBoundingSizeWithConstantPadding( - int n, double a, int w_c, int h_c, int dx, int dy) { - // We want to have the small rects have the same aspect ratio a as a full - // tab. Let w, h be the size of a small rect, and w_c, h_c the size of the - // container. dx, dy are the distances between small rects in x, y direction. - - // Geometry yields: - // w_c = nx * (w + dx) - dx <=> w = (w_c + d_x) / nx - d_x - // h_c = ny * (h + dy) - dy <=> h = (h_c + d_y) / ny - d_t - // Plugging this into - // a := tab_width / tab_height = w / h - // yields - // a = ((w_c - (nx - 1)*d_x)*ny) / (nx*(h_c - (ny - 1)*d_y)) - // Plugging in nx = n/ny and pen and paper (or wolfram alpha: - // http://www.wolframalpha.com/input/?i=(-sqrt((d+n-a+f+n)^2-4+(a+f%2Ba+h)+(-d+n-n+w))%2Ba+f+n-d+n)/(2+a+(f%2Bh)) , (solution for nx) - // http://www.wolframalpha.com/input/?i=+(-sqrt((a+f+n-d+n)^2-4+(d%2Bw)+(-a+f+n-a+h+n))-a+f+n%2Bd+n)/(2+(d%2Bw)) , (solution for ny) - // ) gives us nx and ny (but the wrong root -- s/-sqrt(FOO)/sqrt(FOO)/. - - // This function returns ny. - return (sqrt(pow(n * (a * dy - dx), 2) + - 4 * n * a * (dx + w_c) * (dy + h_c)) - - n * (a * dy - dx)) - / - (2 * (dx + w_c)); -} - -namespace tabpose { - -CGFloat ScaleWithOrigin(CGFloat x, CGFloat origin, CGFloat scale) { - return (x - origin) * scale + origin; -} - -NSRect ScaleRectWithOrigin(NSRect r, NSPoint p, CGFloat scale) { - return NSMakeRect(ScaleWithOrigin(NSMinX(r), p.x, scale), - ScaleWithOrigin(NSMinY(r), p.y, scale), - NSWidth(r) * scale, - NSHeight(r) * scale); -} - -// A tile is what is shown for a single tab in tabpose mode. It consists of a -// title, favicon, thumbnail image, and pre- and postanimation rects. -class Tile { - public: - Tile() {} - - // Returns the rectangle this thumbnail is at at the beginning of the zoom-in - // animation. |tile| is the rectangle that's covering the whole tab area when - // the animation starts. - NSRect GetStartRectRelativeTo(const Tile& tile) const; - NSRect thumb_rect() const { return thumb_rect_; } - - NSRect GetFaviconStartRectRelativeTo(const Tile& tile) const; - NSRect favicon_rect() const { return NSIntegralRect(favicon_rect_); } - NSImage* favicon() const; - - // This changes |title_rect| and |favicon_rect| such that the favicon is on - // the font's baseline and that the minimum distance between thumb rect and - // favicon and title rects doesn't change. - // The view code - // 1. queries desired font size by calling |title_font_size()| - // 2. loads that font - // 3. calls |set_font_metrics()| which updates the title rect - // 4. receives the title rect and puts the title on it with the font from 2. - void set_font_metrics(CGFloat ascender, CGFloat descender); - CGFloat title_font_size() const { return title_font_size_; } - - NSRect GetTitleStartRectRelativeTo(const Tile& tile) const; - NSRect title_rect() const { return NSIntegralRect(title_rect_); } - - // Returns an unelided title. The view logic is responsible for eliding. - const base::string16& title() const { - return contents_->GetTitle(); - } - - content::WebContents* web_contents() const { return contents_; } - void set_tab_contents(content::WebContents* new_contents) { - contents_ = new_contents; - } - - private: - friend class TileSet; - - // The thumb rect includes infobars, detached thumbnail bar, web contents, - // and devtools. - NSRect thumb_rect_; - NSRect start_thumb_rect_; - - NSRect favicon_rect_; - - CGFloat title_font_size_; - NSRect title_rect_; - - content::WebContents* contents_; // weak - - DISALLOW_COPY_AND_ASSIGN(Tile); -}; - -NSRect Tile::GetStartRectRelativeTo(const Tile& tile) const { - NSRect rect = start_thumb_rect_; - rect.origin.x -= tile.start_thumb_rect_.origin.x; - rect.origin.y -= tile.start_thumb_rect_.origin.y; - return rect; -} - -NSRect Tile::GetFaviconStartRectRelativeTo(const Tile& tile) const { - NSRect thumb_start = GetStartRectRelativeTo(tile); - CGFloat scale_to_start = NSWidth(thumb_start) / NSWidth(thumb_rect_); - NSRect rect = - ScaleRectWithOrigin(favicon_rect_, thumb_rect_.origin, scale_to_start); - rect.origin.x += NSMinX(thumb_start) - NSMinX(thumb_rect_); - rect.origin.y += NSMinY(thumb_start) - NSMinY(thumb_rect_); - return rect; -} - -NSImage* Tile::favicon() const { - extensions::TabHelper* extensions_tab_helper = - extensions::TabHelper::FromWebContents(contents_); - if (extensions_tab_helper->is_app()) { - SkBitmap* bitmap = extensions_tab_helper->GetExtensionAppIcon(); - if (bitmap) - return gfx::SkBitmapToNSImage(*bitmap); - } - return mac::FaviconForWebContents(contents_); -} - -NSRect Tile::GetTitleStartRectRelativeTo(const Tile& tile) const { - NSRect thumb_start = GetStartRectRelativeTo(tile); - CGFloat scale_to_start = NSWidth(thumb_start) / NSWidth(thumb_rect_); - NSRect rect = - ScaleRectWithOrigin(title_rect_, thumb_rect_.origin, scale_to_start); - rect.origin.x += NSMinX(thumb_start) - NSMinX(thumb_rect_); - rect.origin.y += NSMinY(thumb_start) - NSMinY(thumb_rect_); - return rect; -} - -// Changes |title_rect| and |favicon_rect| such that the favicon's and the -// title's vertical center is aligned and that the minimum distance between -// the thumb rect and favicon and title rects doesn't change. -void Tile::set_font_metrics(CGFloat ascender, CGFloat descender) { - // Make the title height big enough to fit the font, and adopt the title - // position to keep its distance from the thumb rect. - title_rect_.origin.y -= ascender + descender - NSHeight(title_rect_); - title_rect_.size.height = ascender + descender; - - // Align vertical center. Both rects are currently aligned on their top edge. - CGFloat delta_y = NSMidY(title_rect_) - NSMidY(favicon_rect_); - if (delta_y > 0) { - // Title is higher: Move favicon down to align the centers. - favicon_rect_.origin.y += delta_y; - } else { - // Favicon is higher: Move title down to align the centers. - title_rect_.origin.y -= delta_y; - } -} - -// A tileset is responsible for owning and laying out all |Tile|s shown in a -// tabpose window. -class TileSet { - public: - TileSet() {} - - // Fills in |tiles_|. - void Build(TabStripModel* source_model); - - // Computes coordinates for |tiles_|. - void Layout(NSRect containing_rect); - - int selected_index() const { return selected_index_; } - void set_selected_index(int index); - - const Tile& selected_tile() const { return *tiles_[selected_index()]; } - Tile& tile_at(int index) { return *tiles_[index]; } - const Tile& tile_at(int index) const { return *tiles_[index]; } - - // These return which index needs to be selected when the user presses - // up, down, left, or right respectively. - int up_index() const; - int down_index() const; - int left_index() const; - int right_index() const; - - // These return which index needs to be selected on tab / shift-tab. - int next_index() const; - int previous_index() const; - - // Inserts a new Tile object containing |contents| at |index|. Does no - // relayout. - void InsertTileAt(int index, content::WebContents* contents); - - // Removes the Tile object at |index|. Does no relayout. - void RemoveTileAt(int index); - - // Moves the Tile object at |from_index| to |to_index|. Since this doesn't - // change the number of tiles, relayout can be done just by swapping the - // tile rectangles in the index interval [from_index, to_index], so this does - // layout. - void MoveTileFromTo(int from_index, int to_index); - - private: - int count_x() const { - return ceilf(tiles_.size() / static_cast<float>(count_y_)); - } - int count_y() const { - return count_y_; - } - int last_row_count_x() const { - return tiles_.size() - count_x() * (count_y() - 1); - } - int tiles_in_row(int row) const { - return row != count_y() - 1 ? count_x() : last_row_count_x(); - } - void index_to_tile_xy(int index, int* tile_x, int* tile_y) const { - *tile_x = index % count_x(); - *tile_y = index / count_x(); - } - int tile_xy_to_index(int tile_x, int tile_y) const { - return tile_y * count_x() + tile_x; - } - - ScopedVector<Tile> tiles_; - int selected_index_; - int count_y_; - - DISALLOW_COPY_AND_ASSIGN(TileSet); -}; - -void TileSet::Build(TabStripModel* source_model) { - selected_index_ = source_model->active_index(); - tiles_.resize(source_model->count()); - for (size_t i = 0; i < tiles_.size(); ++i) { - tiles_[i] = new Tile; - tiles_[i]->contents_ = source_model->GetWebContentsAt(i); - } -} - -void TileSet::Layout(NSRect containing_rect) { - int tile_count = tiles_.size(); - if (tile_count == 0) // Happens e.g. during test shutdown. - return; - - // Room around the tiles insde of |containing_rect|. - const int kSmallPaddingTop = 30; - const int kSmallPaddingLeft = 30; - const int kSmallPaddingRight = 30; - const int kSmallPaddingBottom = 30; - - // Favicon / title area. - const int kThumbTitlePaddingY = 6; - const int kFaviconSize = 16; - const int kTitleHeight = 14; // Font size. - const int kTitleExtraHeight = kThumbTitlePaddingY + kTitleHeight; - const int kFaviconExtraHeight = kThumbTitlePaddingY + kFaviconSize; - const int kFaviconTitleDistanceX = 6; - const int kFooterExtraHeight = - std::max(kFaviconExtraHeight, kTitleExtraHeight); - - // Room between the tiles. - const int kSmallPaddingX = 15; - const int kSmallPaddingY = kFooterExtraHeight; - - // Aspect ratio of the containing rect. - CGFloat aspect = NSWidth(containing_rect) / NSHeight(containing_rect); - - // Room left in container after the outer padding is removed. - double container_width = - NSWidth(containing_rect) - kSmallPaddingLeft - kSmallPaddingRight; - double container_height = - NSHeight(containing_rect) - kSmallPaddingTop - kSmallPaddingBottom; - - // The tricky part is figuring out the size of a tab thumbnail, or since the - // size of the containing rect is known, the number of tiles in x and y - // direction. - // Given are the size of the containing rect, and the number of thumbnails - // that need to fit into that rect. The aspect ratio of the thumbnails needs - // to be the same as that of |containing_rect|, else they will look distorted. - // The thumbnails need to be distributed such that - // |count_x * count_y >= tile_count|, and such that wasted space is minimized. - // See the comments in - // |FitNRectsWithAspectIntoBoundingSizeWithConstantPadding()| for a more - // detailed discussion. - // TODO(thakis): It might be good enough to choose |count_x| and |count_y| - // such that count_x / count_y is roughly equal to |aspect|? - double fny = FitNRectsWithAspectIntoBoundingSizeWithConstantPadding( - tile_count, aspect, - container_width, container_height - kFooterExtraHeight, - kSmallPaddingX, kSmallPaddingY + kFooterExtraHeight); - count_y_ = roundf(fny); - - // Now that |count_x()| and |count_y_| are known, it's straightforward to - // compute thumbnail width/height. See comment in - // |FitNRectsWithAspectIntoBoundingSizeWithConstantPadding| for the derivation - // of these two formulas. - int small_width = - floor((container_width + kSmallPaddingX) / static_cast<float>(count_x()) - - kSmallPaddingX); - int small_height = - floor((container_height + kSmallPaddingY) / static_cast<float>(count_y_) - - (kSmallPaddingY + kFooterExtraHeight)); - - // |small_width / small_height| has only roughly an aspect ratio of |aspect|. - // Shrink the thumbnail rect to make the aspect ratio fit exactly, and add - // the extra space won by shrinking to the outer padding. - int smallExtraPaddingLeft = 0; - int smallExtraPaddingTop = 0; - if (aspect > small_width/static_cast<float>(small_height)) { - small_height = small_width / aspect; - CGFloat all_tiles_height = - (small_height + kSmallPaddingY + kFooterExtraHeight) * count_y() - - (kSmallPaddingY + kFooterExtraHeight); - smallExtraPaddingTop = (container_height - all_tiles_height)/2; - } else { - small_width = small_height * aspect; - CGFloat all_tiles_width = - (small_width + kSmallPaddingX) * count_x() - kSmallPaddingX; - smallExtraPaddingLeft = (container_width - all_tiles_width)/2; - } - - // Compute inter-tile padding in the zoomed-out view. - CGFloat scale_small_to_big = - NSWidth(containing_rect) / static_cast<float>(small_width); - CGFloat big_padding_x = kSmallPaddingX * scale_small_to_big; - CGFloat big_padding_y = - (kSmallPaddingY + kFooterExtraHeight) * scale_small_to_big; - - // Now all dimensions are known. Lay out all tiles on a regular grid: - // X X X X - // X X X X - // X X - for (int row = 0, i = 0; i < tile_count; ++row) { - for (int col = 0; col < count_x() && i < tile_count; ++col, ++i) { - // Compute the smalled, zoomed-out thumbnail rect. - tiles_[i]->thumb_rect_.size = NSMakeSize(small_width, small_height); - - int small_x = col * (small_width + kSmallPaddingX) + - kSmallPaddingLeft + smallExtraPaddingLeft; - int small_y = row * (small_height + kSmallPaddingY + kFooterExtraHeight) + - kSmallPaddingTop + smallExtraPaddingTop; - - tiles_[i]->thumb_rect_.origin = NSMakePoint( - small_x, NSHeight(containing_rect) - small_y - small_height); - - tiles_[i]->favicon_rect_.size = NSMakeSize(kFaviconSize, kFaviconSize); - tiles_[i]->favicon_rect_.origin = NSMakePoint( - small_x, - NSHeight(containing_rect) - - (small_y + small_height + kFaviconExtraHeight)); - - // Align lower left corner of title rect with lower left corner of favicon - // for now. The final position is computed later by - // |Tile::set_font_metrics()|. - tiles_[i]->title_font_size_ = kTitleHeight; - tiles_[i]->title_rect_.origin = NSMakePoint( - NSMaxX(tiles_[i]->favicon_rect()) + kFaviconTitleDistanceX, - NSMinY(tiles_[i]->favicon_rect())); - tiles_[i]->title_rect_.size = NSMakeSize( - small_width - - NSWidth(tiles_[i]->favicon_rect()) - kFaviconTitleDistanceX, - kTitleHeight); - - // Compute the big, pre-zoom thumbnail rect. - tiles_[i]->start_thumb_rect_.size = containing_rect.size; - - int big_x = col * (NSWidth(containing_rect) + big_padding_x); - int big_y = row * (NSHeight(containing_rect) + big_padding_y); - tiles_[i]->start_thumb_rect_.origin = NSMakePoint(big_x, -big_y); - } - } -} - -void TileSet::set_selected_index(int index) { - CHECK_GE(index, 0); - CHECK_LT(index, static_cast<int>(tiles_.size())); - selected_index_ = index; -} - -// Given a |value| in [0, from_scale), map it into [0, to_scale) such that: -// * [0, from_scale) ends up in the middle of [0, to_scale) if the latter is -// a bigger range -// * The middle of [0, from_scale) is mapped to [0, to_scale), and the parts -// of the former that don't fit are mapped to 0 and to_scale - respectively -// if the former is a bigger range. -static int rescale(int value, int from_scale, int to_scale) { - int left = (to_scale - from_scale) / 2; - int result = value + left; - if (result < 0) - return 0; - if (result >= to_scale) - return to_scale - 1; - return result; -} - -int TileSet::up_index() const { - int tile_x, tile_y; - index_to_tile_xy(selected_index(), &tile_x, &tile_y); - tile_y -= 1; - if (tile_y == count_y() - 2) { - // Transition from last row to second-to-last row. - tile_x = rescale(tile_x, last_row_count_x(), count_x()); - } else if (tile_y < 0) { - // Transition from first row to last row. - tile_x = rescale(tile_x, count_x(), last_row_count_x()); - tile_y = count_y() - 1; - } - return tile_xy_to_index(tile_x, tile_y); -} - -int TileSet::down_index() const { - int tile_x, tile_y; - index_to_tile_xy(selected_index(), &tile_x, &tile_y); - tile_y += 1; - if (tile_y == count_y() - 1) { - // Transition from second-to-last row to last row. - tile_x = rescale(tile_x, count_x(), last_row_count_x()); - } else if (tile_y >= count_y()) { - // Transition from last row to first row. - tile_x = rescale(tile_x, last_row_count_x(), count_x()); - tile_y = 0; - } - return tile_xy_to_index(tile_x, tile_y); -} - -int TileSet::left_index() const { - int tile_x, tile_y; - index_to_tile_xy(selected_index(), &tile_x, &tile_y); - tile_x -= 1; - if (tile_x < 0) - tile_x = tiles_in_row(tile_y) - 1; - return tile_xy_to_index(tile_x, tile_y); -} - -int TileSet::right_index() const { - int tile_x, tile_y; - index_to_tile_xy(selected_index(), &tile_x, &tile_y); - tile_x += 1; - if (tile_x >= tiles_in_row(tile_y)) - tile_x = 0; - return tile_xy_to_index(tile_x, tile_y); -} - -int TileSet::next_index() const { - int new_index = selected_index() + 1; - if (new_index >= static_cast<int>(tiles_.size())) - new_index = 0; - return new_index; -} - -int TileSet::previous_index() const { - int new_index = selected_index() - 1; - if (new_index < 0) - new_index = tiles_.size() - 1; - return new_index; -} - -void TileSet::InsertTileAt(int index, content::WebContents* contents) { - tiles_.insert(tiles_.begin() + index, new Tile); - tiles_[index]->contents_ = contents; -} - -void TileSet::RemoveTileAt(int index) { - tiles_.erase(tiles_.begin() + index); -} - -// Moves the Tile object at |from_index| to |to_index|. Also updates rectangles -// so that the tiles stay in a left-to-right, top-to-bottom layout when walked -// in sequential order. -void TileSet::MoveTileFromTo(int from_index, int to_index) { - NSRect thumb = tiles_[from_index]->thumb_rect_; - NSRect start_thumb = tiles_[from_index]->start_thumb_rect_; - NSRect favicon = tiles_[from_index]->favicon_rect_; - NSRect title = tiles_[from_index]->title_rect_; - - scoped_ptr<Tile> tile(tiles_[from_index]); - tiles_.weak_erase(tiles_.begin() + from_index); - tiles_.insert(tiles_.begin() + to_index, tile.release()); - - int step = from_index < to_index ? -1 : 1; - for (int i = to_index; (i - from_index) * step < 0; i += step) { - tiles_[i]->thumb_rect_ = tiles_[i + step]->thumb_rect_; - tiles_[i]->start_thumb_rect_ = tiles_[i + step]->start_thumb_rect_; - tiles_[i]->favicon_rect_ = tiles_[i + step]->favicon_rect_; - tiles_[i]->title_rect_ = tiles_[i + step]->title_rect_; - } - tiles_[from_index]->thumb_rect_ = thumb; - tiles_[from_index]->start_thumb_rect_ = start_thumb; - tiles_[from_index]->favicon_rect_ = favicon; - tiles_[from_index]->title_rect_ = title; -} - -} // namespace tabpose - -void AnimateScaledCALayerFrameFromTo( - CALayer* layer, - const NSRect& from, CGFloat from_scale, - const NSRect& to, CGFloat to_scale, - NSTimeInterval duration, id boundsAnimationDelegate) { - // http://developer.apple.com/mac/library/qa/qa2008/qa1620.html - CABasicAnimation* animation; - - animation = [CABasicAnimation animationWithKeyPath:@"bounds"]; - animation.fromValue = [NSValue valueWithRect:from]; - animation.toValue = [NSValue valueWithRect:to]; - animation.duration = duration; - animation.timingFunction = - [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; - animation.delegate = boundsAnimationDelegate; - - // Update the layer's bounds so the layer doesn't snap back when the animation - // completes. - layer.bounds = NSRectToCGRect(to); - - // Add the animation, overriding the implicit animation. - [layer addAnimation:animation forKey:@"bounds"]; - - // Prepare the animation from the current position to the new position. - NSPoint opoint = from.origin; - NSPoint point = to.origin; - - // Adapt to anchorPoint. - opoint.x += NSWidth(from) * from_scale * layer.anchorPoint.x; - opoint.y += NSHeight(from) * from_scale * layer.anchorPoint.y; - point.x += NSWidth(to) * to_scale * layer.anchorPoint.x; - point.y += NSHeight(to) * to_scale * layer.anchorPoint.y; - - animation = [CABasicAnimation animationWithKeyPath:@"position"]; - animation.fromValue = [NSValue valueWithPoint:opoint]; - animation.toValue = [NSValue valueWithPoint:point]; - animation.duration = duration; - animation.timingFunction = - [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; - - // Update the layer's position so that the layer doesn't snap back when the - // animation completes. - layer.position = NSPointToCGPoint(point); - - // Add the animation, overriding the implicit animation. - [layer addAnimation:animation forKey:@"position"]; -} - -void AnimateCALayerFrameFromTo( - CALayer* layer, const NSRect& from, const NSRect& to, - NSTimeInterval duration, id boundsAnimationDelegate) { - AnimateScaledCALayerFrameFromTo( - layer, from, 1.0, to, 1.0, duration, boundsAnimationDelegate); -} - -void AnimateCALayerOpacityFromTo( - CALayer* layer, double from, double to, NSTimeInterval duration) { - CABasicAnimation* animation; - animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; - animation.fromValue = [NSNumber numberWithFloat:from]; - animation.toValue = [NSNumber numberWithFloat:to]; - animation.duration = duration; - - layer.opacity = to; - // Add the animation, overriding the implicit animation. - [layer addAnimation:animation forKey:@"opacity"]; -} - -@interface TabposeWindow (Private) -- (id)initForWindow:(NSWindow*)parent - rect:(NSRect)rect - slomo:(BOOL)slomo - tabStripModel:(TabStripModel*)tabStripModel; - -// Creates and initializes the CALayer in the background and all the CALayers -// for the thumbnails, favicons, and titles. -- (void)setUpLayersInSlomo:(BOOL)slomo; - -// Tells the browser to make the tab corresponding to currently selected -// thumbnail the current tab and starts the tabpose exit animmation. -- (void)fadeAwayInSlomo:(BOOL)slomo; - -// Returns the CALayer for the close button belonging to the thumbnail at -// index |index|. -- (CALayer*)closebuttonLayerAtIndex:(NSUInteger)index; - -// Updates the visibility of all closebutton layers. -- (void)updateClosebuttonLayersVisibility; -@end - -@implementation TabposeWindow - -+ (id)openTabposeFor:(NSWindow*)parent - rect:(NSRect)rect - slomo:(BOOL)slomo - tabStripModel:(TabStripModel*)tabStripModel { - // Releases itself when closed. - return [[TabposeWindow alloc] - initForWindow:parent rect:rect slomo:slomo tabStripModel:tabStripModel]; -} - -- (id)initForWindow:(NSWindow*)parent - rect:(NSRect)rect - slomo:(BOOL)slomo - tabStripModel:(TabStripModel*)tabStripModel { - NSRect frame = [parent frame]; - if ((self = [super initWithContentRect:frame - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO])) { - containingRect_ = rect; - tabStripModel_ = tabStripModel; - state_ = tabpose::kFadingIn; - tileSet_.reset(new tabpose::TileSet); - tabStripModelObserverBridge_.reset( - new TabStripModelObserverBridge(tabStripModel_, self)); - closeIcon_.reset([ResourceBundle::GetSharedInstance().GetNativeImageNamed( - IDR_TABPOSE_CLOSE).ToNSImage() retain]); - [self setReleasedWhenClosed:YES]; - [self setOpaque:NO]; - [self setBackgroundColor:[NSColor clearColor]]; - [self setUpLayersInSlomo:slomo]; - [self setAcceptsMouseMovedEvents:YES]; - [parent addChildWindow:self ordered:NSWindowAbove]; - [self makeKeyAndOrderFront:self]; - } - return self; -} - -- (CALayer*)selectedLayer { - return [allThumbnailLayers_ objectAtIndex:tileSet_->selected_index()]; -} - -- (void)selectTileAtIndexWithoutAnimation:(int)newIndex { - ScopedCAActionDisabler disabler; - const tabpose::Tile& tile = tileSet_->tile_at(newIndex); - selectionHighlight_.frame = - NSRectToCGRect(NSInsetRect(tile.thumb_rect(), - -kSelectionInset, -kSelectionInset)); - tileSet_->set_selected_index(newIndex); - - [self updateClosebuttonLayersVisibility]; -} - -- (void)addLayersForTile:(tabpose::Tile&)tile - showZoom:(BOOL)showZoom - slomo:(BOOL)slomo - animationDelegate:(id)animationDelegate { - base::scoped_nsobject<CALayer> layer( - [[ThumbnailLayer alloc] initWithWebContents:tile.web_contents() - fullSize:tile.GetStartRectRelativeTo( - tileSet_->selected_tile()).size]); - [layer setNeedsDisplay]; - - NSTimeInterval interval = - kDefaultAnimationDuration * (slomo ? kSlomoFactor : 1); - - // Background color as placeholder for now. - layer.get().backgroundColor = CGColorGetConstantColor(kCGColorWhite); - if (showZoom) { - AnimateCALayerFrameFromTo( - layer, - tile.GetStartRectRelativeTo(tileSet_->selected_tile()), - tile.thumb_rect(), - interval, - animationDelegate); - } else { - layer.get().frame = NSRectToCGRect(tile.thumb_rect()); - } - - layer.get().shadowRadius = 10; - layer.get().shadowOffset = CGSizeMake(0, -10); - if (state_ == tabpose::kFadedIn) - layer.get().shadowOpacity = 0.5; - - // Add a close button to the thumb layer. - CALayer* closeLayer = [CALayer layer]; - closeLayer.contents = closeIcon_.get(); - CGRect closeBounds = {}; - closeBounds.size = NSSizeToCGSize([closeIcon_ size]); - closeLayer.bounds = closeBounds; - closeLayer.hidden = YES; - - [closeLayer addConstraint: - [CAConstraint constraintWithAttribute:kCAConstraintMidX - relativeTo:@"superlayer" - attribute:kCAConstraintMinX]]; - [closeLayer addConstraint: - [CAConstraint constraintWithAttribute:kCAConstraintMidY - relativeTo:@"superlayer" - attribute:kCAConstraintMaxY]]; - - layer.get().layoutManager = [CAConstraintLayoutManager layoutManager]; - [layer.get() addSublayer:closeLayer]; - - [bgLayer_ addSublayer:layer]; - [allThumbnailLayers_ addObject:layer]; - - // Favicon and title. - NSFont* font = [NSFont systemFontOfSize:tile.title_font_size()]; - tile.set_font_metrics([font ascender], -[font descender]); - - CALayer* faviconLayer = [CALayer layer]; - if (showZoom) { - AnimateCALayerFrameFromTo( - faviconLayer, - tile.GetFaviconStartRectRelativeTo(tileSet_->selected_tile()), - tile.favicon_rect(), - interval, - nil); - AnimateCALayerOpacityFromTo(faviconLayer, 0.0, 1.0, interval); - } else { - faviconLayer.frame = NSRectToCGRect(tile.favicon_rect()); - } - faviconLayer.contents = tile.favicon(); - faviconLayer.zPosition = 1; // On top of the thumb shadow. - [bgLayer_ addSublayer:faviconLayer]; - [allFaviconLayers_ addObject:faviconLayer]; - - // CATextLayers can't animate their fontSize property, at least on 10.5. - // Animate transform.scale instead. - - // The scaling should have its origin in the layer's upper left corner. - // This needs to be set before |AnimateCALayerFrameFromTo()| is called. - CATextLayer* titleLayer = [CATextLayer layer]; - titleLayer.anchorPoint = CGPointMake(0, 1); - if (showZoom) { - NSRect fromRect = - tile.GetTitleStartRectRelativeTo(tileSet_->selected_tile()); - NSRect toRect = tile.title_rect(); - CGFloat scale = NSWidth(fromRect) / NSWidth(toRect); - fromRect.size = toRect.size; - - // Add scale animation. - CABasicAnimation* scaleAnimation = - [CABasicAnimation animationWithKeyPath:@"transform.scale"]; - scaleAnimation.fromValue = [NSNumber numberWithDouble:scale]; - scaleAnimation.toValue = [NSNumber numberWithDouble:1.0]; - scaleAnimation.duration = interval; - scaleAnimation.timingFunction = - [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; - [titleLayer addAnimation:scaleAnimation forKey:@"transform.scale"]; - - // Add the position and opacity animations. - AnimateScaledCALayerFrameFromTo( - titleLayer, fromRect, scale, toRect, 1.0, interval, nil); - AnimateCALayerOpacityFromTo(faviconLayer, 0.0, 1.0, interval); - } else { - titleLayer.frame = NSRectToCGRect(tile.title_rect()); - } - titleLayer.string = base::SysUTF16ToNSString(tile.title()); - titleLayer.fontSize = [font pointSize]; - titleLayer.truncationMode = kCATruncationEnd; - titleLayer.font = font; - titleLayer.zPosition = 1; // On top of the thumb shadow. - [bgLayer_ addSublayer:titleLayer]; - [allTitleLayers_ addObject:titleLayer]; -} - -- (void)setUpLayersInSlomo:(BOOL)slomo { - // Root layer -- covers whole window. - rootLayer_ = [CALayer layer]; - - // In a block so that the layers don't fade in. - { - ScopedCAActionDisabler disabler; - // Background layer -- the visible part of the window. - gray_.reset(CGColorCreateGenericGray(kCentralGray, 1.0)); - bgLayer_ = [CALayer layer]; - bgLayer_.backgroundColor = gray_; - bgLayer_.frame = NSRectToCGRect(containingRect_); - bgLayer_.masksToBounds = YES; - [rootLayer_ addSublayer:bgLayer_]; - - // Selection highlight layer. - darkBlue_.reset(CGColorCreateGenericRGB(0.25, 0.34, 0.86, 1.0)); - selectionHighlight_ = [CALayer layer]; - selectionHighlight_.backgroundColor = darkBlue_; - selectionHighlight_.cornerRadius = 5.0; - selectionHighlight_.zPosition = -1; // Behind other layers. - selectionHighlight_.hidden = YES; - [bgLayer_ addSublayer:selectionHighlight_]; - - // Bottom gradient. - CALayer* gradientLayer = [[[GrayGradientLayer alloc] - initWithStartGray:kCentralGray endGray:kBottomGray] autorelease]; - gradientLayer.frame = CGRectMake( - 0, - 0, - NSWidth(containingRect_), - kBottomGradientHeight); - [gradientLayer setNeedsDisplay]; // Draw once. - [bgLayer_ addSublayer:gradientLayer]; - } - // Top gradient (fades in). - CGFloat toolbarHeight = NSHeight([self frame]) - NSHeight(containingRect_); - topGradient_ = [[[GrayGradientLayer alloc] - initWithStartGray:kTopGray endGray:kCentralGray] autorelease]; - topGradient_.frame = CGRectMake( - 0, - NSHeight([self frame]) - toolbarHeight, - NSWidth(containingRect_), - toolbarHeight); - [topGradient_ setNeedsDisplay]; // Draw once. - [rootLayer_ addSublayer:topGradient_]; - NSTimeInterval interval = - kDefaultAnimationDuration * (slomo ? kSlomoFactor : 1); - AnimateCALayerOpacityFromTo(topGradient_, 0, 1, interval); - - // Layers for the tab thumbnails. - tileSet_->Build(tabStripModel_); - tileSet_->Layout(containingRect_); - allThumbnailLayers_.reset( - [[NSMutableArray alloc] initWithCapacity:tabStripModel_->count()]); - allFaviconLayers_.reset( - [[NSMutableArray alloc] initWithCapacity:tabStripModel_->count()]); - allTitleLayers_.reset( - [[NSMutableArray alloc] initWithCapacity:tabStripModel_->count()]); - - for (int i = 0; i < tabStripModel_->count(); ++i) { - // Add a delegate to one of the animations to get a notification once the - // animations are done. - [self addLayersForTile:tileSet_->tile_at(i) - showZoom:YES - slomo:slomo - animationDelegate:i == tileSet_->selected_index() ? self : nil]; - if (i == tileSet_->selected_index()) { - CALayer* layer = [allThumbnailLayers_ objectAtIndex:i]; - CAAnimation* animation = [layer animationForKey:@"bounds"]; - DCHECK(animation); - [animation setValue:kAnimationIdFadeIn forKey:kAnimationIdKey]; - } - } - [self selectTileAtIndexWithoutAnimation:tileSet_->selected_index()]; - - // Needs to happen after all layers have been added to |rootLayer_|, else - // there's a one frame flash of grey at the beginning of the animation - // (|bgLayer_| showing through with none of its children visible yet). - [[self contentView] setLayer:rootLayer_]; - [[self contentView] setWantsLayer:YES]; -} - -- (BOOL)canBecomeKeyWindow { - return YES; -} - -// Lets the traffic light buttons on the browser window keep their "active" -// state while an info bubble is open. Only has an effect on 10.7. -- (BOOL)_sharesParentKeyState { - return YES; -} - -// Handle key events that should be executed repeatedly while the key is down. -- (void)keyDown:(NSEvent*)event { - if (state_ == tabpose::kFadingOut) - return; - NSString* characters = [event characters]; - if ([characters length] < 1) - return; - - unichar character = [characters characterAtIndex:0]; - int newIndex = -1; - switch (character) { - case NSUpArrowFunctionKey: - newIndex = tileSet_->up_index(); - break; - case NSDownArrowFunctionKey: - newIndex = tileSet_->down_index(); - break; - case NSLeftArrowFunctionKey: - newIndex = tileSet_->left_index(); - break; - case NSRightArrowFunctionKey: - newIndex = tileSet_->right_index(); - break; - case NSTabCharacter: - newIndex = tileSet_->next_index(); - break; - case NSBackTabCharacter: - newIndex = tileSet_->previous_index(); - break; - } - if (newIndex != -1) - [self selectTileAtIndexWithoutAnimation:newIndex]; -} - -// Handle keyboard events that should be executed once when the key is released. -- (void)keyUp:(NSEvent*)event { - if (state_ == tabpose::kFadingOut) - return; - NSString* characters = [event characters]; - if ([characters length] < 1) - return; - - unichar character = [characters characterAtIndex:0]; - switch (character) { - case NSEnterCharacter: - case NSNewlineCharacter: - case NSCarriageReturnCharacter: - case ' ': - [self fadeAwayInSlomo:([event modifierFlags] & NSShiftKeyMask) != 0]; - break; - case '\e': // Escape - tileSet_->set_selected_index(tabStripModel_->active_index()); - [self fadeAwayInSlomo:([event modifierFlags] & NSShiftKeyMask) != 0]; - break; - } -} - -// Handle keyboard events that contain cmd or ctrl. -- (BOOL)performKeyEquivalent:(NSEvent*)event { - if (state_ == tabpose::kFadingOut) - return NO; - NSString* characters = [event characters]; - if ([characters length] < 1) - return NO; - unichar character = [characters characterAtIndex:0]; - if ([event modifierFlags] & NSCommandKeyMask) { - if (character >= '1' && character <= '9') { - int index = - character == '9' ? tabStripModel_->count() - 1 : character - '1'; - if (index < tabStripModel_->count()) { - tileSet_->set_selected_index(index); - [self fadeAwayInSlomo:([event modifierFlags] & NSShiftKeyMask) != 0]; - return YES; - } - } - } - return NO; -} - -- (void)flagsChanged:(NSEvent*)event { - showAllCloseLayers_ = ([event modifierFlags] & NSAlternateKeyMask) != 0; - [self updateClosebuttonLayersVisibility]; -} - -- (void)selectTileFromMouseEvent:(NSEvent*)event { - int newIndex = -1; - CGPoint p = NSPointToCGPoint([event locationInWindow]); - for (NSUInteger i = 0; i < [allThumbnailLayers_ count]; ++i) { - CALayer* layer = [allThumbnailLayers_ objectAtIndex:i]; - CGPoint lp = [layer convertPoint:p fromLayer:rootLayer_]; - if ([static_cast<CALayer*>([layer presentationLayer]) containsPoint:lp]) - newIndex = i; - } - if (newIndex >= 0) - [self selectTileAtIndexWithoutAnimation:newIndex]; -} - -- (void)mouseMoved:(NSEvent*)event { - [self selectTileFromMouseEvent:event]; -} - -- (CALayer*)closebuttonLayerAtIndex:(NSUInteger)index { - CALayer* layer = [allThumbnailLayers_ objectAtIndex:index]; - return [[layer sublayers] objectAtIndex:0]; -} - -- (void)updateClosebuttonLayersVisibility { - for (NSUInteger i = 0; i < [allThumbnailLayers_ count]; ++i) { - CALayer* layer = [self closebuttonLayerAtIndex:i]; - BOOL isSelectedTile = static_cast<int>(i) == tileSet_->selected_index(); - BOOL isVisible = state_ == tabpose::kFadedIn && - (isSelectedTile || showAllCloseLayers_); - layer.hidden = !isVisible; - } -} - -- (void)mouseDown:(NSEvent*)event { - // Just in case the user clicked without ever moving the mouse. - [self selectTileFromMouseEvent:event]; - - // If the click occurred in a close box, close that tab and don't do anything - // else. - CGPoint p = NSPointToCGPoint([event locationInWindow]); - for (NSUInteger i = 0; i < [allThumbnailLayers_ count]; ++i) { - CALayer* layer = [self closebuttonLayerAtIndex:i]; - CGPoint lp = [layer convertPoint:p fromLayer:rootLayer_]; - if ([static_cast<CALayer*>([layer presentationLayer]) containsPoint:lp] && - !layer.hidden) { - tabStripModel_->CloseWebContentsAt(i, - TabStripModel::CLOSE_USER_GESTURE | - TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); - return; - } - } - - [self fadeAwayInSlomo:([event modifierFlags] & NSShiftKeyMask) != 0]; -} - -- (void)swipeWithEvent:(NSEvent*)event { - if (abs([event deltaY]) > 0.5) // Swipe up or down. - [self fadeAwayInSlomo:([event modifierFlags] & NSShiftKeyMask) != 0]; -} - -- (void)close { - // Prevent parent window from disappearing. - [[self parentWindow] removeChildWindow:self]; - - // We're dealloc'd in an autorelease pool – by then the observer registry - // might be dead, so explicitly reset the observer now. - tabStripModelObserverBridge_.reset(); - - [super close]; -} - -- (void)commandDispatch:(id)sender { - if ([sender tag] == IDC_TABPOSE) - [self fadeAwayInSlomo:NO]; -} - -- (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item { - // Disable all browser-related menu items except the tab overview toggle. - SEL action = [item action]; - NSInteger tag = [item tag]; - return action == @selector(commandDispatch:) && tag == IDC_TABPOSE; -} - -- (void)fadeAwayTileAtIndex:(int)index { - const tabpose::Tile& tile = tileSet_->tile_at(index); - CALayer* layer = [allThumbnailLayers_ objectAtIndex:index]; - // Add a delegate to one of the implicit animations to get a notification - // once the animations are done. - if (static_cast<int>(index) == tileSet_->selected_index()) { - CAAnimation* animation = [CAAnimation animation]; - animation.delegate = self; - [animation setValue:kAnimationIdFadeOut forKey:kAnimationIdKey]; - [layer addAnimation:animation forKey:@"frame"]; - } - - // Thumbnail. - layer.frame = NSRectToCGRect( - tile.GetStartRectRelativeTo(tileSet_->selected_tile())); - - if (static_cast<int>(index) == tileSet_->selected_index()) { - // Redraw layer at big resolution, so that zoom-in isn't blocky. - [layer setNeedsDisplay]; - } - - // Title. - CALayer* faviconLayer = [allFaviconLayers_ objectAtIndex:index]; - faviconLayer.frame = NSRectToCGRect( - tile.GetFaviconStartRectRelativeTo(tileSet_->selected_tile())); - faviconLayer.opacity = 0; - - // Favicon. - // The |fontSize| cannot be animated directly, animate the layer's scale - // instead. |transform.scale| affects the rendered width, so keep the small - // bounds. - CALayer* titleLayer = [allTitleLayers_ objectAtIndex:index]; - NSRect titleRect = tile.title_rect(); - NSRect titleToRect = - tile.GetTitleStartRectRelativeTo(tileSet_->selected_tile()); - CGFloat scale = NSWidth(titleToRect) / NSWidth(titleRect); - titleToRect.origin.x += - NSWidth(titleRect) * scale * titleLayer.anchorPoint.x; - titleToRect.origin.y += - NSHeight(titleRect) * scale * titleLayer.anchorPoint.y; - titleLayer.position = NSPointToCGPoint(titleToRect.origin); - [titleLayer setValue:[NSNumber numberWithDouble:scale] - forKeyPath:@"transform.scale"]; - titleLayer.opacity = 0; -} - -- (void)fadeAwayInSlomo:(BOOL)slomo { - if (state_ == tabpose::kFadingOut) - return; - - state_ = tabpose::kFadingOut; - [self setAcceptsMouseMovedEvents:NO]; - - // Select chosen tab. - if (tileSet_->selected_index() < tabStripModel_->count()) { - tabStripModel_->ActivateTabAt(tileSet_->selected_index(), - /*user_gesture=*/true); - } else { - DCHECK_EQ(tileSet_->selected_index(), 0); - } - - { - ScopedCAActionDisabler disableCAActions; - - // Move the selected layer on top of all other layers. - [self selectedLayer].zPosition = 1; - - selectionHighlight_.hidden = YES; - // Running animations with shadows is slow, so turn shadows off before - // running the exit animation. - for (CALayer* layer in allThumbnailLayers_.get()) - layer.shadowOpacity = 0.0; - - [self updateClosebuttonLayersVisibility]; - } - - // Animate layers out, all in one transaction. - CGFloat duration = - 1.3 * kDefaultAnimationDuration * (slomo ? kSlomoFactor : 1); - ScopedCAActionSetDuration durationSetter(duration); - for (int i = 0; i < tabStripModel_->count(); ++i) - [self fadeAwayTileAtIndex:i]; - AnimateCALayerOpacityFromTo(topGradient_, 1, 0, duration); -} - -- (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)finished { - NSString* animationId = [animation valueForKey:kAnimationIdKey]; - if ([animationId isEqualToString:kAnimationIdFadeIn]) { - if (finished && state_ == tabpose::kFadingIn) { - // If the user clicks while the fade in animation is still running, - // |state_| is already kFadingOut. In that case, don't do anything. - state_ = tabpose::kFadedIn; - - selectionHighlight_.hidden = NO; - - // Running animations with shadows is slow, so turn shadows on only after - // the animation is done. - ScopedCAActionDisabler disableCAActions; - for (CALayer* layer in allThumbnailLayers_.get()) - layer.shadowOpacity = 0.5; - - [self updateClosebuttonLayersVisibility]; - } - } else if ([animationId isEqualToString:kAnimationIdFadeOut]) { - DCHECK_EQ(tabpose::kFadingOut, state_); - [self close]; - } -} - -- (NSUInteger)thumbnailLayerCount { - return [allThumbnailLayers_ count]; -} - -- (int)selectedIndex { - return tileSet_->selected_index(); -} - -#pragma mark TabStripModelBridge - -- (void)refreshLayerFramesAtIndex:(int)i { - const tabpose::Tile& tile = tileSet_->tile_at(i); - - CALayer* thumbLayer = [allThumbnailLayers_ objectAtIndex:i]; - - if (i == tileSet_->selected_index()) { - AnimateCALayerFrameFromTo( - selectionHighlight_, - NSInsetRect(NSRectFromCGRect(thumbLayer.frame), - -kSelectionInset, -kSelectionInset), - NSInsetRect(tile.thumb_rect(), - -kSelectionInset, -kSelectionInset), - kObserverChangeAnimationDuration, - nil); - } - - // Repaint layer if necessary. - if (!NSEqualSizes(NSRectFromCGRect(thumbLayer.frame).size, - tile.thumb_rect().size)) { - [thumbLayer setNeedsDisplay]; - } - - // Use AnimateCALayerFrameFromTo() instead of just setting |frame| to let - // the animation match the selection animation -- - // |kCAMediaTimingFunctionDefault| is 10.6-only. - AnimateCALayerFrameFromTo( - thumbLayer, - NSRectFromCGRect(thumbLayer.frame), - tile.thumb_rect(), - kObserverChangeAnimationDuration, - nil); - - CALayer* faviconLayer = [allFaviconLayers_ objectAtIndex:i]; - AnimateCALayerFrameFromTo( - faviconLayer, - NSRectFromCGRect(faviconLayer.frame), - tile.favicon_rect(), - kObserverChangeAnimationDuration, - nil); - - CALayer* titleLayer = [allTitleLayers_ objectAtIndex:i]; - AnimateCALayerFrameFromTo( - titleLayer, - NSRectFromCGRect(titleLayer.frame), - tile.title_rect(), - kObserverChangeAnimationDuration, - nil); -} - -- (void)insertTabWithContents:(content::WebContents*)contents - atIndex:(NSInteger)index - inForeground:(bool)inForeground { - // This happens if you cmd-click a link and then immediately open tabpose - // on a slowish machine. - ScopedCAActionSetDuration durationSetter(kObserverChangeAnimationDuration); - - // Insert new layer and relayout. - tileSet_->InsertTileAt(index, contents); - tileSet_->Layout(containingRect_); - [self addLayersForTile:tileSet_->tile_at(index) - showZoom:NO - slomo:NO - animationDelegate:nil]; - - // Update old layers. - DCHECK_EQ(tabStripModel_->count(), - static_cast<int>([allThumbnailLayers_ count])); - DCHECK_EQ(tabStripModel_->count(), - static_cast<int>([allTitleLayers_ count])); - DCHECK_EQ(tabStripModel_->count(), - static_cast<int>([allFaviconLayers_ count])); - - // Update selection. - int selectedIndex = tileSet_->selected_index(); - if (selectedIndex >= index) - selectedIndex++; - [self selectTileAtIndexWithoutAnimation:selectedIndex]; - - // Animate everything into its new place. - for (int i = 0; i < tabStripModel_->count(); ++i) { - if (i == index) // The new layer. - continue; - [self refreshLayerFramesAtIndex:i]; - } -} - -- (void)tabClosingWithContents:(content::WebContents*)contents - atIndex:(NSInteger)index { - // We will also get a -tabDetachedWithContents:atIndex: notification for - // closing tabs, so do nothing here. -} - -- (void)tabDetachedWithContents:(content::WebContents*)contents - atIndex:(NSInteger)index { - ScopedCAActionSetDuration durationSetter(kObserverChangeAnimationDuration); - - // Remove layer and relayout. - tileSet_->RemoveTileAt(index); - tileSet_->Layout(containingRect_); - - { - ScopedCAActionDisabler disabler; - [[allThumbnailLayers_ objectAtIndex:index] removeFromSuperlayer]; - [allThumbnailLayers_ removeObjectAtIndex:index]; - [[allTitleLayers_ objectAtIndex:index] removeFromSuperlayer]; - [allTitleLayers_ removeObjectAtIndex:index]; - [[allFaviconLayers_ objectAtIndex:index] removeFromSuperlayer]; - [allFaviconLayers_ removeObjectAtIndex:index]; - } - - // Update old layers. - DCHECK_EQ(tabStripModel_->count(), - static_cast<int>([allThumbnailLayers_ count])); - DCHECK_EQ(tabStripModel_->count(), - static_cast<int>([allTitleLayers_ count])); - DCHECK_EQ(tabStripModel_->count(), - static_cast<int>([allFaviconLayers_ count])); - - if (tabStripModel_->count() == 0) - [self close]; - - // Update selection. - int selectedIndex = tileSet_->selected_index(); - if (selectedIndex > index || selectedIndex >= tabStripModel_->count()) - selectedIndex--; - if (selectedIndex >= 0) - [self selectTileAtIndexWithoutAnimation:selectedIndex]; - - // Animate everything into its new place. - for (int i = 0; i < tabStripModel_->count(); ++i) - [self refreshLayerFramesAtIndex:i]; -} - -- (void)tabMovedWithContents:(content::WebContents*)contents - fromIndex:(NSInteger)from - toIndex:(NSInteger)to { - ScopedCAActionSetDuration durationSetter(kObserverChangeAnimationDuration); - - // Move tile from |from| to |to|. - tileSet_->MoveTileFromTo(from, to); - - // Move corresponding layers from |from| to |to|. - base::scoped_nsobject<CALayer> thumbLayer( - [[allThumbnailLayers_ objectAtIndex:from] retain]); - [allThumbnailLayers_ removeObjectAtIndex:from]; - [allThumbnailLayers_ insertObject:thumbLayer.get() atIndex:to]; - base::scoped_nsobject<CALayer> faviconLayer( - [[allFaviconLayers_ objectAtIndex:from] retain]); - [allFaviconLayers_ removeObjectAtIndex:from]; - [allFaviconLayers_ insertObject:faviconLayer.get() atIndex:to]; - base::scoped_nsobject<CALayer> titleLayer( - [[allTitleLayers_ objectAtIndex:from] retain]); - [allTitleLayers_ removeObjectAtIndex:from]; - [allTitleLayers_ insertObject:titleLayer.get() atIndex:to]; - - // Update selection. - int selectedIndex = tileSet_->selected_index(); - if (from == selectedIndex) - selectedIndex = to; - else if (from < selectedIndex && selectedIndex <= to) - selectedIndex--; - else if (to <= selectedIndex && selectedIndex < from) - selectedIndex++; - [self selectTileAtIndexWithoutAnimation:selectedIndex]; - - // Update frames of the layers. - for (int i = std::min(from, to); i <= std::max(from, to); ++i) - [self refreshLayerFramesAtIndex:i]; -} - -- (void)tabChangedWithContents:(content::WebContents*)contents - atIndex:(NSInteger)index - changeType:(TabStripModelObserver::TabChangeType)change { - // Tell the window to update text, title, and thumb layers at |index| to get - // their data from |contents|. |contents| can be different from the old - // contents at that index! - // While a tab is loading, this is unfortunately called quite often for - // both the "loading" and the "all" change types, so we don't really want to - // send thumb requests to the corresponding renderer when this is called. - // For now, just make sure that we don't hold on to an invalid WebContents - // object. - tabpose::Tile& tile = tileSet_->tile_at(index); - if (contents == tile.web_contents()) { - // TODO(thakis): Install a timer to send a thumb request/update title/update - // favicon after 20ms or so, and reset the timer every time this is called - // to make sure we get an updated thumb, without requesting them all over. - return; - } - - tile.set_tab_contents(contents); - ThumbnailLayer* thumbLayer = [allThumbnailLayers_ objectAtIndex:index]; - [thumbLayer setWebContents:contents]; -} - -- (void)tabStripModelDeleted { - [self close]; -} - -@end diff --git a/chrome/browser/ui/cocoa/tabpose_window_unittest.mm b/chrome/browser/ui/cocoa/tabpose_window_unittest.mm deleted file mode 100644 index 0a20f4b..0000000 --- a/chrome/browser/ui/cocoa/tabpose_window_unittest.mm +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2012 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/ui/cocoa/tabpose_window.h" - -#include "base/mac/mac_util.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/cocoa/cocoa_profile_test.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/test/base/testing_profile.h" -#include "content/public/browser/site_instance.h" -#include "content/public/browser/web_contents.h" -#include "testing/gtest/include/gtest/gtest.h" - -using content::SiteInstance; - -class TabposeWindowTest : public CocoaProfileTest { - public: - virtual void SetUp() { - CocoaProfileTest::SetUp(); - ASSERT_TRUE(profile()); - - site_instance_ = SiteInstance::Create(profile()); - } - - void AppendTabToStrip() { - content::WebContents* web_contents = content::WebContents::Create( - content::WebContents::CreateParams(profile(), site_instance_.get())); - browser()->tab_strip_model()->AppendWebContents( - web_contents, /*foreground=*/true); - } - - scoped_refptr<SiteInstance> site_instance_; -}; - -TEST_F(TabposeWindowTest, TestShow) { - // Skip this test on 10.7 - // http://code.google.com/p/chromium/issues/detail?id=127845 - if (base::mac::IsOSLionOrLater()) { - return; - } - - NSWindow* parent = browser()->window()->GetNativeWindow(); - - [parent orderFront:nil]; - EXPECT_TRUE([parent isVisible]); - - // Add a few tabs to the tab strip model. - for (int i = 0; i < 3; ++i) - AppendTabToStrip(); - - base::mac::ScopedNSAutoreleasePool pool; - TabposeWindow* window = - [TabposeWindow openTabposeFor:parent - rect:NSMakeRect(10, 20, 250, 160) - slomo:NO - tabStripModel:browser()->tab_strip_model()]; - - // Should release the window. - [window mouseDown:nil]; -} - -TEST_F(TabposeWindowTest, TestModelObserver) { - // Skip this test on 10.7 - // http://code.google.com/p/chromium/issues/detail?id=127845 - if (base::mac::IsOSLionOrLater()) { - return; - } - - NSWindow* parent = browser()->window()->GetNativeWindow(); - [parent orderFront:nil]; - - // Add a few tabs to the tab strip model. - for (int i = 0; i < 3; ++i) - AppendTabToStrip(); - - base::mac::ScopedNSAutoreleasePool pool; - TabposeWindow* window = - [TabposeWindow openTabposeFor:parent - rect:NSMakeRect(10, 20, 250, 160) - slomo:NO - tabStripModel:browser()->tab_strip_model()]; - - // Exercise all the model change events. - TabStripModel* model = browser()->tab_strip_model(); - DCHECK_EQ([window thumbnailLayerCount], 3u); - DCHECK_EQ([window selectedIndex], 2); - - model->MoveWebContentsAt(0, 2, /*select_after_move=*/false); - DCHECK_EQ([window thumbnailLayerCount], 3u); - DCHECK_EQ([window selectedIndex], 1); - - model->MoveWebContentsAt(2, 0, /*select_after_move=*/false); - DCHECK_EQ([window thumbnailLayerCount], 3u); - DCHECK_EQ([window selectedIndex], 2); - - [window selectTileAtIndexWithoutAnimation:0]; - DCHECK_EQ([window selectedIndex], 0); - - model->MoveWebContentsAt(0, 2, /*select_after_move=*/false); - DCHECK_EQ([window selectedIndex], 2); - - model->MoveWebContentsAt(2, 0, /*select_after_move=*/false); - DCHECK_EQ([window selectedIndex], 0); - - delete model->DetachWebContentsAt(0); - DCHECK_EQ([window thumbnailLayerCount], 2u); - DCHECK_EQ([window selectedIndex], 0); - - AppendTabToStrip(); - DCHECK_EQ([window thumbnailLayerCount], 3u); - DCHECK_EQ([window selectedIndex], 0); - - model->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE); - DCHECK_EQ([window thumbnailLayerCount], 2u); - DCHECK_EQ([window selectedIndex], 0); - - [window selectTileAtIndexWithoutAnimation:1]; - model->CloseWebContentsAt(0, TabStripModel::CLOSE_NONE); - DCHECK_EQ([window thumbnailLayerCount], 1u); - DCHECK_EQ([window selectedIndex], 0); - - // Should release the window. - [window mouseDown:nil]; -} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 77f402f..76fc3ac 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2536,8 +2536,6 @@ 'browser/thumbnails/content_based_thumbnailing_algorithm.h', 'browser/thumbnails/simple_thumbnail_crop.cc', 'browser/thumbnails/simple_thumbnail_crop.h', - 'browser/thumbnails/render_widget_snapshot_taker.cc', - 'browser/thumbnails/render_widget_snapshot_taker.h', 'browser/thumbnails/thumbnail_service.h', 'browser/thumbnails/thumbnail_service_factory.cc', 'browser/thumbnails/thumbnail_service_factory.h', diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index ec7e09e..f4478b9 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -1039,8 +1039,6 @@ 'browser/ui/cocoa/tab_modal_confirm_dialog_mac.mm', 'browser/ui/cocoa/table_row_nsimage_cache.h', 'browser/ui/cocoa/table_row_nsimage_cache.mm', - 'browser/ui/cocoa/tabpose_window.h', - 'browser/ui/cocoa/tabpose_window.mm', 'browser/ui/cocoa/tabs/dock_info_mac.cc', 'browser/ui/cocoa/tabs/media_indicator_view.h', 'browser/ui/cocoa/tabs/media_indicator_view.mm', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index a7e005d..79ae65e 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1418,7 +1418,6 @@ 'browser/themes/theme_syncable_service_unittest.cc', 'browser/thumbnails/content_analysis_unittest.cc', 'browser/thumbnails/content_based_thumbnailing_algorithm_unittest.cc', - 'browser/thumbnails/render_widget_snapshot_taker_unittest.cc', 'browser/thumbnails/simple_thumbnail_crop_unittest.cc', 'browser/thumbnails/thumbnail_service_unittest.cc', 'browser/translate/translate_manager_unittest.cc', @@ -1629,7 +1628,6 @@ 'browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm', 'browser/ui/cocoa/tab_contents/sad_tab_view_unittest.mm', 'browser/ui/cocoa/table_row_nsimage_cache_unittest.mm', - 'browser/ui/cocoa/tabpose_window_unittest.mm', 'browser/ui/cocoa/tabs/media_indicator_view_unittest.mm', 'browser/ui/cocoa/tabs/tab_controller_unittest.mm', 'browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 3863942..fffc3d7 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1609,9 +1609,6 @@ const char kDisableSystemFullscreenForTesting[] = const char kDisableCoreAnimationLayerSquashing[] = "disable-core-animation-layer-squashing"; -// Enables the tabs expose feature ( http://crbug.com/50307 ). -const char kEnableExposeForTabs[] = "enable-expose-for-tabs"; - // Enables a simplified fullscreen UI on Mac. const char kEnableSimplifiedFullscreen[] = "enable-simplified-fullscreen"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 1231a05..8b22543 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -448,7 +448,6 @@ extern const char kMigrateDataDirForSxS[]; extern const char kDisableAppShims[]; extern const char kDisableCoreAnimationLayerSquashing[]; extern const char kDisableSystemFullscreenForTesting[]; -extern const char kEnableExposeForTabs[]; extern const char kEnableSimplifiedFullscreen[]; extern const char kKeychainReauthorize[]; extern const char kRelauncherProcess[]; diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index 3a5072c..5d18e83 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h @@ -134,7 +134,6 @@ class TestBrowserWindow : public BrowserWindow { virtual void Copy() OVERRIDE {} virtual void Paste() OVERRIDE {} #if defined(OS_MACOSX) - virtual void OpenTabpose() OVERRIDE {} virtual void EnterFullscreenWithChrome() OVERRIDE {} virtual bool IsFullscreenWithChrome() OVERRIDE; virtual bool IsFullscreenWithoutChrome() OVERRIDE; diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc index 20a42a0..b27ad17e 100644 --- a/chrome/test/base/testing_browser_process.cc +++ b/chrome/test/base/testing_browser_process.cc @@ -24,7 +24,6 @@ #include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/prerender/prerender_tracker.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" -#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h" #endif #if !defined(OS_IOS) && !defined(OS_ANDROID) @@ -67,9 +66,6 @@ TestingBrowserProcess::TestingBrowserProcess() : notification_service_(content::NotificationService::Create()), module_ref_count_(0), app_locale_("en"), -#if !defined(OS_IOS) - render_widget_snapshot_taker_(new RenderWidgetSnapshotTaker), -#endif local_state_(NULL), io_thread_(NULL), system_request_context_(NULL), @@ -176,16 +172,6 @@ GpuModeManager* TestingBrowserProcess::gpu_mode_manager() { return NULL; } -RenderWidgetSnapshotTaker* -TestingBrowserProcess::GetRenderWidgetSnapshotTaker() { -#if defined(OS_IOS) - NOTREACHED(); - return NULL; -#else - return render_widget_snapshot_taker_.get(); -#endif -} - BackgroundModeManager* TestingBrowserProcess::background_mode_manager() { return NULL; } diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h index 945fe55..717d87b 100644 --- a/chrome/test/base/testing_browser_process.h +++ b/chrome/test/base/testing_browser_process.h @@ -67,7 +67,6 @@ class TestingBrowserProcess : public BrowserProcess { virtual IconManager* icon_manager() OVERRIDE; virtual GLStringManager* gl_string_manager() OVERRIDE; virtual GpuModeManager* gpu_mode_manager() OVERRIDE; - virtual RenderWidgetSnapshotTaker* GetRenderWidgetSnapshotTaker() OVERRIDE; virtual BackgroundModeManager* background_mode_manager() OVERRIDE; virtual void set_background_mode_manager_for_test( scoped_ptr<BackgroundModeManager> manager) OVERRIDE; @@ -160,7 +159,6 @@ class TestingBrowserProcess : public BrowserProcess { #endif scoped_ptr<prerender::PrerenderTracker> prerender_tracker_; - scoped_ptr<RenderWidgetSnapshotTaker> render_widget_snapshot_taker_; scoped_refptr<SafeBrowsingService> sb_service_; scoped_ptr<BookmarkPromptController> bookmark_prompt_controller_; #endif // !defined(OS_IOS) diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index 74c65ec..4a59ddc 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc @@ -35,7 +35,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_test_util.h" -#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h" #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" #include "chrome/browser/ui/browser.h" diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h index 015a968..bd3f3a0f4 100644 --- a/chrome/test/base/ui_test_utils.h +++ b/chrome/test/base/ui_test_utils.h @@ -261,12 +261,6 @@ class BrowserAddedObserver { DISALLOW_COPY_AND_ASSIGN(BrowserAddedObserver); }; -// Takes a snapshot of the given render widget, rendered at |page_size|. The -// snapshot is set to |bitmap|. Returns true on success. -bool TakeRenderWidgetSnapshot(content::RenderWidgetHost* rwh, - const gfx::Size& page_size, - SkBitmap* bitmap) WARN_UNUSED_RESULT; - // Takes a snapshot of the entire page, according to the width and height // properties of the DOM's document. Returns true on success. DOMAutomation // must be enabled. diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index df2e948..8529331 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -481,7 +481,6 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) { OnUpdateScreenRectsAck) IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnRequestMove) IPC_MESSAGE_HANDLER(ViewHostMsg_SetTooltipText, OnSetTooltipText) - IPC_MESSAGE_HANDLER(ViewHostMsg_PaintAtSize_ACK, OnPaintAtSizeAck) #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped, OnCompositorSurfaceBuffersSwapped) @@ -776,17 +775,6 @@ bool RenderWidgetHostImpl::CopyFromBackingStoreToCGContext( } #endif -void RenderWidgetHostImpl::PaintAtSize(TransportDIB::Handle dib_handle, - int tag, - const gfx::Size& page_size, - const gfx::Size& desired_size) { - // Ask the renderer to create a bitmap regardless of whether it's - // hidden, being resized, redrawn, etc. It resizes the web widget - // to the page_size and then scales it to the desired_size. - Send(new ViewMsg_PaintAtSize(routing_id_, dib_handle, tag, - page_size, desired_size)); -} - bool RenderWidgetHostImpl::TryGetBackingStore(const gfx::Size& desired_size, BackingStore** backing_store) { // Check if the view has an accelerated surface of the desired size. @@ -1486,14 +1474,6 @@ void RenderWidgetHostImpl::OnRequestMove(const gfx::Rect& pos) { } } -void RenderWidgetHostImpl::OnPaintAtSizeAck(int tag, const gfx::Size& size) { - std::pair<int, gfx::Size> details = std::make_pair(tag, size); - NotificationService::current()->Notify( - NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK, - Source<RenderWidgetHost>(this), - Details<std::pair<int, gfx::Size> >(&details)); -} - #if defined(OS_MACOSX) void RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwapped( const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) { diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 546e229..b9cfc2f 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -160,10 +160,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, virtual RenderWidgetHostView* GetView() const OVERRIDE; virtual bool IsLoading() const OVERRIDE; virtual bool IsRenderView() const OVERRIDE; - virtual void PaintAtSize(TransportDIB::Handle dib_handle, - int tag, - const gfx::Size& page_size, - const gfx::Size& desired_size) OVERRIDE; virtual void Replace(const base::string16& word) OVERRIDE; virtual void ReplaceMisspelling(const base::string16& word) OVERRIDE; virtual void ResizeRectChanged(const gfx::Rect& new_rect) OVERRIDE; @@ -666,7 +662,6 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost, void OnRequestMove(const gfx::Rect& pos); void OnSetTooltipText(const base::string16& tooltip_text, blink::WebTextDirection text_direction_hint); - void OnPaintAtSizeAck(int tag, const gfx::Size& size); #if defined(OS_MACOSX) void OnCompositorSurfaceBuffersSwapped( const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params); diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index fbfeab6..e9be094 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc @@ -21,11 +21,6 @@ #include "content/common/input_messages.h" #include "content/common/view_messages.h" #include "content/port/browser/render_widget_host_view_port.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" #include "content/public/test/mock_render_process_host.h" #include "content/public/test/test_browser_context.h" #include "content/test/test_render_view_host.h" @@ -205,7 +200,6 @@ class MockRenderWidgetHost : public RenderWidgetHostImpl { } // Allow poking at a few private members. - using RenderWidgetHostImpl::OnPaintAtSizeAck; using RenderWidgetHostImpl::OnUpdateRect; using RenderWidgetHostImpl::RendererExited; using RenderWidgetHostImpl::last_requested_size_; @@ -559,41 +553,6 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate { WebInputEvent::Type unhandled_keyboard_event_type_; }; -// MockPaintingObserver -------------------------------------------------------- - -class MockPaintingObserver : public NotificationObserver { - public: - void WidgetDidReceivePaintAtSizeAck(RenderWidgetHostImpl* host, - int tag, - const gfx::Size& size) { - host_ = reinterpret_cast<MockRenderWidgetHost*>(host); - tag_ = tag; - size_ = size; - } - - virtual void Observe(int type, - const NotificationSource& source, - const NotificationDetails& details) OVERRIDE { - if (type == NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK) { - std::pair<int, gfx::Size>* size_ack_details = - Details<std::pair<int, gfx::Size> >(details).ptr(); - WidgetDidReceivePaintAtSizeAck( - RenderWidgetHostImpl::From(Source<RenderWidgetHost>(source).ptr()), - size_ack_details->first, - size_ack_details->second); - } - } - - MockRenderWidgetHost* host() const { return host_; } - int tag() const { return tag_; } - gfx::Size size() const { return size_; } - - private: - MockRenderWidgetHost* host_; - int tag_; - gfx::Size size_; -}; - // RenderWidgetHostTest -------------------------------------------------------- class RenderWidgetHostTest : public testing::Test { @@ -1118,27 +1077,6 @@ TEST_F(RenderWidgetHostTest, HiddenPaint) { EXPECT_TRUE(needs_repaint.a); } -TEST_F(RenderWidgetHostTest, PaintAtSize) { - const int kPaintAtSizeTag = 42; - host_->PaintAtSize(TransportDIB::GetFakeHandleForTest(), kPaintAtSizeTag, - gfx::Size(40, 60), gfx::Size(20, 30)); - EXPECT_TRUE( - process_->sink().GetUniqueMessageMatching(ViewMsg_PaintAtSize::ID)); - - NotificationRegistrar registrar; - MockPaintingObserver observer; - registrar.Add( - &observer, - NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK, - Source<RenderWidgetHost>(host_.get())); - - host_->OnPaintAtSizeAck(kPaintAtSizeTag, gfx::Size(20, 30)); - EXPECT_EQ(host_.get(), observer.host()); - EXPECT_EQ(kPaintAtSizeTag, observer.tag()); - EXPECT_EQ(20, observer.size().width()); - EXPECT_EQ(30, observer.size().height()); -} - TEST_F(RenderWidgetHostTest, IgnoreKeyEventsHandledByRenderer) { // Simulate a keyboard event. SimulateKeyboardEvent(WebInputEvent::RawKeyDown); diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc index 6572ad0..9f8a72f 100644 --- a/content/common/swapped_out_messages.cc +++ b/content/common/swapped_out_messages.cc @@ -19,7 +19,6 @@ bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) { switch (msg->type()) { // Handled by RenderWidgetHost. case InputHostMsg_HandleInputEvent_ACK::ID: - case ViewHostMsg_PaintAtSize_ACK::ID: case ViewHostMsg_UpdateRect::ID: // Allow targeted navigations while swapped out. case ViewHostMsg_OpenURL::ID: diff --git a/content/common/view_messages.h b/content/common/view_messages.h index c552b3e..1e81893 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -753,20 +753,6 @@ IPC_MESSAGE_ROUTED1(ViewMsg_WasShown, // exit if no other views are using it. IPC_MESSAGE_ROUTED0(ViewMsg_WasSwappedOut) -// Sent to render the view into the supplied transport DIB, resize -// the web widget to match the |page_size|, scale it by the -// appropriate scale to make it fit the |desired_size|, and return -// it. In response to this message, the host generates a -// ViewHostMsg_PaintAtSize_ACK message. Note that the DIB *must* be -// the right size to receive an RGBA image at the |desired_size|. -// |tag| is sent along with ViewHostMsg_PaintAtSize_ACK unmodified to -// identify the PaintAtSize message the ACK belongs to. -IPC_MESSAGE_ROUTED4(ViewMsg_PaintAtSize, - TransportDIB::Handle /* dib_handle */, - int /* tag */, - gfx::Size /* page_size */, - gfx::Size /* desired_size */) - // Tells the render view that a ViewHostMsg_UpdateRect message was processed. // This signals the render view that it can send another UpdateRect message. IPC_MESSAGE_ROUTED0(ViewMsg_UpdateRect_ACK) @@ -1465,13 +1451,6 @@ IPC_MESSAGE_ROUTED2(ViewHostMsg_DidRunInsecureContent, std::string /* security_origin */, GURL /* target URL */) -// Tells the render view that a ViewHostMsg_PaintAtSize message was -// processed, and the DIB is ready for use. |tag| has the same value that -// the tag sent along with ViewMsg_PaintAtSize. -IPC_MESSAGE_ROUTED2(ViewHostMsg_PaintAtSize_ACK, - int /* tag */, - gfx::Size /* size */) - // Sent to update part of the view. In response to this message, the host // generates a ViewMsg_UpdateRect_ACK message. IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateRect, diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h index 3366f16..a284989 100644 --- a/content/public/browser/notification_types.h +++ b/content/public/browser/notification_types.h @@ -179,11 +179,6 @@ enum NotificationType { // painted. The source is the RenderWidgetHost, the details are not used. NOTIFICATION_RENDER_WIDGET_HOST_DID_UPDATE_BACKING_STORE, - // This notifies the observer that a PaintAtSizeACK was received. The source - // is the RenderWidgetHost, the details are an instance of - // std::pair<int, gfx::Size>. - NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK, - // This notifies the observer that a HandleInputEventACK was received. The // source is the RenderWidgetHost, the details are the type of event // received. diff --git a/content/public/browser/render_widget_host.h b/content/public/browser/render_widget_host.h index 944ecbb..2eb913b 100644 --- a/content/public/browser/render_widget_host.h +++ b/content/public/browser/render_widget_host.h @@ -240,20 +240,6 @@ class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender { // Returns true if this is a RenderViewHost, false if not. virtual bool IsRenderView() const = 0; - // This tells the renderer to paint into a bitmap and return it, - // regardless of whether the tab is hidden or not. It resizes the - // web widget to match the |page_size| and then returns the bitmap - // scaled so it matches the |desired_size|, so that the scaling - // happens on the rendering thread. When the bitmap is ready, the - // renderer sends a PaintAtSizeACK to this host, and a - // RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK notification is issued. - // Note that this bypasses most of the update logic that is normally invoked, - // and doesn't put the results into the backing store. - virtual void PaintAtSize(TransportDIB::Handle dib_handle, - int tag, - const gfx::Size& page_size, - const gfx::Size& desired_size) = 0; - // Makes an IPC call to tell webkit to replace the currently selected word // or a word around the cursor. virtual void Replace(const base::string16& word) = 0; diff --git a/content/public/test/render_widget_test.cc b/content/public/test/render_widget_test.cc index ce3bb80..211a24f 100644 --- a/content/public/test/render_widget_test.cc +++ b/content/public/test/render_widget_test.cc @@ -32,122 +32,6 @@ const uint32 RenderWidgetTest::kRedARGB = 0xFFFF0000; RenderWidgetTest::RenderWidgetTest() {} -void RenderWidgetTest::ResizeAndPaint(const gfx::Size& page_size, - const gfx::Size& desired_size, - SkBitmap* snapshot) { - ASSERT_TRUE(snapshot); - static int g_sequence_num = 0; - // Use a new sequence number for each DIB. - scoped_ptr<TransportDIB> pixels( - TransportDIB::Create( - page_size.width() * page_size.height() * kNumBytesPerPixel, - ++g_sequence_num)); - - // Go ahead and map the DIB into memory, so that we can use it below to fill - // tmp_bitmap. Note that we need to do this before calling OnPaintAtSize, or - // the last reference to the shared memory will be closed and the handle will - // no longer be valid. - scoped_ptr<TransportDIB> mapped_pixels(TransportDIB::Map(pixels->handle())); - - RenderViewImpl* impl = static_cast<RenderViewImpl*>(view_); - impl->OnPaintAtSize(pixels->handle(), g_sequence_num, page_size, - desired_size); - ProcessPendingMessages(); - const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching( - ViewHostMsg_PaintAtSize_ACK::ID); - ASSERT_NE(static_cast<IPC::Message*>(NULL), msg); - ViewHostMsg_PaintAtSize_ACK::Param params; - ViewHostMsg_PaintAtSize_ACK::Read(msg, ¶ms); - render_thread_->sink().ClearMessages(); - EXPECT_EQ(g_sequence_num, params.a); - gfx::Size size = params.b; - EXPECT_EQ(desired_size, size); - - SkBitmap tmp_bitmap; - tmp_bitmap.setConfig(SkBitmap::kARGB_8888_Config, - size.width(), size.height()); - tmp_bitmap.setPixels(mapped_pixels->memory()); - // Copy the pixels from the TransportDIB object to the given snapshot. - ASSERT_TRUE(tmp_bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config)); -} - -void RenderWidgetTest::TestResizeAndPaint() { - // Hello World message is only visible if the view size is at least - // kTextPositionX x kTextPositionY - LoadHTML(base::StringPrintf( - "<html><body><div style='position: absolute; top: %d; left: " - "%d; background-color: red;'>Hello World</div></body></html>", - kTextPositionY, kTextPositionX).c_str()); - blink::WebSize old_size = view_->GetWebView()->size(); - - SkBitmap bitmap; - // If we re-size the view to something smaller than where the 'Hello World' - // text is displayed we won't see any text in the snapshot. Hence, - // the snapshot should not contain any red. - gfx::Size size(kSmallWidth, kSmallHeight); - ResizeAndPaint(size, size, &bitmap); - // Make sure that the view has been re-sized to its old size. - EXPECT_TRUE(old_size == view_->GetWebView()->size()); - EXPECT_EQ(kSmallWidth, bitmap.width()); - EXPECT_EQ(kSmallHeight, bitmap.height()); - EXPECT_FALSE(ImageContainsColor(bitmap, kRedARGB)); - - // Since we ask for the view to be re-sized to something larger than where the - // 'Hello World' text is written the text should be visible in the snapshot. - // Hence, the snapshot should contain some red. - size.SetSize(kLargeWidth, kLargeHeight); - ResizeAndPaint(size, size, &bitmap); - EXPECT_TRUE(old_size == view_->GetWebView()->size()); - EXPECT_EQ(kLargeWidth, bitmap.width()); - EXPECT_EQ(kLargeHeight, bitmap.height()); - EXPECT_TRUE(ImageContainsColor(bitmap, kRedARGB)); - - // Even if the desired size is smaller than where the text is located we - // should still see the 'Hello World' message since the view size is - // still large enough. - ResizeAndPaint(size, gfx::Size(kSmallWidth, kSmallHeight), &bitmap); - EXPECT_TRUE(old_size == view_->GetWebView()->size()); - EXPECT_EQ(kSmallWidth, bitmap.width()); - EXPECT_EQ(kSmallHeight, bitmap.height()); - EXPECT_TRUE(ImageContainsColor(bitmap, kRedARGB)); -} - -bool RenderWidgetTest::ImageContainsColor(const SkBitmap& bitmap, - uint32 argb_color) { - SkAutoLockPixels lock(bitmap); - bool ready = bitmap.readyToDraw(); - EXPECT_TRUE(ready); - if (!ready) { - return false; - } - for (int x = 0; x < bitmap.width(); ++x) { - for (int y = 0; y < bitmap.height(); ++y) { - if (argb_color == *bitmap.getAddr32(x, y)) { - return true; - } - } - } - return false; -} - -void RenderWidgetTest::OutputBitmapToFile(const SkBitmap& bitmap, - const base::FilePath& file_path) { - scoped_refptr<base::RefCountedBytes> bitmap_data(new base::RefCountedBytes()); - SkAutoLockPixels lock(bitmap); - ASSERT_TRUE(gfx::JPEGCodec::Encode( - reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), - gfx::JPEGCodec::FORMAT_BGRA, - bitmap.width(), - bitmap.height(), - static_cast<int>(bitmap.rowBytes()), - 90 /* quality */, - &bitmap_data->data())); - ASSERT_LT(0, file_util::WriteFile( - file_path, - reinterpret_cast<const char*>(bitmap_data->front()), - bitmap_data->size())); -} - void RenderWidgetTest::TestOnResize() { RenderWidget* widget = static_cast<RenderViewImpl*>(view_); diff --git a/content/public/test/render_widget_test.h b/content/public/test/render_widget_test.h index 8497194..e5f140e 100644 --- a/content/public/test/render_widget_test.h +++ b/content/public/test/render_widget_test.h @@ -31,32 +31,8 @@ class RenderWidgetTest : public RenderViewTest { static const int kTextPositionY; static const uint32 kRedARGB; - // Helper function which calls OnMsgPaintAtSize and also paints the result - // in the given bitmap. The widget is resized to |page_size| before we paint - // and the final image is resized to |desired_size|. This method is virtual so - // that TestResizeAndPaint() can be reused by subclasses of this test class. - virtual void ResizeAndPaint(const gfx::Size& page_size, - const gfx::Size& desired_size, - SkBitmap* snapshot); - - // Test for ResizeAndPaint. - void TestResizeAndPaint(); - // Test for OnResize and Resize. void TestOnResize(); - - // Helper function which returns true if the given bitmap contains the given - // ARGB color and false otherwise. - bool ImageContainsColor(const SkBitmap& bitmap, uint32 argb_color); - - // This can be used for debugging if you want to output a bitmap - // image to a file. - // FilePath tmp_path; - // base::CreateTemporaryFile(&tmp_path); - // OutputBitmapToFile(bitmap, tmp_path); - // VLOG(0) << "Bitmap image stored at: " << tmp_path.value(); - void OutputBitmapToFile(const SkBitmap& bitmap, - const base::FilePath& file_path); }; } // namespace content diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 1b6073c..3dddbf4 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc @@ -606,7 +606,6 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_CandidateWindowHidden, OnCandidateWindowHidden) IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition) IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition) - IPC_MESSAGE_HANDLER(ViewMsg_PaintAtSize, OnPaintAtSize) IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnRepaint) IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection) IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck) @@ -2170,86 +2169,6 @@ void RenderWidget::OnImeConfirmComposition(const base::string16& text, #endif } -// This message causes the renderer to render an image of the -// desired_size, regardless of whether the tab is hidden or not. -void RenderWidget::OnPaintAtSize(const TransportDIB::Handle& dib_handle, - int tag, - const gfx::Size& page_size, - const gfx::Size& desired_size) { - if (!webwidget_ || !TransportDIB::is_valid_handle(dib_handle)) { - if (TransportDIB::is_valid_handle(dib_handle)) { - // Close our unused handle. -#if defined(OS_WIN) - ::CloseHandle(dib_handle); -#elif defined(OS_MACOSX) - base::SharedMemory::CloseHandle(dib_handle); -#endif - } - return; - } - - if (page_size.IsEmpty() || desired_size.IsEmpty()) { - // If one of these is empty, then we just return the dib we were - // given, to avoid leaking it. - Send(new ViewHostMsg_PaintAtSize_ACK(routing_id_, tag, desired_size)); - return; - } - - // Map the given DIB ID into this process, and unmap it at the end - // of this function. - scoped_ptr<TransportDIB> paint_at_size_buffer( - TransportDIB::CreateWithHandle(dib_handle)); - - gfx::Size page_size_in_pixel = gfx::ToFlooredSize( - gfx::ScaleSize(page_size, device_scale_factor_)); - gfx::Size desired_size_in_pixel = gfx::ToFlooredSize( - gfx::ScaleSize(desired_size, device_scale_factor_)); - gfx::Size canvas_size = page_size_in_pixel; - float x_scale = static_cast<float>(desired_size_in_pixel.width()) / - static_cast<float>(canvas_size.width()); - float y_scale = static_cast<float>(desired_size_in_pixel.height()) / - static_cast<float>(canvas_size.height()); - - gfx::Rect orig_bounds(canvas_size); - canvas_size.set_width(static_cast<int>(canvas_size.width() * x_scale)); - canvas_size.set_height(static_cast<int>(canvas_size.height() * y_scale)); - gfx::Rect bounds(canvas_size); - - scoped_ptr<skia::PlatformCanvas> canvas( - paint_at_size_buffer->GetPlatformCanvas(canvas_size.width(), - canvas_size.height())); - if (!canvas) { - NOTREACHED(); - return; - } - - // Reset bounds to what we actually received, but they should be the - // same. - DCHECK_EQ(bounds.width(), canvas->getDevice()->width()); - DCHECK_EQ(bounds.height(), canvas->getDevice()->height()); - bounds.set_width(canvas->getDevice()->width()); - bounds.set_height(canvas->getDevice()->height()); - - canvas->save(); - // Add the scale factor to the canvas, so that we'll get the desired size. - canvas->scale(SkFloatToScalar(x_scale), SkFloatToScalar(y_scale)); - - // Have to make sure we're laid out at the right size before - // rendering. - gfx::Size old_size = webwidget_->size(); - webwidget_->resize(page_size); - webwidget_->layout(); - - // Paint the entire thing (using original bounds, not scaled bounds). - PaintRect(orig_bounds, orig_bounds.origin(), canvas.get()); - canvas->restore(); - - // Return the widget to its previous size. - webwidget_->resize(old_size); - - Send(new ViewHostMsg_PaintAtSize_ACK(routing_id_, tag, bounds.size())); -} - void RenderWidget::OnSnapshot(const gfx::Rect& src_subrect) { SkBitmap snapshot; diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 5fdae4e..0813df5 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h @@ -360,10 +360,6 @@ class CONTENT_EXPORT RenderWidget virtual void OnImeConfirmComposition(const base::string16& text, const gfx::Range& replacement_range, bool keep_selection); - void OnPaintAtSize(const TransportDIB::Handle& dib_id, - int tag, - const gfx::Size& page_size, - const gfx::Size& desired_size); void OnRepaint(gfx::Size size_to_paint); void OnSyntheticGestureCompleted(); void OnSetTextDirection(blink::WebTextDirection direction); diff --git a/content/renderer/render_widget_browsertest.cc b/content/renderer/render_widget_browsertest.cc index 8d72414..3a2bb1aa 100644 --- a/content/renderer/render_widget_browsertest.cc +++ b/content/renderer/render_widget_browsertest.cc @@ -6,10 +6,6 @@ namespace content { -TEST_F(RenderWidgetTest, OnMsgPaintAtSize) { - TestResizeAndPaint(); -} - TEST_F(RenderWidgetTest, OnResize) { TestOnResize(); } diff --git a/ui/surface/transport_dib.h b/ui/surface/transport_dib.h index 7ec7bb8..4a00967 100644 --- a/ui/surface/transport_dib.h +++ b/ui/surface/transport_dib.h @@ -74,13 +74,6 @@ class SURFACE_EXPORT TransportDIB { // Returns a default, invalid handle, that is meant to indicate a missing // Transport DIB. static Handle DefaultHandleValue() { return NULL; } - - // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE - // ACTUALLY USED AS A REAL HANDLE. - static Handle GetFakeHandleForTest() { - static int fake_handle = 10; - return reinterpret_cast<Handle>(fake_handle++); - } #elif defined(TOOLKIT_GTK) typedef int Handle; // These two ints are SysV IPC shared memory keys struct Id { @@ -102,13 +95,6 @@ class SURFACE_EXPORT TransportDIB { // Returns a default, invalid handle, that is meant to indicate a missing // Transport DIB. static Handle DefaultHandleValue() { return -1; } - - // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE - // ACTUALLY USED AS A REAL HANDLE. - static Handle GetFakeHandleForTest() { - static int fake_handle = 10; - return fake_handle++; - } #else // OS_POSIX typedef base::SharedMemoryHandle Handle; // On POSIX, the inode number of the backing file is used as an id. @@ -121,13 +107,6 @@ class SURFACE_EXPORT TransportDIB { // Returns a default, invalid handle, that is meant to indicate a missing // Transport DIB. static Handle DefaultHandleValue() { return Handle(); } - - // Returns a value that is ONLY USEFUL FOR TESTS WHERE IT WON'T BE - // ACTUALLY USED AS A REAL HANDLE. - static Handle GetFakeHandleForTest() { - static int fake_handle = 10; - return Handle(fake_handle++, false); - } #endif // Create a new TransportDIB, returning NULL on failure. |