Chromium Code Reviews| Index: content/browser/web_contents/web_contents_view_aura.cc |
| diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc |
| index 68e28b305701b2912c29cc1f56e1018a1799c0b0..cd8ac266e2ab9c37286537cabd67a7074597bf44 100644 |
| --- a/content/browser/web_contents/web_contents_view_aura.cc |
| +++ b/content/browser/web_contents/web_contents_view_aura.cc |
| @@ -22,8 +22,7 @@ |
| #include "content/browser/renderer_host/web_input_event_aura.h" |
| #include "content/browser/web_contents/aura/gesture_nav_simple.h" |
| #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" |
| -#include "content/browser/web_contents/aura/shadow_layer_delegate.h" |
| -#include "content/browser/web_contents/aura/window_slider.h" |
| +#include "content/browser/web_contents/aura/overscroll_window_animation.h" |
| #include "content/browser/web_contents/touch_editable_impl_aura.h" |
| #include "content/browser/web_contents/web_contents_impl.h" |
| #include "content/public/browser/content_browser_client.h" |
| @@ -51,7 +50,6 @@ |
| #include "ui/aura/window_observer.h" |
| #include "ui/aura/window_tree_host.h" |
| #include "ui/aura/window_tree_host_observer.h" |
| -#include "ui/aura_extra/image_window_delegate.h" |
| #include "ui/base/clipboard/clipboard.h" |
| #include "ui/base/clipboard/custom_data_helper.h" |
| #include "ui/base/dragdrop/drag_drop_types.h" |
| @@ -60,7 +58,6 @@ |
| #include "ui/base/dragdrop/os_exchange_data.h" |
| #include "ui/base/hit_test.h" |
| #include "ui/compositor/layer.h" |
| -#include "ui/compositor/scoped_layer_animation_settings.h" |
| #include "ui/events/event.h" |
| #include "ui/events/event_utils.h" |
| #include "ui/gfx/canvas.h" |
| @@ -88,18 +85,6 @@ bool IsScrollEndEffectEnabled() { |
| switches::kScrollEndEffect) == "1"; |
| } |
| -bool ShouldNavigateForward(const NavigationController& controller, |
| - OverscrollMode mode) { |
| - return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) && |
| - controller.CanGoForward(); |
| -} |
| - |
| -bool ShouldNavigateBack(const NavigationController& controller, |
| - OverscrollMode mode) { |
| - return mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST) && |
| - controller.CanGoBack(); |
| -} |
| - |
| RenderWidgetHostViewAura* ToRenderWidgetHostViewAura( |
| RenderWidgetHostView* view) { |
| if (!view || RenderViewHostFactory::has_factory()) |
| @@ -113,65 +98,6 @@ RenderWidgetHostViewAura* ToRenderWidgetHostViewAura( |
| return static_cast<RenderWidgetHostViewAura*>(view); |
| } |
| -// The window delegate for the overscroll window. This redirects trackpad events |
| -// to the web-contents window. The delegate destroys itself when the window is |
| -// destroyed. |
| -class OverscrollWindowDelegate : public aura_extra::ImageWindowDelegate { |
| - public: |
| - OverscrollWindowDelegate(WebContentsImpl* web_contents, |
| - OverscrollMode overscroll_mode) |
| - : web_contents_(web_contents), |
| - forward_events_(true) { |
| - const NavigationControllerImpl& controller = web_contents->GetController(); |
| - const NavigationEntryImpl* entry = NULL; |
| - if (ShouldNavigateForward(controller, overscroll_mode)) { |
| - entry = controller.GetEntryAtOffset(1); |
| - } else if (ShouldNavigateBack(controller, overscroll_mode)) { |
| - entry = controller.GetEntryAtOffset(-1); |
| - } |
| - |
| - gfx::Image image; |
| - if (entry && entry->screenshot().get()) { |
| - std::vector<gfx::ImagePNGRep> image_reps; |
| - image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(), 1.0f)); |
| - image = gfx::Image(image_reps); |
| - } |
| - SetImage(image); |
| - } |
| - |
| - void stop_forwarding_events() { forward_events_ = false; } |
| - |
| - private: |
| - ~OverscrollWindowDelegate() override {} |
| - |
| - aura::Window* web_contents_window() { |
| - return web_contents_->GetView()->GetContentNativeView(); |
| - } |
| - |
| - // Overridden from ui::EventHandler. |
| - void OnScrollEvent(ui::ScrollEvent* event) override { |
| - if (forward_events_ && web_contents_window()) |
| - web_contents_window()->delegate()->OnScrollEvent(event); |
| - } |
| - |
| - void OnGestureEvent(ui::GestureEvent* event) override { |
| - if (forward_events_ && web_contents_window()) |
| - web_contents_window()->delegate()->OnGestureEvent(event); |
| - } |
| - |
| - WebContentsImpl* web_contents_; |
| - |
| - // The window is displayed both during the gesture, and after the gesture |
| - // while the navigation is in progress. During the gesture, it is necessary to |
| - // forward input events to the content page (e.g. when the overscroll window |
| - // slides under the cursor and starts receiving scroll events). However, once |
| - // the gesture is complete, and the window is being displayed as an overlay |
| - // window during navigation, events should not be forwarded anymore. |
| - bool forward_events_; |
| - |
| - DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate); |
| -}; |
| - |
| // Listens to all mouse drag events during a drag and drop and sends them to |
| // the renderer. |
| class WebDragSourceAura : public NotificationObserver { |
| @@ -731,17 +657,17 @@ class WebContentsViewAura::WindowObserver |
| //////////////////////////////////////////////////////////////////////////////// |
| // WebContentsViewAura, public: |
| -WebContentsViewAura::WebContentsViewAura( |
| - WebContentsImpl* web_contents, |
| - WebContentsViewDelegate* delegate) |
| +WebContentsViewAura::WebContentsViewAura(WebContentsImpl* web_contents, |
| + WebContentsViewDelegate* delegate) |
| : web_contents_(web_contents), |
| delegate_(delegate), |
| current_drag_op_(blink::WebDragOperationNone), |
| drag_dest_delegate_(NULL), |
| current_rvh_for_drag_(NULL), |
| - overscroll_change_brightness_(false), |
| current_overscroll_gesture_(OVERSCROLL_NONE), |
| completed_overscroll_gesture_(OVERSCROLL_NONE), |
| + navigation_overlay_(nullptr), |
| + overscroll_window_animation_(nullptr), |
| touch_editable_(TouchEditableImplAura::Create()), |
| is_or_was_visible_(false) { |
| } |
| @@ -796,6 +722,7 @@ void WebContentsViewAura::InstallOverscrollControllerDelegate( |
| GetSwitchValueASCII(switches::kOverscrollHistoryNavigation); |
| if (value == "0") { |
| navigation_overlay_.reset(); |
| + overscroll_window_animation_ = nullptr; |
| return; |
| } |
| if (value == "2") { |
| @@ -806,86 +733,10 @@ void WebContentsViewAura::InstallOverscrollControllerDelegate( |
| return; |
| } |
| view->overscroll_controller()->set_delegate(this); |
| - if (!navigation_overlay_) |
| - navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_)); |
| -} |
| - |
| -void WebContentsViewAura::PrepareOverscrollWindow() { |
| - // If there is an existing |overscroll_window_| which is in the middle of an |
| - // animation, then destroying the window here causes the animation to be |
| - // completed immediately, which triggers |OnImplicitAnimationsCompleted()| |
| - // callback, and that tries to reset |overscroll_window_| again, causing a |
| - // double-free. So use a temporary variable here. |
| - if (overscroll_window_) { |
| - base::AutoReset<OverscrollMode> reset_state(¤t_overscroll_gesture_, |
| - current_overscroll_gesture_); |
| - scoped_ptr<aura::Window> reset_window(overscroll_window_.release()); |
| - } |
| - |
| - OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate( |
| - web_contents_, |
| - current_overscroll_gesture_); |
| - overscroll_window_.reset(new aura::Window(overscroll_delegate)); |
| - overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL); |
| - overscroll_window_->SetTransparent(true); |
| - overscroll_window_->Init(ui::LAYER_TEXTURED); |
| - overscroll_window_->layer()->SetMasksToBounds(false); |
| - overscroll_window_->SetName("OverscrollOverlay"); |
| - |
| - overscroll_change_brightness_ = overscroll_delegate->has_image(); |
| - window_->AddChild(overscroll_window_.get()); |
| - |
| - gfx::Rect bounds = gfx::Rect(window_->bounds().size()); |
| - if (ShouldNavigateForward(web_contents_->GetController(), |
| - current_overscroll_gesture_)) { |
| - // The overlay will be sliding in from the right edge towards the left in |
| - // non-RTL, or sliding in from the left edge towards the right in RTL. |
| - // So position the overlay window accordingly. |
| - bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0); |
| - } |
| - |
| - aura::Window* animate_window = GetWindowToAnimateForOverscroll(); |
| - if (animate_window == overscroll_window_) |
| - window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView()); |
| - else |
| - window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView()); |
| - |
| - UpdateOverscrollWindowBrightness(0.f); |
| - |
| - overscroll_window_->SetBounds(bounds); |
| - overscroll_window_->Show(); |
| - |
| - overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer())); |
| -} |
| - |
| -void WebContentsViewAura::PrepareContentWindowForOverscroll() { |
| - StopObservingImplicitAnimations(); |
| - aura::Window* content = GetContentNativeView(); |
| - content->layer()->GetAnimator()->AbortAllAnimations(); |
| - content->SetTransform(gfx::Transform()); |
| - content->layer()->SetLayerBrightness(0.f); |
| -} |
| - |
| -void WebContentsViewAura::ResetOverscrollTransform() { |
| - if (!web_contents_->GetRenderWidgetHostView()) |
| - return; |
| - aura::Window* target = GetWindowToAnimateForOverscroll(); |
| - if (!target) |
| - return; |
| - { |
| - ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); |
| - settings.SetPreemptionStrategy( |
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| - settings.SetTweenType(gfx::Tween::EASE_OUT); |
| - settings.AddObserver(this); |
| - target->SetTransform(gfx::Transform()); |
| - } |
| - { |
| - ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); |
| - settings.SetPreemptionStrategy( |
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| - settings.SetTweenType(gfx::Tween::EASE_OUT); |
| - UpdateOverscrollWindowBrightness(0.f); |
| + if (!navigation_overlay_) { |
| + navigation_overlay_.reset( |
| + new OverscrollNavigationOverlay(web_contents_, window_.get())); |
| + overscroll_window_animation_ = navigation_overlay_->owa(); |
| } |
| } |
| @@ -893,91 +744,10 @@ void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) { |
| if (!web_contents_->GetRenderWidgetHostView()) |
| return; |
| - // Animate out the current view first. Navigate to the requested history at |
| - // the end of the animation. |
| - if (current_overscroll_gesture_ == OVERSCROLL_NONE) |
| - return; |
| - |
| UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated", |
| current_overscroll_gesture_, OVERSCROLL_COUNT); |
| - OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( |
| - overscroll_window_->delegate()); |
| - delegate->stop_forwarding_events(); |
| - |
| - completed_overscroll_gesture_ = mode; |
| - aura::Window* target = GetWindowToAnimateForOverscroll(); |
| - ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator()); |
| - settings.SetPreemptionStrategy( |
| - ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| - settings.SetTweenType(gfx::Tween::EASE_OUT); |
| - settings.AddObserver(this); |
| - gfx::Transform transform; |
| - int content_width = |
| - web_contents_->GetRenderWidgetHostView()->GetViewBounds().width(); |
| - float translate_x = static_cast<float>(mode == OVERSCROLL_WEST ? |
| - -content_width : content_width); |
| - transform.Translate(translate_x, 0); |
| - target->SetTransform(transform); |
| - UpdateOverscrollWindowBrightness(translate_x); |
| -} |
| - |
| -aura::Window* WebContentsViewAura::GetWindowToAnimateForOverscroll() { |
| - if (current_overscroll_gesture_ == OVERSCROLL_NONE) |
| - return NULL; |
| - |
| - return ShouldNavigateForward(web_contents_->GetController(), |
| - current_overscroll_gesture_) ? |
| - overscroll_window_.get() : GetContentNativeView(); |
| -} |
| -gfx::Vector2dF WebContentsViewAura::GetTranslationForOverscroll(float delta_x, |
| - float delta_y) { |
| - if (current_overscroll_gesture_ == OVERSCROLL_NORTH || |
| - current_overscroll_gesture_ == OVERSCROLL_SOUTH) { |
| - return gfx::Vector2dF(0, delta_y); |
| - } |
| - // For horizontal overscroll, scroll freely if a navigation is possible. Do a |
| - // resistive scroll otherwise. |
| - const NavigationControllerImpl& controller = web_contents_->GetController(); |
| - const gfx::Rect& bounds = GetViewBounds(); |
| - const float bounds_width = static_cast<float>(bounds.width()); |
| - if (ShouldNavigateForward(controller, current_overscroll_gesture_)) |
| - return gfx::Vector2dF(std::max(-bounds_width, delta_x), 0); |
| - else if (ShouldNavigateBack(controller, current_overscroll_gesture_)) |
| - return gfx::Vector2dF(std::min(bounds_width, delta_x), 0); |
| - return gfx::Vector2dF(); |
| -} |
| - |
| -void WebContentsViewAura::PrepareOverscrollNavigationOverlay() { |
| - OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>( |
| - overscroll_window_->delegate()); |
| - overscroll_window_->SchedulePaintInRect( |
| - gfx::Rect(overscroll_window_->bounds().size())); |
| - overscroll_window_->SetBounds(gfx::Rect(window_->bounds().size())); |
| - overscroll_window_->SetTransform(gfx::Transform()); |
| - navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(), |
| - delegate); |
| - navigation_overlay_->StartObserving(); |
| -} |
| - |
| -void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) { |
| - if (!overscroll_change_brightness_) |
| - return; |
| - |
| - const float kBrightnessMin = -.1f; |
| - const float kBrightnessMax = -.01f; |
| - |
| - float ratio = fabs(delta_x) / GetViewBounds().width(); |
| - ratio = std::min(1.f, ratio); |
| - if (base::i18n::IsRTL()) |
| - ratio = 1.f - ratio; |
| - float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ? |
| - kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) : |
| - kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin); |
| - brightness = std::max(kBrightnessMin, brightness); |
| - brightness = std::min(kBrightnessMax, brightness); |
| - aura::Window* window = GetWindowToAnimateForOverscroll(); |
| - window->layer()->SetLayerBrightness(brightness); |
| + overscroll_window_animation_->OnOverscrollComplete(mode); |
| } |
| void WebContentsViewAura::AttachTouchEditableToRenderView() { |
| @@ -1136,10 +906,6 @@ RenderWidgetHostViewBase* WebContentsViewAura::CreateViewForWidget( |
| view->InitAsChild(NULL); |
| GetNativeView()->AddChild(view->GetNativeView()); |
| - if (navigation_overlay_.get() && navigation_overlay_->has_window()) { |
| - navigation_overlay_->StartObserving(); |
| - } |
| - |
| RenderWidgetHostImpl* host_impl = |
| RenderWidgetHostImpl::From(render_widget_host); |
| @@ -1172,8 +938,6 @@ void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) { |
| } |
| void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) { |
| - if (navigation_overlay_.get() && navigation_overlay_->has_window()) |
| - navigation_overlay_->StartObserving(); |
| AttachTouchEditableToRenderView(); |
| } |
| @@ -1186,10 +950,15 @@ void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) { |
| InstallOverscrollControllerDelegate(view); |
| } |
| - if (!enabled) |
| + if (!enabled) { |
| navigation_overlay_.reset(); |
| - else if (!navigation_overlay_) |
| - navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_)); |
| + overscroll_window_animation_ = nullptr; |
| + } |
| + if (!navigation_overlay_) { |
| + navigation_overlay_.reset( |
| + new OverscrollNavigationOverlay(web_contents_, window_.get())); |
| + overscroll_window_animation_ = navigation_overlay_->owa(); |
| + } |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -1315,21 +1084,12 @@ bool WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) { |
| if (current_overscroll_gesture_ == OVERSCROLL_NONE) |
| return false; |
| - aura::Window* target = GetWindowToAnimateForOverscroll(); |
| - gfx::Vector2dF translate = GetTranslationForOverscroll(delta_x, delta_y); |
| - gfx::Transform transform; |
| - |
| if (current_overscroll_gesture_ == OVERSCROLL_NORTH || |
| current_overscroll_gesture_ == OVERSCROLL_SOUTH) { |
| - OverscrollUpdateForWebContentsDelegate(translate.y()); |
| - } else { |
| - // Only horizontal overscrolls participate in the navigation gesture. |
| - transform.Translate(translate.x(), translate.y()); |
| - target->SetTransform(transform); |
| - UpdateOverscrollWindowBrightness(delta_x); |
| + OverscrollUpdateForWebContentsDelegate(delta_y); |
| + return delta_y != 0; |
| } |
| - |
| - return !translate.IsZero(); |
| + return overscroll_window_animation_->OnOverscrollUpdate(delta_x, delta_y); |
| } |
| void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) { |
| @@ -1339,82 +1099,27 @@ void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) { |
| (mode == OVERSCROLL_NORTH || mode == OVERSCROLL_SOUTH)) { |
| web_contents_->GetDelegate()->OverscrollComplete(); |
| } |
| - NavigationControllerImpl& controller = web_contents_->GetController(); |
| - if (ShouldNavigateForward(controller, mode) || |
| - ShouldNavigateBack(controller, mode)) { |
| - CompleteOverscrollNavigation(mode); |
| - return; |
| - } |
| - |
| - ResetOverscrollTransform(); |
| + CompleteOverscrollNavigation(mode); |
| } |
| void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode, |
| OverscrollMode new_mode) { |
| - // Reset any in-progress overscroll animation first. |
| - ResetOverscrollTransform(); |
| - |
| if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH) |
| OverscrollUpdateForWebContentsDelegate(0); |
| if (new_mode != OVERSCROLL_NONE && touch_editable_) |
| touch_editable_->OverscrollStarted(); |
| - if (new_mode == OVERSCROLL_NONE || |
| - !GetContentNativeView() || |
| - ((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) && |
| - navigation_overlay_.get() && navigation_overlay_->has_window())) { |
| - current_overscroll_gesture_ = OVERSCROLL_NONE; |
| - } else { |
| - aura::Window* target = GetWindowToAnimateForOverscroll(); |
| - if (target) { |
| - StopObservingImplicitAnimations(); |
| - target->layer()->GetAnimator()->AbortAllAnimations(); |
| - } |
| - // Cleanup state of the content window first, because that can reset the |
| - // value of |current_overscroll_gesture_|. |
| - PrepareContentWindowForOverscroll(); |
| - |
| - current_overscroll_gesture_ = new_mode; |
| - if (current_overscroll_gesture_ == OVERSCROLL_EAST || |
| - current_overscroll_gesture_ == OVERSCROLL_WEST) |
| - PrepareOverscrollWindow(); |
| - |
| + if (current_overscroll_gesture_ == OVERSCROLL_NONE && |
| + new_mode != OVERSCROLL_NONE) { |
| UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT); |
| } |
| + current_overscroll_gesture_ = new_mode; |
| + overscroll_window_animation_->OnOverscrollModeChange(old_mode, new_mode); |
| completed_overscroll_gesture_ = OVERSCROLL_NONE; |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| -// WebContentsViewAura, ui::ImplicitAnimationObserver implementation: |
| - |
| -void WebContentsViewAura::OnImplicitAnimationsCompleted() { |
| - overscroll_shadow_.reset(); |
| - |
| - if (ShouldNavigateForward(web_contents_->GetController(), |
| - completed_overscroll_gesture_)) { |
| - web_contents_->GetController().GoForward(); |
| - PrepareOverscrollNavigationOverlay(); |
| - } else if (ShouldNavigateBack(web_contents_->GetController(), |
| - completed_overscroll_gesture_)) { |
| - web_contents_->GetController().GoBack(); |
| - PrepareOverscrollNavigationOverlay(); |
| - } else { |
| - if (touch_editable_) |
| - touch_editable_->OverscrollCompleted(); |
| - } |
| - |
| - aura::Window* content = GetContentNativeView(); |
| - if (content) { |
| - content->SetTransform(gfx::Transform()); |
| - content->layer()->SetLayerBrightness(0.f); |
| - } |
| - current_overscroll_gesture_ = OVERSCROLL_NONE; |
| - completed_overscroll_gesture_ = OVERSCROLL_NONE; |
| - overscroll_window_.reset(); |
| -} |
| - |
| -//////////////////////////////////////////////////////////////////////////////// |
| // WebContentsViewAura, aura::WindowDelegate implementation: |
| gfx::Size WebContentsViewAura::GetMinimumSize() const { |
| @@ -1491,7 +1196,7 @@ void WebContentsViewAura::OnWindowDestroying(aura::Window* window) { |
| // virtual functions to be called (e.g. OnImplicitAnimationsCompleted()). So |
| // destroy the overscroll window here. |
| navigation_overlay_.reset(); |
| - overscroll_window_.reset(); |
| + overscroll_window_animation_ = nullptr; |
|
sadrul
2015/04/07 17:10:08
Instead of keeping this pointer |overscroll_window
Nina
2015/04/07 19:08:56
Done.
|
| } |
| void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) { |