summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/plugin_process_host.cc94
-rw-r--r--chrome/browser/plugin_process_host.h3
-rw-r--r--chrome/browser/render_widget_host.cc8
-rw-r--r--chrome/common/plugin_messages_internal.h13
-rw-r--r--chrome/plugin/webplugin_delegate_stub.cc5
-rw-r--r--chrome/plugin/webplugin_delegate_stub.h2
-rw-r--r--chrome/plugin/webplugin_proxy.cc39
-rw-r--r--chrome/plugin/webplugin_proxy.h3
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc11
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h6
-rw-r--r--webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc3
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc89
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h23
-rw-r--r--webkit/glue/webplugin_delegate.h8
-rw-r--r--webkit/glue/webplugin_impl.cc87
-rw-r--r--webkit/glue/webplugin_impl.h6
-rw-r--r--webkit/tools/test_shell/test_webview_delegate.cc30
17 files changed, 237 insertions, 193 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index 4607b2a..50ca1b9 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -347,6 +347,86 @@ class PluginResolveProxyHelper : RevocableStore::Revocable {
};
+// Sends the reply to the create window message on the IO thread.
+class SendReplyTask : public Task {
+ public:
+ SendReplyTask(FilePath plugin_path, IPC::Message* reply_msg)
+ : plugin_path_(plugin_path), reply_msg_(reply_msg) { }
+
+ virtual void Run() {
+ PluginProcessHost* plugin =
+ PluginService::GetInstance()->FindPluginProcess(plugin_path_);
+ if (!plugin)
+ return;
+
+ plugin->Send(reply_msg_);
+ }
+
+ private:
+ FilePath plugin_path_;
+ IPC::Message* reply_msg_;
+};
+
+
+// Creates a child window of the given HWND on the UI thread.
+class CreateWindowTask : public Task {
+ public:
+ CreateWindowTask(
+ FilePath plugin_path, HWND parent, IPC::Message* reply_msg)
+ : plugin_path_(plugin_path), parent_(parent), reply_msg_(reply_msg) { }
+
+ virtual void Run() {
+ static ATOM window_class = 0;
+ if (!window_class) {
+ WNDCLASSEX wcex;
+ wcex.cbSize = sizeof(WNDCLASSEX);
+ wcex.style = CS_DBLCLKS;
+ wcex.lpfnWndProc = DefWindowProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = 0;
+ wcex.hInstance = GetModuleHandle(NULL);
+ wcex.hIcon = 0;
+ wcex.hCursor = 0;
+ wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
+ wcex.lpszMenuName = 0;
+ wcex.lpszClassName = L"NativeWindowClassWrapper";
+ wcex.hIconSm = 0;
+ window_class = RegisterClassEx(&wcex);
+ }
+
+ HWND window = CreateWindowEx(
+ WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
+ MAKEINTATOM(window_class), 0,
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
+ 0, 0, 0, 0, parent_, 0, GetModuleHandle(NULL), 0);
+
+ PluginProcessHostMsg_CreateWindow::WriteReplyParams(
+ reply_msg_, window);
+
+ g_browser_process->io_thread()->message_loop()->PostTask(
+ FROM_HERE, new SendReplyTask(plugin_path_, reply_msg_));
+ }
+
+ private:
+ FilePath plugin_path_;
+ HWND parent_;
+ IPC::Message* reply_msg_;
+};
+
+// Destroys the given window on the UI thread.
+class DestroyWindowTask : public Task {
+ public:
+ DestroyWindowTask(HWND window) : window_(window) { }
+
+ virtual void Run() {
+ DestroyWindow(window_);
+ }
+
+ private:
+ HWND window_;
+};
+
+
PluginProcessHost::PluginProcessHost(PluginService* plugin_service)
: process_(NULL),
opening_channel_(false),
@@ -580,6 +660,9 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(PluginProcessHostMsg_GetCookies, OnGetCookies)
IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_ResolveProxy,
OnResolveProxy)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginProcessHostMsg_CreateWindow,
+ OnCreateWindow)
+ IPC_MESSAGE_HANDLER(PluginProcessHostMsg_DestroyWindow, OnDestroyWindow)
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
@@ -839,6 +922,17 @@ void PluginProcessHost::OnGetPluginDataDir(std::wstring* retval) {
*retval = plugin_service_->GetChromePluginDataDir();
}
+void PluginProcessHost::OnCreateWindow(HWND parent, IPC::Message* reply_msg) {
+ // Need to create this window on the UI thread.
+ plugin_service_->main_message_loop()->PostTask(FROM_HERE,
+ new CreateWindowTask(plugin_path_, parent, reply_msg));
+}
+
+void PluginProcessHost::OnDestroyWindow(HWND window) {
+ plugin_service_->main_message_loop()->PostTask(FROM_HERE,
+ new DestroyWindowTask(window));
+}
+
void PluginProcessHost::Shutdown() {
Send(new PluginProcessMsg_BrowserShutdown);
diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h
index 713c2d4..24737fc 100644
--- a/chrome/browser/plugin_process_host.h
+++ b/chrome/browser/plugin_process_host.h
@@ -111,10 +111,11 @@ class PluginProcessHost : public IPC::Channel::Listener,
void OnGetCookies(uint32 request_context, const GURL& url,
std::string* cookies);
void OnResolveProxy(const GURL& url, IPC::Message* reply_msg);
-
void OnPluginShutdownRequest();
void OnPluginMessage(const std::vector<uint8>& data);
void OnGetPluginDataDir(std::wstring* retval);
+ void OnCreateWindow(HWND parent, IPC::Message* reply_msg);
+ void OnDestroyWindow(HWND window);
struct ChannelRequest {
ChannelRequest(ResourceMessageFilter* renderer_message_filter,
diff --git a/chrome/browser/render_widget_host.cc b/chrome/browser/render_widget_host.cc
index 2823cba..9ce5f0a 100644
--- a/chrome/browser/render_widget_host.cc
+++ b/chrome/browser/render_widget_host.cc
@@ -436,6 +436,9 @@ void RenderWidgetHost::OnMsgScrollRect(
void RenderWidgetHost::MovePluginWindows(
const std::vector<WebPluginGeometry>& plugin_window_moves) {
+ if (plugin_window_moves.empty())
+ return;
+
HDWP defer_window_pos_info =
::BeginDeferWindowPos(static_cast<int>(plugin_window_moves.size()));
@@ -445,7 +448,10 @@ void RenderWidgetHost::MovePluginWindows(
}
for (size_t i = 0; i < plugin_window_moves.size(); ++i) {
- unsigned long flags = 0;
+ // 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;
const WebPluginGeometry& move = plugin_window_moves[i];
if (move.visible)
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index d78bb5e..1d9380c 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -81,6 +81,15 @@ IPC_BEGIN_MESSAGES(PluginProcessHost, 4)
int /* network error */,
std::string /* proxy list */)
+ // Creates a child window of the given parent window on the UI thread.
+ IPC_SYNC_MESSAGE_CONTROL1_1(PluginProcessHostMsg_CreateWindow,
+ HWND /* parent */,
+ HWND /* child */)
+
+ // Destroys the given window on the UI thread.
+ IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_DestroyWindow,
+ HWND /* window */)
+
IPC_END_MESSAGES(PluginProcessHost)
@@ -131,11 +140,9 @@ IPC_BEGIN_MESSAGES(Plugin, 5)
// contains a buffer that the plugin draws into. background_buffer is used
// for transparent windowless plugins, and holds the background of the plugin
// rectangle.
- IPC_MESSAGE_ROUTED6(PluginMsg_UpdateGeometry,
+ IPC_MESSAGE_ROUTED4(PluginMsg_UpdateGeometry,
gfx::Rect /* window_rect */,
gfx::Rect /* clip_rect */,
- std::vector<gfx::Rect> /* cutout_rects */,
- bool /* visible */,
base::SharedMemoryHandle /* windowless_buffer */,
base::SharedMemoryHandle /* background_buffer */)
diff --git a/chrome/plugin/webplugin_delegate_stub.cc b/chrome/plugin/webplugin_delegate_stub.cc
index 6d9cfe6..28c0e63 100644
--- a/chrome/plugin/webplugin_delegate_stub.cc
+++ b/chrome/plugin/webplugin_delegate_stub.cc
@@ -239,13 +239,10 @@ void WebPluginDelegateStub::OnPrint(PluginMsg_PrintResponse_Params* params) {
void WebPluginDelegateStub::OnUpdateGeometry(
const gfx::Rect& window_rect,
const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible,
const base::SharedMemoryHandle& windowless_buffer,
const base::SharedMemoryHandle& background_buffer) {
webplugin_->UpdateGeometry(
- window_rect, clip_rect, cutout_rects, visible, windowless_buffer,
- background_buffer);
+ window_rect, clip_rect, windowless_buffer, background_buffer);
}
void WebPluginDelegateStub::OnGetPluginScriptableObject(int* route_id,
diff --git a/chrome/plugin/webplugin_delegate_stub.h b/chrome/plugin/webplugin_delegate_stub.h
index 8b49991..1cc21631 100644
--- a/chrome/plugin/webplugin_delegate_stub.h
+++ b/chrome/plugin/webplugin_delegate_stub.h
@@ -65,8 +65,6 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
void OnUpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible,
const base::SharedMemoryHandle& windowless_buffer,
const base::SharedMemoryHandle& background_buffer);
void OnGetPluginScriptableObject(int* route_id, void** npobject_ptr);
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 02bd802..7302cbe 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -12,10 +12,11 @@
#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/common/win_util.h"
-#include "chrome/plugin/plugin_channel.h"
-#include "chrome/plugin/webplugin_delegate_stub.h"
#include "chrome/plugin/npobject_proxy.h"
#include "chrome/plugin/npobject_util.h"
+#include "chrome/plugin/plugin_channel.h"
+#include "chrome/plugin/plugin_thread.h"
+#include "chrome/plugin/webplugin_delegate_stub.h"
#include "skia/ext/platform_device.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
@@ -37,7 +38,8 @@ WebPluginProxy::WebPluginProxy(
delegate_(delegate),
waiting_for_paint_(false),
#pragma warning(suppress: 4355) // can use this
- runnable_method_factory_(this) {
+ runnable_method_factory_(this),
+ parent_window_(NULL) {
HANDLE event;
BOOL result = DuplicateHandle(channel->renderer_handle(),
@@ -54,6 +56,11 @@ WebPluginProxy::WebPluginProxy(
WebPluginProxy::~WebPluginProxy() {
if (cp_browsing_context_)
GetContextMap().erase(cp_browsing_context_);
+
+ if (parent_window_) {
+ PluginThread::GetPluginThread()->Send(
+ new PluginProcessHostMsg_DestroyWindow(parent_window_));
+ }
}
bool WebPluginProxy::Send(IPC::Message* msg) {
@@ -70,6 +77,26 @@ void WebPluginProxy::SetWindow(HWND window, HANDLE pump_messages_event) {
&pump_messages_event_for_renderer,
0, FALSE, DUPLICATE_SAME_ACCESS);
DCHECK(pump_messages_event_for_renderer != NULL);
+ } else {
+ DCHECK (window);
+ // To make scrolling windowed plugins fast, we create the page's direct
+ // child windows in the browser process. This way no cross process messages
+ // are sent.
+ HWND old_parent = GetParent(window);
+ IPC::SyncMessage* msg = new PluginProcessHostMsg_CreateWindow(
+ old_parent, &parent_window_);
+
+ // Need to process window messages in the meantime to avoid a deadlock if
+ // the browser paints or sends any other (synchronous) WM_ message to the
+ // plugin window.
+ msg->EnableMessagePumping();
+ PluginThread::GetPluginThread()->Send(msg);
+
+ SetParent(window, parent_window_);
+
+ // We want the browser process to move this window which has a message loop
+ // in its process.
+ window = parent_window_;
}
Send(new PluginHostMsg_SetWindow(route_id_, window,
@@ -295,8 +322,6 @@ void WebPluginProxy::Paint(const gfx::Rect& rect) {
void WebPluginProxy::UpdateGeometry(
const gfx::Rect& window_rect,
const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible,
const base::SharedMemoryHandle& windowless_buffer,
const base::SharedMemoryHandle& background_buffer) {
gfx::Rect old = delegate_->rect();
@@ -304,7 +329,7 @@ void WebPluginProxy::UpdateGeometry(
bool moved = delegate_->rect().x() != window_rect.x() ||
delegate_->rect().y() != window_rect.y();
- delegate_->UpdateGeometry(window_rect, clip_rect, cutout_rects, visible);
+ delegate_->UpdateGeometry(window_rect, clip_rect);
if (windowless_buffer) {
// The plugin's rect changed, so now we have a new buffer to draw into.
SetWindowlessBuffer(windowless_buffer, background_buffer);
@@ -314,7 +339,7 @@ void WebPluginProxy::UpdateGeometry(
}
// Send over any pending invalidates which occured when the plugin was
// off screen.
- if (visible && delegate_->windowless() && !clip_rect.IsEmpty() &&
+ if (delegate_->windowless() && !clip_rect.IsEmpty() &&
old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) {
InvalidateRect(damaged_rect_);
}
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index 7828abf..9f6177b 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -86,8 +86,6 @@ class WebPluginProxy : public WebPlugin {
void UpdateGeometry(const gfx::Rect& window_rect,
const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible,
const base::SharedMemoryHandle& windowless_buffer,
const base::SharedMemoryHandle& background_buffer);
@@ -132,6 +130,7 @@ class WebPluginProxy : public WebPlugin {
bool waiting_for_paint_;
uint32 cp_browsing_context_;
scoped_ptr<base::WaitableEvent> modal_dialog_event_;
+ HWND parent_window_;
// Variables used for desynchronized windowless plugin painting. See note in
// webplugin_delegate_proxy.h for how this works.
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index f4c61a2..a13053b 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -152,7 +152,6 @@ WebPluginDelegateProxy::WebPluginDelegateProxy(const std::string& mime_type,
windowless_(false),
npobject_(NULL),
send_deferred_update_geometry_(false),
- visible_(false),
sad_plugin_(NULL),
window_script_object_(NULL),
transparent_(false),
@@ -196,8 +195,6 @@ void WebPluginDelegateProxy::FlushGeometryUpdates() {
Send(new PluginMsg_UpdateGeometry(instance_id_,
plugin_rect_,
deferred_clip_rect_,
- deferred_cutout_rects_,
- visible_,
NULL,
NULL));
}
@@ -350,14 +347,10 @@ void WebPluginDelegateProxy::OnChannelError() {
void WebPluginDelegateProxy::UpdateGeometry(
const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible) {
+ const gfx::Rect& clip_rect) {
plugin_rect_ = window_rect;
if (!windowless_) {
deferred_clip_rect_ = clip_rect;
- deferred_cutout_rects_ = cutout_rects;
- visible_ = visible;
send_deferred_update_geometry_ = true;
return;
}
@@ -387,7 +380,7 @@ void WebPluginDelegateProxy::UpdateGeometry(
}
IPC::Message* msg = new PluginMsg_UpdateGeometry(
- instance_id_, window_rect, clip_rect, cutout_rects, visible,
+ instance_id_, window_rect, clip_rect,
transport_store_handle, background_store_handle);
msg->set_unblock(true);
Send(msg);
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index 521b763..65b1edb 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -56,9 +56,7 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
virtual bool Initialize(const GURL& url, char** argn, char** argv, int argc,
WebPlugin* plugin, bool load_manually);
virtual void UpdateGeometry(const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible);
+ const gfx::Rect& clip_rect);
virtual void Paint(HDC hdc, const gfx::Rect& rect);
virtual void Print(HDC hdc);
virtual NPObject* GetPluginScriptableObject();
@@ -162,9 +160,7 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
gfx::Rect plugin_rect_;
gfx::Rect deferred_clip_rect_;
- std::vector<gfx::Rect> deferred_cutout_rects_;
bool send_deferred_update_geometry_;
- bool visible_;
NPObject* npobject_;
NPObjectStub* window_script_object_;
diff --git a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc
index 8f3a89f..2907a5e 100644
--- a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc
+++ b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc
@@ -113,9 +113,6 @@ NPObjectDeletePluginInNPN_Evaluate::~NPObjectDeletePluginInNPN_Evaluate() {
}
NPError NPObjectDeletePluginInNPN_Evaluate::SetWindow(NPWindow* np_window) {
- if (!::IsWindowVisible(reinterpret_cast<HWND>(np_window->window)))
- return NPERR_NO_ERROR;
-
HWND window_handle = reinterpret_cast<HWND>(np_window->window);
// We setup a timerproc to invoke NPN_Evaluate to destroy this plugin
// instance. This is to ensure that we don't destroy the plugin instance
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc
index 0f713d7..a0de8da 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl.cc
@@ -9,8 +9,6 @@
#include "base/file_util.h"
#include "base/message_loop.h"
-#include "base/gfx/gdi_util.h"
-#include "base/gfx/point.h"
#include "base/stats_counters.h"
#include "base/string_util.h"
#include "webkit/default_plugin/plugin_impl.h"
@@ -133,7 +131,6 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
plugin_wnd_proc_(NULL),
last_message_(0),
is_calling_wndproc(false),
- initial_plugin_resize_done_(false),
dummy_window_for_activation_(NULL),
handle_event_message_filter_hook_(NULL),
handle_event_pump_messages_event_(NULL),
@@ -322,13 +319,11 @@ void WebPluginDelegateImpl::DestroyInstance() {
void WebPluginDelegateImpl::UpdateGeometry(
const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible) {
+ const gfx::Rect& clip_rect) {
if (windowless_) {
WindowlessUpdateGeometry(window_rect, clip_rect);
} else {
- WindowedUpdateGeometry(window_rect, clip_rect, cutout_rects, visible);
+ WindowedUpdateGeometry(window_rect, clip_rect);
}
}
@@ -377,6 +372,12 @@ void WebPluginDelegateImpl::SendJavaScriptStream(const std::string& url,
void WebPluginDelegateImpl::DidReceiveManualResponse(
const std::string& url, const std::string& mime_type,
const std::string& headers, uint32 expected_length, uint32 last_modified) {
+ if (!windowless_) {
+ // Calling NPP_WriteReady before NPP_SetWindow causes movies to not load in
+ // Flash. See http://b/issue?id=892174.
+ DCHECK(windowed_did_set_window_);
+ }
+
instance()->DidReceiveManualResponse(url, mime_type, headers,
expected_length, last_modified);
}
@@ -408,10 +409,8 @@ void WebPluginDelegateImpl::InstallMissingPlugin() {
void WebPluginDelegateImpl::WindowedUpdateGeometry(
const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible) {
- if (WindowedReposition(window_rect, clip_rect, cutout_rects, visible) ||
+ const gfx::Rect& clip_rect) {
+ if (WindowedReposition(window_rect, clip_rect) ||
!windowed_did_set_window_) {
// Let the plugin know that it has been moved
WindowedSetWindow();
@@ -663,69 +662,33 @@ bool WebPluginDelegateImpl::CreateDummyWindowForActivation() {
return true;
}
-void WebPluginDelegateImpl::MoveWindow(
- HWND window,
- const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible) {
- HRGN hrgn = ::CreateRectRgn(clip_rect.x(),
- clip_rect.y(),
- clip_rect.right(),
- clip_rect.bottom());
- gfx::SubtractRectanglesFromRegion(hrgn, cutout_rects);
-
- // Note: System will own the hrgn after we call SetWindowRgn,
- // so we don't need to call DeleteObject(hrgn)
- ::SetWindowRgn(window, hrgn, FALSE);
-
- unsigned long flags = 0;
- if (visible)
- flags |= SWP_SHOWWINDOW;
- else
- flags |= SWP_HIDEWINDOW;
-
- ::SetWindowPos(window,
- NULL,
- window_rect.x(),
- window_rect.y(),
- window_rect.width(),
- window_rect.height(),
- flags);
-}
-
bool WebPluginDelegateImpl::WindowedReposition(
const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible) {
+ const gfx::Rect& clip_rect) {
if (!windowed_handle_) {
NOTREACHED();
return false;
}
- if (window_rect_ == window_rect && clip_rect_ == clip_rect &&
- cutout_rects == cutout_rects_ &&
- initial_plugin_resize_done_)
+ if (window_rect_ == window_rect && clip_rect_ == clip_rect)
return false;
+ // Clipping is handled by WebPlugin.
+ if (window_rect.size() != window_rect_.size()) {
+ ::SetWindowPos(windowed_handle_,
+ NULL,
+ 0,
+ 0,
+ window_rect.width(),
+ window_rect.height(),
+ SWP_SHOWWINDOW);
+ }
+
window_rect_ = window_rect;
clip_rect_ = clip_rect;
- cutout_rects_ = cutout_rects;
-
- if (!initial_plugin_resize_done_) {
- // We need to ensure that the plugin process continues to reposition
- // the plugin window until we receive an indication that it is now visible.
- // Subsequent repositions will be done by the browser.
- if (visible)
- initial_plugin_resize_done_ = true;
- // We created the window with 0 width and height since we didn't know it
- // at the time. Now that we know the geometry, we we can update its size
- // since the browser only calls SetWindowPos when scrolling occurs.
- MoveWindow(windowed_handle_, window_rect, clip_rect, cutout_rects, visible);
- // Ensure that the entire window gets repainted.
- ::InvalidateRect(windowed_handle_, NULL, FALSE);
- }
+
+ // Ensure that the entire window gets repainted.
+ ::InvalidateRect(windowed_handle_, NULL, FALSE);
return true;
}
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index 468d3c7..d01046c 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -44,9 +44,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
WebPlugin* plugin,
bool load_manually);
virtual void UpdateGeometry(const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible);
+ const gfx::Rect& clip_rect);
virtual void Paint(HDC hdc, const gfx::Rect& rect);
virtual void Print(HDC hdc);
virtual void SetFocus(); // only called when windowless
@@ -99,12 +97,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
int quirks() { return quirks_; }
- static void MoveWindow(HWND window,
- const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible);
-
private:
WebPluginDelegateImpl(gfx::NativeView containing_view,
NPAPI::PluginInstance *instance);
@@ -113,9 +105,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
//--------------------------
// used for windowed plugins
void WindowedUpdateGeometry(const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible);
+ const gfx::Rect& clip_rect);
// Create the native window.
// Returns true if the window is created (or already exists).
// Returns false if unable to create the window.
@@ -127,9 +117,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
// Reposition the native window to be in sync with the given geometry.
// Returns true if the native window has moved or been clipped differently.
bool WindowedReposition(const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible);
+ const gfx::Rect& clip_rect);
// Tells the plugin about the current state of the window.
// See NPAPI NPP_SetWindow for more information.
@@ -202,11 +190,6 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
std::vector<gfx::Rect> cutout_rects_;
int quirks_;
- // We only move/size the plugin window once after its creation. The
- // rest of the moves are controlled by the browser. This flag controls
- // this behaviour.
- bool initial_plugin_resize_done_;
-
// Windowless plugins don't have keyboard focus causing issues with the
// plugin not receiving keyboard events if the plugin enters a modal
// loop like TrackPopupMenuEx or MessageBox, etc.
diff --git a/webkit/glue/webplugin_delegate.h b/webkit/glue/webplugin_delegate.h
index bfa462a..7ffd952 100644
--- a/webkit/glue/webplugin_delegate.h
+++ b/webkit/glue/webplugin_delegate.h
@@ -48,13 +48,9 @@ class WebPluginDelegate {
// plugin, relative to its containing window, to the coords given by
// window_rect. Its contents should be clipped to the coords given
// by clip_rect, which are relative to the origin of the plugin
- // window. It's contents should also not overlap the given cutout
- // rects. The clip_rect and cutout_rects are in plugin-relative
- // coordinates.
+ // window. The clip_rect is in plugin-relative coordinates.
virtual void UpdateGeometry(const gfx::Rect& window_rect,
- const gfx::Rect& clip_rect,
- const std::vector<gfx::Rect>& cutout_rects,
- bool visible) = 0;
+ const gfx::Rect& clip_rect) = 0;
// Tells the plugin to paint the damaged rect. The HDC is only used for
// windowless plugins.
diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc
index 003ece7..72234ad 100644
--- a/webkit/glue/webplugin_impl.cc
+++ b/webkit/glue/webplugin_impl.cc
@@ -134,6 +134,11 @@ bool WebPluginContainer::isPluginView() const {
void WebPluginContainer::setFrameRect(const WebCore::IntRect& rect) {
+ // WebKit calls move every time it paints (see RenderWidget::paint). No need
+ // to do expensive operations if we didn't actually move.
+ if (rect == frameRect())
+ return;
+
WebCore::Widget::setFrameRect(rect);
impl_->setFrameRect(rect);
}
@@ -166,12 +171,8 @@ void WebPluginContainer::setFocus() {
void WebPluginContainer::show() {
// We don't want to force a geometry update when the plugin widget is
// already visible as this involves a geometry update which may lead
- // to unnecessary window moves in the plugin process. The only case
- // where this does not apply is if the force_geometry_update_ flag
- // is set, which occurs when a plugin is created and does not have
- // a parent. We can send out geometry updates only when the plugin
- // widget has a parent.
- if (!impl_->visible_ || impl_->force_geometry_update_) {
+ // to unnecessary window moves in the plugin process.
+ if (!impl_->visible_) {
impl_->show();
WebCore::Widget::show();
// This is to force an updategeometry call to the plugin process
@@ -181,9 +182,7 @@ void WebPluginContainer::show() {
}
void WebPluginContainer::hide() {
- // Please refer to WebPluginContainer::show for the reasoning behind
- // the if check below.
- if (impl_->visible_ || impl_->force_geometry_update_) {
+ if (impl_->visible_) {
impl_->hide();
WebCore::Widget::hide();
// This is to force an updategeometry call to the plugin process
@@ -216,6 +215,18 @@ void WebPluginContainer::setParentVisible(bool visible) {
hide();
}
+// We override this function so that if the plugin is windowed, we can call
+// NPP_SetWindow at the first possible moment. This ensures that NPP_SetWindow
+// is called before the manual load data is sent to a plugin. If this order is
+// reversed, Flash won't load videos.
+void WebPluginContainer::setParent(WebCore::ScrollView* view) {
+ WebCore::Widget::setParent(view);
+ if (view) {
+ impl_->setFrameRect(frameRect());
+ impl_->delegate_->FlushGeometryUpdates();
+ }
+}
+
void WebPluginContainer::windowCutoutRects(const WebCore::IntRect& bounds,
WTF::Vector<WebCore::IntRect>*
cutouts) const {
@@ -224,7 +235,6 @@ void WebPluginContainer::windowCutoutRects(const WebCore::IntRect& bounds,
void WebPluginContainer::didReceiveResponse(
const WebCore::ResourceResponse& response) {
-
set_ignore_response_error(false);
HttpResponseInfo http_response_info;
@@ -315,9 +325,7 @@ WebPluginImpl::WebPluginImpl(WebCore::Element* element,
element_(element),
webframe_(webframe),
delegate_(delegate),
- force_geometry_update_(false),
visible_(false),
- received_first_paint_notification_(false),
widget_(NULL),
plugin_url_(plugin_url),
load_manually_(load_manually),
@@ -634,18 +642,11 @@ void WebPluginImpl::windowCutoutRects(
}
void WebPluginImpl::setFrameRect(const WebCore::IntRect& rect) {
- // Compute a new position and clip rect for ourselves relative to the
- // containing window. We ask our delegate to reposition us accordingly.
-
- // When the plugin is loaded we don't have a parent frame yet. We need
- // to force the plugin window to get created in the plugin process,
- // when the plugin widget position is updated. This occurs just after
- // the plugin is loaded (See http://b/issue?id=892174).
- if (!parent()) {
- force_geometry_update_ = true;
+ if (!parent())
return;
- }
+ // Compute a new position and clip rect for ourselves relative to the
+ // containing window. We ask our delegate to reposition us accordingly.
WebCore::Frame* frame = element_->document()->frame();
WebFrameImpl* webframe = WebFrameImpl::FromFrame(frame);
WebViewImpl* webview = webframe->webview_impl();
@@ -660,7 +661,11 @@ void WebPluginImpl::setFrameRect(const WebCore::IntRect& rect) {
std::vector<gfx::Rect> cutout_rects;
CalculateBounds(rect, &window_rect, &clip_rect, &cutout_rects);
- if (window_ && received_first_paint_notification_) {
+ delegate_->UpdateGeometry(
+ webkit_glue::FromIntRect(window_rect),
+ webkit_glue::FromIntRect(clip_rect));
+
+ if (window_) {
// Let the WebViewDelegate know that the plugin window needs to be moved,
// so that all the HWNDs are moved together.
WebPluginGeometry move;
@@ -673,17 +678,6 @@ void WebPluginImpl::setFrameRect(const WebCore::IntRect& rect) {
webview->delegate()->DidMove(webview, move);
}
- delegate_->UpdateGeometry(
- webkit_glue::FromIntRect(window_rect),
- webkit_glue::FromIntRect(clip_rect), cutout_rects,
- 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_) {
- force_geometry_update_ = false;
- delegate_->FlushGeometryUpdates();
- }
-
// Initiate a download on the plugin url. This should be done for the
// first update geometry sequence.
if (first_geometry_update_) {
@@ -709,31 +703,6 @@ void WebPluginImpl::paint(WebCore::GraphicsContext* gc,
if (!widget_->frameRect().intersects(damage_rect))
return;
- // A windowed plugin starts out by being invisible regardless of the style
- // which webkit tells us. The paint notification from webkit indicates that
- // the plugin widget is being shown and we need to make sure that
- // it becomes visible.
- // Please refer to https://bugs.webkit.org/show_bug.cgi?id=18901 for more
- // details on this issue.
- // TODO(iyengar): Remove this hack when this issue is fixed in webkit.
- if (!received_first_paint_notification_) {
- received_first_paint_notification_ = true;
-
- if (!windowless_) {
- WebCore::IntRect window_rect;
- WebCore::IntRect clip_rect;
- std::vector<gfx::Rect> cutout_rects;
-
- CalculateBounds(widget_->frameRect(), &window_rect, &clip_rect,
- &cutout_rects);
-
- delegate_->UpdateGeometry(webkit_glue::FromIntRect(window_rect),
- webkit_glue::FromIntRect(clip_rect),
- cutout_rects, visible_);
- delegate_->FlushGeometryUpdates();
- }
- }
-
gc->save();
DCHECK(parent()->isFrameView());
diff --git a/webkit/glue/webplugin_impl.h b/webkit/glue/webplugin_impl.h
index 1d11d71..3654d3a 100644
--- a/webkit/glue/webplugin_impl.h
+++ b/webkit/glue/webplugin_impl.h
@@ -41,6 +41,7 @@ namespace WebCore {
class ResourceHandle;
class ResourceError;
class ResourceResponse;
+ class ScrollView;
class String;
class Widget;
}
@@ -66,6 +67,7 @@ class WebPluginContainer : public WebCore::Widget {
virtual void handleEvent(WebCore::Event* event);
virtual void frameRectsChanged();
virtual void setParentVisible(bool visible);
+ virtual void setParent(WebCore::ScrollView* view);
#if USE(JSC)
virtual bool isPluginView() const;
@@ -325,11 +327,7 @@ class WebPluginImpl : public WebPlugin,
WebFrameImpl* webframe_;
WebPluginDelegate* delegate_;
- bool force_geometry_update_;
bool visible_;
- // Set when we receive the first paint notification for a windowed
- // plugin widget.
- bool received_first_paint_notification_;
WebPluginContainer* widget_;
diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc
index fc28aa1..631d48e 100644
--- a/webkit/tools/test_shell/test_webview_delegate.cc
+++ b/webkit/tools/test_shell/test_webview_delegate.cc
@@ -29,6 +29,7 @@
#if defined(OS_WIN)
// TODO(port): make these files work everywhere.
+#include "base/gfx/gdi_util.h"
#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/tools/test_shell/drag_delegate.h"
#include "webkit/tools/test_shell/drop_delegate.h"
@@ -696,11 +697,32 @@ void TestWebViewDelegate::Blur(WebWidget* webwidget) {
void TestWebViewDelegate::DidMove(WebWidget* webwidget,
const WebPluginGeometry& move) {
#if defined(OS_WIN)
- // TODO(port): add me once plugins work.
- WebPluginDelegateImpl::MoveWindow(
- move.window, move.window_rect, move.clip_rect, move.cutout_rects,
- move.visible);
+ HRGN hrgn = ::CreateRectRgn(move.clip_rect.x(),
+ move.clip_rect.y(),
+ move.clip_rect.right(),
+ move.clip_rect.bottom());
+ gfx::SubtractRectanglesFromRegion(hrgn, move.cutout_rects);
+
+ // Note: System will own the hrgn after we call SetWindowRgn,
+ // so we don't need to call DeleteObject(hrgn)
+ ::SetWindowRgn(move.window, hrgn, FALSE);
+
+ unsigned long flags = 0;
+ if (move.visible)
+ flags |= SWP_SHOWWINDOW;
+ else
+ flags |= SWP_HIDEWINDOW;
+
+ ::SetWindowPos(move.window,
+ NULL,
+ move.window_rect.x(),
+ move.window_rect.y(),
+ move.window_rect.width(),
+ move.window_rect.height(),
+ flags);
+
#endif
+ // TODO(port): add me once plugins work.
}
bool TestWebViewDelegate::IsHidden() {