summaryrefslogtreecommitdiffstats
path: root/content/public/browser/render_widget_host.h
blob: 6fc195b23dca59720a947e6c531225bcc8135c08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_
#define CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_

#include "base/callback.h"
#include "content/common/content_export.h"
#include "content/public/browser/keyboard_listener.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_sender.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebTextDirection.h"
#include "ui/gfx/size.h"
#include "ui/surface/transport_dib.h"

#if defined(TOOLKIT_GTK)
#include "ui/base/x/x11_util.h"
#elif defined(OS_MACOSX)
#include "skia/ext/platform_device.h"
#endif

namespace gfx {
class Rect;
}

namespace skia {
class PlatformCanvas;
}

namespace content {

class RenderProcessHost;
class RenderWidgetHostImpl;
class RenderWidgetHostView;

// A RenderWidgetHost manages the browser side of a browser<->renderer
// HWND connection.  The HWND lives in the browser process, and
// windows events are sent over IPC to the corresponding object in the
// renderer.  The renderer paints into shared memory, which we
// transfer to a backing store and blit to the screen when Windows
// sends us a WM_PAINT message.
//
// How Shutdown Works
//
// There are two situations in which this object, a RenderWidgetHost, can be
// instantiated:
//
// 1. By a WebContents as the communication conduit for a rendered web page.
//    The WebContents instantiates a derived class: RenderViewHost.
// 2. By a WebContents as the communication conduit for a select widget. The
//    WebContents instantiates the RenderWidgetHost directly.
//
// For every WebContents there are several objects in play that need to be
// properly destroyed or cleaned up when certain events occur.
//
// - WebContents - the WebContents itself, and its associated HWND.
// - RenderViewHost - representing the communication conduit with the child
//   process.
// - RenderWidgetHostView - the view of the web page content, message handler,
//   and plugin root.
//
// Normally, the WebContents contains a child RenderWidgetHostView that renders
// the contents of the loaded page. It has a WS_CLIPCHILDREN style so that it
// does no painting of its own.
//
// The lifetime of the RenderWidgetHostView is tied to the render process. If
// the render process dies, the RenderWidgetHostView goes away and all
// references to it must become NULL.
//
// RenderViewHost (a RenderWidgetHost subclass) is the conduit used to
// communicate with the RenderView and is owned by the WebContents. If the
// render process crashes, the RenderViewHost remains and restarts the render
// process if needed to continue navigation.
//
// Some examples of how shutdown works:
//
// For a WebContents, its Destroy method tells the RenderViewHost to
// shut down the render process and die.
//
// When the render process is destroyed it destroys the View: the
// RenderWidgetHostView, which destroys its HWND and deletes that object.
//
// For select popups, the situation is a little different. The RenderWidgetHost
// associated with the select popup owns the view and itself (is responsible
// for destroying itself when the view is closed). The WebContents's only
// responsibility is to select popups is to create them when it is told to. When
// the View is destroyed via an IPC message (for when WebCore destroys the
// popup, e.g. if the user selects one of the options), or because
// WM_CANCELMODE is received by the view, the View schedules the destruction of
// the render process. However in this case since there's no WebContents
// container, when the render process is destroyed, the RenderWidgetHost just
// deletes itself, which is safe because no one else should have any references
// to it (the WebContents does not).
//
// It should be noted that the RenderViewHost, not the RenderWidgetHost,
// handles IPC messages relating to the render process going away, since the
// way a RenderViewHost (WebContents) handles the process dying is different to
// the way a select popup does. As such the RenderWidgetHostView handles these
// messages for select popups. This placement is more out of convenience than
// anything else. When the view is live, these messages are forwarded to it by
// the RenderWidgetHost's IPC message map.
class CONTENT_EXPORT RenderWidgetHost : public IPC::Sender {
 public:
  // Free all backing stores used for rendering to drop memory usage.
  static void RemoveAllBackingStores();

  // Returns the size of all the backing stores used for rendering
  static size_t BackingStoreMemorySize();

