diff options
-rw-r--r-- | chrome/plugin/webplugin_proxy.cc | 28 | ||||
-rw-r--r-- | chrome/plugin/webplugin_proxy.h | 5 | ||||
-rw-r--r-- | webkit/glue/cpp_bound_class_unittest.cc | 2 | ||||
-rw-r--r-- | webkit/glue/webplugin_impl.cc | 2 | ||||
-rw-r--r-- | webkit/glue/webplugin_impl.h | 3 | ||||
-rw-r--r-- | webkit/port/bindings/v8/v8_np_utils.cpp | 5 |
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()) { |