Chromium Code Reviews| Index: ash/shelf/shelf_view.cc |
| diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc |
| index 6e5e3db464e52cd6957e08214719caed6a426914..032ca306b5f1868c25da379eb9506ba427ad6d5a 100644 |
| --- a/ash/shelf/shelf_view.cc |
| +++ b/ash/shelf/shelf_view.cc |
| @@ -69,9 +69,6 @@ const int SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT = 3; |
| // Default amount content is inset on the left edge. |
| const int kDefaultLeadingInset = 8; |
| -// Minimum distance before drag starts. |
| -const int kMinimumDragDistance = 8; |
| - |
| // Additional spacing for the left and right side of icons. |
| const int kHorizontalIconSpacing = 2; |
| @@ -362,6 +359,9 @@ class ShelfView::StartFadeAnimationDelegate : public gfx::AnimationDelegate { |
| DISALLOW_COPY_AND_ASSIGN(StartFadeAnimationDelegate); |
| }; |
| +// static |
| +const int ShelfView::kMinimumDragDistance = 8; |
| + |
| ShelfView::ShelfView(ShelfModel* model, |
| ShelfDelegate* delegate, |
| WmShelf* wm_shelf, |
| @@ -394,7 +394,7 @@ ShelfView::ShelfView(ShelfModel* model, |
| overflow_mode_(false), |
| main_shelf_(nullptr), |
| dragged_off_from_overflow_to_shelf_(false), |
| - is_repost_event_(false), |
| + is_repost_event_on_same_item_(false), |
| last_pressed_index_(-1) { |
| DCHECK(model_); |
| DCHECK(wm_shelf_); |
| @@ -718,6 +718,29 @@ void ShelfView::EndDrag(bool cancel) { |
| drag_and_drop_shelf_id_ = 0; |
| } |
| +bool ShelfView::ShouldEventActivateButton(View* view, const ui::Event& event) { |
| + if (dragging()) |
| + return false; |
| + |
| + // Ignore if we are already in a pointer event sequence started with a repost |
| + // event on the same shelf item. See crbug.com/343005 for more detail. |
| + if (is_repost_event_on_same_item_) |
| + return false; |
| + |
| + // Don't activate the item twice on double-click. Otherwise the window starts |
| + // animating open due to the first click, then immediately minimizes due to |
| + // the second click. The user most likely intended to open or minimize the |
| + // item once, not do both. |
| + if (event.flags() & ui::EF_IS_DOUBLE_CLICK) |
| + return false; |
| + |
| + // Ignore if this is a repost event on the last pressed shelf item. |
| + int index = view_model_->GetIndexOfView(view); |
| + if (index == -1) |
| + return false; |
| + return !IsRepostEvent(event) || last_pressed_index_ != index; |
| +} |
| + |
| void ShelfView::PointerPressedOnButton(views::View* view, |
| Pointer pointer, |
| const ui::LocatedEvent& event) { |
| @@ -725,17 +748,18 @@ void ShelfView::PointerPressedOnButton(views::View* view, |
| return; |
| int index = view_model_->GetIndexOfView(view); |
| - if (index == -1) |
| - return; |
| + if (index == -1 || view_model_->view_size() <= 1) |
| + return; // View is being deleted, ignore request. |
| ShelfItemDelegate* item_delegate = |
| item_manager_->GetShelfItemDelegate(model_->items()[index].id); |
| - if (view_model_->view_size() <= 1 || !item_delegate->IsDraggable()) |
| - return; // View is being deleted or not draggable, ignore request. |
| + if (!item_delegate->IsDraggable()) |
| + return; // View is not draggable, ignore request. |
| // Only when the repost event occurs on the same shelf item, we should ignore |
| // the call in ShelfView::ButtonPressed(...). |
| - is_repost_event_ = IsRepostEvent(event) && (last_pressed_index_ == index); |
| + is_repost_event_on_same_item_ = |
| + IsRepostEvent(event) && (last_pressed_index_ == index); |
| CHECK_EQ(ShelfButton::kViewClassName, view->GetClassName()); |
| drag_view_ = static_cast<ShelfButton*>(view); |
| @@ -765,8 +789,7 @@ void ShelfView::PointerDraggedOnButton(views::View* view, |
| void ShelfView::PointerReleasedOnButton(views::View* view, |
| Pointer pointer, |
| bool canceled) { |
| - // Reset |is_repost_event| to false. |
| - is_repost_event_ = false; |
| + is_repost_event_on_same_item_ = false; |
| if (canceled) { |
| CancelDrag(-1); |
| @@ -997,7 +1020,7 @@ views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { |
| case TYPE_DIALOG: |
| case TYPE_APP_PANEL: |
| case TYPE_IME_MENU: { |
| - ShelfButton* button = new ShelfButton(this); |
| + ShelfButton* button = new ShelfButton(this, this); |
| button->SetImage(item.image); |
| ReflectItemStatus(item, button); |
| view = button; |
| @@ -1005,7 +1028,7 @@ views::View* ShelfView::CreateViewForItem(const ShelfItem& item) { |
| } |
| case TYPE_APP_LIST: { |
| - view = new AppListButton(this); |
| + view = new AppListButton(this, this); |
| break; |
| } |
| @@ -1049,6 +1072,8 @@ void ShelfView::PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event) { |
| // Move the view to the front so that it appears on top of other views. |
| ReorderChildView(drag_view_, -1); |
| bounds_animator_->StopAnimatingView(drag_view_); |
| + |
| + drag_view_->OnDragStarted(); |
| } |
| void ShelfView::ContinueDrag(const ui::LocatedEvent& event) { |
| @@ -1673,11 +1698,9 @@ void ShelfView::ShelfItemMoved(int start_index, int target_index) { |
| AnimateToIdealBounds(); |
| } |
| -void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { |
| - // Do not handle mouse release during drag. |
| - if (dragging()) |
| - return; |
| - |
| +void ShelfView::ButtonPressed(views::Button* sender, |
| + const ui::Event& event, |
| + views::InkDrop* ink_drop) { |
| if (sender == overflow_button_) { |
| ToggleOverflowBubble(); |
| shelf_button_pressed_metric_tracker_.ButtonPressed( |
| @@ -1685,27 +1708,17 @@ void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { |
| return; |
| } |
| - int view_index = view_model_->GetIndexOfView(sender); |
| - // May be -1 while in the process of animating closed. |
| - if (view_index == -1) |
| + // None of the checks in |ShouldEventActivateButton| affects overflow button. |
|
bruthig
2016/06/14 14:37:33
nit: |ShouldEventActivateButton| -> ShouldEventAct
mohsen
2016/06/14 20:40:30
Done.
|
| + // So, it is safe to be checked after handling overflow button. |
| + if (!ShouldEventActivateButton(sender, event)) |
| return; |
| - // If the menu was just closed by the same event as this one, we ignore |
| - // the call and don't open the menu again. See crbug.com/343005 for more |
| - // detail. |
| - if (is_repost_event_) |
| - return; |
| + int view_index = view_model_->GetIndexOfView(sender); |
| + DCHECK_LT(-1, view_index); |
| // Record the index for the last pressed shelf item. |
| last_pressed_index_ = view_index; |
| - // Don't activate the item twice on double-click. Otherwise the window starts |
| - // animating open due to the first click, then immediately minimizes due to |
| - // the second click. The user most likely intended to open or minimize the |
| - // item once, not do both. |
| - if (event.flags() & ui::EF_IS_DOUBLE_CLICK) |
| - return; |
| - |
| { |
| ScopedTargetRootWindow scoped_target( |
| sender->GetWidget()->GetNativeView()->GetRootWindow()); |
| @@ -1713,7 +1726,7 @@ void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { |
| std::unique_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; |
| if (event.IsShiftDown()) { |
| slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( |
| - ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); |
| + ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); |
| } |
| // Collect usage statistics before we decide what to do with the click. |
| @@ -1748,14 +1761,18 @@ void ShelfView::ButtonPressed(views::Button* sender, const ui::Event& event) { |
| shelf_button_pressed_metric_tracker_.ButtonPressed(event, sender, |
| performed_action); |
| - if (performed_action != ShelfItemDelegate::kNewWindowCreated) |
| - ShowListMenuForView(model_->items()[view_index], sender, event); |
| + if (performed_action == ShelfItemDelegate::kNewWindowCreated || |
| + !ShowListMenuForView(model_->items()[view_index], sender, event, |
| + ink_drop)) { |
| + ink_drop->AnimateToState(views::InkDropState::ACTION_TRIGGERED); |
| + } |
| } |
| } |
| -void ShelfView::ShowListMenuForView(const ShelfItem& item, |
| +bool ShelfView::ShowListMenuForView(const ShelfItem& item, |
| views::View* source, |
| - const ui::Event& event) { |
| + const ui::Event& event, |
| + views::InkDrop* ink_drop) { |
| ShelfItemDelegate* item_delegate = |
| item_manager_->GetShelfItemDelegate(item.id); |
| std::unique_ptr<ui::MenuModel> list_menu_model( |
| @@ -1764,16 +1781,23 @@ void ShelfView::ShowListMenuForView(const ShelfItem& item, |
| // Make sure we have a menu and it has at least two items in addition to the |
| // application title and the 3 spacing separators. |
| if (!list_menu_model.get() || list_menu_model->GetItemCount() <= 5) |
| - return; |
| + return false; |
| + ink_drop->AnimateToState(views::InkDropState::ACTIVATED); |
| context_menu_id_ = item.id; |
| ShowMenu(list_menu_model.get(), source, gfx::Point(), false, |
| ui::GetMenuSourceTypeForEvent(event)); |
| + // Menu is run synchronously, the menu is closed now and we need to go to |
| + // the deactivated state. |
| + ink_drop->AnimateToState(views::InkDropState::DEACTIVATED); |
| + return true; |
| } |
| void ShelfView::ShowContextMenuForView(views::View* source, |
| const gfx::Point& point, |
| ui::MenuSourceType source_type) { |
| + last_pressed_index_ = -1; |
| + |
| const ShelfItem* item = ShelfItemForView(source); |
| if (!item) { |
| Shell::GetInstance()->ShowContextMenu(point, source_type); |
| @@ -1883,11 +1907,9 @@ bool ShelfView::IsRepostEvent(const ui::Event& event) { |
| if (closing_event_time_.is_null()) |
| return false; |
| - base::TimeTicks last_closing_event_time = closing_event_time_; |
| - closing_event_time_ = base::TimeTicks(); |
| // If the current (press down) event is a repost event, the time stamp of |
| // these two events should be the same. |
| - return last_closing_event_time == event.time_stamp(); |
| + return closing_event_time_ == event.time_stamp(); |
| } |
| const ShelfItem* ShelfView::ShelfItemForView(const views::View* view) const { |