Commit be913dcb authored by Alex Newcomer's avatar Alex Newcomer Committed by Commit Bot

cros: Fix menus getting squished

Menu bounds do not fit new wider options if the menu options are added
after the menu is initially drawn, and the width of the new options
exceeds {screen_width - original_menu_origin.x}. This makes wide menu
options unusable in some cases because the menu does not widen to
accommodate the new items.

Regression started: r573978

Test case:
1. Show a website with link[1] on the far right side of the screen:
https://www.google.com/chromebook/
2. Right click to show a menu on one of the links in the toolbar.

The menu should be wide enough to show all contents of the menu.

[1]Step 1 must have a link as the source of the menu because
links use arc::OpenWithMenu, which can add wider ("Open with ...")
options to a context menu. These options are added after the menu
is drawn because we show the menu before arc calls back with the new
menu options.

Test: MenuControllerTest.GrowingMenuMovesLaterallyNotVertically
Bug: 882662
Change-Id: Ic848fdb545bbdd05f874041bf1044adb7bd1d094
Reviewed-on: https://chromium-review.googlesource.com/c/1262397
Commit-Queue: Alex Newcomer <newcomer@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600563}
parent 24f11a7b
......@@ -2136,7 +2136,14 @@ gfx::Rect MenuController::CalculateMenuBounds(MenuItemView* item,
item->actual_menu_position() == MenuItemView::POSITION_ABOVE_BOUNDS) {
// Menu has been drawn below/above the anchor bounds, make sure it fits
// on the screen in its current location.
const int drawn_width = menu_bounds.width();
menu_bounds.Intersect(monitor_bounds);
// Do not allow the menu to get narrower. This handles the case where the
// menu would have drawn off-screen, but the effective anchor was shifted
// at the end of this function. Preserve the width, so it is shifted
// again.
menu_bounds.set_width(drawn_width);
} else if (menu_bounds.bottom() <= monitor_bounds.bottom()) {
// Menu fits below anchor bounds.
item->set_actual_menu_position(MenuItemView::POSITION_BELOW_BOUNDS);
......@@ -2165,6 +2172,7 @@ gfx::Rect MenuController::CalculateMenuBounds(MenuItemView* item,
}
}
// Ensure the menu is not displayed off screen.
menu_bounds.set_x(
base::ClampToRange(menu_bounds.x(), monitor_bounds.x(),
monitor_bounds.right() - menu_bounds.width()));
......
......@@ -278,6 +278,9 @@ class TestMenuItemViewShown : public MenuItemView {
void SetActualMenuPosition(MenuItemView::MenuPosition position) {
set_actual_menu_position(position);
}
MenuItemView::MenuPosition ActualMenuPosition() {
return actual_menu_position();
}
private:
DISALLOW_COPY_AND_ASSIGN(TestMenuItemViewShown);
......@@ -1612,6 +1615,37 @@ TEST_F(MenuControllerTest, CalculateMenuBoundsMonitorFitTest) {
EXPECT_EQ(expected, CalculateMenuBounds(options));
}
// Test that a menu that was originally drawn below the anchor does not get
// squished or move above the anchor when it grows vertically and horizontally
// beyond the monitor bounds.
TEST_F(MenuControllerTest, GrowingMenuMovesLaterallyNotVertically) {
MenuBoundsOptions options;
options.monitor_bounds = gfx::Rect(0, 0, 100, 100);
// The anchor should be near the bottom right side of the screen.
options.anchor_bounds = gfx::Rect(80, 70, 15, 10);
// The menu should fit the available space, below the anchor.
options.menu_size = gfx::Size(20, 20);
// Ensure the menu is initially drawn below the bounds, and the MenuPosition
// is set to POSITION_BELOW_BOUNDS;
const gfx::Rect first_drawn_expected(80, 80, 20, 20);
EXPECT_EQ(first_drawn_expected, CalculateMenuBounds(options));
EXPECT_EQ(MenuItemView::MenuPosition::POSITION_BELOW_BOUNDS,
menu_item()->ActualMenuPosition());
options.menu_position = MenuItemView::MenuPosition::POSITION_BELOW_BOUNDS;
// The menu bounds are larger than the remaining space on the monitor. This
// simulates the case where the menu has been grown vertically and
// horizontally to where it would no longer fit on the screen.
options.menu_size = gfx::Size(50, 50);
// The menu bounds should move left to show the wider menu, and grow to fill
// the remaining vertical space without moving upwards.
const gfx::Rect final_expected(50, 80, 50, 20);
EXPECT_EQ(final_expected, CalculateMenuBounds(options));
}
#if defined(USE_AURA)
// This tests that mouse moved events from the initial position of the mouse
// when the menu was shown don't select the menu item at the mouse position.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment