diff --git a/src/Wt/WMenu.C b/src/Wt/WMenu.C index ac3c576aa..b0e211c1c 100644 --- a/src/Wt/WMenu.C +++ b/src/Wt/WMenu.C @@ -283,10 +283,13 @@ std::unique_ptr WMenu::removeItem(WMenuItem *item) item->setParentMenu(nullptr); - if (itemIndex <= current_ && current_ >= 0) + if (itemIndex == current_) { + setCurrent(-1); + select(-1, true); + } else if (itemIndex < current_ && current_ > 0) { --current_; - - select(current_, true); + select(current_, true); + } } return result; diff --git a/test/widgets/WMenuTest.C b/test/widgets/WMenuTest.C index 84c1b947c..33f851798 100644 --- a/test/widgets/WMenuTest.C +++ b/test/widgets/WMenuTest.C @@ -39,3 +39,56 @@ BOOST_AUTO_TEST_CASE(WMenu_addItem_change_index_for_internal_path_match) BOOST_TEST(menu->currentIndex() == previousIndex); } +// Regression test: removeItem() must clear selection (not select the previous +// item) when the currently-selected item is the one being removed. +BOOST_AUTO_TEST_CASE(WMenu_removeItem_clears_selection_of_current_item) +{ + Wt::Test::WTestEnvironment testEnv; + Wt::WApplication app(testEnv); + + Wt::WStackedWidget *stack = app.root()->addNew(); + Wt::WMenu *menu = app.root()->addNew(stack); + + Wt::WMenuItem *item0 = menu->addItem("Item 0", std::make_unique("Content 0")); + Wt::WMenuItem *item1 = menu->addItem("Item 1", std::make_unique("Content 1")); + Wt::WMenuItem *item2 = menu->addItem("Item 2", std::make_unique("Content 2")); + + // Select the middle item + menu->select(item1); + BOOST_REQUIRE(menu->currentIndex() == 1); + + // Remove the currently-selected item — selection must be cleared, not moved + auto removed = menu->removeItem(item1); + BOOST_TEST(menu->currentIndex() == -1); + BOOST_TEST(menu->currentItem() == nullptr); + + // Remaining items must be accessible at correct indices + BOOST_TEST(menu->count() == 2); + BOOST_TEST(menu->itemAt(0) == item0); + BOOST_TEST(menu->itemAt(1) == item2); +} + +// Regression test: removeItem() must decrement current_ (not clear) when +// an item *before* the currently-selected item is removed. +BOOST_AUTO_TEST_CASE(WMenu_removeItem_before_current_keeps_selection) +{ + Wt::Test::WTestEnvironment testEnv; + Wt::WApplication app(testEnv); + + Wt::WStackedWidget *stack = app.root()->addNew(); + Wt::WMenu *menu = app.root()->addNew(stack); + + Wt::WMenuItem *item0 = menu->addItem("Item 0", std::make_unique("Content 0")); + Wt::WMenuItem *item1 = menu->addItem("Item 1", std::make_unique("Content 1")); + Wt::WMenuItem *item2 = menu->addItem("Item 2", std::make_unique("Content 2")); + + // Select item2 (index 2) + menu->select(item2); + BOOST_REQUIRE(menu->currentIndex() == 2); + + // Remove item0 (before current) — item2 must remain selected at new index 1 + auto removed = menu->removeItem(item0); + BOOST_TEST(menu->currentItem() == item2); + BOOST_TEST(menu->currentIndex() == 1); +} +