summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/plugin_process_host.cc3
-rw-r--r--chrome/browser/render_widget_host.cc5
-rw-r--r--chrome/browser/render_widget_host_view_win.cc62
-rw-r--r--chrome/browser/render_widget_host_view_win.h4
-rw-r--r--webkit/glue/plugins/plugin_constants_win.h13
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc24
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) {