| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef CHROME_RENDERER_RENDER_WIDGET_H_ | |
| 6 #define CHROME_RENDERER_RENDER_WIDGET_H_ | |
| 7 #pragma once | |
| 8 | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "app/surface/transport_dib.h" | |
| 12 #include "base/basictypes.h" | |
| 13 #include "base/ref_counted.h" | |
| 14 #include "chrome/renderer/render_process.h" | |
| 15 #include "content/renderer/paint_aggregator.h" | |
| 16 #include "ipc/ipc_channel.h" | |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCompositionUnderli
ne.h" | |
| 18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupType.h" | |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" | |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextDirection.h" | |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextInputType.h" | |
| 22 #include "third_party/WebKit/Source/WebKit/chromium/public/WebWidgetClient.h" | |
| 23 #include "third_party/skia/include/core/SkBitmap.h" | |
| 24 #include "ui/gfx/native_widget_types.h" | |
| 25 #include "ui/gfx/rect.h" | |
| 26 #include "ui/gfx/size.h" | |
| 27 #include "webkit/glue/webcursor.h" | |
| 28 | |
| 29 class RenderThreadBase; | |
| 30 | |
| 31 namespace gfx { | |
| 32 class Point; | |
| 33 } | |
| 34 | |
| 35 namespace IPC { | |
| 36 class SyncMessage; | |
| 37 } | |
| 38 | |
| 39 namespace skia { | |
| 40 class PlatformCanvas; | |
| 41 } | |
| 42 | |
| 43 namespace WebKit { | |
| 44 class WebMouseEvent; | |
| 45 class WebWidget; | |
| 46 struct WebPopupMenuInfo; | |
| 47 } | |
| 48 | |
| 49 namespace webkit { | |
| 50 namespace npapi { | |
| 51 struct WebPluginGeometry; | |
| 52 } // namespace npapi | |
| 53 | |
| 54 namespace ppapi { | |
| 55 class PluginInstance; | |
| 56 } // namespace ppapi | |
| 57 } // namespace webkit | |
| 58 | |
| 59 // RenderWidget provides a communication bridge between a WebWidget and | |
| 60 // a RenderWidgetHost, the latter of which lives in a different process. | |
| 61 class RenderWidget : public IPC::Channel::Listener, | |
| 62 public IPC::Message::Sender, | |
| 63 virtual public WebKit::WebWidgetClient, | |
| 64 public base::RefCounted<RenderWidget> { | |
| 65 public: | |
| 66 // Creates a new RenderWidget. The opener_id is the routing ID of the | |
| 67 // RenderView that this widget lives inside. The render_thread is any | |
| 68 // RenderThreadBase implementation, mostly commonly RenderThread::current(). | |
| 69 static RenderWidget* Create(int32 opener_id, | |
| 70 RenderThreadBase* render_thread, | |
| 71 WebKit::WebPopupType popup_type); | |
| 72 | |
| 73 // Creates a WebWidget based on the popup type. | |
| 74 static WebKit::WebWidget* CreateWebWidget(RenderWidget* render_widget); | |
| 75 | |
| 76 // The routing ID assigned by the RenderProcess. Will be MSG_ROUTING_NONE if | |
| 77 // not yet assigned a view ID, in which case, the process MUST NOT send | |
| 78 // messages with this ID to the parent. | |
| 79 int32 routing_id() const { | |
| 80 return routing_id_; | |
| 81 } | |
| 82 | |
| 83 // May return NULL when the window is closing. | |
| 84 WebKit::WebWidget* webwidget() const { | |
| 85 return webwidget_; | |
| 86 } | |
| 87 | |
| 88 gfx::NativeViewId host_window() const { | |
| 89 return host_window_; | |
| 90 } | |
| 91 | |
| 92 bool has_focus() const { return has_focus_; } | |
| 93 | |
| 94 // IPC::Channel::Listener | |
| 95 virtual bool OnMessageReceived(const IPC::Message& msg); | |
| 96 | |
| 97 // IPC::Message::Sender | |
| 98 virtual bool Send(IPC::Message* msg); | |
| 99 | |
| 100 // WebKit::WebWidgetClient | |
| 101 virtual void didInvalidateRect(const WebKit::WebRect&); | |
| 102 virtual void didScrollRect(int dx, int dy, const WebKit::WebRect& clipRect); | |
| 103 virtual void didActivateAcceleratedCompositing(bool active); | |
| 104 virtual void scheduleComposite(); | |
| 105 virtual void scheduleAnimation(); | |
| 106 virtual void didFocus(); | |
| 107 virtual void didBlur(); | |
| 108 virtual void didChangeCursor(const WebKit::WebCursorInfo&); | |
| 109 virtual void closeWidgetSoon(); | |
| 110 virtual void show(WebKit::WebNavigationPolicy); | |
| 111 virtual void runModal() {} | |
| 112 virtual WebKit::WebRect windowRect(); | |
| 113 virtual void setWindowRect(const WebKit::WebRect&); | |
| 114 virtual WebKit::WebRect windowResizerRect(); | |
| 115 virtual WebKit::WebRect rootWindowRect(); | |
| 116 virtual WebKit::WebScreenInfo screenInfo(); | |
| 117 virtual void resetInputMethod(); | |
| 118 | |
| 119 // Called when a plugin is moved. These events are queued up and sent with | |
| 120 // the next paint or scroll message to the host. | |
| 121 void SchedulePluginMove(const webkit::npapi::WebPluginGeometry& move); | |
| 122 | |
| 123 // Called when a plugin window has been destroyed, to make sure the currently | |
| 124 // pending moves don't try to reference it. | |
| 125 void CleanupWindowInPluginMoves(gfx::PluginWindowHandle window); | |
| 126 | |
| 127 // Close the underlying WebWidget. | |
| 128 virtual void Close(); | |
| 129 | |
| 130 protected: | |
| 131 // Friend RefCounted so that the dtor can be non-public. Using this class | |
| 132 // without ref-counting is an error. | |
| 133 friend class base::RefCounted<RenderWidget>; | |
| 134 // For unit tests. | |
| 135 friend class RenderWidgetTest; | |
| 136 | |
| 137 RenderWidget(RenderThreadBase* render_thread, | |
| 138 WebKit::WebPopupType popup_type); | |
| 139 virtual ~RenderWidget(); | |
| 140 | |
| 141 // Initializes this view with the given opener. CompleteInit must be called | |
| 142 // later. | |
| 143 void Init(int32 opener_id); | |
| 144 | |
| 145 // Called by Init and subclasses to perform initialization. | |
| 146 void DoInit(int32 opener_id, | |
| 147 WebKit::WebWidget* web_widget, | |
| 148 IPC::SyncMessage* create_widget_message); | |
| 149 | |
| 150 // Finishes creation of a pending view started with Init. | |
| 151 void CompleteInit(gfx::NativeViewId parent); | |
| 152 | |
| 153 // Paints the given rectangular region of the WebWidget into canvas (a | |
| 154 // shared memory segment returned by AllocPaintBuf on Windows). The caller | |
| 155 // must ensure that the given rect fits within the bounds of the WebWidget. | |
| 156 void PaintRect(const gfx::Rect& rect, const gfx::Point& canvas_origin, | |
| 157 skia::PlatformCanvas* canvas); | |
| 158 | |
| 159 // Paints a border at the given rect for debugging purposes. | |
| 160 void PaintDebugBorder(const gfx::Rect& rect, skia::PlatformCanvas* canvas); | |
| 161 | |
| 162 void AnimationCallback(); | |
| 163 void AnimateIfNeeded(); | |
| 164 void CallDoDeferredUpdate(); | |
| 165 void DoDeferredUpdate(); | |
| 166 void DoDeferredClose(); | |
| 167 void DoDeferredSetWindowRect(const WebKit::WebRect& pos); | |
| 168 | |
| 169 // Set the background of the render widget to a bitmap. The bitmap will be | |
| 170 // tiled in both directions if it isn't big enough to fill the area. This is | |
| 171 // mainly intended to be used in conjuction with WebView::SetIsTransparent(). | |
| 172 virtual void SetBackground(const SkBitmap& bitmap); | |
| 173 | |
| 174 // RenderWidget IPC message handlers | |
| 175 void OnClose(); | |
| 176 void OnCreatingNewAck(gfx::NativeViewId parent); | |
| 177 virtual void OnResize(const gfx::Size& new_size, | |
| 178 const gfx::Rect& resizer_rect); | |
| 179 virtual void OnWasHidden(); | |
| 180 virtual void OnWasRestored(bool needs_repainting); | |
| 181 void OnUpdateRectAck(); | |
| 182 void OnCreateVideoAck(int32 video_id); | |
| 183 void OnUpdateVideoAck(int32 video_id); | |
| 184 void OnRequestMoveAck(); | |
| 185 void OnHandleInputEvent(const IPC::Message& message); | |
| 186 void OnMouseCaptureLost(); | |
| 187 virtual void OnSetFocus(bool enable); | |
| 188 void OnSetInputMethodActive(bool is_active); | |
| 189 void OnImeSetComposition( | |
| 190 const string16& text, | |
| 191 const std::vector<WebKit::WebCompositionUnderline>& underlines, | |
| 192 int selection_start, | |
| 193 int selection_end); | |
| 194 void OnImeConfirmComposition(const string16& text); | |
| 195 void OnMsgPaintAtSize(const TransportDIB::Handle& dib_id, | |
| 196 int tag, | |
| 197 const gfx::Size& page_size, | |
| 198 const gfx::Size& desired_size); | |
| 199 void OnMsgRepaint(const gfx::Size& size_to_paint); | |
| 200 void OnSetTextDirection(WebKit::WebTextDirection direction); | |
| 201 | |
| 202 // Override point to notify derived classes that a paint has happened. | |
| 203 // DidInitiatePaint happens when we've generated a new bitmap and sent it to | |
| 204 // the browser. DidFlushPaint happens once we've received the ACK that the | |
| 205 // screen has actually been updated. | |
| 206 virtual void DidInitiatePaint() {} | |
| 207 virtual void DidFlushPaint() {} | |
| 208 | |
| 209 // Detects if a suitable opaque plugin covers the given paint bounds with no | |
| 210 // compositing necessary. | |
| 211 // | |
| 212 // Returns the plugin instance that's the source of the paint if the paint | |
| 213 // can be handled by just blitting the plugin bitmap. In this case, the | |
| 214 // location, clipping, and ID of the backing store will be filled into the | |
| 215 // given output parameters. | |
| 216 // | |
| 217 // A return value of null means optimized painting can not be used and we | |
| 218 // should continue with the normal painting code path. | |
| 219 virtual webkit::ppapi::PluginInstance* GetBitmapForOptimizedPluginPaint( | |
| 220 const gfx::Rect& paint_bounds, | |
| 221 TransportDIB** dib, | |
| 222 gfx::Rect* location, | |
| 223 gfx::Rect* clip); | |
| 224 | |
| 225 // Gets the scroll offset of this widget, if this widget has a notion of | |
| 226 // scroll offset. | |
| 227 virtual gfx::Point GetScrollOffset(); | |
| 228 | |
| 229 // Sets the "hidden" state of this widget. All accesses to is_hidden_ should | |
| 230 // use this method so that we can properly inform the RenderThread of our | |
| 231 // state. | |
| 232 void SetHidden(bool hidden); | |
| 233 | |
| 234 bool is_hidden() const { return is_hidden_; } | |
| 235 | |
| 236 // True if an UpdateRect_ACK message is pending. | |
| 237 bool update_reply_pending() const { | |
| 238 return update_reply_pending_; | |
| 239 } | |
| 240 | |
| 241 bool next_paint_is_resize_ack() const; | |
| 242 bool next_paint_is_restore_ack() const; | |
| 243 void set_next_paint_is_resize_ack(); | |
| 244 void set_next_paint_is_restore_ack(); | |
| 245 void set_next_paint_is_repaint_ack(); | |
| 246 | |
| 247 // Checks if the input method state and caret position have been changed. | |
| 248 // If they are changed, the new value will be sent to the browser process. | |
| 249 void UpdateInputMethod(); | |
| 250 | |
| 251 // Tells the renderer it does not have focus. Used to prevent us from getting | |
| 252 // the focus on our own when the browser did not focus us. | |
| 253 void ClearFocus(); | |
| 254 | |
| 255 // Set the pending window rect. | |
| 256 // Because the real render_widget is hosted in another process, there is | |
| 257 // a time period where we may have set a new window rect which has not yet | |
| 258 // been processed by the browser. So we maintain a pending window rect | |
| 259 // size. If JS code sets the WindowRect, and then immediately calls | |
| 260 // GetWindowRect() we'll use this pending window rect as the size. | |
| 261 void SetPendingWindowRect(const WebKit::WebRect& r); | |
| 262 | |
| 263 // Called by OnHandleInputEvent() to notify subclasses that a key event was | |
| 264 // just handled. | |
| 265 virtual void DidHandleKeyEvent() {} | |
| 266 | |
| 267 // Called by OnHandleInputEvent() to notify subclasses that a mouse event was | |
| 268 // just handled. | |
| 269 virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {} | |
| 270 | |
| 271 // Routing ID that allows us to communicate to the parent browser process | |
| 272 // RenderWidgetHost. When MSG_ROUTING_NONE, no messages may be sent. | |
| 273 int32 routing_id_; | |
| 274 | |
| 275 // We are responsible for destroying this object via its Close method. | |
| 276 WebKit::WebWidget* webwidget_; | |
| 277 | |
| 278 // Set to the ID of the view that initiated creating this view, if any. When | |
| 279 // the view was initiated by the browser (the common case), this will be | |
| 280 // MSG_ROUTING_NONE. This is used in determining ownership when opening | |
| 281 // child tabs. See RenderWidget::createWebViewWithRequest. | |
| 282 // | |
| 283 // This ID may refer to an invalid view if that view is closed before this | |
| 284 // view is. | |
| 285 int32 opener_id_; | |
| 286 | |
| 287 // The thread that does our IPC. | |
| 288 RenderThreadBase* render_thread_; | |
| 289 | |
| 290 // The position where this view should be initially shown. | |
| 291 gfx::Rect initial_pos_; | |
| 292 | |
| 293 // The window we are embedded within. TODO(darin): kill this. | |
| 294 gfx::NativeViewId host_window_; | |
| 295 | |
| 296 // We store the current cursor object so we can avoid spamming SetCursor | |
| 297 // messages. | |
| 298 WebCursor current_cursor_; | |
| 299 | |
| 300 // The size of the RenderWidget. | |
| 301 gfx::Size size_; | |
| 302 | |
| 303 // The TransportDIB that is being used to transfer an image to the browser. | |
| 304 TransportDIB* current_paint_buf_; | |
| 305 | |
| 306 PaintAggregator paint_aggregator_; | |
| 307 | |
| 308 // The area that must be reserved for drawing the resize corner. | |
| 309 gfx::Rect resizer_rect_; | |
| 310 | |
| 311 // Flags for the next ViewHostMsg_UpdateRect message. | |
| 312 int next_paint_flags_; | |
| 313 | |
| 314 // True if we are expecting an UpdateRect_ACK message (i.e., that a | |
| 315 // UpdateRect message has been sent). | |
| 316 bool update_reply_pending_; | |
| 317 | |
| 318 // Set to true if we should ignore RenderWidget::Show calls. | |
| 319 bool did_show_; | |
| 320 | |
| 321 // Indicates that we shouldn't bother generated paint events. | |
| 322 bool is_hidden_; | |
| 323 | |
| 324 // Indicates that we should be repainted when restored. This flag is set to | |
| 325 // true if we receive an invalidation / scroll event from webkit while our | |
| 326 // is_hidden_ flag is set to true. This is used to force a repaint once we | |
| 327 // restore to account for the fact that our host would not know about the | |
| 328 // invalidation / scroll event(s) from webkit while we are hidden. | |
| 329 bool needs_repainting_on_restore_; | |
| 330 | |
| 331 // Indicates whether we have been focused/unfocused by the browser. | |
| 332 bool has_focus_; | |
| 333 | |
| 334 // Are we currently handling an input event? | |
| 335 bool handling_input_event_; | |
| 336 | |
| 337 // True if we have requested this widget be closed. No more messages will | |
| 338 // be sent, except for a Close. | |
| 339 bool closing_; | |
| 340 | |
| 341 // Indicates if an input method is active in the browser process. | |
| 342 bool input_method_is_active_; | |
| 343 | |
| 344 // Stores the current text input type of |webwidget_|. | |
| 345 WebKit::WebTextInputType text_input_type_; | |
| 346 | |
| 347 // Stores the current caret bounds of input focus. | |
| 348 WebKit::WebRect caret_bounds_; | |
| 349 | |
| 350 // The kind of popup this widget represents, NONE if not a popup. | |
| 351 WebKit::WebPopupType popup_type_; | |
| 352 | |
| 353 // Holds all the needed plugin window moves for a scroll. | |
| 354 typedef std::vector<webkit::npapi::WebPluginGeometry> WebPluginGeometryVector; | |
| 355 WebPluginGeometryVector plugin_window_moves_; | |
| 356 | |
| 357 // A custom background for the widget. | |
| 358 SkBitmap background_; | |
| 359 | |
| 360 // While we are waiting for the browser to update window sizes, | |
| 361 // we track the pending size temporarily. | |
| 362 int pending_window_rect_count_; | |
| 363 WebKit::WebRect pending_window_rect_; | |
| 364 | |
| 365 scoped_ptr<IPC::Message> pending_input_event_ack_; | |
| 366 | |
| 367 // Indicates if the next sequence of Char events should be suppressed or not. | |
| 368 bool suppress_next_char_events_; | |
| 369 | |
| 370 // Set to true if painting to the window is handled by the accelerated | |
| 371 // compositor. | |
| 372 bool is_accelerated_compositing_active_; | |
| 373 | |
| 374 base::Time animation_floor_time_; | |
| 375 bool animation_update_pending_; | |
| 376 bool animation_task_posted_; | |
| 377 | |
| 378 DISALLOW_COPY_AND_ASSIGN(RenderWidget); | |
| 379 }; | |
| 380 | |
| 381 #endif // CHROME_RENDERER_RENDER_WIDGET_H_ | |
| OLD | NEW |