Give the main frame a RenderWidget.
Currently, RenderView is a subclass of RenderWidget, and the RenderWidget
portion is effectively treated as the the widget for the main frame as
well. For a number of reasons, this is a problematic model:
- A remote frame doesn't need a widget; however, a RenderView with a remote
main frame still has a vestigal RenderWidget.
- Code that needs to affect both RenderWidget / RenderView is awkwardly
split between them, in both content and blink.
- RenderView itself is often seen as an easy entry point to perform
page-level work in the renderer. With OOPI, this is no longer a valid
assumption.
In order to incrementally de-widgetize RenderView, the main frame will
have also have a RenderWidget, to make it consistent with the local frame
roots for subframes, which already have a RenderWidget. However, instead of
giving main frames their own RenderWidget, the main frame re-uses the
RenderView as its RenderWidget.
The rationale for taking this approach is to minimize the breakage: today,
Chrome simply doesn't expect to have two "widgets" for a frame.
Instantiating a distinct RenderWidget for the main frame can confuse code
that iterates or counts the active widgets: an example of this is the
security check for injecting WebUI bindings.
In the future, when RenderViewHost has-a RenderWidgetHost (and similarly,
when RenderViewImpl has-a RenderWidget) instead of today's is-a relation,
then it be conceptually much more straightforward to transition completely
to the new model.
BUG=419087
Review URL: https://codereview.chromium.org/1303773002
Cr-Commit-Position: refs/heads/master@{#356176}
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index 2ece707..44b971f 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -50,6 +50,7 @@
#include "content/renderer/render_frame_proxy.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h"
+#include "content/renderer/render_view_impl.h"
#include "content/renderer/renderer_blink_platform_impl.h"
#include "content/renderer/resizing_mode_selector.h"
#include "ipc/ipc_sync_message.h"
@@ -571,6 +572,14 @@
CompositorDependencies* compositor_deps,
blink::WebLocalFrame* frame) {
CHECK_NE(routing_id, MSG_ROUTING_NONE);
+ // TODO(avi): Before RenderViewImpl has-a RenderWidget, the browser passes the
+ // same routing ID for both the view routing ID and the main frame widget
+ // routing ID. https://crbug.com/545684
+ RenderViewImpl* view = RenderViewImpl::FromRoutingID(routing_id);
+ if (view) {
+ view->AttachWebFrameWidget(RenderWidget::CreateWebFrameWidget(view, frame));
+ return view;
+ }
scoped_refptr<RenderWidget> widget(
new RenderWidget(compositor_deps, blink::WebPopupTypeNone, screen_info,
false, hidden, false));
@@ -590,6 +599,11 @@
blink::WebWidget* RenderWidget::CreateWebFrameWidget(
RenderWidget* render_widget,
blink::WebLocalFrame* frame) {
+ if (!frame->parent()) {
+ // TODO(dcheng): The main frame widget currently has a special case.
+ // Eliminate this once WebView is no longer a WebWidget.
+ return blink::WebFrameWidget::create(render_widget, frame->view(), frame);
+ }
return blink::WebFrameWidget::create(render_widget, frame);
}