Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / content / browser / web_contents / web_contents_view_aura.cc
blob705fbb912c35fae2df8d56ee1010dfea2b765838
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/web_contents/web_contents_view_aura.h"
7 #include "base/auto_reset.h"
8 #include "base/command_line.h"
9 #include "base/files/file_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/browser/browser_plugin/browser_plugin_guest.h"
12 #include "content/browser/download/drag_download_util.h"
13 #include "content/browser/frame_host/interstitial_page_impl.h"
14 #include "content/browser/frame_host/navigation_entry_impl.h"
15 #include "content/browser/renderer_host/dip_util.h"
16 #include "content/browser/renderer_host/overscroll_controller.h"
17 #include "content/browser/renderer_host/render_view_host_factory.h"
18 #include "content/browser/renderer_host/render_view_host_impl.h"
19 #include "content/browser/renderer_host/render_widget_host_impl.h"
20 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
21 #include "content/browser/renderer_host/web_input_event_aura.h"
22 #include "content/browser/web_contents/aura/gesture_nav_simple.h"
23 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
24 #include "content/browser/web_contents/touch_editable_impl_aura.h"
25 #include "content/browser/web_contents/web_contents_impl.h"
26 #include "content/public/browser/content_browser_client.h"
27 #include "content/public/browser/notification_observer.h"
28 #include "content/public/browser/notification_registrar.h"
29 #include "content/public/browser/notification_source.h"
30 #include "content/public/browser/notification_types.h"
31 #include "content/public/browser/overscroll_configuration.h"
32 #include "content/public/browser/render_view_host.h"
33 #include "content/public/browser/render_widget_host.h"
34 #include "content/public/browser/render_widget_host_view.h"
35 #include "content/public/browser/web_contents_delegate.h"
36 #include "content/public/browser/web_contents_observer.h"
37 #include "content/public/browser/web_contents_view_delegate.h"
38 #include "content/public/browser/web_drag_dest_delegate.h"
39 #include "content/public/common/content_client.h"
40 #include "content/public/common/content_switches.h"
41 #include "content/public/common/drop_data.h"
42 #include "net/base/filename_util.h"
43 #include "third_party/WebKit/public/web/WebInputEvent.h"
44 #include "ui/aura/client/aura_constants.h"
45 #include "ui/aura/client/window_tree_client.h"
46 #include "ui/aura/env.h"
47 #include "ui/aura/window.h"
48 #include "ui/aura/window_observer.h"
49 #include "ui/aura/window_tree_host.h"
50 #include "ui/aura/window_tree_host_observer.h"
51 #include "ui/base/clipboard/clipboard.h"
52 #include "ui/base/clipboard/custom_data_helper.h"
53 #include "ui/base/dragdrop/drag_drop_types.h"
54 #include "ui/base/dragdrop/drag_utils.h"
55 #include "ui/base/dragdrop/drop_target_event.h"
56 #include "ui/base/dragdrop/os_exchange_data.h"
57 #include "ui/base/hit_test.h"
58 #include "ui/compositor/layer.h"
59 #include "ui/events/event.h"
60 #include "ui/events/event_utils.h"
61 #include "ui/gfx/canvas.h"
62 #include "ui/gfx/image/image.h"
63 #include "ui/gfx/image/image_png_rep.h"
64 #include "ui/gfx/image/image_skia.h"
65 #include "ui/gfx/screen.h"
66 #include "ui/wm/public/drag_drop_client.h"
67 #include "ui/wm/public/drag_drop_delegate.h"
69 namespace content {
70 WebContentsView* CreateWebContentsView(
71 WebContentsImpl* web_contents,
72 WebContentsViewDelegate* delegate,
73 RenderViewHostDelegateView** render_view_host_delegate_view) {
74 WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate);
75 *render_view_host_delegate_view = rv;
76 return rv;
79 namespace {
81 bool IsScrollEndEffectEnabled() {
82 return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
83 switches::kScrollEndEffect) == "1";
86 RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
87 RenderWidgetHostView* view) {
88 if (!view || RenderViewHostFactory::has_factory())
89 return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests.
91 RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost());
92 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>(
93 rvh ? WebContents::FromRenderViewHost(rvh) : NULL);
94 if (BrowserPluginGuest::IsGuest(web_contents))
95 return NULL;
96 return static_cast<RenderWidgetHostViewAura*>(view);
99 // Listens to all mouse drag events during a drag and drop and sends them to
100 // the renderer.
101 class WebDragSourceAura : public NotificationObserver {
102 public:
103 WebDragSourceAura(aura::Window* window, WebContentsImpl* contents)
104 : window_(window),
105 contents_(contents) {
106 registrar_.Add(this,
107 NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
108 Source<WebContents>(contents));
111 ~WebDragSourceAura() override {}
113 // NotificationObserver:
114 void Observe(int type,
115 const NotificationSource& source,
116 const NotificationDetails& details) override {
117 if (type != NOTIFICATION_WEB_CONTENTS_DISCONNECTED)
118 return;
120 // Cancel the drag if it is still in progress.
121 aura::client::DragDropClient* dnd_client =
122 aura::client::GetDragDropClient(window_->GetRootWindow());
123 if (dnd_client && dnd_client->IsDragDropInProgress())
124 dnd_client->DragCancel();
126 window_ = NULL;
127 contents_ = NULL;
130 aura::Window* window() const { return window_; }
132 private:
133 aura::Window* window_;
134 WebContentsImpl* contents_;
135 NotificationRegistrar registrar_;
137 DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
140 #if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
141 // Fill out the OSExchangeData with a file contents, synthesizing a name if
142 // necessary.
143 void PrepareDragForFileContents(const DropData& drop_data,
144 ui::OSExchangeData::Provider* provider) {
145 base::FilePath file_name =
146 base::FilePath::FromUTF16Unsafe(drop_data.file_description_filename);
147 // Images without ALT text will only have a file extension so we need to
148 // synthesize one from the provided extension and URL.
149 if (file_name.BaseName().RemoveExtension().empty()) {
150 const base::FilePath::StringType extension = file_name.Extension();
151 // Retrieve the name from the URL.
152 file_name = net::GenerateFileName(drop_data.url, "", "", "", "", "")
153 .ReplaceExtension(extension);
155 provider->SetFileContents(file_name, drop_data.file_contents);
157 #endif
159 #if defined(OS_WIN)
160 void PrepareDragForDownload(
161 const DropData& drop_data,
162 ui::OSExchangeData::Provider* provider,
163 WebContentsImpl* web_contents) {
164 const GURL& page_url = web_contents->GetLastCommittedURL();
165 const std::string& page_encoding = web_contents->GetEncoding();
167 // Parse the download metadata.
168 base::string16 mime_type;
169 base::FilePath file_name;
170 GURL download_url;
171 if (!ParseDownloadMetadata(drop_data.download_metadata,
172 &mime_type,
173 &file_name,
174 &download_url))
175 return;
177 // Generate the file name based on both mime type and proposed file name.
178 std::string default_name =
179 GetContentClient()->browser()->GetDefaultDownloadName();
180 base::FilePath generated_download_file_name =
181 net::GenerateFileName(download_url,
182 std::string(),
183 std::string(),
184 base::UTF16ToUTF8(file_name.value()),
185 base::UTF16ToUTF8(mime_type),
186 default_name);
188 // http://crbug.com/332579
189 base::ThreadRestrictions::ScopedAllowIO allow_file_operations;
191 base::FilePath temp_dir_path;
192 if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"),
193 &temp_dir_path))
194 return;
196 base::FilePath download_path =
197 temp_dir_path.Append(generated_download_file_name);
199 // We cannot know when the target application will be done using the temporary
200 // file, so schedule it to be deleted after rebooting.
201 base::DeleteFileAfterReboot(download_path);
202 base::DeleteFileAfterReboot(temp_dir_path);
204 // Provide the data as file (CF_HDROP). A temporary download file with the
205 // Zone.Identifier ADS (Alternate Data Stream) attached will be created.
206 scoped_refptr<DragDownloadFile> download_file =
207 new DragDownloadFile(
208 download_path,
209 base::File(),
210 download_url,
211 Referrer(page_url, drop_data.referrer_policy),
212 page_encoding,
213 web_contents);
214 ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(),
215 download_file.get());
216 provider->SetDownloadFileInfo(file_download);
218 #endif // defined(OS_WIN)
220 // Returns the CustomFormat to store file system files.
221 const ui::OSExchangeData::CustomFormat& GetFileSystemFileCustomFormat() {
222 static const char kFormatString[] = "chromium/x-file-system-files";
223 CR_DEFINE_STATIC_LOCAL(ui::OSExchangeData::CustomFormat,
224 format,
225 (ui::Clipboard::GetFormatType(kFormatString)));
226 return format;
229 // Writes file system files to the pickle.
230 void WriteFileSystemFilesToPickle(
231 const std::vector<DropData::FileSystemFileInfo>& file_system_files,
232 Pickle* pickle) {
233 pickle->WriteSizeT(file_system_files.size());
234 for (size_t i = 0; i < file_system_files.size(); ++i) {
235 pickle->WriteString(file_system_files[i].url.spec());
236 pickle->WriteInt64(file_system_files[i].size);
240 // Reads file system files from the pickle.
241 bool ReadFileSystemFilesFromPickle(
242 const Pickle& pickle,
243 std::vector<DropData::FileSystemFileInfo>* file_system_files) {
244 PickleIterator iter(pickle);
246 size_t num_files = 0;
247 if (!iter.ReadSizeT(&num_files))
248 return false;
249 file_system_files->resize(num_files);
251 for (size_t i = 0; i < num_files; ++i) {
252 std::string url_string;
253 int64 size = 0;
254 if (!iter.ReadString(&url_string) || !iter.ReadInt64(&size))
255 return false;
257 GURL url(url_string);
258 if (!url.is_valid())
259 return false;
261 (*file_system_files)[i].url = url;
262 (*file_system_files)[i].size = size;
264 return true;
267 // Utility to fill a ui::OSExchangeDataProvider object from DropData.
268 void PrepareDragData(const DropData& drop_data,
269 ui::OSExchangeData::Provider* provider,
270 WebContentsImpl* web_contents) {
271 provider->MarkOriginatedFromRenderer();
272 #if defined(OS_WIN)
273 // Put download before file contents to prefer the download of a image over
274 // its thumbnail link.
275 if (!drop_data.download_metadata.empty())
276 PrepareDragForDownload(drop_data, provider, web_contents);
277 #endif
278 #if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
279 // We set the file contents before the URL because the URL also sets file
280 // contents (to a .URL shortcut). We want to prefer file content data over
281 // a shortcut so we add it first.
282 if (!drop_data.file_contents.empty())
283 PrepareDragForFileContents(drop_data, provider);
284 #endif
285 // Call SetString() before SetURL() when we actually have a custom string.
286 // SetURL() will itself do SetString() when a string hasn't been set yet,
287 // but we want to prefer drop_data.text.string() over the URL string if it
288 // exists.
289 if (!drop_data.text.string().empty())
290 provider->SetString(drop_data.text.string());
291 if (drop_data.url.is_valid())
292 provider->SetURL(drop_data.url, drop_data.url_title);
293 if (!drop_data.html.string().empty())
294 provider->SetHtml(drop_data.html.string(), drop_data.html_base_url);
295 if (!drop_data.filenames.empty())
296 provider->SetFilenames(drop_data.filenames);
297 if (!drop_data.file_system_files.empty()) {
298 Pickle pickle;
299 WriteFileSystemFilesToPickle(drop_data.file_system_files, &pickle);
300 provider->SetPickledData(GetFileSystemFileCustomFormat(), pickle);
302 if (!drop_data.custom_data.empty()) {
303 Pickle pickle;
304 ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle);
305 provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
306 pickle);
310 // Utility to fill a DropData object from ui::OSExchangeData.
311 void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) {
312 drop_data->did_originate_from_renderer = data.DidOriginateFromRenderer();
314 base::string16 plain_text;
315 data.GetString(&plain_text);
316 if (!plain_text.empty())
317 drop_data->text = base::NullableString16(plain_text, false);
319 GURL url;
320 base::string16 url_title;
321 data.GetURLAndTitle(
322 ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &url, &url_title);
323 if (url.is_valid()) {
324 drop_data->url = url;
325 drop_data->url_title = url_title;
328 base::string16 html;
329 GURL html_base_url;
330 data.GetHtml(&html, &html_base_url);
331 if (!html.empty())
332 drop_data->html = base::NullableString16(html, false);
333 if (html_base_url.is_valid())
334 drop_data->html_base_url = html_base_url;
336 data.GetFilenames(&drop_data->filenames);
338 Pickle pickle;
339 std::vector<DropData::FileSystemFileInfo> file_system_files;
340 if (data.GetPickledData(GetFileSystemFileCustomFormat(), &pickle) &&
341 ReadFileSystemFilesFromPickle(pickle, &file_system_files))
342 drop_data->file_system_files = file_system_files;
344 if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle))
345 ui::ReadCustomDataIntoMap(
346 pickle.data(), pickle.size(), &drop_data->custom_data);
349 // Utilities to convert between blink::WebDragOperationsMask and
350 // ui::DragDropTypes.
351 int ConvertFromWeb(blink::WebDragOperationsMask ops) {
352 int drag_op = ui::DragDropTypes::DRAG_NONE;
353 if (ops & blink::WebDragOperationCopy)
354 drag_op |= ui::DragDropTypes::DRAG_COPY;
355 if (ops & blink::WebDragOperationMove)
356 drag_op |= ui::DragDropTypes::DRAG_MOVE;
357 if (ops & blink::WebDragOperationLink)
358 drag_op |= ui::DragDropTypes::DRAG_LINK;
359 return drag_op;
362 blink::WebDragOperationsMask ConvertToWeb(int drag_op) {
363 int web_drag_op = blink::WebDragOperationNone;
364 if (drag_op & ui::DragDropTypes::DRAG_COPY)
365 web_drag_op |= blink::WebDragOperationCopy;
366 if (drag_op & ui::DragDropTypes::DRAG_MOVE)
367 web_drag_op |= blink::WebDragOperationMove;
368 if (drag_op & ui::DragDropTypes::DRAG_LINK)
369 web_drag_op |= blink::WebDragOperationLink;
370 return (blink::WebDragOperationsMask) web_drag_op;
373 int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) {
374 int web_input_event_modifiers = 0;
375 if (aura_event_flags & ui::EF_SHIFT_DOWN)
376 web_input_event_modifiers |= blink::WebInputEvent::ShiftKey;
377 if (aura_event_flags & ui::EF_CONTROL_DOWN)
378 web_input_event_modifiers |= blink::WebInputEvent::ControlKey;
379 if (aura_event_flags & ui::EF_ALT_DOWN)
380 web_input_event_modifiers |= blink::WebInputEvent::AltKey;
381 if (aura_event_flags & ui::EF_COMMAND_DOWN)
382 web_input_event_modifiers |= blink::WebInputEvent::MetaKey;
383 if (aura_event_flags & ui::EF_LEFT_MOUSE_BUTTON)
384 web_input_event_modifiers |= blink::WebInputEvent::LeftButtonDown;
385 if (aura_event_flags & ui::EF_MIDDLE_MOUSE_BUTTON)
386 web_input_event_modifiers |= blink::WebInputEvent::MiddleButtonDown;
387 if (aura_event_flags & ui::EF_RIGHT_MOUSE_BUTTON)
388 web_input_event_modifiers |= blink::WebInputEvent::RightButtonDown;
389 return web_input_event_modifiers;
392 } // namespace
394 class WebContentsViewAura::WindowObserver
395 : public aura::WindowObserver, public aura::WindowTreeHostObserver {
396 public:
397 explicit WindowObserver(WebContentsViewAura* view)
398 : view_(view),
399 host_window_(NULL) {
400 view_->window_->AddObserver(this);
402 #if defined(OS_WIN)
403 if (view_->window_->GetRootWindow())
404 view_->window_->GetRootWindow()->AddObserver(this);
405 #endif
408 ~WindowObserver() override {
409 view_->window_->RemoveObserver(this);
410 if (view_->window_->GetHost())
411 view_->window_->GetHost()->RemoveObserver(this);
412 if (host_window_)
413 host_window_->RemoveObserver(this);
414 #if defined(OS_WIN)
415 if (host_window_) {
416 const aura::Window::Windows& children = host_window_->children();
417 for (size_t i = 0; i < children.size(); ++i)
418 children[i]->RemoveObserver(this);
421 aura::Window* root_window = view_->window_->GetRootWindow();
422 if (root_window) {
423 root_window->RemoveObserver(this);
424 const aura::Window::Windows& root_children = root_window->children();
425 for (size_t i = 0; i < root_children.size(); ++i)
426 root_children[i]->RemoveObserver(this);
428 #endif
431 #if defined(OS_WIN)
432 // Constrained windows are added as children of the parent's parent's view
433 // which may overlap with windowed NPAPI plugins. In that case, tell the RWHV
434 // so that it can update the plugins' cutout rects accordingly.
435 // Note: this is hard coding how Chrome layer adds its dialogs. Since NPAPI is
436 // going to be deprecated in a year, this is ok for now. The test for this is
437 // PrintPreviewTest.WindowedNPAPIPluginHidden.
438 void OnWindowAdded(aura::Window* new_window) override {
439 if (!new_window->Contains(view_->window_.get())) {
440 // Skip the case when the parent moves to the root window.
441 if (new_window != host_window_) {
442 // Observe sibling windows of the WebContents, or children of the root
443 // window.
444 if (new_window->parent() == host_window_ ||
445 new_window->parent() == view_->window_->GetRootWindow()) {
446 new_window->AddObserver(this);
451 if (new_window->parent() == host_window_) {
452 UpdateConstrainedWindows(NULL);
456 void OnWillRemoveWindow(aura::Window* window) override {
457 if (window == view_->window_)
458 return;
460 window->RemoveObserver(this);
461 UpdateConstrainedWindows(window);
464 void OnWindowVisibilityChanged(aura::Window* window, bool visible) override {
465 if (window == view_->window_ ||
466 window->parent() == host_window_ ||
467 window->parent() == view_->window_->GetRootWindow()) {
468 UpdateConstrainedWindows(NULL);
471 #endif
473 void OnWindowParentChanged(aura::Window* window,
474 aura::Window* parent) override {
475 if (window != view_->window_)
476 return;
478 aura::Window* host_window =
479 window->GetProperty(aura::client::kHostWindowKey);
480 if (!host_window)
481 host_window = parent;
483 if (host_window_)
484 host_window_->RemoveObserver(this);
486 #if defined(OS_WIN)
487 if (host_window_) {
488 const aura::Window::Windows& children = host_window_->children();
489 for (size_t i = 0; i < children.size(); ++i)
490 children[i]->RemoveObserver(this);
491 RenderWidgetHostViewAura* rwhv = ToRenderWidgetHostViewAura(
492 view_->web_contents_->GetRenderWidgetHostView());
493 if (rwhv)
494 rwhv->UpdateConstrainedWindowRects(std::vector<gfx::Rect>());
497 // When we get parented to the root window, the code below will watch the
498 // host window, aka root window. Since we already watch the root window on
499 // Windows, unregister first so that the debug check doesn't fire.
500 if (host_window && host_window == window->GetRootWindow())
501 host_window->RemoveObserver(this);
503 // We need to undo the above if we were parented to the root window and then
504 // got parented to another window. At that point, the code before the ifdef
505 // would have stopped watching the root window.
506 if (window->GetRootWindow() &&
507 host_window != window->GetRootWindow() &&
508 !window->GetRootWindow()->HasObserver(this)) {
509 window->GetRootWindow()->AddObserver(this);
511 #endif
513 host_window_ = host_window;
514 if (host_window) {
515 host_window->AddObserver(this);
516 #if defined(OS_WIN)
517 if (host_window != window->GetRootWindow()) {
518 const aura::Window::Windows& children = host_window->children();
519 for (size_t i = 0; i < children.size(); ++i) {
520 if (!children[i]->Contains(view_->window_.get()))
521 children[i]->AddObserver(this);
524 #endif
528 void OnWindowBoundsChanged(aura::Window* window,
529 const gfx::Rect& old_bounds,
530 const gfx::Rect& new_bounds) override {
531 if (window == host_window_ || window == view_->window_) {
532 SendScreenRects();
533 if (view_->touch_editable_)
534 view_->touch_editable_->UpdateEditingController();
535 #if defined(OS_WIN)
536 } else {
537 UpdateConstrainedWindows(NULL);
538 #endif
542 void OnWindowDestroying(aura::Window* window) override {
543 if (window == host_window_) {
544 host_window_->RemoveObserver(this);
545 host_window_ = NULL;
549 void OnWindowAddedToRootWindow(aura::Window* window) override {
550 if (window == view_->window_) {
551 window->GetHost()->AddObserver(this);
552 #if defined(OS_WIN)
553 if (!window->GetRootWindow()->HasObserver(this))
554 window->GetRootWindow()->AddObserver(this);
555 #endif
559 void OnWindowRemovingFromRootWindow(aura::Window* window,
560 aura::Window* new_root) override {
561 if (window == view_->window_) {
562 window->GetHost()->RemoveObserver(this);
563 #if defined(OS_WIN)
564 window->GetRootWindow()->RemoveObserver(this);
566 const aura::Window::Windows& root_children =
567 window->GetRootWindow()->children();
568 for (size_t i = 0; i < root_children.size(); ++i) {
569 if (root_children[i] != view_->window_ &&
570 root_children[i] != host_window_) {
571 root_children[i]->RemoveObserver(this);
574 #endif
578 // Overridden WindowTreeHostObserver:
579 void OnHostMoved(const aura::WindowTreeHost* host,
580 const gfx::Point& new_origin) override {
581 TRACE_EVENT1("ui",
582 "WebContentsViewAura::WindowObserver::OnHostMoved",
583 "new_origin", new_origin.ToString());
585 // This is for the desktop case (i.e. Aura desktop).
586 SendScreenRects();
589 private:
590 void SendScreenRects() {
591 RenderWidgetHostImpl::From(view_->web_contents_->GetRenderViewHost())->
592 SendScreenRects();
595 #if defined(OS_WIN)
596 void UpdateConstrainedWindows(aura::Window* exclude) {
597 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
598 view_->web_contents_->GetRenderWidgetHostView());
599 if (!view)
600 return;
602 std::vector<gfx::Rect> constrained_windows;
603 if (host_window_) {
604 const aura::Window::Windows& children = host_window_->children();
605 for (size_t i = 0; i < children.size(); ++i) {
606 if (!children[i]->Contains(view_->window_.get()) &&
607 children[i] != exclude &&
608 children[i]->IsVisible()) {
609 constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
614 aura::Window* root_window = view_->window_->GetRootWindow();
615 const aura::Window::Windows& root_children = root_window->children();
616 if (root_window) {
617 for (size_t i = 0; i < root_children.size(); ++i) {
618 if (root_children[i]->IsVisible() &&
619 !root_children[i]->Contains(view_->window_.get())) {
620 constrained_windows.push_back(
621 root_children[i]->GetBoundsInRootWindow());
626 view->UpdateConstrainedWindowRects(constrained_windows);
628 #endif
630 WebContentsViewAura* view_;
632 // The parent window that hosts the constrained windows. We cache the old host
633 // view so that we can unregister when it's not the parent anymore.
634 aura::Window* host_window_;
636 DISALLOW_COPY_AND_ASSIGN(WindowObserver);
639 ////////////////////////////////////////////////////////////////////////////////
640 // WebContentsViewAura, public:
642 WebContentsViewAura::WebContentsViewAura(WebContentsImpl* web_contents,
643 WebContentsViewDelegate* delegate)
644 : web_contents_(web_contents),
645 delegate_(delegate),
646 current_drag_op_(blink::WebDragOperationNone),
647 drag_dest_delegate_(NULL),
648 current_rvh_for_drag_(NULL),
649 current_overscroll_gesture_(OVERSCROLL_NONE),
650 completed_overscroll_gesture_(OVERSCROLL_NONE),
651 navigation_overlay_(nullptr),
652 touch_editable_(TouchEditableImplAura::Create()),
653 is_or_was_visible_(false) {
656 ////////////////////////////////////////////////////////////////////////////////
657 // WebContentsViewAura, private:
659 WebContentsViewAura::~WebContentsViewAura() {
660 if (!window_)
661 return;
663 window_observer_.reset();
664 window_->RemoveObserver(this);
666 // Window needs a valid delegate during its destructor, so we explicitly
667 // delete it here.
668 window_.reset();
671 void WebContentsViewAura::SetTouchEditableForTest(
672 TouchEditableImplAura* touch_editable) {
673 touch_editable_.reset(touch_editable);
674 AttachTouchEditableToRenderView();
677 void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
678 if (web_contents_->GetInterstitialPage())
679 web_contents_->GetInterstitialPage()->SetSize(size);
680 RenderWidgetHostView* rwhv =
681 web_contents_->GetRenderWidgetHostView();
682 if (rwhv)
683 rwhv->SetSize(size);
686 void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) {
687 aura::Window* root_window = GetNativeView()->GetRootWindow();
688 gfx::Point screen_loc =
689 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
690 gfx::Point client_loc = screen_loc;
691 RenderViewHost* rvh = web_contents_->GetRenderViewHost();
692 aura::Window* window = rvh->GetView()->GetNativeView();
693 aura::Window::ConvertPointToTarget(root_window, window, &client_loc);
694 if (!web_contents_)
695 return;
696 web_contents_->DragSourceEndedAt(client_loc.x(), client_loc.y(),
697 screen_loc.x(), screen_loc.y(), ops);
700 void WebContentsViewAura::InstallOverscrollControllerDelegate(
701 RenderWidgetHostViewAura* view) {
702 const std::string value = base::CommandLine::ForCurrentProcess()->
703 GetSwitchValueASCII(switches::kOverscrollHistoryNavigation);
704 if (value == "0") {
705 navigation_overlay_.reset();
706 return;
708 if (value == "2") {
709 navigation_overlay_.reset();
710 if (!gesture_nav_simple_)
711 gesture_nav_simple_.reset(new GestureNavSimple(web_contents_));
712 view->overscroll_controller()->set_delegate(gesture_nav_simple_.get());
713 return;
715 view->overscroll_controller()->set_delegate(this);
716 if (!navigation_overlay_) {
717 navigation_overlay_.reset(
718 new OverscrollNavigationOverlay(web_contents_, window_.get()));
722 void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) {
723 if (!web_contents_->GetRenderWidgetHostView())
724 return;
725 navigation_overlay_->relay_delegate()->OnOverscrollComplete(mode);
726 if (touch_editable_)
727 touch_editable_->OverscrollCompleted();
730 void WebContentsViewAura::AttachTouchEditableToRenderView() {
731 if (!touch_editable_)
732 return;
733 RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura(
734 web_contents_->GetRenderWidgetHostView());
735 touch_editable_->AttachToView(rwhva);
738 void WebContentsViewAura::OverscrollUpdateForWebContentsDelegate(
739 float delta_y) {
740 if (web_contents_->GetDelegate() && IsScrollEndEffectEnabled())
741 web_contents_->GetDelegate()->OverscrollUpdate(delta_y);
744 ////////////////////////////////////////////////////////////////////////////////
745 // WebContentsViewAura, WebContentsView implementation:
747 gfx::NativeView WebContentsViewAura::GetNativeView() const {
748 return window_.get();
751 gfx::NativeView WebContentsViewAura::GetContentNativeView() const {
752 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
753 return rwhv ? rwhv->GetNativeView() : NULL;
756 gfx::NativeWindow WebContentsViewAura::GetTopLevelNativeWindow() const {
757 gfx::NativeWindow window = window_->GetToplevelWindow();
758 return window ? window : delegate_->GetNativeWindow();
761 void WebContentsViewAura::GetContainerBounds(gfx::Rect *out) const {
762 *out = window_->GetBoundsInScreen();
765 void WebContentsViewAura::SizeContents(const gfx::Size& size) {
766 gfx::Rect bounds = window_->bounds();
767 if (bounds.size() != size) {
768 bounds.set_size(size);
769 window_->SetBounds(bounds);
770 } else {
771 // Our size matches what we want but the renderers size may not match.
772 // Pretend we were resized so that the renderers size is updated too.
773 SizeChangedCommon(size);
777 void WebContentsViewAura::Focus() {
778 if (web_contents_->GetInterstitialPage()) {
779 web_contents_->GetInterstitialPage()->Focus();
780 return;
783 if (delegate_.get() && delegate_->Focus())
784 return;
786 RenderWidgetHostView* rwhv =
787 web_contents_->GetFullscreenRenderWidgetHostView();
788 if (!rwhv)
789 rwhv = web_contents_->GetRenderWidgetHostView();
790 if (rwhv)
791 rwhv->Focus();
794 void WebContentsViewAura::SetInitialFocus() {
795 if (web_contents_->FocusLocationBarByDefault())
796 web_contents_->SetFocusToLocationBar(false);
797 else
798 Focus();
801 void WebContentsViewAura::StoreFocus() {
802 if (delegate_)
803 delegate_->StoreFocus();
806 void WebContentsViewAura::RestoreFocus() {
807 if (delegate_)
808 delegate_->RestoreFocus();
811 DropData* WebContentsViewAura::GetDropData() const {
812 return current_drop_data_.get();
815 gfx::Rect WebContentsViewAura::GetViewBounds() const {
816 return window_->GetBoundsInScreen();
819 ////////////////////////////////////////////////////////////////////////////////
820 // WebContentsViewAura, WebContentsView implementation:
822 void WebContentsViewAura::CreateView(
823 const gfx::Size& initial_size, gfx::NativeView context) {
824 // NOTE: we ignore |initial_size| since in some cases it's wrong (such as
825 // if the bookmark bar is not shown and you create a new tab). The right
826 // value is set shortly after this, so its safe to ignore.
828 aura::Env::CreateInstance(true);
829 window_.reset(new aura::Window(this));
830 window_->set_owned_by_parent(false);
831 window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
832 window_->SetTransparent(false);
833 window_->Init(ui::LAYER_NOT_DRAWN);
834 window_->AddObserver(this);
835 aura::Window* root_window = context ? context->GetRootWindow() : NULL;
836 if (root_window) {
837 // There are places where there is no context currently because object
838 // hierarchies are built before they're attached to a Widget. (See
839 // views::WebView as an example; GetWidget() returns NULL at the point
840 // where we are created.)
842 // It should be OK to not set a default parent since such users will
843 // explicitly add this WebContentsViewAura to their tree after they create
844 // us.
845 if (root_window) {
846 aura::client::ParentWindowWithContext(
847 window_.get(), root_window, root_window->GetBoundsInScreen());
850 window_->layer()->SetMasksToBounds(true);
851 window_->SetName("WebContentsViewAura");
853 // WindowObserver is not interesting and is problematic for Browser Plugin
854 // guests.
855 // The use cases for WindowObserver do not apply to Browser Plugins:
856 // 1) guests do not support NPAPI plugins.
857 // 2) guests' window bounds are supposed to come from its embedder.
858 if (!BrowserPluginGuest::IsGuest(web_contents_))
859 window_observer_.reset(new WindowObserver(this));
861 // delegate_->GetDragDestDelegate() creates a new delegate on every call.
862 // Hence, we save a reference to it locally. Similar model is used on other
863 // platforms as well.
864 if (delegate_)
865 drag_dest_delegate_ = delegate_->GetDragDestDelegate();
868 RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget(
869 RenderWidgetHost* render_widget_host, bool is_guest_view_hack) {
870 if (render_widget_host->GetView()) {
871 // During testing, the view will already be set up in most cases to the
872 // test view, so we don't want to clobber it with a real one. To verify that
873 // this actually is happening (and somebody isn't accidentally creating the
874 // view twice), we check for the RVH Factory, which will be set when we're
875 // making special ones (which go along with the special views).
876 DCHECK(RenderViewHostFactory::has_factory());
877 return static_cast<RenderWidgetHostViewBase*>(
878 render_widget_host->GetView());
881 RenderWidgetHostViewAura* view =
882 new RenderWidgetHostViewAura(render_widget_host, is_guest_view_hack);
883 view->InitAsChild(NULL);
884 GetNativeView()->AddChild(view->GetNativeView());
886 RenderWidgetHostImpl* host_impl =
887 RenderWidgetHostImpl::From(render_widget_host);
889 if (!host_impl->is_hidden())
890 view->Show();
892 // We listen to drag drop events in the newly created view's window.
893 aura::client::SetDragDropDelegate(view->GetNativeView(), this);
895 if (view->overscroll_controller() &&
896 (!web_contents_->GetDelegate() ||
897 web_contents_->GetDelegate()->CanOverscrollContent())) {
898 InstallOverscrollControllerDelegate(view);
901 AttachTouchEditableToRenderView();
902 return view;
905 RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForPopupWidget(
906 RenderWidgetHost* render_widget_host) {
907 return new RenderWidgetHostViewAura(render_widget_host, false);
910 void WebContentsViewAura::SetPageTitle(const base::string16& title) {
911 window_->SetTitle(title);
914 void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
917 void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
918 AttachTouchEditableToRenderView();
921 void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
922 RenderWidgetHostViewAura* view =
923 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView());
924 if (view) {
925 view->SetOverscrollControllerEnabled(enabled);
926 if (enabled)
927 InstallOverscrollControllerDelegate(view);
930 if (!enabled) {
931 navigation_overlay_.reset();
932 } else if (!navigation_overlay_) {
933 navigation_overlay_.reset(
934 new OverscrollNavigationOverlay(web_contents_, window_.get()));
938 ////////////////////////////////////////////////////////////////////////////////
939 // WebContentsViewAura, RenderViewHostDelegateView implementation:
941 void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
942 const ContextMenuParams& params) {
943 if (touch_editable_) {
944 touch_editable_->EndTouchEditing(false);
946 if (delegate_) {
947 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
948 web_contents_->GetRenderWidgetHostView());
949 if (view)
950 view->OnShowContextMenu();
952 delegate_->ShowContextMenu(render_frame_host, params);
953 // WARNING: we may have been deleted during the call to ShowContextMenu().
957 void WebContentsViewAura::StartDragging(
958 const DropData& drop_data,
959 blink::WebDragOperationsMask operations,
960 const gfx::ImageSkia& image,
961 const gfx::Vector2d& image_offset,
962 const DragEventSourceInfo& event_info) {
963 aura::Window* root_window = GetNativeView()->GetRootWindow();
964 if (!aura::client::GetDragDropClient(root_window)) {
965 web_contents_->SystemDragEnded();
966 return;
969 if (touch_editable_)
970 touch_editable_->EndTouchEditing(false);
972 ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
973 PrepareDragData(drop_data, provider, web_contents_);
975 ui::OSExchangeData data(provider); // takes ownership of |provider|.
977 if (!image.isNull())
978 drag_utils::SetDragImageOnDataObject(image, image_offset, &data);
980 scoped_ptr<WebDragSourceAura> drag_source(
981 new WebDragSourceAura(GetNativeView(), web_contents_));
983 // We need to enable recursive tasks on the message loop so we can get
984 // updates while in the system DoDragDrop loop.
985 int result_op = 0;
987 gfx::NativeView content_native_view = GetContentNativeView();
988 base::MessageLoop::ScopedNestableTaskAllower allow(
989 base::MessageLoop::current());
990 result_op = aura::client::GetDragDropClient(root_window)
991 ->StartDragAndDrop(data,
992 root_window,
993 content_native_view,
994 event_info.event_location,
995 ConvertFromWeb(operations),
996 event_info.event_source);
999 // Bail out immediately if the contents view window is gone. Note that it is
1000 // not safe to access any class members in this case since |this| may already
1001 // be destroyed. The local variable |drag_source| will still be valid though,
1002 // so we can use it to determine if the window is gone.
1003 if (!drag_source->window()) {
1004 // Note that in this case, we don't need to call SystemDragEnded() since the
1005 // renderer is going away.
1006 return;
1009 EndDrag(ConvertToWeb(result_op));
1010 web_contents_->SystemDragEnded();
1013 void WebContentsViewAura::UpdateDragCursor(blink::WebDragOperation operation) {
1014 current_drag_op_ = operation;
1017 void WebContentsViewAura::GotFocus() {
1018 web_contents_->NotifyWebContentsFocused();
1021 void WebContentsViewAura::TakeFocus(bool reverse) {
1022 if (web_contents_->GetDelegate() &&
1023 !web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) &&
1024 delegate_.get()) {
1025 delegate_->TakeFocus(reverse);
1029 void WebContentsViewAura::ShowDisambiguationPopup(
1030 const gfx::Rect& target_rect,
1031 const SkBitmap& zoomed_bitmap,
1032 const base::Callback<void(ui::GestureEvent*)>& gesture_cb,
1033 const base::Callback<void(ui::MouseEvent*)>& mouse_cb) {
1034 if (delegate_) {
1035 delegate_->ShowDisambiguationPopup(target_rect, zoomed_bitmap,
1036 window_.get(), gesture_cb, mouse_cb);
1040 void WebContentsViewAura::HideDisambiguationPopup() {
1041 if (delegate_)
1042 delegate_->HideDisambiguationPopup();
1045 ////////////////////////////////////////////////////////////////////////////////
1046 // WebContentsViewAura, OverscrollControllerDelegate implementation:
1048 gfx::Rect WebContentsViewAura::GetVisibleBounds() const {
1049 RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
1050 if (!rwhv || !rwhv->IsShowing())
1051 return gfx::Rect();
1053 return rwhv->GetViewBounds();
1056 bool WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) {
1057 if (current_overscroll_gesture_ == OVERSCROLL_NONE)
1058 return false;
1060 if (current_overscroll_gesture_ == OVERSCROLL_NORTH ||
1061 current_overscroll_gesture_ == OVERSCROLL_SOUTH) {
1062 OverscrollUpdateForWebContentsDelegate(delta_y);
1063 return delta_y != 0;
1065 return navigation_overlay_->relay_delegate()->OnOverscrollUpdate(delta_x,
1066 delta_y);
1069 void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) {
1070 if (web_contents_->GetDelegate() &&
1071 IsScrollEndEffectEnabled() &&
1072 (mode == OVERSCROLL_NORTH || mode == OVERSCROLL_SOUTH)) {
1073 web_contents_->GetDelegate()->OverscrollComplete();
1075 CompleteOverscrollNavigation(mode);
1078 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode,
1079 OverscrollMode new_mode) {
1080 if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH)
1081 OverscrollUpdateForWebContentsDelegate(0);
1083 if (touch_editable_) {
1084 if (new_mode == OVERSCROLL_NONE)
1085 touch_editable_->OverscrollCompleted();
1086 else
1087 touch_editable_->OverscrollStarted();
1090 current_overscroll_gesture_ = new_mode;
1091 navigation_overlay_->relay_delegate()->OnOverscrollModeChange(old_mode,
1092 new_mode);
1093 completed_overscroll_gesture_ = OVERSCROLL_NONE;
1096 ////////////////////////////////////////////////////////////////////////////////
1097 // WebContentsViewAura, aura::WindowDelegate implementation:
1099 gfx::Size WebContentsViewAura::GetMinimumSize() const {
1100 return gfx::Size();
1103 gfx::Size WebContentsViewAura::GetMaximumSize() const {
1104 return gfx::Size();
1107 void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
1108 const gfx::Rect& new_bounds) {
1109 SizeChangedCommon(new_bounds.size());
1110 if (delegate_)
1111 delegate_->SizeChanged(new_bounds.size());
1113 // Constrained web dialogs, need to be kept centered over our content area.
1114 for (size_t i = 0; i < window_->children().size(); i++) {
1115 if (window_->children()[i]->GetProperty(
1116 aura::client::kConstrainedWindowKey)) {
1117 gfx::Rect bounds = window_->children()[i]->bounds();
1118 bounds.set_origin(
1119 gfx::Point((new_bounds.width() - bounds.width()) / 2,
1120 (new_bounds.height() - bounds.height()) / 2));
1121 window_->children()[i]->SetBounds(bounds);
1126 ui::TextInputClient* WebContentsViewAura::GetFocusedTextInputClient() {
1127 return nullptr;
1130 gfx::NativeCursor WebContentsViewAura::GetCursor(const gfx::Point& point) {
1131 return gfx::kNullCursor;
1134 int WebContentsViewAura::GetNonClientComponent(const gfx::Point& point) const {
1135 return HTCLIENT;
1138 bool WebContentsViewAura::ShouldDescendIntoChildForEventHandling(
1139 aura::Window* child,
1140 const gfx::Point& location) {
1141 return true;
1144 bool WebContentsViewAura::CanFocus() {
1145 // Do not take the focus if the render widget host view aura is gone or
1146 // is in the process of shutting down because neither the view window nor
1147 // this window can handle key events.
1148 RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
1149 web_contents_->GetRenderWidgetHostView());
1150 if (view != NULL && !view->IsClosing())
1151 return true;
1153 return false;
1156 void WebContentsViewAura::OnCaptureLost() {
1159 void WebContentsViewAura::OnPaint(const ui::PaintContext& context) {
1162 void WebContentsViewAura::OnDeviceScaleFactorChanged(
1163 float device_scale_factor) {
1166 void WebContentsViewAura::OnWindowDestroying(aura::Window* window) {
1167 // This means the destructor is going to be called soon. If there is an
1168 // overscroll gesture in progress (i.e. |overscroll_window_| is not NULL),
1169 // then destroying it in the WebContentsViewAura destructor can trigger other
1170 // virtual functions to be called (e.g. OnImplicitAnimationsCompleted()). So
1171 // destroy the overscroll window here.
1172 navigation_overlay_.reset();
1175 void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) {
1178 void WebContentsViewAura::OnWindowTargetVisibilityChanged(bool visible) {
1181 bool WebContentsViewAura::HasHitTestMask() const {
1182 return false;
1185 void WebContentsViewAura::GetHitTestMask(gfx::Path* mask) const {
1188 ////////////////////////////////////////////////////////////////////////////////
1189 // WebContentsViewAura, ui::EventHandler implementation:
1191 void WebContentsViewAura::OnKeyEvent(ui::KeyEvent* event) {
1194 void WebContentsViewAura::OnMouseEvent(ui::MouseEvent* event) {
1195 if (!web_contents_->GetDelegate())
1196 return;
1198 switch (event->type()) {
1199 case ui::ET_MOUSE_PRESSED:
1200 web_contents_->GetDelegate()->ActivateContents(web_contents_);
1201 break;
1202 case ui::ET_MOUSE_MOVED:
1203 case ui::ET_MOUSE_EXITED:
1204 web_contents_->GetDelegate()->ContentsMouseEvent(
1205 web_contents_,
1206 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
1207 event->type() == ui::ET_MOUSE_MOVED);
1208 break;
1209 default:
1210 break;
1214 ////////////////////////////////////////////////////////////////////////////////
1215 // WebContentsViewAura, aura::client::DragDropDelegate implementation:
1217 void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
1218 current_rvh_for_drag_ = web_contents_->GetRenderViewHost();
1219 current_drop_data_.reset(new DropData());
1221 PrepareDropData(current_drop_data_.get(), event.data());
1222 blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
1224 // Give the delegate an opportunity to cancel the drag.
1225 if (web_contents_->GetDelegate() &&
1226 !web_contents_->GetDelegate()->CanDragEnter(
1227 web_contents_, *current_drop_data_.get(), op)) {
1228 current_drop_data_.reset(NULL);
1229 return;
1232 if (drag_dest_delegate_)
1233 drag_dest_delegate_->DragInitialize(web_contents_);
1235 gfx::Point screen_pt =
1236 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
1237 web_contents_->GetRenderViewHost()->DragTargetDragEnter(
1238 *current_drop_data_.get(), event.location(), screen_pt, op,
1239 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
1241 if (drag_dest_delegate_) {
1242 drag_dest_delegate_->OnReceiveDragData(event.data());
1243 drag_dest_delegate_->OnDragEnter();
1247 int WebContentsViewAura::OnDragUpdated(const ui::DropTargetEvent& event) {
1248 DCHECK(current_rvh_for_drag_);
1249 if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
1250 OnDragEntered(event);
1252 if (!current_drop_data_)
1253 return ui::DragDropTypes::DRAG_NONE;
1255 blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
1256 gfx::Point screen_pt =
1257 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
1258 web_contents_->GetRenderViewHost()->DragTargetDragOver(
1259 event.location(), screen_pt, op,
1260 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
1262 if (drag_dest_delegate_)
1263 drag_dest_delegate_->OnDragOver();
1265 return ConvertFromWeb(current_drag_op_);
1268 void WebContentsViewAura::OnDragExited() {
1269 DCHECK(current_rvh_for_drag_);
1270 if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
1271 return;
1273 if (!current_drop_data_)
1274 return;
1276 web_contents_->GetRenderViewHost()->DragTargetDragLeave();
1277 if (drag_dest_delegate_)
1278 drag_dest_delegate_->OnDragLeave();
1280 current_drop_data_.reset();
1283 int WebContentsViewAura::OnPerformDrop(const ui::DropTargetEvent& event) {
1284 DCHECK(current_rvh_for_drag_);
1285 if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
1286 OnDragEntered(event);
1288 if (!current_drop_data_)
1289 return ui::DragDropTypes::DRAG_NONE;
1291 web_contents_->GetRenderViewHost()->DragTargetDrop(
1292 event.location(),
1293 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
1294 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
1295 if (drag_dest_delegate_)
1296 drag_dest_delegate_->OnDrop();
1297 current_drop_data_.reset();
1298 return ConvertFromWeb(current_drag_op_);
1301 void WebContentsViewAura::OnWindowVisibilityChanged(aura::Window* window,
1302 bool visible) {
1303 // Ignore any visibility changes in the hierarchy below.
1304 if (window != window_.get() && window_->Contains(window))
1305 return;
1307 UpdateWebContentsVisibility(visible);
1310 void WebContentsViewAura::UpdateWebContentsVisibility(bool visible) {
1311 if (!is_or_was_visible_) {
1312 // We should not hide the web contents before it was shown the first time,
1313 // since resources would immediately be destroyed and only re-created after
1314 // content got loaded. In this state the window content is undefined and can
1315 // show garbage.
1316 // However - the page load mechanism requires an activation call through a
1317 // visibility call to (re)load.
1318 if (visible) {
1319 is_or_was_visible_ = true;
1320 web_contents_->WasShown();
1322 return;
1324 if (visible) {
1325 if (!web_contents_->should_normally_be_visible())
1326 web_contents_->WasShown();
1327 } else {
1328 if (web_contents_->should_normally_be_visible())
1329 web_contents_->WasHidden();
1333 } // namespace content