summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/plugin/webplugin_proxy.cc28
-rw-r--r--chrome/plugin/webplugin_proxy.h5
-rw-r--r--webkit/glue/cpp_bound_class_unittest.cc2
-rw-r--r--webkit/glue/webplugin_impl.cc2
-rw-r--r--webkit/glue/webplugin_impl.h3
-rw-r--r--webkit/port/bindings/v8/v8_np_utils.cpp5
6 files changed, 35 insertions, 10 deletions
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 2cbb3ee..255c843 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -34,7 +34,9 @@ WebPluginProxy::WebPluginProxy(
window_npobject_(NULL),
plugin_element_(NULL),
delegate_(delegate),
- waiting_for_paint_(false) {
+ waiting_for_paint_(false),
+#pragma warning(suppress: 4355) // can use this
+ runnable_method_factory_(this) {
HANDLE event;
BOOL result = DuplicateHandle(channel->renderer_handle(),
@@ -84,21 +86,22 @@ void WebPluginProxy::Invalidate() {
}
void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) {
+ damaged_rect_ = damaged_rect_.Union(rect);
// Ignore NPN_InvalidateRect calls with empty rects. Also don't send an
// invalidate if it's outside the clipping region, since if we did it won't
// lead to a paint and we'll be stuck waiting forever for a DidPaint response.
if (rect.IsEmpty() || !delegate_->clip_rect().Intersects(rect))
return;
- damaged_rect_ = damaged_rect_.Union(rect);
// Only send a single InvalidateRect message at a time. From DidPaint we
// will dispatch an additional InvalidateRect message if necessary.
if (!waiting_for_paint_) {
waiting_for_paint_ = true;
- // Paint to the plugin bitmap and let the renderer know so it can update
- // its backing store.
- Paint(damaged_rect_);
- Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect_));
+ // Invalidates caused by calls to NPN_InvalidateRect/NPN_InvalidateRgn
+ // need to be painted asynchronously as per the NPAPI spec.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ runnable_method_factory_.NewRunnableMethod(
+ &WebPluginProxy::OnPaint, damaged_rect_));
damaged_rect_ = gfx::Rect();
}
}
@@ -282,6 +285,8 @@ void WebPluginProxy::UpdateGeometry(
const base::SharedMemoryHandle& windowless_buffer,
const base::SharedMemoryHandle& background_buffer) {
gfx::Rect old = delegate_->rect();
+ gfx::Rect old_clip_rect = delegate_->clip_rect();
+
bool moved = delegate_->rect().x() != window_rect.x() ||
delegate_->rect().y() != window_rect.y();
delegate_->UpdateGeometry(window_rect, clip_rect, cutout_rects, visible);
@@ -292,6 +297,12 @@ void WebPluginProxy::UpdateGeometry(
// The plugin moved, so update our world transform.
UpdateTransform();
}
+ // Send over any pending invalidates which occured when the plugin was
+ // off screen.
+ if (visible && delegate_->windowless() && !clip_rect.IsEmpty() &&
+ old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) {
+ InvalidateRect(damaged_rect_);
+ }
}
void WebPluginProxy::SetWindowlessBuffer(
@@ -376,3 +387,8 @@ void WebPluginProxy::InitiateHTTPRangeRequest(const char* url,
range_info, existing_stream,
notify_needed, notify_data));
}
+
+void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) {
+ Paint(damaged_rect);
+ Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect));
+}
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index e6a231d..c2cefc7 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -108,6 +108,9 @@ class WebPluginProxy : public WebPlugin {
ScopedBitmap* bitmap,
ScopedHDC* hdc);
+ // Handler for sending over the paint event to the plugin.
+ void OnPaint(const gfx::Rect& damaged_rect);
+
// Called when a plugin's origin moves, so that we can update the world
// transform of the local HDC.
void UpdateTransform();
@@ -137,6 +140,8 @@ class WebPluginProxy : public WebPlugin {
ScopedHandle background_shared_section_;
ScopedBitmap background_bitmap_;
ScopedHDC background_hdc_;
+
+ ScopedRunnableMethodFactory<WebPluginProxy> runnable_method_factory_;
};
#endif // CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__
diff --git a/webkit/glue/cpp_bound_class_unittest.cc b/webkit/glue/cpp_bound_class_unittest.cc
index d57604a..73b118f2 100644
--- a/webkit/glue/cpp_bound_class_unittest.cc
+++ b/webkit/glue/cpp_bound_class_unittest.cc
@@ -194,7 +194,7 @@ TEST_F(CppBoundClassTest, InvokeMethods) {
"example.echoValue()", "null", // Too few arguments
"example.echoType(false)", "true",
- "example.echoType(19)", "3.14159",
+ "example.echoType(19)", "7",
"example.echoType(9.876)", "3.14159",
"example.echoType('test string')", "'Success!'",
"example.echoType()", "null", // Too few arguments
diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc
index 5edcae4..4d915cc 100644
--- a/webkit/glue/webplugin_impl.cc
+++ b/webkit/glue/webplugin_impl.cc
@@ -656,7 +656,7 @@ void WebPluginImpl::setFrameRect(const WebCore::IntRect& rect) {
delegate_->UpdateGeometry(
webkit_glue::FromIntRect(window_rect),
webkit_glue::FromIntRect(clip_rect), cutout_rects,
- received_first_paint_notification_? visible_ : false);
+ windowless_ || received_first_paint_notification_ ? visible_ : false);
// delegate_ can go away as a result of above call, so check it first.
if (force_geometry_update_ && delegate_) {
diff --git a/webkit/glue/webplugin_impl.h b/webkit/glue/webplugin_impl.h
index e16f1b6..3cc60ed 100644
--- a/webkit/glue/webplugin_impl.h
+++ b/webkit/glue/webplugin_impl.h
@@ -305,7 +305,8 @@ class WebPluginImpl : public WebPlugin,
WebPluginDelegate* delegate_;
bool force_geometry_update_;
bool visible_;
- // Set when we receive the first paint notification for the plugin widget.
+ // Set when we receive the first paint notification for a windowed
+ // plugin widget.
bool received_first_paint_notification_;
WebPluginContainer* widget_;
diff --git a/webkit/port/bindings/v8/v8_np_utils.cpp b/webkit/port/bindings/v8/v8_np_utils.cpp
index 287d268..74f5bd6 100644
--- a/webkit/port/bindings/v8/v8_np_utils.cpp
+++ b/webkit/port/bindings/v8/v8_np_utils.cpp
@@ -53,7 +53,10 @@ void ConvertV8ObjectToNPVariant(v8::Local<v8::Value> object, NPObject *owner,
if (object.IsEmpty()) return;
- if (object->IsNumber()) {
+ if (object->IsInt32()) {
+ INT32_TO_NPVARIANT(object->NumberValue(), *result);
+
+ } else if (object->IsNumber()) {
DOUBLE_TO_NPVARIANT(object->NumberValue(), *result);
} else if (object->IsBoolean()) {