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 1/2] 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 } From 0b8a85ad649c6747b8284c0782f320558f577602 Mon Sep 17 00:00:00 2001 From: taler21 <99262969+taler21@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:51:09 +0100 Subject: [PATCH 2/2] Enable MultiSelect() unit test for generic wxListCtrl This test just doesn't want to work when run on GitHub CI under wxGTK2 even though it works perfectly locally. So enable the test at least for all other ports. --- tests/controls/listbasetest.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/controls/listbasetest.cpp b/tests/controls/listbasetest.cpp index 5efce9ac79..240ef3e676 100644 --- a/tests/controls/listbasetest.cpp +++ b/tests/controls/listbasetest.cpp @@ -179,12 +179,12 @@ void ListBaseTestCase::MultiSelect() { #if wxUSE_UIACTIONSIMULATOR -#ifndef __WXMSW__ - // FIXME: This test fails on Travis CI although works fine on +#if defined(__WXGTK__) && !defined(__WXGTK3__) + // FIXME: This test fails on GitHub CI under wxGTK2 although works fine on // development machine, no idea why though! if ( IsAutomaticTest() ) return; -#endif // !__WXMSW__ +#endif // wxGTK2 wxListCtrl* const list = GetList();