1 // Copyright (c) 2012 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.
5 #ifndef CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_
6 #define CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_
8 #include "base/callback.h"
9 #include "content/common/content_export.h"
10 #include "content/public/browser/keyboard_listener.h"
11 #include "content/public/browser/native_web_keyboard_event.h"
12 #include "ipc/ipc_channel.h"
13 #include "ipc/ipc_sender.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextDirection.h"
16 #include "ui/gfx/size.h"
17 #include "ui/surface/transport_dib.h"
19 #if defined(TOOLKIT_GTK)
20 #include "ui/base/x/x11_util.h"
21 #elif defined(OS_MACOSX)
22 #include "skia/ext/platform_device.h"
37 class RenderProcessHost
;
38 class RenderWidgetHostImpl
;
39 class RenderWidgetHostView
;
41 // A RenderWidgetHost manages the browser side of a browser<->renderer
42 // HWND connection. The HWND lives in the browser process, and
43 // windows events are sent over IPC to the corresponding object in the
44 // renderer. The renderer paints into shared memory, which we
45 // transfer to a backing store and blit to the screen when Windows
46 // sends us a WM_PAINT message.
50 // There are two situations in which this object, a RenderWidgetHost, can be
53 // 1. By a WebContents as the communication conduit for a rendered web page.
54 // The WebContents instantiates a derived class: RenderViewHost.
55 // 2. By a WebContents as the communication conduit for a select widget. The
56 // WebContents instantiates the RenderWidgetHost directly.
58 // For every WebContents there are several objects in play that need to be
59 // properly destroyed or cleaned up when certain events occur.
61 // - WebContents - the WebContents itself, and its associated HWND.
62 // - RenderViewHost - representing the communication conduit with the child
64 // - RenderWidgetHostView - the view of the web page content, message handler,
67 // Normally, the WebContents contains a child RenderWidgetHostView that renders
68 // the contents of the loaded page. It has a WS_CLIPCHILDREN style so that it
69 // does no painting of its own.
71 // The lifetime of the RenderWidgetHostView is tied to the render process. If
72 // the render process dies, the RenderWidgetHostView goes away and all
73 // references to it must become NULL.
75 // RenderViewHost (a RenderWidgetHost subclass) is the conduit used to
76 // communicate with the RenderView and is owned by the WebContents. If the
77 // render process crashes, the RenderViewHost remains and restarts the render
78 // process if needed to continue navigation.
80 // Some examples of how shutdown works:
82 // For a WebContents, its Destroy method tells the RenderViewHost to
83 // shut down the render process and die.
85 // When the render process is destroyed it destroys the View: the
86 // RenderWidgetHostView, which destroys its HWND and deletes that object.
88 // For select popups, the situation is a little different. The RenderWidgetHost
89 // associated with the select popup owns the view and itself (is responsible
90 // for destroying itself when the view is closed). The WebContents's only
91 // responsibility is to select popups is to create them when it is told to. When
92 // the View is destroyed via an IPC message (for when WebCore destroys the
93 // popup, e.g. if the user selects one of the options), or because
94 // WM_CANCELMODE is received by the view, the View schedules the destruction of
95 // the render process. However in this case since there's no WebContents
96 // container, when the render process is destroyed, the RenderWidgetHost just
97 // deletes itself, which is safe because no one else should have any references
98 // to it (the WebContents does not).
100 // It should be noted that the RenderViewHost, not the RenderWidgetHost,
101 // handles IPC messages relating to the render process going away, since the
102 // way a RenderViewHost (WebContents) handles the process dying is different to
103 // the way a select popup does. As such the RenderWidgetHostView handles these
104 // messages for select popups. This placement is more out of convenience than
105 // anything else. When the view is live, these messages are forwarded to it by
106 // the RenderWidgetHost's IPC message map.
107 class CONTENT_EXPORT RenderWidgetHost
: public IPC::Sender
{
109 // Free all backing stores used for rendering to drop memory usage.
110 static void RemoveAllBackingStores();
112 // Returns the size of all the backing stores used for rendering
113 static size_t BackingStoreMemorySize();
115 // Adds/removes a callback called on creation of each new RenderWidgetHost.
116 typedef base::Callback
<void(RenderWidgetHost
*)> CreatedCallback
;
117 static void AddCreatedCallback(const CreatedCallback
& callback
);
118 static void RemoveCreatedCallback(const CreatedCallback
& callback
);
120 virtual ~RenderWidgetHost() {}
123 virtual void Undo() = 0;
124 virtual void Redo() = 0;
125 virtual void Cut() = 0;
126 virtual void Copy() = 0;
127 virtual void CopyToFindPboard() = 0;
128 virtual void Paste() = 0;
129 virtual void PasteAndMatchStyle() = 0;
130 virtual void Delete() = 0;
131 virtual void SelectAll() = 0;
133 // Update the text direction of the focused input element and notify it to a
135 // These functions have two usage scenarios: changing the text direction
136 // from a menu (as Safari does), and; changing the text direction when a user
137 // presses a set of keys (as IE and Firefox do).
138 // 1. Change the text direction from a menu.
139 // In this scenario, we receive a menu event only once and we should update
140 // the text direction immediately when a user chooses a menu item. So, we
141 // should call both functions at once as listed in the following snippet.
142 // void RenderViewHost::SetTextDirection(WebTextDirection direction) {
143 // UpdateTextDirection(direction);
144 // NotifyTextDirection();
146 // 2. Change the text direction when pressing a set of keys.
147 // Because of auto-repeat, we may receive the same key-press event many
148 // times while we presses the keys and it is nonsense to send the same IPC
149 // message every time when we receive a key-press event.
150 // To suppress the number of IPC messages, we just update the text direction
151 // when receiving a key-press event and send an IPC message when we release
152 // the keys as listed in the following snippet.
153 // if (key_event.type == WebKeyboardEvent::KEY_DOWN) {
154 // if (key_event.windows_key_code == 'A' &&
155 // key_event.modifiers == WebKeyboardEvent::CTRL_KEY) {
156 // UpdateTextDirection(dir);
158 // CancelUpdateTextDirection();
160 // } else if (key_event.type == WebKeyboardEvent::KEY_UP) {
161 // NotifyTextDirection();
163 // Once we cancel updating the text direction, we have to ignore all
164 // succeeding UpdateTextDirection() requests until calling
165 // NotifyTextDirection(). (We may receive keydown events even after we
166 // canceled updating the text direction because of auto-repeat.)
167 // Note: we cannot undo this change for compatibility with Firefox and IE.
168 virtual void UpdateTextDirection(WebKit::WebTextDirection direction
) = 0;
169 virtual void NotifyTextDirection() = 0;
171 virtual void Focus() = 0;
172 virtual void Blur() = 0;
174 // Sets whether the renderer should show controls in an active state. On all
175 // platforms except mac, that's the same as focused. On mac, the frontmost
176 // window will show active controls even if the focus is not in the web
177 // contents, but e.g. in the omnibox.
178 virtual void SetActive(bool active
) = 0;
180 // Copies the given subset of the backing store, and passes the result as a
181 // bitmap to a callback.
183 // If |src_rect| is empty, the whole contents is copied. If non empty
184 // |accelerated_dst_size| is given and accelerated compositing is active, the
185 // content is shrunk so that it fits in |accelerated_dst_size|. If
186 // |accelerated_dst_size| is larger than the content size, the content is not
187 // resized. If |accelerated_dst_size| is empty, the size copied from the
188 // source contents is used. |callback| is invoked with true on success, false
189 // otherwise, along with a SkBitmap containing the copied pixel data.
191 // NOTE: |callback| is called synchronously if the backing store is available.
192 // When accelerated compositing is active, |callback| may be called
194 virtual void CopyFromBackingStore(
195 const gfx::Rect
& src_rect
,
196 const gfx::Size
& accelerated_dst_size
,
197 const base::Callback
<void(bool, const SkBitmap
&)>& callback
) = 0;
198 #if defined(TOOLKIT_GTK)
199 // Paint the backing store into the target's |dest_rect|.
200 virtual bool CopyFromBackingStoreToGtkWindow(const gfx::Rect
& dest_rect
,
201 GdkWindow
* target
) = 0;
202 #elif defined(OS_MACOSX)
203 virtual gfx::Size
GetBackingStoreSize() = 0;
204 virtual bool CopyFromBackingStoreToCGContext(const CGRect
& dest_rect
,
205 CGContextRef target
) = 0;
208 // Send a command to the renderer to turn on full accessibility.
209 virtual void EnableFullAccessibilityMode() = 0;
211 // Forwards the given message to the renderer. These are called by
212 // the view when it has received a message.
213 virtual void ForwardMouseEvent(
214 const WebKit::WebMouseEvent
& mouse_event
) = 0;
215 virtual void ForwardWheelEvent(
216 const WebKit::WebMouseWheelEvent
& wheel_event
) = 0;
217 virtual void ForwardKeyboardEvent(
218 const NativeWebKeyboardEvent
& key_event
) = 0;
220 virtual const gfx::Vector2d
& GetLastScrollOffset() const = 0;
222 virtual RenderProcessHost
* GetProcess() const = 0;
224 virtual int GetRoutingID() const = 0;
226 // Gets the View of this RenderWidgetHost. Can be NULL, e.g. if the
227 // RenderWidget is being destroyed or the render process crashed. You should
228 // never cache this pointer since it can become NULL if the renderer crashes,
229 // instead you should always ask for it using the accessor.
230 virtual RenderWidgetHostView
* GetView() const = 0;
232 // Returns true if the renderer is loading, false if not.
233 virtual bool IsLoading() const = 0;
235 // Returns true if this is a RenderViewHost, false if not.
236 virtual bool IsRenderView() const = 0;
238 // This tells the renderer to paint into a bitmap and return it,
239 // regardless of whether the tab is hidden or not. It resizes the
240 // web widget to match the |page_size| and then returns the bitmap
241 // scaled so it matches the |desired_size|, so that the scaling
242 // happens on the rendering thread. When the bitmap is ready, the
243 // renderer sends a PaintAtSizeACK to this host, and a
244 // RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK notification is issued.
245 // Note that this bypasses most of the update logic that is normally invoked,
246 // and doesn't put the results into the backing store.
247 virtual void PaintAtSize(TransportDIB::Handle dib_handle
,
249 const gfx::Size
& page_size
,
250 const gfx::Size
& desired_size
) = 0;
252 // Makes an IPC call to tell webkit to replace the currently selected word
253 // or a word around the cursor.
254 virtual void Replace(const string16
& word
) = 0;
256 // Makes an IPC call to tell webkit to replace the misspelling in the current
258 virtual void ReplaceMisspelling(const string16
& word
) = 0;
260 // Called to notify the RenderWidget that the resize rect has changed without
261 // the size of the RenderWidget itself changing.
262 virtual void ResizeRectChanged(const gfx::Rect
& new_rect
) = 0;
264 // Restart the active hang monitor timeout. Clears all existing timeouts and
265 // starts with a new one. This can be because the renderer has become
266 // active, the tab is being hidden, or the user has chosen to wait some more
267 // to give the tab a chance to become active and we don't want to display a
269 virtual void RestartHangMonitorTimeout() = 0;
271 virtual void SetIgnoreInputEvents(bool ignore_input_events
) = 0;
273 // Stops loading the page.
274 virtual void Stop() = 0;
276 // Called to notify the RenderWidget that it has been resized.
277 virtual void WasResized() = 0;
279 // Access to the implementation's IPC::Listener::OnMessageReceived. Intended
280 // only for test code.
282 // Add a keyboard listener that can handle key presses without requiring
284 virtual void AddKeyboardListener(KeyboardListener
* listener
) = 0;
286 // Remove a keyboard listener.
287 virtual void RemoveKeyboardListener(KeyboardListener
* listener
) = 0;
289 // Get the screen info corresponding to this render widget.
290 virtual void GetWebScreenInfo(WebKit::WebScreenInfo
* result
) = 0;
292 // Grabs snapshot from renderer side and returns the bitmap to a callback.
293 // If |src_rect| is empty, the whole contents is copied. This is an expensive
294 // operation due to the IPC, but it can be used as a fallback method when
295 // CopyFromBackingStore fails due to the backing store not being available or,
296 // in composited mode, when the accelerated surface is not available to the
298 virtual void GetSnapshotFromRenderer(
299 const gfx::Rect
& src_subrect
,
300 const base::Callback
<void(bool, const SkBitmap
&)>& callback
) = 0;
303 friend class RenderWidgetHostImpl
;
305 // Retrieves the implementation class. Intended only for code
306 // within content/. This method is necessary because
307 // RenderWidgetHost is the root of a diamond inheritance pattern, so
308 // subclasses inherit it virtually, which removes our ability to
309 // static_cast to the subclass.
310 virtual RenderWidgetHostImpl
* AsRenderWidgetHostImpl() = 0;
313 } // namespace content
315 #endif // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_