Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(348)

Unified Diff: content/browser/web_contents/web_contents_view_aura.cc

Issue 895543005: Refactor GestureNavigation to eliminate code redundancy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: New design with window|wrapper in OWA Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 da9af68e420cdc09215582c10653ba5f9c4bb620..5ce1f9da8603205d510a0e592ad6b3e300db8c3e 100644
--- a/content/browser/web_contents/web_contents_view_aura.cc
+++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -22,7 +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/overscroll_window_animation.h"
#include "content/browser/web_contents/aura/window_slider.h"
#include "content/browser/web_contents/touch_editable_impl_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
@@ -60,7 +60,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 +87,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 +100,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 {
@@ -725,17 +653,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) {
}
@@ -800,178 +728,36 @@ 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(&current_overscroll_gesture_,
- current_overscroll_gesture_);
- scoped_ptr<aura::Window> reset_window(overscroll_window_.release());
+ LOG(ERROR) << "Installing OCD";
+ if (!overscroll_window_animation_) {
mfomitchev 2015/03/06 01:36:43 Can we do the same thing for overscroll_window_ani
Nina 2015/03/09 15:54:53 Done.
+ overscroll_window_animation_.reset(
+ new OverscrollWindowAnimation());
}
-
- 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(aura::WINDOW_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);
+ if (!navigation_overlay_) {
+ navigation_overlay_.reset(
+ new OverscrollNavigationOverlay(web_contents_,
+ overscroll_window_animation_.get(),
+ window_.get()));
+ overscroll_window_animation_->set_delegate(navigation_overlay_.get());
}
-
- 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()));
+ LOG(ERROR) << "Installing overscroll window animation controller";
}
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);
- }
-}
-
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() {
@@ -1130,10 +916,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);
@@ -1166,8 +948,6 @@ void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
}
void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
- if (navigation_overlay_.get() && navigation_overlay_->has_window())
- navigation_overlay_->StartObserving();
AttachTouchEditableToRenderView();
}
@@ -1182,8 +962,19 @@ void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
if (!enabled)
navigation_overlay_.reset();
mfomitchev 2015/03/06 01:36:43 reset OWA here as well
Nina 2015/03/09 15:54:53 Done.
- else if (!navigation_overlay_)
- navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
+ // TODO maybe we can delete this code, as it should be applied in
+ // InstallOverscrollControllerDelegate?
+ LOG(ERROR) << "Installing OCD";
+ if (!overscroll_window_animation_) {
mfomitchev 2015/03/06 01:36:43 remove this if
Nina 2015/03/09 15:54:53 Done.
+ overscroll_window_animation_.reset(
+ new OverscrollWindowAnimation());
+ } else if (!navigation_overlay_) {
+ navigation_overlay_.reset(
mfomitchev 2015/03/06 01:36:43 Create OWA here as well
Nina 2015/03/09 15:54:53 I rewrote this. OWA is now created on overscroll u
mfomitchev 2015/03/10 19:25:59 Hmm.. I don't really like that we are initializing
Nina 2015/03/12 22:21:28 Done.
+ new OverscrollNavigationOverlay(web_contents_,
+ overscroll_window_animation_.get(),
+ window_.get()));
+ overscroll_window_animation_->set_delegate(navigation_overlay_.get());
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -1304,44 +1095,33 @@ 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();
+ // Only horizontal overscrolls participate in the navigation gesture.
mfomitchev 2015/03/06 01:36:43 shouldn't this be inside else like it was before?
Nina 2015/03/09 15:54:53 We have a return on the other if, no need for an e
+ if (!overscroll_window_animation_)
mfomitchev 2015/03/06 01:36:43 Is this even possible? Previous flow ddidn't accou
Nina 2015/03/09 15:54:53 TBH I don't know as I didn't look much at the code
mfomitchev 2015/03/10 19:25:59 I think overscroll events won't go to WCVA in the
Nina 2015/03/12 22:21:28 Acknowledged.
+ return false;
+ return overscroll_window_animation_->OnOverscrollUpdate(delta_x, delta_y);
}
void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) {
UMA_HISTOGRAM_ENUMERATION("Overscroll.Completed", mode, OVERSCROLL_COUNT);
+ LOG(ERROR) << "OVERSCROLL COMPLETE";
if (web_contents_->GetDelegate() &&
IsScrollEndEffectEnabled() &&
(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) {
+ LOG(ERROR) << "Overscroll mode change";
// Reset any in-progress overscroll animation first.
- ResetOverscrollTransform();
+ // ResetOverscrollTransform();
if (old_mode == OVERSCROLL_NORTH || old_mode == OVERSCROLL_SOUTH)
OverscrollUpdateForWebContentsDelegate(0);
@@ -1349,58 +1129,22 @@ void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode,
if (new_mode != OVERSCROLL_NONE && touch_editable_)
touch_editable_->OverscrollStarted();
+ overscroll_window_animation_->set_live_window(GetContentNativeView());
mfomitchev 2015/03/05 23:37:06 Calling this every time the mode changes seems exc
Nina 2015/03/09 15:54:53 Yes, but it was necessary. I changed it so that we
if (new_mode == OVERSCROLL_NONE ||
!GetContentNativeView() ||
((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) &&
- navigation_overlay_.get() && navigation_overlay_->has_window())) {
+ overscroll_window_animation_ &&
+ overscroll_window_animation_->is_active())) {
current_overscroll_gesture_ = OVERSCROLL_NONE;
+ overscroll_window_animation_->OnOverscrollModeChange(old_mode,
+ 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();
-
- UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT);
mfomitchev 2015/03/06 01:36:43 Looks like we lost this histogram
Nina 2015/03/09 15:54:53 Brought back
- }
- 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);
+ if (overscroll_window_animation_)
+ overscroll_window_animation_->OnOverscrollModeChange(old_mode, new_mode);
+ PrepareContentWindowForOverscroll();
}
- current_overscroll_gesture_ = OVERSCROLL_NONE;
completed_overscroll_gesture_ = OVERSCROLL_NONE;
- overscroll_window_.reset();
}
////////////////////////////////////////////////////////////////////////////////
@@ -1480,7 +1224,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_.reset();
}
void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) {

Powered by Google App Engine
This is Rietveld 408576698