#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/aura/image_window_delegate.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/touch_editable_impl_aura.h"
return web_input_event_modifiers;
}
-// A LayerDelegate that paints an image for the layer.
-class ImageLayerDelegate : public ui::LayerDelegate {
- public:
- ImageLayerDelegate() {}
-
- virtual ~ImageLayerDelegate() {}
-
- void SetImage(const gfx::Image& image) {
- image_ = image;
- image_size_ = image.AsImageSkia().size();
- }
- const gfx::Image& image() const { return image_; }
-
- private:
- // Overridden from ui::LayerDelegate:
- virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
- if (image_.IsEmpty()) {
- canvas->DrawColor(SK_ColorGRAY);
- } else {
- SkISize size = canvas->sk_canvas()->getDeviceSize();
- if (size.width() != image_size_.width() ||
- size.height() != image_size_.height()) {
- canvas->DrawColor(SK_ColorWHITE);
- }
- canvas->DrawImageInt(image_.AsImageSkia(), 0, 0);
- }
- }
-
- // Called when the layer's device scale factor has changed.
- virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE {
- }
-
- // Invoked prior to the bounds changing. The returned closured is run after
- // the bounds change.
- virtual base::Closure PrepareForLayerBoundsChange() OVERRIDE {
- return base::Closure();
- }
-
- gfx::Image image_;
- gfx::Size image_size_;
-
- DISALLOW_COPY_AND_ASSIGN(ImageLayerDelegate);
-};
-
} // namespace
-// When a history navigation is triggered at the end of an overscroll
-// navigation, it is necessary to show the history-screenshot until the page is
-// done navigating and painting. This class accomplishes this by showing the
-// screenshot window on top of the page until the page has completed loading and
-// painting.
-class OverscrollNavigationOverlay :
- public RenderWidgetHostViewAura::PaintObserver,
- public WindowSlider::Delegate {
- public:
- explicit OverscrollNavigationOverlay(WebContentsImpl* web_contents)
- : web_contents_(web_contents),
- image_delegate_(NULL),
- view_(NULL),
- loading_complete_(false),
- received_paint_update_(false),
- compositor_updated_(false),
- slide_direction_(SLIDE_UNKNOWN),
- need_paint_update_(true) {
- }
-
- virtual ~OverscrollNavigationOverlay() {
- if (view_)
- view_->set_paint_observer(NULL);
- }
-
- bool has_window() const { return !!window_.get(); }
-
- void StartObservingView(RenderWidgetHostViewAura* view) {
- if (view_)
- view_->set_paint_observer(NULL);
-
- loading_complete_ = false;
- received_paint_update_ = false;
- compositor_updated_ = false;
- view_ = view;
- if (view_)
- view_->set_paint_observer(this);
-
- // Make sure the overlay window is on top.
- if (window_.get() && window_->parent())
- window_->parent()->StackChildAtTop(window_.get());
- }
-
- void SetOverlayWindow(scoped_ptr<aura::Window> window,
- ImageWindowDelegate* delegate) {
- window_ = window.Pass();
- if (window_.get() && window_->parent())
- window_->parent()->StackChildAtTop(window_.get());
- image_delegate_ = delegate;
-
- if (window_.get() && delegate->has_image()) {
- window_slider_.reset(new WindowSlider(this,
- window_->parent(),
- window_.get()));
- slide_direction_ = SLIDE_UNKNOWN;
- } else {
- window_slider_.reset();
- }
- }
-
- void SetupForTesting() {
- need_paint_update_ = false;
- }
-
- private:
- // Stop observing the page if the page-load has completed and the page has
- // been painted, and a window-slide isn't in progress.
- void StopObservingIfDone() {
- // If there is a screenshot displayed in the overlay window, then wait for
- // the navigated page to complete loading and some paint update before
- // hiding the overlay.
- // If there is no screenshot in the overlay window, then hide this view
- // as soon as there is any new painting notification.
- if ((need_paint_update_ && !received_paint_update_) ||
- (image_delegate_->has_image() && !loading_complete_)) {
- return;
- }
-
- // If a slide is in progress, then do not destroy the window or the slide.
- if (window_slider_.get() && window_slider_->IsSlideInProgress())
- return;
-
- window_slider_.reset();
- window_.reset();
- image_delegate_ = NULL;
- if (view_) {
- view_->set_paint_observer(NULL);
- view_ = NULL;
- }
- }
-
- // Creates a layer to be used for window-slide. |offset| is the offset of the
- // NavigationEntry for the screenshot image to display.
- ui::Layer* CreateSlideLayer(int offset) {
- const NavigationControllerImpl& controller = web_contents_->GetController();
- const NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
- controller.GetEntryAtOffset(offset));
-
- gfx::Image image;
- if (entry && entry->screenshot().get()) {
- std::vector<gfx::ImagePNGRep> image_reps;
- image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(),
- ui::GetImageScale(
- ui::GetScaleFactorForNativeView(window_.get()))));
- image = gfx::Image(image_reps);
- }
- layer_delegate_.SetImage(image);
-
- ui::Layer* layer = new ui::Layer(ui::LAYER_TEXTURED);
- layer->set_delegate(&layer_delegate_);
- return layer;
- }
-
- // Overridden from WindowSlider::Delegate:
- virtual ui::Layer* CreateBackLayer() OVERRIDE {
- if (!web_contents_->GetController().CanGoBack())
- return NULL;
- slide_direction_ = SLIDE_BACK;
- return CreateSlideLayer(-1);
- }
-
- virtual ui::Layer* CreateFrontLayer() OVERRIDE {
- if (!web_contents_->GetController().CanGoForward())
- return NULL;
- slide_direction_ = SLIDE_FRONT;
- return CreateSlideLayer(1);
- }
-
- virtual void OnWindowSlideComplete() OVERRIDE {
- if (slide_direction_ == SLIDE_UNKNOWN) {
- window_slider_.reset();
- StopObservingIfDone();
- return;
- }
-
- // Change the image used for the overlay window.
- image_delegate_->SetImage(layer_delegate_.image());
- window_->layer()->SetTransform(gfx::Transform());
- window_->SchedulePaintInRect(gfx::Rect(window_->bounds().size()));
-
- SlideDirection direction = slide_direction_;
- slide_direction_ = SLIDE_UNKNOWN;
-
- // Reset state and wait for the new navigation page to complete
- // loading/painting.
- StartObservingView(ToRenderWidgetHostViewAura(
- web_contents_->GetRenderWidgetHostView()));
-
- // Perform the navigation.
- if (direction == SLIDE_BACK)
- web_contents_->GetController().GoBack();
- else if (direction == SLIDE_FRONT)
- web_contents_->GetController().GoForward();
- else
- NOTREACHED();
- }
-
- virtual void OnWindowSlideAborted() OVERRIDE {
- StopObservingIfDone();
- }
-
- virtual void OnWindowSliderDestroyed() OVERRIDE {
- // The slider has just been destroyed. Release the ownership.
- WindowSlider* slider ALLOW_UNUSED = window_slider_.release();
- StopObservingIfDone();
- }
-
- // Overridden from RenderWidgetHostViewAura::PaintObserver:
- virtual void OnPaintComplete() OVERRIDE {
- received_paint_update_ = true;
- StopObservingIfDone();
- }
-
- virtual void OnCompositingComplete() OVERRIDE {
- received_paint_update_ = compositor_updated_;
- StopObservingIfDone();
- }
-
- virtual void OnUpdateCompositorContent() OVERRIDE {
- compositor_updated_ = true;
- }
-
- virtual void OnPageLoadComplete() OVERRIDE {
- loading_complete_ = true;
- StopObservingIfDone();
- }
-
- virtual void OnViewDestroyed() OVERRIDE {
- DCHECK(view_);
- view_->set_paint_observer(NULL);
- view_ = NULL;
- }
-
- // The WebContents which is being navigated.
- WebContentsImpl* web_contents_;
-
- scoped_ptr<aura::Window> window_;
-
- // This is the WindowDelegate of |window_|. The delegate manages its own
- // lifetime (destroys itself when |window_| is destroyed).
- ImageWindowDelegate* image_delegate_;
-
- RenderWidgetHostViewAura* view_;
- bool loading_complete_;
- bool received_paint_update_;
- bool compositor_updated_;
-
- enum SlideDirection {
- SLIDE_UNKNOWN,
- SLIDE_BACK,
- SLIDE_FRONT
- };
-
- // The |WindowSlider| that allows sliding history layers while the page is
- // being reloaded.
- scoped_ptr<WindowSlider> window_slider_;
-
- // The direction of the in-progress slide (if any).
- SlideDirection slide_direction_;
-
- // The LayerDelegate used for the back/front layers during a slide.
- ImageLayerDelegate layer_delegate_;
-
- // During tests, the aura windows don't get any paint updates. So the overlay
- // container keeps waiting for a paint update it never receives, causing a
- // timeout. So during tests, disable the wait for paint updates.
- bool need_paint_update_;
-
- DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlay);
-};
-
class WebContentsViewAura::WindowObserver
: public aura::WindowObserver, public aura::RootWindowObserver {
public:
virtual void OnWindowVisibilityChanged(aura::Window* window,
bool visible) OVERRIDE {
- if (window == view_->window_)
- return;
-
- if (window->parent() == parent_ ||
+ if (window == view_->window_ ||
+ window->parent() == parent_ ||
window->parent() == view_->window_->GetRootWindow()) {
UpdateConstrainedWindows(NULL);
}
overscroll_window_->SetTransform(gfx::Transform());
navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(),
delegate);
- navigation_overlay_->StartObservingView(ToRenderWidgetHostViewAura(
- web_contents_->GetRenderWidgetHostView()));
+ navigation_overlay_->StartObserving();
}
void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) {
GetNativeView()->AddChild(view->GetNativeView());
if (navigation_overlay_.get() && navigation_overlay_->has_window()) {
- navigation_overlay_->StartObservingView(ToRenderWidgetHostViewAura(view));
+ navigation_overlay_->StartObserving();
}
RenderWidgetHostImpl* host_impl =
}
void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
- if (navigation_overlay_.get() && navigation_overlay_->has_window()) {
- navigation_overlay_->StartObservingView(
- ToRenderWidgetHostViewAura(host->GetView()));
- }
+ if (navigation_overlay_.get() && navigation_overlay_->has_window())
+ navigation_overlay_->StartObserving();
AttachTouchEditableToRenderView();
}
////////////////////////////////////////////////////////////////////////////////
// WebContentsViewAura, RenderViewHostDelegateView implementation:
-void WebContentsViewAura::ShowContextMenu(const ContextMenuParams& params) {
+void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
+ const ContextMenuParams& params) {
if (touch_editable_)
touch_editable_->EndTouchEditing(false);
if (delegate_) {
- delegate_->ShowContextMenu(params);
+ delegate_->ShowContextMenu(render_frame_host, params);
// WARNING: we may have been deleted during the call to ShowContextMenu().
}
}