web_contents_view_aura.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// Copyright (c) 2012 The Chromium Authors. All rights reserved. 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Use of this source code is governed by a BSD-style license that can be 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com// found in the LICENSE file. 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "content/browser/web_contents/web_contents_view_aura.h" 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "base/auto_reset.h" 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "base/command_line.h" 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com#include "base/file_util.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "base/metrics/histogram.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "base/strings/utf_string_conversions.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/browser_plugin/browser_plugin_guest.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/download/drag_download_util.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/frame_host/interstitial_page_impl.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/frame_host/navigation_entry_impl.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/renderer_host/dip_util.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/renderer_host/overscroll_controller.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/renderer_host/render_view_host_factory.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/renderer_host/render_view_host_impl.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/renderer_host/render_widget_host_impl.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/renderer_host/render_widget_host_view_aura.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/web_contents/aura/gesture_nav_simple.h" 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/web_contents/aura/image_window_delegate.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/web_contents/aura/shadow_layer_delegate.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/web_contents/aura/window_slider.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/web_contents/touch_editable_impl_aura.h" 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/browser/web_contents/web_contents_impl.h" 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/content_browser_client.h" 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/notification_observer.h" 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/notification_registrar.h" 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/notification_source.h" 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/notification_types.h" 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/overscroll_configuration.h" 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/render_view_host.h" 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/render_widget_host.h" 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/render_widget_host_view.h" 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/web_contents_delegate.h" 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/web_contents_observer.h" 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/web_contents_view_delegate.h" 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/browser/web_drag_dest_delegate.h" 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/common/content_client.h" 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/common/content_switches.h" 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "content/public/common/drop_data.h" 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "net/base/filename_util.h" 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "third_party/WebKit/public/web/WebInputEvent.h" 477ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org#include "ui/aura/client/aura_constants.h" 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/aura/client/window_tree_client.h" 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/aura/env.h" 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/aura/window.h" 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/aura/window_observer.h" 527ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org#include "ui/aura/window_tree_host.h" 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/aura/window_tree_host_observer.h" 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/base/clipboard/clipboard.h" 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/base/clipboard/custom_data_helper.h" 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/base/dragdrop/drag_drop_types.h" 577ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org#include "ui/base/dragdrop/drag_utils.h" 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/base/dragdrop/drop_target_event.h" 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/base/dragdrop/os_exchange_data.h" 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/base/hit_test.h" 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/compositor/layer.h" 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/compositor/scoped_layer_animation_settings.h" 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/events/event.h" 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/events/event_utils.h" 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/gfx/canvas.h" 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/gfx/image/image.h" 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/gfx/image/image_png_rep.h" 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/gfx/image/image_skia.h" 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/gfx/screen.h" 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/wm/public/drag_drop_client.h" 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "ui/wm/public/drag_drop_delegate.h" 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace content { 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comWebContentsView* CreateWebContentsView( 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WebContentsImpl* web_contents, 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WebContentsViewDelegate* delegate, 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com RenderViewHostDelegateView** render_view_host_delegate_view) { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate); 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *render_view_host_delegate_view = rv; 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rv; 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comnamespace { 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool IsScrollEndEffectEnabled() { 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switches::kScrollEndEffect) == "1"; 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool ShouldNavigateForward(const NavigationController& controller, 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com OverscrollMode mode) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) && 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com controller.CanGoForward(); 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool ShouldNavigateBack(const NavigationController& controller, 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com OverscrollMode mode) { 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST) && 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com controller.CanGoBack(); 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Update the |web contents| to be |visible|. 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid UpdateWebContentsVisibility(WebContentsImpl* web_contents, bool visible) { 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (visible) { 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!web_contents->should_normally_be_visible()) 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com web_contents->WasShown(); 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (web_contents->should_normally_be_visible()) 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com web_contents->WasHidden(); 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comRenderWidgetHostViewAura* ToRenderWidgetHostViewAura( 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com RenderWidgetHostView* view) { 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!view || RenderViewHostFactory::has_factory()) 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests. 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost()); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com rvh ? WebContents::FromRenderViewHost(rvh) : NULL); 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (BrowserPluginGuest::IsGuest(web_contents)) 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return static_cast<RenderWidgetHostViewAura*>(view); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// The window delegate for the overscroll window. This redirects trackpad events 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// to the web-contents window. The delegate destroys itself when the window is 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// destroyed. 1298f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.comclass OverscrollWindowDelegate : public ImageWindowDelegate { 1308f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com public: 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com OverscrollWindowDelegate(WebContentsImpl* web_contents, 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com OverscrollMode overscroll_mode) 133 : web_contents_(web_contents), 134 forward_events_(true) { 135 const NavigationControllerImpl& controller = web_contents->GetController(); 136 const NavigationEntryImpl* entry = NULL; 137 if (ShouldNavigateForward(controller, overscroll_mode)) { 138 entry = NavigationEntryImpl::FromNavigationEntry( 139 controller.GetEntryAtOffset(1)); 140 } else if (ShouldNavigateBack(controller, overscroll_mode)) { 141 entry = NavigationEntryImpl::FromNavigationEntry( 142 controller.GetEntryAtOffset(-1)); 143 } 144 145 gfx::Image image; 146 if (entry && entry->screenshot().get()) { 147 std::vector<gfx::ImagePNGRep> image_reps; 148 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 149 ui::GetScaleFactorForNativeView(web_contents_window()))); 150 image = gfx::Image(image_reps); 151 } 152 SetImage(image); 153 } 154 155 void stop_forwarding_events() { forward_events_ = false; } 156 157 private: 158 virtual ~OverscrollWindowDelegate() {} 159 160 aura::Window* web_contents_window() { 161 return web_contents_->GetView()->GetContentNativeView(); 162 } 163 164 // Overridden from ui::EventHandler. 165 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { 166 if (forward_events_ && web_contents_window()) 167 web_contents_window()->delegate()->OnScrollEvent(event); 168 } 169 170 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { 171 if (forward_events_ && web_contents_window()) 172 web_contents_window()->delegate()->OnGestureEvent(event); 173 } 174 175 WebContentsImpl* web_contents_; 176 177 // The window is displayed both during the gesture, and after the gesture 178 // while the navigation is in progress. During the gesture, it is necessary to 179 // forward input events to the content page (e.g. when the overscroll window 180 // slides under the cursor and starts receiving scroll events). However, once 181 // the gesture is complete, and the window is being displayed as an overlay 182 // window during navigation, events should not be forwarded anymore. 183 bool forward_events_; 184 185 DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate); 186}; 187 188// Listens to all mouse drag events during a drag and drop and sends them to 189// the renderer. 190class WebDragSourceAura : public NotificationObserver { 191 public: 192 WebDragSourceAura(aura::Window* window, WebContentsImpl* contents) 193 : window_(window), 194 contents_(contents) { 195 registrar_.Add(this, 196 NOTIFICATION_WEB_CONTENTS_DISCONNECTED, 197 Source<WebContents>(contents)); 198 } 199 200 virtual ~WebDragSourceAura() { 201 } 202 203 // NotificationObserver: 204 virtual void Observe(int type, 205 const NotificationSource& source, 206 const NotificationDetails& details) OVERRIDE { 207 if (type != NOTIFICATION_WEB_CONTENTS_DISCONNECTED) 208 return; 209 210 // Cancel the drag if it is still in progress. 211 aura::client::DragDropClient* dnd_client = 212 aura::client::GetDragDropClient(window_->GetRootWindow()); 213 if (dnd_client && dnd_client->IsDragDropInProgress()) 214 dnd_client->DragCancel(); 215 216 window_ = NULL; 217 contents_ = NULL; 218 } 219 220 aura::Window* window() const { return window_; } 221 222 private: 223 aura::Window* window_; 224 WebContentsImpl* contents_; 225 NotificationRegistrar registrar_; 226 227 DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura); 228}; 229 230#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN) 231// Fill out the OSExchangeData with a file contents, synthesizing a name if 232// necessary. 233void PrepareDragForFileContents(const DropData& drop_data, 234 ui::OSExchangeData::Provider* provider) { 235 base::FilePath file_name = 236 base::FilePath::FromUTF16Unsafe(drop_data.file_description_filename); 237 // Images without ALT text will only have a file extension so we need to 238 // synthesize one from the provided extension and URL. 239 if (file_name.BaseName().RemoveExtension().empty()) { 240 const base::FilePath::StringType extension = file_name.Extension(); 241 // Retrieve the name from the URL. 242 file_name = net::GenerateFileName(drop_data.url, "", "", "", "", "") 243 .ReplaceExtension(extension); 244 } 245 provider->SetFileContents(file_name, drop_data.file_contents); 246} 247#endif 248 249#if defined(OS_WIN) 250void PrepareDragForDownload( 251 const DropData& drop_data, 252 ui::OSExchangeData::Provider* provider, 253 WebContentsImpl* web_contents) { 254 const GURL& page_url = web_contents->GetLastCommittedURL(); 255 const std::string& page_encoding = web_contents->GetEncoding(); 256 257 // Parse the download metadata. 258 base::string16 mime_type; 259 base::FilePath file_name; 260 GURL download_url; 261 if (!ParseDownloadMetadata(drop_data.download_metadata, 262 &mime_type, 263 &file_name, 264 &download_url)) 265 return; 266 267 // Generate the file name based on both mime type and proposed file name. 268 std::string default_name = 269 GetContentClient()->browser()->GetDefaultDownloadName(); 270 base::FilePath generated_download_file_name = 271 net::GenerateFileName(download_url, 272 std::string(), 273 std::string(), 274 base::UTF16ToUTF8(file_name.value()), 275 base::UTF16ToUTF8(mime_type), 276 default_name); 277 278 // http://crbug.com/332579 279 base::ThreadRestrictions::ScopedAllowIO allow_file_operations; 280 281 base::FilePath temp_dir_path; 282 if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"), 283 &temp_dir_path)) 284 return; 285 286 base::FilePath download_path = 287 temp_dir_path.Append(generated_download_file_name); 288 289 // We cannot know when the target application will be done using the temporary 290 // file, so schedule it to be deleted after rebooting. 291 base::DeleteFileAfterReboot(download_path); 292 base::DeleteFileAfterReboot(temp_dir_path); 293 294 // Provide the data as file (CF_HDROP). A temporary download file with the 295 // Zone.Identifier ADS (Alternate Data Stream) attached will be created. 296 scoped_refptr<DragDownloadFile> download_file = 297 new DragDownloadFile( 298 download_path, 299 base::File(), 300 download_url, 301 Referrer(page_url, drop_data.referrer_policy), 302 page_encoding, 303 web_contents); 304 ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(), 305 download_file.get()); 306 provider->SetDownloadFileInfo(file_download); 307} 308#endif // defined(OS_WIN) 309 310// Returns the CustomFormat to store file system files. 311const ui::OSExchangeData::CustomFormat& GetFileSystemFileCustomFormat() { 312 static const char kFormatString[] = "chromium/x-file-system-files"; 313 CR_DEFINE_STATIC_LOCAL(ui::OSExchangeData::CustomFormat, 314 format, 315 (ui::Clipboard::GetFormatType(kFormatString))); 316 return format; 317} 318 319// Writes file system files to the pickle. 320void WriteFileSystemFilesToPickle( 321 const std::vector<DropData::FileSystemFileInfo>& file_system_files, 322 Pickle* pickle) { 323 pickle->WriteUInt64(file_system_files.size()); 324 for (size_t i = 0; i < file_system_files.size(); ++i) { 325 pickle->WriteString(file_system_files[i].url.spec()); 326 pickle->WriteInt64(file_system_files[i].size); 327 } 328} 329 330// Reads file system files from the pickle. 331bool ReadFileSystemFilesFromPickle( 332 const Pickle& pickle, 333 std::vector<DropData::FileSystemFileInfo>* file_system_files) { 334 PickleIterator iter(pickle); 335 336 uint64 num_files = 0; 337 if (!pickle.ReadUInt64(&iter, &num_files)) 338 return false; 339 file_system_files->resize(num_files); 340 341 for (uint64 i = 0; i < num_files; ++i) { 342 std::string url_string; 343 int64 size = 0; 344 if (!pickle.ReadString(&iter, &url_string) || 345 !pickle.ReadInt64(&iter, &size)) 346 return false; 347 348 GURL url(url_string); 349 if (!url.is_valid()) 350 return false; 351 352 (*file_system_files)[i].url = url; 353 (*file_system_files)[i].size = size; 354 } 355 return true; 356} 357 358// Utility to fill a ui::OSExchangeDataProvider object from DropData. 359void PrepareDragData(const DropData& drop_data, 360 ui::OSExchangeData::Provider* provider, 361 WebContentsImpl* web_contents) { 362 provider->MarkOriginatedFromRenderer(); 363#if defined(OS_WIN) 364 // Put download before file contents to prefer the download of a image over 365 // its thumbnail link. 366 if (!drop_data.download_metadata.empty()) 367 PrepareDragForDownload(drop_data, provider, web_contents); 368#endif 369#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN) 370 // We set the file contents before the URL because the URL also sets file 371 // contents (to a .URL shortcut). We want to prefer file content data over 372 // a shortcut so we add it first. 373 if (!drop_data.file_contents.empty()) 374 PrepareDragForFileContents(drop_data, provider); 375#endif 376 if (!drop_data.text.string().empty()) 377 provider->SetString(drop_data.text.string()); 378 if (drop_data.url.is_valid()) 379 provider->SetURL(drop_data.url, drop_data.url_title); 380 if (!drop_data.html.string().empty()) 381 provider->SetHtml(drop_data.html.string(), drop_data.html_base_url); 382 if (!drop_data.filenames.empty()) 383 provider->SetFilenames(drop_data.filenames); 384 if (!drop_data.file_system_files.empty()) { 385 Pickle pickle; 386 WriteFileSystemFilesToPickle(drop_data.file_system_files, &pickle); 387 provider->SetPickledData(GetFileSystemFileCustomFormat(), pickle); 388 } 389 if (!drop_data.custom_data.empty()) { 390 Pickle pickle; 391 ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle); 392 provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), 393 pickle); 394 } 395} 396 397// Utility to fill a DropData object from ui::OSExchangeData. 398void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) { 399 drop_data->did_originate_from_renderer = data.DidOriginateFromRenderer(); 400 401 base::string16 plain_text; 402 data.GetString(&plain_text); 403 if (!plain_text.empty()) 404 drop_data->text = base::NullableString16(plain_text, false); 405 406 GURL url; 407 base::string16 url_title; 408 data.GetURLAndTitle( 409 ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &url, &url_title); 410 if (url.is_valid()) { 411 drop_data->url = url; 412 drop_data->url_title = url_title; 413 } 414 415 base::string16 html; 416 GURL html_base_url; 417 data.GetHtml(&html, &html_base_url); 418 if (!html.empty()) 419 drop_data->html = base::NullableString16(html, false); 420 if (html_base_url.is_valid()) 421 drop_data->html_base_url = html_base_url; 422 423 data.GetFilenames(&drop_data->filenames); 424 425 Pickle pickle; 426 std::vector<DropData::FileSystemFileInfo> file_system_files; 427 if (data.GetPickledData(GetFileSystemFileCustomFormat(), &pickle) && 428 ReadFileSystemFilesFromPickle(pickle, &file_system_files)) 429 drop_data->file_system_files = file_system_files; 430 431 if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle)) 432 ui::ReadCustomDataIntoMap( 433 pickle.data(), pickle.size(), &drop_data->custom_data); 434} 435 436// Utilities to convert between blink::WebDragOperationsMask and 437// ui::DragDropTypes. 438int ConvertFromWeb(blink::WebDragOperationsMask ops) { 439 int drag_op = ui::DragDropTypes::DRAG_NONE; 440 if (ops & blink::WebDragOperationCopy) 441 drag_op |= ui::DragDropTypes::DRAG_COPY; 442 if (ops & blink::WebDragOperationMove) 443 drag_op |= ui::DragDropTypes::DRAG_MOVE; 444 if (ops & blink::WebDragOperationLink) 445 drag_op |= ui::DragDropTypes::DRAG_LINK; 446 return drag_op; 447} 448 449blink::WebDragOperationsMask ConvertToWeb(int drag_op) { 450 int web_drag_op = blink::WebDragOperationNone; 451 if (drag_op & ui::DragDropTypes::DRAG_COPY) 452 web_drag_op |= blink::WebDragOperationCopy; 453 if (drag_op & ui::DragDropTypes::DRAG_MOVE) 454 web_drag_op |= blink::WebDragOperationMove; 455 if (drag_op & ui::DragDropTypes::DRAG_LINK) 456 web_drag_op |= blink::WebDragOperationLink; 457 return (blink::WebDragOperationsMask) web_drag_op; 458} 459 460int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) { 461 int web_input_event_modifiers = 0; 462 if (aura_event_flags & ui::EF_SHIFT_DOWN) 463 web_input_event_modifiers |= blink::WebInputEvent::ShiftKey; 464 if (aura_event_flags & ui::EF_CONTROL_DOWN) 465 web_input_event_modifiers |= blink::WebInputEvent::ControlKey; 466 if (aura_event_flags & ui::EF_ALT_DOWN) 467 web_input_event_modifiers |= blink::WebInputEvent::AltKey; 468 if (aura_event_flags & ui::EF_COMMAND_DOWN) 469 web_input_event_modifiers |= blink::WebInputEvent::MetaKey; 470 return web_input_event_modifiers; 471} 472 473} // namespace 474 475class WebContentsViewAura::WindowObserver 476 : public aura::WindowObserver, public aura::WindowTreeHostObserver { 477 public: 478 explicit WindowObserver(WebContentsViewAura* view) 479 : view_(view), 480 parent_(NULL) { 481 view_->window_->AddObserver(this); 482 483#if defined(OS_WIN) 484 if (view_->window_->GetRootWindow()) 485 view_->window_->GetRootWindow()->AddObserver(this); 486#endif 487 } 488 489 virtual ~WindowObserver() { 490 view_->window_->RemoveObserver(this); 491 if (view_->window_->GetHost()) 492 view_->window_->GetHost()->RemoveObserver(this); 493 if (parent_) 494 parent_->RemoveObserver(this); 495 496#if defined(OS_WIN) 497 if (parent_) { 498 const aura::Window::Windows& children = parent_->children(); 499 for (size_t i = 0; i < children.size(); ++i) 500 children[i]->RemoveObserver(this); 501 } 502 503 aura::Window* root_window = view_->window_->GetRootWindow(); 504 if (root_window) { 505 root_window->RemoveObserver(this); 506 const aura::Window::Windows& root_children = root_window->children(); 507 for (size_t i = 0; i < root_children.size(); ++i) 508 root_children[i]->RemoveObserver(this); 509 } 510#endif 511 } 512 513 // Overridden from aura::WindowObserver: 514#if defined(OS_WIN) 515 // Constrained windows are added as children of the parent's parent's view 516 // which may overlap with windowed NPAPI plugins. In that case, tell the RWHV 517 // so that it can update the plugins' cutout rects accordingly. 518 // Note: this is hard coding how Chrome layer adds its dialogs. Since NPAPI is 519 // going to be deprecated in a year, this is ok for now. The test for this is 520 // PrintPreviewTest.WindowedNPAPIPluginHidden. 521 virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE { 522 if (new_window != view_->window_) { 523 // Skip the case when the parent moves to the root window. 524 if (new_window != parent_) { 525 // Observe sibling windows of the WebContents, or children of the root 526 // window. 527 if (new_window->parent() == parent_ || 528 new_window->parent() == view_->window_->GetRootWindow()) { 529 new_window->AddObserver(this); 530 } 531 } 532 } 533 534 if (new_window->parent() == parent_) { 535 UpdateConstrainedWindows(NULL); 536 } 537 } 538 539 virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE { 540 if (window == view_->window_) 541 return; 542 543 window->RemoveObserver(this); 544 UpdateConstrainedWindows(window); 545 } 546 547 virtual void OnWindowVisibilityChanged(aura::Window* window, 548 bool visible) OVERRIDE { 549 if (window == view_->window_ || 550 window->parent() == parent_ || 551 window->parent() == view_->window_->GetRootWindow()) { 552 UpdateConstrainedWindows(NULL); 553 } 554 } 555#endif 556 557 virtual void OnWindowParentChanged(aura::Window* window, 558 aura::Window* parent) OVERRIDE { 559 if (window != view_->window_) 560 return; 561 if (parent_) 562 parent_->RemoveObserver(this); 563 564#if defined(OS_WIN) 565 if (parent_) { 566 const aura::Window::Windows& children = parent_->children(); 567 for (size_t i = 0; i < children.size(); ++i) 568 children[i]->RemoveObserver(this); 569 570 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura( 571 view_->web_contents_->GetRenderWidgetHostView()); 572 if (view) 573 view->UpdateConstrainedWindowRects(std::vector<gfx::Rect>()); 574 } 575 576 // When we get parented to the root window, the code below will watch the 577 // parent, aka root window. Since we already watch the root window on 578 // Windows, unregister first so that the debug check doesn't fire. 579 if (parent && parent == window->GetRootWindow()) 580 parent->RemoveObserver(this); 581 582 // We need to undo the above if we were parented to the root window and then 583 // got parented to another window. At that point, the code before the ifdef 584 // would have stopped watching the root window. 585 if (window->GetRootWindow() && 586 parent != window->GetRootWindow() && 587 !window->GetRootWindow()->HasObserver(this)) { 588 window->GetRootWindow()->AddObserver(this); 589 } 590#endif 591 592 parent_ = parent; 593 if (parent) { 594 parent->AddObserver(this); 595#if defined(OS_WIN) 596 if (parent != window->GetRootWindow()) { 597 const aura::Window::Windows& children = parent->children(); 598 for (size_t i = 0; i < children.size(); ++i) { 599 if (children[i] != view_->window_) 600 children[i]->AddObserver(this); 601 } 602 } 603#endif 604 } 605 } 606 607 virtual void OnWindowBoundsChanged(aura::Window* window, 608 const gfx::Rect& old_bounds, 609 const gfx::Rect& new_bounds) OVERRIDE { 610 if (window == parent_ || window == view_->window_) { 611 SendScreenRects(); 612 if (view_->touch_editable_) 613 view_->touch_editable_->UpdateEditingController(); 614#if defined(OS_WIN) 615 } else { 616 UpdateConstrainedWindows(NULL); 617#endif 618 } 619 } 620 621 virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE { 622 if (window == view_->window_) { 623 window->GetHost()->AddObserver(this); 624#if defined(OS_WIN) 625 if (!window->GetRootWindow()->HasObserver(this)) 626 window->GetRootWindow()->AddObserver(this); 627#endif 628 } 629 } 630 631 virtual void OnWindowRemovingFromRootWindow(aura::Window* window, 632 aura::Window* new_root) OVERRIDE { 633 if (window == view_->window_) { 634 window->GetHost()->RemoveObserver(this); 635#if defined(OS_WIN) 636 window->GetRootWindow()->RemoveObserver(this); 637 638 const aura::Window::Windows& root_children = 639 window->GetRootWindow()->children(); 640 for (size_t i = 0; i < root_children.size(); ++i) { 641 if (root_children[i] != view_->window_ && root_children[i] != parent_) 642 root_children[i]->RemoveObserver(this); 643 } 644#endif 645 } 646 } 647 648 // Overridden WindowTreeHostObserver: 649 virtual void OnHostMoved(const aura::WindowTreeHost* host, 650 const gfx::Point& new_origin) OVERRIDE { 651 TRACE_EVENT1("ui", 652 "WebContentsViewAura::WindowObserver::OnHostMoved", 653 "new_origin", new_origin.ToString()); 654 655 // This is for the desktop case (i.e. Aura desktop). 656 SendScreenRects(); 657 } 658 659 private: 660 void SendScreenRects() { 661 RenderWidgetHostImpl::From(view_->web_contents_->GetRenderViewHost())-> 662 SendScreenRects(); 663 } 664 665#if defined(OS_WIN) 666 void UpdateConstrainedWindows(aura::Window* exclude) { 667 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura( 668 view_->web_contents_->GetRenderWidgetHostView()); 669 if (!view) 670 return; 671 672 std::vector<gfx::Rect> constrained_windows; 673 if (parent_) { 674 const aura::Window::Windows& children = parent_->children(); 675 for (size_t i = 0; i < children.size(); ++i) { 676 if (children[i] != view_->window_ && 677 children[i] != exclude && 678 children[i]->IsVisible()) { 679 constrained_windows.push_back(children[i]->GetBoundsInRootWindow()); 680 } 681 } 682 } 683 684 aura::Window* root_window = view_->window_->GetRootWindow(); 685 const aura::Window::Windows& root_children = root_window->children(); 686 if (root_window) { 687 for (size_t i = 0; i < root_children.size(); ++i) { 688 if (root_children[i]->IsVisible() && 689 !root_children[i]->Contains(view_->window_.get())) { 690 constrained_windows.push_back( 691 root_children[i]->GetBoundsInRootWindow()); 692 } 693 } 694 } 695 696 view->UpdateConstrainedWindowRects(constrained_windows); 697 } 698#endif 699 700 WebContentsViewAura* view_; 701 702 // We cache the old parent so that we can unregister when it's not the parent 703 // anymore. 704 aura::Window* parent_; 705 706 DISALLOW_COPY_AND_ASSIGN(WindowObserver); 707}; 708 709//////////////////////////////////////////////////////////////////////////////// 710// WebContentsViewAura, public: 711 712WebContentsViewAura::WebContentsViewAura( 713 WebContentsImpl* web_contents, 714 WebContentsViewDelegate* delegate) 715 : web_contents_(web_contents), 716 delegate_(delegate), 717 current_drag_op_(blink::WebDragOperationNone), 718 drag_dest_delegate_(NULL), 719 current_rvh_for_drag_(NULL), 720 overscroll_change_brightness_(false), 721 current_overscroll_gesture_(OVERSCROLL_NONE), 722 completed_overscroll_gesture_(OVERSCROLL_NONE), 723 touch_editable_(TouchEditableImplAura::Create()) { 724} 725 726//////////////////////////////////////////////////////////////////////////////// 727// WebContentsViewAura, private: 728 729WebContentsViewAura::~WebContentsViewAura() { 730 if (!window_) 731 return; 732 733 window_observer_.reset(); 734 window_->RemoveObserver(this); 735 736 // Window needs a valid delegate during its destructor, so we explicitly 737 // delete it here. 738 window_.reset(); 739} 740 741void WebContentsViewAura::SetTouchEditableForTest( 742 TouchEditableImplAura* touch_editable) { 743 touch_editable_.reset(touch_editable); 744 AttachTouchEditableToRenderView(); 745} 746 747void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) { 748 if (web_contents_->GetInterstitialPage()) 749 web_contents_->GetInterstitialPage()->SetSize(size); 750 RenderWidgetHostView* rwhv = 751 web_contents_->GetRenderWidgetHostView(); 752 if (rwhv) 753 rwhv->SetSize(size); 754} 755 756void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) { 757 aura::Window* root_window = GetNativeView()->GetRootWindow(); 758 gfx::Point screen_loc = 759 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(); 760 gfx::Point client_loc = screen_loc; 761 RenderViewHost* rvh = web_contents_->GetRenderViewHost(); 762 aura::Window* window = rvh->GetView()->GetNativeView(); 763 aura::Window::ConvertPointToTarget(root_window, window, &client_loc); 764 if (!web_contents_) 765 return; 766 web_contents_->DragSourceEndedAt(client_loc.x(), client_loc.y(), 767 screen_loc.x(), screen_loc.y(), ops); 768} 769 770void WebContentsViewAura::InstallOverscrollControllerDelegate( 771 RenderWidgetHostViewAura* view) { 772 const std::string value = CommandLine::ForCurrentProcess()-> 773 GetSwitchValueASCII(switches::kOverscrollHistoryNavigation); 774 if (value == "0") { 775 navigation_overlay_.reset(); 776 return; 777 } 778 if (value == "2") { 779 navigation_overlay_.reset(); 780 if (!gesture_nav_simple_) 781 gesture_nav_simple_.reset(new GestureNavSimple(web_contents_)); 782 view->overscroll_controller()->set_delegate(gesture_nav_simple_.get()); 783 return; 784 } 785 view->overscroll_controller()->set_delegate(this); 786 if (!navigation_overlay_) 787 navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_)); 788} 789 790void WebContentsViewAura::PrepareOverscrollWindow() { 791 // If there is an existing |overscroll_window_| which is in the middle of an 792 // animation, then destroying the window here causes the animation to be 793 // completed immidiately, which triggers |OnImplicitAnimationsCompleted()| 794 // callback, and that tries to reset |overscroll_window_| again, causing a 795 // double-free. So use a temporary variable here. 796 if (overscroll_window_) { 797 base::AutoReset<OverscrollMode> reset_state(¤t_overscroll_gesture_, 798 current_overscroll_gesture_); 799 scoped_ptr<aura::Window> reset_window(overscroll_window_.release()); 800 } 801 802 OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate( 803 web_contents_, 804 current_overscroll_gesture_); 805 overscroll_window_.reset(new aura::Window(overscroll_delegate)); 806 overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL); 807 overscroll_window_->SetTransparent(true); 808 overscroll_window_->Init(aura::WINDOW_LAYER_TEXTURED); 809 overscroll_window_->layer()->SetMasksToBounds(false); 810 overscroll_window_->SetName("OverscrollOverlay"); 811 812 overscroll_change_brightness_ = overscroll_delegate->has_image(); 813 window_->AddChild(overscroll_window_.get()); 814 815 gfx::Rect bounds = gfx::Rect(window_->bounds().size()); 816 if (ShouldNavigateForward(web_contents_->GetController(), 817 current_overscroll_gesture_)) { 818 // The overlay will be sliding in from the right edge towards the left in 819 // non-RTL, or sliding in from the left edge towards the right in RTL. 820 // So position the overlay window accordingly. 821 bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0); 822 } 823 824 aura::Window* animate_window = GetWindowToAnimateForOverscroll(); 825 if (animate_window == overscroll_window_) 826 window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView()); 827 else 828 window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView()); 829 830 UpdateOverscrollWindowBrightness(0.f); 831 832 overscroll_window_->SetBounds(bounds); 833 overscroll_window_->Show(); 834 835 overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer())); 836} 837 838void WebContentsViewAura::PrepareContentWindowForOverscroll() { 839 StopObservingImplicitAnimations(); 840 aura::Window* content = GetContentNativeView(); 841 content->layer()->GetAnimator()->AbortAllAnimations(); 842 content->SetTransform(gfx::Transform()); 843 content->layer()->SetLayerBrightness(0.f); 844} 845 846void WebContentsViewAura::ResetOverscrollTransform() { 847 if (!web_contents_->GetRenderWidgetHostView()) 848 return; 849 aura::Window* target = GetWindowToAnimateForOverscroll(); 850 if (!target) 851 return; 852 { 853 ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); 854 settings.SetPreemptionStrategy( 855 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 856 settings.SetTweenType(gfx::Tween::EASE_OUT); 857 settings.AddObserver(this); 858 target->SetTransform(gfx::Transform()); 859 } 860 { 861 ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); 862 settings.SetPreemptionStrategy( 863 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 864 settings.SetTweenType(gfx::Tween::EASE_OUT); 865 UpdateOverscrollWindowBrightness(0.f); 866 } 867} 868 869void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) { 870 if (!web_contents_->GetRenderWidgetHostView()) 871 return; 872 873 // Animate out the current view first. Navigate to the requested history at 874 // the end of the animation. 875 if (current_overscroll_gesture_ == OVERSCROLL_NONE) 876 return; 877 878 UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated", 879 current_overscroll_gesture_, OVERSCROLL_COUNT); 880 OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( 881 overscroll_window_->delegate()); 882 delegate->stop_forwarding_events(); 883 884 completed_overscroll_gesture_ = mode; 885 aura::Window* target = GetWindowToAnimateForOverscroll(); 886 ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); 887 settings.SetPreemptionStrategy( 888 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); 889 settings.SetTweenType(gfx::Tween::EASE_OUT); 890 settings.AddObserver(this); 891 gfx::Transform transform; 892 int content_width = 893 web_contents_->GetRenderWidgetHostView()->GetViewBounds().width(); 894 int translate_x = mode == OVERSCROLL_WEST ? -content_width : content_width; 895 transform.Translate(translate_x, 0); 896 target->SetTransform(transform); 897 UpdateOverscrollWindowBrightness(translate_x); 898} 899 900aura::Window* WebContentsViewAura::GetWindowToAnimateForOverscroll() { 901 if (current_overscroll_gesture_ == OVERSCROLL_NONE) 902 return NULL; 903 904 return ShouldNavigateForward(web_contents_->GetController(), 905 current_overscroll_gesture_) ? 906 overscroll_window_.get() : GetContentNativeView(); 907} 908 909gfx::Vector2d WebContentsViewAura::GetTranslationForOverscroll(int delta_x, 910 int delta_y) { 911 if (current_overscroll_gesture_ == OVERSCROLL_NORTH || 912 current_overscroll_gesture_ == OVERSCROLL_SOUTH) { 913 return gfx::Vector2d(0, delta_y); 914 } 915 // For horizontal overscroll, scroll freely if a navigation is possible. Do a 916 // resistive scroll otherwise. 917 const NavigationControllerImpl& controller = web_contents_->GetController(); 918 const gfx::Rect& bounds = GetViewBounds(); 919 if (ShouldNavigateForward(controller, current_overscroll_gesture_)) 920 return gfx::Vector2d(std::max(-bounds.width(), delta_x), 0); 921 else if (ShouldNavigateBack(controller, current_overscroll_gesture_)) 922 return gfx::Vector2d(std::min(bounds.width(), delta_x), 0); 923 return gfx::Vector2d(); 924} 925 926void WebContentsViewAura::PrepareOverscrollNavigationOverlay() { 927 OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( 928 overscroll_window_->delegate()); 929 overscroll_window_->SchedulePaintInRect( 930 gfx::Rect(overscroll_window_->bounds().size())); 931 overscroll_window_->SetBounds(gfx::Rect(window_->bounds().size())); 932 overscroll_window_->SetTransform(gfx::Transform()); 933 navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(), 934 delegate); 935 navigation_overlay_->StartObserving(); 936} 937 938void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) { 939 if (!overscroll_change_brightness_) 940 return; 941 942 const float kBrightnessMin = -.1f; 943 const float kBrightnessMax = -.01f; 944 945 float ratio = fabs(delta_x) / GetViewBounds().width(); 946 ratio = std::min(1.f, ratio); 947 if (base::i18n::IsRTL()) 948 ratio = 1.f - ratio; 949 float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ? 950 kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) : 951 kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin); 952 brightness = std::max(kBrightnessMin, brightness); 953 brightness = std::min(kBrightnessMax, brightness); 954 aura::Window* window = GetWindowToAnimateForOverscroll(); 955 window->layer()->SetLayerBrightness(brightness); 956} 957 958void WebContentsViewAura::AttachTouchEditableToRenderView() { 959 if (!touch_editable_) 960 return; 961 RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura( 962 web_contents_->GetRenderWidgetHostView()); 963 touch_editable_->AttachToView(rwhva); 964} 965 966void WebContentsViewAura::OverscrollUpdateForWebContentsDelegate(int delta_y) { 967 if (web_contents_->GetDelegate() && IsScrollEndEffectEnabled()) 968 web_contents_->GetDelegate()->OverscrollUpdate(delta_y); 969} 970 971//////////////////////////////////////////////////////////////////////////////// 972// WebContentsViewAura, WebContentsView implementation: 973 974gfx::NativeView WebContentsViewAura::GetNativeView() const { 975 return window_.get(); 976} 977 978gfx::NativeView WebContentsViewAura::GetContentNativeView() const { 979 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView(); 980 return rwhv ? rwhv->GetNativeView() : NULL; 981} 982 983gfx::NativeWindow WebContentsViewAura::GetTopLevelNativeWindow() const { 984 return window_->GetToplevelWindow(); 985} 986 987void WebContentsViewAura::GetContainerBounds(gfx::Rect *out) const { 988 *out = window_->GetBoundsInScreen(); 989} 990 991void WebContentsViewAura::SizeContents(const gfx::Size& size) { 992 gfx::Rect bounds = window_->bounds(); 993 if (bounds.size() != size) { 994 bounds.set_size(size); 995 window_->SetBounds(bounds); 996 } else { 997 // Our size matches what we want but the renderers size may not match. 998 // Pretend we were resized so that the renderers size is updated too. 999 SizeChangedCommon(size); 1000 } 1001} 1002 1003void WebContentsViewAura::Focus() { 1004 if (web_contents_->GetInterstitialPage()) { 1005 web_contents_->GetInterstitialPage()->Focus(); 1006 return; 1007 } 1008 1009 if (delegate_.get() && delegate_->Focus()) 1010 return; 1011 1012 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView(); 1013 if (rwhv) 1014 rwhv->Focus(); 1015} 1016 1017void WebContentsViewAura::SetInitialFocus() { 1018 if (web_contents_->FocusLocationBarByDefault()) 1019 web_contents_->SetFocusToLocationBar(false); 1020 else 1021 Focus(); 1022} 1023 1024void WebContentsViewAura::StoreFocus() { 1025 if (delegate_) 1026 delegate_->StoreFocus(); 1027} 1028 1029void WebContentsViewAura::RestoreFocus() { 1030 if (delegate_) 1031 delegate_->RestoreFocus(); 1032} 1033 1034DropData* WebContentsViewAura::GetDropData() const { 1035 return current_drop_data_.get(); 1036} 1037 1038gfx::Rect WebContentsViewAura::GetViewBounds() const { 1039 return window_->GetBoundsInScreen(); 1040} 1041 1042//////////////////////////////////////////////////////////////////////////////// 1043// WebContentsViewAura, WebContentsView implementation: 1044 1045void WebContentsViewAura::CreateView( 1046 const gfx::Size& initial_size, gfx::NativeView context) { 1047 // NOTE: we ignore |initial_size| since in some cases it's wrong (such as 1048 // if the bookmark bar is not shown and you create a new tab). The right 1049 // value is set shortly after this, so its safe to ignore. 1050 1051 aura::Env::CreateInstance(true); 1052 window_.reset(new aura::Window(this)); 1053 window_->set_owned_by_parent(false); 1054 window_->SetType(ui::wm::WINDOW_TYPE_CONTROL); 1055 window_->SetTransparent(false); 1056 window_->Init(aura::WINDOW_LAYER_NOT_DRAWN); 1057 window_->AddObserver(this); 1058 aura::Window* root_window = context ? context->GetRootWindow() : NULL; 1059 if (root_window) { 1060 // There are places where there is no context currently because object 1061 // hierarchies are built before they're attached to a Widget. (See 1062 // views::WebView as an example; GetWidget() returns NULL at the point 1063 // where we are created.) 1064 // 1065 // It should be OK to not set a default parent since such users will 1066 // explicitly add this WebContentsViewAura to their tree after they create 1067 // us. 1068 if (root_window) { 1069 aura::client::ParentWindowWithContext( 1070 window_.get(), root_window, root_window->GetBoundsInScreen()); 1071 } 1072 } 1073 window_->layer()->SetMasksToBounds(true); 1074 window_->SetName("WebContentsViewAura"); 1075 1076 // WindowObserver is not interesting and is problematic for Browser Plugin 1077 // guests. 1078 // The use cases for WindowObserver do not apply to Browser Plugins: 1079 // 1) guests do not support NPAPI plugins. 1080 // 2) guests' window bounds are supposed to come from its embedder. 1081 if (!BrowserPluginGuest::IsGuest(web_contents_)) 1082 window_observer_.reset(new WindowObserver(this)); 1083 1084 // delegate_->GetDragDestDelegate() creates a new delegate on every call. 1085 // Hence, we save a reference to it locally. Similar model is used on other 1086 // platforms as well. 1087 if (delegate_) 1088 drag_dest_delegate_ = delegate_->GetDragDestDelegate(); 1089} 1090 1091RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget( 1092 RenderWidgetHost* render_widget_host) { 1093 if (render_widget_host->GetView()) { 1094 // During testing, the view will already be set up in most cases to the 1095 // test view, so we don't want to clobber it with a real one. To verify that 1096 // this actually is happening (and somebody isn't accidentally creating the 1097 // view twice), we check for the RVH Factory, which will be set when we're 1098 // making special ones (which go along with the special views). 1099 DCHECK(RenderViewHostFactory::has_factory()); 1100 return static_cast<RenderWidgetHostViewBase*>( 1101 render_widget_host->GetView()); 1102 } 1103 1104 RenderWidgetHostViewAura* view = 1105 new RenderWidgetHostViewAura(render_widget_host); 1106 view->InitAsChild(NULL); 1107 GetNativeView()->AddChild(view->GetNativeView()); 1108 1109 if (navigation_overlay_.get() && navigation_overlay_->has_window()) { 1110 navigation_overlay_->StartObserving(); 1111 } 1112 1113 RenderWidgetHostImpl* host_impl = 1114 RenderWidgetHostImpl::From(render_widget_host); 1115 1116 if (!host_impl->is_hidden()) 1117 view->Show(); 1118 1119 // We listen to drag drop events in the newly created view's window. 1120 aura::client::SetDragDropDelegate(view->GetNativeView(), this); 1121 1122 if (view->overscroll_controller() && 1123 (!web_contents_->GetDelegate() || 1124 web_contents_->GetDelegate()->CanOverscrollContent())) { 1125 InstallOverscrollControllerDelegate(view); 1126 } 1127 1128 AttachTouchEditableToRenderView(); 1129 return view; 1130} 1131 1132RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget( 1133 RenderWidgetHost* render_widget_host) { 1134 return new RenderWidgetHostViewAura(render_widget_host); 1135} 1136 1137void WebContentsViewAura::SetPageTitle(const base::string16& title) { 1138 window_->set_title(title); 1139} 1140 1141void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) { 1142} 1143 1144void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) { 1145 if (navigation_overlay_.get() && navigation_overlay_->has_window()) 1146 navigation_overlay_->StartObserving(); 1147 AttachTouchEditableToRenderView(); 1148} 1149 1150void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) { 1151 RenderWidgetHostViewAura* view = 1152 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView()); 1153 if (view) { 1154 view->SetOverscrollControllerEnabled(enabled); 1155 if (enabled) 1156 InstallOverscrollControllerDelegate(view); 1157 } 1158 1159 if (!enabled) 1160 navigation_overlay_.reset(); 1161 else if (!navigation_overlay_) 1162 navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_)); 1163} 1164 1165//////////////////////////////////////////////////////////////////////////////// 1166// WebContentsViewAura, RenderViewHostDelegateView implementation: 1167 1168void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host, 1169 const ContextMenuParams& params) { 1170 if (touch_editable_) { 1171 touch_editable_->EndTouchEditing(false); 1172 } 1173 if (delegate_) { 1174 delegate_->ShowContextMenu(render_frame_host, params); 1175 // WARNING: we may have been deleted during the call to ShowContextMenu(). 1176 } 1177} 1178 1179void WebContentsViewAura::StartDragging( 1180 const DropData& drop_data, 1181 blink::WebDragOperationsMask operations, 1182 const gfx::ImageSkia& image, 1183 const gfx::Vector2d& image_offset, 1184 const DragEventSourceInfo& event_info) { 1185 aura::Window* root_window = GetNativeView()->GetRootWindow(); 1186 if (!aura::client::GetDragDropClient(root_window)) { 1187 web_contents_->SystemDragEnded(); 1188 return; 1189 } 1190 1191 if (touch_editable_) 1192 touch_editable_->EndTouchEditing(false); 1193 1194 ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider(); 1195 PrepareDragData(drop_data, provider, web_contents_); 1196 1197 ui::OSExchangeData data(provider); // takes ownership of |provider|. 1198 1199 if (!image.isNull()) 1200 drag_utils::SetDragImageOnDataObject(image, image_offset, &data); 1201 1202 scoped_ptr<WebDragSourceAura> drag_source( 1203 new WebDragSourceAura(GetNativeView(), web_contents_)); 1204 1205 // We need to enable recursive tasks on the message loop so we can get 1206 // updates while in the system DoDragDrop loop. 1207 int result_op = 0; 1208 { 1209 gfx::NativeView content_native_view = GetContentNativeView(); 1210 base::MessageLoop::ScopedNestableTaskAllower allow( 1211 base::MessageLoop::current()); 1212 result_op = aura::client::GetDragDropClient(root_window) 1213 ->StartDragAndDrop(data, 1214 root_window, 1215 content_native_view, 1216 event_info.event_location, 1217 ConvertFromWeb(operations), 1218 event_info.event_source); 1219 } 1220 1221 // Bail out immediately if the contents view window is gone. Note that it is 1222 // not safe to access any class members in this case since |this| may already 1223 // be destroyed. The local variable |drag_source| will still be valid though, 1224 // so we can use it to determine if the window is gone. 1225 if (!drag_source->window()) { 1226 // Note that in this case, we don't need to call SystemDragEnded() since the 1227 // renderer is going away. 1228 return; 1229 } 1230 1231 EndDrag(ConvertToWeb(result_op)); 1232 web_contents_->SystemDragEnded(); 1233} 1234 1235void WebContentsViewAura::UpdateDragCursor(blink::WebDragOperation operation) { 1236 current_drag_op_ = operation; 1237} 1238 1239void WebContentsViewAura::GotFocus() { 1240 if (web_contents_->GetDelegate()) 1241 web_contents_->GetDelegate()->WebContentsFocused(web_contents_); 1242} 1243 1244void WebContentsViewAura::TakeFocus(bool reverse) { 1245 if (web_contents_->GetDelegate() && 1246 !web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) && 1247 delegate_.get()) { 1248 delegate_->TakeFocus(reverse); 1249 } 1250} 1251 1252//////////////////////////////////////////////////////////////////////////////// 1253// WebContentsViewAura, OverscrollControllerDelegate implementation: 1254 1255gfx::Rect WebContentsViewAura::GetVisibleBounds() const { 1256 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView(); 1257 if (!rwhv || !rwhv->IsShowing()) 1258 return gfx::Rect(); 1259 1260 return rwhv->GetViewBounds(); 1261} 1262 1263void WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) { 1264 if (current_overscroll_gesture_ == OVERSCROLL_NONE) 1265 return; 1266 1267 aura::Window* target = GetWindowToAnimateForOverscroll(); 1268 gfx::Vector2d translate = GetTranslationForOverscroll(delta_x, delta_y); 1269 gfx::Transform transform; 1270 1271 // Vertical overscrolls don't participate in the navigation gesture. 1272 if (current_overscroll_gesture_ != OVERSCROLL_NORTH && 1273 current_overscroll_gesture_ != OVERSCROLL_SOUTH) { 1274 transform.Translate(translate.x(), translate.y()); 1275 target->SetTransform(transform); 1276 UpdateOverscrollWindowBrightness(delta_x); 1277 } 1278 1279 OverscrollUpdateForWebContentsDelegate(translate.y()); 1280} 1281 1282void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) { 1283 UMA_HISTOGRAM_ENUMERATION("Overscroll.Completed", mode, OVERSCROLL_COUNT); 1284 OverscrollUpdateForWebContentsDelegate(0); 1285 NavigationControllerImpl& controller = web_contents_->GetController(); 1286 if (ShouldNavigateForward(controller, mode) || 1287 ShouldNavigateBack(controller, mode)) { 1288 CompleteOverscrollNavigation(mode); 1289 return; 1290 } 1291 1292 ResetOverscrollTransform(); 1293} 1294 1295void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, 1296 OverscrollMode new_mode) { 1297 // Reset any in-progress overscroll animation first. 1298 ResetOverscrollTransform(); 1299 1300 if (new_mode != OVERSCROLL_NONE && touch_editable_) 1301 touch_editable_->OverscrollStarted(); 1302 1303 if (new_mode == OVERSCROLL_NONE || 1304 !GetContentNativeView() || 1305 ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) && 1306 navigation_overlay_.get() && navigation_overlay_->has_window())) { 1307 current_overscroll_gesture_ = OVERSCROLL_NONE; 1308 OverscrollUpdateForWebContentsDelegate(0); 1309 } else { 1310 aura::Window* target = GetWindowToAnimateForOverscroll(); 1311 if (target) { 1312 StopObservingImplicitAnimations(); 1313 target->layer()->GetAnimator()->AbortAllAnimations(); 1314 } 1315 // Cleanup state of the content window first, because that can reset the 1316 // value of |current_overscroll_gesture_|. 1317 PrepareContentWindowForOverscroll(); 1318 1319 current_overscroll_gesture_ = new_mode; 1320 if (current_overscroll_gesture_ == OVERSCROLL_EAST || 1321 current_overscroll_gesture_ == OVERSCROLL_WEST) 1322 PrepareOverscrollWindow(); 1323 1324 UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT); 1325 } 1326 completed_overscroll_gesture_ = OVERSCROLL_NONE; 1327} 1328 1329//////////////////////////////////////////////////////////////////////////////// 1330// WebContentsViewAura, ui::ImplicitAnimationObserver implementation: 1331 1332void WebContentsViewAura::OnImplicitAnimationsCompleted() { 1333 overscroll_shadow_.reset(); 1334 1335 if (ShouldNavigateForward(web_contents_->GetController(), 1336 completed_overscroll_gesture_)) { 1337 web_contents_->GetController().GoForward(); 1338 PrepareOverscrollNavigationOverlay(); 1339 } else if (ShouldNavigateBack(web_contents_->GetController(), 1340 completed_overscroll_gesture_)) { 1341 web_contents_->GetController().GoBack(); 1342 PrepareOverscrollNavigationOverlay(); 1343 } else { 1344 if (touch_editable_) 1345 touch_editable_->OverscrollCompleted(); 1346 } 1347 1348 aura::Window* content = GetContentNativeView(); 1349 if (content) { 1350 content->SetTransform(gfx::Transform()); 1351 content->layer()->SetLayerBrightness(0.f); 1352 } 1353 current_overscroll_gesture_ = OVERSCROLL_NONE; 1354 completed_overscroll_gesture_ = OVERSCROLL_NONE; 1355 overscroll_window_.reset(); 1356} 1357 1358//////////////////////////////////////////////////////////////////////////////// 1359// WebContentsViewAura, aura::WindowDelegate implementation: 1360 1361gfx::Size WebContentsViewAura::GetMinimumSize() const { 1362 return gfx::Size(); 1363} 1364 1365gfx::Size WebContentsViewAura::GetMaximumSize() const { 1366 return gfx::Size(); 1367} 1368 1369void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds, 1370 const gfx::Rect& new_bounds) { 1371 SizeChangedCommon(new_bounds.size()); 1372 if (delegate_) 1373 delegate_->SizeChanged(new_bounds.size()); 1374 1375 // Constrained web dialogs, need to be kept centered over our content area. 1376 for (size_t i = 0; i < window_->children().size(); i++) { 1377 if (window_->children()[i]->GetProperty( 1378 aura::client::kConstrainedWindowKey)) { 1379 gfx::Rect bounds = window_->children()[i]->bounds(); 1380 bounds.set_origin( 1381 gfx::Point((new_bounds.width() - bounds.width()) / 2, 1382 (new_bounds.height() - bounds.height()) / 2)); 1383 window_->children()[i]->SetBounds(bounds); 1384 } 1385 } 1386} 1387 1388gfx::NativeCursor WebContentsViewAura::GetCursor(const gfx::Point& point) { 1389 return gfx::kNullCursor; 1390} 1391 1392int WebContentsViewAura::GetNonClientComponent(const gfx::Point& point) const { 1393 return HTCLIENT; 1394} 1395 1396bool WebContentsViewAura::ShouldDescendIntoChildForEventHandling( 1397 aura::Window* child, 1398 const gfx::Point& location) { 1399 return true; 1400} 1401 1402bool WebContentsViewAura::CanFocus() { 1403 // Do not take the focus if the render widget host view aura is gone or 1404 // is in the process of shutting down because neither the view window nor 1405 // this window can handle key events. 1406 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura( 1407 web_contents_->GetRenderWidgetHostView()); 1408 if (view != NULL && !view->IsClosing()) 1409 return true; 1410 1411 return false; 1412} 1413 1414void WebContentsViewAura::OnCaptureLost() { 1415} 1416 1417void WebContentsViewAura::OnPaint(gfx::Canvas* canvas) { 1418} 1419 1420void WebContentsViewAura::OnDeviceScaleFactorChanged( 1421 float device_scale_factor) { 1422} 1423 1424void WebContentsViewAura::OnWindowDestroying(aura::Window* window) { 1425 // This means the destructor is going to be called soon. If there is an 1426 // overscroll gesture in progress (i.e. |overscroll_window_| is not NULL), 1427 // then destroying it in the WebContentsViewAura destructor can trigger other 1428 // virtual functions to be called (e.g. OnImplicitAnimationsCompleted()). So 1429 // destroy the overscroll window here. 1430 navigation_overlay_.reset(); 1431 overscroll_window_.reset(); 1432} 1433 1434void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) { 1435} 1436 1437void WebContentsViewAura::OnWindowTargetVisibilityChanged(bool visible) { 1438} 1439 1440bool WebContentsViewAura::HasHitTestMask() const { 1441 return false; 1442} 1443 1444void WebContentsViewAura::GetHitTestMask(gfx::Path* mask) const { 1445} 1446 1447//////////////////////////////////////////////////////////////////////////////// 1448// WebContentsViewAura, ui::EventHandler implementation: 1449 1450void WebContentsViewAura::OnKeyEvent(ui::KeyEvent* event) { 1451} 1452 1453void WebContentsViewAura::OnMouseEvent(ui::MouseEvent* event) { 1454 if (!web_contents_->GetDelegate()) 1455 return; 1456 1457 switch (event->type()) { 1458 case ui::ET_MOUSE_PRESSED: 1459 web_contents_->GetDelegate()->ActivateContents(web_contents_); 1460 break; 1461 case ui::ET_MOUSE_MOVED: 1462 case ui::ET_MOUSE_EXITED: 1463 web_contents_->GetDelegate()->ContentsMouseEvent( 1464 web_contents_, 1465 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(), 1466 event->type() == ui::ET_MOUSE_MOVED); 1467 break; 1468 default: 1469 break; 1470 } 1471} 1472 1473//////////////////////////////////////////////////////////////////////////////// 1474// WebContentsViewAura, aura::client::DragDropDelegate implementation: 1475 1476void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) { 1477 current_rvh_for_drag_ = web_contents_->GetRenderViewHost(); 1478 current_drop_data_.reset(new DropData()); 1479 1480 PrepareDropData(current_drop_data_.get(), event.data()); 1481 blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations()); 1482 1483 // Give the delegate an opportunity to cancel the drag. 1484 if (!web_contents_->GetDelegate()->CanDragEnter(web_contents_, 1485 *current_drop_data_.get(), 1486 op)) { 1487 current_drop_data_.reset(NULL); 1488 return; 1489 } 1490 1491 if (drag_dest_delegate_) 1492 drag_dest_delegate_->DragInitialize(web_contents_); 1493 1494 gfx::Point screen_pt = 1495 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(); 1496 web_contents_->GetRenderViewHost()->DragTargetDragEnter( 1497 *current_drop_data_.get(), event.location(), screen_pt, op, 1498 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); 1499 1500 if (drag_dest_delegate_) { 1501 drag_dest_delegate_->OnReceiveDragData(event.data()); 1502 drag_dest_delegate_->OnDragEnter(); 1503 } 1504} 1505 1506int WebContentsViewAura::OnDragUpdated(const ui::DropTargetEvent& event) { 1507 DCHECK(current_rvh_for_drag_); 1508 if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost()) 1509 OnDragEntered(event); 1510 1511 if (!current_drop_data_) 1512 return ui::DragDropTypes::DRAG_NONE; 1513 1514 blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations()); 1515 gfx::Point screen_pt = 1516 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(); 1517 web_contents_->GetRenderViewHost()->DragTargetDragOver( 1518 event.location(), screen_pt, op, 1519 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); 1520 1521 if (drag_dest_delegate_) 1522 drag_dest_delegate_->OnDragOver(); 1523 1524 return ConvertFromWeb(current_drag_op_); 1525} 1526 1527void WebContentsViewAura::OnDragExited() { 1528 DCHECK(current_rvh_for_drag_); 1529 if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost()) 1530 return; 1531 1532 if (!current_drop_data_) 1533 return; 1534 1535 web_contents_->GetRenderViewHost()->DragTargetDragLeave(); 1536 if (drag_dest_delegate_) 1537 drag_dest_delegate_->OnDragLeave(); 1538 1539 current_drop_data_.reset(); 1540} 1541 1542int WebContentsViewAura::OnPerformDrop(const ui::DropTargetEvent& event) { 1543 DCHECK(current_rvh_for_drag_); 1544 if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost()) 1545 OnDragEntered(event); 1546 1547 if (!current_drop_data_) 1548 return ui::DragDropTypes::DRAG_NONE; 1549 1550 web_contents_->GetRenderViewHost()->DragTargetDrop( 1551 event.location(), 1552 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(), 1553 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); 1554 if (drag_dest_delegate_) 1555 drag_dest_delegate_->OnDrop(); 1556 current_drop_data_.reset(); 1557 return ConvertFromWeb(current_drag_op_); 1558} 1559 1560void WebContentsViewAura::OnWindowParentChanged(aura::Window* window, 1561 aura::Window* parent) { 1562 // On Windows we will get called with a parent of NULL as part of the shut 1563 // down process. As such we do only change the visibility when a parent gets 1564 // set. 1565 if (parent) 1566 UpdateWebContentsVisibility(web_contents_, window->IsVisible()); 1567} 1568 1569void WebContentsViewAura::OnWindowVisibilityChanged(aura::Window* window, 1570 bool visible) { 1571 // Ignore any visibility changes in the hierarchy below. 1572 if (window != window_.get() && window_->Contains(window)) 1573 return; 1574 1575 UpdateWebContentsVisibility(web_contents_, visible); 1576} 1577 1578} // namespace content 1579