Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Side by Side Diff: ash/shelf/shelf_view.cc

Issue 2861873002: Align the base of the shelf's context menu to the top edge of the shelf. (Closed)
Patch Set: Fix UT. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc » ('j') | ui/base/ui_base_types.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698