diff options
-rw-r--r-- | content/browser/renderer_host/render_message_filter.cc | 23 | ||||
-rw-r--r-- | content/browser/renderer_host/render_message_filter.h | 19 | ||||
-rw-r--r-- | content/browser/renderer_host/render_message_filter_gtk.cc | 150 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host.cc | 7 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host.h | 7 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_gtk.cc | 86 | ||||
-rw-r--r-- | content/content_browser.gypi | 1 | ||||
-rw-r--r-- | ui/gfx/gtk_native_view_id_manager.cc | 17 | ||||
-rw-r--r-- | ui/gfx/gtk_native_view_id_manager.h | 12 |
9 files changed, 133 insertions, 189 deletions
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index 9b0d75e..dd3f0cd 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc @@ -304,13 +304,6 @@ RenderMessageFilter::~RenderMessageFilter() { void RenderMessageFilter::OverrideThreadForMessage(const IPC::Message& message, BrowserThread::ID* thread) { switch (message.type()) { -#if defined(USE_X11) - case ViewHostMsg_GetScreenInfo::ID: - case ViewHostMsg_GetWindowRect::ID: - case ViewHostMsg_GetRootWindowRect::ID: - *thread = BrowserThread::BACKGROUND_X11; - break; -#endif // Can't load plugins on IO thread. case ViewHostMsg_GetPlugins::ID: // The PluginService::GetPluginInfo may need to load the plugins. Don't do @@ -327,15 +320,16 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message, bool* message_was_ok) { bool handled = true; IPC_BEGIN_MESSAGE_MAP_EX(RenderMessageFilter, message, *message_was_ok) - // 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) +#if defined(OS_WIN) + // On Windows, we handle these on the IO thread to avoid a deadlock with + // plugins. On non-Windows systems, we need to handle them on the UI + // thread. IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnGetScreenInfo) IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnGetWindowRect) IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnGetRootWindowRect) + + // This hack is Windows-specific. + IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFont, OnPreCacheFont) #endif IPC_MESSAGE_HANDLER(ViewHostMsg_GenerateRoutingID, OnGenerateRoutingID) @@ -351,9 +345,6 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message, #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ViewHostMsg_LoadFont, OnLoadFont) #endif -#if defined(OS_WIN) // This hack is Windows-specific. - IPC_MESSAGE_HANDLER(ViewHostMsg_PreCacheFont, OnPreCacheFont) -#endif IPC_MESSAGE_HANDLER(ViewHostMsg_GetPlugins, OnGetPlugins) IPC_MESSAGE_HANDLER(ViewHostMsg_GetPluginInfo, OnGetPluginInfo) IPC_MESSAGE_HANDLER(ViewHostMsg_DownloadUrl, OnDownloadUrl) diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index f9d183d..08741b6 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h @@ -135,19 +135,20 @@ class RenderMessageFilter : public BrowserMessageFilter { uint32* font_id); #endif -#if defined(OS_WIN) // This hack is Windows-specific. - // Cache fonts for the renderer. See RenderMessageFilter::OnPreCacheFont - // implementation for more details. - void OnPreCacheFont(LOGFONT font); -#endif - -#if !defined(OS_MACOSX) - // Not handled in the IO thread on Mac. +#if defined(OS_WIN) + // On Windows, we handle these on the IO thread to avoid a deadlock with + // plugins. On non-Windows systems, we need to handle them on the UI thread. void OnGetScreenInfo(gfx::NativeViewId window, WebKit::WebScreenInfo* results); void OnGetWindowRect(gfx::NativeViewId window, gfx::Rect* rect); void OnGetRootWindowRect(gfx::NativeViewId window, gfx::Rect* rect); + + // This hack is Windows-specific. + // Cache fonts for the renderer. See RenderMessageFilter::OnPreCacheFont + // implementation for more details. + void OnPreCacheFont(LOGFONT font); #endif + void OnGetPlugins(bool refresh, std::vector<webkit::npapi::WebPluginInfo>* plugins); void OnGetPluginInfo(int routing_id, @@ -173,7 +174,7 @@ class RenderMessageFilter : public BrowserMessageFilter { void OnCheckNotificationPermission(const GURL& source_url, int* permission_level); -// Used to ask the browser to allocate a block of shared memory for the + // Used to ask the browser to allocate a block of shared memory for the // renderer to send back data in, since shared memory can't be created // in the renderer on POSIX due to the sandbox. void OnAllocateSharedMemoryBuffer(uint32 buffer_size, diff --git a/content/browser/renderer_host/render_message_filter_gtk.cc b/content/browser/renderer_host/render_message_filter_gtk.cc deleted file mode 100644 index 4612734..0000000 --- a/content/browser/renderer_host/render_message_filter_gtk.cc +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2011 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 <dlfcn.h> - -#include "content/browser/renderer_host/render_message_filter.h" - -#include "content/browser/browser_thread.h" -#include "content/common/view_messages.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h" -#include "ui/base/clipboard/clipboard.h" -#include "ui/base/x/x11_util.h" -#include "ui/gfx/gtk_native_view_id_manager.h" - -#if !defined(OS_CHROMEOS) -// We want to obey the alphabetical order for including header files, but -// #define macros in X11 header files affect chrome header files -// (e.g. Success), so include Xinerama.h here. We don't include Xinerama.h on -// Chrome OS since the X server for Chrome OS does not support the extension. -#include <X11/extensions/Xinerama.h> -#endif // OS_CHROMEOS - -using WebKit::WebScreenInfo; -using WebKit::WebScreenInfoFactory; - -namespace { - -// Return the top-level parent of the given window. Called on the -// BACKGROUND_X11 thread. -XID GetTopLevelWindow(XID window) { - bool parent_is_root; - XID parent_window; - - if (!ui::GetWindowParent(&parent_window, &parent_is_root, window)) - return 0; - if (parent_is_root) - return window; - - return GetTopLevelWindow(parent_window); -} - -gfx::Rect GetWindowRectFromView(gfx::NativeViewId view) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11)); - // This is called to get the x, y offset (in screen coordinates) of the given - // view and its width and height. - gfx::Rect rect; - XID window; - - base::AutoLock lock(GtkNativeViewManager::GetInstance()->unrealize_lock()); - if (GtkNativeViewManager::GetInstance()->GetXIDForId(&window, view)) { - if (window) { - int x, y; - unsigned width, height; - if (ui::GetWindowGeometry(&x, &y, &width, &height, window)) - rect = gfx::Rect(x, y, width, height); - } - } - return rect; -} - -} // namespace - -// We get null window_ids passed into the two functions below; please see -// http://crbug.com/9060 for more details. -void RenderMessageFilter::OnGetScreenInfo(gfx::NativeViewId view, - WebKit::WebScreenInfo* results) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11)); - Display* display = ui::GetSecondaryDisplay(); - - *results = WebScreenInfoFactory::screenInfo(display, - ui::GetDefaultScreen(display)); - -#if !defined(OS_CHROMEOS) - // First check if we can use Xinerama. - XineramaScreenInfo* screen_info = NULL; - int screen_num = 0; - void* xinerama_lib = dlopen("libXinerama.so.1", RTLD_LAZY); - if (xinerama_lib) { - // Prototypes for Xinerama functions. - typedef Bool (*XineramaIsActiveFunction)(Display* display); - typedef XineramaScreenInfo* - (*XineramaQueryScreensFunction)(Display* display, int* num); - - XineramaIsActiveFunction is_active = (XineramaIsActiveFunction) - dlsym(xinerama_lib, "XineramaIsActive"); - - XineramaQueryScreensFunction query_screens = (XineramaQueryScreensFunction) - dlsym(xinerama_lib, "XineramaQueryScreens"); - - // Get the number of screens via Xinerama - if (is_active && query_screens && is_active(display)) - screen_info = query_screens(display, &screen_num); - - if (screen_info) { - // We can use Xinerama information. Calculate the intersect rect size - // between window rect and screen rect, and choose the biggest size. - gfx::Rect rect = GetWindowRectFromView(view); - int max_intersect_index = 0; - for (int i = 0, max_intersect_size = 0; i < screen_num; ++i) { - gfx::Rect screen_rect(screen_info[i].x_org, screen_info[i].y_org, - screen_info[i].width, screen_info[i].height); - gfx::Rect intersect_rect = screen_rect.Intersect(rect); - int intersect_size = intersect_rect.width() * intersect_rect.height(); - if (intersect_size > max_intersect_size) { - max_intersect_size = intersect_size; - max_intersect_index = i; - } - } - XineramaScreenInfo& target_screen = screen_info[max_intersect_index]; - results->rect = WebKit::WebRect(target_screen.x_org, - target_screen.y_org, - target_screen.width, - target_screen.height); - results->availableRect = results->rect; - - XFree(screen_info); - } - } -#endif // OS_CHROMEOS -} - -void RenderMessageFilter::OnGetWindowRect(gfx::NativeViewId view, - gfx::Rect* rect) { - *rect = GetWindowRectFromView(view); -} - -void RenderMessageFilter::OnGetRootWindowRect(gfx::NativeViewId view, - gfx::Rect* rect) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::BACKGROUND_X11)); - // This is called to get the screen coordinates and size of the browser - // window itself. - *rect = gfx::Rect(); - XID window; - - base::AutoLock lock(GtkNativeViewManager::GetInstance()->unrealize_lock()); - if (GtkNativeViewManager::GetInstance()->GetXIDForId(&window, view)) { - if (window) { - const XID toplevel = GetTopLevelWindow(window); - if (toplevel) { - int x, y; - unsigned width, height; - if (ui::GetWindowGeometry(&x, &y, &width, &height, toplevel)) - *rect = gfx::Rect(x, y, width, height); - } - } - } -} diff --git a/content/browser/renderer_host/render_widget_host.cc b/content/browser/renderer_host/render_widget_host.cc index 30ad1b0..670e50f 100644 --- a/content/browser/renderer_host/render_widget_host.cc +++ b/content/browser/renderer_host/render_widget_host.cc @@ -170,10 +170,12 @@ bool RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) { OnMsgImeCancelComposition) IPC_MESSAGE_HANDLER(ViewHostMsg_DidActivateAcceleratedCompositing, OnMsgDidActivateAcceleratedCompositing) -#if defined(OS_MACOSX) +#if defined(OS_POSIX) IPC_MESSAGE_HANDLER(ViewHostMsg_GetScreenInfo, OnMsgGetScreenInfo) IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowRect, OnMsgGetWindowRect) IPC_MESSAGE_HANDLER(ViewHostMsg_GetRootWindowRect, OnMsgGetRootWindowRect) +#endif +#if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ViewHostMsg_PluginFocusChanged, OnMsgPluginFocusChanged) IPC_MESSAGE_HANDLER(ViewHostMsg_StartPluginIme, @@ -188,7 +190,8 @@ bool RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) { OnAcceleratedSurfaceSetTransportDIB) IPC_MESSAGE_HANDLER(ViewHostMsg_AcceleratedSurfaceBuffersSwapped, OnAcceleratedSurfaceBuffersSwapped) -#elif defined(TOOLKIT_USES_GTK) +#endif +#if defined(TOOLKIT_USES_GTK) IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer, OnMsgCreatePluginContainer) IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer, diff --git a/content/browser/renderer_host/render_widget_host.h b/content/browser/renderer_host/render_widget_host.h index a275b58..e610958 100644 --- a/content/browser/renderer_host/render_widget_host.h +++ b/content/browser/renderer_host/render_widget_host.h @@ -460,11 +460,13 @@ class RenderWidgetHost : public IPC::Channel::Listener, void OnMsgDidActivateAcceleratedCompositing(bool activated); -#if defined(OS_MACOSX) +#if defined(OS_POSIX) 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 +#if defined(OS_MACOSX) void OnMsgPluginFocusChanged(bool focused, int plugin_id); void OnMsgStartPluginIme(); void OnAllocateFakePluginWindowHandle(bool opaque, @@ -481,7 +483,8 @@ class RenderWidgetHost : public IPC::Channel::Listener, TransportDIB::Handle transport_dib); void OnAcceleratedSurfaceBuffersSwapped(gfx::PluginWindowHandle window, uint64 surface_id); -#elif defined(OS_POSIX) +#endif +#if defined(TOOLKIT_USES_GTK) void OnMsgCreatePluginContainer(gfx::PluginWindowHandle id); void OnMsgDestroyPluginContainer(gfx::PluginWindowHandle id); #endif diff --git a/content/browser/renderer_host/render_widget_host_gtk.cc b/content/browser/renderer_host/render_widget_host_gtk.cc index e378edf..b7dd333 100644 --- a/content/browser/renderer_host/render_widget_host_gtk.cc +++ b/content/browser/renderer_host/render_widget_host_gtk.cc @@ -4,7 +4,93 @@ #include "content/browser/renderer_host/render_widget_host.h" +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#include "base/synchronization/lock.h" #include "content/browser/renderer_host/render_widget_host_view.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/x11/WebScreenInfoFactory.h" +#include "ui/gfx/gtk_native_view_id_manager.h" +#include "ui/gfx/rect.h" + +using WebKit::WebScreenInfo; +using WebKit::WebScreenInfoFactory; + +// We get a null |view| passed into this function please see +// http://crbug.com/9060 for more details. +void RenderWidgetHost::OnMsgGetScreenInfo(gfx::NativeViewId view, + WebScreenInfo* results) { + GtkWidget* widget = NULL; + GdkWindow* gdk_window = NULL; + if (GtkNativeViewManager::GetInstance()->GetNativeViewForId( + &widget, view) && widget) { + gdk_window = widget->window; + } else { + GdkDisplay* display = gdk_display_get_default(); + gdk_window = gdk_display_get_window_at_pointer(display, NULL, NULL); + } + if (!gdk_window) + return; + GdkScreen* screen = gdk_drawable_get_screen(gdk_window); + *results = WebScreenInfoFactory::screenInfo( + gdk_x11_drawable_get_xdisplay(gdk_window), + gdk_x11_screen_get_screen_number(screen)); + + // TODO(tony): We should move this code into WebScreenInfoFactory. + int monitor_number = gdk_screen_get_monitor_at_window(screen, gdk_window); + GdkRectangle monitor_rect; + gdk_screen_get_monitor_geometry(screen, monitor_number, &monitor_rect); + results->rect = WebKit::WebRect(monitor_rect.x, monitor_rect.y, + monitor_rect.width, monitor_rect.height); + // TODO(tony): Should we query _NET_WORKAREA to get the workarea? + results->availableRect = results->rect; +} + +// We get null window_ids passed into this function please see +// http://crbug.com/9060 for more details. +void RenderWidgetHost::OnMsgGetWindowRect(gfx::NativeViewId window_id, + gfx::Rect* results) { + GtkWidget* widget = NULL; + if (!GtkNativeViewManager::GetInstance()->GetNativeViewForId( + &widget, window_id) || !widget) { + return; + } + GdkWindow* gdk_window = widget->window; + if (!gdk_window) + return; + GdkRectangle window_rect; + gdk_window_get_origin(gdk_window, &window_rect.x, &window_rect.y); + gdk_drawable_get_size(gdk_window, &window_rect.width, &window_rect.height); + *results = window_rect; +} + +// We get null window_ids passed into this function please see +// http://crbug.com/9060 for more details. +void RenderWidgetHost::OnMsgGetRootWindowRect(gfx::NativeViewId window_id, + gfx::Rect* results) { + GtkWidget* widget = NULL; + if (!GtkNativeViewManager::GetInstance()->GetNativeViewForId( + &widget, window_id) || !widget) { + return; + } + GtkWidget* toplevel = gtk_widget_get_toplevel(widget); + if (!toplevel) + return; + + GdkRectangle frame_extents; + GdkWindow* gdk_window = toplevel->window; + if (!gdk_window) + return; + gdk_window_get_frame_extents(gdk_window, &frame_extents); + int width = 0; + int height = 0; + gdk_drawable_get_size(gdk_window, &width, &height); + // Although we return a rect, this is actually two pairs of data: The + // position of the top left corner of the window and the size of the window + // not including the window decorations. + *results = gfx::Rect(frame_extents.x, frame_extents.y, width, height); +} void RenderWidgetHost::OnMsgCreatePluginContainer(gfx::PluginWindowHandle id) { // TODO(piman): view_ can only be NULL with delayed view creation in diff --git a/content/content_browser.gypi b/content/content_browser.gypi index bfc92d0..8da029e 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -238,7 +238,6 @@ 'browser/renderer_host/redirect_to_file_resource_handler.h', 'browser/renderer_host/render_message_filter.cc', 'browser/renderer_host/render_message_filter.h', - 'browser/renderer_host/render_message_filter_gtk.cc', 'browser/renderer_host/render_message_filter_win.cc', 'browser/renderer_host/render_process_host.cc', 'browser/renderer_host/render_process_host.h', diff --git a/ui/gfx/gtk_native_view_id_manager.cc b/ui/gfx/gtk_native_view_id_manager.cc index d2a3699..14105f8 100644 --- a/ui/gfx/gtk_native_view_id_manager.cc +++ b/ui/gfx/gtk_native_view_id_manager.cc @@ -86,7 +86,7 @@ bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) { base::AutoLock locked(lock_); std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i = - id_to_info_.find(id); + id_to_info_.find(id); if (i == id_to_info_.end()) return false; @@ -95,6 +95,20 @@ bool GtkNativeViewManager::GetXIDForId(XID* output, gfx::NativeViewId id) { return true; } +bool GtkNativeViewManager::GetNativeViewForId(gfx::NativeView* output, + gfx::NativeViewId id) { + base::AutoLock locked(lock_); + + std::map<gfx::NativeViewId, NativeViewInfo>::const_iterator i = + id_to_info_.find(id); + + if (i == id_to_info_.end()) + return false; + + *output = i->second.widget; + return true; +} + bool GtkNativeViewManager::GetPermanentXIDForId(XID* output, gfx::NativeViewId id) { base::AutoLock locked(lock_); @@ -197,7 +211,6 @@ void GtkNativeViewManager::OnRealize(gfx::NativeView widget) { } void GtkNativeViewManager::OnUnrealize(gfx::NativeView widget) { - base::AutoLock unrealize_locked(unrealize_lock_); base::AutoLock locked(lock_); const gfx::NativeViewId id = GetWidgetId(widget); diff --git a/ui/gfx/gtk_native_view_id_manager.h b/ui/gfx/gtk_native_view_id_manager.h index 6ea16a2..6b544ff 100644 --- a/ui/gfx/gtk_native_view_id_manager.h +++ b/ui/gfx/gtk_native_view_id_manager.h @@ -61,6 +61,11 @@ class GtkNativeViewManager { // |*xid| is set to 0. bool GetXIDForId(XID* xid, gfx::NativeViewId id); + // May be called from the UI thread: + // + // Same as GetXIDForId except it returns the NativeView (GtkWidget*). + bool GetNativeViewForId(gfx::NativeView* xid, gfx::NativeViewId id); + // Must be called from the UI thread because we may need the associated // widget to create a window. // @@ -90,8 +95,6 @@ class GtkNativeViewManager { void OnUnrealize(gfx::NativeView widget); void OnDestroy(gfx::NativeView widget); - base::Lock& unrealize_lock() { return unrealize_lock_; } - private: // This object is a singleton: GtkNativeViewManager(); @@ -107,11 +110,6 @@ class GtkNativeViewManager { gfx::NativeViewId GetWidgetId(gfx::NativeView id); - // This lock can be used to block GTK from unrealizing windows. This is needed - // when the BACKGROUND_X11 thread is using a window obtained via GetXIDForId, - // and can't allow the X11 resource to be deleted. - base::Lock unrealize_lock_; - // protects native_view_to_id_ and id_to_info_ base::Lock lock_; |