OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/shelf/shelf_view.h" | 5 #include "ash/shelf/shelf_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <memory> | 8 #include <memory> |
9 | 9 |
10 #include "ash/ash_constants.h" | 10 #include "ash/ash_constants.h" |
11 #include "ash/drag_drop/drag_image_view.h" | 11 #include "ash/drag_drop/drag_image_view.h" |
12 #include "ash/public/cpp/shelf_item_delegate.h" | 12 #include "ash/public/cpp/shelf_item_delegate.h" |
13 #include "ash/scoped_root_window_for_new_windows.h" | 13 #include "ash/scoped_root_window_for_new_windows.h" |
14 #include "ash/shelf/app_list_button.h" | 14 #include "ash/shelf/app_list_button.h" |
15 #include "ash/shelf/overflow_bubble.h" | 15 #include "ash/shelf/overflow_bubble.h" |
16 #include "ash/shelf/overflow_bubble_view.h" | 16 #include "ash/shelf/overflow_bubble_view.h" |
17 #include "ash/shelf/overflow_button.h" | 17 #include "ash/shelf/overflow_button.h" |
18 #include "ash/shelf/shelf_application_menu_model.h" | 18 #include "ash/shelf/shelf_application_menu_model.h" |
19 #include "ash/shelf/shelf_button.h" | 19 #include "ash/shelf/shelf_button.h" |
20 #include "ash/shelf/shelf_constants.h" | 20 #include "ash/shelf/shelf_constants.h" |
21 #include "ash/shelf/shelf_model.h" | 21 #include "ash/shelf/shelf_model.h" |
22 #include "ash/shelf/shelf_widget.h" | 22 #include "ash/shelf/shelf_widget.h" |
23 #include "ash/shelf/wm_shelf.h" | 23 #include "ash/shelf/wm_shelf.h" |
24 #include "ash/shell.h" | 24 #include "ash/shell.h" |
25 #include "ash/shell_delegate.h" | 25 #include "ash/shell_delegate.h" |
26 #include "ash/shell_port.h" | 26 #include "ash/shell_port.h" |
27 #include "ash/strings/grit/ash_strings.h" | 27 #include "ash/strings/grit/ash_strings.h" |
28 #include "ash/wm/root_window_finder.h" | 28 #include "ash/wm/root_window_finder.h" |
29 #include "ash/wm/wm_screen_util.h" | |
29 #include "ash/wm_window.h" | 30 #include "ash/wm_window.h" |
30 #include "base/auto_reset.h" | 31 #include "base/auto_reset.h" |
31 #include "base/memory/ptr_util.h" | 32 #include "base/memory/ptr_util.h" |
32 #include "base/metrics/histogram_macros.h" | 33 #include "base/metrics/histogram_macros.h" |
33 #include "ui/accessibility/ax_node_data.h" | 34 #include "ui/accessibility/ax_node_data.h" |
34 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
35 #include "ui/base/models/simple_menu_model.h" | 36 #include "ui/base/models/simple_menu_model.h" |
36 #include "ui/compositor/layer.h" | 37 #include "ui/compositor/layer.h" |
37 #include "ui/compositor/layer_animator.h" | 38 #include "ui/compositor/layer_animator.h" |
38 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | 39 #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
(...skipping 1554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1593 } | 1594 } |
1594 } | 1595 } |
1595 // The menu clears |scoped_root_window_for_new_windows_| in OnMenuClosed. | 1596 // The menu clears |scoped_root_window_for_new_windows_| in OnMenuClosed. |
1596 if (!IsShowingMenu()) | 1597 if (!IsShowingMenu()) |
1597 scoped_root_window_for_new_windows_.reset(); | 1598 scoped_root_window_for_new_windows_.reset(); |
1598 } | 1599 } |
1599 | 1600 |
1600 void ShelfView::ShowContextMenuForView(views::View* source, | 1601 void ShelfView::ShowContextMenuForView(views::View* source, |
1601 const gfx::Point& point, | 1602 const gfx::Point& point, |
1602 ui::MenuSourceType source_type) { | 1603 ui::MenuSourceType source_type) { |
1604 WmWindow* shelf_window = WmWindow::Get(shelf_widget_->GetNativeWindow()); | |
msw
2017/05/05 17:34:18
nit: add a comment to this block of code, like "Al
minch1
2017/05/08 17:21:02
Done.
| |
1605 gfx::Rect shelf_bounds = | |
1606 is_overflow_mode() | |
1607 ? (owner_overflow_bubble_->bubble_view()->GetBubbleBounds()) | |
1608 : (wm::GetDisplayBoundsInParent(shelf_window)); | |
msw
2017/05/05 17:34:18
You'll probably need to refactor this as per https
| |
1609 | |
1610 gfx::Point point_aligned_shelf; | |
msw
2017/05/05 17:34:18
nit: consider |menu_point| or |context_menu_point|
minch1
2017/05/08 17:21:02
Done.
| |
1611 switch (wm_shelf_->GetAlignment()) { | |
1612 case SHELF_ALIGNMENT_BOTTOM: | |
1613 case SHELF_ALIGNMENT_BOTTOM_LOCKED: | |
1614 point_aligned_shelf.SetPoint(point.x(), | |
1615 shelf_bounds.bottom() - kShelfSize); | |
msw
2017/05/05 17:34:19
Why not just use shelf_bounds.y()?
minch1
2017/05/08 17:21:02
This is fine for overflow mode, if it is not. The
| |
1616 break; | |
1617 case SHELF_ALIGNMENT_LEFT: | |
1618 point_aligned_shelf.SetPoint(shelf_bounds.x() + kShelfSize, point.y()); | |
msw
2017/05/05 17:34:19
Ditto: why not just use shelf_bounds.right()?
| |
1619 break; | |
1620 case SHELF_ALIGNMENT_RIGHT: | |
1621 point_aligned_shelf.SetPoint(shelf_bounds.right() - kShelfSize, | |
msw
2017/05/05 17:34:19
Ditto: why not just use shelf_bounds.x()?
| |
1622 point.y()); | |
1623 default: | |
msw
2017/05/05 17:34:19
Remove the default case, so if anyone adds a new a
| |
1624 break; | |
1625 } | |
1603 last_pressed_index_ = -1; | 1626 last_pressed_index_ = -1; |
1604 | 1627 |
1605 const ShelfItem* item = ShelfItemForView(source); | 1628 const ShelfItem* item = ShelfItemForView(source); |
1606 if (!item) { | 1629 if (!item) { |
1607 ShellPort::Get()->ShowContextMenu(point, source_type); | 1630 ShellPort::Get()->ShowContextMenu(point_aligned_shelf, source_type); |
1608 return; | 1631 return; |
1609 } | 1632 } |
1610 | 1633 |
1611 std::unique_ptr<ui::MenuModel> context_menu_model( | 1634 std::unique_ptr<ui::MenuModel> context_menu_model( |
1612 Shell::Get()->shell_delegate()->CreateContextMenu(wm_shelf_, item)); | 1635 Shell::Get()->shell_delegate()->CreateContextMenu(wm_shelf_, item)); |
1613 if (!context_menu_model) | 1636 if (!context_menu_model) |
1614 return; | 1637 return; |
1615 | 1638 |
1616 context_menu_id_ = item ? item->id : 0; | 1639 context_menu_id_ = item ? item->id : 0; |
1617 ShowMenu(std::move(context_menu_model), source, point, true, source_type, | 1640 ShowMenu(std::move(context_menu_model), source, point_aligned_shelf, true, |
1618 nullptr); | 1641 source_type, nullptr); |
1619 } | 1642 } |
1620 | 1643 |
1621 void ShelfView::ShowMenu(std::unique_ptr<ui::MenuModel> menu_model, | 1644 void ShelfView::ShowMenu(std::unique_ptr<ui::MenuModel> menu_model, |
1622 views::View* source, | 1645 views::View* source, |
1623 const gfx::Point& click_point, | 1646 const gfx::Point& click_point, |
1624 bool context_menu, | 1647 bool context_menu, |
1625 ui::MenuSourceType source_type, | 1648 ui::MenuSourceType source_type, |
1626 views::InkDrop* ink_drop) { | 1649 views::InkDrop* ink_drop) { |
1627 menu_model_ = std::move(menu_model); | 1650 menu_model_ = std::move(menu_model); |
1628 menu_model_adapter_.reset(new views::MenuModelAdapter( | 1651 menu_model_adapter_.reset(new views::MenuModelAdapter( |
1629 menu_model_.get(), | 1652 menu_model_.get(), |
1630 base::Bind(&ShelfView::OnMenuClosed, base::Unretained(this), ink_drop))); | 1653 base::Bind(&ShelfView::OnMenuClosed, base::Unretained(this), ink_drop))); |
1631 | 1654 |
1632 closing_event_time_ = base::TimeTicks(); | 1655 closing_event_time_ = base::TimeTicks(); |
1633 int run_types = 0; | 1656 int run_types = 0; |
1634 if (context_menu) | 1657 if (context_menu) |
1635 run_types |= views::MenuRunner::CONTEXT_MENU; | 1658 run_types |= views::MenuRunner::CONTEXT_MENU; |
1636 launcher_menu_runner_.reset( | 1659 launcher_menu_runner_.reset( |
1637 new views::MenuRunner(menu_model_adapter_->CreateMenu(), run_types)); | 1660 new views::MenuRunner(menu_model_adapter_->CreateMenu(), run_types)); |
1638 | 1661 |
1639 // Place new windows on the same display as the button that spawned the menu. | 1662 // Place new windows on the same display as the button that spawned the menu. |
1640 WmWindow* window = WmWindow::Get(source->GetWidget()->GetNativeWindow()); | 1663 WmWindow* window = WmWindow::Get(source->GetWidget()->GetNativeWindow()); |
1641 scoped_root_window_for_new_windows_.reset( | 1664 scoped_root_window_for_new_windows_.reset( |
1642 new ScopedRootWindowForNewWindows(window->GetRootWindow())); | 1665 new ScopedRootWindowForNewWindows(window->GetRootWindow())); |
1643 | 1666 |
1644 views::MenuAnchorPosition menu_alignment = views::MENU_ANCHOR_TOPLEFT; | 1667 views::MenuAnchorPosition menu_alignment = views::MENU_ANCHOR_TOPLEFT; |
1645 gfx::Rect anchor = gfx::Rect(click_point, gfx::Size()); | 1668 gfx::Rect anchor = gfx::Rect(click_point, gfx::Size()); |
1646 | 1669 |
1670 ShelfAlignment shelf_alignment = wm_shelf_->GetAlignment(); | |
1647 if (!context_menu) { | 1671 if (!context_menu) { |
1648 // Application lists use a bubble. | 1672 // Application lists use a bubble. |
1649 // It is possible to invoke the menu while it is sliding into view. To cover | 1673 // It is possible to invoke the menu while it is sliding into view. To cover |
1650 // that case, the screen coordinates are offsetted by the animation delta. | 1674 // that case, the screen coordinates are offsetted by the animation delta. |
1651 anchor = source->GetBoundsInScreen() + (window->GetTargetBounds().origin() - | 1675 anchor = source->GetBoundsInScreen() + (window->GetTargetBounds().origin() - |
1652 window->GetBounds().origin()); | 1676 window->GetBounds().origin()); |
1653 | 1677 |
1654 // Adjust the anchor location for shelf items with asymmetrical borders. | 1678 // Adjust the anchor location for shelf items with asymmetrical borders. |
1655 if (source->border()) | 1679 if (source->border()) |
1656 anchor.Inset(source->border()->GetInsets()); | 1680 anchor.Inset(source->border()->GetInsets()); |
1657 | 1681 |
1658 // Determine the menu alignment dependent on the shelf. | 1682 // Determine the menu alignment dependent on the shelf. |
1659 switch (wm_shelf_->GetAlignment()) { | 1683 switch (shelf_alignment) { |
1660 case SHELF_ALIGNMENT_BOTTOM: | 1684 case SHELF_ALIGNMENT_BOTTOM: |
1661 case SHELF_ALIGNMENT_BOTTOM_LOCKED: | 1685 case SHELF_ALIGNMENT_BOTTOM_LOCKED: |
1662 menu_alignment = views::MENU_ANCHOR_BUBBLE_ABOVE; | 1686 menu_alignment = views::MENU_ANCHOR_BUBBLE_ABOVE; |
1663 break; | 1687 break; |
1664 case SHELF_ALIGNMENT_LEFT: | 1688 case SHELF_ALIGNMENT_LEFT: |
1665 menu_alignment = views::MENU_ANCHOR_BUBBLE_RIGHT; | 1689 menu_alignment = views::MENU_ANCHOR_BUBBLE_RIGHT; |
1666 break; | 1690 break; |
1667 case SHELF_ALIGNMENT_RIGHT: | 1691 case SHELF_ALIGNMENT_RIGHT: |
1668 menu_alignment = views::MENU_ANCHOR_BUBBLE_LEFT; | 1692 menu_alignment = views::MENU_ANCHOR_BUBBLE_LEFT; |
1669 break; | 1693 break; |
1670 } | 1694 } |
1671 } | 1695 } |
1672 | 1696 |
1697 // Distinguish the touch events that triggered on the bottom shelf or | |
1698 // left / right shelf. Since they should have different |MenuAnchorPosition|. | |
1699 if (source_type == ui::MENU_SOURCE_TOUCH && | |
1700 (shelf_alignment == SHELF_ALIGNMENT_LEFT || | |
msw
2017/05/05 17:34:18
Use !WmShelf::IsHorizontalAlignment() instead, and
| |
1701 shelf_alignment == SHELF_ALIGNMENT_RIGHT)) { | |
1702 source_type = ui::MENU_SOURCE_TOUCH_SIDE_SHELF; | |
1703 } | |
1673 // NOTE: if you convert to HAS_MNEMONICS be sure to update menu building code. | 1704 // NOTE: if you convert to HAS_MNEMONICS be sure to update menu building code. |
1674 launcher_menu_runner_->RunMenuAt(source->GetWidget(), nullptr, anchor, | 1705 launcher_menu_runner_->RunMenuAt(source->GetWidget(), nullptr, anchor, |
1675 menu_alignment, source_type); | 1706 menu_alignment, source_type); |
1676 } | 1707 } |
1677 | 1708 |
1678 void ShelfView::OnMenuClosed(views::InkDrop* ink_drop) { | 1709 void ShelfView::OnMenuClosed(views::InkDrop* ink_drop) { |
1679 context_menu_id_ = 0; | 1710 context_menu_id_ = 0; |
1680 | 1711 |
1681 // Hide the hide overflow bubble after showing a context menu for its items. | 1712 // Hide the hide overflow bubble after showing a context menu for its items. |
1682 if (owner_overflow_bubble_) | 1713 if (owner_overflow_bubble_) |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1749 // Bail if dragging has already begun, or if no item has been pressed. | 1780 // Bail if dragging has already begun, or if no item has been pressed. |
1750 if (dragging() || !drag_view_) | 1781 if (dragging() || !drag_view_) |
1751 return false; | 1782 return false; |
1752 | 1783 |
1753 // Dragging only begins once the pointer has travelled a minimum distance. | 1784 // Dragging only begins once the pointer has travelled a minimum distance. |
1754 if ((std::abs(event.x() - drag_origin_.x()) < kMinimumDragDistance) && | 1785 if ((std::abs(event.x() - drag_origin_.x()) < kMinimumDragDistance) && |
1755 (std::abs(event.y() - drag_origin_.y()) < kMinimumDragDistance)) { | 1786 (std::abs(event.y() - drag_origin_.y()) < kMinimumDragDistance)) { |
1756 return false; | 1787 return false; |
1757 } | 1788 } |
1758 | 1789 |
1759 // Touch dragging only begins after a dealy from the press event. This | 1790 // Touch dragging only begins after a delay from the press event. This |
1760 // prevents accidental dragging on swipe or scroll gestures. | 1791 // prevents accidental dragging on swipe or scroll gestures. |
1761 if (pointer == TOUCH && | 1792 if (pointer == TOUCH && |
1762 (base::TimeTicks::Now() - touch_press_time_) < | 1793 (base::TimeTicks::Now() - touch_press_time_) < |
1763 base::TimeDelta::FromMilliseconds(kTouchDragTimeThresholdMs)) { | 1794 base::TimeDelta::FromMilliseconds(kTouchDragTimeThresholdMs)) { |
1764 return false; | 1795 return false; |
1765 } | 1796 } |
1766 | 1797 |
1767 return true; | 1798 return true; |
1768 } | 1799 } |
1769 | 1800 |
1770 } // namespace ash | 1801 } // namespace ash |
OLD | NEW |