Commit c457cea4 authored by lazyboy@chromium.org's avatar lazyboy@chromium.org

dragend fix for mac <webview>.

dragend would never fire on mac because
BrowserPluginEmbedder::SystemDragEnded() clears |guest_dragging_over_|, which stops
BrowserPluginEmbedder::DragSourceEndedAt() to send the dragend
message.
This isn't an issue in aura b/c, we see DrageSourceEndedAt() before
SystemDragEnded().

BUG=401941
Test=On mac, load a <webview> in a chrome app, register a "dragend"
listener to a draggable div. Drag that div, observe "dragend" listener
firing properly.

Review URL: https://codereview.chromium.org/499493002

Cr-Commit-Position: refs/heads/master@{#291356}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291356 0039d316-1c4b-4281-b951-d872f2087c98
parent 596e3dbd
...@@ -28,6 +28,7 @@ namespace content { ...@@ -28,6 +28,7 @@ namespace content {
BrowserPluginEmbedder::BrowserPluginEmbedder(WebContentsImpl* web_contents) BrowserPluginEmbedder::BrowserPluginEmbedder(WebContentsImpl* web_contents)
: WebContentsObserver(web_contents), : WebContentsObserver(web_contents),
guest_drag_ending_(false),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
} }
...@@ -54,6 +55,7 @@ void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) { ...@@ -54,6 +55,7 @@ void BrowserPluginEmbedder::DragLeftGuest(BrowserPluginGuest* guest) {
void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) { void BrowserPluginEmbedder::StartDrag(BrowserPluginGuest* guest) {
guest_started_drag_ = guest->AsWeakPtr(); guest_started_drag_ = guest->AsWeakPtr();
guest_drag_ending_ = false;
} }
WebContentsImpl* BrowserPluginEmbedder::GetWebContents() const { WebContentsImpl* BrowserPluginEmbedder::GetWebContents() const {
...@@ -65,6 +67,20 @@ BrowserPluginEmbedder::GetBrowserPluginGuestManager() const { ...@@ -65,6 +67,20 @@ BrowserPluginEmbedder::GetBrowserPluginGuestManager() const {
return GetWebContents()->GetBrowserContext()->GetGuestManager(); return GetWebContents()->GetBrowserContext()->GetGuestManager();
} }
void BrowserPluginEmbedder::ClearGuestDragStateIfApplicable() {
// The order at which we observe SystemDragEnded() and DragSourceEndedAt() is
// platform dependent.
// In OSX, we see SystemDragEnded() first, where in aura, we see
// DragSourceEndedAt() first. For this reason, we check if both methods were
// called before resetting |guest_started_drag_|.
if (guest_drag_ending_) {
if (guest_started_drag_)
guest_started_drag_.reset();
} else {
guest_drag_ending_ = true;
}
}
bool BrowserPluginEmbedder::DidSendScreenRectsCallback( bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
WebContents* guest_web_contents) { WebContents* guest_web_contents) {
static_cast<RenderViewHostImpl*>( static_cast<RenderViewHostImpl*>(
...@@ -93,22 +109,23 @@ bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) { ...@@ -93,22 +109,23 @@ bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) {
void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y, void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y,
int screen_x, int screen_y, blink::WebDragOperation operation) { int screen_x, int screen_y, blink::WebDragOperation operation) {
if (guest_started_drag_.get()) { if (guest_started_drag_) {
gfx::Point guest_offset = gfx::Point guest_offset =
guest_started_drag_->GetScreenCoordinates(gfx::Point()); guest_started_drag_->GetScreenCoordinates(gfx::Point());
guest_started_drag_->DragSourceEndedAt(client_x - guest_offset.x(), guest_started_drag_->DragSourceEndedAt(client_x - guest_offset.x(),
client_y - guest_offset.y(), screen_x, screen_y, operation); client_y - guest_offset.y(), screen_x, screen_y, operation);
} }
ClearGuestDragStateIfApplicable();
} }
void BrowserPluginEmbedder::SystemDragEnded() { void BrowserPluginEmbedder::SystemDragEnded() {
// When the embedder's drag/drop operation ends, we need to pass the message // When the embedder's drag/drop operation ends, we need to pass the message
// to the guest that initiated the drag/drop operation. This will ensure that // to the guest that initiated the drag/drop operation. This will ensure that
// the guest's RVH state is reset properly. // the guest's RVH state is reset properly.
if (guest_started_drag_.get()) if (guest_started_drag_)
guest_started_drag_->EndSystemDrag(); guest_started_drag_->EndSystemDrag();
guest_started_drag_.reset();
guest_dragging_over_.reset(); guest_dragging_over_.reset();
ClearGuestDragStateIfApplicable();
} }
void BrowserPluginEmbedder::OnUpdateDragCursor(bool* handled) { void BrowserPluginEmbedder::OnUpdateDragCursor(bool* handled) {
......
...@@ -75,6 +75,8 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver { ...@@ -75,6 +75,8 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
BrowserPluginGuestManager* GetBrowserPluginGuestManager() const; BrowserPluginGuestManager* GetBrowserPluginGuestManager() const;
void ClearGuestDragStateIfApplicable();
bool DidSendScreenRectsCallback(WebContents* guest_web_contents); bool DidSendScreenRectsCallback(WebContents* guest_web_contents);
bool SetZoomLevelCallback(double level, WebContents* guest_web_contents); bool SetZoomLevelCallback(double level, WebContents* guest_web_contents);
...@@ -106,6 +108,9 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver { ...@@ -106,6 +108,9 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
// status messages to the correct guest. // status messages to the correct guest.
base::WeakPtr<BrowserPluginGuest> guest_started_drag_; base::WeakPtr<BrowserPluginGuest> guest_started_drag_;
// Keeps track of "dragend" state.
bool guest_drag_ending_;
base::WeakPtrFactory<BrowserPluginEmbedder> weak_ptr_factory_; base::WeakPtrFactory<BrowserPluginEmbedder> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BrowserPluginEmbedder); DISALLOW_COPY_AND_ASSIGN(BrowserPluginEmbedder);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment