Index: content/browser/web_contents/aura/window_slider.cc |
diff --git a/content/browser/web_contents/aura/window_slider.cc b/content/browser/web_contents/aura/window_slider.cc |
index 4e2b3628052162da400c203b009f0118d9ce0ea2..5eec8360fea12c6f73fcec0eccb1fd9852ddf1a2 100644 |
--- a/content/browser/web_contents/aura/window_slider.cc |
+++ b/content/browser/web_contents/aura/window_slider.cc |
@@ -4,6 +4,8 @@ |
#include "content/browser/web_contents/aura/window_slider.h" |
+#include <algorithm> |
+ |
#include "base/bind.h" |
#include "base/callback.h" |
#include "content/browser/web_contents/aura/shadow_layer_delegate.h" |
@@ -86,6 +88,10 @@ void WindowSlider::ChangeOwner(aura::Window* new_owner) { |
} |
} |
+bool WindowSlider::SlideIsInProgress() const { |
+ return fabs(delta_x_) >= min_start_threshold_ || weak_factory_.HasWeakPtrs(); |
+} |
+ |
void WindowSlider::SetupSliderLayer() { |
ui::Layer* parent = owner_->layer()->parent(); |
parent->Add(slider_.get()); |
@@ -100,10 +106,8 @@ void WindowSlider::SetupSliderLayer() { |
void WindowSlider::UpdateForScroll(float x_offset, float y_offset) { |
float old_delta = delta_x_; |
delta_x_ += x_offset; |
- if (fabs(delta_x_) < min_start_threshold_) { |
- ResetScroll(); |
+ if (fabs(delta_x_) < min_start_threshold_ && !slider_.get()) |
return; |
- } |
if ((old_delta < 0 && delta_x_ > 0) || |
(old_delta > 0 && delta_x_ < 0)) { |
@@ -117,17 +121,23 @@ void WindowSlider::UpdateForScroll(float x_offset, float y_offset) { |
if (delta_x_ <= -min_start_threshold_) { |
if (!slider_.get()) { |
slider_.reset(delegate_->CreateFrontLayer()); |
+ if (!slider_.get()) |
+ return; |
SetupSliderLayer(); |
} |
- translate = event_window_->bounds().width() - |
- fabs(delta_x_ - min_start_threshold_); |
+ translate = owner_->bounds().width() + |
+ std::max(delta_x_ + min_start_threshold_, |
+ static_cast<float>(-owner_->bounds().width())); |
translate_layer = slider_.get(); |
} else if (delta_x_ >= min_start_threshold_) { |
if (!slider_.get()) { |
slider_.reset(delegate_->CreateBackLayer()); |
+ if (!slider_.get()) |
+ return; |
SetupSliderLayer(); |
} |
- translate = delta_x_ - min_start_threshold_; |
+ translate = std::min(delta_x_ - min_start_threshold_, |
+ static_cast<float>(owner_->bounds().width())); |
translate_layer = owner_->layer(); |
} else { |
NOTREACHED(); |
@@ -214,6 +224,14 @@ void WindowSlider::CancelScroll() { |
} |
void WindowSlider::CompleteWindowSlideAfterAnimation() { |
+ // The delegate may delete the |owner_| from the |OnWindowSlideComplete()| |
+ // callback, which would trigger the |
+ // |WindowSlider::OnWindowRemovingFromRootWindow()| callback, which would try |
+ // to delete itself again. So avoid that by resetting |owner_| before calling |
+ // the |OnWindowSlideComplete()| callback on the delegate. |
+ owner_->RemoveObserver(this); |
+ owner_ = NULL; |
+ |
delegate_->OnWindowSlideComplete(); |
delete this; |
} |