diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-08 14:37:26 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-08 14:37:26 +0000 |
commit | 62464e049919ba2868c1b4bbca685865167bc52a (patch) | |
tree | 3a5b06c6a5a953f9cd314d1b11b35d336bba4e15 /chrome/browser/renderer_host | |
parent | 6c3cb5d0cd05941282d47a40ea902453924821a5 (diff) | |
download | chromium_src-62464e049919ba2868c1b4bbca685865167bc52a.zip chromium_src-62464e049919ba2868c1b4bbca685865167bc52a.tar.gz chromium_src-62464e049919ba2868c1b4bbca685865167bc52a.tar.bz2 |
Wire GetWindowRect, GetRootWindowRect, and GetScreenInfo out to the UI thread.
Convert GetScreenInfo to be sync and routed.
http://crbug.com/13113
R=darin@chromium.org, jam@chromium.org, amanda@chromium.org
TEST=See bug.
Review URL: http://codereview.chromium.org/151130
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20143 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
12 files changed, 138 insertions, 93 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index cd23770..4aa5de0 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -680,10 +680,11 @@ bool RenderViewHost::SuddenTerminationAllowed() const { // RenderViewHost, IPC message handlers: void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { -#if !defined(OS_LINUX) +#if defined(OS_WIN) // On Windows there's a potential deadlock with sync messsages going in // a circle from browser -> plugin -> renderer -> browser. // On Linux we can avoid this by avoiding sync messages from browser->plugin. + // On Mac we avoid this by not supporting windowed plugins. if (msg.is_sync() && !msg.is_caller_pumping_messages()) { NOTREACHED() << "Can't send sync messages to UI thread without pumping " "messages in the renderer or else deadlocks can occur if the page " diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc index 88c8c51..6481881 100644 --- a/chrome/browser/renderer_host/render_widget_host.cc +++ b/chrome/browser/renderer_host/render_widget_host.cc @@ -24,6 +24,11 @@ #include "chrome/app/chrome_dll_resource.h" #endif // defined(OS_WIN) +#if defined (OS_MACOSX) +#include "webkit/api/public/WebScreenInfo.h" +#include "webkit/api/public/mac/WebScreenInfoFactory.h" +#endif + using base::Time; using base::TimeDelta; using base::TimeTicks; @@ -33,6 +38,11 @@ using WebKit::WebKeyboardEvent; using WebKit::WebMouseEvent; using WebKit::WebMouseWheelEvent; +#if defined (OS_MACOSX) +using WebKit::WebScreenInfo; +using WebKit::WebScreenInfoFactory; +#endif + // How long to (synchronously) wait for the renderer to respond with a // PaintRect message, when our backing-store is invalid, before giving up and // returning a null or incorrectly sized backing-store from GetBackingStore. @@ -119,12 +129,16 @@ IPC_DEFINE_MESSAGE_MAP(RenderWidgetHost) IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateStatus, OnMsgImeUpdateStatus) - IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ShowPopup, OnMsgShowPopup(msg)) #if defined(OS_LINUX) IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer, OnMsgCreatePluginContainer) IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer, OnMsgDestroyPluginContainer) +#elif defined(OS_MACOSX) + IPC_MESSAGE_HANDLER_GENERIC(ViewHostMsg_ShowPopup, OnMsgShowPopup(msg)) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnMsgGetScreenInfo) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnMsgGetWindowRect) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnMsgGetRootWindowRect) #endif IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() @@ -737,8 +751,18 @@ void RenderWidgetHost::OnMsgImeUpdateStatus(int control, } } +#if defined(OS_LINUX) +void RenderWidgetHost::OnMsgCreatePluginContainer( + gfx::PluginWindowHandle *container) { + *container = view_->CreatePluginContainer(); +} + +void RenderWidgetHost::OnMsgDestroyPluginContainer( + gfx::PluginWindowHandle container) { + view_->DestroyPluginContainer(container); +} +#elif defined(OS_MACOSX) void RenderWidgetHost::OnMsgShowPopup(const IPC::Message& message) { -#if defined(OS_MACOSX) void* iter = NULL; ViewHostMsg_ShowPopup_Params validated_params; if (!IPC::ParamTraits<ViewHostMsg_ShowPopup_Params>::Read(&message, &iter, @@ -749,20 +773,26 @@ void RenderWidgetHost::OnMsgShowPopup(const IPC::Message& message) { validated_params.item_height, validated_params.selected_item, validated_params.popup_items); -#else // OS_WIN || OS_LINUX - NOTREACHED(); -#endif } -#if defined(OS_LINUX) -void RenderWidgetHost::OnMsgCreatePluginContainer( - gfx::PluginWindowHandle *container) { - *container = view_->CreatePluginContainer(); +void RenderWidgetHost::OnMsgGetScreenInfo(gfx::NativeViewId view, + WebScreenInfo* results) { + gfx::NativeView native_view = view_ ? view_->GetNativeView() : NULL; + *results = WebScreenInfoFactory::screenInfo(native_view); } -void RenderWidgetHost::OnMsgDestroyPluginContainer( - gfx::PluginWindowHandle container) { - view_->DestroyPluginContainer(container); +void RenderWidgetHost::OnMsgGetWindowRect(gfx::NativeViewId window_id, + gfx::Rect* results) { + if (view_) { + *results = view_->GetWindowRect(); + } +} + +void RenderWidgetHost::OnMsgGetRootWindowRect(gfx::NativeViewId window_id, + gfx::Rect* results) { + if (view_) { + *results = view_->GetRootWindowRect(); + } } #endif diff --git a/chrome/browser/renderer_host/render_widget_host.h b/chrome/browser/renderer_host/render_widget_host.h index cf3f9d5..d2d2826 100644 --- a/chrome/browser/renderer_host/render_widget_host.h +++ b/chrome/browser/renderer_host/render_widget_host.h @@ -26,6 +26,7 @@ namespace WebKit { class WebInputEvent; class WebMouseEvent; class WebMouseWheelEvent; +struct WebScreenInfo; } class BackingStore; @@ -391,10 +392,15 @@ class RenderWidgetHost : public IPC::Channel::Listener { // Using int instead of ViewHostMsg_ImeControl for control's type to avoid // having to bring in render_messages.h in a header file. void OnMsgImeUpdateStatus(int control, const gfx::Rect& caret_rect); - void OnMsgShowPopup(const IPC::Message& message); #if defined(OS_LINUX) void OnMsgCreatePluginContainer(gfx::PluginWindowHandle *container); void OnMsgDestroyPluginContainer(gfx::PluginWindowHandle container); +#elif defined(OS_MACOSX) + void OnMsgShowPopup(const IPC::Message& message); + void OnMsgGetScreenInfo(gfx::NativeViewId view, + WebKit::WebScreenInfo* results); + void OnMsgGetWindowRect(gfx::NativeViewId window_id, gfx::Rect* results); + void OnMsgGetRootWindowRect(gfx::NativeViewId window_id, gfx::Rect* results); #endif // Paints the given bitmap to the current backing store at the given location. diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h index dca077e..fd72167 100644 --- a/chrome/browser/renderer_host/render_widget_host_view.h +++ b/chrome/browser/renderer_host/render_widget_host_view.h @@ -149,6 +149,12 @@ class RenderWidgetHostView { int item_height, int selected_item, const std::vector<WebMenuItem>& items) = 0; + + // Get the view's position on the screen. + virtual gfx::Rect GetWindowRect() = 0; + + // Get the view's window's position on the screen. + virtual gfx::Rect GetRootWindowRect() = 0; #endif #if defined(OS_LINUX) diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h index 617d495..270f00f 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.h +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h @@ -103,6 +103,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { int item_height, int selected_item, const std::vector<WebMenuItem>& items); + virtual gfx::Rect GetWindowRect(); + virtual gfx::Rect GetRootWindowRect(); void KillSelf(); diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index d5082a2..a039497 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -338,6 +338,44 @@ void RenderWidgetHostViewMac::ShutdownHost() { // Do not touch any members at this point, |this| has been deleted. } +namespace { + +// Adjusts an NSRect in screen coordinates to have an origin in the upper left, +// and stuffs it into a gfx::Rect. This is likely incorrect for a multiple- +// monitor setup. +gfx::Rect NSRectToRect(const NSRect rect, NSScreen* screen) { + gfx::Rect new_rect(NSRectToCGRect(rect)); + new_rect.set_y([screen frame].size.height - new_rect.y() - new_rect.height()); + return new_rect; +} + +} // namespace + +gfx::Rect RenderWidgetHostViewMac::GetWindowRect() { + // TODO(shess): In case of !window, the view has been removed from + // the view hierarchy because the tab isn't main. Could retrieve + // the information from the main tab for our window. + if (!cocoa_view_ || ![cocoa_view_ window]) { + return gfx::Rect(); + } + + NSRect bounds = [cocoa_view_ bounds]; + bounds = [cocoa_view_ convertRect:bounds toView:nil]; + bounds.origin = [[cocoa_view_ window] convertBaseToScreen:bounds.origin]; + return NSRectToRect(bounds, [[cocoa_view_ window] screen]); +} + +gfx::Rect RenderWidgetHostViewMac::GetRootWindowRect() { + // TODO(shess): In case of !window, the view has been removed from + // the view hierarchy because the tab isn't main. Could retrieve + // the information from the main tab for our window. + if (!cocoa_view_ || ![cocoa_view_ window]) { + return gfx::Rect(); + } + + NSRect bounds = [[cocoa_view_ window] frame]; + return NSRectToRect(bounds, [[cocoa_view_ window] screen]); +} // RenderWidgetHostViewCocoa --------------------------------------------------- diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index f9b535e..fa3af6ec3 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -51,17 +51,7 @@ #include "chrome/common/temp_scaffolding_stubs.h" #endif -#if defined(OS_WIN) -#include "webkit/api/public/win/WebScreenInfoFactory.h" -#elif defined(OS_MACOSX) -#include "webkit/api/public/mac/WebScreenInfoFactory.h" -#endif - using WebKit::WebCache; -using WebKit::WebScreenInfo; -#if !defined(OS_LINUX) -using WebKit::WebScreenInfoFactory; -#endif namespace { @@ -259,15 +249,19 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) { DCHECK(msg_is_ok); // It should have been marked handled if it wasn't OK. handled = true; IPC_BEGIN_MESSAGE_MAP_EX(ResourceMessageFilter, message, msg_is_ok) - // On Linux we need to dispatch these messages to the UI2 thread because - // we cannot make X calls from the IO thread. On other platforms, we can - // handle these calls directly. + // On Linux we need to dispatch these messages to the UI2 thread + // because we cannot make X calls from the IO thread. Mac + // doesn't have windowed plug-ins so we handle the messages in + // the UI thread. On Windows, we intercept the messages and + // handle them directly. +#if !defined(OS_MACOSX) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetScreenInfo, OnGetScreenInfo) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetWindowRect, OnGetWindowRect) IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_GetRootWindowRect, OnGetRootWindowRect) +#endif IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWindow, OnMsgCreateWindow) IPC_MESSAGE_HANDLER(ViewHostMsg_CreateWidget, OnMsgCreateWidget) @@ -524,18 +518,6 @@ void ResourceMessageFilter::OnLoadFont(LOGFONT font) { } #endif -#if !defined(OS_LINUX) -void ResourceMessageFilter::OnGetScreenInfo(gfx::NativeViewId view, - IPC::Message* reply_msg) { - // TODO(darin): Change this into a routed message so that we can eliminate - // the NativeViewId parameter. - WebScreenInfo results = - WebScreenInfoFactory::screenInfo(gfx::NativeViewFromId(view)); - ViewHostMsg_GetScreenInfo::WriteReplyParams(reply_msg, results); - Send(reply_msg); -} -#endif - void ResourceMessageFilter::OnGetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { plugin_service_->GetPlugins(refresh, plugins); diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 6ab9c3c..91a20d8 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -129,7 +129,10 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, void OnLoadFont(LOGFONT font); #endif +#if !defined(OS_MACOSX) + // Not handled in the IO thread on Mac. void OnGetScreenInfo(gfx::NativeViewId window, IPC::Message* reply); +#endif void OnGetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); void OnGetPluginPath(const GURL& url, const GURL& policy_url, @@ -167,8 +170,11 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, void OnClipboardReadAsciiText(IPC::Message* reply); void OnClipboardReadHTML(IPC::Message* reply); +#if !defined(OS_MACOSX) + // Not handled in the IO thread on Mac. void OnGetWindowRect(gfx::NativeViewId window, IPC::Message* reply); void OnGetRootWindowRect(gfx::NativeViewId window, IPC::Message* reply); +#endif void OnGetMimeTypeFromExtension(const FilePath::StringType& ext, std::string* mime_type); void OnGetMimeTypeFromFile(const FilePath& file_path, diff --git a/chrome/browser/renderer_host/resource_message_filter_mac.mm b/chrome/browser/renderer_host/resource_message_filter_mac.mm deleted file mode 100644 index 81ad814..0000000 --- a/chrome/browser/renderer_host/resource_message_filter_mac.mm +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2009 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. - -#include "chrome/browser/renderer_host/resource_message_filter.h" -#include "chrome/common/render_messages.h" - -#import <Cocoa/Cocoa.h> - -namespace { - -// Adjusts an NSRect in screen coordinates to have an origin in the upper left, -// and stuffs it into a gfx::Rect. This is likely incorrect for a multiple- -// monitor setup. -gfx::Rect NSRectToRect(const NSRect rect, NSScreen* screen) { - gfx::Rect new_rect(NSRectToCGRect(rect)); - new_rect.set_y([screen frame].size.height - new_rect.y() - new_rect.height()); - return new_rect; -} - -} - -// We get null window_ids passed into the two functions below; please see -// http://crbug.com/9060 for more details. - -void ResourceMessageFilter::OnGetWindowRect(gfx::NativeViewId window_id, - IPC::Message* reply_msg) { - NSView* view = gfx::NativeViewFromId(window_id); - gfx::Rect rect; - - if (view && [view window]) { - NSRect bounds = [view bounds]; - bounds = [view convertRect:bounds toView:nil]; - bounds.origin = [[view window] convertBaseToScreen:bounds.origin]; - rect = NSRectToRect(bounds, [[view window] screen]); - } - - ViewHostMsg_GetWindowRect::WriteReplyParams(reply_msg, rect); - Send(reply_msg); -} - -void ResourceMessageFilter::OnGetRootWindowRect(gfx::NativeViewId window_id, - IPC::Message* reply_msg) { - NSView* view = gfx::NativeViewFromId(window_id); - gfx::Rect rect; - - if (view && [view window]) { - NSRect bounds = [[view window] frame]; - rect = NSRectToRect(bounds, [[view window] screen]); - } - - ViewHostMsg_GetRootWindowRect::WriteReplyParams(reply_msg, rect); - Send(reply_msg); -} diff --git a/chrome/browser/renderer_host/resource_message_filter_win.cc b/chrome/browser/renderer_host/resource_message_filter_win.cc index 2aae6ed..b9acece 100644 --- a/chrome/browser/renderer_host/resource_message_filter_win.cc +++ b/chrome/browser/renderer_host/resource_message_filter_win.cc @@ -4,10 +4,17 @@ #include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/render_messages.h" +#include "webkit/api/public/win/WebScreenInfoFactory.h" + +using WebKit::WebScreenInfo; +using WebKit::WebScreenInfoFactory; // We get null window_ids passed into the two functions below; please see // http://crbug.com/9060 for more details. +// TODO(shess): Provide a mapping from reply_msg->routing_id() to HWND +// so that we can eliminate the NativeViewId parameter. + void ResourceMessageFilter::OnGetWindowRect(gfx::NativeViewId window_id, IPC::Message* reply_msg) { HWND window = gfx::NativeViewFromId(window_id); @@ -30,3 +37,11 @@ void ResourceMessageFilter::OnGetRootWindowRect(gfx::NativeViewId window_id, ViewHostMsg_GetRootWindowRect::WriteReplyParams(reply_msg, rect); Send(reply_msg); } + +void ResourceMessageFilter::OnGetScreenInfo(gfx::NativeViewId view, + IPC::Message* reply_msg) { + WebScreenInfo results = + WebScreenInfoFactory::screenInfo(gfx::NativeViewFromId(view)); + ViewHostMsg_GetScreenInfo::WriteReplyParams(reply_msg, results); + Send(reply_msg); +} diff --git a/chrome/browser/renderer_host/test/test_render_view_host.cc b/chrome/browser/renderer_host/test/test_render_view_host.cc index 17b91e3..b682916 100644 --- a/chrome/browser/renderer_host/test/test_render_view_host.cc +++ b/chrome/browser/renderer_host/test/test_render_view_host.cc @@ -4,6 +4,7 @@ #include "chrome/browser/renderer_host/test/test_render_view_host.h" +#include "base/gfx/rect.h" #include "chrome/browser/renderer_host/backing_store.h" #include "chrome/browser/tab_contents/test_web_contents.h" #include "chrome/common/render_messages.h" @@ -76,6 +77,16 @@ BackingStore* TestRenderWidgetHostView::AllocBackingStore( return new BackingStore(rwh_, size); } +#if defined(OS_MACOSX) +gfx::Rect TestRenderWidgetHostView::GetWindowRect() { + return gfx::Rect(); +} + +gfx::Rect TestRenderWidgetHostView::GetRootWindowRect() { + return gfx::Rect(); +} +#endif + void RenderViewHostTestHarness::NavigateAndCommit(const GURL& url) { controller().LoadURL(url, GURL(), 0); rvh()->SendNavigate(process()->max_page_id() + 1, url); diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h index 0b16181..dcc3e1a 100644 --- a/chrome/browser/renderer_host/test/test_render_view_host.h +++ b/chrome/browser/renderer_host/test/test_render_view_host.h @@ -77,6 +77,8 @@ class TestRenderWidgetHostView : public RenderWidgetHostView { int item_height, int selected_item, const std::vector<WebMenuItem>& items) {} + virtual gfx::Rect GetWindowRect(); + virtual gfx::Rect GetRootWindowRect(); #endif #if defined(OS_LINUX) |