| Index: content/browser/browser_plugin/browser_plugin_guest.cc
|
| diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc
|
| index 543a63c7359b4c74796686fd5f7cf24f1bb4c4ef..e8d16c8a513df9a032066b07e72030e96c4a62c0 100644
|
| --- a/content/browser/browser_plugin/browser_plugin_guest.cc
|
| +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
|
| @@ -91,6 +91,9 @@ BrowserPluginGuest::BrowserPluginGuest(bool has_render_view,
|
| last_input_flags_(0),
|
| last_can_compose_inline_(true),
|
| guest_proxy_routing_id_(MSG_ROUTING_NONE),
|
| + last_drag_status_(blink::WebDragStatusUnknown),
|
| + seen_embedder_system_drag_ended_(false),
|
| + seen_embedder_drag_source_ended_at_(false),
|
| delegate_(delegate),
|
| weak_ptr_factory_(this) {
|
| DCHECK(web_contents);
|
| @@ -417,12 +420,45 @@ void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y,
|
| int screen_x, int screen_y, blink::WebDragOperation operation) {
|
| web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y,
|
| screen_x, screen_y, operation);
|
| + seen_embedder_drag_source_ended_at_ = true;
|
| + EndSystemDragIfApplicable();
|
| }
|
|
|
| -void BrowserPluginGuest::EndSystemDrag() {
|
| - RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
|
| - GetWebContents()->GetRenderViewHost());
|
| - guest_rvh->DragSourceSystemDragEnded();
|
| +void BrowserPluginGuest::EndSystemDragIfApplicable() {
|
| + // Ideally we'd want either WebDragStatusDrop or WebDragStatusLeave...
|
| + // Call guest RVH->DragSourceSystemDragEnded() correctly on the guest where
|
| + // the drag was initiated. Calling DragSourceSystemDragEnded() correctly
|
| + // means we call it in all cases and also make sure we only call it once.
|
| + // This ensures that the input state of the guest stays correct, otherwise
|
| + // it will go stale and won't accept any further input events.
|
| + //
|
| + // The strategy used here to call DragSourceSystemDragEnded() on the RVH
|
| + // is when the following conditions are met:
|
| + // a. Embedder has seen SystemDragEnded()
|
| + // b. Embedder has seen DragSourceEndedAt()
|
| + // c. The guest has seen some drag status update other than
|
| + // WebDragStatusUnknown. Note that this step should ideally be done
|
| + // differently: The guest has seen at least one of
|
| + // {WebDragStatusOver, WebDragStatusDrop}. However, if a user drags
|
| + // a source quickly outside of <webview> bounds, then the
|
| + // BrowserPluginGuest never sees any of these drag status updates,
|
| + // there we just check whether we've seen any drag status update or
|
| + // not.
|
| + if (last_drag_status_ != blink::WebDragStatusOver &&
|
| + seen_embedder_drag_source_ended_at_ && seen_embedder_system_drag_ended_) {
|
| + RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
|
| + GetWebContents()->GetRenderViewHost());
|
| + guest_rvh->DragSourceSystemDragEnded();
|
| +
|
| + last_drag_status_ = blink::WebDragStatusUnknown;
|
| + seen_embedder_system_drag_ended_ = false;
|
| + seen_embedder_drag_source_ended_at_ = false;
|
| + }
|
| +}
|
| +
|
| +void BrowserPluginGuest::EmbedderSystemDragEnded() {
|
| + seen_embedder_system_drag_ended_ = true;
|
| + EndSystemDragIfApplicable();
|
| }
|
|
|
| void BrowserPluginGuest::SendQueuedMessages() {
|
| @@ -649,11 +685,12 @@ void BrowserPluginGuest::OnDragStatusUpdate(int browser_plugin_instance_id,
|
| break;
|
| case blink::WebDragStatusDrop:
|
| host->DragTargetDrop(location, location, 0);
|
| - EndSystemDrag();
|
| break;
|
| case blink::WebDragStatusUnknown:
|
| NOTREACHED();
|
| }
|
| + last_drag_status_ = drag_status;
|
| + EndSystemDragIfApplicable();
|
| }
|
|
|
| void BrowserPluginGuest::OnExecuteEditCommand(int browser_plugin_instance_id,
|
|
|