diff options
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 3 | ||||
-rw-r--r-- | chrome/browser/render_widget_host.cc | 5 | ||||
-rw-r--r-- | chrome/browser/render_widget_host_view_win.cc | 62 | ||||
-rw-r--r-- | chrome/browser/render_widget_host_view_win.h | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_constants_win.h | 13 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.cc | 24 |
6 files changed, 83 insertions, 28 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 0362423..7c272a5 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -39,6 +39,7 @@ #include "net/proxy/proxy_service.h" #include "net/url_request/url_request.h" #include "sandbox/src/sandbox.h" +#include "webkit/glue/plugins/plugin_constants_win.h" static const char kDefaultPluginFinderURL[] = "http://dl.google.com/chrome/plugins/plugins2.xml"; @@ -389,7 +390,7 @@ class CreateWindowTask : public Task { wcex.hCursor = 0; wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1); wcex.lpszMenuName = 0; - wcex.lpszClassName = L"NativeWindowClassWrapper"; + wcex.lpszClassName = kWrapperNativeWindowClassName; wcex.hIconSm = 0; window_class = RegisterClassEx(&wcex); } diff --git a/chrome/browser/render_widget_host.cc b/chrome/browser/render_widget_host.cc index 9ce5f0a..fdbec92 100644 --- a/chrome/browser/render_widget_host.cc +++ b/chrome/browser/render_widget_host.cc @@ -448,10 +448,7 @@ void RenderWidgetHost::MovePluginWindows( } for (size_t i = 0; i < plugin_window_moves.size(); ++i) { - // Don't invalidate now because that would result in cross process calls - // that make scrolling slow. Instead the window is invalidated - // asynchronously by the plugin code. - unsigned long flags = SWP_NOREDRAW; + unsigned long flags = 0; const WebPluginGeometry& move = plugin_window_moves[i]; if (move.visible) diff --git a/chrome/browser/render_widget_host_view_win.cc b/chrome/browser/render_widget_host_view_win.cc index 0aa756d..251a8c7 100644 --- a/chrome/browser/render_widget_host_view_win.cc +++ b/chrome/browser/render_widget_host_view_win.cc @@ -24,6 +24,8 @@ #include "chrome/common/win_util.h" // Included for views::kReflectedMessage - TODO(beng): move this to win_util.h! #include "chrome/views/widget_win.h" +#include "webkit/glue/plugins/plugin_constants_win.h" +#include "webkit/glue/plugins/webplugin_delegate_impl.h" #include "webkit/glue/webcursor.h" using base::TimeDelta; @@ -259,22 +261,51 @@ void RenderWidgetHostViewWin::IMEUpdateStatus(ViewHostMsg_ImeControl control, } } -void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) { - if (is_hidden_) - return; +BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) { + if (!WebPluginDelegateImpl::IsPluginDelegateWindow(hwnd)) + return TRUE; - RECT invalid_rect = rect.ToRECT(); + gfx::Rect* rect = reinterpret_cast<gfx::Rect*>(lparam); + static UINT msg = RegisterWindowMessage(kPaintMessageName); + WPARAM wparam = rect->x() << 16 | rect->y(); + lparam = rect->width() << 16 | rect->height(); + // SendMessage gets the message across much quicker than PostMessage, since it + // doesn't get queued. When the plugin thread calls PeekMessage or other + // Win32 APIs, sent messages are dispatched automatically. + SendNotifyMessage(hwnd, msg, wparam, lparam); + + return TRUE; +} + +void RenderWidgetHostViewWin::Redraw(const gfx::Rect& rect) { // Paint the invalid region synchronously. Our caller will not paint again // until we return, so by painting to the screen here, we ensure effective // rate-limiting of backing store updates. This helps a lot on pages that // have animations or fairly expensive layout (e.g., google maps). // - // Please refer to the RenderWidgetHostViewWin::DidScrollRect function for the - // reasoning behind the combination of flags passed to RedrawWindow. + // We paint this window synchronously, however child windows (i.e. plugins) + // are painted asynchronously. By avoiding synchronous cross-process window + // message dispatching we allow scrolling to be smooth, and also avoid the + // browser process locking up if the plugin process is hung. // - RedrawWindow(&invalid_rect, NULL, - RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME); + RedrawWindow( + &rect.ToRECT(), NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN); + + // Send the invalid rect in screen coordinates. + gfx::Rect screen_rect = GetViewBounds(); + gfx::Rect invalid_screen_rect = rect; + invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y()); + + LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect); + EnumChildWindows(m_hWnd, EnumChildProc, lparam); +} + +void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) { + if (is_hidden_) + return; + + Redraw(rect); } void RenderWidgetHostViewWin::DidScrollRect( @@ -291,20 +322,7 @@ void RenderWidgetHostViewWin::DidScrollRect( RECT invalid_rect = {0}; GetUpdateRect(&invalid_rect); - - // Paint the invalid region synchronously. Our caller will not paint again - // until we return, so by painting to the screen here, we ensure effective - // rate-limiting of backing store updates. This helps a lot on pages that - // have animations or fairly expensive layout (e.g., google maps). - // - // Our RenderWidgetHostViewWin does not have a non-client area, whereas the - // children (plugin windows) may. If we don't pass in RDW_FRAME then the - // children don't receive WM_NCPAINT messages while scrolling, which causes - // painting problems (http://b/issue?id=923945). We need to pass - // RDW_INVALIDATE as it is required for RDW_FRAME to work. - // - RedrawWindow(&invalid_rect, NULL, - RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME); + Redraw(gfx::Rect(invalid_rect)); } void RenderWidgetHostViewWin::RendererGone() { diff --git a/chrome/browser/render_widget_host_view_win.h b/chrome/browser/render_widget_host_view_win.h index bbf6e63..91b3684 100644 --- a/chrome/browser/render_widget_host_view_win.h +++ b/chrome/browser/render_widget_host_view_win.h @@ -209,6 +209,10 @@ class RenderWidgetHostViewWin : // invoke it from the message loop. void ShutdownHost(); + // Redraws the window synchronously, and any child windows (i.e. plugins) + // asynchronously. + void Redraw(const gfx::Rect& invalid_rect); + // The associated Model. RenderWidgetHost* render_widget_host_; diff --git a/webkit/glue/plugins/plugin_constants_win.h b/webkit/glue/plugins/plugin_constants_win.h index 9b91335..170ae62 100644 --- a/webkit/glue/plugins/plugin_constants_win.h +++ b/webkit/glue/plugins/plugin_constants_win.h @@ -20,4 +20,17 @@ #define kActiveXShimFileNameForMediaPlayer \ L"Microsoft\xAE Windows Media Player Firefox Plugin" + +// The window class name for a plugin window. +#define kNativeWindowClassName L"NativeWindowClass" + +// The name of the window class name for the wrapper HWND around the actual +// plugin window that's used when running in multi-process mode. This window +// is created on the browser UI thread. +#define kWrapperNativeWindowClassName L"WrapperNativeWindowClass" + +// The name of the custom window message that the browser uses to tell the +// plugin process to paint a window. +#define kPaintMessageName L"Chrome_CustomPaint" + #endif // WEBKIT_GLUE_PLUGIN_PLUGIN_LIST_H_ diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc index a0de8da..3abcbd6 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl.cc @@ -14,6 +14,7 @@ #include "webkit/default_plugin/plugin_impl.h" #include "webkit/glue/glue_util.h" #include "webkit/glue/webplugin.h" +#include "webkit/glue/plugins/plugin_constants_win.h" #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/plugins/plugin_lib.h" #include "webkit/glue/plugins/plugin_list.h" @@ -22,7 +23,6 @@ static StatsCounter windowless_queue("Plugin.ThrottleQueue"); -static const wchar_t kNativeWindowClassName[] = L"NativeWindowClass"; static const wchar_t kWebPluginDelegateProperty[] = L"WebPluginDelegateProperty"; static const wchar_t kPluginNameAtomProperty[] = L"PluginNameAtom"; @@ -793,6 +793,28 @@ LRESULT CALLBACK WebPluginDelegateImpl::NativeWndProc( return TRUE; } + static UINT custom_msg = RegisterWindowMessage(kPaintMessageName); + if (message == custom_msg) { + // Get the invalid rect which is in screen coordinates and convert to + // window coordinates. + gfx::Rect invalid_rect; + invalid_rect.set_x(wparam >> 16); + invalid_rect.set_y(wparam & 0xFFFF); + invalid_rect.set_width(lparam >> 16); + invalid_rect.set_height(lparam & 0xFFFF); + + RECT window_rect; + GetWindowRect(hwnd, &window_rect); + invalid_rect.Offset(-window_rect.left, -window_rect.top); + + // The plugin window might have non-client area. If we don't pass in + // RDW_FRAME then the children don't receive WM_NCPAINT messages while + // scrolling, which causes painting problems (http://b/issue?id=923945). + RedrawWindow(hwnd, &invalid_rect.ToRECT(), NULL, + RDW_UPDATENOW | RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_FRAME); + return FALSE; + } + current_plugin_instance_ = delegate; switch (message) { |