  virtual ~RenderWidgetHost() {}

  // Edit operations.
  virtual void Undo() = 0;
  virtual void Redo() = 0;
  virtual void Cut() = 0;
  virtual void Copy() = 0;
  virtual void CopyToFindPboard() = 0;
  virtual void Paste() = 0;
  virtual void PasteAndMatchStyle() = 0;
  virtual void Delete() = 0;
  virtual void SelectAll() = 0;

  // Update the text direction of the focused input element and notify it to a
  // renderer process.
  // These functions have two usage scenarios: changing the text direction
  // from a menu (as Safari does), and; changing the text direction when a user
  // presses a set of keys (as IE and Firefox do).
  // 1. Change the text direction from a menu.
  // In this scenario, we receive a menu event only once and we should update
  // the text direction immediately when a user chooses a menu item. So, we
  // should call both functions at once as listed in the following snippet.
  //   void RenderViewHost::SetTextDirection(WebTextDirection direction) {
  //     UpdateTextDirection(direction);
  //     NotifyTextDirection();
  //   }
  // 2. Change the text direction when pressing a set of keys.
  // Because of auto-repeat, we may receive the same key-press event many
  // times while we presses the keys and it is nonsense to send the same IPC
  // message every time when we receive a key-press event.
  // To suppress the number of IPC messages, we just update the text direction
  // when receiving a key-press event and send an IPC message when we release
  // the keys as listed in the following snippet.
  //   if (key_event.type == WebKeyboardEvent::KEY_DOWN) {
  //     if (key_event.windows_key_code == 'A' &&
  //         key_event.modifiers == WebKeyboardEvent::CTRL_KEY) {
  //       UpdateTextDirection(dir);
  //     } else {
  //       CancelUpdateTextDirection();
  //     }
  //   } else if (key_event.type == WebKeyboardEvent::KEY_UP) {
  //     NotifyTextDirection();
  //   }
  // Once we cancel updating the text direction, we have to ignore all
  // succeeding UpdateTextDirection() requests until calling
  // NotifyTextDirection(). (We may receive keydown events even after we
  // canceled updating the text direction because of auto-repeat.)
  // Note: we cannot undo this change for compatibility with Firefox and IE.
  virtual void UpdateTextDirection(WebKit::WebTextDirection direction) = 0;
  virtual void NotifyTextDirection() = 0;

  virtual void Blur() = 0;

  // Copies the given subset of the backing store into the given (uninitialized)
  // PlatformCanvas. If |src_rect| is empty, the whole contents is copied.
  // NOTE: |src_rect| is not supported yet when accelerated compositing is
  // active (http://crbug.com/118571) and the whole content is always copied
  // regardless of |src_rect|.
  // If non empty |accelerated_dest_size| is given and accelerated compositing
  // is active, the content is shrinked so that it fits in
  // |accelerated_dest_size|. If |accelerated_dest_size| is larger than the
  // contens size, the content is not resized. If |accelerated_dest_size| is
  // empty, the size copied from the source contents is used.
  // |callback| is invoked with true on success, false otherwise. |output| can
  // be initialized even on failure.
  // NOTE: |callback| is called synchronously if the backing store is available.
  // When accelerated compositing is active, it is called asynchronously on Aura
  // and synchronously on the other platforms.
  virtual void CopyFromBackingStore(const gfx::Rect& src_rect,
                                    const gfx::Size& accelerated_dest_size,
                                    const base::Callback<void(bool)>& callback,
                                    skia::PlatformCanvas* output) = 0;
#if defined(TOOLKIT_GTK)
  // Paint the backing store into the target's |dest_rect|.
  virtual bool CopyFromBackingStoreToGtkWindow(const gfx::Rect& dest_rect,
                                               GdkWindow* target) = 0;
#elif defined(OS_MACOSX)
  virtual gfx::Size GetBackingStoreSize() = 0;
  virtual bool CopyFromBackingStoreToCGContext(const CGRect& dest_rect,
                                               CGContextRef target) = 0;
#endif

