| Index: content/renderer/render_widget.cc
|
| diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
|
| index abb144d592fe57e85ec293e64de9776f7a6456b7..3c64e512b0e169d9881575354f1c011328f5836a 100644
|
| --- a/content/renderer/render_widget.cc
|
| +++ b/content/renderer/render_widget.cc
|
| @@ -26,6 +26,7 @@
|
| #include "content/common/view_messages.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "content/renderer/cursor_utils.h"
|
| +#include "content/renderer/external_popup_menu.h"
|
| #include "content/renderer/gpu/compositor_output_surface.h"
|
| #include "content/renderer/gpu/compositor_software_output_device.h"
|
| #include "content/renderer/gpu/delegated_compositor_output_surface.h"
|
| @@ -53,7 +54,7 @@
|
| #include "third_party/WebKit/public/web/WebScreenInfo.h"
|
| #include "third_party/skia/include/core/SkShader.h"
|
| #include "ui/base/ui_base_switches.h"
|
| -#include "ui/gfx/point.h"
|
| +#include "ui/gfx/point_conversions.h"
|
| #include "ui/gfx/rect_conversions.h"
|
| #include "ui/gfx/size_conversions.h"
|
| #include "ui/gfx/skia_util.h"
|
| @@ -80,6 +81,7 @@ using WebKit::WebGestureEvent;
|
| using WebKit::WebInputEvent;
|
| using WebKit::WebKeyboardEvent;
|
| using WebKit::WebMouseEvent;
|
| +using WebKit::WebMouseWheelEvent;
|
| using WebKit::WebNavigationPolicy;
|
| using WebKit::WebPagePopup;
|
| using WebKit::WebPoint;
|
| @@ -187,6 +189,172 @@ ui::TextInputMode ConvertInputMode(
|
|
|
| namespace content {
|
|
|
| +// RenderWidget::ScreenMetricsEmulator ----------------------------------------
|
| +
|
| +class RenderWidget::ScreenMetricsEmulator {
|
| + public:
|
| + ScreenMetricsEmulator(
|
| + RenderWidget* widget,
|
| + const gfx::Size& device_size,
|
| + const gfx::Rect& widget_rect,
|
| + float device_scale_factor,
|
| + bool fit_to_view);
|
| + virtual ~ScreenMetricsEmulator();
|
| +
|
| + float scale() { return scale_; }
|
| + gfx::Rect widget_rect() const { return widget_rect_; }
|
| + gfx::Rect original_screen_rect() const { return original_view_screen_rect_; }
|
| +
|
| + void ChangeEmulationParams(
|
| + const gfx::Size& device_size,
|
| + const gfx::Rect& widget_rect,
|
| + float device_scale_factor,
|
| + bool fit_to_view);
|
| +
|
| + // The following methods alter handlers' behavior for messages related to
|
| + // widget size and position.
|
| + void OnResizeMessage(const ViewMsg_Resize_Params& params);
|
| + void OnUpdateScreenRectsMessage(const gfx::Rect& view_screen_rect,
|
| + const gfx::Rect& window_screen_rect);
|
| + void OnShowContextMenu(ContextMenuParams* params);
|
| +
|
| + private:
|
| + void Apply(float overdraw_bottom_height,
|
| + gfx::Rect resizer_rect, bool is_fullscreen);
|
| +
|
| + RenderWidget* widget_;
|
| +
|
| + // Parameters as passed by RenderWidget::EmulateScreenMetrics.
|
| + gfx::Size device_size_;
|
| + gfx::Rect widget_rect_;
|
| + float device_scale_factor_;
|
| + bool fit_to_view_;
|
| +
|
| + // The computed scaled used to fit widget into browser window.
|
| + float scale_;
|
| +
|
| + // Original values to restore back after emulation ends.
|
| + gfx::Size original_size_;
|
| + gfx::Size original_physical_backing_size_;
|
| + WebKit::WebScreenInfo original_screen_info_;
|
| + gfx::Rect original_view_screen_rect_;
|
| + gfx::Rect original_window_screen_rect_;
|
| +};
|
| +
|
| +RenderWidget::ScreenMetricsEmulator::ScreenMetricsEmulator(
|
| + RenderWidget* widget,
|
| + const gfx::Size& device_size,
|
| + const gfx::Rect& widget_rect,
|
| + float device_scale_factor,
|
| + bool fit_to_view)
|
| + : widget_(widget),
|
| + device_size_(device_size),
|
| + widget_rect_(widget_rect),
|
| + device_scale_factor_(device_scale_factor),
|
| + fit_to_view_(fit_to_view),
|
| + scale_(1.f) {
|
| + original_size_ = widget_->size_;
|
| + original_physical_backing_size_ = widget_->physical_backing_size_;
|
| + original_screen_info_ = widget_->screen_info_;
|
| + original_view_screen_rect_ = widget_->view_screen_rect_;
|
| + original_window_screen_rect_ = widget_->window_screen_rect_;
|
| + Apply(widget_->overdraw_bottom_height_,
|
| + widget_->resizer_rect_, widget_->is_fullscreen_);
|
| +}
|
| +
|
| +RenderWidget::ScreenMetricsEmulator::~ScreenMetricsEmulator() {
|
| + widget_->screen_info_ = original_screen_info_;
|
| +
|
| + widget_->SetDeviceScaleFactor(original_screen_info_.deviceScaleFactor);
|
| + widget_->SetScreenMetricsEmulationParameters(0.f, 1.f);
|
| + widget_->view_screen_rect_ = original_view_screen_rect_;
|
| + widget_->window_screen_rect_ = original_window_screen_rect_;
|
| + widget_->Resize(original_size_, original_physical_backing_size_,
|
| + widget_->overdraw_bottom_height_, widget_->resizer_rect_,
|
| + widget_->is_fullscreen_, NO_RESIZE_ACK);
|
| +}
|
| +
|
| +void RenderWidget::ScreenMetricsEmulator::ChangeEmulationParams(
|
| + const gfx::Size& device_size,
|
| + const gfx::Rect& widget_rect,
|
| + float device_scale_factor,
|
| + bool fit_to_view) {
|
| + device_size_ = device_size;
|
| + widget_rect_ = widget_rect;
|
| + device_scale_factor_ = device_scale_factor;
|
| + fit_to_view_ = fit_to_view;
|
| + Apply(widget_->overdraw_bottom_height_,
|
| + widget_->resizer_rect_, widget_->is_fullscreen_);
|
| +}
|
| +
|
| +void RenderWidget::ScreenMetricsEmulator::Apply(
|
| + float overdraw_bottom_height, gfx::Rect resizer_rect, bool is_fullscreen) {
|
| + if (fit_to_view_) {
|
| + DCHECK(!original_size_.IsEmpty());
|
| + float width_ratio =
|
| + static_cast<float>(widget_rect_.width()) / original_size_.width();
|
| + float height_ratio =
|
| + static_cast<float>(widget_rect_.height()) / original_size_.height();
|
| + float ratio = std::max(1.0f, std::max(width_ratio, height_ratio));
|
| + scale_ = 1.f / ratio;
|
| + } else {
|
| + scale_ = 1.f;
|
| + }
|
| +
|
| + widget_->screen_info_.rect = gfx::Rect(device_size_);
|
| + widget_->screen_info_.availableRect = gfx::Rect(device_size_);
|
| + widget_->screen_info_.deviceScaleFactor = device_scale_factor_;
|
| +
|
| + // Pass two emulation parameters to the blink side:
|
| + // - we keep the real device scale factor in compositor to produce sharp image
|
| + // even when emulating different scale factor;
|
| + // - in order to fit into view, WebView applies scaling transform to the
|
| + // root layer.
|
| + widget_->SetScreenMetricsEmulationParameters(
|
| + original_screen_info_.deviceScaleFactor, scale_);
|
| +
|
| + widget_->SetDeviceScaleFactor(device_scale_factor_);
|
| + widget_->view_screen_rect_ = widget_rect_;
|
| + widget_->window_screen_rect_ = widget_->screen_info_.availableRect;
|
| +
|
| + gfx::Size physical_backing_size = gfx::ToCeiledSize(gfx::ScaleSize(
|
| + original_size_, original_screen_info_.deviceScaleFactor));
|
| + widget_->Resize(widget_rect_.size(), physical_backing_size,
|
| + overdraw_bottom_height, resizer_rect, is_fullscreen, NO_RESIZE_ACK);
|
| +}
|
| +
|
| +void RenderWidget::ScreenMetricsEmulator::OnResizeMessage(
|
| + const ViewMsg_Resize_Params& params) {
|
| + bool need_ack = params.new_size != original_size_ &&
|
| + !params.new_size.IsEmpty() && !params.physical_backing_size.IsEmpty();
|
| + original_size_ = params.new_size;
|
| + original_physical_backing_size_ = params.physical_backing_size;
|
| + original_screen_info_ = params.screen_info;
|
| + Apply(params.overdraw_bottom_height, params.resizer_rect,
|
| + params.is_fullscreen);
|
| +
|
| + if (need_ack) {
|
| + widget_->set_next_paint_is_resize_ack();
|
| + if (widget_->compositor_)
|
| + widget_->compositor_->SetNeedsRedrawRect(gfx::Rect(widget_->size_));
|
| + }
|
| +}
|
| +
|
| +void RenderWidget::ScreenMetricsEmulator::OnUpdateScreenRectsMessage(
|
| + const gfx::Rect& view_screen_rect,
|
| + const gfx::Rect& window_screen_rect) {
|
| + original_view_screen_rect_ = view_screen_rect;
|
| + original_window_screen_rect_ = window_screen_rect;
|
| +}
|
| +
|
| +void RenderWidget::ScreenMetricsEmulator::OnShowContextMenu(
|
| + ContextMenuParams* params) {
|
| + params->x *= scale_;
|
| + params->y *= scale_;
|
| +}
|
| +
|
| +// RenderWidget ---------------------------------------------------------------
|
| +
|
| RenderWidget::RenderWidget(WebKit::WebPopupType popup_type,
|
| const WebKit::WebScreenInfo& screen_info,
|
| bool swapped_out,
|
| @@ -232,6 +400,7 @@ RenderWidget::RenderWidget(WebKit::WebPopupType popup_type,
|
| #if defined(OS_ANDROID)
|
| outstanding_ime_acks_(0),
|
| #endif
|
| + popup_origin_scale_for_emulation_(0.f),
|
| weak_ptr_factory_(this) {
|
| if (!swapped_out)
|
| RenderProcess::current()->AddRefProcess();
|
| @@ -370,6 +539,48 @@ bool RenderWidget::UsingSynchronousRendererCompositor() const {
|
| #endif
|
| }
|
|
|
| +void RenderWidget::EnableScreenMetricsEmulation(
|
| + const gfx::Size& device_size,
|
| + const gfx::Rect& widget_rect,
|
| + float device_scale_factor,
|
| + bool fit_to_view) {
|
| + if (!screen_metrics_emulator_) {
|
| + screen_metrics_emulator_.reset(new ScreenMetricsEmulator(this,
|
| + device_size, widget_rect, device_scale_factor, fit_to_view));
|
| + } else {
|
| + screen_metrics_emulator_->ChangeEmulationParams(device_size,
|
| + widget_rect, device_scale_factor, fit_to_view);
|
| + }
|
| +}
|
| +
|
| +void RenderWidget::DisableScreenMetricsEmulation() {
|
| + screen_metrics_emulator_.reset();
|
| +}
|
| +
|
| +void RenderWidget::SetPopupOriginAdjustmentsForEmulation(
|
| + ScreenMetricsEmulator* emulator) {
|
| + popup_origin_scale_for_emulation_ = emulator->scale();
|
| + popup_view_origin_for_emulation_ = emulator->widget_rect().origin();
|
| + popup_screen_origin_for_emulation_ =
|
| + emulator->original_screen_rect().origin();
|
| +}
|
| +
|
| +void RenderWidget::SetScreenMetricsEmulationParameters(
|
| + float device_scale_factor, float root_layer_scale) {
|
| + // This is only supported in RenderView.
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void RenderWidget::SetExternalPopupOriginAdjustmentsForEmulation(
|
| + ExternalPopupMenu* popup, ScreenMetricsEmulator* emulator) {
|
| + popup->SetOriginScaleForEmulation(emulator->scale());
|
| +}
|
| +
|
| +void RenderWidget::OnShowHostContextMenu(ContextMenuParams* params) {
|
| + if (screen_metrics_emulator_)
|
| + screen_metrics_emulator_->OnShowContextMenu(params);
|
| +}
|
| +
|
| bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
|
| bool handled = true;
|
| IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
|
| @@ -532,6 +743,11 @@ void RenderWidget::OnCreatingNewAck() {
|
| }
|
|
|
| void RenderWidget::OnResize(const ViewMsg_Resize_Params& params) {
|
| + if (screen_metrics_emulator_) {
|
| + screen_metrics_emulator_->OnResizeMessage(params);
|
| + return;
|
| + }
|
| +
|
| screen_info_ = params.screen_info;
|
| SetDeviceScaleFactor(screen_info_.deviceScaleFactor);
|
| Resize(params.new_size, params.physical_backing_size,
|
| @@ -1791,7 +2007,16 @@ void RenderWidget::setToolTipText(const WebKit::WebString& text,
|
| Send(new ViewHostMsg_SetTooltipText(routing_id_, text, hint));
|
| }
|
|
|
| -void RenderWidget::setWindowRect(const WebRect& pos) {
|
| +void RenderWidget::setWindowRect(const WebRect& rect) {
|
| + WebRect pos = rect;
|
| + if (popup_origin_scale_for_emulation_) {
|
| + float scale = popup_origin_scale_for_emulation_;
|
| + pos.x = popup_screen_origin_for_emulation_.x() +
|
| + (pos.x - popup_view_origin_for_emulation_.x()) * scale;
|
| + pos.y = popup_screen_origin_for_emulation_.y() +
|
| + (pos.y - popup_view_origin_for_emulation_.y()) * scale;
|
| + }
|
| +
|
| if (did_show_) {
|
| if (!RenderThreadImpl::current()->layout_test_mode()) {
|
| Send(new ViewHostMsg_RequestMove(routing_id_, pos));
|
| @@ -2032,8 +2257,13 @@ void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
|
|
|
| void RenderWidget::OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
|
| const gfx::Rect& window_screen_rect) {
|
| - view_screen_rect_ = view_screen_rect;
|
| - window_screen_rect_ = window_screen_rect;
|
| + if (screen_metrics_emulator_) {
|
| + screen_metrics_emulator_->OnUpdateScreenRectsMessage(
|
| + view_screen_rect, window_screen_rect);
|
| + } else {
|
| + view_screen_rect_ = view_screen_rect;
|
| + window_screen_rect_ = window_screen_rect;
|
| + }
|
| Send(new ViewHostMsg_UpdateScreenRects_ACK(routing_id()));
|
| }
|
|
|
|
|