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/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "content/browser/browser_plugin/browser_plugin_guest.h" | 12 #include "content/browser/browser_plugin/browser_plugin_guest.h" |
13 #include "content/browser/download/drag_download_util.h" | 13 #include "content/browser/download/drag_download_util.h" |
14 #include "content/browser/frame_host/interstitial_page_impl.h" | 14 #include "content/browser/frame_host/interstitial_page_impl.h" |
15 #include "content/browser/frame_host/navigation_entry_impl.h" | 15 #include "content/browser/frame_host/navigation_entry_impl.h" |
16 #include "content/browser/renderer_host/dip_util.h" | 16 #include "content/browser/renderer_host/dip_util.h" |
17 #include "content/browser/renderer_host/overscroll_controller.h" | 17 #include "content/browser/renderer_host/overscroll_controller.h" |
18 #include "content/browser/renderer_host/render_view_host_factory.h" | 18 #include "content/browser/renderer_host/render_view_host_factory.h" |
19 #include "content/browser/renderer_host/render_view_host_impl.h" | 19 #include "content/browser/renderer_host/render_view_host_impl.h" |
20 #include "content/browser/renderer_host/render_widget_host_impl.h" | 20 #include "content/browser/renderer_host/render_widget_host_impl.h" |
21 #include "content/browser/renderer_host/render_widget_host_view_aura.h" | 21 #include "content/browser/renderer_host/render_widget_host_view_aura.h" |
22 #include "content/browser/renderer_host/web_input_event_aura.h" | 22 #include "content/browser/renderer_host/web_input_event_aura.h" |
23 #include "content/browser/web_contents/aura/gesture_nav_simple.h" | 23 #include "content/browser/web_contents/aura/gesture_nav_simple.h" |
24 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" | 24 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" |
| 25 #include "content/browser/web_contents/aura/shadow_layer_delegate.h" |
| 26 #include "content/browser/web_contents/aura/window_slider.h" |
25 #include "content/browser/web_contents/touch_editable_impl_aura.h" | 27 #include "content/browser/web_contents/touch_editable_impl_aura.h" |
26 #include "content/browser/web_contents/web_contents_impl.h" | 28 #include "content/browser/web_contents/web_contents_impl.h" |
27 #include "content/public/browser/content_browser_client.h" | 29 #include "content/public/browser/content_browser_client.h" |
28 #include "content/public/browser/notification_observer.h" | 30 #include "content/public/browser/notification_observer.h" |
29 #include "content/public/browser/notification_registrar.h" | 31 #include "content/public/browser/notification_registrar.h" |
30 #include "content/public/browser/notification_source.h" | 32 #include "content/public/browser/notification_source.h" |
31 #include "content/public/browser/notification_types.h" | 33 #include "content/public/browser/notification_types.h" |
32 #include "content/public/browser/overscroll_configuration.h" | 34 #include "content/public/browser/overscroll_configuration.h" |
33 #include "content/public/browser/render_view_host.h" | 35 #include "content/public/browser/render_view_host.h" |
34 #include "content/public/browser/render_widget_host.h" | 36 #include "content/public/browser/render_widget_host.h" |
35 #include "content/public/browser/render_widget_host_view.h" | 37 #include "content/public/browser/render_widget_host_view.h" |
36 #include "content/public/browser/web_contents_delegate.h" | 38 #include "content/public/browser/web_contents_delegate.h" |
37 #include "content/public/browser/web_contents_observer.h" | 39 #include "content/public/browser/web_contents_observer.h" |
38 #include "content/public/browser/web_contents_view_delegate.h" | 40 #include "content/public/browser/web_contents_view_delegate.h" |
39 #include "content/public/browser/web_drag_dest_delegate.h" | 41 #include "content/public/browser/web_drag_dest_delegate.h" |
40 #include "content/public/common/content_client.h" | 42 #include "content/public/common/content_client.h" |
41 #include "content/public/common/content_switches.h" | 43 #include "content/public/common/content_switches.h" |
42 #include "content/public/common/drop_data.h" | 44 #include "content/public/common/drop_data.h" |
43 #include "net/base/filename_util.h" | 45 #include "net/base/filename_util.h" |
44 #include "third_party/WebKit/public/web/WebInputEvent.h" | 46 #include "third_party/WebKit/public/web/WebInputEvent.h" |
45 #include "ui/aura/client/aura_constants.h" | 47 #include "ui/aura/client/aura_constants.h" |
46 #include "ui/aura/client/window_tree_client.h" | 48 #include "ui/aura/client/window_tree_client.h" |
47 #include "ui/aura/env.h" | 49 #include "ui/aura/env.h" |
48 #include "ui/aura/window.h" | 50 #include "ui/aura/window.h" |
49 #include "ui/aura/window_observer.h" | 51 #include "ui/aura/window_observer.h" |
50 #include "ui/aura/window_tree_host.h" | 52 #include "ui/aura/window_tree_host.h" |
51 #include "ui/aura/window_tree_host_observer.h" | 53 #include "ui/aura/window_tree_host_observer.h" |
| 54 #include "ui/aura_extra/image_window_delegate.h" |
52 #include "ui/base/clipboard/clipboard.h" | 55 #include "ui/base/clipboard/clipboard.h" |
53 #include "ui/base/clipboard/custom_data_helper.h" | 56 #include "ui/base/clipboard/custom_data_helper.h" |
54 #include "ui/base/dragdrop/drag_drop_types.h" | 57 #include "ui/base/dragdrop/drag_drop_types.h" |
55 #include "ui/base/dragdrop/drag_utils.h" | 58 #include "ui/base/dragdrop/drag_utils.h" |
56 #include "ui/base/dragdrop/drop_target_event.h" | 59 #include "ui/base/dragdrop/drop_target_event.h" |
57 #include "ui/base/dragdrop/os_exchange_data.h" | 60 #include "ui/base/dragdrop/os_exchange_data.h" |
58 #include "ui/base/hit_test.h" | 61 #include "ui/base/hit_test.h" |
59 #include "ui/compositor/layer.h" | 62 #include "ui/compositor/layer.h" |
| 63 #include "ui/compositor/scoped_layer_animation_settings.h" |
60 #include "ui/events/event.h" | 64 #include "ui/events/event.h" |
61 #include "ui/events/event_utils.h" | 65 #include "ui/events/event_utils.h" |
62 #include "ui/gfx/canvas.h" | 66 #include "ui/gfx/canvas.h" |
63 #include "ui/gfx/image/image.h" | 67 #include "ui/gfx/image/image.h" |
64 #include "ui/gfx/image/image_png_rep.h" | 68 #include "ui/gfx/image/image_png_rep.h" |
65 #include "ui/gfx/image/image_skia.h" | 69 #include "ui/gfx/image/image_skia.h" |
66 #include "ui/gfx/screen.h" | 70 #include "ui/gfx/screen.h" |
67 #include "ui/wm/public/drag_drop_client.h" | 71 #include "ui/wm/public/drag_drop_client.h" |
68 #include "ui/wm/public/drag_drop_delegate.h" | 72 #include "ui/wm/public/drag_drop_delegate.h" |
69 | 73 |
70 namespace content { | 74 namespace content { |
71 WebContentsView* CreateWebContentsView( | 75 WebContentsView* CreateWebContentsView( |
72 WebContentsImpl* web_contents, | 76 WebContentsImpl* web_contents, |
73 WebContentsViewDelegate* delegate, | 77 WebContentsViewDelegate* delegate, |
74 RenderViewHostDelegateView** render_view_host_delegate_view) { | 78 RenderViewHostDelegateView** render_view_host_delegate_view) { |
75 WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate); | 79 WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate); |
76 *render_view_host_delegate_view = rv; | 80 *render_view_host_delegate_view = rv; |
77 return rv; | 81 return rv; |
78 } | 82 } |
79 | 83 |
80 namespace { | 84 namespace { |
81 | 85 |
82 bool IsScrollEndEffectEnabled() { | 86 bool IsScrollEndEffectEnabled() { |
83 return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 87 return base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
84 switches::kScrollEndEffect) == "1"; | 88 switches::kScrollEndEffect) == "1"; |
85 } | 89 } |
86 | 90 |
| 91 bool ShouldNavigateForward(const NavigationController& controller, |
| 92 OverscrollMode mode) { |
| 93 return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) && |
| 94 controller.CanGoForward(); |
| 95 } |
| 96 |
| 97 bool ShouldNavigateBack(const NavigationController& controller, |
| 98 OverscrollMode mode) { |
| 99 return mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST) && |
| 100 controller.CanGoBack(); |
| 101 } |
| 102 |
87 RenderWidgetHostViewAura* ToRenderWidgetHostViewAura( | 103 RenderWidgetHostViewAura* ToRenderWidgetHostViewAura( |
88 RenderWidgetHostView* view) { | 104 RenderWidgetHostView* view) { |
89 if (!view || RenderViewHostFactory::has_factory()) | 105 if (!view || RenderViewHostFactory::has_factory()) |
90 return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests. | 106 return NULL; // Can't cast to RenderWidgetHostViewAura in unit tests. |
91 | 107 |
92 RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost()); | 108 RenderViewHost* rvh = RenderViewHost::From(view->GetRenderWidgetHost()); |
93 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( | 109 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( |
94 rvh ? WebContents::FromRenderViewHost(rvh) : NULL); | 110 rvh ? WebContents::FromRenderViewHost(rvh) : NULL); |
95 if (BrowserPluginGuest::IsGuest(web_contents)) | 111 if (BrowserPluginGuest::IsGuest(web_contents)) |
96 return NULL; | 112 return NULL; |
97 return static_cast<RenderWidgetHostViewAura*>(view); | 113 return static_cast<RenderWidgetHostViewAura*>(view); |
98 } | 114 } |
99 | 115 |
| 116 // The window delegate for the overscroll window. This redirects trackpad events |
| 117 // to the web-contents window. The delegate destroys itself when the window is |
| 118 // destroyed. |
| 119 class OverscrollWindowDelegate : public aura_extra::ImageWindowDelegate { |
| 120 public: |
| 121 OverscrollWindowDelegate(WebContentsImpl* web_contents, |
| 122 OverscrollMode overscroll_mode) |
| 123 : web_contents_(web_contents), |
| 124 forward_events_(true) { |
| 125 const NavigationControllerImpl& controller = web_contents->GetController(); |
| 126 const NavigationEntryImpl* entry = NULL; |
| 127 if (ShouldNavigateForward(controller, overscroll_mode)) { |
| 128 entry = controller.GetEntryAtOffset(1); |
| 129 } else if (ShouldNavigateBack(controller, overscroll_mode)) { |
| 130 entry = controller.GetEntryAtOffset(-1); |
| 131 } |
| 132 |
| 133 gfx::Image image; |
| 134 if (entry && entry->screenshot().get()) { |
| 135 std::vector<gfx::ImagePNGRep> image_reps; |
| 136 image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f)); |
| 137 image = gfx::Image(image_reps); |
| 138 } |
| 139 SetImage(image); |
| 140 } |
| 141 |
| 142 void stop_forwarding_events() { forward_events_ = false; } |
| 143 |
| 144 private: |
| 145 ~OverscrollWindowDelegate() override {} |
| 146 |
| 147 aura::Window* web_contents_window() { |
| 148 return web_contents_->GetView()->GetContentNativeView(); |
| 149 } |
| 150 |
| 151 // Overridden from ui::EventHandler. |
| 152 void OnScrollEvent(ui::ScrollEvent* event) override { |
| 153 if (forward_events_ && web_contents_window()) |
| 154 web_contents_window()->delegate()->OnScrollEvent(event); |
| 155 } |
| 156 |
| 157 void OnGestureEvent(ui::GestureEvent* event) override { |
| 158 if (forward_events_ && web_contents_window()) |
| 159 web_contents_window()->delegate()->OnGestureEvent(event); |
| 160 } |
| 161 |
| 162 WebContentsImpl* web_contents_; |
| 163 |
| 164 // The window is displayed both during the gesture, and after the gesture |
| 165 // while the navigation is in progress. During the gesture, it is necessary to |
| 166 // forward input events to the content page (e.g. when the overscroll window |
| 167 // slides under the cursor and starts receiving scroll events). However, once |
| 168 // the gesture is complete, and the window is being displayed as an overlay |
| 169 // window during navigation, events should not be forwarded anymore. |
| 170 bool forward_events_; |
| 171 |
| 172 DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate); |
| 173 }; |
| 174 |
100 // Listens to all mouse drag events during a drag and drop and sends them to | 175 // Listens to all mouse drag events during a drag and drop and sends them to |
101 // the renderer. | 176 // the renderer. |
102 class WebDragSourceAura : public NotificationObserver { | 177 class WebDragSourceAura : public NotificationObserver { |
103 public: | 178 public: |
104 WebDragSourceAura(aura::Window* window, WebContentsImpl* contents) | 179 WebDragSourceAura(aura::Window* window, WebContentsImpl* contents) |
105 : window_(window), | 180 : window_(window), |
106 contents_(contents) { | 181 contents_(contents) { |
107 registrar_.Add(this, | 182 registrar_.Add(this, |
108 NOTIFICATION_WEB_CONTENTS_DISCONNECTED, | 183 NOTIFICATION_WEB_CONTENTS_DISCONNECTED, |
109 Source<WebContents>(contents)); | 184 Source<WebContents>(contents)); |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 // The parent window that hosts the constrained windows. We cache the old host | 724 // The parent window that hosts the constrained windows. We cache the old host |
650 // view so that we can unregister when it's not the parent anymore. | 725 // view so that we can unregister when it's not the parent anymore. |
651 aura::Window* host_window_; | 726 aura::Window* host_window_; |
652 | 727 |
653 DISALLOW_COPY_AND_ASSIGN(WindowObserver); | 728 DISALLOW_COPY_AND_ASSIGN(WindowObserver); |
654 }; | 729 }; |
655 | 730 |
656 //////////////////////////////////////////////////////////////////////////////// | 731 //////////////////////////////////////////////////////////////////////////////// |
657 // WebContentsViewAura, public: | 732 // WebContentsViewAura, public: |
658 | 733 |
659 WebContentsViewAura::WebContentsViewAura(WebContentsImpl* web_contents, | 734 WebContentsViewAura::WebContentsViewAura( |
660 WebContentsViewDelegate* delegate) | 735 WebContentsImpl* web_contents, |
| 736 WebContentsViewDelegate* delegate) |
661 : web_contents_(web_contents), | 737 : web_contents_(web_contents), |
662 delegate_(delegate), | 738 delegate_(delegate), |
663 current_drag_op_(blink::WebDragOperationNone), | 739 current_drag_op_(blink::WebDragOperationNone), |
664 drag_dest_delegate_(NULL), | 740 drag_dest_delegate_(NULL), |
665 current_rvh_for_drag_(NULL), | 741 current_rvh_for_drag_(NULL), |
| 742 overscroll_change_brightness_(false), |
666 current_overscroll_gesture_(OVERSCROLL_NONE), | 743 current_overscroll_gesture_(OVERSCROLL_NONE), |
667 completed_overscroll_gesture_(OVERSCROLL_NONE), | 744 completed_overscroll_gesture_(OVERSCROLL_NONE), |
668 navigation_overlay_(nullptr), | |
669 touch_editable_(TouchEditableImplAura::Create()), | 745 touch_editable_(TouchEditableImplAura::Create()), |
670 is_or_was_visible_(false) { | 746 is_or_was_visible_(false) { |
671 } | 747 } |
672 | 748 |
673 //////////////////////////////////////////////////////////////////////////////// | 749 //////////////////////////////////////////////////////////////////////////////// |
674 // WebContentsViewAura, private: | 750 // WebContentsViewAura, private: |
675 | 751 |
676 WebContentsViewAura::~WebContentsViewAura() { | 752 WebContentsViewAura::~WebContentsViewAura() { |
677 if (!window_) | 753 if (!window_) |
678 return; | 754 return; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 return; | 799 return; |
724 } | 800 } |
725 if (value == "2") { | 801 if (value == "2") { |
726 navigation_overlay_.reset(); | 802 navigation_overlay_.reset(); |
727 if (!gesture_nav_simple_) | 803 if (!gesture_nav_simple_) |
728 gesture_nav_simple_.reset(new GestureNavSimple(web_contents_)); | 804 gesture_nav_simple_.reset(new GestureNavSimple(web_contents_)); |
729 view->overscroll_controller()->set_delegate(gesture_nav_simple_.get()); | 805 view->overscroll_controller()->set_delegate(gesture_nav_simple_.get()); |
730 return; | 806 return; |
731 } | 807 } |
732 view->overscroll_controller()->set_delegate(this); | 808 view->overscroll_controller()->set_delegate(this); |
733 if (!navigation_overlay_) { | 809 if (!navigation_overlay_) |
734 navigation_overlay_.reset( | 810 navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_)); |
735 new OverscrollNavigationOverlay(web_contents_, window_.get())); | 811 } |
| 812 |
| 813 void WebContentsViewAura::PrepareOverscrollWindow() { |
| 814 // If there is an existing |overscroll_window_| which is in the middle of an |
| 815 // animation, then destroying the window here causes the animation to be |
| 816 // completed immediately, which triggers |OnImplicitAnimationsCompleted()| |
| 817 // callback, and that tries to reset |overscroll_window_| again, causing a |
| 818 // double-free. So use a temporary variable here. |
| 819 if (overscroll_window_) { |
| 820 base::AutoReset<OverscrollMode> reset_state(¤t_overscroll_gesture_, |
| 821 current_overscroll_gesture_); |
| 822 scoped_ptr<aura::Window> reset_window(overscroll_window_.release()); |
| 823 } |
| 824 |
| 825 OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate( |
| 826 web_contents_, |
| 827 current_overscroll_gesture_); |
| 828 overscroll_window_.reset(new aura::Window(overscroll_delegate)); |
| 829 overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL); |
| 830 overscroll_window_->SetTransparent(true); |
| 831 overscroll_window_->Init(ui::LAYER_TEXTURED); |
| 832 overscroll_window_->layer()->SetMasksToBounds(false); |
| 833 overscroll_window_->SetName("OverscrollOverlay"); |
| 834 |
| 835 overscroll_change_brightness_ = overscroll_delegate->has_image(); |
| 836 window_->AddChild(overscroll_window_.get()); |
| 837 |
| 838 gfx::Rect bounds = gfx::Rect(window_->bounds().size()); |
| 839 if (ShouldNavigateForward(web_contents_->GetController(), |
| 840 current_overscroll_gesture_)) { |
| 841 // The overlay will be sliding in from the right edge towards the left in |
| 842 // non-RTL, or sliding in from the left edge towards the right in RTL. |
| 843 // So position the overlay window accordingly. |
| 844 bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0); |
| 845 } |
| 846 |
| 847 aura::Window* animate_window = GetWindowToAnimateForOverscroll(); |
| 848 if (animate_window == overscroll_window_) |
| 849 window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView()); |
| 850 else |
| 851 window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView()); |
| 852 |
| 853 UpdateOverscrollWindowBrightness(0.f); |
| 854 |
| 855 overscroll_window_->SetBounds(bounds); |
| 856 overscroll_window_->Show(); |
| 857 |
| 858 overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer())); |
| 859 } |
| 860 |
| 861 void WebContentsViewAura::PrepareContentWindowForOverscroll() { |
| 862 StopObservingImplicitAnimations(); |
| 863 aura::Window* content = GetContentNativeView(); |
| 864 content->layer()->GetAnimator()->AbortAllAnimations(); |
| 865 content->SetTransform(gfx::Transform()); |
| 866 content->layer()->SetLayerBrightness(0.f); |
| 867 } |
| 868 |
| 869 void WebContentsViewAura::ResetOverscrollTransform() { |
| 870 if (!web_contents_->GetRenderWidgetHostView()) |
| 871 return; |
| 872 aura::Window* target = GetWindowToAnimateForOverscroll(); |
| 873 if (!target) |
| 874 return; |
| 875 { |
| 876 ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); |
| 877 settings.SetPreemptionStrategy( |
| 878 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 879 settings.SetTweenType(gfx::Tween::EASE_OUT); |
| 880 settings.AddObserver(this); |
| 881 target->SetTransform(gfx::Transform()); |
| 882 } |
| 883 { |
| 884 ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); |
| 885 settings.SetPreemptionStrategy( |
| 886 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 887 settings.SetTweenType(gfx::Tween::EASE_OUT); |
| 888 UpdateOverscrollWindowBrightness(0.f); |
736 } | 889 } |
737 } | 890 } |
738 | 891 |
739 void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) { | 892 void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) { |
740 if (!web_contents_->GetRenderWidgetHostView()) | 893 if (!web_contents_->GetRenderWidgetHostView()) |
741 return; | 894 return; |
742 | 895 |
| 896 // Animate out the current view first. Navigate to the requested history at |
| 897 // the end of the animation. |
| 898 if (current_overscroll_gesture_ == OVERSCROLL_NONE) |
| 899 return; |
| 900 |
743 UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated", | 901 UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated", |
744 current_overscroll_gesture_, OVERSCROLL_COUNT); | 902 current_overscroll_gesture_, OVERSCROLL_COUNT); |
| 903 OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( |
| 904 overscroll_window_->delegate()); |
| 905 delegate->stop_forwarding_events(); |
745 | 906 |
746 navigation_overlay_->relay_delegate()->OnOverscrollComplete(mode); | 907 completed_overscroll_gesture_ = mode; |
| 908 aura::Window* target = GetWindowToAnimateForOverscroll(); |
| 909 ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); |
| 910 settings.SetPreemptionStrategy( |
| 911 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 912 settings.SetTweenType(gfx::Tween::EASE_OUT); |
| 913 settings.AddObserver(this); |
| 914 gfx::Transform transform; |
| 915 int content_width = |
| 916 web_contents_->GetRenderWidgetHostView()->GetViewBounds().width(); |
| 917 float translate_x = static_cast<float>(mode == OVERSCROLL_WEST ? |
| 918 -content_width : content_width); |
| 919 transform.Translate(translate_x, 0); |
| 920 target->SetTransform(transform); |
| 921 UpdateOverscrollWindowBrightness(translate_x); |
| 922 } |
| 923 |
| 924 aura::Window* WebContentsViewAura::GetWindowToAnimateForOverscroll() { |
| 925 if (current_overscroll_gesture_ == OVERSCROLL_NONE) |
| 926 return NULL; |
| 927 |
| 928 return ShouldNavigateForward(web_contents_->GetController(), |
| 929 current_overscroll_gesture_) ? |
| 930 overscroll_window_.get() : GetContentNativeView(); |
| 931 } |
| 932 |
| 933 gfx::Vector2dF WebContentsViewAura::GetTranslationForOverscroll(float delta_x, |
| 934 float delta_y) { |
| 935 if (current_overscroll_gesture_ == OVERSCROLL_NORTH || |
| 936 current_overscroll_gesture_ == OVERSCROLL_SOUTH) { |
| 937 return gfx::Vector2dF(0, delta_y); |
| 938 } |
| 939 // For horizontal overscroll, scroll freely if a navigation is possible. Do a |
| 940 // resistive scroll otherwise. |
| 941 const NavigationControllerImpl& controller = web_contents_->GetController(); |
| 942 const gfx::Rect& bounds = GetViewBounds(); |
| 943 const float bounds_width = static_cast<float>(bounds.width()); |
| 944 if (ShouldNavigateForward(controller, current_overscroll_gesture_)) |
| 945 return gfx::Vector2dF(std::max(-bounds_width, delta_x), 0); |
| 946 else if (ShouldNavigateBack(controller, current_overscroll_gesture_)) |
| 947 return gfx::Vector2dF(std::min(bounds_width, delta_x), 0); |
| 948 return gfx::Vector2dF(); |
| 949 } |
| 950 |
| 951 void WebContentsViewAura::PrepareOverscrollNavigationOverlay() { |
| 952 OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( |
| 953 overscroll_window_->delegate()); |
| 954 overscroll_window_->SchedulePaintInRect( |
| 955 gfx::Rect(overscroll_window_->bounds().size())); |
| 956 overscroll_window_->SetBounds(gfx::Rect(window_->bounds().size())); |
| 957 overscroll_window_->SetTransform(gfx::Transform()); |
| 958 navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(), |
| 959 delegate); |
| 960 navigation_overlay_->StartObserving(); |
| 961 } |
| 962 |
| 963 void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) { |
| 964 if (!overscroll_change_brightness_) |
| 965 return; |
| 966 |
| 967 const float kBrightnessMin = -.1f; |
| 968 const float kBrightnessMax = -.01f; |
| 969 |
| 970 float ratio = fabs(delta_x) / GetViewBounds().width(); |
| 971 ratio = std::min(1.f, ratio); |
| 972 if (base::i18n::IsRTL()) |
| 973 ratio = 1.f - ratio; |
| 974 float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ? |
| 975 kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) : |
| 976 kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin); |
| 977 brightness = std::max(kBrightnessMin, brightness); |
| 978 brightness = std::min(kBrightnessMax, brightness); |
| 979 aura::Window* window = GetWindowToAnimateForOverscroll(); |
| 980 window->layer()->SetLayerBrightness(brightness); |
747 } | 981 } |
748 | 982 |
749 void WebContentsViewAura::AttachTouchEditableToRenderView() { | 983 void WebContentsViewAura::AttachTouchEditableToRenderView() { |
750 if (!touch_editable_) | 984 if (!touch_editable_) |
751 return; | 985 return; |
752 RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura( | 986 RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura( |
753 web_contents_->GetRenderWidgetHostView()); | 987 web_contents_->GetRenderWidgetHostView()); |
754 touch_editable_->AttachToView(rwhva); | 988 touch_editable_->AttachToView(rwhva); |
755 } | 989 } |
756 | 990 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
895 DCHECK(RenderViewHostFactory::has_factory()); | 1129 DCHECK(RenderViewHostFactory::has_factory()); |
896 return static_cast<RenderWidgetHostViewBase*>( | 1130 return static_cast<RenderWidgetHostViewBase*>( |
897 render_widget_host->GetView()); | 1131 render_widget_host->GetView()); |
898 } | 1132 } |
899 | 1133 |
900 RenderWidgetHostViewAura* view = | 1134 RenderWidgetHostViewAura* view = |
901 new RenderWidgetHostViewAura(render_widget_host, is_guest_view_hack); | 1135 new RenderWidgetHostViewAura(render_widget_host, is_guest_view_hack); |
902 view->InitAsChild(NULL); | 1136 view->InitAsChild(NULL); |
903 GetNativeView()->AddChild(view->GetNativeView()); | 1137 GetNativeView()->AddChild(view->GetNativeView()); |
904 | 1138 |
| 1139 if (navigation_overlay_.get() && navigation_overlay_->has_window()) { |
| 1140 navigation_overlay_->StartObserving(); |
| 1141 } |
| 1142 |
905 RenderWidgetHostImpl* host_impl = | 1143 RenderWidgetHostImpl* host_impl = |
906 RenderWidgetHostImpl::From(render_widget_host); | 1144 RenderWidgetHostImpl::From(render_widget_host); |
907 | 1145 |
908 if (!host_impl->is_hidden()) | 1146 if (!host_impl->is_hidden()) |
909 view->Show(); | 1147 view->Show(); |
910 | 1148 |
911 // We listen to drag drop events in the newly created view's window. | 1149 // We listen to drag drop events in the newly created view's window. |
912 aura::client::SetDragDropDelegate(view->GetNativeView(), this); | 1150 aura::client::SetDragDropDelegate(view->GetNativeView(), this); |
913 | 1151 |
914 if (view->overscroll_controller() && | 1152 if (view->overscroll_controller() && |
(...skipping 12 matching lines...) Expand all Loading... |
927 } | 1165 } |
928 | 1166 |
929 void WebContentsViewAura::SetPageTitle(const base::string16& title) { | 1167 void WebContentsViewAura::SetPageTitle(const base::string16& title) { |
930 window_->SetTitle(title); | 1168 window_->SetTitle(title); |
931 } | 1169 } |
932 | 1170 |
933 void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) { | 1171 void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) { |
934 } | 1172 } |
935 | 1173 |
936 void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) { | 1174 void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) { |
| 1175 if (navigation_overlay_.get() && navigation_overlay_->has_window()) |
| 1176 navigation_overlay_->StartObserving(); |
937 AttachTouchEditableToRenderView(); | 1177 AttachTouchEditableToRenderView(); |
938 } | 1178 } |
939 | 1179 |
940 void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) { | 1180 void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) { |
941 RenderWidgetHostViewAura* view = | 1181 RenderWidgetHostViewAura* view = |
942 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView()); | 1182 ToRenderWidgetHostViewAura(web_contents_->GetRenderWidgetHostView()); |
943 if (view) { | 1183 if (view) { |
944 view->SetOverscrollControllerEnabled(enabled); | 1184 view->SetOverscrollControllerEnabled(enabled); |
945 if (enabled) | 1185 if (enabled) |
946 InstallOverscrollControllerDelegate(view); | 1186 InstallOverscrollControllerDelegate(view); |
947 } | 1187 } |
948 | 1188 |
949 if (!enabled) | 1189 if (!enabled) |
950 navigation_overlay_.reset(); | 1190 navigation_overlay_.reset(); |
951 if (!navigation_overlay_) { | 1191 else if (!navigation_overlay_) |
952 navigation_overlay_.reset( | 1192 navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_)); |
953 new OverscrollNavigationOverlay(web_contents_, window_.get())); | |
954 } | |
955 } | 1193 } |
956 | 1194 |
957 //////////////////////////////////////////////////////////////////////////////// | 1195 //////////////////////////////////////////////////////////////////////////////// |
958 // WebContentsViewAura, RenderViewHostDelegateView implementation: | 1196 // WebContentsViewAura, RenderViewHostDelegateView implementation: |
959 | 1197 |
960 void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host, | 1198 void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host, |
961 const ContextMenuParams& params) { | 1199 const ContextMenuParams& params) { |
962 if (touch_editable_) { | 1200 if (touch_editable_) { |
963 touch_editable_->EndTouchEditing(false); | 1201 touch_editable_->EndTouchEditing(false); |
964 } | 1202 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1070 if (!rwhv || !rwhv->IsShowing()) | 1308 if (!rwhv || !rwhv->IsShowing()) |
1071 return gfx::Rect(); | 1309 return gfx::Rect(); |
1072 | 1310 |
1073 return rwhv->GetViewBounds(); | 1311 return rwhv->GetViewBounds(); |
1074 } | 1312 } |
1075 | 1313 |
1076 bool WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) { | 1314 bool WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) { |
1077 if (current_overscroll_gesture_ == OVERSCROLL_NONE) | 1315 if (current_overscroll_gesture_ == OVERSCROLL_NONE) |
1078 return false; | 1316 return false; |
1079 | 1317 |
| 1318 aura::Window* target = GetWindowToAnimateForOverscroll(); |
| 1319 gfx::Vector2dF translate = GetTranslationForOverscroll(delta_x, delta_y); |
| 1320 gfx::Transform transform; |
| 1321 |
1080 if (current_overscroll_gesture_ == OVERSCROLL_NORTH || | 1322 if (current_overscroll_gesture_ == OVERSCROLL_NORTH || |
1081 current_overscroll_gesture_ == OVERSCROLL_SOUTH) { | 1323 current_overscroll_gesture_ == OVERSCROLL_SOUTH) { |
1082 OverscrollUpdateForWebContentsDelegate(delta_y); | 1324 OverscrollUpdateForWebContentsDelegate(translate.y()); |
1083 return delta_y != 0; | 1325 } else { |
| 1326 // Only horizontal overscrolls participate in the navigation gesture. |
| 1327 transform.Translate(translate.x(), translate.y()); |
| 1328 target->SetTransform(transform); |
| 1329 UpdateOverscrollWindowBrightness(delta_x); |
1084 } | 1330 } |
1085 return navigation_overlay_->relay_delegate()->OnOverscrollUpdate(delta_x, | 1331 |
1086 delta_y); | 1332 return !translate.IsZero(); |
1087 } | 1333 } |
1088 | 1334 |
1089 void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) { | 1335 void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) { |
1090 UMA_HISTOGRAM_ENUMERATION("Overscroll.Completed", mode, OVERSCROLL_COUNT); | 1336 UMA_HISTOGRAM_ENUMERATION("Overscroll.Completed", mode, OVERSCROLL_COUNT); |
1091 if (web_contents_->GetDelegate() && | 1337 if (web_contents_->GetDelegate() && |
1092 IsScrollEndEffectEnabled() && | 1338 IsScrollEndEffectEnabled() && |
1093 (mode == OVERSCROLL_NORTH || mode == OVERSCROLL_SOUTH)) { | 1339 (mode == OVERSCROLL_NORTH || mode == OVERSCROLL_SOUTH)) { |
1094 web_contents_->GetDelegate()->OverscrollComplete(); | 1340 web_contents_->GetDelegate()->OverscrollComplete(); |
1095 } | 1341 } |
1096 CompleteOverscrollNavigation(mode); | 1342 NavigationControllerImpl& controller = web_contents_->GetController(); |
| 1343 if (ShouldNavigateForward(controller, mode) || |
| 1344 ShouldNavigateBack(controller, mode)) { |
| 1345 CompleteOverscrollNavigation(mode); |
| 1346 return; |
| 1347 } |
| 1348 |
| 1349 ResetOverscrollTransform(); |
1097 } | 1350 } |
1098 | 1351 |
1099 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, | 1352 void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, |
1100 OverscrollMode new_mode) { | 1353 OverscrollMode new_mode) { |
| 1354 // Reset any in-progress overscroll animation first. |
| 1355 ResetOverscrollTransform(); |
| 1356 |
1101 if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH) | 1357 if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH) |
1102 OverscrollUpdateForWebContentsDelegate(0); | 1358 OverscrollUpdateForWebContentsDelegate(0); |
1103 | 1359 |
1104 if (new_mode != OVERSCROLL_NONE && touch_editable_) | 1360 if (new_mode != OVERSCROLL_NONE && touch_editable_) |
1105 touch_editable_->OverscrollStarted(); | 1361 touch_editable_->OverscrollStarted(); |
1106 | 1362 |
1107 if (current_overscroll_gesture_ == OVERSCROLL_NONE && | 1363 if (new_mode == OVERSCROLL_NONE || |
1108 new_mode != OVERSCROLL_NONE) { | 1364 !GetContentNativeView() || |
| 1365 ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) && |
| 1366 navigation_overlay_.get() && navigation_overlay_->has_window())) { |
| 1367 current_overscroll_gesture_ = OVERSCROLL_NONE; |
| 1368 } else { |
| 1369 aura::Window* target = GetWindowToAnimateForOverscroll(); |
| 1370 if (target) { |
| 1371 StopObservingImplicitAnimations(); |
| 1372 target->layer()->GetAnimator()->AbortAllAnimations(); |
| 1373 } |
| 1374 // Cleanup state of the content window first, because that can reset the |
| 1375 // value of |current_overscroll_gesture_|. |
| 1376 PrepareContentWindowForOverscroll(); |
| 1377 |
| 1378 current_overscroll_gesture_ = new_mode; |
| 1379 if (current_overscroll_gesture_ == OVERSCROLL_EAST || |
| 1380 current_overscroll_gesture_ == OVERSCROLL_WEST) |
| 1381 PrepareOverscrollWindow(); |
| 1382 |
1109 UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT); | 1383 UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT); |
1110 } | 1384 } |
1111 current_overscroll_gesture_ = new_mode; | |
1112 navigation_overlay_->relay_delegate()->OnOverscrollModeChange(old_mode, | |
1113 new_mode); | |
1114 completed_overscroll_gesture_ = OVERSCROLL_NONE; | 1385 completed_overscroll_gesture_ = OVERSCROLL_NONE; |
1115 } | 1386 } |
1116 | 1387 |
1117 //////////////////////////////////////////////////////////////////////////////// | 1388 //////////////////////////////////////////////////////////////////////////////// |
| 1389 // WebContentsViewAura, ui::ImplicitAnimationObserver implementation: |
| 1390 |
| 1391 void WebContentsViewAura::OnImplicitAnimationsCompleted() { |
| 1392 overscroll_shadow_.reset(); |
| 1393 |
| 1394 if (ShouldNavigateForward(web_contents_->GetController(), |
| 1395 completed_overscroll_gesture_)) { |
| 1396 web_contents_->GetController().GoForward(); |
| 1397 PrepareOverscrollNavigationOverlay(); |
| 1398 } else if (ShouldNavigateBack(web_contents_->GetController(), |
| 1399 completed_overscroll_gesture_)) { |
| 1400 web_contents_->GetController().GoBack(); |
| 1401 PrepareOverscrollNavigationOverlay(); |
| 1402 } else { |
| 1403 if (touch_editable_) |
| 1404 touch_editable_->OverscrollCompleted(); |
| 1405 } |
| 1406 |
| 1407 aura::Window* content = GetContentNativeView(); |
| 1408 if (content) { |
| 1409 content->SetTransform(gfx::Transform()); |
| 1410 content->layer()->SetLayerBrightness(0.f); |
| 1411 } |
| 1412 current_overscroll_gesture_ = OVERSCROLL_NONE; |
| 1413 completed_overscroll_gesture_ = OVERSCROLL_NONE; |
| 1414 overscroll_window_.reset(); |
| 1415 } |
| 1416 |
| 1417 //////////////////////////////////////////////////////////////////////////////// |
1118 // WebContentsViewAura, aura::WindowDelegate implementation: | 1418 // WebContentsViewAura, aura::WindowDelegate implementation: |
1119 | 1419 |
1120 gfx::Size WebContentsViewAura::GetMinimumSize() const { | 1420 gfx::Size WebContentsViewAura::GetMinimumSize() const { |
1121 return gfx::Size(); | 1421 return gfx::Size(); |
1122 } | 1422 } |
1123 | 1423 |
1124 gfx::Size WebContentsViewAura::GetMaximumSize() const { | 1424 gfx::Size WebContentsViewAura::GetMaximumSize() const { |
1125 return gfx::Size(); | 1425 return gfx::Size(); |
1126 } | 1426 } |
1127 | 1427 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 float device_scale_factor) { | 1484 float device_scale_factor) { |
1185 } | 1485 } |
1186 | 1486 |
1187 void WebContentsViewAura::OnWindowDestroying(aura::Window* window) { | 1487 void WebContentsViewAura::OnWindowDestroying(aura::Window* window) { |
1188 // This means the destructor is going to be called soon. If there is an | 1488 // This means the destructor is going to be called soon. If there is an |
1189 // overscroll gesture in progress (i.e. |overscroll_window_| is not NULL), | 1489 // overscroll gesture in progress (i.e. |overscroll_window_| is not NULL), |
1190 // then destroying it in the WebContentsViewAura destructor can trigger other | 1490 // then destroying it in the WebContentsViewAura destructor can trigger other |
1191 // virtual functions to be called (e.g. OnImplicitAnimationsCompleted()). So | 1491 // virtual functions to be called (e.g. OnImplicitAnimationsCompleted()). So |
1192 // destroy the overscroll window here. | 1492 // destroy the overscroll window here. |
1193 navigation_overlay_.reset(); | 1493 navigation_overlay_.reset(); |
| 1494 overscroll_window_.reset(); |
1194 } | 1495 } |
1195 | 1496 |
1196 void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) { | 1497 void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) { |
1197 } | 1498 } |
1198 | 1499 |
1199 void WebContentsViewAura::OnWindowTargetVisibilityChanged(bool visible) { | 1500 void WebContentsViewAura::OnWindowTargetVisibilityChanged(bool visible) { |
1200 } | 1501 } |
1201 | 1502 |
1202 bool WebContentsViewAura::HasHitTestMask() const { | 1503 bool WebContentsViewAura::HasHitTestMask() const { |
1203 return false; | 1504 return false; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1345 if (visible) { | 1646 if (visible) { |
1346 if (!web_contents_->should_normally_be_visible()) | 1647 if (!web_contents_->should_normally_be_visible()) |
1347 web_contents_->WasShown(); | 1648 web_contents_->WasShown(); |
1348 } else { | 1649 } else { |
1349 if (web_contents_->should_normally_be_visible()) | 1650 if (web_contents_->should_normally_be_visible()) |
1350 web_contents_->WasHidden(); | 1651 web_contents_->WasHidden(); |
1351 } | 1652 } |
1352 } | 1653 } |
1353 | 1654 |
1354 } // namespace content | 1655 } // namespace content |
OLD | NEW |