diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-04 19:26:13 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-04 19:26:13 +0000 |
commit | 68b522563b8dc3c28d66455959915cf23ac6331e (patch) | |
tree | 8c4c3217574743efd8f84ac94c1392770bafd06f | |
parent | 872b5045d897456ebcea2fe8a527740d5eab2fd2 (diff) | |
download | chromium_src-68b522563b8dc3c28d66455959915cf23ac6331e.zip chromium_src-68b522563b8dc3c28d66455959915cf23ac6331e.tar.gz chromium_src-68b522563b8dc3c28d66455959915cf23ac6331e.tar.bz2 |
Adds a TabContentsViewAura.
It is derived from TCVV/NTCVA. Right now, it's behind the flag --enable-tcva.
http://crbug.com/118410
TEST=none
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=130442
Review URL: https://chromiumcodereview.appspot.com/9963079
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@130704 0039d316-1c4b-4281-b951-d872f2087c98
14 files changed, 843 insertions, 44 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 578f549..6c1cfbb 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -113,8 +113,9 @@ #if defined(USE_AURA) #include "chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.h" +#include "chrome/browser/tab_contents/chrome_web_contents_view_delegate_views.h" #elif defined(OS_WIN) -#include "chrome/browser/tab_contents/chrome_web_contents_view_delegate_win.h" +#include "chrome/browser/tab_contents/chrome_web_contents_view_delegate_views.h" #endif #if defined(TOOLKIT_USES_GTK) @@ -364,9 +365,13 @@ content::BrowserMainParts* ChromeContentBrowserClient::CreateBrowserMainParts( content::WebContentsView* ChromeContentBrowserClient::OverrideCreateWebContentsView( WebContents* web_contents) { -#if defined(TOOLKIT_VIEWS) && (!defined(OS_WIN) || defined(USE_AURA)) - return new TabContentsViewViews(web_contents, - GetWebContentsViewDelegate(web_contents)); +#if defined(USE_AURA) + // TODO(beng): remove this once TCVV is gone. + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (!command_line.HasSwitch(switches::kEnableTCVA)) { + return new TabContentsViewViews(web_contents, + GetWebContentsViewDelegate(web_contents)); + } #endif return NULL; } @@ -374,16 +379,22 @@ content::WebContentsView* content::WebContentsViewDelegate* ChromeContentBrowserClient::GetWebContentsViewDelegate( content::WebContents* web_contents) { -#if defined(OS_WIN) && !defined(USE_AURA) - return new ChromeWebContentsViewDelegateWin(web_contents); +#if defined(OS_WIN) || defined(USE_AURA) +// TODO(beng): replace all of this once TCVV is removed. +#if defined(OS_WIN) + return new ChromeWebContentsViewDelegateViews(web_contents); +#elif defined(USE_AURA) + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kEnableTCVA)) + return new ChromeWebContentsViewDelegateViews(web_contents); + return new ChromeWebContentsViewDelegateAura(web_contents); +#endif #elif defined(TOOLKIT_GTK) return new ChromeWebContentsViewDelegateGtk(web_contents); #elif defined(OS_MACOSX) return chrome_web_contents_view_delegate_mac::CreateWebContentsViewDelegateMac( web_contents); -#elif defined(USE_AURA) - return new ChromeWebContentsViewDelegateAura(web_contents); #else return NULL; #endif diff --git a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.cc b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.cc index ac69b79..f528182 100644 --- a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.cc +++ b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.cc @@ -24,6 +24,22 @@ content::WebDragDestDelegate* return bookmark_handler_.get(); } +void ChromeWebContentsViewDelegateAura::StoreFocus() { +} + +void ChromeWebContentsViewDelegateAura::RestoreFocus() { +} + +bool ChromeWebContentsViewDelegateAura::Focus() { + return false; +} + +void ChromeWebContentsViewDelegateAura::TakeFocus(bool reverse) { +} + void ChromeWebContentsViewDelegateAura::ShowContextMenu( const content::ContextMenuParams& params) { } + +void ChromeWebContentsViewDelegateAura::SizeChanged(const gfx::Size& size) { +} diff --git a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.h b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.h index 0a152da..99e7b05 100644 --- a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.h +++ b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_aura.h @@ -28,8 +28,13 @@ class ChromeWebContentsViewDelegateAura // Overridden from WebContentsViewDelegate: virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE; + virtual void StoreFocus() OVERRIDE; + virtual void RestoreFocus() OVERRIDE; + virtual bool Focus() OVERRIDE; + virtual void TakeFocus(bool reverse) OVERRIDE; virtual void ShowContextMenu( const content::ContextMenuParams& params) OVERRIDE; + virtual void SizeChanged(const gfx::Size& size) OVERRIDE; private: content::WebContents* web_contents_; diff --git a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_win.cc b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_views.cc index 802de7c..bfef3c8 100644 --- a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_win.cc +++ b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_views.cc @@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/tab_contents/chrome_web_contents_view_delegate_win.h" +#include "chrome/browser/tab_contents/chrome_web_contents_view_delegate_views.h" #include "chrome/browser/browser_shutdown.h" -#include "chrome/browser/tab_contents/web_drag_bookmark_handler_win.h" #include "chrome/browser/ui/constrained_window_tab_helper.h" #include "chrome/browser/ui/sad_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" @@ -20,14 +19,21 @@ #include "ui/views/focus/view_storage.h" #include "ui/views/widget/widget.h" -ChromeWebContentsViewDelegateWin::ChromeWebContentsViewDelegateWin( +#if defined(USE_AURA) +#include "chrome/browser/tab_contents/web_drag_bookmark_handler_aura.h" +#include "ui/aura/window.h" +#else +#include "chrome/browser/tab_contents/web_drag_bookmark_handler_win.h" +#endif + +ChromeWebContentsViewDelegateViews::ChromeWebContentsViewDelegateViews( content::WebContents* web_contents) : web_contents_(web_contents) { last_focused_view_storage_id_ = views::ViewStorage::GetInstance()->CreateStorageID(); } -ChromeWebContentsViewDelegateWin::~ChromeWebContentsViewDelegateWin() { +ChromeWebContentsViewDelegateViews::~ChromeWebContentsViewDelegateViews() { // Makes sure to remove any stored view we may still have in the ViewStorage. // // It is possible the view went away before us, so we only do this if the @@ -39,14 +45,18 @@ ChromeWebContentsViewDelegateWin::~ChromeWebContentsViewDelegateWin() { } content::WebDragDestDelegate* - ChromeWebContentsViewDelegateWin::GetDragDestDelegate() { + ChromeWebContentsViewDelegateViews::GetDragDestDelegate() { // We install a chrome specific handler to intercept bookmark drags for the // bookmark manager/extension API. +#if defined(USE_AURA) + bookmark_handler_.reset(new WebDragBookmarkHandlerAura); +#else bookmark_handler_.reset(new WebDragBookmarkHandlerWin); +#endif return bookmark_handler_.get(); } -bool ChromeWebContentsViewDelegateWin::Focus() { +bool ChromeWebContentsViewDelegateViews::Focus() { TabContentsWrapper* wrapper = TabContentsWrapper::GetCurrentWrapperForContents(web_contents_); if (wrapper) { @@ -71,11 +81,11 @@ bool ChromeWebContentsViewDelegateWin::Focus() { return false; } -void ChromeWebContentsViewDelegateWin::TakeFocus(bool reverse) { +void ChromeWebContentsViewDelegateViews::TakeFocus(bool reverse) { GetFocusManager()->AdvanceFocus(reverse); } -void ChromeWebContentsViewDelegateWin::StoreFocus() { +void ChromeWebContentsViewDelegateViews::StoreFocus() { views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL) @@ -88,7 +98,7 @@ void ChromeWebContentsViewDelegateWin::StoreFocus() { view_storage->StoreView(last_focused_view_storage_id_, focused_view); } -void ChromeWebContentsViewDelegateWin::RestoreFocus() { +void ChromeWebContentsViewDelegateViews::RestoreFocus() { views::ViewStorage* view_storage = views::ViewStorage::GetInstance(); views::View* last_focused_view = view_storage->RetrieveView(last_focused_view_storage_id_); @@ -111,7 +121,7 @@ void ChromeWebContentsViewDelegateWin::RestoreFocus() { } } -void ChromeWebContentsViewDelegateWin::ShowContextMenu( +void ChromeWebContentsViewDelegateViews::ShowContextMenu( const content::ContextMenuParams& params) { context_menu_.reset(new RenderViewContextMenuViews(web_contents_, params)); context_menu_->Init(); @@ -122,9 +132,15 @@ void ChromeWebContentsViewDelegateWin::ShowContextMenu( gfx::Point screen_point(params.x, params.y); +#if defined(USE_AURA) + gfx::Point view_origin = + web_contents_->GetView()->GetNativeView()->GetScreenBounds().origin(); + screen_point.Offset(view_origin.x(), view_origin.y()); +#else POINT temp = screen_point.ToPOINT(); ClientToScreen(web_contents_->GetView()->GetNativeView(), &temp); screen_point = temp; +#endif // Enable recursive tasks on the message loop so we can get updates while // the context menu is being displayed. @@ -132,7 +148,7 @@ void ChromeWebContentsViewDelegateWin::ShowContextMenu( context_menu_->RunMenuAt(GetTopLevelWidget(), screen_point); } -void ChromeWebContentsViewDelegateWin::SizeChanged(const gfx::Size& size) { +void ChromeWebContentsViewDelegateViews::SizeChanged(const gfx::Size& size) { TabContentsWrapper* wrapper = TabContentsWrapper::GetCurrentWrapperForContents(web_contents_); if (!wrapper) @@ -142,20 +158,21 @@ void ChromeWebContentsViewDelegateWin::SizeChanged(const gfx::Size& size) { sad_tab->SetBounds(gfx::Rect(size)); } -views::Widget* ChromeWebContentsViewDelegateWin::GetTopLevelWidget() { - HWND top_level_window = web_contents_->GetView()->GetTopLevelNativeWindow(); +views::Widget* ChromeWebContentsViewDelegateViews::GetTopLevelWidget() { + gfx::NativeWindow top_level_window = + web_contents_->GetView()->GetTopLevelNativeWindow(); if (!top_level_window) return NULL; return views::Widget::GetWidgetForNativeWindow(top_level_window); } views::FocusManager* - ChromeWebContentsViewDelegateWin::GetFocusManager() { + ChromeWebContentsViewDelegateViews::GetFocusManager() { views::Widget* toplevel_widget = GetTopLevelWidget(); return toplevel_widget ? toplevel_widget->GetFocusManager() : NULL; } -void ChromeWebContentsViewDelegateWin::SetInitialFocus() { +void ChromeWebContentsViewDelegateViews::SetInitialFocus() { if (web_contents_->FocusLocationBarByDefault()) { web_contents_->SetFocusToLocationBar(false); } else { diff --git a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_win.h b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_views.h index a573372..cbf6486 100644 --- a/chrome/browser/tab_contents/chrome_web_contents_view_delegate_win.h +++ b/chrome/browser/tab_contents/chrome_web_contents_view_delegate_views.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_WIN_H_ -#define CHROME_BROWSER_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_WIN_H_ +#ifndef CHROME_BROWSER_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_VIEWS_H_ +#define CHROME_BROWSER_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_VIEWS_H_ #pragma once #include "base/basictypes.h" @@ -13,10 +13,10 @@ class ConstrainedWindowViews; class RenderViewContextMenuViews; -class WebDragBookmarkHandlerWin; namespace content { class WebContents; +class WebDragDestDelegate; } namespace views { @@ -26,11 +26,12 @@ class Widget; // A chrome specific class that extends TabContentsViewWin with features like // constrained windows, which live in chrome. -class ChromeWebContentsViewDelegateWin +class ChromeWebContentsViewDelegateViews : public content::WebContentsViewDelegate { public: - explicit ChromeWebContentsViewDelegateWin(content::WebContents* web_contents); - virtual ~ChromeWebContentsViewDelegateWin(); + explicit ChromeWebContentsViewDelegateViews( + content::WebContents* web_contents); + virtual ~ChromeWebContentsViewDelegateViews(); // Overridden from WebContentsViewDelegate: virtual content::WebDragDestDelegate* GetDragDestDelegate() OVERRIDE; @@ -55,11 +56,11 @@ class ChromeWebContentsViewDelegateWin scoped_ptr<RenderViewContextMenuViews> context_menu_; // The chrome specific delegate that receives events from WebDragDest. - scoped_ptr<WebDragBookmarkHandlerWin> bookmark_handler_; + scoped_ptr<content::WebDragDestDelegate> bookmark_handler_; content::WebContents* web_contents_; - DISALLOW_COPY_AND_ASSIGN(ChromeWebContentsViewDelegateWin); + DISALLOW_COPY_AND_ASSIGN(ChromeWebContentsViewDelegateViews); }; -#endif // CHROME_BROWSER_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_WIN_H_ +#endif // CHROME_BROWSER_TAB_CONTENTS_CHROME_WEB_CONTENTS_VIEW_DELEGATE_VIEWS_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 1fb6531..23de458 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2210,8 +2210,8 @@ 'browser/tab_contents/chrome_web_contents_view_delegate_gtk.h', 'browser/tab_contents/chrome_web_contents_view_delegate_mac.h', 'browser/tab_contents/chrome_web_contents_view_delegate_mac.mm', - 'browser/tab_contents/chrome_web_contents_view_delegate_win.cc', - 'browser/tab_contents/chrome_web_contents_view_delegate_win.h', + 'browser/tab_contents/chrome_web_contents_view_delegate_views.cc', + 'browser/tab_contents/chrome_web_contents_view_delegate_views.h', 'browser/tab_contents/confirm_infobar_delegate.cc', 'browser/tab_contents/confirm_infobar_delegate.h', 'browser/tab_contents/insecure_content_infobar_delegate.cc', @@ -4288,8 +4288,6 @@ ['exclude', '^browser/google/google_update.h'], ['exclude', '^browser/hang_monitor/'], ['exclude', '^browser/renderer_host/render_widget_host_view_views*'], - ['exclude', '^browser/tab_contents/chrome_web_contents_view_delegate_win.cc'], - ['exclude', '^browser/tab_contents/chrome_web_contents_view_delegate_win.h'], ['exclude', '^browser/tab_contents/web_drag_bookmark_handler_win.cc'], ['exclude', '^browser/tab_contents/web_drag_bookmark_handler_win.h'], ['exclude', '^browser/ui/browser_list_stub.cc'], diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index f92e020..fe4aee7 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -1363,6 +1363,11 @@ const char kDisableDesktopShortcuts[] = "disable-desktop-shortcuts"; const char kTouchDevices[] = "touch-devices"; #endif +#if defined(USE_AURA) +// Use TabContentsViewAura instead of the default implementation. +const char kEnableTCVA[] = "enable-tcva"; +#endif + #ifndef NDEBUG // Enables overriding the path of file manager extension. const char kFileManagerExtensionPath[] = "filemgr-ext-path"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 96c819a..a531f5d 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -390,6 +390,10 @@ extern const char kDisableDesktopShortcuts[]; extern const char kTouchDevices[]; #endif +#if defined(USE_AURA) +extern const char kEnableTCVA[]; +#endif + #ifndef NDEBUG extern const char kFileManagerExtensionPath[]; extern const char kDumpProfileDependencyGraph[]; diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc index b6243ec..cd36641 100644 --- a/content/browser/tab_contents/tab_contents.cc +++ b/content/browser/tab_contents/tab_contents.cc @@ -64,7 +64,9 @@ #include "webkit/glue/web_intent_data.h" #include "webkit/glue/webpreferences.h" -#if defined(OS_WIN) && !defined(USE_AURA) +#if defined(USE_AURA) +#include "content/browser/tab_contents/tab_contents_view_aura.h" +#elif defined(OS_WIN) #include "content/browser/tab_contents/tab_contents_view_win.h" #elif defined(TOOLKIT_GTK) #include "content/browser/tab_contents/tab_contents_view_gtk.h" @@ -281,7 +283,9 @@ TabContents::TabContents(content::BrowserContext* browser_context, content::WebContentsViewDelegate* delegate = content::GetContentClient()->browser()->GetWebContentsViewDelegate( this); -#if defined(OS_WIN) && !defined(USE_AURA) +#if defined(USE_AURA) + view_.reset(new TabContentsViewAura(this, delegate)); +#elif defined(OS_WIN) view_.reset(new TabContentsViewWin(this, delegate)); #elif defined(TOOLKIT_GTK) view_.reset(new content::TabContentsViewGtk(this, delegate)); diff --git a/content/browser/tab_contents/tab_contents_view_aura.cc b/content/browser/tab_contents/tab_contents_view_aura.cc index e2df6be..dbe93a4 100644 --- a/content/browser/tab_contents/tab_contents_view_aura.cc +++ b/content/browser/tab_contents/tab_contents_view_aura.cc @@ -2,10 +2,599 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This is just a placeholder - TabContentsViewAura is not yet implemented -// (instead chrome has it's own TabContentsViewViews that is used for Aura). +#include "content/browser/tab_contents/tab_contents_view_aura.h" -// We need to make sure the compiler sees this interface declaration somewhere -// so that it can emit exported versions of the inline ctor/dtor functions, -// otherwise chrome.dll will get a linker error on Windows Aura builds. +#include "base/utf_string_conversions.h" +#include "content/browser/renderer_host/render_view_host_factory.h" +#include "content/browser/tab_contents/interstitial_page_impl.h" +#include "content/browser/tab_contents/tab_contents.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host.h" +#include "content/public/browser/render_widget_host_view.h" +#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_view_delegate.h" +#include "content/public/browser/web_drag_dest_delegate.h" +#include "ui/aura/client/drag_drop_client.h" +#include "ui/aura/client/drag_drop_delegate.h" +#include "ui/aura/event.h" +#include "ui/aura/root_window.h" +#include "ui/aura/window.h" +#include "ui/base/clipboard/custom_data_helper.h" +#include "ui/base/dragdrop/drag_drop_types.h" +#include "ui/base/dragdrop/os_exchange_data.h" +#include "ui/base/dragdrop/os_exchange_data_provider_aura.h" +#include "ui/base/hit_test.h" +#include "ui/gfx/compositor/layer.h" +#include "ui/gfx/screen.h" +#include "webkit/glue/webdropdata.h" + +namespace { + +// Listens to all mouse drag events during a drag and drop and sends them to +// the renderer. +class WebDragSourceAura : public MessageLoopForUI::Observer { + public: + explicit WebDragSourceAura(TabContents* contents) + : contents_(contents) { + MessageLoopForUI::current()->AddObserver(this); + } + + virtual ~WebDragSourceAura() { + MessageLoopForUI::current()->RemoveObserver(this); + } + + // MessageLoop::Observer implementation: + virtual base::EventStatus WillProcessEvent( + const base::NativeEvent& event) OVERRIDE { + return base::EVENT_CONTINUE; + } + virtual void DidProcessEvent(const base::NativeEvent& event) OVERRIDE { + ui::EventType type = ui::EventTypeFromNative(event); + content::RenderViewHost* rvh = NULL; + switch (type) { + case ui::ET_MOUSE_DRAGGED: + rvh = contents_->GetRenderViewHost(); + if (rvh) { + gfx::Point screen_loc = ui::EventLocationFromNative(event); + gfx::Point client_loc = screen_loc; + aura::Window* window = rvh->GetView()->GetNativeView(); + aura::Window::ConvertPointToWindow(window->GetRootWindow(), + window, &client_loc); + rvh->DragSourceMovedTo(client_loc.x(), client_loc.y(), + screen_loc.x(), screen_loc.y()); + } + break; + default: + break; + } + } + + + private: + TabContents* contents_; + + DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura); +}; + +// Utility to fill a ui::OSExchangeDataProviderAura object from WebDropData. +void PrepareDragData(const WebDropData& drop_data, + ui::OSExchangeDataProviderAura* provider) { + if (!drop_data.plain_text.empty()) + provider->SetString(drop_data.plain_text); + if (drop_data.url.is_valid()) + provider->SetURL(drop_data.url, drop_data.url_title); + if (!drop_data.text_html.empty()) + provider->SetHtml(drop_data.text_html, drop_data.html_base_url); + if (!drop_data.filenames.empty()) { + std::vector<FilePath> paths; + for (std::vector<string16>::const_iterator it = drop_data.filenames.begin(); + it != drop_data.filenames.end(); ++it) + paths.push_back(FilePath::FromUTF8Unsafe(UTF16ToUTF8(*it))); + provider->SetFilenames(paths); + } + if (!drop_data.custom_data.empty()) { + Pickle pickle; + ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle); + provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), + pickle); + } +} + +// Utility to fill a WebDropData object from ui::OSExchangeData. +void PrepareWebDropData(WebDropData* drop_data, + const ui::OSExchangeData& data) { + string16 plain_text, url_title; + GURL url; + + data.GetString(&plain_text); + if (!plain_text.empty()) + drop_data->plain_text = plain_text; + + data.GetURLAndTitle(&url, &url_title); + if (url.is_valid()) { + drop_data->url = url; + drop_data->url_title = url_title; + } + + data.GetHtml(&drop_data->text_html, &drop_data->html_base_url); + + std::vector<FilePath> files; + if (data.GetFilenames(&files) && !files.empty()) { + for (std::vector<FilePath>::const_iterator it = files.begin(); + it != files.end(); ++it) + drop_data->filenames.push_back(UTF8ToUTF16(it->AsUTF8Unsafe())); + } + + Pickle pickle; + if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), + &pickle)) + ui::ReadCustomDataIntoMap(pickle.data(), pickle.size(), + &drop_data->custom_data); +} + +// Utilities to convert between WebKit::WebDragOperationsMask and +// ui::DragDropTypes. +int ConvertFromWeb(WebKit::WebDragOperationsMask ops) { + int drag_op = ui::DragDropTypes::DRAG_NONE; + if (ops & WebKit::WebDragOperationCopy) + drag_op |= ui::DragDropTypes::DRAG_COPY; + if (ops & WebKit::WebDragOperationMove) + drag_op |= ui::DragDropTypes::DRAG_MOVE; + if (ops & WebKit::WebDragOperationLink) + drag_op |= ui::DragDropTypes::DRAG_LINK; + return drag_op; +} + +WebKit::WebDragOperationsMask ConvertToWeb(int drag_op) { + int web_drag_op = WebKit::WebDragOperationNone; + if (drag_op & ui::DragDropTypes::DRAG_COPY) + web_drag_op |= WebKit::WebDragOperationCopy; + if (drag_op & ui::DragDropTypes::DRAG_MOVE) + web_drag_op |= WebKit::WebDragOperationMove; + if (drag_op & ui::DragDropTypes::DRAG_LINK) + web_drag_op |= WebKit::WebDragOperationLink; + return (WebKit::WebDragOperationsMask) web_drag_op; +} + +} // namespace + + +//////////////////////////////////////////////////////////////////////////////// +// TabContentsViewAura, public: + +TabContentsViewAura::TabContentsViewAura( + TabContents* tab_contents, + content::WebContentsViewDelegate* delegate) + : tab_contents_(tab_contents), + view_(NULL), + delegate_(delegate), + current_drag_op_(WebKit::WebDragOperationNone), + close_tab_after_drag_ends_(false) { +} + +TabContentsViewAura::~TabContentsViewAura() { +} + +//////////////////////////////////////////////////////////////////////////////// +// TabContentsViewAura, private: + +void TabContentsViewAura::SizeChangedCommon(const gfx::Size& size) { + if (tab_contents_->GetInterstitialPage()) + tab_contents_->GetInterstitialPage()->SetSize(size); + content::RenderWidgetHostView* rwhv = + tab_contents_->GetRenderWidgetHostView(); + if (rwhv) + rwhv->SetSize(size); +} + +void TabContentsViewAura::EndDrag(WebKit::WebDragOperationsMask ops) { + aura::RootWindow* root_window = GetNativeView()->GetRootWindow(); + gfx::Point screen_loc = root_window->last_mouse_location(); + gfx::Point client_loc = screen_loc; + content::RenderViewHost* rvh = tab_contents_->GetRenderViewHost(); + aura::Window* window = rvh->GetView()->GetNativeView(); + aura::Window::ConvertPointToWindow(root_window, window, &client_loc); + rvh->DragSourceEndedAt(client_loc.x(), client_loc.y(), screen_loc.x(), + screen_loc.y(), ops); +} + +content::WebDragDestDelegate* TabContentsViewAura::GetDragDestDelegate() { + return delegate_.get() ? delegate_->GetDragDestDelegate() : NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +// TabContentsViewAura, WebContentsView implementation: + +void TabContentsViewAura::CreateView(const gfx::Size& initial_size) { + initial_size_ = initial_size; + + window_.reset(new aura::Window(this)); + window_->SetType(aura::client::WINDOW_TYPE_CONTROL); + window_->SetTransparent(false); + window_->Init(ui::LAYER_TEXTURED); + window_->layer()->SetMasksToBounds(true); + window_->SetName("TabContentsViewAura"); + + // TODO(beng): allow for delegate init step. + + // TODO(beng): drag & drop init. +} + +content::RenderWidgetHostView* TabContentsViewAura::CreateViewForWidget( + content::RenderWidgetHost* render_widget_host) { + if (render_widget_host->GetView()) { + // During testing, the view will already be set up in most cases to the + // test view, so we don't want to clobber it with a real one. To verify that + // this actually is happening (and somebody isn't accidentally creating the + // view twice), we check for the RVH Factory, which will be set when we're + // making special ones (which go along with the special views). + DCHECK(RenderViewHostFactory::has_factory()); + return render_widget_host->GetView(); + } + + view_ = content::RenderWidgetHostView::CreateViewForWidget( + render_widget_host); + view_->InitAsChild(NULL); + GetNativeView()->AddChild(view_->GetNativeView()); + view_->Show(); + + // We listen to drag drop events in the newly created view's window. + aura::client::SetDragDropDelegate(view_->GetNativeView(), this); + return view_; +} + +gfx::NativeView TabContentsViewAura::GetNativeView() const { + return window_.get(); +} + +gfx::NativeView TabContentsViewAura::GetContentNativeView() const { + return view_->GetNativeView(); +} + +gfx::NativeWindow TabContentsViewAura::GetTopLevelNativeWindow() const { + return window_->GetToplevelWindow(); +} + +void TabContentsViewAura::GetContainerBounds(gfx::Rect *out) const { + *out = window_->GetScreenBounds(); +} + +void TabContentsViewAura::SetPageTitle(const string16& title) { + window_->set_title(title); +} + +void TabContentsViewAura::OnTabCrashed(base::TerminationStatus status, + int error_code) { + view_ = NULL; +} + +void TabContentsViewAura::SizeContents(const gfx::Size& size) { + gfx::Rect bounds = window_->bounds(); + if (bounds.size() != size) { + bounds.set_size(size); + window_->SetBounds(bounds); + } else { + // Our size matches what we want but the renderers size may not match. + // Pretend we were resized so that the renderers size is updated too. + SizeChangedCommon(size); + + } +} + +void TabContentsViewAura::RenderViewCreated(content::RenderViewHost* host) { +} + +void TabContentsViewAura::Focus() { + if (tab_contents_->GetInterstitialPage()) { + tab_contents_->GetInterstitialPage()->Focus(); + return; + } + + if (delegate_.get() && delegate_->Focus()) + return; + + content::RenderWidgetHostView* rwhv = + tab_contents_->GetRenderWidgetHostView(); + if (rwhv) + rwhv->Focus(); +} + +void TabContentsViewAura::SetInitialFocus() { + if (tab_contents_->FocusLocationBarByDefault()) + tab_contents_->SetFocusToLocationBar(false); + else + Focus(); +} + +void TabContentsViewAura::StoreFocus() { + if (delegate_.get()) + delegate_->StoreFocus(); +} + +void TabContentsViewAura::RestoreFocus() { + if (delegate_.get()) + delegate_->RestoreFocus(); +} + +bool TabContentsViewAura::IsDoingDrag() const { + aura::RootWindow* root_window = GetNativeView()->GetRootWindow(); + if (aura::client::GetDragDropClient(root_window)) + return aura::client::GetDragDropClient(root_window)->IsDragDropInProgress(); + return false; +} + +void TabContentsViewAura::CancelDragAndCloseTab() { + DCHECK(IsDoingDrag()); + // We can't close the tab while we're in the drag and + // |drag_handler_->CancelDrag()| is async. Instead, set a flag to cancel + // the drag and when the drag nested message loop ends, close the tab. + aura::RootWindow* root_window = GetNativeView()->GetRootWindow(); + if (aura::client::GetDragDropClient(root_window)) + aura::client::GetDragDropClient(root_window)->DragCancel(); + + close_tab_after_drag_ends_ = true; +} + +bool TabContentsViewAura::IsEventTracking() const { + return false; +} + +void TabContentsViewAura::CloseTabAfterEventTracking() { +} + +void TabContentsViewAura::GetViewBounds(gfx::Rect* out) const { + *out = window_->GetScreenBounds(); +} + +//////////////////////////////////////////////////////////////////////////////// +// TabContentsViewAura, RenderViewHostDelegate::View implementation: + +void TabContentsViewAura::CreateNewWindow( + int route_id, + const ViewHostMsg_CreateWindow_Params& params) { + tab_contents_view_helper_.CreateNewWindow(tab_contents_, route_id, params); +} + +void TabContentsViewAura::CreateNewWidget(int route_id, + WebKit::WebPopupType popup_type) { + tab_contents_view_helper_.CreateNewWidget(tab_contents_, + route_id, + false, + popup_type); +} + +void TabContentsViewAura::CreateNewFullscreenWidget(int route_id) { + tab_contents_view_helper_.CreateNewWidget(tab_contents_, + route_id, + true, + WebKit::WebPopupTypeNone); +} + +void TabContentsViewAura::ShowCreatedWindow(int route_id, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) { + tab_contents_view_helper_.ShowCreatedWindow( + tab_contents_, route_id, disposition, initial_pos, user_gesture); +} + +void TabContentsViewAura::ShowCreatedWidget(int route_id, + const gfx::Rect& initial_pos) { + tab_contents_view_helper_.ShowCreatedWidget(tab_contents_, + route_id, + false, + initial_pos); +} + +void TabContentsViewAura::ShowCreatedFullscreenWidget(int route_id) { + tab_contents_view_helper_.ShowCreatedWidget(tab_contents_, + route_id, + true, + gfx::Rect()); +} + +void TabContentsViewAura::ShowContextMenu( + const content::ContextMenuParams& params) { + // Allow WebContentsDelegates to handle the context menu operation first. + if (tab_contents_->GetDelegate() && + tab_contents_->GetDelegate()->HandleContextMenu(params)) { + return; + } + + if (delegate_.get()) + delegate_->ShowContextMenu(params); +} + +void TabContentsViewAura::ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned) { + // External popup menus are only used on Mac. + NOTIMPLEMENTED(); +} + +void TabContentsViewAura::StartDragging( + const WebDropData& drop_data, + WebKit::WebDragOperationsMask operations, + const SkBitmap& image, + const gfx::Point& image_offset) { + aura::RootWindow* root_window = GetNativeView()->GetRootWindow(); + if (!aura::client::GetDragDropClient(root_window)) + return; + + ui::OSExchangeDataProviderAura* provider = new ui::OSExchangeDataProviderAura; + PrepareDragData(drop_data, provider); + if (!image.isNull()) + provider->set_drag_image(image); + ui::OSExchangeData data(provider); // takes ownership of |provider|. + + scoped_ptr<WebDragSourceAura> drag_source( + new WebDragSourceAura(tab_contents_)); + + // We need to enable recursive tasks on the message loop so we can get + // updates while in the system DoDragDrop loop. + int result_op = 0; + { + // TODO(sad): Avoid using last_mouse_location here, since the drag may not + // always start from a mouse-event (e.g. a touch or gesture event could + // initiate the drag). The location information should be carried over from + // webkit. http://crbug.com/114754 + gfx::Point location(root_window->last_mouse_location()); + location.Offset(-image_offset.x(), -image_offset.y()); + MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); + result_op = aura::client::GetDragDropClient(root_window)->StartDragAndDrop( + data, location, ConvertFromWeb(operations)); + } + + EndDrag(ConvertToWeb(result_op)); + tab_contents_->GetRenderViewHost()->DragSourceSystemDragEnded();} + +void TabContentsViewAura::UpdateDragCursor(WebKit::WebDragOperation operation) { + current_drag_op_ = operation; +} + +void TabContentsViewAura::GotFocus() { + if (tab_contents_->GetDelegate()) + tab_contents_->GetDelegate()->WebContentsFocused(tab_contents_); +} + +void TabContentsViewAura::TakeFocus(bool reverse) { + if (tab_contents_->GetDelegate() && + !tab_contents_->GetDelegate()->TakeFocus(reverse) && + delegate_.get()) { + delegate_->TakeFocus(reverse); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// TabContentsViewAura, aura::WindowDelegate implementation: + +gfx::Size TabContentsViewAura::GetMinimumSize() const { + return gfx::Size(); +} + +void TabContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) { + SizeChangedCommon(new_bounds.size()); + if (delegate_.get()) + delegate_->SizeChanged(new_bounds.size()); +} + +void TabContentsViewAura::OnFocus() { +} + +void TabContentsViewAura::OnBlur() { +} + +bool TabContentsViewAura::OnKeyEvent(aura::KeyEvent* event) { + return false; +} + +gfx::NativeCursor TabContentsViewAura::GetCursor(const gfx::Point& point) { + return gfx::kNullCursor; +} + +int TabContentsViewAura::GetNonClientComponent(const gfx::Point& point) const { + return HTCLIENT; +} + +bool TabContentsViewAura::OnMouseEvent(aura::MouseEvent* event) { + if (!tab_contents_->GetDelegate()) + return false; + + switch (event->type()) { + case ui::ET_MOUSE_PRESSED: + tab_contents_->GetDelegate()->ActivateContents(tab_contents_); + break; + case ui::ET_MOUSE_MOVED: + tab_contents_->GetDelegate()->ContentsMouseEvent( + tab_contents_, gfx::Screen::GetCursorScreenPoint(), true); + break; + default: + break; + } + return false; +} + +ui::TouchStatus TabContentsViewAura::OnTouchEvent(aura::TouchEvent* event) { + return ui::TOUCH_STATUS_UNKNOWN; +} + +ui::GestureStatus TabContentsViewAura::OnGestureEvent( + aura::GestureEvent* event) { + return ui::GESTURE_STATUS_UNKNOWN; +} + +bool TabContentsViewAura::CanFocus() { + return false; +} + +void TabContentsViewAura::OnCaptureLost() { +} + +void TabContentsViewAura::OnPaint(gfx::Canvas* canvas) { +} + +void TabContentsViewAura::OnWindowDestroying() { +} + +void TabContentsViewAura::OnWindowDestroyed() { +} + +void TabContentsViewAura::OnWindowVisibilityChanged(bool visible) { + if (visible) + tab_contents_->ShowContents(); + else + tab_contents_->HideContents(); +} +//////////////////////////////////////////////////////////////////////////////// +// TabContentsViewAura, aura::client::DragDropDelegate implementation: + +void TabContentsViewAura::OnDragEntered(const aura::DropTargetEvent& event) { + if (GetDragDestDelegate()) + GetDragDestDelegate()->DragInitialize(tab_contents_); + + WebDropData drop_data; + PrepareWebDropData(&drop_data, event.data()); + WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations()); + + gfx::Point screen_pt = + GetNativeView()->GetRootWindow()->last_mouse_location(); + tab_contents_->GetRenderViewHost()->DragTargetDragEnter( + drop_data, event.location(), screen_pt, op); + + if (GetDragDestDelegate()) { + GetDragDestDelegate()->OnReceiveDragData(event.data()); + GetDragDestDelegate()->OnDragEnter(); + } +} + +int TabContentsViewAura::OnDragUpdated(const aura::DropTargetEvent& event) { + WebKit::WebDragOperationsMask op = ConvertToWeb(event.source_operations()); + gfx::Point screen_pt = + GetNativeView()->GetRootWindow()->last_mouse_location(); + tab_contents_->GetRenderViewHost()->DragTargetDragOver( + event.location(), screen_pt, op); + + if (GetDragDestDelegate()) + GetDragDestDelegate()->OnDragOver(); + + return ConvertFromWeb(current_drag_op_); +} + +void TabContentsViewAura::OnDragExited() { + tab_contents_->GetRenderViewHost()->DragTargetDragLeave(); + if (GetDragDestDelegate()) + GetDragDestDelegate()->OnDragLeave(); +} + +int TabContentsViewAura::OnPerformDrop(const aura::DropTargetEvent& event) { + tab_contents_->GetRenderViewHost()->DragTargetDrop( + event.location(), + GetNativeView()->GetRootWindow()->last_mouse_location()); + if (GetDragDestDelegate()) + GetDragDestDelegate()->OnDrop(); + return current_drag_op_; +} diff --git a/content/browser/tab_contents/tab_contents_view_aura.h b/content/browser/tab_contents/tab_contents_view_aura.h new file mode 100644 index 0000000..21466ee --- /dev/null +++ b/content/browser/tab_contents/tab_contents_view_aura.h @@ -0,0 +1,143 @@ +// 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 CONTENT_BROWSER_TAB_CONTENTS_TAB_CONTENTS_VIEW_AURA_H_ +#define CONTENT_BROWSER_TAB_CONTENTS_TAB_CONTENTS_VIEW_AURA_H_ +#pragma once + +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "content/browser/tab_contents/tab_contents_view_helper.h" +#include "content/common/content_export.h" +#include "content/public/browser/web_contents_view.h" +#include "ui/aura/client/drag_drop_delegate.h" +#include "ui/aura/window_delegate.h" + +namespace aura { +class Window; +} + +namespace content { +class WebContentsViewDelegate; +class WebDragDestDelegate; +} + +class CONTENT_EXPORT TabContentsViewAura + : public content::WebContentsView, + public aura::WindowDelegate, + public aura::client::DragDropDelegate { + public: + TabContentsViewAura(TabContents* tab_contents, + content::WebContentsViewDelegate* delegate); + virtual ~TabContentsViewAura(); + + private: + void SizeChangedCommon(const gfx::Size& size); + + void EndDrag(WebKit::WebDragOperationsMask ops); + + content::WebDragDestDelegate* GetDragDestDelegate(); + + // Overridden from WebContentsView: + virtual void CreateView(const gfx::Size& initial_size) OVERRIDE; + virtual content::RenderWidgetHostView* CreateViewForWidget( + content::RenderWidgetHost* render_widget_host) OVERRIDE; + virtual gfx::NativeView GetNativeView() const OVERRIDE; + virtual gfx::NativeView GetContentNativeView() const OVERRIDE; + virtual gfx::NativeWindow GetTopLevelNativeWindow() const OVERRIDE; + virtual void GetContainerBounds(gfx::Rect *out) const OVERRIDE; + virtual void SetPageTitle(const string16& title) OVERRIDE; + virtual void OnTabCrashed(base::TerminationStatus status, + int error_code) OVERRIDE; + virtual void SizeContents(const gfx::Size& size) OVERRIDE; + virtual void RenderViewCreated(content::RenderViewHost* host) OVERRIDE; + virtual void Focus() OVERRIDE; + virtual void SetInitialFocus() OVERRIDE; + virtual void StoreFocus() OVERRIDE; + virtual void RestoreFocus() OVERRIDE; + virtual bool IsDoingDrag() const OVERRIDE; + virtual void CancelDragAndCloseTab() OVERRIDE; + virtual bool IsEventTracking() const OVERRIDE; + virtual void CloseTabAfterEventTracking() OVERRIDE; + virtual void GetViewBounds(gfx::Rect* out) const OVERRIDE; + + // Overridden from RenderViewHostDelegate::View: + virtual void CreateNewWindow( + int route_id, + const ViewHostMsg_CreateWindow_Params& params) OVERRIDE; + virtual void CreateNewWidget(int route_id, + WebKit::WebPopupType popup_type) OVERRIDE; + virtual void CreateNewFullscreenWidget(int route_id) OVERRIDE; + virtual void ShowCreatedWindow(int route_id, + WindowOpenDisposition disposition, + const gfx::Rect& initial_pos, + bool user_gesture) OVERRIDE; + virtual void ShowCreatedWidget(int route_id, + const gfx::Rect& initial_pos) OVERRIDE; + virtual void ShowCreatedFullscreenWidget(int route_id) OVERRIDE; + virtual void ShowContextMenu( + const content::ContextMenuParams& params) OVERRIDE; + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned) OVERRIDE; + virtual void StartDragging(const WebDropData& drop_data, + WebKit::WebDragOperationsMask operations, + const SkBitmap& image, + const gfx::Point& image_offset) OVERRIDE; + virtual void UpdateDragCursor(WebKit::WebDragOperation operation) OVERRIDE; + virtual void GotFocus() OVERRIDE; + virtual void TakeFocus(bool reverse) OVERRIDE; + + // Overridden from aura::WindowDelegate: + virtual gfx::Size GetMinimumSize() const OVERRIDE; + virtual void OnBoundsChanged(const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) OVERRIDE; + virtual void OnFocus() OVERRIDE; + virtual void OnBlur() OVERRIDE; + virtual bool OnKeyEvent(aura::KeyEvent* event) OVERRIDE; + virtual gfx::NativeCursor GetCursor(const gfx::Point& point) OVERRIDE; + virtual int GetNonClientComponent(const gfx::Point& point) const OVERRIDE; + virtual bool OnMouseEvent(aura::MouseEvent* event) OVERRIDE; + virtual ui::TouchStatus OnTouchEvent(aura::TouchEvent* event) OVERRIDE; + virtual ui::GestureStatus OnGestureEvent(aura::GestureEvent* event) OVERRIDE; + virtual bool CanFocus() OVERRIDE; + virtual void OnCaptureLost() OVERRIDE; + virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; + virtual void OnWindowDestroying() OVERRIDE; + virtual void OnWindowDestroyed() OVERRIDE; + virtual void OnWindowVisibilityChanged(bool visible) OVERRIDE; + + // Overridden from aura::client::DragDropDelegate: + virtual void OnDragEntered(const aura::DropTargetEvent& event) OVERRIDE; + virtual int OnDragUpdated(const aura::DropTargetEvent& event) OVERRIDE; + virtual void OnDragExited() OVERRIDE; + virtual int OnPerformDrop(const aura::DropTargetEvent& event) OVERRIDE; + + gfx::Size initial_size_; + + scoped_ptr<aura::Window> window_; + + // The TabContents whose contents we display. + TabContents* tab_contents_; + + content::RenderWidgetHostView* view_; + + scoped_ptr<content::WebContentsViewDelegate> delegate_; + + // Common implementations of some WebContentsView methods. + TabContentsViewHelper tab_contents_view_helper_; + + WebKit::WebDragOperationsMask current_drag_op_; + + // Set to true if we want to close the tab after the system drag operation + // has finished. + bool close_tab_after_drag_ends_; + + DISALLOW_COPY_AND_ASSIGN(TabContentsViewAura); +}; + +#endif // CONTENT_BROWSER_TAB_CONTENTS_TAB_CONTENTS_VIEW_AURA_H_
\ No newline at end of file diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 32bdc65..7b6e50fb 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -664,6 +664,7 @@ 'browser/tab_contents/tab_contents.cc', 'browser/tab_contents/tab_contents.h', 'browser/tab_contents/tab_contents_view_aura.cc', + 'browser/tab_contents/tab_contents_view_aura.h', 'browser/tab_contents/tab_contents_view_gtk.cc', 'browser/tab_contents/tab_contents_view_gtk.h', 'browser/tab_contents/tab_contents_view_helper.cc', diff --git a/content/public/browser/web_contents_view_delegate.h b/content/public/browser/web_contents_view_delegate.h index 05b4f33..dbd67ff 100644 --- a/content/public/browser/web_contents_view_delegate.h +++ b/content/public/browser/web_contents_view_delegate.h @@ -45,7 +45,7 @@ class CONTENT_EXPORT WebContentsViewDelegate { // Shows a context menu. virtual void ShowContextMenu(const content::ContextMenuParams& params) = 0; -#if defined(OS_WIN) && !defined(USE_AURA) +#if defined(OS_WIN) || defined(USE_AURA) // These methods allow the embedder to intercept WebContentsViewWin's // implementation of these WebContentsView methods. See the WebContentsView // interface documentation for more information about these methods. diff --git a/ui/aura/window.cc b/ui/aura/window.cc index b67b2b2..d9862c8 100644 --- a/ui/aura/window.cc +++ b/ui/aura/window.cc @@ -187,6 +187,11 @@ bool Window::IsVisible() const { } gfx::Rect Window::GetScreenBounds() const { + // TODO(beng): There may be a better way to handle this, and the existing code + // is likely wrong anyway in a multi-monitor world, but this will + // do for now. + if (!GetRootWindow()) + return bounds(); gfx::Point origin = bounds().origin(); Window::ConvertPointToWindow(parent_, GetRootWindow(), &origin); return gfx::Rect(origin, bounds().size()); |