Commit b3c9cc19 authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

Hot track the child button when the mouse hovering on the host item

MenuController::HandleMouseLocation() called in
MenuController::OnMouseMoved() calls MenuController::SetSelection()
which may reset the hot-tracked view. Meanwhile, in OnMouseMoved(),
the hot-tracked view updates before HandleMouseLocation(). As a result,
the hot-tracked view may fail to update after the mouse move event.

This bug should have existed for long time. But it is not noticeable
on real devices: when a user moves the mouse, it usually creates more
than one mouse move events. Then the second mouse move event updates
the hot-tracked view.

This CL updates the hot-tracked view after HandleMouseLocation().

Bug: 1135000
Change-Id: Iae810563e897d75912bcc140ed56022d72e3170c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2448650Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814039}
parent e3d073b8
......@@ -837,6 +837,7 @@ void MenuController::OnMouseMoved(SubmenuView* source,
menu_open_mouse_loc_.reset();
MenuHostRootView* root_view = GetRootView(source, event.location());
Button* new_hot_tracked_button = nullptr;
if (root_view) {
root_view->ProcessMouseMoved(event);
......@@ -846,12 +847,15 @@ void MenuController::OnMouseMoved(SubmenuView* source,
ui::MouseEvent event_for_root(event);
ConvertLocatedEventForRootView(source, root_view, &event_for_root);
View* view = root_view->GetEventHandlerForPoint(event_for_root.location());
Button* button = Button::AsButton(view);
if (button)
SetHotTrackedButton(button);
new_hot_tracked_button = Button::AsButton(view);
}
HandleMouseLocation(source, event.location());
// Updating the hot tracked button should be after `HandleMouseLocation()`
// which may reset the current hot tracked button.
if (new_hot_tracked_button)
SetHotTrackedButton(new_hot_tracked_button);
}
void MenuController::OnMouseEntered(SubmenuView* source,
......
......@@ -1370,6 +1370,31 @@ TEST_F(MenuControllerTest, DeleteChildButtonView) {
EXPECT_FALSE(button3->IsHotTracked());
}
// Verifies that the child button of the menu item which is under mouse hovering
// is hot tracked (https://crbug.com/1135000).
TEST_F(MenuControllerTest, ChildButtonHotTrackedAfterMouseMove) {
// Add a menu item which owns a button as child.
menu_item()->SetBounds(0, 0, 200, 300);
MenuItemView* button_host_view =
menu_item()->AppendMenuItem(/*command_id=*/5);
auto* button = button_host_view->AddChildView(
std::make_unique<LabelButton>(nullptr, base::ASCIIToUTF16("Label")));
button->SetFocusBehavior(View::FocusBehavior::ALWAYS);
menu_item()->GetSubmenu()->ShowAt(owner(), menu_item()->bounds(), false);
EXPECT_FALSE(button->IsHotTracked());
SubmenuView* sub_menu = menu_item()->GetSubmenu();
gfx::Point location(button->GetBoundsInScreen().CenterPoint());
View::ConvertPointFromScreen(sub_menu->GetScrollViewContainer(), &location);
ui::MouseEvent event(ui::ET_MOUSE_MOVED, location, location,
ui::EventTimeForNow(), 0, 0);
ProcessMouseMoved(sub_menu, event);
// After the mouse moves to `button`, `button` should be hot tracked.
EXPECT_EQ(button, GetHotButton());
EXPECT_TRUE(button->IsHotTracked());
}
// Creates a menu with Button child views, simulates running a nested
// menu and tests that existing the nested run restores hot-tracked child view.
TEST_F(MenuControllerTest, ChildButtonHotTrackedWhenNested) {
......
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