0

Ignore mouse released events in menus shown for a drag-and-drop

This CL adds back a line that was recently removed (see thread[1]), and
introduces a regression test to ensure that menus don't crash when the
mouse is released while open for a dnd that was canceled.

[1]
https://chromium-review.googlesource.com/c/chromium/src/+/5941362/comment/922f3925_f49e2401

Change-Id: I0aa729abe7eed994b11a147c37160f852c1f20b3
Bug: 410095496
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6497573
Reviewed-by: Dana Fried <dfried@chromium.org>
Commit-Queue: Kaan Alsan <alsan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1453976}
This commit is contained in:
Kaan Alsan
2025-04-30 09:12:16 -07:00
committed by Chromium LUCI CQ
parent e65f68afe5
commit 65ff74609e
2 changed files with 21 additions and 5 deletions

@ -946,11 +946,10 @@ void MenuController::OnMouseReleased(SubmenuView* source,
return;
}
// Mouse releases during DnD are handled differently by platforms. Most will
// consume the mouse release to end the DnD, which would subsequently trigger
// OnDragComplete. However, Wayland will send a spurious mouse release event
// before ending the DnD, which should be ignored by this menu.
if (drag_in_progress_) {
// The menu should ignore mouse release events and refrain from closing if a
// drag operation is in progress or has been recently canceled without
// immediate notification.
if (drag_in_progress_ || for_drop_) {
return;
}

@ -1823,6 +1823,23 @@ TEST_F(MenuControllerForDropTest, AsyncDropCallback) {
EXPECT_TRUE(menu_delegate->is_drop_performed());
}
TEST_F(MenuControllerForDropTest, OnMouseReleasedIgnored) {
ShowSubmenu();
SubmenuView* const submenu = menu_item()->GetSubmenu();
MenuItemView* const target = submenu->GetMenuItemAt(0);
const gfx::Point press_location = target->bounds().CenterPoint();
ProcessMouseReleased(
submenu, ui::MouseEvent(ui::EventType::kMouseReleased, press_location,
press_location, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, 0));
// The command shouldn't be executed if this menu is open for a drop.
EXPECT_EQ(menu_delegate()->execute_command_id(),
test::TestMenuDelegate::kInvalidExecuteCommandId);
EXPECT_EQ(menu_controller_delegate()->on_menu_closed_called(), 0);
EXPECT_TRUE(showing());
}
// Widget destruction and cleanup occurs on the MessageLoop after the
// MenuController has been destroyed. A MenuHostRootView should not attempt to
// access a destroyed MenuController. This test should not cause a crash.