blob: cb0944417a612a42d4176a4e3642d324ebeeec02 [file] [log] [blame]
[email protected]60a50072012-01-11 02:05:351// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]2cff0052011-03-18 16:51:445#include "content/renderer/render_widget.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]c27dd4f2014-05-22 18:05:197#include "base/auto_reset.h"
[email protected]32876ae2011-11-15 22:25:218#include "base/bind.h"
[email protected]4fb66842009-12-04 21:41:009#include "base/command_line.h"
initial.commit09911bf2008-07-26 23:55:2910#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/scoped_ptr.h"
[email protected]b256eca2013-07-11 10:57:4012#include "base/memory/singleton.h"
[email protected]aaf68892013-07-18 00:11:3013#include "base/message_loop/message_loop.h"
[email protected]835d7c82010-10-14 04:38:3814#include "base/metrics/histogram.h"
[email protected]aa4117f2011-12-09 22:19:2115#include "base/stl_util.h"
[email protected]74ebfb12013-06-07 20:48:0016#include "base/strings/utf_string_conversions.h"
[email protected]35b4f0c2014-06-26 16:55:2717#include "base/sys_info.h"
primiano9e38d552015-01-28 04:18:0118#include "base/trace_event/trace_event.h"
19#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]661eb9d2009-02-03 02:11:4820#include "build/build_config.h"
[email protected]681ccff2013-03-18 06:13:5221#include "cc/base/switches.h"
[email protected]adbe30f2013-10-11 21:12:3322#include "cc/debug/benchmark_instrumentation.h"
[email protected]7f0d825f2013-03-18 07:24:3023#include "cc/output/output_surface.h"
[email protected]556fd292013-03-18 08:03:0424#include "cc/trees/layer_tree_host.h"
alexclarke7fa93942015-10-21 15:37:1125#include "components/scheduler/renderer/render_widget_scheduling_state.h"
alexclarke7819e2552015-06-03 11:17:2126#include "components/scheduler/renderer/renderer_scheduler.h"
[email protected]29e2fb42013-07-19 01:13:4727#include "content/child/npapi/webplugin.h"
oshima750cb4342015-10-31 00:59:0128#include "content/common/content_switches_internal.h"
[email protected]0634cdd42013-08-16 00:46:0929#include "content/common/gpu/client/context_provider_command_buffer.h"
[email protected]ed7defa2013-03-12 21:29:5930#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
[email protected]96ab016c2013-10-23 00:50:2931#include "content/common/gpu/gpu_process_launch_causes.h"
[email protected]9017d7852013-11-21 17:47:3532#include "content/common/input/synthetic_gesture_packet.h"
[email protected]8e299aa2013-10-16 18:17:4433#include "content/common/input/web_input_event_traits.h"
[email protected]c084330e02013-04-27 01:08:1534#include "content/common/input_messages.h"
[email protected]992db4c2011-05-12 15:37:1535#include "content/common/swapped_out_messages.h"
[email protected]778574e2011-03-21 22:03:5036#include "content/common/view_messages.h"
[email protected]c08950d22011-10-13 22:20:2937#include "content/public/common/content_switches.h"
[email protected]a09d53ce2014-01-31 00:46:4238#include "content/public/common/context_menu_params.h"
[email protected]953bd0062013-08-01 00:58:4039#include "content/renderer/cursor_utils.h"
[email protected]b2e4c70132013-10-03 02:07:5140#include "content/renderer/external_popup_menu.h"
[email protected]ed7defa2013-03-12 21:29:5941#include "content/renderer/gpu/compositor_output_surface.h"
[email protected]36e5ff12013-06-11 12:19:2942#include "content/renderer/gpu/delegated_compositor_output_surface.h"
[email protected]586871b2014-07-22 17:05:1143#include "content/renderer/gpu/frame_swap_message_queue.h"
[email protected]ed7defa2013-03-12 21:29:5944#include "content/renderer/gpu/mailbox_output_surface.h"
[email protected]586871b2014-07-22 17:05:1145#include "content/renderer/gpu/queue_message_swap_promise.h"
[email protected]ba91a792013-02-06 09:48:2846#include "content/renderer/gpu/render_widget_compositor.h"
[email protected]66fca5bc2013-05-23 06:58:2947#include "content/renderer/ime_event_guard.h"
[email protected]7a72d452013-12-13 10:01:1348#include "content/renderer/input/input_handler_manager.h"
[email protected]adab2332013-07-25 18:04:3249#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
[email protected]bffc8302014-01-23 20:52:1650#include "content/renderer/render_frame_impl.h"
[email protected]e3244ed2014-06-20 20:04:2751#include "content/renderer/render_frame_proxy.h"
[email protected]8704f89b2011-04-15 00:30:0552#include "content/renderer/render_process.h"
[email protected]f1a29a02011-10-06 23:08:4453#include "content/renderer/render_thread_impl.h"
dcheng3ce04b62015-10-26 23:30:5554#include "content/renderer/render_view_impl.h"
tfarina556a7232014-10-05 01:02:0955#include "content/renderer/renderer_blink_platform_impl.h"
[email protected]5b45ad42013-10-25 00:42:0456#include "content/renderer/resizing_mode_selector.h"
[email protected]484955942010-08-19 16:13:1857#include "ipc/ipc_sync_message.h"
[email protected]661eb9d2009-02-03 02:11:4858#include "skia/ext/platform_canvas.h"
[email protected]ec173b522013-11-14 11:01:1859#include "third_party/WebKit/public/platform/WebCursorInfo.h"
[email protected]aaf68892013-07-18 00:11:3060#include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
donnda070f3c2015-01-16 19:54:1161#include "third_party/WebKit/public/platform/WebPoint.h"
[email protected]aaf68892013-07-18 00:11:3062#include "third_party/WebKit/public/platform/WebRect.h"
[email protected]ec173b522013-11-14 11:01:1863#include "third_party/WebKit/public/platform/WebScreenInfo.h"
[email protected]aaf68892013-07-18 00:11:3064#include "third_party/WebKit/public/platform/WebSize.h"
65#include "third_party/WebKit/public/platform/WebString.h"
[email protected]19193682014-04-03 15:01:4366#include "third_party/WebKit/public/web/WebDeviceEmulationParams.h"
kenrba7199832015-01-22 23:44:5967#include "third_party/WebKit/public/web/WebFrameWidget.h"
68#include "third_party/WebKit/public/web/WebLocalFrame.h"
donnda070f3c2015-01-16 19:54:1169#include "third_party/WebKit/public/web/WebNode.h"
[email protected]2255a9332013-06-17 05:12:3170#include "third_party/WebKit/public/web/WebPagePopup.h"
[email protected]2255a9332013-06-17 05:12:3171#include "third_party/WebKit/public/web/WebPopupMenuInfo.h"
72#include "third_party/WebKit/public/web/WebRange.h"
jddukeacf809e2014-09-23 20:38:3873#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
kenrba7199832015-01-22 23:44:5974#include "third_party/WebKit/public/web/WebView.h"
[email protected]d353541f2012-05-03 22:45:4175#include "third_party/skia/include/core/SkShader.h"
[email protected]faec7b12012-06-19 14:42:1376#include "ui/base/ui_base_switches.h"
tfarina655f81d2014-12-23 02:38:5077#include "ui/gfx/geometry/point_conversions.h"
tfarina3b0452d2014-12-31 15:20:0978#include "ui/gfx/geometry/rect_conversions.h"
tfarinaebe974f02015-01-03 04:25:3279#include "ui/gfx/geometry/size_conversions.h"
[email protected]1835b9e2012-02-28 13:12:4880#include "ui/gfx/skia_util.h"
[email protected]c9e2cbbb2012-05-12 21:17:2781#include "ui/gl/gl_switches.h"
[email protected]d353541f2012-05-03 22:45:4182#include "ui/surface/transport_dib.h"
[email protected]661eb9d2009-02-03 02:11:4883
[email protected]eeb93112013-05-01 19:41:1084#if defined(OS_ANDROID)
[email protected]cefe9b152014-03-27 18:16:1585#include <android/keycodes.h>
[email protected]913d99a2013-05-31 07:16:0786#include "content/renderer/android/synchronous_compositor_factory.h"
boliubee541f42015-11-05 00:52:5387#include "content/renderer/android/synchronous_compositor_filter.h"
88#include "content/renderer/android/synchronous_compositor_output_surface.h"
[email protected]eeb93112013-05-01 19:41:1089#endif
90
[email protected]661eb9d2009-02-03 02:11:4891#if defined(OS_POSIX)
[email protected]6b889fb2010-03-23 20:09:4992#include "ipc/ipc_channel_posix.h"
[email protected]d5282e72009-05-13 13:16:5293#include "third_party/skia/include/core/SkMallocPixelRef.h"
[email protected]d353541f2012-05-03 22:45:4194#include "third_party/skia/include/core/SkPixelRef.h"
[email protected]661eb9d2009-02-03 02:11:4895#endif // defined(OS_POSIX)
[email protected]8085dbc82008-09-26 22:53:4496
penghuang28a5fa22015-12-02 17:58:1997#if defined(MOJO_SHELL_CLIENT)
98#include "content/public/common/mojo_shell_connection.h"
fsamuel2545ecc2015-12-05 00:44:4699#include "content/renderer/mus/render_widget_mus_connection.h"
penghuang28a5fa22015-12-02 17:58:19100#endif
101
[email protected]2255a9332013-06-17 05:12:31102#include "third_party/WebKit/public/web/WebWidget.h"
initial.commit09911bf2008-07-26 23:55:29103
[email protected]180ef242013-11-07 06:50:46104using blink::WebCompositionUnderline;
105using blink::WebCursorInfo;
[email protected]19193682014-04-03 15:01:43106using blink::WebDeviceEmulationParams;
[email protected]180ef242013-11-07 06:50:46107using blink::WebGestureEvent;
108using blink::WebInputEvent;
dtapuska5d2e9c32015-12-03 16:39:49109using blink::WebInputEventResult;
[email protected]180ef242013-11-07 06:50:46110using blink::WebKeyboardEvent;
111using blink::WebMouseEvent;
112using blink::WebMouseWheelEvent;
113using blink::WebNavigationPolicy;
donnda070f3c2015-01-16 19:54:11114using blink::WebNode;
[email protected]180ef242013-11-07 06:50:46115using blink::WebPagePopup;
donnda070f3c2015-01-16 19:54:11116using blink::WebPoint;
[email protected]180ef242013-11-07 06:50:46117using blink::WebPopupType;
118using blink::WebRange;
119using blink::WebRect;
120using blink::WebScreenInfo;
121using blink::WebSize;
122using blink::WebTextDirection;
123using blink::WebTouchEvent;
[email protected]f8ed4722013-12-03 03:27:25124using blink::WebTouchPoint;
[email protected]180ef242013-11-07 06:50:46125using blink::WebVector;
126using blink::WebWidget;
[email protected]e9ff79c2012-10-19 21:31:26127
[email protected]6a4d7f62013-01-07 21:32:13128namespace {
[email protected]b256eca2013-07-11 10:57:40129
130typedef std::map<std::string, ui::TextInputMode> TextInputModeMap;
131
132class TextInputModeMapSingleton {
133 public:
134 static TextInputModeMapSingleton* GetInstance() {
olli.raula36aa8be2015-09-10 11:14:22135 return base::Singleton<TextInputModeMapSingleton>::get();
[email protected]b256eca2013-07-11 10:57:40136 }
[email protected]dd705d4d2013-11-27 08:14:41137 TextInputModeMapSingleton() {
138 map_["verbatim"] = ui::TEXT_INPUT_MODE_VERBATIM;
139 map_["latin"] = ui::TEXT_INPUT_MODE_LATIN;
140 map_["latin-name"] = ui::TEXT_INPUT_MODE_LATIN_NAME;
141 map_["latin-prose"] = ui::TEXT_INPUT_MODE_LATIN_PROSE;
142 map_["full-width-latin"] = ui::TEXT_INPUT_MODE_FULL_WIDTH_LATIN;
143 map_["kana"] = ui::TEXT_INPUT_MODE_KANA;
144 map_["katakana"] = ui::TEXT_INPUT_MODE_KATAKANA;
145 map_["numeric"] = ui::TEXT_INPUT_MODE_NUMERIC;
146 map_["tel"] = ui::TEXT_INPUT_MODE_TEL;
147 map_["email"] = ui::TEXT_INPUT_MODE_EMAIL;
148 map_["url"] = ui::TEXT_INPUT_MODE_URL;
[email protected]b256eca2013-07-11 10:57:40149 }
[email protected]dd705d4d2013-11-27 08:14:41150 const TextInputModeMap& map() const { return map_; }
[email protected]b256eca2013-07-11 10:57:40151 private:
[email protected]dd705d4d2013-11-27 08:14:41152 TextInputModeMap map_;
[email protected]b256eca2013-07-11 10:57:40153
olli.raula36aa8be2015-09-10 11:14:22154 friend struct base::DefaultSingletonTraits<TextInputModeMapSingleton>;
[email protected]b256eca2013-07-11 10:57:40155
156 DISALLOW_COPY_AND_ASSIGN(TextInputModeMapSingleton);
157};
158
[email protected]dd705d4d2013-11-27 08:14:41159ui::TextInputMode ConvertInputMode(const blink::WebString& input_mode) {
[email protected]b256eca2013-07-11 10:57:40160 static TextInputModeMapSingleton* singleton =
161 TextInputModeMapSingleton::GetInstance();
[email protected]dd705d4d2013-11-27 08:14:41162 TextInputModeMap::const_iterator it =
163 singleton->map().find(input_mode.utf8());
164 if (it == singleton->map().end())
[email protected]b256eca2013-07-11 10:57:40165 return ui::TEXT_INPUT_MODE_DEFAULT;
166 return it->second;
[email protected]6a4d7f62013-01-07 21:32:13167}
[email protected]b256eca2013-07-11 10:57:40168
[email protected]fd847792013-10-24 17:12:35169// TODO(brianderson): Replace the hard-coded threshold with a fraction of
170// the BeginMainFrame interval.
171// 4166us will allow 1/4 of a 60Hz interval or 1/2 of a 120Hz interval to
172// be spent in input hanlders before input starts getting throttled.
173const int kInputHandlingTimeThrottlingThresholdMicroseconds = 4166;
174
miletus14a25642015-08-13 19:23:23175int64 GetEventLatencyMicros(double event_timestamp, base::TimeTicks now) {
176 return (now - base::TimeDelta::FromSecondsD(event_timestamp))
jdduke07788062014-12-05 03:16:30177 .ToInternalValue();
178}
179
miletus14a25642015-08-13 19:23:23180void LogInputEventLatencyUmaImpl(WebInputEvent::Type event_type,
181 double event_timestamp,
182 base::TimeTicks now) {
183 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.AggregatedLatency.Renderer2",
184 GetEventLatencyMicros(event_timestamp, now), 1,
185 10000000, 100);
jdduke07788062014-12-05 03:16:30186
miletus14a25642015-08-13 19:23:23187#define CASE_TYPE(t) \
188 case WebInputEvent::t: \
189 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Renderer2." #t, \
190 GetEventLatencyMicros(event_timestamp, now), \
191 1, 10000000, 100); \
192 break;
jdduke07788062014-12-05 03:16:30193
miletus14a25642015-08-13 19:23:23194 switch (event_type) {
jdduke07788062014-12-05 03:16:30195 CASE_TYPE(Undefined);
196 CASE_TYPE(MouseDown);
197 CASE_TYPE(MouseUp);
198 CASE_TYPE(MouseMove);
199 CASE_TYPE(MouseEnter);
200 CASE_TYPE(MouseLeave);
201 CASE_TYPE(ContextMenu);
202 CASE_TYPE(MouseWheel);
203 CASE_TYPE(RawKeyDown);
204 CASE_TYPE(KeyDown);
205 CASE_TYPE(KeyUp);
206 CASE_TYPE(Char);
207 CASE_TYPE(GestureScrollBegin);
208 CASE_TYPE(GestureScrollEnd);
209 CASE_TYPE(GestureScrollUpdate);
210 CASE_TYPE(GestureFlingStart);
211 CASE_TYPE(GestureFlingCancel);
212 CASE_TYPE(GestureShowPress);
213 CASE_TYPE(GestureTap);
214 CASE_TYPE(GestureTapUnconfirmed);
215 CASE_TYPE(GestureTapDown);
216 CASE_TYPE(GestureTapCancel);
217 CASE_TYPE(GestureDoubleTap);
218 CASE_TYPE(GestureTwoFingerTap);
219 CASE_TYPE(GestureLongPress);
220 CASE_TYPE(GestureLongTap);
221 CASE_TYPE(GesturePinchBegin);
222 CASE_TYPE(GesturePinchEnd);
223 CASE_TYPE(GesturePinchUpdate);
224 CASE_TYPE(TouchStart);
225 CASE_TYPE(TouchMove);
226 CASE_TYPE(TouchEnd);
227 CASE_TYPE(TouchCancel);
228 default:
229 // Must include default to let blink::WebInputEvent add new event types
230 // before they're added here.
miletus14a25642015-08-13 19:23:23231 DLOG(WARNING) << "Unhandled WebInputEvent type: " << event_type;
jdduke07788062014-12-05 03:16:30232 break;
233 }
234
235#undef CASE_TYPE
236}
237
miletus14a25642015-08-13 19:23:23238void LogInputEventLatencyUma(const WebInputEvent& event, base::TimeTicks now,
239 const ui::LatencyInfo& latency_info) {
240 LogInputEventLatencyUmaImpl(event.type, event.timeStampSeconds, now);
241 for (size_t i = 0; i < latency_info.coalesced_events_size(); i++) {
242 LogInputEventLatencyUmaImpl(
243 event.type,
244 latency_info.timestamps_of_coalesced_events()[i],
245 now);
246 }
247}
248
dtapuskae7473612015-12-04 14:23:06249void LogPassiveLatency(int64 latency) {
250 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.PassiveListeners.Latency", latency, 1,
251 10000000, 100);
252}
253
254void LogPassiveEventListenersUma(WebInputEventResult result,
255 bool passive,
256 bool cancelable,
257 double event_timestamp,
258 const ui::LatencyInfo& latency_info) {
259 enum {
260 PASSIVE_LISTENER_UMA_ENUM_PASSIVE,
261 PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE,
262 PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED,
263 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE,
264 PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED,
265 PASSIVE_LISTENER_UMA_ENUM_COUNT
266 };
267
268 int enum_value;
269 if (passive)
270 enum_value = PASSIVE_LISTENER_UMA_ENUM_PASSIVE;
271 else if (!cancelable)
272 enum_value = PASSIVE_LISTENER_UMA_ENUM_UNCANCELABLE;
273 else if (result == WebInputEventResult::HandledApplication)
274 enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE_AND_CANCELED;
275 else if (result == WebInputEventResult::HandledSuppressed)
276 enum_value = PASSIVE_LISTENER_UMA_ENUM_SUPPRESSED;
277 else
278 enum_value = PASSIVE_LISTENER_UMA_ENUM_CANCELABLE;
279
280 UMA_HISTOGRAM_ENUMERATION("Event.PassiveListeners", enum_value,
281 PASSIVE_LISTENER_UMA_ENUM_COUNT);
282
283 if (enum_value == PASSIVE_LISTENER_UMA_ENUM_CANCELABLE &&
284 base::TimeTicks::IsHighResolution()) {
285 base::TimeTicks now = base::TimeTicks::Now();
286 LogPassiveLatency(GetEventLatencyMicros(event_timestamp, now));
287 for (size_t i = 0; i < latency_info.coalesced_events_size(); i++)
288 LogPassiveLatency(GetEventLatencyMicros(
289 latency_info.timestamps_of_coalesced_events()[i], now));
290 }
291}
292
[email protected]b256eca2013-07-11 10:57:40293} // namespace
294
[email protected]e9ff79c2012-10-19 21:31:26295namespace content {
[email protected]62cb33cae2009-03-27 23:30:22296
[email protected]b2e4c70132013-10-03 02:07:51297// RenderWidget::ScreenMetricsEmulator ----------------------------------------
298
299class RenderWidget::ScreenMetricsEmulator {
300 public:
301 ScreenMetricsEmulator(
302 RenderWidget* widget,
[email protected]19193682014-04-03 15:01:43303 const WebDeviceEmulationParams& params);
[email protected]b2e4c70132013-10-03 02:07:51304 virtual ~ScreenMetricsEmulator();
305
[email protected]19193682014-04-03 15:01:43306 // Scale and offset used to convert between host coordinates
307 // and webwidget coordinates.
[email protected]b2e4c70132013-10-03 02:07:51308 float scale() { return scale_; }
dgozman9260b0a12015-03-16 13:45:20309 gfx::PointF offset() { return offset_; }
[email protected]19193682014-04-03 15:01:43310 gfx::Rect applied_widget_rect() const { return applied_widget_rect_; }
[email protected]b2e4c70132013-10-03 02:07:51311 gfx::Rect original_screen_rect() const { return original_view_screen_rect_; }
[email protected]5f75aa42014-04-01 23:00:56312 const WebScreenInfo& original_screen_info() { return original_screen_info_; }
[email protected]b2e4c70132013-10-03 02:07:51313
314 void ChangeEmulationParams(
[email protected]19193682014-04-03 15:01:43315 const WebDeviceEmulationParams& params);
[email protected]b2e4c70132013-10-03 02:07:51316
317 // The following methods alter handlers' behavior for messages related to
318 // widget size and position.
319 void OnResizeMessage(const ViewMsg_Resize_Params& params);
320 void OnUpdateScreenRectsMessage(const gfx::Rect& view_screen_rect,
321 const gfx::Rect& window_screen_rect);
322 void OnShowContextMenu(ContextMenuParams* params);
[email protected]2d6836f42014-07-02 17:25:31323 gfx::Rect AdjustValidationMessageAnchor(const gfx::Rect& anchor);
[email protected]b2e4c70132013-10-03 02:07:51324
325 private:
[email protected]19193682014-04-03 15:01:43326 void Reapply();
dtrainorcb7779b82014-12-04 01:08:02327 void Apply(bool top_controls_shrink_blink_size,
328 float top_controls_height,
[email protected]bb6378fe2014-04-28 21:19:44329 gfx::Rect resizer_rect,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12330 bool is_fullscreen_granted,
331 blink::WebDisplayMode display_mode);
[email protected]b2e4c70132013-10-03 02:07:51332
333 RenderWidget* widget_;
334
[email protected]7f99fc22013-11-08 14:05:58335 // Parameters as passed by RenderWidget::EnableScreenMetricsEmulation.
[email protected]19193682014-04-03 15:01:43336 WebDeviceEmulationParams params_;
[email protected]b2e4c70132013-10-03 02:07:51337
[email protected]a179d3962013-11-12 14:44:40338 // The computed scale and offset used to fit widget into browser window.
[email protected]b2e4c70132013-10-03 02:07:51339 float scale_;
dgozman9260b0a12015-03-16 13:45:20340 gfx::PointF offset_;
[email protected]b2e4c70132013-10-03 02:07:51341
[email protected]19193682014-04-03 15:01:43342 // Widget rect as passed to webwidget.
343 gfx::Rect applied_widget_rect_;
344
[email protected]b2e4c70132013-10-03 02:07:51345 // Original values to restore back after emulation ends.
346 gfx::Size original_size_;
347 gfx::Size original_physical_backing_size_;
[email protected]6949e0d22014-06-02 22:39:28348 gfx::Size original_visible_viewport_size_;
[email protected]180ef242013-11-07 06:50:46349 blink::WebScreenInfo original_screen_info_;
[email protected]b2e4c70132013-10-03 02:07:51350 gfx::Rect original_view_screen_rect_;
351 gfx::Rect original_window_screen_rect_;
352};
353
354RenderWidget::ScreenMetricsEmulator::ScreenMetricsEmulator(
355 RenderWidget* widget,
[email protected]19193682014-04-03 15:01:43356 const WebDeviceEmulationParams& params)
[email protected]b2e4c70132013-10-03 02:07:51357 : widget_(widget),
[email protected]19193682014-04-03 15:01:43358 params_(params),
[email protected]b2e4c70132013-10-03 02:07:51359 scale_(1.f) {
360 original_size_ = widget_->size_;
361 original_physical_backing_size_ = widget_->physical_backing_size_;
[email protected]6949e0d22014-06-02 22:39:28362 original_visible_viewport_size_ = widget_->visible_viewport_size_;
[email protected]b2e4c70132013-10-03 02:07:51363 original_screen_info_ = widget_->screen_info_;
364 original_view_screen_rect_ = widget_->view_screen_rect_;
365 original_window_screen_rect_ = widget_->window_screen_rect_;
dtrainorcb7779b82014-12-04 01:08:02366 Apply(widget_->top_controls_shrink_blink_size_,
367 widget_->top_controls_height_,
368 widget_->resizer_rect_,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12369 widget_->is_fullscreen_granted_,
370 widget_->display_mode_);
[email protected]b2e4c70132013-10-03 02:07:51371}
372
373RenderWidget::ScreenMetricsEmulator::~ScreenMetricsEmulator() {
374 widget_->screen_info_ = original_screen_info_;
375
376 widget_->SetDeviceScaleFactor(original_screen_info_.deviceScaleFactor);
dgozman9260b0a12015-03-16 13:45:20377 widget_->SetScreenMetricsEmulationParameters(false, params_);
[email protected]b2e4c70132013-10-03 02:07:51378 widget_->view_screen_rect_ = original_view_screen_rect_;
379 widget_->window_screen_rect_ = original_window_screen_rect_;
[email protected]587941d2014-08-22 01:40:01380 widget_->Resize(original_size_,
381 original_physical_backing_size_,
dtrainorcb7779b82014-12-04 01:08:02382 widget_->top_controls_shrink_blink_size_,
383 widget_->top_controls_height_,
[email protected]587941d2014-08-22 01:40:01384 original_visible_viewport_size_,
385 widget_->resizer_rect_,
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12386 widget_->is_fullscreen_granted_,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12387 widget_->display_mode_,
[email protected]587941d2014-08-22 01:40:01388 NO_RESIZE_ACK);
[email protected]b2e4c70132013-10-03 02:07:51389}
390
391void RenderWidget::ScreenMetricsEmulator::ChangeEmulationParams(
[email protected]19193682014-04-03 15:01:43392 const WebDeviceEmulationParams& params) {
393 params_ = params;
394 Reapply();
395}
396
397void RenderWidget::ScreenMetricsEmulator::Reapply() {
dtrainorcb7779b82014-12-04 01:08:02398 Apply(widget_->top_controls_shrink_blink_size_,
399 widget_->top_controls_height_,
400 widget_->resizer_rect_,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12401 widget_->is_fullscreen_granted_,
402 widget_->display_mode_);
[email protected]b2e4c70132013-10-03 02:07:51403}
404
[email protected]19193682014-04-03 15:01:43405void RenderWidget::ScreenMetricsEmulator::Apply(
dtrainorcb7779b82014-12-04 01:08:02406 bool top_controls_shrink_blink_size,
407 float top_controls_height,
[email protected]bb6378fe2014-04-28 21:19:44408 gfx::Rect resizer_rect,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12409 bool is_fullscreen_granted,
410 blink::WebDisplayMode display_mode) {
[email protected]92d13b72014-05-09 14:42:31411 applied_widget_rect_.set_size(gfx::Size(params_.viewSize));
412 if (!applied_widget_rect_.width())
413 applied_widget_rect_.set_width(original_size_.width());
414 if (!applied_widget_rect_.height())
415 applied_widget_rect_.set_height(original_size_.height());
[email protected]19193682014-04-03 15:01:43416
[email protected]f442ee42014-05-14 11:53:12417 if (params_.fitToView && !original_size_.IsEmpty()) {
[email protected]0b3578c2014-06-20 18:29:02418 int original_width = std::max(original_size_.width(), 1);
419 int original_height = std::max(original_size_.height(), 1);
[email protected]b2e4c70132013-10-03 02:07:51420 float width_ratio =
[email protected]0b3578c2014-06-20 18:29:02421 static_cast<float>(applied_widget_rect_.width()) / original_width;
[email protected]b2e4c70132013-10-03 02:07:51422 float height_ratio =
[email protected]0b3578c2014-06-20 18:29:02423 static_cast<float>(applied_widget_rect_.height()) / original_height;
[email protected]b2e4c70132013-10-03 02:07:51424 float ratio = std::max(1.0f, std::max(width_ratio, height_ratio));
425 scale_ = 1.f / ratio;
[email protected]7f0e8fa2014-03-26 12:32:01426
427 // Center emulated view inside available view space.
[email protected]19193682014-04-03 15:01:43428 offset_.set_x(
429 (original_size_.width() - scale_ * applied_widget_rect_.width()) / 2);
[email protected]7f0e8fa2014-03-26 12:32:01430 offset_.set_y(
[email protected]19193682014-04-03 15:01:43431 (original_size_.height() - scale_ * applied_widget_rect_.height()) / 2);
[email protected]b2e4c70132013-10-03 02:07:51432 } else {
[email protected]0b3578c2014-06-20 18:29:02433 scale_ = params_.scale;
434 offset_.SetPoint(params_.offset.x, params_.offset.y);
[email protected]7f0e8fa2014-03-26 12:32:01435 }
[email protected]7f0e8fa2014-03-26 12:32:01436
[email protected]19193682014-04-03 15:01:43437 if (params_.screenPosition == WebDeviceEmulationParams::Desktop) {
438 applied_widget_rect_.set_origin(original_view_screen_rect_.origin());
[email protected]7f0e8fa2014-03-26 12:32:01439 widget_->screen_info_.rect = original_screen_info_.rect;
440 widget_->screen_info_.availableRect = original_screen_info_.availableRect;
441 widget_->window_screen_rect_ = original_window_screen_rect_;
442 } else {
dgozmanf28ccbe2015-06-24 08:50:49443 applied_widget_rect_.set_origin(params_.viewPosition);
444 gfx::Rect screen_rect = applied_widget_rect_;
445 if (!params_.screenSize.isEmpty()) {
446 screen_rect =
447 gfx::Rect(0, 0, params_.screenSize.width, params_.screenSize.height);
448 }
449 widget_->screen_info_.rect = screen_rect;
450 widget_->screen_info_.availableRect = screen_rect;
[email protected]19193682014-04-03 15:01:43451 widget_->window_screen_rect_ = applied_widget_rect_;
[email protected]7f0e8fa2014-03-26 12:32:01452 }
[email protected]a179d3962013-11-12 14:44:40453
[email protected]19193682014-04-03 15:01:43454 float applied_device_scale_factor = params_.deviceScaleFactor ?
455 params_.deviceScaleFactor : original_screen_info_.deviceScaleFactor;
[email protected]7f0e8fa2014-03-26 12:32:01456 widget_->screen_info_.deviceScaleFactor = applied_device_scale_factor;
[email protected]b2e4c70132013-10-03 02:07:51457
[email protected]7f99fc22013-11-08 14:05:58458 // Pass three emulation parameters to the blink side:
[email protected]b2e4c70132013-10-03 02:07:51459 // - we keep the real device scale factor in compositor to produce sharp image
460 // even when emulating different scale factor;
[email protected]7f99fc22013-11-08 14:05:58461 // - in order to fit into view, WebView applies offset and scale to the
[email protected]b2e4c70132013-10-03 02:07:51462 // root layer.
dgozman9260b0a12015-03-16 13:45:20463 blink::WebDeviceEmulationParams modified_params = params_;
464 modified_params.deviceScaleFactor = original_screen_info_.deviceScaleFactor;
465 modified_params.offset = blink::WebFloatPoint(offset_.x(), offset_.y());
466 modified_params.scale = scale_;
467 widget_->SetScreenMetricsEmulationParameters(true, modified_params);
[email protected]b2e4c70132013-10-03 02:07:51468
[email protected]7f0e8fa2014-03-26 12:32:01469 widget_->SetDeviceScaleFactor(applied_device_scale_factor);
[email protected]19193682014-04-03 15:01:43470 widget_->view_screen_rect_ = applied_widget_rect_;
[email protected]b2e4c70132013-10-03 02:07:51471
danakjddaec912015-09-25 19:38:40472 gfx::Size physical_backing_size = gfx::ScaleToCeiledSize(
473 original_size_, original_screen_info_.deviceScaleFactor);
dtrainorcb7779b82014-12-04 01:08:02474 widget_->Resize(applied_widget_rect_.size(),
475 physical_backing_size,
476 top_controls_shrink_blink_size,
477 top_controls_height,
478 applied_widget_rect_.size(),
479 resizer_rect,
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12480 is_fullscreen_granted,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12481 display_mode,
dtrainorcb7779b82014-12-04 01:08:02482 NO_RESIZE_ACK);
[email protected]b2e4c70132013-10-03 02:07:51483}
484
485void RenderWidget::ScreenMetricsEmulator::OnResizeMessage(
486 const ViewMsg_Resize_Params& params) {
487 bool need_ack = params.new_size != original_size_ &&
488 !params.new_size.IsEmpty() && !params.physical_backing_size.IsEmpty();
489 original_size_ = params.new_size;
490 original_physical_backing_size_ = params.physical_backing_size;
491 original_screen_info_ = params.screen_info;
[email protected]6949e0d22014-06-02 22:39:28492 original_visible_viewport_size_ = params.visible_viewport_size;
dtrainorcb7779b82014-12-04 01:08:02493 Apply(params.top_controls_shrink_blink_size,
494 params.top_controls_height,
495 params.resizer_rect,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12496 params.is_fullscreen_granted,
497 params.display_mode);
[email protected]b2e4c70132013-10-03 02:07:51498
499 if (need_ack) {
500 widget_->set_next_paint_is_resize_ack();
501 if (widget_->compositor_)
502 widget_->compositor_->SetNeedsRedrawRect(gfx::Rect(widget_->size_));
503 }
504}
505
506void RenderWidget::ScreenMetricsEmulator::OnUpdateScreenRectsMessage(
507 const gfx::Rect& view_screen_rect,
508 const gfx::Rect& window_screen_rect) {
509 original_view_screen_rect_ = view_screen_rect;
510 original_window_screen_rect_ = window_screen_rect;
[email protected]19193682014-04-03 15:01:43511 if (params_.screenPosition == WebDeviceEmulationParams::Desktop)
512 Reapply();
[email protected]b2e4c70132013-10-03 02:07:51513}
514
515void RenderWidget::ScreenMetricsEmulator::OnShowContextMenu(
516 ContextMenuParams* params) {
517 params->x *= scale_;
[email protected]a179d3962013-11-12 14:44:40518 params->x += offset_.x();
[email protected]b2e4c70132013-10-03 02:07:51519 params->y *= scale_;
[email protected]a179d3962013-11-12 14:44:40520 params->y += offset_.y();
[email protected]b2e4c70132013-10-03 02:07:51521}
522
[email protected]2d6836f42014-07-02 17:25:31523gfx::Rect RenderWidget::ScreenMetricsEmulator::AdjustValidationMessageAnchor(
524 const gfx::Rect& anchor) {
danakj4606f6332015-08-31 23:56:56525 gfx::Rect scaled = gfx::ScaleToEnclosedRect(anchor, scale_);
[email protected]2d6836f42014-07-02 17:25:31526 scaled.set_x(scaled.x() + offset_.x());
527 scaled.set_y(scaled.y() + offset_.y());
528 return scaled;
529}
530
[email protected]b2e4c70132013-10-03 02:07:51531// RenderWidget ---------------------------------------------------------------
532
dcheng35d31c112015-07-22 00:17:36533RenderWidget::RenderWidget(CompositorDependencies* compositor_deps,
534 blink::WebPopupType popup_type,
[email protected]180ef242013-11-07 06:50:46535 const blink::WebScreenInfo& screen_info,
[email protected]1ac10dca2013-08-20 20:47:04536 bool swapped_out,
[email protected]7912e822014-04-16 02:37:03537 bool hidden,
538 bool never_visible)
initial.commit09911bf2008-07-26 23:55:29539 : routing_id_(MSG_ROUTING_NONE),
dcheng35d31c112015-07-22 00:17:36540 compositor_deps_(compositor_deps),
danakj6e3bf8012014-12-16 18:27:53541 webwidget_(nullptr),
initial.commit09911bf2008-07-26 23:55:29542 opener_id_(MSG_ROUTING_NONE),
dtrainorcb7779b82014-12-04 01:08:02543 top_controls_shrink_blink_size_(false),
544 top_controls_height_(0.f),
initial.commit09911bf2008-07-26 23:55:29545 next_paint_flags_(0),
[email protected]847a2582013-03-09 02:29:51546 auto_resize_mode_(false),
[email protected]ea3ee0a2012-05-15 03:43:09547 need_update_rect_for_auto_resize_(false),
initial.commit09911bf2008-07-26 23:55:29548 did_show_(false),
[email protected]1ac10dca2013-08-20 20:47:04549 is_hidden_(hidden),
sievers71c62dd52015-10-07 01:44:39550 compositor_never_visible_(never_visible),
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12551 is_fullscreen_granted_(false),
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12552 display_mode_(blink::WebDisplayModeUndefined),
[email protected]5dd768212009-08-13 23:34:49553 handling_input_event_(false),
jddukec05612b2015-06-25 23:13:18554 handling_event_overscroll_(nullptr),
changwanf2a707b2015-10-30 08:22:16555 ime_event_guard_(nullptr),
[email protected]c27dd4f2014-05-22 18:05:19556 handling_event_type_(WebInputEvent::Undefined),
557 ignore_ack_for_mouse_move_from_debugger_(false),
[email protected]661eb9d2009-02-03 02:11:48558 closing_(false),
[email protected]aeeedad2014-08-22 18:16:22559 host_closing_(false),
[email protected]14392a52012-05-02 20:28:44560 is_swapped_out_(swapped_out),
simonhong628f9812015-04-27 23:13:20561 for_oopif_(false),
[email protected]ad26ef42011-06-17 07:59:45562 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
[email protected]b256eca2013-07-11 10:57:40563 text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
shuchen82ce8c52014-10-23 01:55:20564 text_input_flags_(0),
[email protected]86ba5fcb2013-09-04 00:36:53565 can_compose_inline_(true),
[email protected]3e2b375b2010-04-07 17:03:12566 popup_type_(popup_type),
[email protected]867125a02009-12-10 06:01:48567 pending_window_rect_count_(0),
[email protected]b68a0e52011-12-08 15:11:12568 suppress_next_char_events_(false),
[email protected]842f10652012-06-06 01:54:04569 screen_info_(screen_info),
[email protected]3d779472012-11-15 20:49:52570 device_scale_factor_(screen_info_.deviceScaleFactor),
[email protected]53b4cc12013-07-18 23:02:30571 next_output_surface_id_(0),
[email protected]0d1ebed12013-08-05 22:01:13572#if defined(OS_ANDROID)
[email protected]90f24152014-04-09 12:41:36573 text_field_is_dirty_(false),
[email protected]0d1ebed12013-08-05 22:01:13574#endif
[email protected]b2e4c70132013-10-03 02:07:51575 popup_origin_scale_for_emulation_(0.f),
[email protected]586871b2014-07-22 17:05:11576 frame_swap_message_queue_(new FrameSwapMessageQueue()),
[email protected]a09d53ce2014-01-31 00:46:42577 resizing_mode_selector_(new ResizingModeSelector()),
[email protected]be1af0662014-07-29 19:55:51578 context_menu_source_type_(ui::MENU_SOURCE_MOUSE),
579 has_host_context_menu_location_(false) {
[email protected]8b3f0eb2012-05-03 19:15:05580 if (!swapped_out)
581 RenderProcess::current()->AddRefProcess();
[email protected]380244092011-10-07 17:26:27582 DCHECK(RenderThread::Get());
[email protected]3079c28a2014-06-24 03:38:53583 device_color_profile_.push_back('0');
changwan3a841162015-08-11 02:53:37584#if defined(OS_ANDROID)
585 text_input_info_history_.push_back(blink::WebTextInputInfo());
586#endif
alexclarke7fa93942015-10-21 15:37:11587
588 // In tests there may not be a RenderThreadImpl.
589 if (RenderThreadImpl::current()) {
590 render_widget_scheduling_state_ = RenderThreadImpl::current()
591 ->GetRendererScheduler()
592 ->NewRenderWidgetSchedulingState()
593 .Pass();
594 render_widget_scheduling_state_->SetHidden(is_hidden_);
595 }
initial.commit09911bf2008-07-26 23:55:29596}
597
598RenderWidget::~RenderWidget() {
[email protected]c5b3b5e2009-02-13 06:41:11599 DCHECK(!webwidget_) << "Leaking our WebWidget!";
[email protected]bffc8302014-01-23 20:52:16600
[email protected]992db4c2011-05-12 15:37:15601 // If we are swapped out, we have released already.
[email protected]d2e2f9ee2013-08-21 11:02:02602 if (!is_swapped_out_ && RenderProcess::current())
[email protected]992db4c2011-05-12 15:37:15603 RenderProcess::current()->ReleaseProcess();
initial.commit09911bf2008-07-26 23:55:29604}
605
[email protected]484955942010-08-19 16:13:18606// static
[email protected]8085dbc82008-09-26 22:53:44607RenderWidget* RenderWidget::Create(int32 opener_id,
danakj6e3bf8012014-12-16 18:27:53608 CompositorDependencies* compositor_deps,
[email protected]180ef242013-11-07 06:50:46609 blink::WebPopupType popup_type,
610 const blink::WebScreenInfo& screen_info) {
initial.commit09911bf2008-07-26 23:55:29611 DCHECK(opener_id != MSG_ROUTING_NONE);
dcheng35d31c112015-07-22 00:17:36612 scoped_refptr<RenderWidget> widget(new RenderWidget(
613 compositor_deps, popup_type, screen_info, false, false, false));
614 if (widget->Init(opener_id)) { // adds reference on success.
[email protected]fc72bb12013-06-02 21:13:46615 return widget.get();
[email protected]a635f942012-12-07 10:34:29616 }
617 return NULL;
initial.commit09911bf2008-07-26 23:55:29618}
619
[email protected]484955942010-08-19 16:13:18620// static
kenrba7199832015-01-22 23:44:59621RenderWidget* RenderWidget::CreateForFrame(
622 int routing_id,
kenrba7199832015-01-22 23:44:59623 bool hidden,
624 const blink::WebScreenInfo& screen_info,
625 CompositorDependencies* compositor_deps,
626 blink::WebLocalFrame* frame) {
627 CHECK_NE(routing_id, MSG_ROUTING_NONE);
dcheng3ce04b62015-10-26 23:30:55628 // TODO(avi): Before RenderViewImpl has-a RenderWidget, the browser passes the
629 // same routing ID for both the view routing ID and the main frame widget
630 // routing ID. https://crbug.com/545684
631 RenderViewImpl* view = RenderViewImpl::FromRoutingID(routing_id);
632 if (view) {
633 view->AttachWebFrameWidget(RenderWidget::CreateWebFrameWidget(view, frame));
634 return view;
635 }
dcheng35d31c112015-07-22 00:17:36636 scoped_refptr<RenderWidget> widget(
637 new RenderWidget(compositor_deps, blink::WebPopupTypeNone, screen_info,
638 false, hidden, false));
kenrba7199832015-01-22 23:44:59639 widget->routing_id_ = routing_id;
simonhong628f9812015-04-27 23:13:20640 widget->for_oopif_ = true;
kenrba7199832015-01-22 23:44:59641 // DoInit increments the reference count on |widget|, keeping it alive after
642 // this function returns.
dcheng35d31c112015-07-22 00:17:36643 if (widget->DoInit(MSG_ROUTING_NONE,
kenrba7199832015-01-22 23:44:59644 RenderWidget::CreateWebFrameWidget(widget.get(), frame),
645 nullptr)) {
kenrba7199832015-01-22 23:44:59646 return widget.get();
647 }
648 return nullptr;
649}
650
651// static
dchengda9b4bb2015-07-20 20:58:08652blink::WebWidget* RenderWidget::CreateWebFrameWidget(
653 RenderWidget* render_widget,
654 blink::WebLocalFrame* frame) {
dcheng3ce04b62015-10-26 23:30:55655 if (!frame->parent()) {
656 // TODO(dcheng): The main frame widget currently has a special case.
657 // Eliminate this once WebView is no longer a WebWidget.
658 return blink::WebFrameWidget::create(render_widget, frame->view(), frame);
659 }
dchengda9b4bb2015-07-20 20:58:08660 return blink::WebFrameWidget::create(render_widget, frame);
661}
662
663// static
kenrba7199832015-01-22 23:44:59664blink::WebWidget* RenderWidget::CreateWebWidget(RenderWidget* render_widget) {
[email protected]484955942010-08-19 16:13:18665 switch (render_widget->popup_type_) {
[email protected]180ef242013-11-07 06:50:46666 case blink::WebPopupTypeNone: // Nothing to create.
[email protected]484955942010-08-19 16:13:18667 break;
[email protected]180ef242013-11-07 06:50:46668 case blink::WebPopupTypePage:
[email protected]a7547fb2012-03-08 04:43:44669 return WebPagePopup::create(render_widget);
[email protected]484955942010-08-19 16:13:18670 default:
671 NOTREACHED();
672 }
673 return NULL;
674}
675
dchengda9b4bb2015-07-20 20:58:08676void RenderWidget::CloseForFrame() {
dchengd96a27a2015-07-24 20:17:32677 OnClose();
kenrba7199832015-01-22 23:44:59678}
679
dcheng35d31c112015-07-22 00:17:36680bool RenderWidget::Init(int32 opener_id) {
piman5d36dae2015-09-24 22:47:05681 return DoInit(
682 opener_id, RenderWidget::CreateWebWidget(this),
683 new ViewHostMsg_CreateWidget(opener_id, popup_type_, &routing_id_));
[email protected]484955942010-08-19 16:13:18684}
685
[email protected]a635f942012-12-07 10:34:29686bool RenderWidget::DoInit(int32 opener_id,
[email protected]6a8ddba52010-09-05 04:38:06687 WebWidget* web_widget,
[email protected]484955942010-08-19 16:13:18688 IPC::SyncMessage* create_widget_message) {
initial.commit09911bf2008-07-26 23:55:29689 DCHECK(!webwidget_);
690
691 if (opener_id != MSG_ROUTING_NONE)
692 opener_id_ = opener_id;
693
[email protected]484955942010-08-19 16:13:18694 webwidget_ = web_widget;
initial.commit09911bf2008-07-26 23:55:29695
kenrba7199832015-01-22 23:44:59696 bool result = true;
697 if (create_widget_message)
698 result = RenderThread::Get()->Send(create_widget_message);
699
initial.commit09911bf2008-07-26 23:55:29700 if (result) {
[email protected]380244092011-10-07 17:26:27701 RenderThread::Get()->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29702 // Take a reference on behalf of the RenderThread. This will be balanced
703 // when we receive ViewMsg_Close.
704 AddRef();
[email protected]b2db9272014-01-10 17:42:00705 if (RenderThreadImpl::current()) {
706 RenderThreadImpl::current()->WidgetCreated();
707 if (is_hidden_)
708 RenderThreadImpl::current()->WidgetHidden();
709 }
[email protected]a635f942012-12-07 10:34:29710 return true;
initial.commit09911bf2008-07-26 23:55:29711 } else {
[email protected]a635f942012-12-07 10:34:29712 // The above Send can fail when the tab is closing.
713 return false;
initial.commit09911bf2008-07-26 23:55:29714 }
715}
716
[email protected]992db4c2011-05-12 15:37:15717void RenderWidget::SetSwappedOut(bool is_swapped_out) {
718 // We should only toggle between states.
719 DCHECK(is_swapped_out_ != is_swapped_out);
720 is_swapped_out_ = is_swapped_out;
721
722 // If we are swapping out, we will call ReleaseProcess, allowing the process
723 // to exit if all of its RenderViews are swapped out. We wait until the
[email protected]949b6592014-08-20 13:17:52724 // WasSwappedOut call to do this, to allow the unload handler to finish.
[email protected]992db4c2011-05-12 15:37:15725 // If we are swapping in, we call AddRefProcess to prevent the process from
726 // exiting.
[email protected]949b6592014-08-20 13:17:52727 if (!is_swapped_out_)
[email protected]992db4c2011-05-12 15:37:15728 RenderProcess::current()->AddRefProcess();
729}
730
[email protected]949b6592014-08-20 13:17:52731void RenderWidget::WasSwappedOut() {
732 // If we have been swapped out and no one else is using this process,
733 // it's safe to exit now.
734 CHECK(is_swapped_out_);
735 RenderProcess::current()->ReleaseProcess();
736}
737
[email protected]b2e4c70132013-10-03 02:07:51738void RenderWidget::SetPopupOriginAdjustmentsForEmulation(
739 ScreenMetricsEmulator* emulator) {
740 popup_origin_scale_for_emulation_ = emulator->scale();
[email protected]19193682014-04-03 15:01:43741 popup_view_origin_for_emulation_ = emulator->applied_widget_rect().origin();
[email protected]9a2d7ee32013-12-05 12:15:49742 popup_screen_origin_for_emulation_ = gfx::Point(
743 emulator->original_screen_rect().origin().x() + emulator->offset().x(),
744 emulator->original_screen_rect().origin().y() + emulator->offset().y());
[email protected]5f75aa42014-04-01 23:00:56745 screen_info_ = emulator->original_screen_info();
746 device_scale_factor_ = screen_info_.deviceScaleFactor;
[email protected]b2e4c70132013-10-03 02:07:51747}
748
[email protected]2d6836f42014-07-02 17:25:31749gfx::Rect RenderWidget::AdjustValidationMessageAnchor(const gfx::Rect& anchor) {
750 if (screen_metrics_emulator_)
751 return screen_metrics_emulator_->AdjustValidationMessageAnchor(anchor);
752 return anchor;
753}
754
[email protected]b2e4c70132013-10-03 02:07:51755void RenderWidget::SetScreenMetricsEmulationParameters(
dgozman9260b0a12015-03-16 13:45:20756 bool enabled,
757 const blink::WebDeviceEmulationParams& params) {
[email protected]b2e4c70132013-10-03 02:07:51758 // This is only supported in RenderView.
759 NOTREACHED();
760}
761
[email protected]53907862014-03-25 15:42:40762#if defined(OS_MACOSX) || defined(OS_ANDROID)
[email protected]b2e4c70132013-10-03 02:07:51763void RenderWidget::SetExternalPopupOriginAdjustmentsForEmulation(
764 ExternalPopupMenu* popup, ScreenMetricsEmulator* emulator) {
[email protected]9a2d7ee32013-12-05 12:15:49765 popup->SetOriginScaleAndOffsetForEmulation(
766 emulator->scale(), emulator->offset());
[email protected]b2e4c70132013-10-03 02:07:51767}
[email protected]53907862014-03-25 15:42:40768#endif
[email protected]b2e4c70132013-10-03 02:07:51769
770void RenderWidget::OnShowHostContextMenu(ContextMenuParams* params) {
771 if (screen_metrics_emulator_)
772 screen_metrics_emulator_->OnShowContextMenu(params);
773}
774
[email protected]a95986a82010-12-24 06:19:28775bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
776 bool handled = true;
777 IPC_BEGIN_MESSAGE_MAP(RenderWidget, message)
[email protected]c084330e02013-04-27 01:08:15778 IPC_MESSAGE_HANDLER(InputMsg_HandleInputEvent, OnHandleInputEvent)
[email protected]34202de2013-05-06 23:36:22779 IPC_MESSAGE_HANDLER(InputMsg_CursorVisibilityChange,
780 OnCursorVisibilityChange)
[email protected]a2214eb2014-06-23 18:31:22781 IPC_MESSAGE_HANDLER(InputMsg_ImeSetComposition, OnImeSetComposition)
782 IPC_MESSAGE_HANDLER(InputMsg_ImeConfirmComposition, OnImeConfirmComposition)
[email protected]c084330e02013-04-27 01:08:15783 IPC_MESSAGE_HANDLER(InputMsg_MouseCaptureLost, OnMouseCaptureLost)
784 IPC_MESSAGE_HANDLER(InputMsg_SetFocus, OnSetFocus)
[email protected]9017d7852013-11-21 17:47:35785 IPC_MESSAGE_HANDLER(InputMsg_SyntheticGestureCompleted,
786 OnSyntheticGestureCompleted)
[email protected]a95986a82010-12-24 06:19:28787 IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
[email protected]a95986a82010-12-24 06:19:28788 IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize)
dgozman9260b0a12015-03-16 13:45:20789 IPC_MESSAGE_HANDLER(ViewMsg_EnableDeviceEmulation,
790 OnEnableDeviceEmulation)
791 IPC_MESSAGE_HANDLER(ViewMsg_DisableDeviceEmulation,
792 OnDisableDeviceEmulation)
noel89949e62014-09-30 01:12:41793 IPC_MESSAGE_HANDLER(ViewMsg_ColorProfile, OnColorProfile)
[email protected]b5913d72012-02-07 22:26:54794 IPC_MESSAGE_HANDLER(ViewMsg_ChangeResizeRect, OnChangeResizeRect)
[email protected]a95986a82010-12-24 06:19:28795 IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
[email protected]9e2e4632012-07-27 16:38:41796 IPC_MESSAGE_HANDLER(ViewMsg_WasShown, OnWasShown)
[email protected]3d9ec5052013-01-02 22:05:25797 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnRepaint)
[email protected]a95986a82010-12-24 06:19:28798 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
799 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck)
[email protected]80ad8622012-11-07 16:33:03800 IPC_MESSAGE_HANDLER(ViewMsg_UpdateScreenRects, OnUpdateScreenRects)
kenrbb4e2a3b2015-05-14 15:05:05801 IPC_MESSAGE_HANDLER(ViewMsg_SetSurfaceIdNamespace, OnSetSurfaceIdNamespace)
[email protected]105dffb42013-02-20 03:46:21802#if defined(OS_ANDROID)
changwan3a841162015-08-11 02:53:37803 IPC_MESSAGE_HANDLER(InputMsg_ImeEventAck, OnImeEventAck)
[email protected]2384b6c2013-02-28 23:58:51804 IPC_MESSAGE_HANDLER(ViewMsg_ShowImeIfNeeded, OnShowImeIfNeeded)
[email protected]105dffb42013-02-20 03:46:21805#endif
dtrainor5ef644e2015-11-19 00:12:47806 IPC_MESSAGE_HANDLER(ViewMsg_HandleCompositorProto, OnHandleCompositorProto)
[email protected]a95986a82010-12-24 06:19:28807 IPC_MESSAGE_UNHANDLED(handled = false)
808 IPC_END_MESSAGE_MAP()
809 return handled;
810}
initial.commit09911bf2008-07-26 23:55:29811
812bool RenderWidget::Send(IPC::Message* message) {
[email protected]992db4c2011-05-12 15:37:15813 // Don't send any messages after the browser has told us to close, and filter
814 // most outgoing messages while swapped out.
815 if ((is_swapped_out_ &&
[email protected]e9ff79c2012-10-19 21:31:26816 !SwappedOutMessages::CanSendWhileSwappedOut(message)) ||
[email protected]c6c921e92012-05-10 23:31:11817 closing_) {
initial.commit09911bf2008-07-26 23:55:29818 delete message;
819 return false;
820 }
821
822 // If given a messsage without a routing ID, then assign our routing ID.
823 if (message->routing_id() == MSG_ROUTING_NONE)
824 message->set_routing_id(routing_id_);
825
[email protected]380244092011-10-07 17:26:27826 return RenderThread::Get()->Send(message);
[email protected]8085dbc82008-09-26 22:53:44827}
828
[email protected]61e2b3cc2012-03-02 16:13:34829void RenderWidget::Resize(const gfx::Size& new_size,
[email protected]60d47ac2013-03-01 23:42:44830 const gfx::Size& physical_backing_size,
dtrainorcb7779b82014-12-04 01:08:02831 bool top_controls_shrink_blink_size,
832 float top_controls_height,
[email protected]bb6378fe2014-04-28 21:19:44833 const gfx::Size& visible_viewport_size,
[email protected]61e2b3cc2012-03-02 16:13:34834 const gfx::Rect& resizer_rect,
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12835 bool is_fullscreen_granted,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12836 blink::WebDisplayMode display_mode,
sievers4e33dae2015-02-25 20:43:58837 const ResizeAck resize_ack) {
[email protected]f7c1f092013-11-05 20:20:56838 if (resizing_mode_selector_->NeverUsesSynchronousResize()) {
[email protected]1c0008842013-06-06 08:35:48839 // A resize ack shouldn't be requested if we have not ACK'd the previous
840 // one.
841 DCHECK(resize_ack != SEND_RESIZE_ACK || !next_paint_is_resize_ack());
842 DCHECK(resize_ack == SEND_RESIZE_ACK || resize_ack == NO_RESIZE_ACK);
843 }
initial.commit09911bf2008-07-26 23:55:29844
[email protected]61e2b3cc2012-03-02 16:13:34845 // Ignore this during shutdown.
846 if (!webwidget_)
847 return;
848
oshima750cb4342015-10-31 00:59:01849 if (compositor_)
850 compositor_->setViewportSize(physical_backing_size);
[email protected]60d47ac2013-03-01 23:42:44851
oshima750cb4342015-10-31 00:59:01852 bool resized = size_ != new_size ||
853 physical_backing_size_ != physical_backing_size;
854
855 size_ = new_size;
[email protected]dade8992013-03-04 07:34:34856 physical_backing_size_ = physical_backing_size;
oshima750cb4342015-10-31 00:59:01857
dtrainorcb7779b82014-12-04 01:08:02858 top_controls_shrink_blink_size_ = top_controls_shrink_blink_size;
859 top_controls_height_ = top_controls_height;
[email protected]39244e72014-05-14 04:20:28860 visible_viewport_size_ = visible_viewport_size;
[email protected]61e2b3cc2012-03-02 16:13:34861 resizer_rect_ = resizer_rect;
862
863 // NOTE: We may have entered fullscreen mode without changing our size.
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12864 bool fullscreen_change = is_fullscreen_granted_ != is_fullscreen_granted;
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12865 is_fullscreen_granted_ = is_fullscreen_granted;
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12866 display_mode_ = display_mode;
[email protected]61e2b3cc2012-03-02 16:13:34867
aelias6004fe02015-02-07 21:43:01868 webwidget_->setTopControlsHeight(top_controls_height,
869 top_controls_shrink_blink_size_);
bokan0c93cd82014-09-30 19:20:43870
oshima750cb4342015-10-31 00:59:01871 if (resized) {
872 gfx::Size new_widget_size =
873 IsUseZoomForDSFEnabled() ? physical_backing_size_ : size_;
[email protected]61e2b3cc2012-03-02 16:13:34874 // When resizing, we want to wait to paint before ACK'ing the resize. This
875 // ensures that we only resize as fast as we can paint. We only need to
876 // send an ACK if we are resized to a non-empty rect.
oshima750cb4342015-10-31 00:59:01877 webwidget_->resize(new_widget_size);
878 }
jbroman304f01a2015-11-05 17:04:21879 WebSize visual_viewport_size;
oshima750cb4342015-10-31 00:59:01880
881 if (IsUseZoomForDSFEnabled()) {
882 gfx::SizeF scaled_visible_viewport_size =
883 gfx::ScaleSize(gfx::SizeF(visible_viewport_size), device_scale_factor_);
jbroman304f01a2015-11-05 17:04:21884 visual_viewport_size = gfx::ToCeiledSize(scaled_visible_viewport_size);
oshima750cb4342015-10-31 00:59:01885 } else {
jbroman304f01a2015-11-05 17:04:21886 visual_viewport_size = visible_viewport_size_;
[email protected]632c4382013-05-15 08:58:45887 }
888
jbroman304f01a2015-11-05 17:04:21889 webwidget()->resizeVisualViewport(visual_viewport_size);
[email protected]bb6378fe2014-04-28 21:19:44890
[email protected]632c4382013-05-15 08:58:45891 if (new_size.IsEmpty() || physical_backing_size.IsEmpty()) {
sievers4e33dae2015-02-25 20:43:58892 // In this case there is no paint/composite and therefore no
893 // ViewHostMsg_UpdateRect to send the resize ack with. We'd need to send the
894 // ack through a fake ViewHostMsg_UpdateRect or a different message.
895 DCHECK_EQ(resize_ack, NO_RESIZE_ACK);
[email protected]61e2b3cc2012-03-02 16:13:34896 }
897
[email protected]20fbfc22013-05-08 20:50:58898 // Send the Resize_ACK flag once we paint again if requested.
[email protected]632c4382013-05-15 08:58:45899 if (resize_ack == SEND_RESIZE_ACK)
[email protected]20fbfc22013-05-08 20:50:58900 set_next_paint_is_resize_ack();
901
[email protected]61e2b3cc2012-03-02 16:13:34902 if (fullscreen_change)
903 DidToggleFullscreen();
904
905 // If a resize ack is requested and it isn't set-up, then no more resizes will
906 // come in and in general things will go wrong.
[email protected]632c4382013-05-15 08:58:45907 DCHECK(resize_ack != SEND_RESIZE_ACK || next_paint_is_resize_ack());
initial.commit09911bf2008-07-26 23:55:29908}
909
bokanc007c3a2015-02-03 07:15:56910void RenderWidget::SetWindowRectSynchronously(
911 const gfx::Rect& new_window_rect) {
912 Resize(new_window_rect.size(),
913 new_window_rect.size(),
dtrainorcb7779b82014-12-04 01:08:02914 top_controls_shrink_blink_size_,
915 top_controls_height_,
bokanc007c3a2015-02-03 07:15:56916 new_window_rect.size(),
[email protected]587941d2014-08-22 01:40:01917 gfx::Rect(),
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12918 is_fullscreen_granted_,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12919 display_mode_,
[email protected]587941d2014-08-22 01:40:01920 NO_RESIZE_ACK);
bokanc007c3a2015-02-03 07:15:56921 view_screen_rect_ = new_window_rect;
922 window_screen_rect_ = new_window_rect;
[email protected]92650162013-10-30 03:31:02923 if (!did_show_)
bokanc007c3a2015-02-03 07:15:56924 initial_rect_ = new_window_rect;
[email protected]92650162013-10-30 03:31:02925}
926
initial.commit09911bf2008-07-26 23:55:29927void RenderWidget::OnClose() {
dchengd96a27a2015-07-24 20:17:32928 DCHECK(content::RenderThread::Get());
929 if (closing_)
930 return;
931 NotifyOnClose();
932 closing_ = true;
933
934 // Browser correspondence is no longer needed at this point.
935 if (routing_id_ != MSG_ROUTING_NONE) {
936 RenderThread::Get()->RemoveRoute(routing_id_);
937 SetHidden(false);
938 if (RenderThreadImpl::current())
939 RenderThreadImpl::current()->WidgetDestroyed();
940 }
941
942 if (for_oopif_) {
943 // Widgets for frames may be created and closed at any time while the frame
944 // is alive. However, the closing process must happen synchronously. Frame
945 // widget and frames hold pointers to each other. If Close() is deferred to
946 // the message loop like in the non-frame widget case, WebWidget::close()
947 // can end up accessing members of an already-deleted frame.
948 Close();
949 } else {
950 // If there is a Send call on the stack, then it could be dangerous to close
951 // now. Post a task that only gets invoked when there are no nested message
952 // loops.
953 base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
954 FROM_HERE, base::Bind(&RenderWidget::Close, this));
955 }
956
957 // Balances the AddRef taken when we called AddRoute.
958 Release();
initial.commit09911bf2008-07-26 23:55:29959}
960
[email protected]0fdd5012013-05-29 08:05:56961void RenderWidget::OnResize(const ViewMsg_Resize_Params& params) {
[email protected]5b45ad42013-10-25 00:42:04962 if (resizing_mode_selector_->ShouldAbortOnResize(this, params))
[email protected]03e88672013-10-22 21:31:32963 return;
964
[email protected]b2e4c70132013-10-03 02:07:51965 if (screen_metrics_emulator_) {
966 screen_metrics_emulator_->OnResizeMessage(params);
967 return;
968 }
969
[email protected]fcdc5642014-05-09 14:32:24970 bool orientation_changed =
971 screen_info_.orientationAngle != params.screen_info.orientationAngle;
972
[email protected]0fdd5012013-05-29 08:05:56973 screen_info_ = params.screen_info;
974 SetDeviceScaleFactor(screen_info_.deviceScaleFactor);
dtrainorcb7779b82014-12-04 01:08:02975 Resize(params.new_size,
976 params.physical_backing_size,
977 params.top_controls_shrink_blink_size,
978 params.top_controls_height,
979 params.visible_viewport_size,
980 params.resizer_rect,
mikhail.pozdnyakovf2c902a2015-04-14 08:09:12981 params.is_fullscreen_granted,
mikhail.pozdnyakovc0e251b2015-04-15 06:51:12982 params.display_mode,
sievers4e33dae2015-02-25 20:43:58983 params.needs_resize_ack ? SEND_RESIZE_ACK : NO_RESIZE_ACK);
[email protected]fcdc5642014-05-09 14:32:24984
985 if (orientation_changed)
986 OnOrientationChange();
initial.commit09911bf2008-07-26 23:55:29987}
988
dgozman9260b0a12015-03-16 13:45:20989void RenderWidget::OnEnableDeviceEmulation(
990 const blink::WebDeviceEmulationParams& params) {
991 if (!screen_metrics_emulator_)
992 screen_metrics_emulator_.reset(new ScreenMetricsEmulator(this, params));
993 else
994 screen_metrics_emulator_->ChangeEmulationParams(params);
995}
996
997void RenderWidget::OnDisableDeviceEmulation() {
998 screen_metrics_emulator_.reset();
999}
1000
noel89949e62014-09-30 01:12:411001void RenderWidget::OnColorProfile(const std::vector<char>& color_profile) {
1002 SetDeviceColorProfile(color_profile);
1003}
1004
[email protected]b5913d72012-02-07 22:26:541005void RenderWidget::OnChangeResizeRect(const gfx::Rect& resizer_rect) {
[email protected]721e2302014-04-30 23:42:011006 if (resizer_rect_ == resizer_rect)
1007 return;
1008 resizer_rect_ = resizer_rect;
1009 if (webwidget_)
1010 webwidget_->didChangeWindowResizerRect();
[email protected]b5913d72012-02-07 22:26:541011}
1012
initial.commit09911bf2008-07-26 23:55:291013void RenderWidget::OnWasHidden() {
[email protected]9c3085f2011-06-09 02:10:311014 TRACE_EVENT0("renderer", "RenderWidget::OnWasHidden");
initial.commit09911bf2008-07-26 23:55:291015 // Go into a mode where we stop generating paint and scrolling events.
[email protected]bee16aab2009-08-26 15:55:031016 SetHidden(true);
[email protected]de3c5d82014-05-28 22:12:591017 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
1018 WasHidden());
initial.commit09911bf2008-07-26 23:55:291019}
1020
[email protected]3399dd822014-08-09 11:14:241021void RenderWidget::OnWasShown(bool needs_repainting,
1022 const ui::LatencyInfo& latency_info) {
[email protected]9e2e4632012-07-27 16:38:411023 TRACE_EVENT0("renderer", "RenderWidget::OnWasShown");
initial.commit09911bf2008-07-26 23:55:291024 // During shutdown we can just ignore this message.
1025 if (!webwidget_)
1026 return;
1027
1028 // See OnWasHidden
[email protected]bee16aab2009-08-26 15:55:031029 SetHidden(false);
[email protected]de3c5d82014-05-28 22:12:591030 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
1031 WasShown());
initial.commit09911bf2008-07-26 23:55:291032
[email protected]8a23afb32014-04-30 22:40:231033 if (!needs_repainting)
initial.commit09911bf2008-07-26 23:55:291034 return;
initial.commit09911bf2008-07-26 23:55:291035
1036 // Generate a full repaint.
[email protected]3399dd822014-08-09 11:14:241037 if (compositor_) {
1038 ui::LatencyInfo swap_latency_info(latency_info);
1039 scoped_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor(
1040 compositor_->CreateLatencyInfoSwapPromiseMonitor(&swap_latency_info));
[email protected]aca33f4f2014-05-17 17:08:051041 compositor_->SetNeedsForcedRedraw();
[email protected]3399dd822014-08-09 11:14:241042 }
jdduke491a3f0c2015-06-15 23:30:261043 ScheduleComposite();
initial.commit09911bf2008-07-26 23:55:291044}
1045
[email protected]53d3f302009-12-21 04:42:051046void RenderWidget::OnRequestMoveAck() {
1047 DCHECK(pending_window_rect_count_);
1048 pending_window_rect_count_--;
1049}
1050
[email protected]ed7defa2013-03-12 21:29:591051GURL RenderWidget::GetURLForGraphicsContext3D() {
1052 return GURL();
[email protected]65225772011-05-12 21:10:241053}
1054
[email protected]ebc0e1df2013-08-01 02:46:221055scoped_ptr<cc::OutputSurface> RenderWidget::CreateOutputSurface(bool fallback) {
[email protected]7912e822014-04-16 02:37:031056 // For widgets that are never visible, we don't start the compositor, so we
1057 // never get a request for a cc::OutputSurface.
sievers71c62dd52015-10-07 01:44:391058 DCHECK(!compositor_never_visible_);
[email protected]a1811b8912013-05-09 15:35:191059
avi83883c82014-12-23 00:08:491060 const base::CommandLine& command_line =
1061 *base::CommandLine::ForCurrentProcess();
[email protected]e09994a2014-03-26 19:59:331062 bool use_software = fallback;
1063 if (command_line.HasSwitch(switches::kDisableGpuCompositing))
1064 use_software = true;
1065
penghuang28a5fa22015-12-02 17:58:191066#if defined(MOJO_SHELL_CLIENT)
1067 if (MojoShellConnection::Get() && !use_software) {
1068 RenderWidgetMusConnection* connection =
1069 RenderWidgetMusConnection::GetOrCreate(routing_id());
1070 return connection->CreateOutputSurface();
1071 }
1072#endif
1073
[email protected]0634cdd42013-08-16 00:46:091074 scoped_refptr<ContextProviderCommandBuffer> context_provider;
vmiura78b69282015-02-14 00:01:171075 scoped_refptr<ContextProviderCommandBuffer> worker_context_provider;
[email protected]e09994a2014-03-26 19:59:331076 if (!use_software) {
[email protected]0634cdd42013-08-16 00:46:091077 context_provider = ContextProviderCommandBuffer::Create(
jbauman5e420d32015-08-05 09:33:011078 CreateGraphicsContext3D(true), RENDER_COMPOSITOR_CONTEXT);
[email protected]e09994a2014-03-26 19:59:331079 if (!context_provider.get()) {
1080 // Cause the compositor to wait and try again.
piman8944e1c2015-09-22 21:10:341081 return nullptr;
[email protected]e09994a2014-03-26 19:59:331082 }
revemand180dfc32015-09-24 00:19:431083 worker_context_provider =
1084 RenderThreadImpl::current()->SharedWorkerContextProvider();
1085 if (!worker_context_provider) {
vmiura78b69282015-02-14 00:01:171086 // Cause the compositor to wait and try again.
piman8944e1c2015-09-22 21:10:341087 return nullptr;
vmiura78b69282015-02-14 00:01:171088 }
boliu853d46052015-10-13 20:20:061089
1090#if defined(OS_ANDROID)
1091 if (SynchronousCompositorFactory* factory =
1092 SynchronousCompositorFactory::GetInstance()) {
1093 return factory->CreateOutputSurface(
1094 routing_id(), frame_swap_message_queue_, context_provider,
1095 worker_context_provider);
boliubee541f42015-11-05 00:52:531096 } else if (RenderThreadImpl::current()->sync_compositor_message_filter()) {
1097 return make_scoped_ptr(new SynchronousCompositorOutputSurface(
1098 context_provider, worker_context_provider, routing_id(),
1099 content::RenderThreadImpl::current()
1100 ->sync_compositor_message_filter(),
1101 frame_swap_message_queue_));
boliu853d46052015-10-13 20:20:061102 }
1103#endif
[email protected]0634cdd42013-08-16 00:46:091104 }
[email protected]ebc0e1df2013-08-01 02:46:221105
[email protected]b6eb8e332013-09-10 00:51:011106 uint32 output_surface_id = next_output_surface_id_++;
piman8944e1c2015-09-22 21:10:341107 // Composite-to-mailbox is currently used for layout tests in order to cause
1108 // them to draw inside in the renderer to do the readback there. This should
1109 // no longer be the case when crbug.com/311404 is fixed.
1110 if (!RenderThreadImpl::current() ||
1111 !RenderThreadImpl::current()->layout_test_mode()) {
danakj6e3bf8012014-12-16 18:27:531112 DCHECK(compositor_deps_->GetCompositorImplThreadTaskRunner());
piman8944e1c2015-09-22 21:10:341113 return make_scoped_ptr(new DelegatedCompositorOutputSurface(
vmiura78b69282015-02-14 00:01:171114 routing_id(), output_surface_id, context_provider,
1115 worker_context_provider, frame_swap_message_queue_));
[email protected]65a33ce2014-03-25 22:37:091116 }
piman8944e1c2015-09-22 21:10:341117
[email protected]0634cdd42013-08-16 00:46:091118 if (!context_provider.get()) {
[email protected]0634cdd42013-08-16 00:46:091119 scoped_ptr<cc::SoftwareOutputDevice> software_device(
jbauman7e15c6a2015-05-11 23:43:121120 new cc::SoftwareOutputDevice());
[email protected]0634cdd42013-08-16 00:46:091121
piman8944e1c2015-09-22 21:10:341122 return make_scoped_ptr(new CompositorOutputSurface(
caseqff9c74c2015-02-10 14:56:291123 routing_id(), output_surface_id, nullptr, nullptr,
1124 software_device.Pass(), frame_swap_message_queue_, true));
[email protected]ebc0e1df2013-08-01 02:46:221125 }
[email protected]ed7defa2013-03-12 21:29:591126
piman8944e1c2015-09-22 21:10:341127 return make_scoped_ptr(new MailboxOutputSurface(
vmiura78b69282015-02-14 00:01:171128 routing_id(), output_surface_id, context_provider,
piman8944e1c2015-09-22 21:10:341129 worker_context_provider, frame_swap_message_queue_, cc::RGBA_8888));
[email protected]ba91a792013-02-06 09:48:281130}
1131
[email protected]4d7e46a2013-11-08 05:33:401132void RenderWidget::OnSwapBuffersAborted() {
[email protected]65225772011-05-12 21:10:241133 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersAborted");
[email protected]65225772011-05-12 21:10:241134 // Schedule another frame so the compositor learns about it.
jdduke491a3f0c2015-06-15 23:30:261135 ScheduleComposite();
[email protected]65225772011-05-12 21:10:241136}
1137
[email protected]4d7e46a2013-11-08 05:33:401138void RenderWidget::OnSwapBuffersPosted() {
[email protected]37a6f302011-07-11 23:43:081139 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersPosted");
[email protected]37a6f302011-07-11 23:43:081140}
1141
[email protected]4d7e46a2013-11-08 05:33:401142void RenderWidget::OnSwapBuffersComplete() {
[email protected]65225772011-05-12 21:10:241143 TRACE_EVENT0("renderer", "RenderWidget::OnSwapBuffersComplete");
[email protected]29ed96a2012-02-04 18:12:161144
[email protected]404939f2012-06-01 04:06:181145 // Notify subclasses that composited rendering was flushed to the screen.
[email protected]29ed96a2012-02-04 18:12:161146 DidFlushPaint();
initial.commit09911bf2008-07-26 23:55:291147}
1148
[email protected]180ef242013-11-07 06:50:461149void RenderWidget::OnHandleInputEvent(const blink::WebInputEvent* input_event,
jdduke0cf1e662015-10-15 22:43:281150 const ui::LatencyInfo& latency_info) {
[email protected]c27dd4f2014-05-22 18:05:191151 if (!input_event)
initial.commit09911bf2008-07-26 23:55:291152 return;
dtapuskae7473612015-12-04 14:23:061153
1154 // TODO(dtapuska): Passive support not implemented yet crbug.com/489802
1155 bool passive = false;
jddukec05612b2015-06-25 23:13:181156 base::AutoReset<bool> handling_input_event_resetter(&handling_input_event_,
1157 true);
[email protected]c27dd4f2014-05-22 18:05:191158 base::AutoReset<WebInputEvent::Type> handling_event_type_resetter(
1159 &handling_event_type_, input_event->type);
jddukec05612b2015-06-25 23:13:181160
1161 // Calls into |didOverscroll()| while handling this event will populate
1162 // |event_overscroll|, which in turn will be bundled with the event ack.
1163 scoped_ptr<DidOverscrollParams> event_overscroll;
1164 base::AutoReset<scoped_ptr<DidOverscrollParams>*>
1165 handling_event_overscroll_resetter(&handling_event_overscroll_,
1166 &event_overscroll);
1167
[email protected]25402eb2014-07-18 03:09:521168#if defined(OS_ANDROID)
changwanf2a707b2015-10-30 08:22:161169 const bool is_keyboard_event =
1170 WebInputEvent::isKeyboardEventType(input_event->type);
1171
1172 // For non-keyboard events, we want the change source to be FROM_NON_IME.
1173 ImeEventGuard guard(this, false, is_keyboard_event);
[email protected]25402eb2014-07-18 03:09:521174#endif
initial.commit09911bf2008-07-26 23:55:291175
[email protected]fd847792013-10-24 17:12:351176 base::TimeTicks start_time;
charliea3be839702015-01-26 17:35:411177 if (base::TimeTicks::IsHighResolution())
1178 start_time = base::TimeTicks::Now();
[email protected]fd847792013-10-24 17:12:351179
miletusfed8c43b2015-01-26 20:04:521180 TRACE_EVENT1("renderer,benchmark", "RenderWidget::OnHandleInputEvent",
jdduke07788062014-12-05 03:16:301181 "event", WebInputEventTraits::GetName(input_event->type));
[email protected]b2e92592014-01-10 15:47:151182 TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("blink.HandleInputEvent");
yuhaoz8df9334c2015-08-18 17:48:511183 TRACE_EVENT_WITH_FLOW1("input,benchmark",
1184 "LatencyInfo.Flow",
1185 TRACE_ID_DONT_MANGLE(latency_info.trace_id()),
1186 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
1187 "step", "HandleInputEventMain");
[email protected]b4841e1c2013-05-16 22:30:101188
jdduke07788062014-12-05 03:16:301189 // If we don't have a high res timer, these metrics won't be accurate enough
1190 // to be worth collecting. Note that this does introduce some sampling bias.
1191 if (!start_time.is_null())
miletus14a25642015-08-13 19:23:231192 LogInputEventLatencyUma(*input_event, start_time, latency_info);
jdduke07788062014-12-05 03:16:301193
[email protected]6be422b2013-12-08 06:47:311194 scoped_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor;
[email protected]205294b2014-03-18 20:48:351195 ui::LatencyInfo swap_latency_info(latency_info);
[email protected]6be422b2013-12-08 06:47:311196 if (compositor_) {
1197 latency_info_swap_promise_monitor =
[email protected]205294b2014-03-18 20:48:351198 compositor_->CreateLatencyInfoSwapPromiseMonitor(&swap_latency_info)
1199 .Pass();
[email protected]6be422b2013-12-08 06:47:311200 }
[email protected]c2eaa8f2013-05-10 02:41:551201
[email protected]67bfb83f2011-09-22 03:36:371202 bool prevent_default = false;
1203 if (WebInputEvent::isMouseEventType(input_event->type)) {
[email protected]936c6f52011-12-13 01:35:261204 const WebMouseEvent& mouse_event =
1205 *static_cast<const WebMouseEvent*>(input_event);
1206 TRACE_EVENT2("renderer", "HandleMouseMove",
1207 "x", mouse_event.x, "y", mouse_event.y);
[email protected]a09d53ce2014-01-31 00:46:421208 context_menu_source_type_ = ui::MENU_SOURCE_MOUSE;
[email protected]936c6f52011-12-13 01:35:261209 prevent_default = WillHandleMouseEvent(mouse_event);
[email protected]67bfb83f2011-09-22 03:36:371210 }
1211
[email protected]cefe9b152014-03-27 18:16:151212 if (WebInputEvent::isKeyboardEventType(input_event->type)) {
[email protected]a09d53ce2014-01-31 00:46:421213 context_menu_source_type_ = ui::MENU_SOURCE_KEYBOARD;
[email protected]cefe9b152014-03-27 18:16:151214#if defined(OS_ANDROID)
1215 // The DPAD_CENTER key on Android has a dual semantic: (1) in the general
1216 // case it should behave like a select key (i.e. causing a click if a button
1217 // is focused). However, if a text field is focused (2), its intended
1218 // behavior is to just show the IME and don't propagate the key.
1219 // A typical use case is a web form: the DPAD_CENTER should bring up the IME
1220 // when clicked on an input text field and cause the form submit if clicked
1221 // when the submit button is focused, but not vice-versa.
1222 // The UI layer takes care of translating DPAD_CENTER into a RETURN key,
1223 // but at this point we have to swallow the event for the scenario (2).
1224 const WebKeyboardEvent& key_event =
1225 *static_cast<const WebKeyboardEvent*>(input_event);
1226 if (key_event.nativeKeyCode == AKEYCODE_DPAD_CENTER &&
1227 GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) {
1228 OnShowImeIfNeeded();
1229 prevent_default = true;
1230 }
1231#endif
1232 }
[email protected]f56c7872013-06-18 12:31:571233
[email protected]41d86852012-11-07 12:23:241234 if (WebInputEvent::isGestureEventType(input_event->type)) {
1235 const WebGestureEvent& gesture_event =
1236 *static_cast<const WebGestureEvent*>(input_event);
[email protected]a09d53ce2014-01-31 00:46:421237 context_menu_source_type_ = ui::MENU_SOURCE_TOUCH;
[email protected]41d86852012-11-07 12:23:241238 prevent_default = prevent_default || WillHandleGestureEvent(gesture_event);
1239 }
1240
dtapuskae7473612015-12-04 14:23:061241 WebInputEventResult processed =
1242 prevent_default ? WebInputEventResult::HandledSuppressed
1243 : WebInputEventResult::NotHandled;
[email protected]b68a0e52011-12-08 15:11:121244 if (input_event->type != WebInputEvent::Char || !suppress_next_char_events_) {
1245 suppress_next_char_events_ = false;
dtapuskae7473612015-12-04 14:23:061246 if (processed == WebInputEventResult::NotHandled && webwidget_)
1247 processed = webwidget_->handleInputEvent(*input_event);
1248 }
1249
1250 // TODO(dtapuska): Use the input_event->timeStampSeconds as the start
1251 // ideally this should be when the event was sent by the compositor to the
1252 // renderer. crbug.com/565348
1253 if (input_event->type == WebInputEvent::TouchStart ||
1254 input_event->type == WebInputEvent::TouchMove ||
1255 input_event->type == WebInputEvent::TouchEnd) {
1256 LogPassiveEventListenersUma(
1257 processed, passive,
1258 static_cast<const WebTouchEvent*>(input_event)->cancelable,
1259 input_event->timeStampSeconds, latency_info);
1260 } else if (input_event->type == WebInputEvent::MouseWheel) {
1261 LogPassiveEventListenersUma(processed, passive, !passive,
1262 input_event->timeStampSeconds, latency_info);
[email protected]b68a0e52011-12-08 15:11:121263 }
1264
1265 // If this RawKeyDown event corresponds to a browser keyboard shortcut and
1266 // it's not processed by webkit, then we need to suppress the upcoming Char
1267 // events.
jdduke0cf1e662015-10-15 22:43:281268 bool is_keyboard_shortcut =
1269 input_event->type == WebInputEvent::RawKeyDown &&
1270 static_cast<const WebKeyboardEvent*>(input_event)->isBrowserShortcut;
dtapuskae7473612015-12-04 14:23:061271 if (processed == WebInputEventResult::NotHandled && is_keyboard_shortcut)
[email protected]b68a0e52011-12-08 15:11:121272 suppress_next_char_events_ = true;
initial.commit09911bf2008-07-26 23:55:291273
dtapuskae7473612015-12-04 14:23:061274 InputEventAckState ack_result = processed == WebInputEventResult::NotHandled
1275 ? INPUT_EVENT_ACK_STATE_NOT_CONSUMED
1276 : INPUT_EVENT_ACK_STATE_CONSUMED;
1277 if (processed == WebInputEventResult::NotHandled &&
1278 input_event->type == WebInputEvent::TouchStart) {
[email protected]3d5c243b2012-11-30 00:26:011279 const WebTouchEvent& touch_event =
1280 *static_cast<const WebTouchEvent*>(input_event);
[email protected]f8ed4722013-12-03 03:27:251281 // Hit-test for all the pressed touch points. If there is a touch-handler
1282 // for any of the touch points, then the renderer should continue to receive
1283 // touch events.
1284 ack_result = INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
1285 for (size_t i = 0; i < touch_event.touchesLength; ++i) {
1286 if (touch_event.touches[i].state == WebTouchPoint::StatePressed &&
[email protected]a66e18e2014-01-29 20:58:271287 HasTouchEventHandlersAt(
[email protected]9c769d412014-03-20 18:27:391288 gfx::ToFlooredPoint(touch_event.touches[i].position))) {
[email protected]f8ed4722013-12-03 03:27:251289 ack_result = INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
1290 break;
1291 }
1292 }
[email protected]3d5c243b2012-11-30 00:26:011293 }
1294
ccamerond4ba47902014-12-17 07:20:311295 // Send mouse wheel events and their disposition to the compositor thread, so
1296 // that they can be used to produce the elastic overscroll effect on Mac.
1297 if (input_event->type == WebInputEvent::MouseWheel) {
ccamerona7644752014-12-30 01:16:311298 ObserveWheelEventAndResult(
sataya.mf405d0e2015-07-07 16:51:111299 static_cast<const WebMouseWheelEvent&>(*input_event),
1300 event_overscroll ? event_overscroll->latest_overscroll_delta
1301 : gfx::Vector2dF(),
dtapuskae7473612015-12-04 14:23:061302 processed != WebInputEventResult::NotHandled);
ccamerond4ba47902014-12-17 07:20:311303 }
1304
[email protected]721e2302014-04-30 23:42:011305 bool frame_pending = compositor_ && compositor_->BeginMainFrameRequested();
[email protected]8926c602013-01-23 05:32:061306
charliea3be839702015-01-26 17:35:411307 // If we don't have a fast and accurate Now(), we assume the input handlers
1308 // are heavy and rate limit them.
jdduke07788062014-12-05 03:16:301309 bool rate_limiting_wanted =
1310 input_event->type == WebInputEvent::MouseMove ||
1311 input_event->type == WebInputEvent::MouseWheel;
1312 if (rate_limiting_wanted && !start_time.is_null()) {
charliea3be839702015-01-26 17:35:411313 base::TimeTicks end_time = base::TimeTicks::Now();
[email protected]fd847792013-10-24 17:12:351314 total_input_handling_time_this_frame_ += (end_time - start_time);
1315 rate_limiting_wanted =
1316 total_input_handling_time_this_frame_.InMicroseconds() >
1317 kInputHandlingTimeThrottlingThresholdMicroseconds;
1318 }
1319
[email protected]7f19e9d2014-05-09 15:16:291320 TRACE_EVENT_SYNTHETIC_DELAY_END("blink.HandleInputEvent");
1321
[email protected]c27dd4f2014-05-22 18:05:191322 // Note that we can't use handling_event_type_ here since it will be overriden
1323 // by reentrant calls for events after the paused one.
1324 bool no_ack = ignore_ack_for_mouse_move_from_debugger_ &&
1325 input_event->type == WebInputEvent::MouseMove;
lanweif1a22832015-05-19 17:24:101326 if (WebInputEventTraits::WillReceiveAckFromRenderer(*input_event) &&
1327 !no_ack) {
1328 InputEventAck ack(input_event->type, ack_result, swap_latency_info,
jddukec05612b2015-06-25 23:13:181329 event_overscroll.Pass(),
lanweif1a22832015-05-19 17:24:101330 WebInputEventTraits::GetUniqueTouchEventId(*input_event));
[email protected]34afe102013-12-13 17:24:551331 scoped_ptr<IPC::Message> response(
[email protected]8e431f2032014-05-20 02:34:561332 new InputHostMsg_HandleInputEvent_ACK(routing_id_, ack));
jdduke07788062014-12-05 03:16:301333 if (rate_limiting_wanted && frame_pending && !is_hidden_) {
[email protected]34afe102013-12-13 17:24:551334 // We want to rate limit the input events in this case, so we'll wait for
1335 // painting to finish before ACKing this message.
1336 TRACE_EVENT_INSTANT0("renderer",
1337 "RenderWidget::OnHandleInputEvent ack throttled",
1338 TRACE_EVENT_SCOPE_THREAD);
1339 if (pending_input_event_ack_) {
jddukefffb67c2015-01-07 22:32:291340 TRACE_EVENT_ASYNC_END0("input", "RenderWidget::ThrottledInputEventAck",
1341 pending_input_event_ack_.get());
[email protected]34afe102013-12-13 17:24:551342 // As two different kinds of events could cause us to postpone an ack
1343 // we send it now, if we have one pending. The Browser should never
1344 // send us the same kind of event we are delaying the ack for.
1345 Send(pending_input_event_ack_.release());
1346 }
1347 pending_input_event_ack_ = response.Pass();
jddukefffb67c2015-01-07 22:32:291348 TRACE_EVENT_ASYNC_BEGIN0("input", "RenderWidget::ThrottledInputEventAck",
1349 pending_input_event_ack_.get());
[email protected]34afe102013-12-13 17:24:551350 if (compositor_)
1351 compositor_->NotifyInputThrottledUntilCommit();
1352 } else {
1353 Send(response.release());
[email protected]353a34c2010-05-28 23:35:171354 }
jddukec05612b2015-06-25 23:13:181355 } else {
1356 DCHECK(!event_overscroll) << "Unexpected overscroll for un-acked event";
[email protected]12fbad812009-09-01 18:21:241357 }
alexclarke7819e2552015-06-03 11:17:211358 if (!no_ack && RenderThreadImpl::current()) {
1359 RenderThreadImpl::current()
1360 ->GetRendererScheduler()
1361 ->DidHandleInputEventOnMainThread(*input_event);
1362 }
[email protected]5fea4a52014-05-27 00:17:521363 if (input_event->type == WebInputEvent::MouseMove)
1364 ignore_ack_for_mouse_move_from_debugger_ = false;
[email protected]12fbad812009-09-01 18:21:241365
[email protected]3306f262012-09-21 19:20:421366#if defined(OS_ANDROID)
1367 // Allow the IME to be shown when the focus changes as a consequence
1368 // of a processed touch end event.
dtapuskae7473612015-12-04 14:23:061369 if (input_event->type == WebInputEvent::TouchEnd &&
1370 processed != WebInputEventResult::NotHandled) {
[email protected]90f24152014-04-09 12:41:361371 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME);
dtapuskae7473612015-12-04 14:23:061372 }
[email protected]183e28d2014-01-20 18:18:021373#elif defined(USE_AURA)
1374 // Show the virtual keyboard if enabled and a user gesture triggers a focus
1375 // change.
dtapuskae7473612015-12-04 14:23:061376 if (processed != WebInputEventResult::NotHandled &&
1377 (input_event->type == WebInputEvent::TouchEnd ||
1378 input_event->type == WebInputEvent::MouseUp)) {
[email protected]90f24152014-04-09 12:41:361379 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_IME);
rouslanf7ebd8832015-01-22 01:54:141380 }
[email protected]3306f262012-09-21 19:20:421381#endif
1382
[email protected]67bfb83f2011-09-22 03:36:371383 if (!prevent_default) {
1384 if (WebInputEvent::isKeyboardEventType(input_event->type))
1385 DidHandleKeyEvent();
[email protected]67bfb83f2011-09-22 03:36:371386 }
rouslanf7ebd8832015-01-22 01:54:141387
1388// TODO(rouslan): Fix ChromeOS and Windows 8 behavior of autofill popup with
1389// virtual keyboard.
1390#if !defined(OS_ANDROID)
1391 // Virtual keyboard is not supported, so react to focus change immediately.
dtapuskae7473612015-12-04 14:23:061392 if (processed != WebInputEventResult::NotHandled &&
1393 (input_event->type == WebInputEvent::TouchEnd ||
1394 input_event->type == WebInputEvent::MouseUp)) {
rouslanf7ebd8832015-01-22 01:54:141395 FocusChangeComplete();
1396 }
1397#endif
initial.commit09911bf2008-07-26 23:55:291398}
1399
[email protected]34202de2013-05-06 23:36:221400void RenderWidget::OnCursorVisibilityChange(bool is_visible) {
1401 if (webwidget_)
1402 webwidget_->setCursorVisibilityState(is_visible);
1403}
1404
initial.commit09911bf2008-07-26 23:55:291405void RenderWidget::OnMouseCaptureLost() {
1406 if (webwidget_)
[email protected]4873c7d2009-07-16 06:36:281407 webwidget_->mouseCaptureLost();
initial.commit09911bf2008-07-26 23:55:291408}
1409
1410void RenderWidget::OnSetFocus(bool enable) {
[email protected]9d166af2010-03-02 22:04:331411 if (webwidget_)
1412 webwidget_->setFocus(enable);
initial.commit09911bf2008-07-26 23:55:291413}
1414
[email protected]fd847792013-10-24 17:12:351415void RenderWidget::FlushPendingInputEventAck() {
jddukefffb67c2015-01-07 22:32:291416 if (pending_input_event_ack_) {
1417 TRACE_EVENT_ASYNC_END0("input", "RenderWidget::ThrottledInputEventAck",
1418 pending_input_event_ack_.get());
[email protected]d8a8ecb2013-10-23 18:03:071419 Send(pending_input_event_ack_.release());
jddukefffb67c2015-01-07 22:32:291420 }
[email protected]fd847792013-10-24 17:12:351421 total_input_handling_time_this_frame_ = base::TimeDelta();
1422}
1423
initial.commit09911bf2008-07-26 23:55:291424///////////////////////////////////////////////////////////////////////////////
[email protected]f98d7e3c2010-09-13 22:30:461425// WebWidgetClient
initial.commit09911bf2008-07-26 23:55:291426
[email protected]244ac1892011-12-02 17:04:471427void RenderWidget::didAutoResize(const WebSize& new_size) {
oshima750cb4342015-10-31 00:59:011428 // TODO(oshima): support UseZoomForDSFEnabled()
[email protected]ea3ee0a2012-05-15 03:43:091429 if (size_.width() != new_size.width || size_.height() != new_size.height) {
[email protected]eac2b362013-05-22 07:01:451430 size_ = new_size;
[email protected]20fbfc22013-05-08 20:50:581431
[email protected]5b45ad42013-10-25 00:42:041432 if (resizing_mode_selector_->is_synchronous_mode()) {
[email protected]eac2b362013-05-22 07:01:451433 WebRect new_pos(rootWindowRect().x,
1434 rootWindowRect().y,
1435 new_size.width,
1436 new_size.height);
1437 view_screen_rect_ = new_pos;
1438 window_screen_rect_ = new_pos;
[email protected]8be1c582013-03-06 00:55:031439 }
[email protected]20fbfc22013-05-08 20:50:581440
[email protected]eac2b362013-05-22 07:01:451441 AutoResizeCompositor();
[email protected]20fbfc22013-05-08 20:50:581442
[email protected]5b45ad42013-10-25 00:42:041443 if (!resizing_mode_selector_->is_synchronous_mode())
[email protected]20fbfc22013-05-08 20:50:581444 need_update_rect_for_auto_resize_ = true;
[email protected]ea3ee0a2012-05-15 03:43:091445 }
[email protected]244ac1892011-12-02 17:04:471446}
1447
[email protected]3a1c8a8032013-03-18 22:35:321448void RenderWidget::AutoResizeCompositor() {
danakjddaec912015-09-25 19:38:401449 physical_backing_size_ = gfx::ScaleToCeiledSize(size_, device_scale_factor_);
[email protected]97e1bf72013-03-06 14:06:051450 if (compositor_)
oshima750cb4342015-10-31 00:59:011451 compositor_->setViewportSize(physical_backing_size_);
[email protected]97e1bf72013-03-06 14:06:051452}
1453
[email protected]e195e582013-03-08 01:32:591454void RenderWidget::initializeLayerTreeView() {
[email protected]aeeedad2014-08-22 18:16:221455 DCHECK(!host_closing_);
1456
danakj6e3bf8012014-12-16 18:27:531457 compositor_ = RenderWidgetCompositor::Create(this, compositor_deps_);
oshima750cb4342015-10-31 00:59:011458 compositor_->setViewportSize(physical_backing_size_);
sievers71c62dd52015-10-07 01:44:391459
1460 // For background pages and certain tests, we don't want to trigger
1461 // OutputSurface creation.
1462 if (compositor_never_visible_ || !RenderThreadImpl::current())
1463 compositor_->SetNeverVisible();
1464
pimanc4af3072015-10-02 03:45:591465 StartCompositor();
[email protected]e195e582013-03-08 01:32:591466}
1467
ennef3c58142014-12-09 21:44:381468void RenderWidget::WillCloseLayerTreeView() {
1469 if (host_closing_)
1470 return;
1471
1472 // Prevent new compositors or output surfaces from being created.
1473 host_closing_ = true;
1474
[email protected]aeeedad2014-08-22 18:16:221475 // Always send this notification to prevent new layer tree views from
1476 // being created, even if one hasn't been created yet.
1477 if (webwidget_)
1478 webwidget_->willCloseLayerTreeView();
[email protected]aeeedad2014-08-22 18:16:221479}
1480
[email protected]180ef242013-11-07 06:50:461481blink::WebLayerTreeView* RenderWidget::layerTreeView() {
[email protected]ba91a792013-02-06 09:48:281482 return compositor_.get();
[email protected]8926c602013-01-23 05:32:061483}
1484
dglazkovf0e1d6d2015-10-10 02:13:481485void RenderWidget::didMeaningfulLayout(blink::WebMeaningfulLayout layout_type) {
1486 if (layout_type == blink::WebMeaningfulLayout::VisuallyNonEmpty) {
1487 QueueMessage(new ViewHostMsg_DidFirstVisuallyNonEmptyPaint(routing_id_),
1488 MESSAGE_DELIVERY_POLICY_WITH_VISUAL_STATE);
1489 }
dglazkov79c426102015-08-31 21:22:431490
dglazkovf0e1d6d2015-10-10 02:13:481491 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
1492 DidMeaningfulLayout(layout_type));
dglazkov79c426102015-08-31 21:22:431493}
1494
jdduke491a3f0c2015-06-15 23:30:261495void RenderWidget::WillBeginCompositorFrame() {
[email protected]9cd43a62012-03-26 08:03:561496 TRACE_EVENT0("gpu", "RenderWidget::willBeginCompositorFrame");
[email protected]abe8b3a2012-03-28 21:19:371497
shuchen913f8b622015-07-31 13:22:431498 // The UpdateTextInputState can result in further layout and possibly
[email protected]abe8b3a2012-03-28 21:19:371499 // enable GPU acceleration so they need to be called before any painting
1500 // is done.
[email protected]90f24152014-04-09 12:41:361501 UpdateTextInputState(NO_SHOW_IME, FROM_NON_IME);
[email protected]abe8b3a2012-03-28 21:19:371502 UpdateSelectionBounds();
[email protected]9cd43a62012-03-26 08:03:561503}
1504
[email protected]6fceb912013-02-15 06:24:151505void RenderWidget::DidCommitCompositorFrame() {
fsamuel2e9413d2015-02-25 01:25:441506 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_,
1507 DidCommitCompositorFrame());
[email protected]e3244ed2014-06-20 20:04:271508 FOR_EACH_OBSERVER(RenderFrameProxy, render_frame_proxies_,
[email protected]bffc8302014-01-23 20:52:161509 DidCommitCompositorFrame());
[email protected]a017938b2014-05-27 21:17:171510#if defined(VIDEO_HOLE)
[email protected]e3244ed2014-06-20 20:04:271511 FOR_EACH_OBSERVER(RenderFrameImpl, video_hole_frames_,
1512 DidCommitCompositorFrame());
[email protected]a017938b2014-05-27 21:17:171513#endif // defined(VIDEO_HOLE)
jdduke491a3f0c2015-06-15 23:30:261514 FlushPendingInputEventAck();
1515}
1516
1517void RenderWidget::DidCommitAndDrawCompositorFrame() {
1518 // NOTE: Tests may break if this event is renamed or moved. See
1519 // tab_capture_performancetest.cc.
1520 TRACE_EVENT0("gpu", "RenderWidget::DidCommitAndDrawCompositorFrame");
1521 // Notify subclasses that we initiated the paint operation.
1522 DidInitiatePaint();
1523}
1524
1525void RenderWidget::DidCompleteSwapBuffers() {
1526 TRACE_EVENT0("renderer", "RenderWidget::DidCompleteSwapBuffers");
1527
1528 // Notify subclasses threaded composited rendering was flushed to the screen.
1529 DidFlushPaint();
1530
1531 if (!next_paint_flags_ &&
1532 !need_update_rect_for_auto_resize_ &&
1533 !plugin_window_moves_.size()) {
1534 return;
1535 }
1536
1537 ViewHostMsg_UpdateRect_Params params;
1538 params.view_size = size_;
1539 params.plugin_window_moves.swap(plugin_window_moves_);
1540 params.flags = next_paint_flags_;
1541
1542 Send(new ViewHostMsg_UpdateRect(routing_id_, params));
1543 next_paint_flags_ = 0;
1544 need_update_rect_for_auto_resize_ = false;
1545}
1546
1547void RenderWidget::ScheduleComposite() {
1548 if (compositor_ &&
1549 compositor_deps_->GetCompositorImplThreadTaskRunner().get()) {
1550 compositor_->setNeedsAnimate();
1551 }
1552}
1553
1554void RenderWidget::ScheduleCompositeWithForcedRedraw() {
1555 if (compositor_) {
1556 // Regardless of whether threaded compositing is enabled, always
1557 // use this mechanism to force the compositor to redraw. However,
1558 // the invalidation code path below is still needed for the
1559 // non-threaded case.
1560 compositor_->SetNeedsForcedRedraw();
1561 }
1562 ScheduleComposite();
[email protected]6fceb912013-02-15 06:24:151563}
1564
[email protected]586871b2014-07-22 17:05:111565// static
1566scoped_ptr<cc::SwapPromise> RenderWidget::QueueMessageImpl(
1567 IPC::Message* msg,
1568 MessageDeliveryPolicy policy,
1569 FrameSwapMessageQueue* frame_swap_message_queue,
1570 scoped_refptr<IPC::SyncMessageFilter> sync_message_filter,
[email protected]586871b2014-07-22 17:05:111571 int source_frame_number) {
[email protected]586871b2014-07-22 17:05:111572 bool first_message_for_frame = false;
1573 frame_swap_message_queue->QueueMessageForFrame(policy,
1574 source_frame_number,
1575 make_scoped_ptr(msg),
1576 &first_message_for_frame);
1577 if (first_message_for_frame) {
1578 scoped_ptr<cc::SwapPromise> promise(new QueueMessageSwapPromise(
1579 sync_message_filter, frame_swap_message_queue, source_frame_number));
dcheng4b6b5ff2014-10-16 00:42:061580 return promise;
[email protected]586871b2014-07-22 17:05:111581 }
dcheng4b6b5ff2014-10-16 00:42:061582 return nullptr;
[email protected]586871b2014-07-22 17:05:111583}
1584
1585void RenderWidget::QueueMessage(IPC::Message* msg,
1586 MessageDeliveryPolicy policy) {
1587 // RenderThreadImpl::current() is NULL in some tests.
1588 if (!compositor_ || !RenderThreadImpl::current()) {
1589 Send(msg);
1590 return;
1591 }
1592
1593 scoped_ptr<cc::SwapPromise> swap_promise =
1594 QueueMessageImpl(msg,
1595 policy,
dcheng58867a92014-08-26 02:50:221596 frame_swap_message_queue_.get(),
[email protected]586871b2014-07-22 17:05:111597 RenderThreadImpl::current()->sync_message_filter(),
[email protected]586871b2014-07-22 17:05:111598 compositor_->GetSourceFrameNumber());
1599
1600 if (swap_promise) {
1601 compositor_->QueueSwapPromise(swap_promise.Pass());
igsollaeab34cc2015-02-20 11:33:351602 // Request a commit. This might either A) request a commit ahead of time
1603 // or B) request a commit which is not needed because there are not
1604 // pending updates. If B) then the commit will be skipped and the swap
1605 // promises will be broken (see EarlyOut_NoUpdates). To achieve that we
1606 // call SetNeedsUpdateLayers instead of SetNeedsCommit so that
1607 // can_cancel_commit is not unset.
1608 compositor_->SetNeedsUpdateLayers();
[email protected]586871b2014-07-22 17:05:111609 }
1610}
1611
[email protected]4873c7d2009-07-16 06:36:281612void RenderWidget::didChangeCursor(const WebCursorInfo& cursor_info) {
[email protected]7c51b0ee2009-07-08 21:49:301613 // TODO(darin): Eliminate this temporary.
[email protected]9ec87712013-05-24 23:23:521614 WebCursor cursor;
tfarina75a0abf2015-10-06 15:07:181615 InitializeCursorFromWebCursorInfo(&cursor, cursor_info);
initial.commit09911bf2008-07-26 23:55:291616 // Only send a SetCursor message if we need to make a change.
1617 if (!current_cursor_.IsEqual(cursor)) {
1618 current_cursor_ = cursor;
1619 Send(new ViewHostMsg_SetCursor(routing_id_, cursor));
1620 }
1621}
1622
1623// We are supposed to get a single call to Show for a newly created RenderWidget
1624// that was created via RenderWidget::CreateWebView. So, we wait until this
1625// point to dispatch the ShowWidget message.
1626//
1627// This method provides us with the information about how to display the newly
[email protected]5f9de5882011-09-30 23:36:281628// created RenderWidget (i.e., as a blocked popup or as a new tab).
initial.commit09911bf2008-07-26 23:55:291629//
[email protected]4873c7d2009-07-16 06:36:281630void RenderWidget::show(WebNavigationPolicy) {
initial.commit09911bf2008-07-26 23:55:291631 DCHECK(!did_show_) << "received extraneous Show call";
1632 DCHECK(routing_id_ != MSG_ROUTING_NONE);
1633 DCHECK(opener_id_ != MSG_ROUTING_NONE);
1634
[email protected]8de12d942010-11-17 20:42:441635 if (did_show_)
1636 return;
1637
1638 did_show_ = true;
bokanc007c3a2015-02-03 07:15:561639 // NOTE: initial_rect_ may still have its default values at this point, but
[email protected]8de12d942010-11-17 20:42:441640 // that's okay. It'll be ignored if as_popup is false, or the browser
1641 // process will impose a default position otherwise.
bokanc007c3a2015-02-03 07:15:561642 Send(new ViewHostMsg_ShowWidget(opener_id_, routing_id_, initial_rect_));
1643 SetPendingWindowRect(initial_rect_);
initial.commit09911bf2008-07-26 23:55:291644}
1645
[email protected]4873c7d2009-07-16 06:36:281646void RenderWidget::didFocus() {
initial.commit09911bf2008-07-26 23:55:291647}
1648
[email protected]2533ce12009-05-09 00:02:241649void RenderWidget::DoDeferredClose() {
ennef3c58142014-12-09 21:44:381650 WillCloseLayerTreeView();
[email protected]2533ce12009-05-09 00:02:241651 Send(new ViewHostMsg_Close(routing_id_));
1652}
1653
dgozmancf9039cd2015-04-06 12:01:311654void RenderWidget::NotifyOnClose() {
1655 FOR_EACH_OBSERVER(RenderFrameImpl, render_frames_, WidgetWillClose());
1656}
1657
[email protected]4873c7d2009-07-16 06:36:281658void RenderWidget::closeWidgetSoon() {
skyostiled8969c2015-07-20 16:57:081659 DCHECK(content::RenderThread::Get());
[email protected]e1c3a552012-05-04 20:51:321660 if (is_swapped_out_) {
1661 // This widget is currently swapped out, and the active widget is in a
1662 // different process. Have the browser route the close request to the
1663 // active widget instead, so that the correct unload handlers are run.
1664 Send(new ViewHostMsg_RouteCloseEvent(routing_id_));
1665 return;
1666 }
1667
initial.commit09911bf2008-07-26 23:55:291668 // If a page calls window.close() twice, we'll end up here twice, but that's
1669 // OK. It is safe to send multiple Close messages.
1670
[email protected]2533ce12009-05-09 00:02:241671 // Ask the RenderWidgetHost to initiate close. We could be called from deep
1672 // in Javascript. If we ask the RendwerWidgetHost to close now, the window
1673 // could be closed before the JS finishes executing. So instead, post a
1674 // message back to the message loop, which won't run until the JS is
1675 // complete, and then the Close message can be sent.
skyostiled8969c2015-07-20 16:57:081676 base::ThreadTaskRunnerHandle::Get()->PostTask(
[email protected]32876ae2011-11-15 22:25:211677 FROM_HERE, base::Bind(&RenderWidget::DoDeferredClose, this));
initial.commit09911bf2008-07-26 23:55:291678}
1679
[email protected]9017d7852013-11-21 17:47:351680void RenderWidget::QueueSyntheticGesture(
1681 scoped_ptr<SyntheticGestureParams> gesture_params,
1682 const SyntheticGestureCompletionCallback& callback) {
1683 DCHECK(!callback.is_null());
1684
1685 pending_synthetic_gesture_callbacks_.push(callback);
1686
1687 SyntheticGesturePacket gesture_packet;
1688 gesture_packet.set_gesture_params(gesture_params.Pass());
1689
1690 Send(new InputHostMsg_QueueSyntheticGesture(routing_id_, gesture_packet));
1691}
1692
initial.commit09911bf2008-07-26 23:55:291693void RenderWidget::Close() {
[email protected]404630b2014-07-03 19:33:031694 screen_metrics_emulator_.reset();
ennef3c58142014-12-09 21:44:381695 WillCloseLayerTreeView();
1696 compositor_.reset();
initial.commit09911bf2008-07-26 23:55:291697 if (webwidget_) {
[email protected]4873c7d2009-07-16 06:36:281698 webwidget_->close();
initial.commit09911bf2008-07-26 23:55:291699 webwidget_ = NULL;
1700 }
1701}
1702
[email protected]4873c7d2009-07-16 06:36:281703WebRect RenderWidget::windowRect() {
1704 if (pending_window_rect_count_)
1705 return pending_window_rect_;
[email protected]2533ce12009-05-09 00:02:241706
[email protected]80ad8622012-11-07 16:33:031707 return view_screen_rect_;
initial.commit09911bf2008-07-26 23:55:291708}
1709
[email protected]180ef242013-11-07 06:50:461710void RenderWidget::setToolTipText(const blink::WebString& text,
[email protected]8a9d6ca32011-06-06 20:11:301711 WebTextDirection hint) {
[email protected]5a395b72011-08-08 19:13:541712 Send(new ViewHostMsg_SetTooltipText(routing_id_, text, hint));
[email protected]8a9d6ca32011-06-06 20:11:301713}
1714
[email protected]b2e4c70132013-10-03 02:07:511715void RenderWidget::setWindowRect(const WebRect& rect) {
oshima750cb4342015-10-31 00:59:011716 // TODO(oshima): Scale back to DIP coordinates.
bokanc007c3a2015-02-03 07:15:561717 WebRect window_rect = rect;
[email protected]b2e4c70132013-10-03 02:07:511718 if (popup_origin_scale_for_emulation_) {
1719 float scale = popup_origin_scale_for_emulation_;
bokanc007c3a2015-02-03 07:15:561720 window_rect.x = popup_screen_origin_for_emulation_.x() +
1721 (window_rect.x - popup_view_origin_for_emulation_.x()) * scale;
1722 window_rect.y = popup_screen_origin_for_emulation_.y() +
1723 (window_rect.y - popup_view_origin_for_emulation_.y()) * scale;
[email protected]b2e4c70132013-10-03 02:07:511724 }
1725
[email protected]5b45ad42013-10-25 00:42:041726 if (!resizing_mode_selector_->is_synchronous_mode()) {
[email protected]ec951b9d2013-10-20 06:21:201727 if (did_show_) {
bokanc007c3a2015-02-03 07:15:561728 Send(new ViewHostMsg_RequestMove(routing_id_, window_rect));
1729 SetPendingWindowRect(window_rect);
[email protected]8be1c582013-03-06 00:55:031730 } else {
bokanc007c3a2015-02-03 07:15:561731 initial_rect_ = window_rect;
[email protected]8be1c582013-03-06 00:55:031732 }
initial.commit09911bf2008-07-26 23:55:291733 } else {
bokanc007c3a2015-02-03 07:15:561734 SetWindowRectSynchronously(window_rect);
initial.commit09911bf2008-07-26 23:55:291735 }
1736}
1737
[email protected]2533ce12009-05-09 00:02:241738void RenderWidget::SetPendingWindowRect(const WebRect& rect) {
1739 pending_window_rect_ = rect;
1740 pending_window_rect_count_++;
1741}
1742
[email protected]4873c7d2009-07-16 06:36:281743WebRect RenderWidget::rootWindowRect() {
[email protected]2533ce12009-05-09 00:02:241744 if (pending_window_rect_count_) {
1745 // NOTE(mbelshe): If there is a pending_window_rect_, then getting
1746 // the RootWindowRect is probably going to return wrong results since the
1747 // browser may not have processed the Move yet. There isn't really anything
1748 // good to do in this case, and it shouldn't happen - since this size is
1749 // only really needed for windowToScreen, which is only used for Popups.
[email protected]4873c7d2009-07-16 06:36:281750 return pending_window_rect_;
[email protected]2533ce12009-05-09 00:02:241751 }
1752
[email protected]80ad8622012-11-07 16:33:031753 return window_screen_rect_;
[email protected]d4547452008-08-28 18:36:371754}
1755
[email protected]4873c7d2009-07-16 06:36:281756WebRect RenderWidget::windowResizerRect() {
1757 return resizer_rect_;
[email protected]c04b6362008-11-21 18:54:191758}
1759
[email protected]fa7b1dc2010-06-23 17:53:041760void RenderWidget::OnImeSetComposition(
[email protected]fcf75d42013-12-03 20:11:261761 const base::string16& text,
[email protected]fa7b1dc2010-06-23 17:53:041762 const std::vector<WebCompositionUnderline>& underlines,
1763 int selection_start, int selection_end) {
[email protected]0d1ebed12013-08-05 22:01:131764 if (!ShouldHandleImeEvent())
[email protected]4873c7d2009-07-16 06:36:281765 return;
[email protected]66fca5bc2013-05-23 06:58:291766 ImeEventGuard guard(this);
[email protected]88dbe32f2013-06-20 23:31:361767 if (!webwidget_->setComposition(
[email protected]fa7b1dc2010-06-23 17:53:041768 text, WebVector<WebCompositionUnderline>(underlines),
1769 selection_start, selection_end)) {
1770 // If we failed to set the composition text, then we need to let the browser
1771 // process to cancel the input method's ongoing composition session, to make
1772 // sure we are in a consistent state.
[email protected]a2214eb2014-06-23 18:31:221773 Send(new InputHostMsg_ImeCancelComposition(routing_id()));
[email protected]7f00efa2010-04-15 05:01:261774 }
[email protected]88dbe32f2013-06-20 23:31:361775 UpdateCompositionInfo(true);
[email protected]fa7b1dc2010-06-23 17:53:041776}
1777
[email protected]fcf75d42013-12-03 20:11:261778void RenderWidget::OnImeConfirmComposition(const base::string16& text,
[email protected]db4fc1e2013-09-06 20:01:511779 const gfx::Range& replacement_range,
[email protected]0e45bd02013-07-12 20:20:021780 bool keep_selection) {
[email protected]0d1ebed12013-08-05 22:01:131781 if (!ShouldHandleImeEvent())
[email protected]d0be63772011-12-20 23:18:041782 return;
[email protected]66fca5bc2013-05-23 06:58:291783 ImeEventGuard guard(this);
[email protected]d0be63772011-12-20 23:18:041784 handling_input_event_ = true;
[email protected]0e45bd02013-07-12 20:20:021785 if (text.length())
1786 webwidget_->confirmComposition(text);
1787 else if (keep_selection)
1788 webwidget_->confirmComposition(WebWidget::KeepSelection);
1789 else
1790 webwidget_->confirmComposition(WebWidget::DoNotKeepSelection);
[email protected]d0be63772011-12-20 23:18:041791 handling_input_event_ = false;
[email protected]88dbe32f2013-06-20 23:31:361792 UpdateCompositionInfo(true);
initial.commit09911bf2008-07-26 23:55:291793}
1794
[email protected]0bc1f572013-04-17 01:46:311795void RenderWidget::OnRepaint(gfx::Size size_to_paint) {
[email protected]ec7dc112008-08-06 05:30:121796 // During shutdown we can just ignore this message.
1797 if (!webwidget_)
1798 return;
1799
[email protected]0bc1f572013-04-17 01:46:311800 // Even if the browser provides an empty damage rect, it's still expecting to
1801 // receive a repaint ack so just damage the entire widget bounds.
1802 if (size_to_paint.IsEmpty()) {
1803 size_to_paint = size_;
1804 }
1805
[email protected]ec7dc112008-08-06 05:30:121806 set_next_paint_is_repaint_ack();
[email protected]aca33f4f2014-05-17 17:08:051807 if (compositor_)
[email protected]0bc1f572013-04-17 01:46:311808 compositor_->SetNeedsRedrawRect(gfx::Rect(size_to_paint));
[email protected]ec7dc112008-08-06 05:30:121809}
1810
[email protected]79fa22e2013-08-23 15:18:121811void RenderWidget::OnSyntheticGestureCompleted() {
[email protected]9017d7852013-11-21 17:47:351812 DCHECK(!pending_synthetic_gesture_callbacks_.empty());
1813
1814 pending_synthetic_gesture_callbacks_.front().Run();
1815 pending_synthetic_gesture_callbacks_.pop();
[email protected]0e241b4b2012-08-18 09:06:271816}
1817
[email protected]4873c7d2009-07-16 06:36:281818void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
[email protected]07f953332009-03-25 04:31:111819 if (!webwidget_)
1820 return;
[email protected]4873c7d2009-07-16 06:36:281821 webwidget_->setTextDirection(direction);
[email protected]07f953332009-03-25 04:31:111822}
1823
[email protected]80ad8622012-11-07 16:33:031824void RenderWidget::OnUpdateScreenRects(const gfx::Rect& view_screen_rect,
1825 const gfx::Rect& window_screen_rect) {
[email protected]b2e4c70132013-10-03 02:07:511826 if (screen_metrics_emulator_) {
1827 screen_metrics_emulator_->OnUpdateScreenRectsMessage(
1828 view_screen_rect, window_screen_rect);
1829 } else {
1830 view_screen_rect_ = view_screen_rect;
1831 window_screen_rect_ = window_screen_rect;
1832 }
[email protected]80ad8622012-11-07 16:33:031833 Send(new ViewHostMsg_UpdateScreenRects_ACK(routing_id()));
1834}
1835
kenrbb4e2a3b2015-05-14 15:05:051836void RenderWidget::OnSetSurfaceIdNamespace(uint32_t surface_id_namespace) {
1837 if (compositor_)
1838 compositor_->SetSurfaceIdNamespace(surface_id_namespace);
1839}
1840
dtrainor5ef644e2015-11-19 00:12:471841void RenderWidget::OnHandleCompositorProto(const std::vector<uint8_t>& proto) {
1842 if (compositor_)
1843 compositor_->OnHandleCompositorProto(proto);
1844}
1845
[email protected]adb362312014-06-28 06:04:241846void RenderWidget::showImeIfNeeded() {
1847 OnShowImeIfNeeded();
[email protected]0d1ebed12013-08-05 22:01:131848}
1849
oshimaf866dab2015-12-05 00:41:541850void RenderWidget::convertViewportToWindow(blink::WebRect* rect) {
1851 if (IsUseZoomForDSFEnabled()) {
1852 float reverse = 1 / device_scale_factor_;
1853 // TODO(oshima): We may wait to allow pixel precision here as the the
1854 // anchor element can be placed at half pixel.
1855 gfx::Rect window_rect =
1856 gfx::ScaleToEnclosedRect(gfx::Rect(*rect), reverse);
1857 rect->x = window_rect.x();
1858 rect->y = window_rect.y();
1859 rect->width = window_rect.width();
1860 rect->height = window_rect.height();
1861 }
1862}
1863
[email protected]adb362312014-06-28 06:04:241864void RenderWidget::OnShowImeIfNeeded() {
1865#if defined(OS_ANDROID) || defined(USE_AURA)
1866 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME);
1867#endif
rouslanf7ebd8832015-01-22 01:54:141868
1869// TODO(rouslan): Fix ChromeOS and Windows 8 behavior of autofill popup with
1870// virtual keyboard.
1871#if !defined(OS_ANDROID)
1872 FocusChangeComplete();
1873#endif
[email protected]adb362312014-06-28 06:04:241874}
1875
1876#if defined(OS_ANDROID)
changwan3a841162015-08-11 02:53:371877void RenderWidget::OnImeEventSentForAck(const blink::WebTextInputInfo& info) {
1878 text_input_info_history_.push_back(info);
[email protected]0d1ebed12013-08-05 22:01:131879}
1880
1881void RenderWidget::OnImeEventAck() {
changwan3a841162015-08-11 02:53:371882 DCHECK_GE(text_input_info_history_.size(), 1u);
1883 text_input_info_history_.pop_front();
[email protected]2384b6c2013-02-28 23:58:511884}
[email protected]105dffb42013-02-20 03:46:211885#endif
1886
[email protected]0d1ebed12013-08-05 22:01:131887bool RenderWidget::ShouldHandleImeEvent() {
1888#if defined(OS_ANDROID)
changwan3a841162015-08-11 02:53:371889 if (!webwidget_)
1890 return false;
1891
1892 // We cannot handle IME events if there is any chance that the event we are
1893 // receiving here from the browser is based on the state that is different
1894 // from our current one as indicated by |text_input_info_|.
1895 // The states the browser might be in are:
1896 // text_input_info_history_[0] - current state ack'd by browser
1897 // text_input_info_history_[1...N] - pending state changes
1898 for (size_t i = 0u; i < text_input_info_history_.size() - 1u; ++i) {
1899 if (text_input_info_history_[i] != text_input_info_)
1900 return false;
1901 }
1902 return true;
[email protected]0d1ebed12013-08-05 22:01:131903#else
1904 return !!webwidget_;
1905#endif
1906}
1907
[email protected]c27dd4f2014-05-22 18:05:191908bool RenderWidget::SendAckForMouseMoveFromDebugger() {
1909 if (handling_event_type_ == WebInputEvent::MouseMove) {
[email protected]5fea4a52014-05-27 00:17:521910 // If we pause multiple times during a single mouse move event, we should
1911 // only send ACK once.
1912 if (!ignore_ack_for_mouse_move_from_debugger_) {
lanweif1a22832015-05-19 17:24:101913 InputEventAck ack(handling_event_type_, INPUT_EVENT_ACK_STATE_CONSUMED);
[email protected]5fea4a52014-05-27 00:17:521914 Send(new InputHostMsg_HandleInputEvent_ACK(routing_id_, ack));
dgozmanb739185d2015-04-10 15:04:021915 return true;
[email protected]5fea4a52014-05-27 00:17:521916 }
[email protected]c27dd4f2014-05-22 18:05:191917 }
1918 return false;
1919}
1920
1921void RenderWidget::IgnoreAckForMouseMoveFromDebugger() {
1922 ignore_ack_for_mouse_move_from_debugger_ = true;
1923}
1924
[email protected]468ac582012-11-20 00:53:191925void RenderWidget::SetDeviceScaleFactor(float device_scale_factor) {
1926 if (device_scale_factor_ == device_scale_factor)
1927 return;
1928
1929 device_scale_factor_ = device_scale_factor;
jdduke491a3f0c2015-06-15 23:30:261930 ScheduleComposite();
[email protected]468ac582012-11-20 00:53:191931}
1932
[email protected]28ed6b32014-06-08 02:16:271933bool RenderWidget::SetDeviceColorProfile(
1934 const std::vector<char>& color_profile) {
1935 if (device_color_profile_ == color_profile)
1936 return false;
1937
1938 device_color_profile_ = color_profile;
1939 return true;
1940}
1941
noeldb4df152014-09-16 17:45:201942void RenderWidget::ResetDeviceColorProfileForTesting() {
1943 if (!device_color_profile_.empty())
1944 device_color_profile_.clear();
1945 device_color_profile_.push_back('0');
1946}
1947
[email protected]fcdc5642014-05-09 14:32:241948void RenderWidget::OnOrientationChange() {
1949}
1950
[email protected]ceb36f7d2012-10-31 18:33:241951gfx::Vector2d RenderWidget::GetScrollOffset() {
[email protected]d54169e92011-01-21 09:19:521952 // Bare RenderWidgets don't support scroll offset.
[email protected]ceb36f7d2012-10-31 18:33:241953 return gfx::Vector2d();
[email protected]d54169e92011-01-21 09:19:521954}
1955
[email protected]bee16aab2009-08-26 15:55:031956void RenderWidget::SetHidden(bool hidden) {
1957 if (is_hidden_ == hidden)
1958 return;
1959
jdduke8fac9d102014-12-20 02:40:131960 // The status has changed. Tell the RenderThread about it and ensure
1961 // throttled acks are released in case frame production ceases.
[email protected]bee16aab2009-08-26 15:55:031962 is_hidden_ = hidden;
jdduke8fac9d102014-12-20 02:40:131963 FlushPendingInputEventAck();
1964
[email protected]bee16aab2009-08-26 15:55:031965 if (is_hidden_)
[email protected]b2db9272014-01-10 17:42:001966 RenderThreadImpl::current()->WidgetHidden();
[email protected]bee16aab2009-08-26 15:55:031967 else
[email protected]b2db9272014-01-10 17:42:001968 RenderThreadImpl::current()->WidgetRestored();
alexclarke7fa93942015-10-21 15:37:111969
1970 if (render_widget_scheduling_state_)
1971 render_widget_scheduling_state_->SetHidden(hidden);
[email protected]bee16aab2009-08-26 15:55:031972}
1973
[email protected]2b624c562011-10-27 22:58:261974void RenderWidget::DidToggleFullscreen() {
[email protected]2b624c562011-10-27 22:58:261975 if (!webwidget_)
1976 return;
1977
mikhail.pozdnyakovf2c902a2015-04-14 08:09:121978 if (is_fullscreen_granted_) {
[email protected]2b624c562011-10-27 22:58:261979 webwidget_->didEnterFullScreen();
1980 } else {
1981 webwidget_->didExitFullScreen();
1982 }
[email protected]2b624c562011-10-27 22:58:261983}
1984
[email protected]674741932009-02-04 23:44:461985bool RenderWidget::next_paint_is_resize_ack() const {
[email protected]53d3f302009-12-21 04:42:051986 return ViewHostMsg_UpdateRect_Flags::is_resize_ack(next_paint_flags_);
[email protected]674741932009-02-04 23:44:461987}
1988
[email protected]674741932009-02-04 23:44:461989void RenderWidget::set_next_paint_is_resize_ack() {
[email protected]53d3f302009-12-21 04:42:051990 next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_RESIZE_ACK;
[email protected]674741932009-02-04 23:44:461991}
1992
[email protected]674741932009-02-04 23:44:461993void RenderWidget::set_next_paint_is_repaint_ack() {
[email protected]53d3f302009-12-21 04:42:051994 next_paint_flags_ |= ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK;
[email protected]674741932009-02-04 23:44:461995}
1996
[email protected]b18583c2012-12-18 06:55:271997static bool IsDateTimeInput(ui::TextInputType type) {
1998 return type == ui::TEXT_INPUT_TYPE_DATE ||
1999 type == ui::TEXT_INPUT_TYPE_DATE_TIME ||
2000 type == ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL ||
2001 type == ui::TEXT_INPUT_TYPE_MONTH ||
2002 type == ui::TEXT_INPUT_TYPE_TIME ||
2003 type == ui::TEXT_INPUT_TYPE_WEEK;
2004}
2005
changwanf2a707b2015-10-30 08:22:162006void RenderWidget::OnImeEventGuardStart(ImeEventGuard* guard) {
2007 if (!ime_event_guard_)
2008 ime_event_guard_ = guard;
[email protected]66fca5bc2013-05-23 06:58:292009}
2010
changwanf2a707b2015-10-30 08:22:162011void RenderWidget::OnImeEventGuardFinish(ImeEventGuard* guard) {
2012 if (ime_event_guard_ != guard) {
2013#if defined(OS_ANDROID)
2014 // In case a from-IME event (e.g. touch) ends up in not-from-IME event
2015 // (e.g. long press gesture), we want to treat it as not-from-IME event
2016 // so that AdapterInputConnection can make changes to its Editable model.
2017 // Therefore, we want to mark this text state update as 'from IME' only
2018 // when all the nested events are all originating from IME.
2019 ime_event_guard_->set_from_ime(
2020 ime_event_guard_->from_ime() && guard->from_ime());
2021#endif
2022 return;
2023 }
2024 ime_event_guard_ = nullptr;
2025
[email protected]66fca5bc2013-05-23 06:58:292026 // While handling an ime event, text input state and selection bounds updates
2027 // are ignored. These must explicitly be updated once finished handling the
2028 // ime event.
2029 UpdateSelectionBounds();
[email protected]cb9e2632013-06-18 11:26:472030#if defined(OS_ANDROID)
changwanf2a707b2015-10-30 08:22:162031 UpdateTextInputState(
2032 guard->show_ime() ? SHOW_IME_IF_NEEDED : NO_SHOW_IME,
2033 guard->from_ime() ? FROM_IME : FROM_NON_IME);
[email protected]cb9e2632013-06-18 11:26:472034#endif
[email protected]66fca5bc2013-05-23 06:58:292035}
2036
[email protected]90f24152014-04-09 12:41:362037void RenderWidget::UpdateTextInputState(ShowIme show_ime,
2038 ChangeSource change_source) {
jdduke1aebad8e2015-07-22 23:25:082039 TRACE_EVENT0("renderer", "RenderWidget::UpdateTextInputState");
changwanf2a707b2015-10-30 08:22:162040 if (ime_event_guard_) {
2041 // show_ime should still be effective even if it was set inside the IME
2042 // event guard.
2043 if (show_ime == SHOW_IME_IF_NEEDED) {
2044 ime_event_guard_->set_show_ime(true);
2045 }
[email protected]e8f775f2013-02-14 21:00:502046 return;
changwanf2a707b2015-10-30 08:22:162047 }
2048
[email protected]ad26ef42011-06-17 07:59:452049 ui::TextInputType new_type = GetTextInputType();
[email protected]b18583c2012-12-18 06:55:272050 if (IsDateTimeInput(new_type))
2051 return; // Not considered as a text input field in WebKit/Chromium.
2052
[email protected]180ef242013-11-07 06:50:462053 blink::WebTextInputInfo new_info;
[email protected]5b739cb2012-08-21 20:35:212054 if (webwidget_)
2055 new_info = webwidget_->textInputInfo();
shuchen913f8b622015-07-31 13:22:432056 const ui::TextInputMode new_mode = ConvertInputMode(new_info.inputMode);
[email protected]5b739cb2012-08-21 20:35:212057
[email protected]ad26ef42011-06-17 07:59:452058 bool new_can_compose_inline = CanComposeInline();
[email protected]5b739cb2012-08-21 20:35:212059
[email protected]3306f262012-09-21 19:20:422060 // Only sends text input params if they are changed or if the ime should be
2061 // shown.
[email protected]90f24152014-04-09 12:41:362062 if (show_ime == SHOW_IME_IF_NEEDED ||
2063 (text_input_type_ != new_type ||
shuchen913f8b622015-07-31 13:22:432064 text_input_mode_ != new_mode ||
[email protected]90f24152014-04-09 12:41:362065 text_input_info_ != new_info ||
2066 can_compose_inline_ != new_can_compose_inline)
2067#if defined(OS_ANDROID)
2068 || text_field_is_dirty_
[email protected]183e28d2014-01-20 18:18:022069#endif
[email protected]90f24152014-04-09 12:41:362070 ) {
shuchen913f8b622015-07-31 13:22:432071 ViewHostMsg_TextInputState_Params params;
2072 params.type = new_type;
2073 params.mode = new_mode;
2074 params.flags = new_info.flags;
2075 params.value = new_info.value.utf8();
2076 params.selection_start = new_info.selectionStart;
2077 params.selection_end = new_info.selectionEnd;
2078 params.composition_start = new_info.compositionStart;
2079 params.composition_end = new_info.compositionEnd;
2080 params.can_compose_inline = new_can_compose_inline;
2081 params.show_ime_if_needed = (show_ime == SHOW_IME_IF_NEEDED);
[email protected]90f24152014-04-09 12:41:362082#if defined(USE_AURA)
shuchen913f8b622015-07-31 13:22:432083 params.is_non_ime_change = true;
[email protected]90f24152014-04-09 12:41:362084#endif
[email protected]183e28d2014-01-20 18:18:022085#if defined(OS_ANDROID)
shuchen913f8b622015-07-31 13:22:432086 params.is_non_ime_change = (change_source == FROM_NON_IME) ||
[email protected]90f24152014-04-09 12:41:362087 text_field_is_dirty_;
shuchen913f8b622015-07-31 13:22:432088 if (params.is_non_ime_change)
changwan3a841162015-08-11 02:53:372089 OnImeEventSentForAck(new_info);
[email protected]90f24152014-04-09 12:41:362090 text_field_is_dirty_ = false;
[email protected]183e28d2014-01-20 18:18:022091#endif
shuchen913f8b622015-07-31 13:22:432092 Send(new ViewHostMsg_TextInputStateChanged(routing_id(), params));
[email protected]5b739cb2012-08-21 20:35:212093
2094 text_input_info_ = new_info;
[email protected]fa7b1dc2010-06-23 17:53:042095 text_input_type_ = new_type;
shuchen913f8b622015-07-31 13:22:432096 text_input_mode_ = new_mode;
[email protected]ad26ef42011-06-17 07:59:452097 can_compose_inline_ = new_can_compose_inline;
shuchen82ce8c52014-10-23 01:55:202098 text_input_flags_ = new_info.flags;
initial.commit09911bf2008-07-26 23:55:292099 }
initial.commit09911bf2008-07-26 23:55:292100}
2101
[email protected]7c8873e2013-02-05 08:03:012102void RenderWidget::GetSelectionBounds(gfx::Rect* focus, gfx::Rect* anchor) {
2103 WebRect focus_webrect;
2104 WebRect anchor_webrect;
2105 webwidget_->selectionBounds(focus_webrect, anchor_webrect);
oshima750cb4342015-10-31 00:59:012106 if (IsUseZoomForDSFEnabled()) {
2107 float inverse_scale = 1.f / device_scale_factor_;
2108 gfx::RectF focus_rect(focus_webrect);
2109 *focus = gfx::ToEnclosingRect(gfx::ScaleRect(focus_rect, inverse_scale));
2110 gfx::RectF anchor_rect(anchor_webrect);
2111 *anchor = gfx::ToEnclosingRect(gfx::ScaleRect(anchor_rect, inverse_scale));
2112 } else {
2113 *focus = focus_webrect;
2114 *anchor = anchor_webrect;
2115 }
[email protected]73bf95812011-10-12 11:38:322116}
2117
[email protected]e99ef6f2011-10-16 01:13:002118void RenderWidget::UpdateSelectionBounds() {
jdduke1aebad8e2015-07-22 23:25:082119 TRACE_EVENT0("renderer", "RenderWidget::UpdateSelectionBounds");
[email protected]e99ef6f2011-10-16 01:13:002120 if (!webwidget_)
2121 return;
changwanf2a707b2015-10-30 08:22:162122 if (ime_event_guard_)
[email protected]66fca5bc2013-05-23 06:58:292123 return;
[email protected]e99ef6f2011-10-16 01:13:002124
mohsenb0eeba72015-08-09 06:20:082125#if defined(USE_AURA)
2126 // TODO(mohsen): For now, always send explicit selection IPC notifications for
2127 // Aura beucause composited selection updates are not working for webview tags
2128 // which regresses IME inside webview. Remove this when composited selection
2129 // updates are fixed for webviews. See, http://crbug.com/510568.
2130 bool send_ipc = true;
2131#else
jddukeacf809e2014-09-23 20:38:382132 // With composited selection updates, the selection bounds will be reported
2133 // directly by the compositor, in which case explicit IPC selection
2134 // notifications should be suppressed.
mohsenb0eeba72015-08-09 06:20:082135 bool send_ipc =
2136 !blink::WebRuntimeFeatures::isCompositedSelectionUpdateEnabled();
2137#endif
2138 if (send_ipc) {
jddukeacf809e2014-09-23 20:38:382139 ViewHostMsg_SelectionBounds_Params params;
2140 GetSelectionBounds(&params.anchor_rect, &params.focus_rect);
2141 if (selection_anchor_rect_ != params.anchor_rect ||
2142 selection_focus_rect_ != params.focus_rect) {
2143 selection_anchor_rect_ = params.anchor_rect;
2144 selection_focus_rect_ = params.focus_rect;
2145 webwidget_->selectionTextDirection(params.focus_dir, params.anchor_dir);
2146 params.is_anchor_first = webwidget_->isSelectionAnchorFirst();
2147 Send(new ViewHostMsg_SelectionBoundsChanged(routing_id_, params));
2148 }
[email protected]58b48a0d2012-06-13 07:01:352149 }
jddukeacf809e2014-09-23 20:38:382150
[email protected]88dbe32f2013-06-20 23:31:362151 UpdateCompositionInfo(false);
[email protected]e99ef6f2011-10-16 01:13:002152}
2153
dtrainor5ef644e2015-11-19 00:12:472154void RenderWidget::ForwardCompositorProto(const std::vector<uint8_t>& proto) {
2155 Send(new ViewHostMsg_ForwardCompositorProto(routing_id_, proto));
2156}
2157
[email protected]180ef242013-11-07 06:50:462158// Check blink::WebTextInputType and ui::TextInputType is kept in sync.
mostynbe29b6882015-01-13 09:59:172159#define STATIC_ASSERT_WTIT_ENUM_MATCH(a, b) \
2160 static_assert(int(blink::WebTextInputType##a) \
2161 == int(ui::TEXT_INPUT_TYPE_##b), \
2162 "mismatching enums: " #a)
2163
2164STATIC_ASSERT_WTIT_ENUM_MATCH(None, NONE);
2165STATIC_ASSERT_WTIT_ENUM_MATCH(Text, TEXT);
2166STATIC_ASSERT_WTIT_ENUM_MATCH(Password, PASSWORD);
2167STATIC_ASSERT_WTIT_ENUM_MATCH(Search, SEARCH);
2168STATIC_ASSERT_WTIT_ENUM_MATCH(Email, EMAIL);
2169STATIC_ASSERT_WTIT_ENUM_MATCH(Number, NUMBER);
2170STATIC_ASSERT_WTIT_ENUM_MATCH(Telephone, TELEPHONE);
2171STATIC_ASSERT_WTIT_ENUM_MATCH(URL, URL);
2172STATIC_ASSERT_WTIT_ENUM_MATCH(Date, DATE);
2173STATIC_ASSERT_WTIT_ENUM_MATCH(DateTime, DATE_TIME);
2174STATIC_ASSERT_WTIT_ENUM_MATCH(DateTimeLocal, DATE_TIME_LOCAL);
2175STATIC_ASSERT_WTIT_ENUM_MATCH(Month, MONTH);
2176STATIC_ASSERT_WTIT_ENUM_MATCH(Time, TIME);
2177STATIC_ASSERT_WTIT_ENUM_MATCH(Week, WEEK);
2178STATIC_ASSERT_WTIT_ENUM_MATCH(TextArea, TEXT_AREA);
2179STATIC_ASSERT_WTIT_ENUM_MATCH(ContentEditable, CONTENT_EDITABLE);
2180STATIC_ASSERT_WTIT_ENUM_MATCH(DateTimeField, DATE_TIME_FIELD);
[email protected]ad26ef42011-06-17 07:59:452181
[email protected]5b739cb2012-08-21 20:35:212182ui::TextInputType RenderWidget::WebKitToUiTextInputType(
[email protected]180ef242013-11-07 06:50:462183 blink::WebTextInputType type) {
[email protected]5b739cb2012-08-21 20:35:212184 // Check the type is in the range representable by ui::TextInputType.
2185 DCHECK_LE(type, static_cast<int>(ui::TEXT_INPUT_TYPE_MAX)) <<
[email protected]180ef242013-11-07 06:50:462186 "blink::WebTextInputType and ui::TextInputType not synchronized";
[email protected]5b739cb2012-08-21 20:35:212187 return static_cast<ui::TextInputType>(type);
2188}
2189
[email protected]ad26ef42011-06-17 07:59:452190ui::TextInputType RenderWidget::GetTextInputType() {
[email protected]8969bb3f2012-11-30 21:49:272191 if (webwidget_)
jdduke3bf083fe2015-09-29 23:40:532192 return WebKitToUiTextInputType(webwidget_->textInputType());
[email protected]ad26ef42011-06-17 07:59:452193 return ui::TEXT_INPUT_TYPE_NONE;
2194}
2195
[email protected]501ea13d2013-07-09 17:03:292196void RenderWidget::UpdateCompositionInfo(bool should_update_range) {
yukawa5f21c6a2014-10-27 17:09:302197#if defined(OS_ANDROID)
yukawa6f899b22014-12-15 18:56:112198 // TODO(yukawa): Start sending character bounds when the browser side
2199 // implementation becomes ready (crbug.com/424866).
2200#else
jdduke1aebad8e2015-07-22 23:25:082201 TRACE_EVENT0("renderer", "RenderWidget::UpdateCompositionInfo");
[email protected]db4fc1e2013-09-06 20:01:512202 gfx::Range range = gfx::Range();
[email protected]501ea13d2013-07-09 17:03:292203 if (should_update_range) {
2204 GetCompositionRange(&range);
2205 } else {
2206 range = composition_range_;
2207 }
2208 std::vector<gfx::Rect> character_bounds;
2209 GetCompositionCharacterBounds(&character_bounds);
2210
2211 if (!ShouldUpdateCompositionInfo(range, character_bounds))
2212 return;
2213 composition_character_bounds_ = character_bounds;
2214 composition_range_ = range;
[email protected]a2214eb2014-06-23 18:31:222215 Send(new InputHostMsg_ImeCompositionRangeChanged(
[email protected]501ea13d2013-07-09 17:03:292216 routing_id(), composition_range_, composition_character_bounds_));
yukawa6f899b22014-12-15 18:56:112217#endif
[email protected]501ea13d2013-07-09 17:03:292218}
2219
[email protected]58b48a0d2012-06-13 07:01:352220void RenderWidget::GetCompositionCharacterBounds(
2221 std::vector<gfx::Rect>* bounds) {
2222 DCHECK(bounds);
2223 bounds->clear();
2224}
2225
[email protected]db4fc1e2013-09-06 20:01:512226void RenderWidget::GetCompositionRange(gfx::Range* range) {
[email protected]88dbe32f2013-06-20 23:31:362227 size_t location, length;
2228 if (webwidget_->compositionRange(&location, &length)) {
2229 range->set_start(location);
2230 range->set_end(location + length);
2231 } else if (webwidget_->caretOrSelectionRange(&location, &length)) {
2232 range->set_start(location);
2233 range->set_end(location + length);
2234 } else {
[email protected]db4fc1e2013-09-06 20:01:512235 *range = gfx::Range::InvalidRange();
[email protected]88dbe32f2013-06-20 23:31:362236 }
2237}
2238
[email protected]501ea13d2013-07-09 17:03:292239bool RenderWidget::ShouldUpdateCompositionInfo(
[email protected]db4fc1e2013-09-06 20:01:512240 const gfx::Range& range,
[email protected]501ea13d2013-07-09 17:03:292241 const std::vector<gfx::Rect>& bounds) {
2242 if (composition_range_ != range)
2243 return true;
2244 if (bounds.size() != composition_character_bounds_.size())
2245 return true;
2246 for (size_t i = 0; i < bounds.size(); ++i) {
2247 if (bounds[i] != composition_character_bounds_[i])
2248 return true;
2249 }
2250 return false;
2251}
[email protected]501ea13d2013-07-09 17:03:292252
[email protected]ad26ef42011-06-17 07:59:452253bool RenderWidget::CanComposeInline() {
2254 return true;
[email protected]56ea1a62011-05-30 07:05:572255}
2256
[email protected]4873c7d2009-07-16 06:36:282257WebScreenInfo RenderWidget::screenInfo() {
[email protected]842f10652012-06-06 01:54:042258 return screen_info_;
[email protected]4873c7d2009-07-16 06:36:282259}
2260
[email protected]fa7b1dc2010-06-23 17:53:042261void RenderWidget::resetInputMethod() {
[email protected]0e45bd02013-07-12 20:20:022262 ImeEventGuard guard(this);
[email protected]fa7b1dc2010-06-23 17:53:042263 // If the last text input type is not None, then we should finish any
2264 // ongoing composition regardless of the new text input type.
[email protected]ad26ef42011-06-17 07:59:452265 if (text_input_type_ != ui::TEXT_INPUT_TYPE_NONE) {
[email protected]fa7b1dc2010-06-23 17:53:042266 // If a composition text exists, then we need to let the browser process
2267 // to cancel the input method's ongoing composition session.
2268 if (webwidget_->confirmComposition())
[email protected]a2214eb2014-06-23 18:31:222269 Send(new InputHostMsg_ImeCancelComposition(routing_id()));
[email protected]fa7b1dc2010-06-23 17:53:042270 }
[email protected]d4cff272011-05-02 15:46:012271
[email protected]88dbe32f2013-06-20 23:31:362272 UpdateCompositionInfo(true);
[email protected]fa7b1dc2010-06-23 17:53:042273}
2274
donnda070f3c2015-01-16 19:54:112275#if defined(OS_ANDROID)
2276void RenderWidget::showUnhandledTapUIIfNeeded(
2277 const WebPoint& tapped_position,
2278 const WebNode& tapped_node,
2279 bool page_changed) {
2280 DCHECK(handling_input_event_);
2281 bool should_trigger = !page_changed && tapped_node.isTextNode() &&
donnd57e54f52015-02-26 19:03:372282 !tapped_node.isContentEditable() &&
2283 !tapped_node.isInsideFocusableElementOrARIAWidget();
donnda070f3c2015-01-16 19:54:112284 if (should_trigger) {
2285 Send(new ViewHostMsg_ShowUnhandledTapUIIfNeeded(routing_id_,
2286 tapped_position.x, tapped_position.y));
2287 }
2288}
2289#endif
2290
[email protected]c68c3e4e2013-01-24 00:36:562291void RenderWidget::didHandleGestureEvent(
2292 const WebGestureEvent& event,
2293 bool event_cancelled) {
[email protected]183e28d2014-01-20 18:18:022294#if defined(OS_ANDROID) || defined(USE_AURA)
[email protected]c68c3e4e2013-01-24 00:36:562295 if (event_cancelled)
2296 return;
[email protected]07c70d22014-08-21 08:33:462297 if (event.type == WebInputEvent::GestureTap) {
[email protected]90f24152014-04-09 12:41:362298 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME);
[email protected]07c70d22014-08-21 08:33:462299 } else if (event.type == WebInputEvent::GestureLongPress) {
2300 DCHECK(webwidget_);
2301 if (webwidget_->textInputInfo().value.isEmpty())
2302 UpdateTextInputState(NO_SHOW_IME, FROM_NON_IME);
2303 else
2304 UpdateTextInputState(SHOW_IME_IF_NEEDED, FROM_NON_IME);
[email protected]c68c3e4e2013-01-24 00:36:562305 }
2306#endif
2307}
2308
sataya.m582c9ce2015-06-09 08:03:422309void RenderWidget::didOverscroll(
2310 const blink::WebFloatSize& unusedDelta,
2311 const blink::WebFloatSize& accumulatedRootOverScroll,
2312 const blink::WebFloatPoint& position,
2313 const blink::WebFloatSize& velocity) {
2314 DidOverscrollParams params;
sataya.m582c9ce2015-06-09 08:03:422315 params.accumulated_overscroll = gfx::Vector2dF(
2316 accumulatedRootOverScroll.width, accumulatedRootOverScroll.height);
2317 params.latest_overscroll_delta =
2318 gfx::Vector2dF(unusedDelta.width, unusedDelta.height);
sataya.ma5cc13a2015-06-13 11:06:022319 // TODO(sataya.m): don't negate velocity once http://crbug.com/499743 is
2320 // fixed.
sataya.m582c9ce2015-06-09 08:03:422321 params.current_fling_velocity =
sataya.ma5cc13a2015-06-13 11:06:022322 gfx::Vector2dF(-velocity.width, -velocity.height);
sataya.m582c9ce2015-06-09 08:03:422323 params.causal_event_viewport_point = gfx::PointF(position.x, position.y);
jddukec05612b2015-06-25 23:13:182324
2325 // If we're currently handling an event, stash the overscroll data such that
2326 // it can be bundled in the event ack.
2327 if (handling_event_overscroll_) {
2328 handling_event_overscroll_->reset(new DidOverscrollParams(params));
2329 return;
2330 }
2331
sataya.m582c9ce2015-06-09 08:03:422332 Send(new InputHostMsg_DidOverscroll(routing_id_, params));
2333}
2334
[email protected]7912e822014-04-16 02:37:032335void RenderWidget::StartCompositor() {
sievers71c62dd52015-10-07 01:44:392336 if (!is_hidden())
2337 compositor_->setVisible(true);
[email protected]7912e822014-04-16 02:37:032338}
2339
[email protected]29e2fb42013-07-19 01:13:472340void RenderWidget::SchedulePluginMove(const WebPluginGeometry& move) {
initial.commit09911bf2008-07-26 23:55:292341 size_t i = 0;
2342 for (; i < plugin_window_moves_.size(); ++i) {
2343 if (plugin_window_moves_[i].window == move.window) {
[email protected]16f89d02009-08-26 17:17:582344 if (move.rects_valid) {
2345 plugin_window_moves_[i] = move;
2346 } else {
2347 plugin_window_moves_[i].visible = move.visible;
2348 }
initial.commit09911bf2008-07-26 23:55:292349 break;
2350 }
2351 }
2352
2353 if (i == plugin_window_moves_.size())
2354 plugin_window_moves_.push_back(move);
2355}
[email protected]268654772009-08-06 23:02:042356
2357void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) {
2358 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin();
2359 i != plugin_window_moves_.end(); ++i) {
2360 if (i->window == window) {
2361 plugin_window_moves_.erase(i);
2362 break;
2363 }
2364 }
2365}
[email protected]67bfb83f2011-09-22 03:36:372366
[email protected]63b465922012-09-06 02:04:522367
[email protected]24ed0432013-04-24 07:50:312368RenderWidgetCompositor* RenderWidget::compositor() const {
2369 return compositor_.get();
2370}
2371
[email protected]180ef242013-11-07 06:50:462372bool RenderWidget::WillHandleMouseEvent(const blink::WebMouseEvent& event) {
[email protected]67bfb83f2011-09-22 03:36:372373 return false;
2374}
[email protected]c3d45532011-10-07 19:20:402375
[email protected]41d86852012-11-07 12:23:242376bool RenderWidget::WillHandleGestureEvent(
[email protected]180ef242013-11-07 06:50:462377 const blink::WebGestureEvent& event) {
[email protected]41d86852012-11-07 12:23:242378 return false;
2379}
2380
ccamerona7644752014-12-30 01:16:312381void RenderWidget::ObserveWheelEventAndResult(
ccamerond4ba47902014-12-17 07:20:312382 const blink::WebMouseWheelEvent& wheel_event,
sataya.mf405d0e2015-07-07 16:51:112383 const gfx::Vector2dF& wheel_unused_delta,
ccamerond4ba47902014-12-17 07:20:312384 bool event_processed) {
ccamerona7644752014-12-30 01:16:312385 if (!compositor_deps_->IsElasticOverscrollEnabled())
ccamerond4ba47902014-12-17 07:20:312386 return;
2387
ccamerond4ba47902014-12-17 07:20:312388 cc::InputHandlerScrollResult scroll_result;
sataya.mf405d0e2015-07-07 16:51:112389 scroll_result.did_scroll = event_processed;
2390 scroll_result.did_overscroll_root = !wheel_unused_delta.IsZero();
2391 scroll_result.unused_scroll_delta = wheel_unused_delta;
ccamerond4ba47902014-12-17 07:20:312392
2393 RenderThreadImpl* render_thread = RenderThreadImpl::current();
2394 InputHandlerManager* input_handler_manager =
2395 render_thread ? render_thread->input_handler_manager() : NULL;
2396 if (input_handler_manager) {
2397 input_handler_manager->ObserveWheelEventAndResultOnMainThread(
2398 routing_id_, wheel_event, scroll_result);
2399 }
2400}
2401
[email protected]ce6689f2013-03-29 12:52:552402void RenderWidget::hasTouchEventHandlers(bool has_handlers) {
alexclarke7fa93942015-10-21 15:37:112403 if (render_widget_scheduling_state_)
2404 render_widget_scheduling_state_->SetHasTouchHandler(has_handlers);
[email protected]ce6689f2013-03-29 12:52:552405 Send(new ViewHostMsg_HasTouchEventHandlers(routing_id_, has_handlers));
2406}
2407
mostynbe29b6882015-01-13 09:59:172408// Check blink::WebTouchAction and blink::WebTouchActionAuto is kept in sync
2409#define STATIC_ASSERT_WTI_ENUM_MATCH(a, b) \
2410 static_assert(int(blink::WebTouchAction##a) == int(TOUCH_ACTION_##b), \
2411 "mismatching enums: " #a)
2412
[email protected]5d0bbdfa92013-12-10 00:35:512413void RenderWidget::setTouchAction(
2414 blink::WebTouchAction web_touch_action) {
2415
2416 // Ignore setTouchAction calls that result from synthetic touch events (eg.
2417 // when blink is emulating touch with mouse).
[email protected]c27dd4f2014-05-22 18:05:192418 if (handling_event_type_ != WebInputEvent::TouchStart)
[email protected]5d0bbdfa92013-12-10 00:35:512419 return;
2420
dtapuskaa98ac8d72015-05-08 19:29:092421 // Verify the same values are used by the types so we can cast between them.
mostynbe29b6882015-01-13 09:59:172422 STATIC_ASSERT_WTI_ENUM_MATCH(None, NONE);
dtapuskaa98ac8d72015-05-08 19:29:092423 STATIC_ASSERT_WTI_ENUM_MATCH(PanLeft, PAN_LEFT);
2424 STATIC_ASSERT_WTI_ENUM_MATCH(PanRight, PAN_RIGHT);
mostynbe29b6882015-01-13 09:59:172425 STATIC_ASSERT_WTI_ENUM_MATCH(PanX, PAN_X);
dtapuskaa98ac8d72015-05-08 19:29:092426 STATIC_ASSERT_WTI_ENUM_MATCH(PanUp, PAN_UP);
2427 STATIC_ASSERT_WTI_ENUM_MATCH(PanDown, PAN_DOWN);
mostynbe29b6882015-01-13 09:59:172428 STATIC_ASSERT_WTI_ENUM_MATCH(PanY, PAN_Y);
rbyersa8b478d2015-10-30 15:49:102429 STATIC_ASSERT_WTI_ENUM_MATCH(Pan, PAN);
mostynbe29b6882015-01-13 09:59:172430 STATIC_ASSERT_WTI_ENUM_MATCH(PinchZoom, PINCH_ZOOM);
rbyersa8b478d2015-10-30 15:49:102431 STATIC_ASSERT_WTI_ENUM_MATCH(Manipulation, MANIPULATION);
2432 STATIC_ASSERT_WTI_ENUM_MATCH(DoubleTapZoom, DOUBLE_TAP_ZOOM);
2433 STATIC_ASSERT_WTI_ENUM_MATCH(Auto, AUTO);
[email protected]a18f67a2013-12-20 19:44:362434
2435 content::TouchAction content_touch_action =
2436 static_cast<content::TouchAction>(web_touch_action);
[email protected]5d0bbdfa92013-12-10 00:35:512437 Send(new InputHostMsg_SetTouchAction(routing_id_, content_touch_action));
2438}
2439
[email protected]90f24152014-04-09 12:41:362440void RenderWidget::didUpdateTextOfFocusedElementByNonUserInput() {
2441#if defined(OS_ANDROID)
2442 text_field_is_dirty_ = true;
2443#endif
2444}
2445
[email protected]3d5c243b2012-11-30 00:26:012446bool RenderWidget::HasTouchEventHandlersAt(const gfx::Point& point) const {
2447 return true;
2448}
2449
[email protected]0634cdd42013-08-16 00:46:092450scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
jbauman5e420d32015-08-05 09:33:012451RenderWidget::CreateGraphicsContext3D(bool compositor) {
[email protected]ed7defa2013-03-12 21:29:592452 if (!webwidget_)
[email protected]0634cdd42013-08-16 00:46:092453 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
avi83883c82014-12-23 00:08:492454 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]ebc0e1df2013-08-01 02:46:222455 switches::kDisableGpuCompositing))
[email protected]0634cdd42013-08-16 00:46:092456 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
[email protected]96ab016c2013-10-23 00:50:292457 if (!RenderThreadImpl::current())
2458 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
[email protected]4d7e46a2013-11-08 05:33:402459 CauseForGpuLaunch cause =
2460 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
[email protected]96ab016c2013-10-23 00:50:292461 scoped_refptr<GpuChannelHost> gpu_channel_host(
[email protected]4d7e46a2013-11-08 05:33:402462 RenderThreadImpl::current()->EstablishGpuChannelSync(cause));
dcheng58867a92014-08-26 02:50:222463 if (!gpu_channel_host.get())
[email protected]96ab016c2013-10-23 00:50:292464 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
[email protected]ed7defa2013-03-12 21:29:592465
[email protected]828a3932014-04-02 14:43:132466 // Explicitly disable antialiasing for the compositor. As of the time of
2467 // this writing, the only platform that supported antialiasing for the
2468 // compositor was Mac OS X, because the on-screen OpenGL context creation
2469 // code paths on Windows and Linux didn't yet have multisampling support.
2470 // Mac OS X essentially always behaves as though it's rendering offscreen.
2471 // Multisampling has a heavy cost especially on devices with relatively low
2472 // fill rate like most notebooks, and the Mac implementation would need to
2473 // be optimized to resolve directly into the IOSurface shared between the
2474 // GPU and browser processes. For these reasons and to avoid platform
2475 // disparities we explicitly disable antialiasing.
2476 blink::WebGraphicsContext3D::Attributes attributes;
2477 attributes.antialias = false;
2478 attributes.shareResources = true;
2479 attributes.noAutomaticFlushes = true;
2480 attributes.depth = false;
2481 attributes.stencil = false;
[email protected]828a3932014-04-02 14:43:132482 bool lose_context_when_out_of_memory = true;
[email protected]96ab016c2013-10-23 00:50:292483 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits limits;
[email protected]b6eb8e332013-09-10 00:51:012484#if defined(OS_ANDROID)
boliu853d46052015-10-13 20:20:062485 bool using_synchronous_compositing =
boliubee541f42015-11-05 00:52:532486 SynchronousCompositorFactory::GetInstance() ||
2487 base::CommandLine::ForCurrentProcess()->HasSwitch(
2488 switches::kIPCSyncCompositing);
[email protected]b6eb8e332013-09-10 00:51:012489 // If we raster too fast we become upload bound, and pending
2490 // uploads consume memory. For maximum upload throughput, we would
2491 // want to allow for upload_throughput * pipeline_time of pending
2492 // uploads, after which we are just wasting memory. Since we don't
2493 // know our upload throughput yet, this just caps our memory usage.
boliu853d46052015-10-13 20:20:062494 // Synchronous compositor uses half because synchronous compositor
2495 // pipeline is only one frame deep. But twice of half for low end
2496 // because 16bit texture is not supported.
2497 size_t divider = using_synchronous_compositing ? 2 : 1;
[email protected]35b4f0c2014-06-26 16:55:272498 if (base::SysInfo::IsLowEndDevice())
[email protected]657be322013-09-20 08:50:032499 divider = 6;
[email protected]b6eb8e332013-09-10 00:51:012500 // For reference Nexus10 can upload 1MB in about 2.5ms.
[email protected]657be322013-09-20 08:50:032501 const double max_mb_uploaded_per_ms = 2.0 / (5 * divider);
[email protected]b6eb8e332013-09-10 00:51:012502 // Deadline to draw a frame to achieve 60 frames per second.
2503 const size_t kMillisecondsPerFrame = 16;
2504 // Assuming a two frame deep pipeline between the CPU and the GPU.
[email protected]657be322013-09-20 08:50:032505 size_t max_transfer_buffer_usage_mb =
2506 static_cast<size_t>(2 * kMillisecondsPerFrame * max_mb_uploaded_per_ms);
2507 static const size_t kBytesPerMegabyte = 1024 * 1024;
[email protected]b6eb8e332013-09-10 00:51:012508 // We keep the MappedMemoryReclaimLimit the same as the upload limit
2509 // to avoid unnecessarily stalling the compositor thread.
[email protected]96ab016c2013-10-23 00:50:292510 limits.mapped_memory_reclaim_limit =
[email protected]657be322013-09-20 08:50:032511 max_transfer_buffer_usage_mb * kBytesPerMegabyte;
[email protected]b6eb8e332013-09-10 00:51:012512#endif
jbauman00ca2dc2015-08-10 23:21:152513 if (compositor) {
jbauman5e420d32015-08-05 09:33:012514 limits.command_buffer_size = 64 * 1024;
jbauman00ca2dc2015-08-10 23:21:152515 limits.start_transfer_buffer_size = 64 * 1024;
2516 limits.min_transfer_buffer_size = 64 * 1024;
2517 }
[email protected]96ab016c2013-10-23 00:50:292518
[email protected]96ab016c2013-10-23 00:50:292519 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
piman5d36dae2015-09-24 22:47:052520 new WebGraphicsContext3DCommandBufferImpl(
piman08f75532015-10-05 18:58:012521 0, GetURLForGraphicsContext3D(), gpu_channel_host.get(), attributes,
2522 lose_context_when_out_of_memory, limits, NULL));
[email protected]0634cdd42013-08-16 00:46:092523 return context.Pass();
[email protected]ed7defa2013-03-12 21:29:592524}
2525
[email protected]e3244ed2014-06-20 20:04:272526void RenderWidget::RegisterRenderFrameProxy(RenderFrameProxy* proxy) {
2527 render_frame_proxies_.AddObserver(proxy);
[email protected]bffc8302014-01-23 20:52:162528}
2529
[email protected]e3244ed2014-06-20 20:04:272530void RenderWidget::UnregisterRenderFrameProxy(RenderFrameProxy* proxy) {
2531 render_frame_proxies_.RemoveObserver(proxy);
[email protected]bffc8302014-01-23 20:52:162532}
2533
[email protected]de3c5d82014-05-28 22:12:592534void RenderWidget::RegisterRenderFrame(RenderFrameImpl* frame) {
2535 render_frames_.AddObserver(frame);
2536}
2537
2538void RenderWidget::UnregisterRenderFrame(RenderFrameImpl* frame) {
2539 render_frames_.RemoveObserver(frame);
2540}
2541
[email protected]a017938b2014-05-27 21:17:172542#if defined(VIDEO_HOLE)
2543void RenderWidget::RegisterVideoHoleFrame(RenderFrameImpl* frame) {
2544 video_hole_frames_.AddObserver(frame);
2545}
2546
2547void RenderWidget::UnregisterVideoHoleFrame(RenderFrameImpl* frame) {
2548 video_hole_frames_.RemoveObserver(frame);
2549}
2550#endif // defined(VIDEO_HOLE)
2551
[email protected]e9ff79c2012-10-19 21:31:262552} // namespace content