  // Send a command to the renderer to turn on full accessibility.
  virtual void EnableFullAccessibilityMode() = 0;

  // Forwards the given message to the renderer. These are called by
  // the view when it has received a message.
  virtual void ForwardMouseEvent(
      const WebKit::WebMouseEvent& mouse_event) = 0;
  virtual void ForwardWheelEvent(
      const WebKit::WebMouseWheelEvent& wheel_event) = 0;
  virtual void ForwardKeyboardEvent(
      const NativeWebKeyboardEvent& key_event) = 0;

  virtual const gfx::Point& GetLastScrollOffset() const = 0;

  virtual RenderProcessHost* GetProcess() const = 0;

  virtual int GetRoutingID() const = 0;

  // Gets the View of this RenderWidgetHost. Can be NULL, e.g. if the
  // RenderWidget is being destroyed or the render process crashed. You should
  // never cache this pointer since it can become NULL if the renderer crashes,
  // instead you should always ask for it using the accessor.
  virtual RenderWidgetHostView* GetView() const = 0;

  // Returns true if the renderer is loading, false if not.
  virtual bool IsLoading() const = 0;

  // Returns true if this is a RenderViewHost, false if not.
  virtual bool IsRenderView() const = 0;

  // This tells the renderer to paint into a bitmap and return it,
  // regardless of whether the tab is hidden or not.  It resizes the
  // web widget to match the |page_size| and then returns the bitmap
  // scaled so it matches the |desired_size|, so that the scaling
  // happens on the rendering thread.  When the bitmap is ready, the
  // renderer sends a PaintAtSizeACK to this host, and a
  // RENDER_WIDGET_HOST_DID_RECEIVE_PAINT_AT_SIZE_ACK notification is issued.
  // Note that this bypasses most of the update logic that is normally invoked,
  // and doesn't put the results into the backing store.
  virtual void PaintAtSize(TransportDIB::Handle dib_handle,
                           int tag,
                           const gfx::Size& page_size,
                           const gfx::Size& desired_size) = 0;

  // Makes an IPC call to tell webkit to replace the currently selected word
  // or a word around the cursor.
  virtual void Replace(const string16& word) = 0;

  // Called to notify the RenderWidget that the resize rect has changed without
  // the size of the RenderWidget itself changing.
  virtual void ResizeRectChanged(const gfx::Rect& new_rect) = 0;

  // Restart the active hang monitor timeout. Clears all existing timeouts and
  // starts with a new one.  This can be because the renderer has become
  // active, the tab is being hidden, or the user has chosen to wait some more
  // to give the tab a chance to become active and we don't want to display a
  // warning too soon.
  virtual void RestartHangMonitorTimeout() = 0;

  virtual void SetIgnoreInputEvents(bool ignore_input_events) = 0;

  // Stops loading the page.
  virtual void Stop() = 0;

  // Called to notify the RenderWidget that it has been resized.
  virtual void WasResized() = 0;

  // Access to the implementation's IPC::Listener::OnMessageReceived. Intended
  // only for test code.

  // Add a keyboard listener that can handle key presses without requiring
  // focus.
  virtual void AddKeyboardListener(KeyboardListener* listener) = 0;

  // Remove a keyboard listener.
  virtual void RemoveKeyboardListener(KeyboardListener* listener) = 0;

  // Update the device scale factor.
  virtual void SetDeviceScaleFactor(float scale) = 0;

 protected:
  friend class RenderWidgetHostImpl;

  // Retrieves the implementation class.  Intended only for code
  // within content/.  This method is necessary because
  // RenderWidgetHost is the root of a diamond inheritance pattern, so
  // subclasses inherit it virtually, which removes our ability to
  // static_cast to the subclass.
  virtual RenderWidgetHostImpl* AsRenderWidgetHostImpl() = 0;
};

}  // namespace content

#endif  // CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_H_