Chromium Code Reviews| 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 |