diff options
author | mthiesse@chromium.org <mthiesse@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 16:24:29 +0000 |
---|---|---|
committer | mthiesse@chromium.org <mthiesse@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 16:24:29 +0000 |
commit | cf200a56e7ca0dcd1a4330289d6d2b000bfec254 (patch) | |
tree | 8e89ab117614e79fcde15749c13e5058bb9ed446 /content/browser/browser_plugin/browser_plugin_guest.cc | |
parent | 100991bcf54f385a593678d1dfc087d84da2a6a2 (diff) | |
download | chromium_src-cf200a56e7ca0dcd1a4330289d6d2b000bfec254.zip chromium_src-cf200a56e7ca0dcd1a4330289d6d2b000bfec254.tar.gz chromium_src-cf200a56e7ca0dcd1a4330289d6d2b000bfec254.tar.bz2 |
Fixed drag and drop into and out of Browser Plugin.
Only works when the --enable-browser-plugin-compositing flag is used, which causes web_contents_view_guest to be used.
How the flow works:
When a drag event is initiated on the web page, the BrowserPluginGuest receives an DragHostMsg_StartDragging IPC, and keeps track of that fact that it has initiated a drag event, but doesn't handle the IPC.
The IPC is then passed down the chain (not sure by who) and eventually calls WebContentsViewGuest::StartDragging.
WebContentsViewGuest::StartDragging calls the platform dependent WebContentsView of the embedder and starts the OS drag event.
Now, we get updates on the drag event from 2 places, BrowserPlugin::handleDragStatusUpdate, and RenderViewImpl::OnDragTargetDragOver of the embedder process.
BrowserPlugin::handleDragStatusUpdate goes through the guest to call RenderViewHostImpl::DragTargetDragOver on the guest process (but only when the mouse is hovering over the guest)
RenderViewImpl::OnDragTargetDragOver also calls RenderViewHostImpl::DragTargetDragOver but on the embedder process, and it always calls the function, whether or not the mouse is over the guest. For that reason, we keep track of if the mouse if over the guest, and use the embedder to capture and ignore the DragTargetDragOver message on the embedder process when the mouse is over the guest (or we get a flickering mouse).
Now, when the mouse is released, the native drag_host calls RenderViewImpl::OnDragSourceSystemDragEnded, which in turn calls webview()->dragSourceSystemDragEnded(); on the embedder process. However, the guest process webview() is not informed that the drag has ended, so it still blocks user input. So we send a new IPC, DragHostMsg_DragStopped to the embedder to let it inform the guest, who in turn informs the guest webview, that the drag has ended.
BUG= 161112
Review URL: https://chromiumcodereview.appspot.com/12086095
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198119 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/browser_plugin/browser_plugin_guest.cc')
-rw-r--r-- | content/browser/browser_plugin/browser_plugin_guest.cc | 65 |
1 files changed, 45 insertions, 20 deletions
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index 2f52561..48afb90 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -6,6 +6,7 @@ #include <algorithm> +#include "base/command_line.h" #include "base/message_loop.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" @@ -37,6 +38,7 @@ #include "content/public/browser/resource_request_details.h" #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents_view.h" +#include "content/public/common/content_switches.h" #include "content/public/common/media_stream_request.h" #include "content/public/common/result_codes.h" #include "net/base/net_errors.h" @@ -611,6 +613,29 @@ void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) { embedder_web_contents_->Send(msg); } +void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y, + int screen_x, int screen_y, WebKit::WebDragOperation operation) { + web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y, + screen_x, screen_y, operation); +} + +void BrowserPluginGuest::DragSourceMovedTo(int client_x, int client_y, + int screen_x, int screen_y) { + web_contents()->GetRenderViewHost()->DragSourceMovedTo(client_x, client_y, + screen_x, screen_y); +} + +void BrowserPluginGuest::EndSystemDrag() { + RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>( + GetWebContents()->GetRenderViewHost()); + guest_rvh->DragSourceSystemDragEnded(); + // Issue a MouseUp event to get out of a selection state. + WebKit::WebMouseEvent mouse_event; + mouse_event.type = WebKit::WebInputEvent::MouseUp; + mouse_event.button = WebKit::WebMouseEvent::ButtonLeft; + guest_rvh->ForwardMouseEvent(mouse_event); +} + void BrowserPluginGuest::LoadRedirect( const GURL& old_url, const GURL& new_url, @@ -693,13 +718,22 @@ void BrowserPluginGuest::DidCommitProvisionalLoadForFrame( } void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) { - // Initiating a drag from inside a guest is currently not supported. So inject - // some JS to disable it. http://crbug.com/161112 - const char script[] = "window.addEventListener('dragstart', function() { " - " window.event.preventDefault(); " - "});"; - render_view_host->ExecuteJavascriptInWebFrame(string16(), - ASCIIToUTF16(script)); + bool disable_dragdrop = true; +#if defined(OS_LINUX) || defined(OS_MACOSX) + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableBrowserPluginDragDrop)) + disable_dragdrop = false; +#endif // defined(OS_LINUX) || defined(OS_MACOSX) + if (disable_dragdrop) { + // Initiating a drag from inside a guest is currently not supported without + // the kEnableBrowserPluginDragDrop flag on a linux platform. So inject some + // JS to disable it. http://crbug.com/161112 + const char script[] = "window.addEventListener('dragstart', function() { " + " window.event.preventDefault(); " + "});"; + render_view_host->ExecuteJavascriptInWebFrame(string16(), + ASCIIToUTF16(script)); + } SendMessageToEmbedder(new BrowserPluginMsg_LoadStop(instance_id())); } @@ -800,7 +834,6 @@ bool BrowserPluginGuest::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget) IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus) IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse) - IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFrameName, OnUpdateFrameName) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect) IPC_MESSAGE_UNHANDLED(handled = false) @@ -886,16 +919,20 @@ void BrowserPluginGuest::OnDragStatusUpdate(int instance_id, RenderViewHost* host = GetWebContents()->GetRenderViewHost(); switch (drag_status) { case WebKit::WebDragStatusEnter: + embedder_web_contents_->GetBrowserPluginEmbedder()->DragEnteredGuest( + this); host->DragTargetDragEnter(drop_data, location, location, mask, 0); break; case WebKit::WebDragStatusOver: host->DragTargetDragOver(location, location, mask, 0); break; case WebKit::WebDragStatusLeave: + embedder_web_contents_->GetBrowserPluginEmbedder()->DragLeftGuest(this); host->DragTargetDragLeave(); break; case WebKit::WebDragStatusDrop: host->DragTargetDrop(location, location, 0); + EndSystemDrag(); break; case WebKit::WebDragStatusUnknown: NOTREACHED(); @@ -1226,18 +1263,6 @@ void BrowserPluginGuest::OnTakeFocus(bool reverse) { new BrowserPluginMsg_AdvanceFocus(instance_id(), reverse)); } -void BrowserPluginGuest::OnUpdateDragCursor( - WebKit::WebDragOperation operation) { - RenderViewHostImpl* embedder_render_view_host = - static_cast<RenderViewHostImpl*>( - embedder_web_contents_->GetRenderViewHost()); - CHECK(embedder_render_view_host); - RenderViewHostDelegateView* view = - embedder_render_view_host->GetDelegate()->GetDelegateView(); - if (view) - view->UpdateDragCursor(operation); -} - void BrowserPluginGuest::OnUpdateFrameName(int frame_id, bool is_top_level, const std::string& name) { |