From d091a44adbc5a228cd351c753b290623b50dd62b Mon Sep 17 00:00:00 2001 From: taler21 <99262969+taler21@users.noreply.github.com> Date: Mon, 19 Feb 2024 13:58:51 +0100 Subject: [PATCH] Fix missing deselection of single selected but not focused item A generic multi-select wxListCtrl did not deselect a single selected item that did not have focus when the user single-selected another item. This fixes a regression introduced in fedc80eee3 (Improve selection and focus events generation in wxGenericLisCtrl, 2020-10-10). Closes #24312. --- src/generic/listctrl.cpp | 2 +- tests/controls/listbasetest.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 21bc5fb92c..9bfe52a2bb 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -2220,7 +2220,7 @@ void wxListMainWindow::HighlightOnly( size_t line, size_t oldLine ) : RefreshLine(oldLine); // refresh the old focus to remove it } - if ( selCount > 1 ) // multiple-selection only + if ( selCount >= 1 ) // multiple-selection only { // Deselecting many items at once will generate wxEVT_XXX_DESELECTED event // for each one of them. although this may be inefficient if the number of diff --git a/tests/controls/listbasetest.cpp b/tests/controls/listbasetest.cpp index c34508adf8..5efce9ac79 100644 --- a/tests/controls/listbasetest.cpp +++ b/tests/controls/listbasetest.cpp @@ -273,6 +273,37 @@ void ListBaseTestCase::MultiSelect() CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // because the focus changed from item 0 to anchor CPPUNIT_ASSERT_EQUAL(0, selected.GetCount()); // anchor is already in selection state CPPUNIT_ASSERT_EQUAL(2, deselected.GetCount()); // items 0 and 1 are deselected + + focused.Clear(); + selected.Clear(); + deselected.Clear(); + + list->GetItemRect(3, pos); + point = list->ClientToScreen(pos.GetPosition()) + wxPoint(10, 10); + + // select and deselect item 3 while leaving item 2 selected + for ( int i = 0; i < 2; ++i ) + { + sim.MouseMove(point + wxPoint(i*10, 0)); + wxYield(); + + sim.KeyDown(WXK_CONTROL); + sim.MouseClick(); + sim.KeyUp(WXK_CONTROL); + wxYield(); + } + + // select only item 3 + sim.MouseMove(point); + wxYield(); + + sim.MouseClick(); + wxYield(); + + CPPUNIT_ASSERT_EQUAL(1, list->GetSelectedItemCount()); // item 3 is the only selected item + CPPUNIT_ASSERT_EQUAL(1, focused.GetCount()); // because the focus changed from anchor to item 3 + CPPUNIT_ASSERT_EQUAL(2, selected.GetCount()); // item 3 was selected twice + CPPUNIT_ASSERT_EQUAL(2, deselected.GetCount()); // anchor and item 3 were each deselected once #endif // wxUSE_UIACTIONSIMULATOR }