summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-15 00:10:09 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-15 00:10:09 +0000
commit8e14284ed88d453f7ae280f033fffe7bcd6d8450 (patch)
tree3d1c5ef57ba393c3782f3095061a948b70f93f3e
parent573ef318ab6f9116139419745d741765ff4bb910 (diff)
downloadchromium_src-8e14284ed88d453f7ae280f033fffe7bcd6d8450.zip
chromium_src-8e14284ed88d453f7ae280f033fffe7bcd6d8450.tar.gz
chromium_src-8e14284ed88d453f7ae280f033fffe7bcd6d8450.tar.bz2
Set disabled style on GPU window and plugin intermediate window so mouse messages pass through to the browser window.
TEST=trybots BUG=none Review URL: http://codereview.chromium.org/549025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@36311 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc8
-rw-r--r--chrome/plugin/webplugin_proxy.h6
-rw-r--r--chrome/renderer/webplugin_delegate_pepper.cc2
-rw-r--r--gpu/gpu_plugin/gpu_plugin.cc57
-rw-r--r--webkit/glue/webplugin.cc23
-rw-r--r--webkit/glue/webplugin.h7
-rw-r--r--webkit/glue/webplugin_impl.cc81
-rw-r--r--webkit/glue/webplugin_impl.h10
-rw-r--r--webkit/webkit.gyp1
9 files changed, 154 insertions, 41 deletions
diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc
index d6287ac..0fa926d 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_win.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc
@@ -440,10 +440,16 @@ HWND RenderWidgetHostViewWin::ReparentWindow(HWND window) {
}
DCHECK(window_class);
+ // TODO(apatrick): the parent window is disabled if the plugin window is
+ // disabled so that mouse messages from the plugin window are passed on to the
+ // browser window. This does not work for regular plugins because it prevents
+ // them from receiving mouse and keyboard input. WS_DISABLED is not
+ // needed when the GPU process stops using child windows for 3D rendering.
+ DWORD enabled_style = ::GetWindowLong(window, GWL_STYLE) & WS_DISABLED;
HWND parent = CreateWindowEx(
WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
MAKEINTATOM(window_class), 0,
- WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
+ WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | enabled_style,
0, 0, 0, 0, ::GetParent(window), 0, GetModuleHandle(NULL), 0);
DCHECK(parent);
::SetParent(window, parent);
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index 2e86bbd..4a91685 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -42,6 +42,12 @@ class WebPluginProxy : public webkit_glue::WebPlugin {
// WebPlugin overrides
void SetWindow(gfx::PluginWindowHandle window);
+
+ // Whether input events should be sent to the delegate.
+ virtual void SetAcceptsInputEvents(bool accepts) {
+ NOTREACHED();
+ }
+
void WillDestroyWindow(gfx::PluginWindowHandle window);
#if defined(OS_WIN)
void SetWindowlessPumpEvent(HANDLE pump_messages_event);
diff --git a/chrome/renderer/webplugin_delegate_pepper.cc b/chrome/renderer/webplugin_delegate_pepper.cc
index 77c9146..e2c62a1 100644
--- a/chrome/renderer/webplugin_delegate_pepper.cc
+++ b/chrome/renderer/webplugin_delegate_pepper.cc
@@ -431,6 +431,8 @@ NPError WebPluginDelegatePepper::Device3DInitializeContext(
std::vector<std::string>(),
plugin_,
false)) {
+ plugin_->SetAcceptsInputEvents(true);
+
// Ask the GPU plugin to create a command buffer and return a proxy.
command_buffer_.reset(nested_delegate_->CreateCommandBuffer());
if (command_buffer_.get()) {
diff --git a/gpu/gpu_plugin/gpu_plugin.cc b/gpu/gpu_plugin/gpu_plugin.cc
index 7413a4f..5bccbe4 100644
--- a/gpu/gpu_plugin/gpu_plugin.cc
+++ b/gpu/gpu_plugin/gpu_plugin.cc
@@ -2,6 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+#include "base/logging.h"
+#include "build/build_config.h"
#include "gpu/gpu_plugin/gpu_plugin.h"
#include "webkit/glue/plugins/nphostapi.h"
@@ -11,12 +17,54 @@ namespace gpu_plugin {
namespace {
+// TODO(apatrick): move this to platform specific source files.
+#if defined(OS_WIN)
+class PluginObject {
+ public:
+ PluginObject();
+ ~PluginObject();
+
+ void SetWindow(HWND hwnd);
+
+ private:
+ HWND hwnd_;
+ DISALLOW_COPY_AND_ASSIGN(PluginObject);
+};
+
+const wchar_t* const kPluginObject = L"GPUPluginObject";
+
+PluginObject::PluginObject() : hwnd_(NULL) {
+}
+
+PluginObject::~PluginObject() {
+}
+
+void PluginObject::SetWindow(HWND hwnd) {
+ hwnd_ = hwnd;
+ if (hwnd_) {
+ // Store plugin object in window property.
+ SetProp(hwnd_, kPluginObject, reinterpret_cast<HANDLE>(this));
+
+ // Disable plugin window so mouse messages are passed to the parent window.
+ EnableWindow(hwnd_, false);
+ } else {
+ // Clean up properties.
+ RemoveProp(hwnd_, kPluginObject);
+ }
+}
+
+#endif // defined(OS_WIN)
+
NPError NPP_New(NPMIMEType plugin_type, NPP instance,
uint16 mode, int16 argc, char* argn[],
char* argv[], NPSavedData* saved) {
if (!instance)
return NPERR_INVALID_INSTANCE_ERROR;
+#if defined(OS_WIN)
+ instance->pdata = new PluginObject;
+#endif
+
return NPERR_NO_ERROR;
}
@@ -24,10 +72,19 @@ NPError NPP_Destroy(NPP instance, NPSavedData** saved) {
if (!instance)
return NPERR_INVALID_INSTANCE_ERROR;
+#if defined(OS_WIN)
+ delete static_cast<PluginObject*>(instance->pdata);
+#endif
+
return NPERR_NO_ERROR;
}
NPError NPP_SetWindow(NPP instance, NPWindow* window) {
+#if defined(OS_WIN)
+ PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata);
+ plugin_object->SetWindow(reinterpret_cast<HWND>(window->window));
+#endif
+
return NPERR_NO_ERROR;
}
diff --git a/webkit/glue/webplugin.cc b/webkit/glue/webplugin.cc
new file mode 100644
index 0000000..237e60c
--- /dev/null
+++ b/webkit/glue/webplugin.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/webplugin.h"
+
+namespace webkit_glue {
+
+WebPluginGeometry::WebPluginGeometry()
+ : window(gfx::kNullPluginWindow),
+ rects_valid(false),
+ visible(false) {
+}
+
+bool WebPluginGeometry::Equals(const WebPluginGeometry& rhs) const {
+ return window == rhs.window &&
+ window_rect == rhs.window_rect &&
+ clip_rect == rhs.clip_rect &&
+ cutout_rects == rhs.cutout_rects &&
+ rects_valid == rhs.rects_valid &&
+ visible == rhs.visible;
+}
+} // namespace webkit_glue
diff --git a/webkit/glue/webplugin.h b/webkit/glue/webplugin.h
index a549b5f..c4e2272 100644
--- a/webkit/glue/webplugin.h
+++ b/webkit/glue/webplugin.h
@@ -32,6 +32,10 @@ class WebPluginResourceClient;
// Describes the new location for a plugin window.
struct WebPluginGeometry {
+ WebPluginGeometry();
+
+ bool Equals(const WebPluginGeometry& rhs) const;
+
// On Windows, this is the plugin window in the plugin process.
// On X11, this is the XID of the plugin-side GtkPlug containing the
// GtkSocket hosting the actual plugin window.
@@ -57,6 +61,9 @@ class WebPlugin {
// as well as the information about the HDC for paint operations.
virtual void SetWindow(gfx::PluginWindowHandle window) = 0;
+ // Whether input events should be sent to the delegate.
+ virtual void SetAcceptsInputEvents(bool accepts) = 0;
+
// Called by the plugin delegate to let it know that the window is being
// destroyed.
virtual void WillDestroyWindow(gfx::PluginWindowHandle window) = 0;
diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc
index 8c1ffa9..20e9a76 100644
--- a/webkit/glue/webplugin_impl.cc
+++ b/webkit/glue/webplugin_impl.cc
@@ -250,51 +250,53 @@ void WebPluginImpl::paint(WebCanvas* canvas, const WebRect& paint_rect) {
void WebPluginImpl::updateGeometry(
const WebRect& window_rect, const WebRect& clip_rect,
const WebVector<WebRect>& cutout_rects, bool is_visible) {
- if (window_ && page_delegate_) {
- // Notify the window hosting the plugin (the WebViewDelegate) that
- // it needs to adjust the plugin, so that all the HWNDs can be moved
- // at the same time.
- WebPluginGeometry move;
- move.window = window_;
- move.window_rect = window_rect;
- move.clip_rect = clip_rect;
- for (size_t i = 0; i < cutout_rects.size(); ++i)
- move.cutout_rects.push_back(cutout_rects[i]);
- move.rects_valid = true;
- move.visible = is_visible;
-
- page_delegate_->DidMovePlugin(move);
+ WebPluginGeometry new_geometry;
+ new_geometry.window = window_;
+ new_geometry.window_rect = window_rect;
+ new_geometry.clip_rect = clip_rect;
+ new_geometry.visible = is_visible;
+ new_geometry.rects_valid = true;
+ for (size_t i = 0; i < cutout_rects.size(); ++i)
+ new_geometry.cutout_rects.push_back(cutout_rects[i]);
+
+ // Only send DidMovePlugin if the geometry changed in some way.
+ if (window_ &&
+ page_delegate_ &&
+ (first_geometry_update_ || !new_geometry.Equals(geometry_))) {
+ page_delegate_->DidMovePlugin(new_geometry);
}
- if (first_geometry_update_ || window_rect != window_rect_ ||
- clip_rect != clip_rect_) {
- window_rect_ = window_rect;
- clip_rect_ = clip_rect;
+ // Only UpdateGeometry if either the window or clip rects have changed.
+ if (first_geometry_update_ ||
+ new_geometry.window_rect != geometry_.window_rect ||
+ new_geometry.clip_rect != geometry_.clip_rect) {
// Notify the plugin that its parameters have changed.
- delegate_->UpdateGeometry(window_rect_, clip_rect_);
-
- // Initiate a download on the plugin url. This should be done for the
- // first update geometry sequence. We need to ensure that the plugin
- // receives the geometry update before it starts receiving data.
- if (first_geometry_update_) {
- first_geometry_update_ = false;
- // An empty url corresponds to an EMBED tag with no src attribute.
- if (!load_manually_ && plugin_url_.is_valid()) {
- // The Flash plugin hangs for a while if it receives data before
- // receiving valid plugin geometry. By valid geometry we mean the
- // geometry received by a call to setFrameRect in the Webkit
- // layout code path. To workaround this issue we download the
- // plugin source url on a timer.
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE, method_factory_.NewRunnableMethod(
- &WebPluginImpl::OnDownloadPluginSrcUrl), 0);
- }
+ delegate_->UpdateGeometry(new_geometry.window_rect, new_geometry.clip_rect);
+ }
+
+ // Initiate a download on the plugin url. This should be done for the
+ // first update geometry sequence. We need to ensure that the plugin
+ // receives the geometry update before it starts receiving data.
+ if (first_geometry_update_) {
+ // An empty url corresponds to an EMBED tag with no src attribute.
+ if (!load_manually_ && plugin_url_.is_valid()) {
+ // The Flash plugin hangs for a while if it receives data before
+ // receiving valid plugin geometry. By valid geometry we mean the
+ // geometry received by a call to setFrameRect in the Webkit
+ // layout code path. To workaround this issue we download the
+ // plugin source url on a timer.
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, method_factory_.NewRunnableMethod(
+ &WebPluginImpl::OnDownloadPluginSrcUrl), 0);
}
}
+
+ first_geometry_update_ = false;
+ geometry_ = new_geometry;
}
void WebPluginImpl::updateFocus(bool focused) {
- if (focused && windowless_)
+ if (focused && accepts_input_events_)
delegate_->SetFocus();
}
@@ -313,7 +315,7 @@ void WebPluginImpl::updateVisibility(bool visible) {
}
bool WebPluginImpl::acceptsInputEvents() {
- return windowless_;
+ return accepts_input_events_;
}
bool WebPluginImpl::handleInputEvent(
@@ -374,6 +376,7 @@ WebPluginImpl::WebPluginImpl(
const base::WeakPtr<WebPluginPageDelegate>& page_delegate)
: windowless_(false),
window_(NULL),
+ accepts_input_events_(false),
page_delegate_(page_delegate),
webframe_(webframe),
delegate_(NULL),
@@ -400,6 +403,7 @@ void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) {
if (window) {
DCHECK(!windowless_);
window_ = window;
+ accepts_input_events_ = false;
if (page_delegate_) {
// Tell the view delegate that the plugin window was created, so that it
// can create necessary container widgets.
@@ -408,6 +412,7 @@ void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) {
} else {
DCHECK(!window_); // Make sure not called twice.
windowless_ = true;
+ accepts_input_events_ = true;
}
}
diff --git a/webkit/glue/webplugin_impl.h b/webkit/glue/webplugin_impl.h
index f4e1108..21a6cee 100644
--- a/webkit/glue/webplugin_impl.h
+++ b/webkit/glue/webplugin_impl.h
@@ -87,6 +87,12 @@ class WebPluginImpl : public WebPlugin,
// WebPlugin implementation:
void SetWindow(gfx::PluginWindowHandle window);
+
+ // Whether input events should be sent to the delegate.
+ virtual void SetAcceptsInputEvents(bool accepts) {
+ accepts_input_events_ = accepts;
+ }
+
void WillDestroyWindow(gfx::PluginWindowHandle window);
#if defined(OS_WIN)
void SetWindowlessPumpEvent(HANDLE pump_messages_event) { }
@@ -252,6 +258,7 @@ class WebPluginImpl : public WebPlugin,
bool windowless_;
gfx::PluginWindowHandle window_;
+ bool accepts_input_events_;
base::WeakPtr<WebPluginPageDelegate> page_delegate_;
WebKit::WebFrame* webframe_;
@@ -280,8 +287,7 @@ class WebPluginImpl : public WebPlugin,
bool ignore_response_error_;
// The current plugin geometry and clip rectangle.
- gfx::Rect window_rect_;
- gfx::Rect clip_rect_;
+ WebPluginGeometry geometry_;
// The mime type of the plugin.
std::string mime_type_;
diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp
index ff86d6a..1065494 100644
--- a/webkit/webkit.gyp
+++ b/webkit/webkit.gyp
@@ -387,6 +387,7 @@
'glue/webmenurunner_mac.mm',
'glue/webpasswordautocompletelistener_impl.cc',
'glue/webpasswordautocompletelistener_impl.h',
+ 'glue/webplugin.cc',
'glue/webplugin.h',
'glue/webplugin_delegate.h',
'glue/webplugin_impl.cc',