blob: fa97ddad4f1fa332f2c6506cb05d3fac1ce957e8 [file] [log] [blame]
[email protected]05d478752009-04-08 23:38:161// Copyright (c) 2009 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
5#include "chrome/renderer/render_widget.h"
6
initial.commit09911bf2008-07-26 23:55:297#include "base/gfx/point.h"
8#include "base/gfx/size.h"
9#include "base/logging.h"
10#include "base/message_loop.h"
initial.commit09911bf2008-07-26 23:55:2911#include "base/scoped_ptr.h"
[email protected]661eb9d2009-02-03 02:11:4812#include "build/build_config.h"
[email protected]674741932009-02-04 23:44:4613#include "chrome/common/render_messages.h"
[email protected]e68e62fa2009-02-20 02:00:0414#include "chrome/common/transport_dib.h"
[email protected]8085dbc82008-09-26 22:53:4415#include "chrome/renderer/render_process.h"
[email protected]661eb9d2009-02-03 02:11:4816#include "skia/ext/platform_canvas.h"
[email protected]d5282e72009-05-13 13:16:5217#include "third_party/skia/include/core/SkShader.h"
[email protected]7c51b0ee2009-07-08 21:49:3018#include "webkit/api/public/WebCursorInfo.h"
[email protected]4873c7d2009-07-16 06:36:2819#include "webkit/api/public/WebPopupMenu.h"
[email protected]88efb7ec2009-07-14 16:32:5920#include "webkit/api/public/WebPopupMenuInfo.h"
[email protected]afdcf5c2009-05-10 20:30:4121#include "webkit/api/public/WebRect.h"
22#include "webkit/api/public/WebScreenInfo.h"
23#include "webkit/api/public/WebSize.h"
[email protected]8c89e7792009-08-19 21:18:3424#include "webkit/glue/webkit_glue.h"
[email protected]661eb9d2009-02-03 02:11:4825
26#if defined(OS_POSIX)
[email protected]d5282e72009-05-13 13:16:5227#include "third_party/skia/include/core/SkPixelRef.h"
28#include "third_party/skia/include/core/SkMallocPixelRef.h"
[email protected]661eb9d2009-02-03 02:11:4829#endif // defined(OS_POSIX)
[email protected]8085dbc82008-09-26 22:53:4430
[email protected]4873c7d2009-07-16 06:36:2831#include "webkit/api/public/WebWidget.h"
initial.commit09911bf2008-07-26 23:55:2932
[email protected]4873c7d2009-07-16 06:36:2833using WebKit::WebCompositionCommand;
[email protected]7c51b0ee2009-07-08 21:49:3034using WebKit::WebCursorInfo;
[email protected]62cb33cae2009-03-27 23:30:2235using WebKit::WebInputEvent;
[email protected]4873c7d2009-07-16 06:36:2836using WebKit::WebNavigationPolicy;
37using WebKit::WebPopupMenu;
[email protected]88efb7ec2009-07-14 16:32:5938using WebKit::WebPopupMenuInfo;
[email protected]b3f2b912009-04-09 16:18:5239using WebKit::WebRect;
[email protected]12456fa2009-04-01 23:07:1940using WebKit::WebScreenInfo;
[email protected]b3f2b912009-04-09 16:18:5241using WebKit::WebSize;
[email protected]4873c7d2009-07-16 06:36:2842using WebKit::WebTextDirection;
[email protected]62cb33cae2009-03-27 23:30:2243
[email protected]cfd727f2009-01-09 20:21:1144RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable)
initial.commit09911bf2008-07-26 23:55:2945 : routing_id_(MSG_ROUTING_NONE),
[email protected]c5b3b5e2009-02-13 06:41:1146 webwidget_(NULL),
initial.commit09911bf2008-07-26 23:55:2947 opener_id_(MSG_ROUTING_NONE),
[email protected]8085dbc82008-09-26 22:53:4448 render_thread_(render_thread),
[email protected]5a3b9142009-08-28 21:03:1749 host_window_(NULL),
initial.commit09911bf2008-07-26 23:55:2950 current_paint_buf_(NULL),
51 current_scroll_buf_(NULL),
52 next_paint_flags_(0),
53 paint_reply_pending_(false),
54 did_show_(false),
initial.commit09911bf2008-07-26 23:55:2955 is_hidden_(false),
56 needs_repainting_on_restore_(false),
57 has_focus_(false),
[email protected]5dd768212009-08-13 23:34:4958 handling_input_event_(false),
[email protected]661eb9d2009-02-03 02:11:4859 closing_(false),
initial.commit09911bf2008-07-26 23:55:2960 ime_is_active_(false),
61 ime_control_enable_ime_(true),
62 ime_control_x_(-1),
63 ime_control_y_(-1),
64 ime_control_new_state_(false),
[email protected]0ebf3872008-11-07 21:35:0365 ime_control_updated_(false),
[email protected]9f23f592008-11-17 08:36:3466 ime_control_busy_(false),
[email protected]2533ce12009-05-09 00:02:2467 activatable_(activatable),
68 pending_window_rect_count_(0) {
[email protected]8930d472009-02-21 08:05:2869 RenderProcess::current()->AddRefProcess();
[email protected]8085dbc82008-09-26 22:53:4470 DCHECK(render_thread_);
initial.commit09911bf2008-07-26 23:55:2971}
72
73RenderWidget::~RenderWidget() {
[email protected]c5b3b5e2009-02-13 06:41:1174 DCHECK(!webwidget_) << "Leaking our WebWidget!";
initial.commit09911bf2008-07-26 23:55:2975 if (current_paint_buf_) {
[email protected]8930d472009-02-21 08:05:2876 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
initial.commit09911bf2008-07-26 23:55:2977 current_paint_buf_ = NULL;
78 }
79 if (current_scroll_buf_) {
[email protected]8930d472009-02-21 08:05:2880 RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_);
initial.commit09911bf2008-07-26 23:55:2981 current_scroll_buf_ = NULL;
82 }
[email protected]8930d472009-02-21 08:05:2883 RenderProcess::current()->ReleaseProcess();
initial.commit09911bf2008-07-26 23:55:2984}
85
86/*static*/
[email protected]8085dbc82008-09-26 22:53:4487RenderWidget* RenderWidget::Create(int32 opener_id,
[email protected]0ebf3872008-11-07 21:35:0388 RenderThreadBase* render_thread,
[email protected]cfd727f2009-01-09 20:21:1189 bool activatable) {
initial.commit09911bf2008-07-26 23:55:2990 DCHECK(opener_id != MSG_ROUTING_NONE);
[email protected]0ebf3872008-11-07 21:35:0391 scoped_refptr<RenderWidget> widget = new RenderWidget(render_thread,
[email protected]cfd727f2009-01-09 20:21:1192 activatable);
initial.commit09911bf2008-07-26 23:55:2993 widget->Init(opener_id); // adds reference
94 return widget;
95}
96
[email protected]88efb7ec2009-07-14 16:32:5997void RenderWidget::ConfigureAsExternalPopupMenu(const WebPopupMenuInfo& info) {
98 popup_params_.reset(new ViewHostMsg_ShowPopup_Params);
99 popup_params_->item_height = info.itemHeight;
100 popup_params_->selected_item = info.selectedIndex;
101 for (size_t i = 0; i < info.items.size(); ++i)
102 popup_params_->popup_items.push_back(WebMenuItem(info.items[i]));
103}
104
initial.commit09911bf2008-07-26 23:55:29105void RenderWidget::Init(int32 opener_id) {
106 DCHECK(!webwidget_);
107
108 if (opener_id != MSG_ROUTING_NONE)
109 opener_id_ = opener_id;
110
[email protected]4873c7d2009-07-16 06:36:28111 webwidget_ = WebPopupMenu::create(this);
initial.commit09911bf2008-07-26 23:55:29112
[email protected]8085dbc82008-09-26 22:53:44113 bool result = render_thread_->Send(
[email protected]cfd727f2009-01-09 20:21:11114 new ViewHostMsg_CreateWidget(opener_id, activatable_, &routing_id_));
initial.commit09911bf2008-07-26 23:55:29115 if (result) {
[email protected]8085dbc82008-09-26 22:53:44116 render_thread_->AddRoute(routing_id_, this);
initial.commit09911bf2008-07-26 23:55:29117 // Take a reference on behalf of the RenderThread. This will be balanced
118 // when we receive ViewMsg_Close.
119 AddRef();
120 } else {
121 DCHECK(false);
122 }
123}
124
125// This is used to complete pending inits and non-pending inits. For non-
126// pending cases, the parent will be the same as the current parent. This
127// indicates we do not need to reparent or anything.
[email protected]18bcc3c2009-01-27 21:39:15128void RenderWidget::CompleteInit(gfx::NativeViewId parent_hwnd) {
initial.commit09911bf2008-07-26 23:55:29129 DCHECK(routing_id_ != MSG_ROUTING_NONE);
initial.commit09911bf2008-07-26 23:55:29130
131 host_window_ = parent_hwnd;
132
[email protected]6de74452009-02-25 18:04:59133 Send(new ViewHostMsg_RenderViewReady(routing_id_));
initial.commit09911bf2008-07-26 23:55:29134}
135
136IPC_DEFINE_MESSAGE_MAP(RenderWidget)
137 IPC_MESSAGE_HANDLER(ViewMsg_Close, OnClose)
138 IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)
139 IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize)
140 IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden)
141 IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored)
142 IPC_MESSAGE_HANDLER(ViewMsg_PaintRect_ACK, OnPaintRectAck)
143 IPC_MESSAGE_HANDLER(ViewMsg_ScrollRect_ACK, OnScrollRectAck)
144 IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent)
145 IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost)
146 IPC_MESSAGE_HANDLER(ViewMsg_SetFocus, OnSetFocus)
147 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetInputMode, OnImeSetInputMode)
148 IPC_MESSAGE_HANDLER(ViewMsg_ImeSetComposition, OnImeSetComposition)
[email protected]ec7dc112008-08-06 05:30:12149 IPC_MESSAGE_HANDLER(ViewMsg_Repaint, OnMsgRepaint)
[email protected]07f953332009-03-25 04:31:11150 IPC_MESSAGE_HANDLER(ViewMsg_SetTextDirection, OnSetTextDirection)
[email protected]2533ce12009-05-09 00:02:24151 IPC_MESSAGE_HANDLER(ViewMsg_Move_ACK, OnRequestMoveAck)
initial.commit09911bf2008-07-26 23:55:29152 IPC_MESSAGE_UNHANDLED_ERROR()
153IPC_END_MESSAGE_MAP()
154
155bool RenderWidget::Send(IPC::Message* message) {
156 // Don't send any messages after the browser has told us to close.
157 if (closing_) {
158 delete message;
159 return false;
160 }
161
162 // If given a messsage without a routing ID, then assign our routing ID.
163 if (message->routing_id() == MSG_ROUTING_NONE)
164 message->set_routing_id(routing_id_);
165
[email protected]d3fc25652009-02-24 22:31:25166 return render_thread_->Send(message);
[email protected]8085dbc82008-09-26 22:53:44167}
168
initial.commit09911bf2008-07-26 23:55:29169// Got a response from the browser after the renderer decided to create a new
170// view.
[email protected]18bcc3c2009-01-27 21:39:15171void RenderWidget::OnCreatingNewAck(gfx::NativeViewId parent) {
initial.commit09911bf2008-07-26 23:55:29172 DCHECK(routing_id_ != MSG_ROUTING_NONE);
173
174 CompleteInit(parent);
175}
176
177void RenderWidget::OnClose() {
178 if (closing_)
179 return;
180 closing_ = true;
181
182 // Browser correspondence is no longer needed at this point.
[email protected]bee16aab2009-08-26 15:55:03183 if (routing_id_ != MSG_ROUTING_NONE) {
[email protected]8085dbc82008-09-26 22:53:44184 render_thread_->RemoveRoute(routing_id_);
[email protected]bee16aab2009-08-26 15:55:03185 SetHidden(false);
186 }
initial.commit09911bf2008-07-26 23:55:29187
initial.commit09911bf2008-07-26 23:55:29188 // If there is a Send call on the stack, then it could be dangerous to close
[email protected]d3fc25652009-02-24 22:31:25189 // now. Post a task that only gets invoked when there are no nested message
190 // loops.
191 MessageLoop::current()->PostNonNestableTask(FROM_HERE,
192 NewRunnableMethod(this, &RenderWidget::Close));
193
194 // Balances the AddRef taken when we called AddRoute.
195 Release();
initial.commit09911bf2008-07-26 23:55:29196}
197
[email protected]f21c613a2009-02-12 14:46:17198void RenderWidget::OnResize(const gfx::Size& new_size,
199 const gfx::Rect& resizer_rect) {
initial.commit09911bf2008-07-26 23:55:29200 // During shutdown we can just ignore this message.
201 if (!webwidget_)
202 return;
203
[email protected]f21c613a2009-02-12 14:46:17204 // Remember the rect where the resize corner will be drawn.
205 resizer_rect_ = resizer_rect;
206
initial.commit09911bf2008-07-26 23:55:29207 // TODO(darin): We should not need to reset this here.
[email protected]bee16aab2009-08-26 15:55:03208 SetHidden(false);
initial.commit09911bf2008-07-26 23:55:29209 needs_repainting_on_restore_ = false;
210
211 // We shouldn't be asked to resize to our current size.
212 DCHECK(size_ != new_size);
213 size_ = new_size;
214
215 // We should not be sent a Resize message if we have not ACK'd the previous
216 DCHECK(!next_paint_is_resize_ack());
217
218 // When resizing, we want to wait to paint before ACK'ing the resize. This
219 // ensures that we only resize as fast as we can paint. We only need to send
220 // an ACK if we are resized to a non-empty rect.
[email protected]4873c7d2009-07-16 06:36:28221 webwidget_->resize(new_size);
initial.commit09911bf2008-07-26 23:55:29222 if (!new_size.IsEmpty()) {
[email protected]2d5d09d52009-06-15 14:29:21223 DCHECK(!paint_rect_.IsEmpty());
initial.commit09911bf2008-07-26 23:55:29224
225 // This should have caused an invalidation of the entire view. The damaged
226 // rect could be larger than new_size if we are being made smaller.
[email protected]2d5d09d52009-06-15 14:29:21227 DCHECK_GE(paint_rect_.width(), new_size.width());
228 DCHECK_GE(paint_rect_.height(), new_size.height());
229
initial.commit09911bf2008-07-26 23:55:29230 // We will send the Resize_ACK flag once we paint again.
231 set_next_paint_is_resize_ack();
232 }
233}
234
235void RenderWidget::OnWasHidden() {
236 // Go into a mode where we stop generating paint and scrolling events.
[email protected]bee16aab2009-08-26 15:55:03237 SetHidden(true);
initial.commit09911bf2008-07-26 23:55:29238}
239
240void RenderWidget::OnWasRestored(bool needs_repainting) {
241 // During shutdown we can just ignore this message.
242 if (!webwidget_)
243 return;
244
245 // See OnWasHidden
[email protected]bee16aab2009-08-26 15:55:03246 SetHidden(false);
initial.commit09911bf2008-07-26 23:55:29247
248 if (!needs_repainting && !needs_repainting_on_restore_)
249 return;
250 needs_repainting_on_restore_ = false;
251
252 // Tag the next paint as a restore ack, which is picked up by DoDeferredPaint
253 // when it sends out the next PaintRect message.
254 set_next_paint_is_restore_ack();
255
256 // Generate a full repaint.
[email protected]4873c7d2009-07-16 06:36:28257 didInvalidateRect(gfx::Rect(size_.width(), size_.height()));
initial.commit09911bf2008-07-26 23:55:29258}
259
[email protected]b7fce1f2008-08-14 05:01:07260void RenderWidget::OnPaintRectAck() {
initial.commit09911bf2008-07-26 23:55:29261 DCHECK(paint_reply_pending());
262 paint_reply_pending_ = false;
[email protected]b7fce1f2008-08-14 05:01:07263 // If we sent a PaintRect message with a zero-sized bitmap, then
264 // we should have no current paint buf.
265 if (current_paint_buf_) {
[email protected]8930d472009-02-21 08:05:28266 RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_);
[email protected]b7fce1f2008-08-14 05:01:07267 current_paint_buf_ = NULL;
initial.commit09911bf2008-07-26 23:55:29268 }
[email protected]e68e62fa2009-02-20 02:00:04269
[email protected]a2f6bc112009-06-27 16:27:25270 // Notify subclasses
271 DidPaint();
272
initial.commit09911bf2008-07-26 23:55:29273 // Continue painting if necessary...
[email protected]12fbad812009-09-01 18:21:24274 CallDoDeferredPaint();
initial.commit09911bf2008-07-26 23:55:29275}
276
[email protected]2533ce12009-05-09 00:02:24277void RenderWidget::OnRequestMoveAck() {
278 DCHECK(pending_window_rect_count_);
279 pending_window_rect_count_--;
280}
281
initial.commit09911bf2008-07-26 23:55:29282void RenderWidget::OnScrollRectAck() {
283 DCHECK(scroll_reply_pending());
284
[email protected]e68e62fa2009-02-20 02:00:04285 if (current_scroll_buf_) {
[email protected]8930d472009-02-21 08:05:28286 RenderProcess::current()->ReleaseTransportDIB(current_scroll_buf_);
[email protected]e68e62fa2009-02-20 02:00:04287 current_scroll_buf_ = NULL;
288 }
initial.commit09911bf2008-07-26 23:55:29289
290 // Continue scrolling if necessary...
[email protected]12fbad812009-09-01 18:21:24291 CallDoDeferredScroll();
292}
293
294void RenderWidget::CallDoDeferredScroll() {
initial.commit09911bf2008-07-26 23:55:29295 DoDeferredScroll();
[email protected]12fbad812009-09-01 18:21:24296
297 if (pending_input_event_ack_.get()) {
298 Send(pending_input_event_ack_.get());
299 pending_input_event_ack_.release();
300 }
initial.commit09911bf2008-07-26 23:55:29301}
302
303void RenderWidget::OnHandleInputEvent(const IPC::Message& message) {
304 void* iter = NULL;
305
306 const char* data;
307 int data_length;
[email protected]5dd768212009-08-13 23:34:49308 handling_input_event_ = true;
309 if (!message.ReadData(&iter, &data, &data_length)) {
310 handling_input_event_ = false;
initial.commit09911bf2008-07-26 23:55:29311 return;
[email protected]5dd768212009-08-13 23:34:49312 }
initial.commit09911bf2008-07-26 23:55:29313
314 const WebInputEvent* input_event =
315 reinterpret_cast<const WebInputEvent*>(data);
316 bool processed = false;
317 if (webwidget_)
[email protected]4873c7d2009-07-16 06:36:28318 processed = webwidget_->handleInputEvent(*input_event);
initial.commit09911bf2008-07-26 23:55:29319
320 IPC::Message* response = new ViewHostMsg_HandleInputEvent_ACK(routing_id_);
321 response->WriteInt(input_event->type);
[email protected]e2824412009-02-27 01:57:05322 response->WriteBool(processed);
323
[email protected]12fbad812009-09-01 18:21:24324 if (input_event->type == WebInputEvent::MouseMove &&
325 (!paint_rect_.IsEmpty() || !scroll_rect_.IsEmpty())) {
326 // We want to rate limit the input events in this case, so we'll wait for
327 // painting to finish before ACKing this message.
328 pending_input_event_ack_.reset(response);
329 } else {
330 Send(response);
331 }
332
[email protected]5dd768212009-08-13 23:34:49333 handling_input_event_ = false;
initial.commit09911bf2008-07-26 23:55:29334}
335
336void RenderWidget::OnMouseCaptureLost() {
337 if (webwidget_)
[email protected]4873c7d2009-07-16 06:36:28338 webwidget_->mouseCaptureLost();
initial.commit09911bf2008-07-26 23:55:29339}
340
341void RenderWidget::OnSetFocus(bool enable) {
342 has_focus_ = enable;
343 if (webwidget_)
[email protected]4873c7d2009-07-16 06:36:28344 webwidget_->setFocus(enable);
initial.commit09911bf2008-07-26 23:55:29345 if (enable) {
346 // Force to retrieve the state of the focused widget to determine if we
347 // should activate IMEs next time when this process calls the UpdateIME()
348 // function.
349 ime_control_updated_ = true;
350 ime_control_new_state_ = true;
351 }
352}
353
354void RenderWidget::ClearFocus() {
355 // We may have got the focus from the browser before this gets processed, in
356 // which case we do not want to unfocus ourself.
357 if (!has_focus_ && webwidget_)
[email protected]4873c7d2009-07-16 06:36:28358 webwidget_->setFocus(false);
initial.commit09911bf2008-07-26 23:55:29359}
360
[email protected]2d5d09d52009-06-15 14:29:21361void RenderWidget::PaintRect(const gfx::Rect& rect,
362 skia::PlatformCanvas* canvas) {
363
364 // Bring the canvas into the coordinate system of the paint rect.
365 canvas->translate(static_cast<SkScalar>(-rect.x()),
366 static_cast<SkScalar>(-rect.y()));
[email protected]96c3499a2009-05-02 18:31:03367
[email protected]699ab0d2009-04-23 23:19:14368 // If there is a custom background, tile it.
369 if (!background_.empty()) {
[email protected]699ab0d2009-04-23 23:19:14370 SkPaint paint;
371 SkShader* shader = SkShader::CreateBitmapShader(background_,
372 SkShader::kRepeat_TileMode,
373 SkShader::kRepeat_TileMode);
374 paint.setShader(shader)->unref();
[email protected]8860e4f52009-06-25 01:01:52375 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
[email protected]699ab0d2009-04-23 23:19:14376 canvas->drawPaint(paint);
[email protected]699ab0d2009-04-23 23:19:14377 }
378
[email protected]8c89e7792009-08-19 21:18:34379 webwidget_->paint(webkit_glue::ToWebCanvas(canvas), rect);
initial.commit09911bf2008-07-26 23:55:29380
381 // Flush to underlying bitmap. TODO(darin): is this needed?
[email protected]661eb9d2009-02-03 02:11:48382 canvas->getTopPlatformDevice().accessBitmap(false);
initial.commit09911bf2008-07-26 23:55:29383}
384
[email protected]12fbad812009-09-01 18:21:24385void RenderWidget::CallDoDeferredPaint() {
386 DoDeferredPaint();
387
388 if (pending_input_event_ack_.get()) {
389 Send(pending_input_event_ack_.get());
390 pending_input_event_ack_.release();
391 }
392}
393
initial.commit09911bf2008-07-26 23:55:29394void RenderWidget::DoDeferredPaint() {
[email protected]2d5d09d52009-06-15 14:29:21395 if (!webwidget_ || paint_reply_pending() || paint_rect_.IsEmpty())
initial.commit09911bf2008-07-26 23:55:29396 return;
397
398 // When we are hidden, we want to suppress painting, but we still need to
399 // mark this DoDeferredPaint as complete.
400 if (is_hidden_ || size_.IsEmpty()) {
[email protected]2d5d09d52009-06-15 14:29:21401 paint_rect_ = gfx::Rect();
initial.commit09911bf2008-07-26 23:55:29402 needs_repainting_on_restore_ = true;
403 return;
404 }
405
406 // Layout may generate more invalidation...
[email protected]4873c7d2009-07-16 06:36:28407 webwidget_->layout();
initial.commit09911bf2008-07-26 23:55:29408
409 // OK, save the current paint_rect to a local since painting may cause more
410 // invalidation. Some WebCore rendering objects only layout when painted.
[email protected]2d5d09d52009-06-15 14:29:21411 gfx::Rect damaged_rect = paint_rect_;
412 paint_rect_ = gfx::Rect();
initial.commit09911bf2008-07-26 23:55:29413
414 // Compute a buffer for painting and cache it.
[email protected]e68e62fa2009-02-20 02:00:04415 skia::PlatformCanvas* canvas =
[email protected]f09c7182009-03-10 12:54:04416 RenderProcess::current()->GetDrawingCanvas(&current_paint_buf_,
[email protected]2d5d09d52009-06-15 14:29:21417 damaged_rect);
[email protected]e68e62fa2009-02-20 02:00:04418 if (!canvas) {
initial.commit09911bf2008-07-26 23:55:29419 NOTREACHED();
420 return;
421 }
422
[email protected]955ee6d62009-06-17 21:53:03423 // We may get back a smaller canvas than we asked for.
424 damaged_rect.set_width(canvas->getDevice()->width());
425 damaged_rect.set_height(canvas->getDevice()->height());
426
[email protected]2d5d09d52009-06-15 14:29:21427 PaintRect(damaged_rect, canvas);
initial.commit09911bf2008-07-26 23:55:29428
429 ViewHostMsg_PaintRect_Params params;
[email protected]2d5d09d52009-06-15 14:29:21430 params.bitmap_rect = damaged_rect;
initial.commit09911bf2008-07-26 23:55:29431 params.view_size = size_;
432 params.plugin_window_moves = plugin_window_moves_;
433 params.flags = next_paint_flags_;
[email protected]2d5d09d52009-06-15 14:29:21434 params.bitmap = current_paint_buf_->id();
initial.commit09911bf2008-07-26 23:55:29435
[email protected]e68e62fa2009-02-20 02:00:04436 delete canvas;
[email protected]661eb9d2009-02-03 02:11:48437
initial.commit09911bf2008-07-26 23:55:29438 plugin_window_moves_.clear();
439
440 paint_reply_pending_ = true;
441 Send(new ViewHostMsg_PaintRect(routing_id_, params));
442 next_paint_flags_ = 0;
443
444 UpdateIME();
445}
446
447void RenderWidget::DoDeferredScroll() {
448 if (!webwidget_ || scroll_reply_pending() || scroll_rect_.IsEmpty())
449 return;
450
451 // When we are hidden, we want to suppress scrolling, but we still need to
452 // mark this DoDeferredScroll as complete.
453 if (is_hidden_ || size_.IsEmpty()) {
454 scroll_rect_ = gfx::Rect();
455 needs_repainting_on_restore_ = true;
456 return;
457 }
458
459 // Layout may generate more invalidation, so we might have to bail on
460 // optimized scrolling...
[email protected]4873c7d2009-07-16 06:36:28461 webwidget_->layout();
initial.commit09911bf2008-07-26 23:55:29462
463 if (scroll_rect_.IsEmpty())
464 return;
465
466 gfx::Rect damaged_rect;
467
468 // Compute the region we will expose by scrolling, and paint that into a
469 // shared memory section.
470 if (scroll_delta_.x()) {
471 int dx = scroll_delta_.x();
472 damaged_rect.set_y(scroll_rect_.y());
473 damaged_rect.set_height(scroll_rect_.height());
474 if (dx > 0) {
475 damaged_rect.set_x(scroll_rect_.x());
476 damaged_rect.set_width(dx);
477 } else {
478 damaged_rect.set_x(scroll_rect_.right() + dx);
479 damaged_rect.set_width(-dx);
480 }
481 } else {
482 int dy = scroll_delta_.y();
483 damaged_rect.set_x(scroll_rect_.x());
484 damaged_rect.set_width(scroll_rect_.width());
485 if (dy > 0) {
486 damaged_rect.set_y(scroll_rect_.y());
487 damaged_rect.set_height(dy);
488 } else {
489 damaged_rect.set_y(scroll_rect_.bottom() + dy);
490 damaged_rect.set_height(-dy);
491 }
492 }
493
494 // In case the scroll offset exceeds the width/height of the scroll rect
495 damaged_rect = scroll_rect_.Intersect(damaged_rect);
496
[email protected]e68e62fa2009-02-20 02:00:04497 skia::PlatformCanvas* canvas =
[email protected]f09c7182009-03-10 12:54:04498 RenderProcess::current()->GetDrawingCanvas(&current_scroll_buf_,
499 damaged_rect);
[email protected]e68e62fa2009-02-20 02:00:04500 if (!canvas) {
initial.commit09911bf2008-07-26 23:55:29501 NOTREACHED();
502 return;
503 }
504
[email protected]955ee6d62009-06-17 21:53:03505 // We may get back a smaller canvas than we asked for.
506 damaged_rect.set_width(canvas->getDevice()->width());
507 damaged_rect.set_height(canvas->getDevice()->height());
508
initial.commit09911bf2008-07-26 23:55:29509 // Set these parameters before calling Paint, since that could result in
510 // further invalidates (uncommon).
511 ViewHostMsg_ScrollRect_Params params;
initial.commit09911bf2008-07-26 23:55:29512 params.bitmap_rect = damaged_rect;
513 params.dx = scroll_delta_.x();
514 params.dy = scroll_delta_.y();
515 params.clip_rect = scroll_rect_;
516 params.view_size = size_;
517 params.plugin_window_moves = plugin_window_moves_;
[email protected]e68e62fa2009-02-20 02:00:04518 params.bitmap = current_scroll_buf_->id();
[email protected]661eb9d2009-02-03 02:11:48519
initial.commit09911bf2008-07-26 23:55:29520 plugin_window_moves_.clear();
521
522 // Mark the scroll operation as no longer pending.
523 scroll_rect_ = gfx::Rect();
524
[email protected]e68e62fa2009-02-20 02:00:04525 PaintRect(damaged_rect, canvas);
initial.commit09911bf2008-07-26 23:55:29526 Send(new ViewHostMsg_ScrollRect(routing_id_, params));
[email protected]e68e62fa2009-02-20 02:00:04527 delete canvas;
initial.commit09911bf2008-07-26 23:55:29528 UpdateIME();
529}
530
531///////////////////////////////////////////////////////////////////////////////
532// WebWidgetDelegate
533
[email protected]4873c7d2009-07-16 06:36:28534void RenderWidget::didInvalidateRect(const WebRect& rect) {
initial.commit09911bf2008-07-26 23:55:29535 // We only want one pending DoDeferredPaint call at any time...
[email protected]2d5d09d52009-06-15 14:29:21536 bool paint_pending = !paint_rect_.IsEmpty();
initial.commit09911bf2008-07-26 23:55:29537
538 // If this invalidate overlaps with a pending scroll, then we have to
539 // downgrade to invalidating the scroll rect.
[email protected]b3f2b912009-04-09 16:18:52540 if (gfx::Rect(rect).Intersects(scroll_rect_)) {
[email protected]2d5d09d52009-06-15 14:29:21541 paint_rect_ = paint_rect_.Union(scroll_rect_);
initial.commit09911bf2008-07-26 23:55:29542 scroll_rect_ = gfx::Rect();
543 }
544
[email protected]2d5d09d52009-06-15 14:29:21545 gfx::Rect view_rect(0, 0, size_.width(), size_.height());
546 // TODO(iyengar) Investigate why we have painting issues when
547 // we ignore invalid regions outside the view.
548 // Ignore invalidates that occur outside the bounds of the view
549 // TODO(darin): maybe this should move into the paint code?
550 // paint_rect_ = view_rect.Intersect(paint_rect_.Union(rect));
551 paint_rect_ = paint_rect_.Union(view_rect.Intersect(rect));
initial.commit09911bf2008-07-26 23:55:29552
[email protected]2d5d09d52009-06-15 14:29:21553 if (paint_rect_.IsEmpty() || paint_reply_pending() || paint_pending)
initial.commit09911bf2008-07-26 23:55:29554 return;
555
556 // Perform painting asynchronously. This serves two purposes:
557 // 1) Ensures that we call WebView::Paint without a bunch of other junk
558 // on the call stack.
559 // 2) Allows us to collect more damage rects before painting to help coalesce
560 // the work that we will need to do.
561 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
[email protected]12fbad812009-09-01 18:21:24562 this, &RenderWidget::CallDoDeferredPaint));
initial.commit09911bf2008-07-26 23:55:29563}
564
[email protected]4873c7d2009-07-16 06:36:28565void RenderWidget::didScrollRect(int dx, int dy, const WebRect& clip_rect) {
[email protected]f911f742009-02-27 02:17:02566 if (dx != 0 && dy != 0) {
567 // We only support scrolling along one axis at a time.
[email protected]4873c7d2009-07-16 06:36:28568 didScrollRect(0, dy, clip_rect);
[email protected]f911f742009-02-27 02:17:02569 dy = 0;
570 }
initial.commit09911bf2008-07-26 23:55:29571
[email protected]2d5d09d52009-06-15 14:29:21572 bool intersects_with_painting = paint_rect_.Intersects(clip_rect);
initial.commit09911bf2008-07-26 23:55:29573
574 // If we already have a pending scroll operation or if this scroll operation
575 // intersects the existing paint region, then just failover to invalidating.
576 if (!scroll_rect_.IsEmpty() || intersects_with_painting) {
[email protected]b3f2b912009-04-09 16:18:52577 if (!intersects_with_painting && scroll_rect_ == gfx::Rect(clip_rect)) {
initial.commit09911bf2008-07-26 23:55:29578 // OK, we can just update the scroll delta (requires same scrolling axis)
579 if (!dx && !scroll_delta_.x()) {
580 scroll_delta_.set_y(scroll_delta_.y() + dy);
581 return;
582 }
583 if (!dy && !scroll_delta_.y()) {
584 scroll_delta_.set_x(scroll_delta_.x() + dx);
585 return;
586 }
587 }
[email protected]4873c7d2009-07-16 06:36:28588 didInvalidateRect(scroll_rect_);
initial.commit09911bf2008-07-26 23:55:29589 DCHECK(scroll_rect_.IsEmpty());
[email protected]4873c7d2009-07-16 06:36:28590 didInvalidateRect(clip_rect);
initial.commit09911bf2008-07-26 23:55:29591 return;
592 }
593
594 // We only want one pending DoDeferredScroll call at any time...
595 bool scroll_pending = !scroll_rect_.IsEmpty();
596
597 scroll_rect_ = clip_rect;
598 scroll_delta_.SetPoint(dx, dy);
599
600 if (scroll_pending)
601 return;
602
603 // Perform scrolling asynchronously since we need to call WebView::Paint
604 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
[email protected]12fbad812009-09-01 18:21:24605 this, &RenderWidget::CallDoDeferredScroll));
initial.commit09911bf2008-07-26 23:55:29606}
607
[email protected]4873c7d2009-07-16 06:36:28608void RenderWidget::didChangeCursor(const WebCursorInfo& cursor_info) {
[email protected]7c51b0ee2009-07-08 21:49:30609 // TODO(darin): Eliminate this temporary.
610 WebCursor cursor(cursor_info);
611
initial.commit09911bf2008-07-26 23:55:29612 // Only send a SetCursor message if we need to make a change.
613 if (!current_cursor_.IsEqual(cursor)) {
614 current_cursor_ = cursor;
615 Send(new ViewHostMsg_SetCursor(routing_id_, cursor));
616 }
617}
618
619// We are supposed to get a single call to Show for a newly created RenderWidget
620// that was created via RenderWidget::CreateWebView. So, we wait until this
621// point to dispatch the ShowWidget message.
622//
623// This method provides us with the information about how to display the newly
624// created RenderWidget (i.e., as a constrained popup or as a new tab).
625//
[email protected]4873c7d2009-07-16 06:36:28626void RenderWidget::show(WebNavigationPolicy) {
initial.commit09911bf2008-07-26 23:55:29627 DCHECK(!did_show_) << "received extraneous Show call";
628 DCHECK(routing_id_ != MSG_ROUTING_NONE);
629 DCHECK(opener_id_ != MSG_ROUTING_NONE);
630
631 if (!did_show_) {
632 did_show_ = true;
633 // NOTE: initial_pos_ may still have its default values at this point, but
634 // that's okay. It'll be ignored if as_popup is false, or the browser
635 // process will impose a default position otherwise.
[email protected]88efb7ec2009-07-14 16:32:59636 if (popup_params_.get()) {
637 popup_params_->bounds = initial_pos_;
638 Send(new ViewHostMsg_ShowPopup(routing_id_, *popup_params_));
639 popup_params_.reset();
640 } else {
641 Send(new ViewHostMsg_ShowWidget(opener_id_, routing_id_, initial_pos_));
642 }
[email protected]2533ce12009-05-09 00:02:24643 SetPendingWindowRect(initial_pos_);
initial.commit09911bf2008-07-26 23:55:29644 }
645}
646
[email protected]4873c7d2009-07-16 06:36:28647void RenderWidget::didFocus() {
initial.commit09911bf2008-07-26 23:55:29648 // Prevent the widget from stealing the focus if it does not have focus
649 // already. We do this by explicitely setting the focus to false again.
650 // We only let the browser focus the renderer.
651 if (!has_focus_ && webwidget_) {
652 MessageLoop::current()->PostTask(FROM_HERE,
653 NewRunnableMethod(this, &RenderWidget::ClearFocus));
654 }
655}
656
[email protected]4873c7d2009-07-16 06:36:28657void RenderWidget::didBlur() {
initial.commit09911bf2008-07-26 23:55:29658 Send(new ViewHostMsg_Blur(routing_id_));
659}
660
[email protected]2533ce12009-05-09 00:02:24661void RenderWidget::DoDeferredClose() {
662 Send(new ViewHostMsg_Close(routing_id_));
663}
664
[email protected]4873c7d2009-07-16 06:36:28665void RenderWidget::closeWidgetSoon() {
initial.commit09911bf2008-07-26 23:55:29666 // If a page calls window.close() twice, we'll end up here twice, but that's
667 // OK. It is safe to send multiple Close messages.
668
[email protected]2533ce12009-05-09 00:02:24669 // Ask the RenderWidgetHost to initiate close. We could be called from deep
670 // in Javascript. If we ask the RendwerWidgetHost to close now, the window
671 // could be closed before the JS finishes executing. So instead, post a
672 // message back to the message loop, which won't run until the JS is
673 // complete, and then the Close message can be sent.
[email protected]75ae4492009-07-10 00:05:15674 MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
[email protected]2533ce12009-05-09 00:02:24675 this, &RenderWidget::DoDeferredClose));
initial.commit09911bf2008-07-26 23:55:29676}
677
[email protected]b4b967e2009-04-22 11:33:05678void RenderWidget::GenerateFullRepaint() {
[email protected]4873c7d2009-07-16 06:36:28679 didInvalidateRect(gfx::Rect(size_.width(), size_.height()));
[email protected]b4b967e2009-04-22 11:33:05680}
681
initial.commit09911bf2008-07-26 23:55:29682void RenderWidget::Close() {
683 if (webwidget_) {
[email protected]4873c7d2009-07-16 06:36:28684 webwidget_->close();
initial.commit09911bf2008-07-26 23:55:29685 webwidget_ = NULL;
686 }
687}
688
[email protected]4873c7d2009-07-16 06:36:28689WebRect RenderWidget::windowRect() {
690 if (pending_window_rect_count_)
691 return pending_window_rect_;
[email protected]2533ce12009-05-09 00:02:24692
[email protected]b3f2b912009-04-09 16:18:52693 gfx::Rect rect;
694 Send(new ViewHostMsg_GetWindowRect(routing_id_, host_window_, &rect));
[email protected]4873c7d2009-07-16 06:36:28695 return rect;
initial.commit09911bf2008-07-26 23:55:29696}
697
[email protected]4873c7d2009-07-16 06:36:28698void RenderWidget::setWindowRect(const WebRect& pos) {
initial.commit09911bf2008-07-26 23:55:29699 if (did_show_) {
700 Send(new ViewHostMsg_RequestMove(routing_id_, pos));
[email protected]2533ce12009-05-09 00:02:24701 SetPendingWindowRect(pos);
initial.commit09911bf2008-07-26 23:55:29702 } else {
703 initial_pos_ = pos;
704 }
705}
706
[email protected]2533ce12009-05-09 00:02:24707void RenderWidget::SetPendingWindowRect(const WebRect& rect) {
708 pending_window_rect_ = rect;
709 pending_window_rect_count_++;
710}
711
[email protected]4873c7d2009-07-16 06:36:28712WebRect RenderWidget::rootWindowRect() {
[email protected]2533ce12009-05-09 00:02:24713 if (pending_window_rect_count_) {
714 // NOTE(mbelshe): If there is a pending_window_rect_, then getting
715 // the RootWindowRect is probably going to return wrong results since the
716 // browser may not have processed the Move yet. There isn't really anything
717 // good to do in this case, and it shouldn't happen - since this size is
718 // only really needed for windowToScreen, which is only used for Popups.
[email protected]4873c7d2009-07-16 06:36:28719 return pending_window_rect_;
[email protected]2533ce12009-05-09 00:02:24720 }
721
[email protected]b3f2b912009-04-09 16:18:52722 gfx::Rect rect;
723 Send(new ViewHostMsg_GetRootWindowRect(routing_id_, host_window_, &rect));
[email protected]4873c7d2009-07-16 06:36:28724 return rect;
[email protected]d4547452008-08-28 18:36:37725}
726
[email protected]4873c7d2009-07-16 06:36:28727WebRect RenderWidget::windowResizerRect() {
728 return resizer_rect_;
[email protected]c04b6362008-11-21 18:54:19729}
730
initial.commit09911bf2008-07-26 23:55:29731void RenderWidget::OnImeSetInputMode(bool is_active) {
[email protected]c4bb35a2008-10-31 17:54:03732 // To prevent this renderer process from sending unnecessary IPC messages to
733 // a browser process, we permit the renderer process to send IPC messages
734 // only during the IME attached to the browser process is active.
initial.commit09911bf2008-07-26 23:55:29735 ime_is_active_ = is_active;
initial.commit09911bf2008-07-26 23:55:29736}
737
[email protected]4873c7d2009-07-16 06:36:28738void RenderWidget::OnImeSetComposition(WebCompositionCommand command,
initial.commit09911bf2008-07-26 23:55:29739 int cursor_position,
740 int target_start, int target_end,
[email protected]4873c7d2009-07-16 06:36:28741 const string16& ime_string) {
742 if (!webwidget_)
743 return;
744 ime_control_busy_ = true;
745 webwidget_->handleCompositionEvent(command, cursor_position,
746 target_start, target_end,
747 ime_string);
748 ime_control_busy_ = false;
initial.commit09911bf2008-07-26 23:55:29749}
750
[email protected]ec7dc112008-08-06 05:30:12751void RenderWidget::OnMsgRepaint(const gfx::Size& size_to_paint) {
752 // During shutdown we can just ignore this message.
753 if (!webwidget_)
754 return;
755
756 set_next_paint_is_repaint_ack();
757 gfx::Rect repaint_rect(size_to_paint.width(), size_to_paint.height());
[email protected]4873c7d2009-07-16 06:36:28758 didInvalidateRect(repaint_rect);
[email protected]ec7dc112008-08-06 05:30:12759}
760
[email protected]4873c7d2009-07-16 06:36:28761void RenderWidget::OnSetTextDirection(WebTextDirection direction) {
[email protected]07f953332009-03-25 04:31:11762 if (!webwidget_)
763 return;
[email protected]4873c7d2009-07-16 06:36:28764 webwidget_->setTextDirection(direction);
[email protected]07f953332009-03-25 04:31:11765}
766
[email protected]bee16aab2009-08-26 15:55:03767void RenderWidget::SetHidden(bool hidden) {
768 if (is_hidden_ == hidden)
769 return;
770
771 // The status has changed. Tell the RenderThread about it.
772 is_hidden_ = hidden;
773 if (is_hidden_)
774 render_thread_->WidgetHidden();
775 else
776 render_thread_->WidgetRestored();
777}
778
[email protected]699ab0d2009-04-23 23:19:14779void RenderWidget::SetBackground(const SkBitmap& background) {
780 background_ = background;
781 // Generate a full repaint.
[email protected]4873c7d2009-07-16 06:36:28782 didInvalidateRect(gfx::Rect(size_.width(), size_.height()));
[email protected]699ab0d2009-04-23 23:19:14783}
784
[email protected]674741932009-02-04 23:44:46785bool RenderWidget::next_paint_is_resize_ack() const {
786 return ViewHostMsg_PaintRect_Flags::is_resize_ack(next_paint_flags_);
787}
788
789bool RenderWidget::next_paint_is_restore_ack() const {
790 return ViewHostMsg_PaintRect_Flags::is_restore_ack(next_paint_flags_);
791}
792
793void RenderWidget::set_next_paint_is_resize_ack() {
794 next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_RESIZE_ACK;
795}
796
797void RenderWidget::set_next_paint_is_restore_ack() {
798 next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_RESTORE_ACK;
799}
800
801void RenderWidget::set_next_paint_is_repaint_ack() {
802 next_paint_flags_ |= ViewHostMsg_PaintRect_Flags::IS_REPAINT_ACK;
803}
804
initial.commit09911bf2008-07-26 23:55:29805void RenderWidget::UpdateIME() {
806 // If a browser process does not have IMEs, its IMEs are not active, or there
807 // are not any attached widgets.
808 // a renderer process does not have to retrieve information of the focused
809 // control or send notification messages to a browser process.
810 if (!ime_is_active_) {
811 return;
812 }
[email protected]34f6bc12008-11-06 07:40:53813 // Retrieve the caret position from the focused widget and verify we should
814 // enabled IMEs attached to the browser process.
815 bool enable_ime = false;
[email protected]b3f2b912009-04-09 16:18:52816 WebRect caret_rect;
[email protected]34f6bc12008-11-06 07:40:53817 if (!webwidget_ ||
[email protected]4873c7d2009-07-16 06:36:28818 !webwidget_->queryCompositionStatus(&enable_ime, &caret_rect)) {
initial.commit09911bf2008-07-26 23:55:29819 // There are not any editable widgets attached to this process.
820 // We should disable the IME to prevent it from sending CJK strings to
821 // non-editable widgets.
822 ime_control_updated_ = true;
823 ime_control_new_state_ = false;
824 }
[email protected]9f23f592008-11-17 08:36:34825 if (ime_control_new_state_ != enable_ime) {
826 ime_control_updated_ = true;
827 ime_control_new_state_ = enable_ime;
828 }
initial.commit09911bf2008-07-26 23:55:29829 if (ime_control_updated_) {
830 // The input focus has been changed.
831 // Compare the current state with the updated state and choose actions.
832 if (ime_control_enable_ime_) {
833 if (ime_control_new_state_) {
834 // Case 1: a text input -> another text input
835 // Complete the current composition and notify the caret position.
[email protected]34f6bc12008-11-06 07:40:53836 Send(new ViewHostMsg_ImeUpdateStatus(routing_id(),
837 IME_COMPLETE_COMPOSITION,
838 caret_rect));
initial.commit09911bf2008-07-26 23:55:29839 } else {
840 // Case 2: a text input -> a password input (or a static control)
841 // Complete the current composition and disable the IME.
[email protected]34f6bc12008-11-06 07:40:53842 Send(new ViewHostMsg_ImeUpdateStatus(routing_id(), IME_DISABLE,
843 caret_rect));
initial.commit09911bf2008-07-26 23:55:29844 }
845 } else {
846 if (ime_control_new_state_) {
847 // Case 3: a password input (or a static control) -> a text input
848 // Enable the IME and notify the caret position.
[email protected]34f6bc12008-11-06 07:40:53849 Send(new ViewHostMsg_ImeUpdateStatus(routing_id(),
850 IME_COMPLETE_COMPOSITION,
851 caret_rect));
initial.commit09911bf2008-07-26 23:55:29852 } else {
853 // Case 4: a password input (or a static contol) -> another password
854 // input (or another static control).
855 // The IME has been already disabled and we don't have to do anything.
856 }
857 }
858 } else {
859 // The input focus is not changed.
860 // Notify the caret position to a browser process only if it is changed.
861 if (ime_control_enable_ime_) {
[email protected]b3f2b912009-04-09 16:18:52862 if (caret_rect.x != ime_control_x_ ||
863 caret_rect.y != ime_control_y_) {
[email protected]34f6bc12008-11-06 07:40:53864 Send(new ViewHostMsg_ImeUpdateStatus(routing_id(), IME_MOVE_WINDOWS,
865 caret_rect));
initial.commit09911bf2008-07-26 23:55:29866 }
867 }
868 }
869 // Save the updated IME status to prevent from sending the same IPC messages.
870 ime_control_updated_ = false;
871 ime_control_enable_ime_ = ime_control_new_state_;
[email protected]b3f2b912009-04-09 16:18:52872 ime_control_x_ = caret_rect.x;
873 ime_control_y_ = caret_rect.y;
initial.commit09911bf2008-07-26 23:55:29874}
875
[email protected]4873c7d2009-07-16 06:36:28876WebScreenInfo RenderWidget::screenInfo() {
877 WebScreenInfo results;
878 Send(new ViewHostMsg_GetScreenInfo(routing_id_, host_window_, &results));
879 return results;
880}
881
882void RenderWidget::SchedulePluginMove(const WebPluginGeometry& move) {
initial.commit09911bf2008-07-26 23:55:29883 size_t i = 0;
884 for (; i < plugin_window_moves_.size(); ++i) {
885 if (plugin_window_moves_[i].window == move.window) {
[email protected]16f89d02009-08-26 17:17:58886 if (move.rects_valid) {
887 plugin_window_moves_[i] = move;
888 } else {
889 plugin_window_moves_[i].visible = move.visible;
890 }
initial.commit09911bf2008-07-26 23:55:29891 break;
892 }
893 }
894
895 if (i == plugin_window_moves_.size())
896 plugin_window_moves_.push_back(move);
897}
[email protected]268654772009-08-06 23:02:04898
899void RenderWidget::CleanupWindowInPluginMoves(gfx::PluginWindowHandle window) {
900 for (WebPluginGeometryVector::iterator i = plugin_window_moves_.begin();
901 i != plugin_window_moves_.end(); ++i) {
902 if (i->window == window) {
903 plugin_window_moves_.erase(i);
904 break;
905 }
906 }
907}