From 979034577b30629702cac5fcd659407f18fb40ef Mon Sep 17 00:00:00 2001 From: "tdanderson@chromium.org" Date: Fri, 7 Feb 2014 23:38:00 +0000 Subject: [PATCH] Determine the source of a drag and drop for the bookmark manager Determine whether or not a drag and drop session was started with touch or mouse and pass this information through to the DragDropController. Passing the correct source (namely touch) to the DDC prevents the unresponsiveness described in issue 316105. BUG=316105 TEST=See bug Review URL: https://codereview.chromium.org/153603003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249852 0039d316-1c4b-4281-b951-d872f2087c98 --- .../bookmark_manager_private_api.cc | 9 +++++++- .../browser/resources/bookmark_manager/js/dnd.js | 25 +++++++++++++++++++++- chrome/browser/ui/bookmarks/bookmark_drag_drop.h | 6 ++++-- .../ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm | 4 +++- .../ui/gtk/bookmarks/bookmark_drag_drop_gtk.cc | 4 +++- .../ui/views/bookmarks/bookmark_drag_drop_views.cc | 11 +++++----- .../extensions/api/bookmark_manager_private.json | 5 +++++ 7 files changed, 52 insertions(+), 12 deletions(-) diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index c01e3c17c6a0..24a884d060b8 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc @@ -37,6 +37,7 @@ #include "extensions/browser/extension_system.h" #include "extensions/browser/view_type_utils.h" #include "grit/generated_resources.h" +#include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" @@ -430,8 +431,14 @@ bool BookmarkManagerPrivateStartDragFunction::RunImpl() { WebContents* web_contents = dispatcher()->delegate()->GetAssociatedWebContents(); CHECK(web_contents); + + ui::DragDropTypes::DragEventSource source = + ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE; + if (params->is_from_touch) + source = ui::DragDropTypes::DRAG_EVENT_SOURCE_TOUCH; + chrome::DragBookmarks( - GetProfile(), nodes, web_contents->GetView()->GetNativeView()); + GetProfile(), nodes, web_contents->GetView()->GetNativeView(), source); return true; } else { diff --git a/chrome/browser/resources/bookmark_manager/js/dnd.js b/chrome/browser/resources/bookmark_manager/js/dnd.js index f65d5a424420..7b2ee40a05d6 100644 --- a/chrome/browser/resources/bookmark_manager/js/dnd.js +++ b/chrome/browser/resources/bookmark_manager/js/dnd.js @@ -33,6 +33,12 @@ cr.define('dnd', function() { var removeDropIndicatorTimer; /** + * The element currently targeted by a touch. + * @type {Element} + */ + var currentTouchTarget; + + /** * The element that had a style applied it to indicate the drop location. * This is used to easily remove the style when necessary. * @type {Element} @@ -313,6 +319,8 @@ cr.define('dnd', function() { // Determine the selected bookmarks. var target = e.target; var draggedNodes = []; + var isFromTouch = target == currentTouchTarget; + if (target instanceof ListItem) { // Use selected items. draggedNodes = target.parentNode.selectedItems; @@ -336,7 +344,7 @@ cr.define('dnd', function() { chrome.bookmarkManagerPrivate.startDrag(draggedNodes.map(function(node) { return node.id; - })); + }), isFromTouch); } } @@ -482,6 +490,17 @@ cr.define('dnd', function() { dropIndicator.finish(); } + function setCurrentTouchTarget(e) { + // Only set a new target for a single touch point. + if (e.touches.length == 1) + currentTouchTarget = getBookmarkElement(e.target); + } + + function clearCurrentTouchTarget(e) { + if (getBookmarkElement(e.target) == currentTouchTarget) + currentTouchTarget = null; + } + function clearDragData() { dragInfo.clearDragData(); dropDestination = null; @@ -501,6 +520,10 @@ cr.define('dnd', function() { document.addEventListener('drop', handleDrop); document.addEventListener('dragend', deferredClearData); document.addEventListener('mouseup', deferredClearData); + document.addEventListener('mousedown', clearCurrentTouchTarget); + document.addEventListener('touchcancel', clearCurrentTouchTarget); + document.addEventListener('touchend', clearCurrentTouchTarget); + document.addEventListener('touchstart', setCurrentTouchTarget); chrome.bookmarkManagerPrivate.onDragEnter.addListener( dragInfo.handleChromeDragEnter); diff --git a/chrome/browser/ui/bookmarks/bookmark_drag_drop.h b/chrome/browser/ui/bookmarks/bookmark_drag_drop.h index 67dfa47da208..1f604b20be6b 100644 --- a/chrome/browser/ui/bookmarks/bookmark_drag_drop.h +++ b/chrome/browser/ui/bookmarks/bookmark_drag_drop.h @@ -7,6 +7,7 @@ #include +#include "ui/base/dragdrop/drag_drop_types.h" #include "ui/gfx/native_widget_types.h" class BookmarkNode; @@ -15,10 +16,11 @@ class Profile; namespace chrome { -// Stars the process of dragging a folder of bookmarks. +// Starts the process of dragging a folder of bookmarks. void DragBookmarks(Profile* profile, const std::vector& nodes, - gfx::NativeView view); + gfx::NativeView view, + ui::DragDropTypes::DragEventSource source); // Drops the bookmark nodes that are in |data| onto |parent_node| at |index|. // Returns the drop type used. diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm index dba228a59241..71e327f4b2b0 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_drag_drop_cocoa.mm @@ -20,6 +20,7 @@ #include "chrome/browser/ui/bookmarks/bookmark_drag_drop.h" #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" #include "grit/ui_resources.h" +#include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" @@ -129,7 +130,8 @@ NSImage* DragImageForBookmark(NSImage* favicon, const base::string16& title) { void DragBookmarks(Profile* profile, const std::vector& nodes, - gfx::NativeView view) { + gfx::NativeView view, + ui::DragDropTypes::DragEventSource source) { DCHECK(!nodes.empty()); // Allow nested message loop so we get DnD events as we drag this around. diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_drag_drop_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_drag_drop_gtk.cc index 926fad29bde1..90a7d4ca79cb 100644 --- a/chrome/browser/ui/gtk/bookmarks/bookmark_drag_drop_gtk.cc +++ b/chrome/browser/ui/gtk/bookmarks/bookmark_drag_drop_gtk.cc @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h" #include "chrome/browser/ui/gtk/custom_drag.h" +#include "ui/base/dragdrop/drag_drop_types.h" namespace { @@ -49,7 +50,8 @@ namespace chrome { void DragBookmarks(Profile* profile, const std::vector& nodes, - gfx::NativeView view) { + gfx::NativeView view, + ui::DragDropTypes::DragEventSource source) { DCHECK(!nodes.empty()); // This starts the drag process, the lifetime of this object is tied to the diff --git a/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc b/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc index 0c2de57739d6..1b3a75b02682 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_drag_drop_views.cc @@ -21,7 +21,8 @@ namespace chrome { void DragBookmarks(Profile* profile, const std::vector& nodes, - gfx::NativeView view) { + gfx::NativeView view, + ui::DragDropTypes::DragEventSource source) { DCHECK(!nodes.empty()); // Set up our OLE machinery @@ -37,15 +38,13 @@ void DragBookmarks(Profile* profile, ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_LINK; views::Widget* widget = views::Widget::GetWidgetForNativeView(view); - // TODO(varunjain): Properly determine and send DRAG_EVENT_SOURCE below. + if (widget) { - widget->RunShellDrag(NULL, data, gfx::Point(), operation, - ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE); + widget->RunShellDrag(NULL, data, gfx::Point(), operation, source); } else { // We hit this case when we're using WebContentsViewWin or // WebContentsViewAura, instead of WebContentsViewViews. - views::RunShellDrag(view, data, gfx::Point(), operation, - ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE); + views::RunShellDrag(view, data, gfx::Point(), operation, source); } base::MessageLoop::current()->SetNestableTasksAllowed(was_nested); diff --git a/chrome/common/extensions/api/bookmark_manager_private.json b/chrome/common/extensions/api/bookmark_manager_private.json index 096fd6625576..1d4e4a95968f 100644 --- a/chrome/common/extensions/api/bookmark_manager_private.json +++ b/chrome/common/extensions/api/bookmark_manager_private.json @@ -151,6 +151,11 @@ "type": "array", "items": {"type": "string"}, "minItems": 1 + }, + { + "name": "isFromTouch", + "type": "boolean", + "description": "True if the drag was initiated from touch" } ] }, -- 2.11.4.GIT