OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/web_contents/web_contents_view_aura.h" | 5 #include "content/browser/web_contents/web_contents_view_aura.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "content/browser/renderer_host/dip_util.h" | 10 #include "content/browser/renderer_host/dip_util.h" |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 } | 93 } |
94 | 94 |
95 // The window delegate for the overscroll window. This redirects trackpad events | 95 // The window delegate for the overscroll window. This redirects trackpad events |
96 // to the web-contents window. The delegate destroys itself when the window is | 96 // to the web-contents window. The delegate destroys itself when the window is |
97 // destroyed. | 97 // destroyed. |
98 class OverscrollWindowDelegate : public aura::WindowDelegate { | 98 class OverscrollWindowDelegate : public aura::WindowDelegate { |
99 public: | 99 public: |
100 OverscrollWindowDelegate(WebContentsImpl* web_contents, | 100 OverscrollWindowDelegate(WebContentsImpl* web_contents, |
101 OverscrollMode overscroll_mode) | 101 OverscrollMode overscroll_mode) |
102 : web_contents_(web_contents), | 102 : web_contents_(web_contents), |
103 show_shadow_(false) { | 103 show_shadow_(false), |
| 104 forward_events_(true) { |
104 const NavigationControllerImpl& controller = web_contents->GetController(); | 105 const NavigationControllerImpl& controller = web_contents->GetController(); |
105 const NavigationEntryImpl* entry = NULL; | 106 const NavigationEntryImpl* entry = NULL; |
106 if (ShouldNavigateForward(controller, overscroll_mode)) { | 107 if (ShouldNavigateForward(controller, overscroll_mode)) { |
107 entry = NavigationEntryImpl::FromNavigationEntry( | 108 entry = NavigationEntryImpl::FromNavigationEntry( |
108 controller.GetEntryAtOffset(1)); | 109 controller.GetEntryAtOffset(1)); |
109 } else if (ShouldNavigateBack(controller, overscroll_mode)) { | 110 } else if (ShouldNavigateBack(controller, overscroll_mode)) { |
110 entry = NavigationEntryImpl::FromNavigationEntry( | 111 entry = NavigationEntryImpl::FromNavigationEntry( |
111 controller.GetEntryAtOffset(-1)); | 112 controller.GetEntryAtOffset(-1)); |
112 } | 113 } |
113 if (!entry || !entry->screenshot()) | 114 if (!entry || !entry->screenshot()) |
114 return; | 115 return; |
115 | 116 |
116 std::vector<gfx::ImagePNGRep> image_reps; | 117 std::vector<gfx::ImagePNGRep> image_reps; |
117 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), | 118 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), |
118 ui::GetScaleFactorForNativeView(web_contents_window()))); | 119 ui::GetScaleFactorForNativeView(web_contents_window()))); |
119 image_ = gfx::Image(image_reps); | 120 image_ = gfx::Image(image_reps); |
120 if (image_.AsImageSkia().size() != web_contents_window()->bounds().size()) | 121 if (image_.AsImageSkia().size() != web_contents_window()->bounds().size()) |
121 image_ = gfx::Image(); | 122 image_ = gfx::Image(); |
122 } | 123 } |
123 | 124 |
124 bool has_screenshot() const { return !image_.IsEmpty(); } | 125 bool has_screenshot() const { return !image_.IsEmpty(); } |
125 | 126 |
126 void set_show_shadow(bool show) { | 127 void set_show_shadow(bool show) { |
127 show_shadow_ = show; | 128 show_shadow_ = show; |
128 } | 129 } |
129 | 130 |
| 131 void stop_forwarding_events() { forward_events_ = false; } |
| 132 |
130 private: | 133 private: |
131 virtual ~OverscrollWindowDelegate() {} | 134 virtual ~OverscrollWindowDelegate() {} |
132 | 135 |
133 aura::Window* web_contents_window() { | 136 aura::Window* web_contents_window() { |
134 return web_contents_->GetView()->GetContentNativeView(); | 137 return web_contents_->GetView()->GetContentNativeView(); |
135 } | 138 } |
136 | 139 |
137 // aura::WindowDelegate implementation: | 140 // aura::WindowDelegate implementation: |
138 virtual gfx::Size GetMinimumSize() const OVERRIDE { | 141 virtual gfx::Size GetMinimumSize() const OVERRIDE { |
139 return gfx::Size(); | 142 return gfx::Size(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 | 220 |
218 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE { | 221 virtual void GetHitTestMask(gfx::Path* mask) const OVERRIDE { |
219 } | 222 } |
220 | 223 |
221 virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE { | 224 virtual scoped_refptr<ui::Texture> CopyTexture() OVERRIDE { |
222 return scoped_refptr<ui::Texture>(); | 225 return scoped_refptr<ui::Texture>(); |
223 } | 226 } |
224 | 227 |
225 // Overridden from ui::EventHandler. | 228 // Overridden from ui::EventHandler. |
226 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { | 229 virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE { |
227 if (web_contents_window()) | 230 if (forward_events_ && web_contents_window()) |
228 web_contents_window()->delegate()->OnScrollEvent(event); | 231 web_contents_window()->delegate()->OnScrollEvent(event); |
229 } | 232 } |
230 | 233 |
231 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { | 234 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { |
232 if (web_contents_window()) | 235 if (forward_events_ && web_contents_window()) |
233 web_contents_window()->delegate()->OnGestureEvent(event); | 236 web_contents_window()->delegate()->OnGestureEvent(event); |
234 } | 237 } |
235 | 238 |
236 WebContents* web_contents_; | 239 WebContents* web_contents_; |
237 gfx::Image image_; | 240 gfx::Image image_; |
238 bool show_shadow_; | 241 bool show_shadow_; |
239 | 242 |
| 243 // The window is displayed both during the gesture, and after the gesture |
| 244 // while the navigation is in progress. During the gesture, it is necessary to |
| 245 // forward input events to the content page (e.g. when the overscroll window |
| 246 // slides under the cursor and starts receiving scroll events). However, once |
| 247 // the gesture is complete, and the window is being displayed as an overlay |
| 248 // window during navigation, events should not be forwarded anymore. |
| 249 bool forward_events_; |
| 250 |
240 DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate); | 251 DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate); |
241 }; | 252 }; |
242 | 253 |
243 // Listens to all mouse drag events during a drag and drop and sends them to | 254 // Listens to all mouse drag events during a drag and drop and sends them to |
244 // the renderer. | 255 // the renderer. |
245 class WebDragSourceAura : public MessageLoopForUI::Observer, | 256 class WebDragSourceAura : public MessageLoopForUI::Observer, |
246 public NotificationObserver { | 257 public NotificationObserver { |
247 public: | 258 public: |
248 WebDragSourceAura(aura::Window* window, WebContentsImpl* contents) | 259 WebDragSourceAura(aura::Window* window, WebContentsImpl* contents) |
249 : window_(window), | 260 : window_(window), |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 // screenshot window on top of the page until the page has completed loading and | 601 // screenshot window on top of the page until the page has completed loading and |
591 // painting. | 602 // painting. |
592 class OverscrollNavigationOverlay : | 603 class OverscrollNavigationOverlay : |
593 public RenderWidgetHostViewAura::PaintObserver { | 604 public RenderWidgetHostViewAura::PaintObserver { |
594 public: | 605 public: |
595 OverscrollNavigationOverlay() | 606 OverscrollNavigationOverlay() |
596 : view_(NULL), | 607 : view_(NULL), |
597 loading_complete_(false), | 608 loading_complete_(false), |
598 received_paint_update_(false), | 609 received_paint_update_(false), |
599 compositor_updated_(false), | 610 compositor_updated_(false), |
600 has_screenshot_(false) { | 611 has_screenshot_(false), |
| 612 need_paint_update_(true) { |
601 } | 613 } |
602 | 614 |
603 virtual ~OverscrollNavigationOverlay() { | 615 virtual ~OverscrollNavigationOverlay() { |
604 if (view_) | 616 if (view_) |
605 view_->set_paint_observer(NULL); | 617 view_->set_paint_observer(NULL); |
606 } | 618 } |
607 | 619 |
608 bool has_window() const { return !!window_.get(); } | 620 bool has_window() const { return !!window_.get(); } |
609 | 621 |
610 void StartObservingView(RenderWidgetHostViewAura* view) { | 622 void StartObservingView(RenderWidgetHostViewAura* view) { |
(...skipping 11 matching lines...) Expand all Loading... |
622 window_->parent()->StackChildAtTop(window_.get()); | 634 window_->parent()->StackChildAtTop(window_.get()); |
623 } | 635 } |
624 | 636 |
625 void SetOverlayWindow(scoped_ptr<aura::Window> window, bool has_screenshot) { | 637 void SetOverlayWindow(scoped_ptr<aura::Window> window, bool has_screenshot) { |
626 window_ = window.Pass(); | 638 window_ = window.Pass(); |
627 if (window_.get() && window_->parent()) | 639 if (window_.get() && window_->parent()) |
628 window_->parent()->StackChildAtTop(window_.get()); | 640 window_->parent()->StackChildAtTop(window_.get()); |
629 has_screenshot_ = has_screenshot; | 641 has_screenshot_ = has_screenshot; |
630 } | 642 } |
631 | 643 |
| 644 void SetupForTesting() { |
| 645 need_paint_update_ = false; |
| 646 } |
| 647 |
632 private: | 648 private: |
633 // Stop observing the page if the page-load has completed and the page has | 649 // Stop observing the page if the page-load has completed and the page has |
634 // been painted. | 650 // been painted. |
635 void StopObservingIfDone() { | 651 void StopObservingIfDone() { |
636 // If there is a screenshot displayed in the overlay window, then wait for | 652 // If there is a screenshot displayed in the overlay window, then wait for |
637 // the navigated page to complete loading and some paint update before | 653 // the navigated page to complete loading and some paint update before |
638 // hiding the overlay. | 654 // hiding the overlay. |
639 // If there is no screenshot in the overlay window, then hide this view | 655 // If there is no screenshot in the overlay window, then hide this view |
640 // as soon as there is any new painting notification. | 656 // as soon as there is any new painting notification. |
641 if (!received_paint_update_ || (has_screenshot_ && !loading_complete_)) | 657 if ((need_paint_update_ && !received_paint_update_) || |
| 658 (has_screenshot_ && !loading_complete_)) { |
642 return; | 659 return; |
| 660 } |
643 | 661 |
644 window_.reset(); | 662 window_.reset(); |
645 if (view_) { | 663 if (view_) { |
646 view_->set_paint_observer(NULL); | 664 view_->set_paint_observer(NULL); |
647 view_ = NULL; | 665 view_ = NULL; |
648 } | 666 } |
649 } | 667 } |
650 | 668 |
651 // Overridden from RenderWidgetHostViewAura::PaintObserver: | 669 // Overridden from RenderWidgetHostViewAura::PaintObserver: |
652 virtual void OnPaintComplete() OVERRIDE { | 670 virtual void OnPaintComplete() OVERRIDE { |
(...skipping 21 matching lines...) Expand all Loading... |
674 view_ = NULL; | 692 view_ = NULL; |
675 } | 693 } |
676 | 694 |
677 scoped_ptr<aura::Window> window_; | 695 scoped_ptr<aura::Window> window_; |
678 RenderWidgetHostViewAura* view_; | 696 RenderWidgetHostViewAura* view_; |
679 bool loading_complete_; | 697 bool loading_complete_; |
680 bool received_paint_update_; | 698 bool received_paint_update_; |
681 bool compositor_updated_; | 699 bool compositor_updated_; |
682 bool has_screenshot_; | 700 bool has_screenshot_; |
683 | 701 |
| 702 // During tests, the aura windows don't get any paint updates. So the overlay |
| 703 // container keeps waiting for a paint update it never receives, causing a |
| 704 // timeout. So during tests, disable the wait for paint updates. |
| 705 bool need_paint_update_; |
| 706 |
684 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlay); | 707 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlay); |
685 }; | 708 }; |
686 | 709 |
687 class WebContentsViewAura::WindowObserver | 710 class WebContentsViewAura::WindowObserver |
688 : public aura::WindowObserver, public aura::RootWindowObserver { | 711 : public aura::WindowObserver, public aura::RootWindowObserver { |
689 public: | 712 public: |
690 explicit WindowObserver(WebContentsViewAura* view) | 713 explicit WindowObserver(WebContentsViewAura* view) |
691 : view_(view), | 714 : view_(view), |
692 parent_(NULL) { | 715 parent_(NULL) { |
693 view_->window_->AddObserver(this); | 716 view_->window_->AddObserver(this); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 | 874 |
852 window_observer_.reset(); | 875 window_observer_.reset(); |
853 #if defined(OS_WIN) | 876 #if defined(OS_WIN) |
854 child_window_observer_.reset(); | 877 child_window_observer_.reset(); |
855 #endif | 878 #endif |
856 // Window needs a valid delegate during its destructor, so we explicitly | 879 // Window needs a valid delegate during its destructor, so we explicitly |
857 // delete it here. | 880 // delete it here. |
858 window_.reset(); | 881 window_.reset(); |
859 } | 882 } |
860 | 883 |
| 884 void WebContentsViewAura::SetupOverlayWindowForTesting() { |
| 885 if (navigation_overlay_.get()) |
| 886 navigation_overlay_->SetupForTesting(); |
| 887 } |
| 888 |
861 void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) { | 889 void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) { |
862 if (web_contents_->GetInterstitialPage()) | 890 if (web_contents_->GetInterstitialPage()) |
863 web_contents_->GetInterstitialPage()->SetSize(size); | 891 web_contents_->GetInterstitialPage()->SetSize(size); |
864 RenderWidgetHostView* rwhv = | 892 RenderWidgetHostView* rwhv = |
865 web_contents_->GetRenderWidgetHostView(); | 893 web_contents_->GetRenderWidgetHostView(); |
866 if (rwhv) | 894 if (rwhv) |
867 rwhv->SetSize(size); | 895 rwhv->SetSize(size); |
868 } | 896 } |
869 | 897 |
870 void WebContentsViewAura::EndDrag(WebKit::WebDragOperationsMask ops) { | 898 void WebContentsViewAura::EndDrag(WebKit::WebDragOperationsMask ops) { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 OVERSCROLL_CONFIG_HORIZ_RESIST_AFTER); | 1072 OVERSCROLL_CONFIG_HORIZ_RESIST_AFTER); |
1045 int scroll = GetResistedScrollAmount(abs(delta_x), | 1073 int scroll = GetResistedScrollAmount(abs(delta_x), |
1046 static_cast<int>(threshold)); | 1074 static_cast<int>(threshold)); |
1047 return gfx::Vector2d(delta_x < 0 ? -scroll : scroll, 0); | 1075 return gfx::Vector2d(delta_x < 0 ? -scroll : scroll, 0); |
1048 } | 1076 } |
1049 | 1077 |
1050 void WebContentsViewAura::PrepareOverscrollNavigationOverlay() { | 1078 void WebContentsViewAura::PrepareOverscrollNavigationOverlay() { |
1051 OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( | 1079 OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( |
1052 overscroll_window_->delegate()); | 1080 overscroll_window_->delegate()); |
1053 delegate->set_show_shadow(false); | 1081 delegate->set_show_shadow(false); |
| 1082 delegate->stop_forwarding_events(); |
1054 overscroll_window_->SchedulePaintInRect( | 1083 overscroll_window_->SchedulePaintInRect( |
1055 gfx::Rect(overscroll_window_->bounds().size())); | 1084 gfx::Rect(overscroll_window_->bounds().size())); |
1056 navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(), | 1085 navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(), |
1057 delegate->has_screenshot()); | 1086 delegate->has_screenshot()); |
1058 navigation_overlay_->StartObservingView(static_cast< | 1087 navigation_overlay_->StartObservingView(static_cast< |
1059 RenderWidgetHostViewAura*>(web_contents_->GetRenderWidgetHostView())); | 1088 RenderWidgetHostViewAura*>(web_contents_->GetRenderWidgetHostView())); |
1060 } | 1089 } |
1061 | 1090 |
1062 void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) { | 1091 void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) { |
1063 if (!overscroll_change_brightness_) | 1092 if (!overscroll_change_brightness_) |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1372 } | 1401 } |
1373 | 1402 |
1374 ResetOverscrollTransform(); | 1403 ResetOverscrollTransform(); |
1375 } | 1404 } |
1376 | 1405 |
1377 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, | 1406 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, |
1378 OverscrollMode new_mode) { | 1407 OverscrollMode new_mode) { |
1379 // Reset any in-progress overscroll animation first. | 1408 // Reset any in-progress overscroll animation first. |
1380 ResetOverscrollTransform(); | 1409 ResetOverscrollTransform(); |
1381 | 1410 |
1382 if (new_mode == OVERSCROLL_NONE) { | 1411 if (new_mode == OVERSCROLL_NONE || |
| 1412 (navigation_overlay_.get() && navigation_overlay_->has_window())) { |
1383 current_overscroll_gesture_ = OVERSCROLL_NONE; | 1413 current_overscroll_gesture_ = OVERSCROLL_NONE; |
1384 } else { | 1414 } else { |
1385 // Cleanup state of the content window first, because that can reset the | 1415 // Cleanup state of the content window first, because that can reset the |
1386 // value of |current_overscroll_gesture_|. | 1416 // value of |current_overscroll_gesture_|. |
1387 PrepareContentWindowForOverscroll(); | 1417 PrepareContentWindowForOverscroll(); |
1388 | 1418 |
1389 current_overscroll_gesture_ = new_mode; | 1419 current_overscroll_gesture_ = new_mode; |
1390 PrepareOverscrollWindow(); | 1420 PrepareOverscrollWindow(); |
1391 | 1421 |
1392 UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT); | 1422 UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1601 event.location(), | 1631 event.location(), |
1602 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(), | 1632 gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(), |
1603 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); | 1633 ConvertAuraEventFlagsToWebInputEventModifiers(event.flags())); |
1604 if (drag_dest_delegate_) | 1634 if (drag_dest_delegate_) |
1605 drag_dest_delegate_->OnDrop(); | 1635 drag_dest_delegate_->OnDrop(); |
1606 current_drop_data_.reset(); | 1636 current_drop_data_.reset(); |
1607 return current_drag_op_; | 1637 return current_drag_op_; |
1608 } | 1638 } |
1609 | 1639 |
1610 } // namespace content | 1640 } // namespace content |
OLD | NEW |