From d8d6c65576e72e28bdc912c600546f6db93e3c4f Mon Sep 17 00:00:00 2001 From: David Murphy Date: Thu, 19 Jul 2018 23:38:23 -0400 Subject: [PATCH] BListView: Restore selection to MouseDown and fix multi-select drag'n'drop * Moves list item selection logic back to MouseDown from MouseUp to improve application compatibility and responsiveness * Fixes multi-select drag and drop by not modifying the existing selection if a MouseDown event is on a selected item. Fixes #9190, #14264, #14289 Change-Id: I58050b403dac985f98e03faa72de1ebc5d24f95b --- src/kits/interface/ListView.cpp | 43 ++++++++++++++------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index 47dee60791..748fa6fe73 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -547,6 +547,11 @@ BListView::MouseDown(BPoint where) } int32 index = IndexOf(where); + int32 modifiers = 0; + + BMessage* message = Looper()->CurrentMessage(); + if (message != NULL) + message->FindInt32("modifiers", &modifiers); // If the user double (or more) clicked within the current selection, // we don't change the selection but invoke the selection. @@ -585,30 +590,6 @@ BListView::MouseDown(BPoint where) &BListView::_DoneTracking, &BListView::_Track); } - BView::MouseDown(where); -} - - -void -BListView::MouseUp(BPoint where) -{ - if (fTrack->is_dragging) { - // do selection only if a drag was not initiated - BView::MouseUp(where); - return; - } - - int32 modifiers = 0; - - BMessage* message = Looper()->CurrentMessage(); - if (message != NULL) - message->FindInt32("modifiers", &modifiers); - - // Evaluate selection based on the selected index - // at the time of the mouse starting to track. - // Otherwise we cannot properly handle dragging and dropping - // with multi-select list. - int32 index = fTrack->item_index; if (index >= 0) { if (fListType == B_MULTIPLE_SELECTION_LIST) { if ((modifiers & B_SHIFT_KEY) != 0) { @@ -627,7 +608,12 @@ BListView::MouseUp(BPoint where) Deselect(index); else Select(index, true); - } else + } else if (!ItemAt(index)->IsSelected()) + // To enable multi-select drag and drop, we only + // exclusively select a single item if it's not one of the + // already selected items. This behavior gives the mouse + // tracking thread the opportunity to initiate the + // multi-selection drag with all the items still selected. Select(index); } } else { @@ -640,6 +626,13 @@ BListView::MouseUp(BPoint where) } else if ((modifiers & B_COMMAND_KEY) == 0) DeselectAll(); + BView::MouseDown(where); +} + + +void +BListView::MouseUp(BPoint where) +{ BView::MouseUp(where); }