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

Unified Diff: content/renderer/render_widget.cc

Issue 23364004: Implementation of device metrics emulation in render view. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 3 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
« content/renderer/render_widget.h ('K') | « content/renderer/render_widget.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/render_widget.cc
===================================================================
--- content/renderer/render_widget.cc (revision 217537)
+++ content/renderer/render_widget.cc (working copy)
@@ -79,6 +79,7 @@
using WebKit::WebInputEvent;
using WebKit::WebKeyboardEvent;
using WebKit::WebMouseEvent;
+using WebKit::WebMouseWheelEvent;
using WebKit::WebNavigationPolicy;
using WebKit::WebPagePopup;
using WebKit::WebPoint;
@@ -380,6 +381,7 @@
IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck)
IPC_MESSAGE_HANDLER(ViewMsg_SwapBuffers_ACK,
OnViewContextSwapBuffersComplete)
+ IPC_MESSAGE_HANDLER(ViewMsg_EmulateDevice_ACK, OnEmulateDeviceAck)
IPC_MESSAGE_HANDLER(ViewMsg_SetInputMethodActive, OnSetInputMethodActive)
IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition)
IPC_MESSAGE_HANDLER(ViewMsg_ImeConfirmComposition, OnImeConfirmComposition)
@@ -515,6 +517,48 @@
Release();
}
+void RenderWidget::EmulateDevice(
+ bool enabled,
+ const gfx::Size& device_size,
+ const gfx::Rect& widget_rect,
+ float device_scale_factor,
+ bool fit_to_view) {
+ pending_device_emulation_enabled_ = enabled;
+ if (enabled) {
+ pending_device_emulation_helper_.reset(new DeviceEmulationHelper(
+ device_size,
+ widget_rect,
+ device_scale_factor,
+ fit_to_view));
+ } else {
+ pending_device_emulation_helper_.reset();
+ }
+ Send(new ViewHostMsg_EmulateDevice(routing_id_, enabled));
+}
+
+void RenderWidget::OnEmulateDeviceAck(bool enabled) {
+ // We may have got another emulate device request while sending message
+ // to the host. If the host idea of whether device emulation is enabled
+ // differs, wait for another ack with the right |enabled| value.
+ if (enabled != pending_device_emulation_enabled_)
+ return;
+
+ if (pending_device_emulation_enabled_) {
+ if (!device_emulation_helper_) {
+ device_emulation_helper_ = pending_device_emulation_helper_.Pass();
+ device_emulation_helper_->BeginEmulation(this);
+ } else {
+ device_emulation_helper_->ChangeEmulationParams(
+ this, pending_device_emulation_helper_.get());
+ pending_device_emulation_helper_.reset();
+ }
+ } else {
+ if (device_emulation_helper_)
+ device_emulation_helper_->EndEmulation(this);
+ device_emulation_helper_.reset();
+ }
+}
+
// Got a response from the browser after the renderer decided to create a new
// view.
void RenderWidget::OnCreatingNewAck() {
@@ -524,6 +568,11 @@
}
void RenderWidget::OnResize(const ViewMsg_Resize_Params& params) {
+ if (device_emulation_helper_) {
+ device_emulation_helper_->OnResizeMessage(this, params);
+ return;
+ }
+
screen_info_ = params.screen_info;
SetDeviceScaleFactor(screen_info_.deviceScaleFactor);
Resize(params.new_size, params.physical_backing_size,
@@ -789,6 +838,15 @@
const ui::LatencyInfo& latency_info,
bool is_keyboard_shortcut) {
handling_input_event_ = true;
+
+ scoped_ptr<const WebKit::WebInputEvent> owner;
+ if (device_emulation_helper_) {
+ input_event = device_emulation_helper_->ConvertInputEventToEmulated(
+ this, input_event);
+ if (input_event)
+ owner.reset(input_event);
+ }
+
if (!input_event) {
handling_input_event_ = false;
return;
@@ -1768,7 +1826,13 @@
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_device_emulation_helper_) {
+ pos = popup_device_emulation_helper_->ConvertPopupScreenRectFromEmulated(
+ this, rect);
+ }
+
if (did_show_) {
if (!RenderThreadImpl::current()->layout_test_mode()) {
Send(new ViewHostMsg_RequestMove(routing_id_, pos));
@@ -2009,6 +2073,11 @@
void RenderWidget::OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
const gfx::Rect& window_screen_rect) {
+ if (device_emulation_helper_) {
+ device_emulation_helper_->OnUpdateScreenRectsMessage(
+ this, view_screen_rect, window_screen_rect);
+ return;
+ }
view_screen_rect_ = view_screen_rect;
window_screen_rect_ = window_screen_rect;
Send(new ViewHostMsg_UpdateScreenRects_ACK(routing_id()));
@@ -2528,4 +2597,191 @@
return context.release();
}
+RenderWidget::DeviceEmulationHelper::DeviceEmulationHelper(
+ 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),
+ weak_ptr_factory_(this) {
+}
+
+RenderWidget::DeviceEmulationHelper::~DeviceEmulationHelper() {
+}
+
+void RenderWidget::DeviceEmulationHelper::BeginEmulation(RenderWidget* widget) {
+ 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, widget->overdraw_bottom_height_, widget->resizer_rect_,
+ widget->is_fullscreen_);
+}
+
+void RenderWidget::DeviceEmulationHelper::ChangeEmulationParams(
+ RenderWidget* widget, DeviceEmulationHelper* params) {
+ device_size_ = params->device_size_;
+ widget_rect_ = params->widget_rect_;
+ device_scale_factor_ = params->device_scale_factor_;
+ fit_to_view_ = params->fit_to_view_;
+ Apply(widget, widget->overdraw_bottom_height_, widget->resizer_rect_,
+ widget->is_fullscreen_);
+}
+
+void RenderWidget::DeviceEmulationHelper::EndEmulation(RenderWidget* widget) {
+ widget->screen_info_ = original_screen_info_;
+ if (widget->compositor_) {
+ // Passing zero cancels override.
+ widget->compositor_->OverrideDeviceScaleFactor(0.f);
+ }
+ widget->SetDeviceScaleFactor(original_screen_info_.deviceScaleFactor);
+ 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::DeviceEmulationHelper::Apply(RenderWidget* widget,
+ float overdraw_bottom_height, gfx::Rect resizer_rect, bool is_fullscreen) {
+ widget->screen_info_.rect = gfx::Rect(device_size_);
+ widget->screen_info_.availableRect = gfx::Rect(device_size_);
+ widget->screen_info_.deviceScaleFactor = device_scale_factor_;
+
+ if (widget->compositor_) {
+ // We keep the real device scale factor in compositor to prevent unnecessary
+ // scaling on browser side. This override ensures that compositor
+ // will not change scale factor due to WebLayerTreeView's call.
+ widget->compositor_->OverrideDeviceScaleFactor(
+ original_screen_info_.deviceScaleFactor);
+ }
+
+ 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(
+ widget_rect_.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::DeviceEmulationHelper::OnResizeMessage(
+ RenderWidget* widget, const ViewMsg_Resize_Params& params) {
+ bool need_ack = params.new_size != original_size_;
+ original_size_ = params.new_size;
+ original_physical_backing_size_ = params.physical_backing_size;
+ original_screen_info_ = params.screen_info;
+ Apply(widget, params.overdraw_bottom_height, params.resizer_rect,
+ params.is_fullscreen);
+
+ if (need_ack) {
+ widget->set_next_paint_is_resize_ack();
+ if (widget->is_accelerated_compositing_active_ && widget->compositor_)
+ widget->compositor_->SetNeedsRedrawRect(gfx::Rect(widget->size_));
+ else
+ widget->didInvalidateRect(gfx::Rect(widget->size_));
+ }
+}
+
+void RenderWidget::DeviceEmulationHelper::OnUpdateScreenRectsMessage(
+ RenderWidget* widget,
+ 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;
+ widget->Send(new ViewHostMsg_UpdateScreenRects_ACK(widget->routing_id()));
+}
+
+WebKit::WebInputEvent* RenderWidget::DeviceEmulationHelper::ConvertInputEventToEmulated(
aelias_OOO_until_Jul13 2013/09/05 08:26:49 The CC impl thread captures input events as well.
dgozman 2013/09/10 19:54:02 As I understand, CC event handling is not interest
aelias_OOO_until_Jul13 2013/09/10 20:33:34 OK, I didn't notice you were only changing those s
dgozman 2013/09/10 20:55:36 Well, wrong screen position of events will conflic
aelias_OOO_until_Jul13 2013/09/10 21:00:02 should be restored back to apply backward scale.
+ RenderWidget* widget, const WebKit::WebInputEvent* event) {
+ if (!event)
+ return NULL;
+
+ if (WebInputEvent::isKeyboardEventType(event->type)) {
+ const WebKeyboardEvent& keyboard_event =
+ *static_cast<const WebKeyboardEvent*>(event);
+ WebKeyboardEvent* result = new WebKeyboardEvent(keyboard_event);
+ return result;
+ }
+
+ if (WebInputEvent::isMouseEventType(event->type)) {
+ const WebMouseEvent& mouse_event =
+ *static_cast<const WebMouseEvent*>(event);
+ WebMouseEvent* result = new WebMouseEvent(mouse_event);
+ ConvertMouseEventToEmulated(result);
+ return result;
+ }
+
+ if (WebInputEvent::MouseWheel == event->type) {
+ const WebMouseWheelEvent& mouse_wheel_event =
+ *static_cast<const WebMouseWheelEvent*>(event);
+ WebMouseWheelEvent* result = new WebMouseWheelEvent(mouse_wheel_event);
+ ConvertMouseEventToEmulated(result);
+ return result;
+ }
+
+ if (WebInputEvent::isGestureEventType(event->type)) {
+ const WebGestureEvent& gesture_event =
+ *static_cast<const WebGestureEvent*>(event);
+ WebGestureEvent* result = new WebGestureEvent(gesture_event);
+ result->globalX = widget_rect_.x() + result->x;
+ result->globalY = widget_rect_.y() + result->y;
+ return result;
+ }
+
+ if (WebInputEvent::isTouchEventType(event->type)) {
+ const WebTouchEvent& touch_event =
+ *static_cast<const WebTouchEvent*>(event);
+ WebTouchEvent* result = new WebTouchEvent(touch_event);
+ for (size_t index = 0; index < result->touchesLength; ++index) {
+ ConvertTouchPointToEmulated(&result->touches[index]);
+ }
+ for (size_t index = 0; index < result->changedTouchesLength; ++index) {
+ ConvertTouchPointToEmulated(&result->changedTouches[index]);
+ }
+ for (size_t index = 0; index < result->targetTouchesLength; ++index) {
+ ConvertTouchPointToEmulated(&result->targetTouches[index]);
+ }
+ return result;
+ }
+
+ return NULL;
+}
+
+void RenderWidget::DeviceEmulationHelper::ConvertMouseEventToEmulated(
+ WebKit::WebMouseEvent* event) {
+ event->windowX = widget_rect_.x() + event->x;
+ event->windowY = widget_rect_.y() + event->y;
+ event->globalX = event->windowX;
+ event->globalY = event->windowY;
+}
+
+void RenderWidget::DeviceEmulationHelper::ConvertTouchPointToEmulated(
+ WebKit::WebTouchPoint* point) {
+ point->screenPosition.x = widget_rect_.x() + point->position.x;
+ point->screenPosition.y = widget_rect_.y() + point->position.y;
+}
+
+void RenderWidget::DeviceEmulationHelper::PopupCreated(
+ RenderWidget* widget, RenderWidget* popup) {
+ popup->popup_device_emulation_helper_ = weak_ptr_factory_.GetWeakPtr();
+}
+
+WebKit::WebRect RenderWidget::DeviceEmulationHelper::ConvertPopupScreenRectFromEmulated(
+ RenderWidget* popup, const WebKit::WebRect& rect) {
+ WebKit::WebRect result = rect;
+ result.x = original_view_screen_rect_.x() +
+ result.x - widget_rect_.x();
+ result.y = original_view_screen_rect_.y() +
+ result.y - widget_rect_.y();
+ return result;
+}
+
} // namespace content
« content/renderer/render_widget.h ('K') | « content/renderer/render_widget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698